forked from OSchip/llvm-project
[libunwind] Factor out getInfoFromFdeCie. NFCI.
Differential Revision: https://reviews.llvm.org/D86255
This commit is contained in:
parent
7a457593ef
commit
3071d5ffba
|
@ -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 §s,
|
||||
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 §s,
|
||||
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue