Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions src/UnwindCursor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ namespace libunwind {

#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
/// Cache of recently found FDEs.

// if we can't use heap = we can't cache anything.
// no need for buffers / rwmutex / class itself
#if !defined(_LIBUNWIND_NO_HEAP)

template <typename A>
class _LIBUNWIND_HIDDEN DwarfFDECache {
typedef typename A::pint_t pint_t;
Expand Down Expand Up @@ -152,7 +157,6 @@ typename A::pint_t DwarfFDECache<A>::findFDE(pint_t mh, pint_t pc) {
template <typename A>
void DwarfFDECache<A>::add(pint_t mh, pint_t ip_start, pint_t ip_end,
pint_t fde) {
#if !defined(_LIBUNWIND_NO_HEAP)
_LIBUNWIND_LOG_IF_FALSE(_lock.lock());
if (_bufferUsed >= _bufferEnd) {
size_t oldSize = (size_t)(_bufferEnd - _buffer);
Expand All @@ -178,7 +182,6 @@ void DwarfFDECache<A>::add(pint_t mh, pint_t ip_start, pint_t ip_end,
}
#endif
_LIBUNWIND_LOG_IF_FALSE(_lock.unlock());
#endif
}

template <typename A>
Expand Down Expand Up @@ -212,6 +215,7 @@ void DwarfFDECache<A>::iterateCacheEntries(void (*func)(
}
_LIBUNWIND_LOG_IF_FALSE(_lock.unlock());
}
#endif // !defined(_LIBUNWIND_NO_HEAP)
#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)


Expand Down Expand Up @@ -1469,8 +1473,12 @@ bool UnwindCursor<A, R>::getInfoFromDwarfSection(pint_t pc,
}
#endif
if (!foundFDE) {
#if !defined(_LIBUNWIND_NO_HEAP)
// otherwise, search cache of previously found FDEs.
pint_t cachedFDE = DwarfFDECache<A>::findFDE(sects.dso_base, pc);
#else
pint_t cachedFDE = 0;
#endif
if (cachedFDE != 0) {
foundFDE =
CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section,
Expand Down Expand Up @@ -1503,13 +1511,16 @@ bool UnwindCursor<A, R>::getInfoFromDwarfSection(pint_t pc,

// Add to cache (to make next lookup faster) if we had no hint
// and there was no index.
#if !defined(_LIBUNWIND_NO_HEAP)
if (!foundInCache && (fdeSectionOffsetHint == 0)) {
#if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX)
if (sects.dwarf_index_section == 0)
#endif
DwarfFDECache<A>::add(sects.dso_base, fdeInfo.pcStart, fdeInfo.pcEnd,
fdeInfo.fdeStart);
}
#endif // !defined(_LIBUNWIND_NO_HEAP)

return true;
}
}
Expand Down Expand Up @@ -1894,7 +1905,11 @@ void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) {
#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
// There is no static unwind info for this pc. Look to see if an FDE was
// dynamically registered for it.
#if !defined(_LIBUNWIND_NO_HEAP)
pint_t cachedFDE = DwarfFDECache<A>::findFDE(0, pc);
#else
pint_t cachedFDE = 0;
#endif
if (cachedFDE != 0) {
CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo;
CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo;
Expand Down
6 changes: 6 additions & 0 deletions src/libunwind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,9 @@ _LIBUNWIND_HIDDEN void __unw_iterate_dwarf_unwind_cache(void (*func)(
unw_word_t ip_start, unw_word_t ip_end, unw_word_t fde, unw_word_t mh)) {
_LIBUNWIND_TRACE_API("__unw_iterate_dwarf_unwind_cache(func=%p)",
reinterpret_cast<void *>(func));
#if !defined(_LIBUNWIND_NO_HEAP)
DwarfFDECache<LocalAddressSpace>::iterateCacheEntries(func);
#endif
}
_LIBUNWIND_WEAK_ALIAS(__unw_iterate_dwarf_unwind_cache,
unw_iterate_dwarf_unwind_cache)
Expand All @@ -261,10 +263,12 @@ void __unw_add_dynamic_fde(unw_word_t fde) {
if (message == NULL) {
// dynamically registered FDEs don't have a mach_header group they are in.
// Use fde as mh_group
#if !defined(_LIBUNWIND_NO_HEAP)
unw_word_t mh_group = fdeInfo.fdeStart;
DwarfFDECache<LocalAddressSpace>::add((LocalAddressSpace::pint_t)mh_group,
fdeInfo.pcStart, fdeInfo.pcEnd,
fdeInfo.fdeStart);
#endif
} else {
_LIBUNWIND_DEBUG_LOG("__unw_add_dynamic_fde: bad fde: %s", message);
}
Expand All @@ -273,7 +277,9 @@ void __unw_add_dynamic_fde(unw_word_t fde) {
/// IPI: for __deregister_frame()
void __unw_remove_dynamic_fde(unw_word_t fde) {
// fde is own mh_group
#if !defined(_LIBUNWIND_NO_HEAP)
DwarfFDECache<LocalAddressSpace>::removeAllIn((LocalAddressSpace::pint_t)fde);
#endif // !defined(_LIBUNWIND_NO_HEAP)
}
#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
#endif // !defined(__USING_SJLJ_EXCEPTIONS__)
Expand Down