#endif
#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
+ bool getInfoFromFdeCie(const typename CFI_Parser<A>::FDE_Info &fdeInfo,
+ const typename CFI_Parser<A>::CIE_Info &cieInfo,
+ pint_t pc, uintptr_t dso_base);
bool getInfoFromDwarfSection(pint_t pc, const UnwindInfoSections §s,
uint32_t fdeSectionOffsetHint=0);
int stepWithDwarfFDE() {
#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
template <typename A, typename R>
+bool UnwindCursor<A, R>::getInfoFromFdeCie(
+ const typename CFI_Parser<A>::FDE_Info &fdeInfo,
+ const typename CFI_Parser<A>::CIE_Info &cieInfo, pint_t pc,
+ uintptr_t dso_base) {
+ typename CFI_Parser<A>::PrologInfo prolog;
+ if (CFI_Parser<A>::parseFDEInstructions(_addressSpace, fdeInfo, cieInfo, pc,
+ R::getArch(), &prolog)) {
+ // Save off parsed FDE info
+ _info.start_ip = fdeInfo.pcStart;
+ _info.end_ip = fdeInfo.pcEnd;
+ _info.lsda = fdeInfo.lsda;
+ _info.handler = cieInfo.personality;
+ // Some frameless functions need SP altered when resuming in function, so
+ // propagate spExtraArgSize.
+ _info.gp = prolog.spExtraArgSize;
+ _info.flags = 0;
+ _info.format = dwarfEncoding();
+ _info.unwind_info = fdeInfo.fdeStart;
+ _info.unwind_info_size = static_cast<uint32_t>(fdeInfo.fdeLength);
+ _info.extra = static_cast<unw_word_t>(dso_base);
+ return true;
+ }
+ return false;
+}
+
+template <typename A, typename R>
bool UnwindCursor<A, R>::getInfoFromDwarfSection(pint_t pc,
const UnwindInfoSections §s,
uint32_t fdeSectionOffsetHint) {
&fdeInfo, &cieInfo);
}
if (foundFDE) {
- typename CFI_Parser<A>::PrologInfo prolog;
- if (CFI_Parser<A>::parseFDEInstructions(_addressSpace, fdeInfo, cieInfo, pc,
- R::getArch(), &prolog)) {
- // Save off parsed FDE info
- _info.start_ip = fdeInfo.pcStart;
- _info.end_ip = fdeInfo.pcEnd;
- _info.lsda = fdeInfo.lsda;
- _info.handler = cieInfo.personality;
- _info.gp = prolog.spExtraArgSize;
- _info.flags = 0;
- _info.format = dwarfEncoding();
- _info.unwind_info = fdeInfo.fdeStart;
- _info.unwind_info_size = (uint32_t)fdeInfo.fdeLength;
- _info.extra = (unw_word_t) sects.dso_base;
-
+ if (getInfoFromFdeCie(fdeInfo, cieInfo, pc, sects.dso_base)) {
// Add to cache (to make next lookup faster) if we had no hint
// and there was no index.
if (!foundInCache && (fdeSectionOffsetHint == 0)) {
// dynamically registered for it.
pint_t cachedFDE = DwarfFDECache<A>::findFDE(0, pc);
if (cachedFDE != 0) {
- CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo;
- CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo;
- const char *msg = CFI_Parser<A>::decodeFDE(_addressSpace,
- cachedFDE, &fdeInfo, &cieInfo);
- if (msg == NULL) {
- typename CFI_Parser<A>::PrologInfo prolog;
- if (CFI_Parser<A>::parseFDEInstructions(_addressSpace, fdeInfo, cieInfo,
- pc, R::getArch(), &prolog)) {
- // save off parsed FDE info
- _info.start_ip = fdeInfo.pcStart;
- _info.end_ip = fdeInfo.pcEnd;
- _info.lsda = fdeInfo.lsda;
- _info.handler = cieInfo.personality;
- _info.gp = prolog.spExtraArgSize;
- // Some frameless functions need SP
- // altered when resuming in function.
- _info.flags = 0;
- _info.format = dwarfEncoding();
- _info.unwind_info = fdeInfo.fdeStart;
- _info.unwind_info_size = (uint32_t)fdeInfo.fdeLength;
- _info.extra = 0;
+ typename CFI_Parser<A>::FDE_Info fdeInfo;
+ typename CFI_Parser<A>::CIE_Info cieInfo;
+ if (!CFI_Parser<A>::decodeFDE(_addressSpace, cachedFDE, &fdeInfo, &cieInfo))
+ if (getInfoFromFdeCie(fdeInfo, cieInfo, pc, 0))
return;
- }
- }
}
// Lastly, ask AddressSpace object about platform specific ways to locate
// other FDEs.
pint_t fde;
if (_addressSpace.findOtherFDE(pc, fde)) {
- CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo;
- CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo;
+ typename CFI_Parser<A>::FDE_Info fdeInfo;
+ typename CFI_Parser<A>::CIE_Info cieInfo;
if (!CFI_Parser<A>::decodeFDE(_addressSpace, fde, &fdeInfo, &cieInfo)) {
// Double check this FDE is for a function that includes the pc.
- if ((fdeInfo.pcStart <= pc) && (pc < fdeInfo.pcEnd)) {
- typename CFI_Parser<A>::PrologInfo prolog;
- if (CFI_Parser<A>::parseFDEInstructions(_addressSpace, fdeInfo, cieInfo,
- pc, R::getArch(), &prolog)) {
- // save off parsed FDE info
- _info.start_ip = fdeInfo.pcStart;
- _info.end_ip = fdeInfo.pcEnd;
- _info.lsda = fdeInfo.lsda;
- _info.handler = cieInfo.personality;
- _info.gp = prolog.spExtraArgSize;
- _info.flags = 0;
- _info.format = dwarfEncoding();
- _info.unwind_info = fdeInfo.fdeStart;
- _info.unwind_info_size = (uint32_t)fdeInfo.fdeLength;
- _info.extra = 0;
+ if ((fdeInfo.pcStart <= pc) && (pc < fdeInfo.pcEnd))
+ if (getInfoFromFdeCie(fdeInfo, cieInfo, pc, 0))
return;
- }
- }
}
}
#endif // #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)