[libunwind] Factor out getInfoFromFdeCie. NFCI.

Differential Revision: https://reviews.llvm.org/D86255
This commit is contained in:
Ryan Prichard 2020-08-18 02:31:38 -07:00
parent 7a457593ef
commit 3071d5ffba
1 changed files with 38 additions and 57 deletions

View File

@ -925,6 +925,9 @@ private:
#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 &sects,
uint32_t fdeSectionOffsetHint=0);
int stepWithDwarfFDE() {
@ -1476,6 +1479,32 @@ bool UnwindCursor<A, R>::getInfoFromEHABISection(
#endif
#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 &sects,
@ -1516,21 +1545,7 @@ bool UnwindCursor<A, R>::getInfoFromDwarfSection(pint_t pc,
&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)) {
@ -1932,58 +1947,24 @@ void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) {
// 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)