From 183fe986d0a937ac9cab3ba25732f23b3f9cefe6 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Tue, 6 Jun 2023 19:20:00 -0700 Subject: [PATCH] WIP --- .../llvm-libunwind/src/EHHeaderParser.hpp | 64 +++++++++++++++++++ .../llvm-libunwind/src/UnwindCursor.hpp | 21 ++++++ 2 files changed, 85 insertions(+) diff --git a/src/native/external/llvm-libunwind/src/EHHeaderParser.hpp b/src/native/external/llvm-libunwind/src/EHHeaderParser.hpp index ed4317c89055c9..69ffe7036d948c 100644 --- a/src/native/external/llvm-libunwind/src/EHHeaderParser.hpp +++ b/src/native/external/llvm-libunwind/src/EHHeaderParser.hpp @@ -112,6 +112,67 @@ bool EHHeaderParser::findFDE(A &addressSpace, pint_t pc, pint_t ehHdrStart, if (hdrInfo.fde_count == 0) return false; + pint_t tableEntryDebug = 0; + + // Special-case the most common encoding with faster binary search implementation + if (hdrInfo.table_enc == (DW_EH_PE_sdata4 | DW_EH_PE_datarel)) + { + size_t tableEntrySize = 8; + + pint_t relpc = pc - ehHdrStart; + + size_t low = 0; + size_t high = hdrInfo.fde_count - 1; + + // Binary search the entry table + // Use linear search once we get down to a small number of elements + // to avoid binary search overhead. + while (high - low > 10) { + size_t middle = low + (high - low) / 2; + + pint_t tableEntry = hdrInfo.table + middle * tableEntrySize; + pint_t relstart = (pint_t)(int32_t)addressSpace.get32(tableEntry); + + if (relpc < relstart) { + high = middle - 1; + } else { + low = middle; + } + } + + for (size_t i = low; i < high; i++) { + pint_t tableEntry = hdrInfo.table + (i + 1) * tableEntrySize; + pint_t relstart = (pint_t)(int32_t)addressSpace.get32(tableEntry); + + if (relpc < relstart) { + high = i; + break; + } + } + + pint_t tableEntry = hdrInfo.table + high * tableEntrySize; + + // Have to decode the whole FDE for the PC range anyway, so just throw away + // the PC start. + pint_t fde = + (pint_t)(int32_t)addressSpace.get32(tableEntry + 4) + ehHdrStart; + const char *message = + CFI_Parser::decodeFDE(addressSpace, fde, fdeInfo, cieInfo); + if (message != NULL) { + _LIBUNWIND_DEBUG_LOG("EHHeaderParser::decodeTableEntry: bad fde: %s", + message); + return false; + } + +#if defined(NDEBUG) + if (pc >= fdeInfo->pcStart && pc < fdeInfo->pcEnd) + return true; + return false; +#else + tableEntryDebug = tableEntry; +#endif + } + size_t tableEntrySize = getTableEntrySize(hdrInfo.table_enc); pint_t tableEntry; @@ -134,6 +195,9 @@ bool EHHeaderParser::findFDE(A &addressSpace, pint_t pc, pint_t ehHdrStart, } tableEntry = hdrInfo.table + low * tableEntrySize; + + assert(tableEntry == tableEntryDebug); + if (decodeTableEntry(addressSpace, tableEntry, ehHdrStart, ehHdrEnd, hdrInfo.table_enc, fdeInfo, cieInfo)) { if (pc >= fdeInfo->pcStart && pc < fdeInfo->pcEnd) diff --git a/src/native/external/llvm-libunwind/src/UnwindCursor.hpp b/src/native/external/llvm-libunwind/src/UnwindCursor.hpp index b57134cdd19bb9..12b9ca2a9154b0 100644 --- a/src/native/external/llvm-libunwind/src/UnwindCursor.hpp +++ b/src/native/external/llvm-libunwind/src/UnwindCursor.hpp @@ -124,6 +124,25 @@ class _LIBUNWIND_HIDDEN DwarfFDECache { static entry _initialBuffer[64]; }; +template +typename A::pint_t DwarfFDECache::findFDE(pint_t mh, pint_t pc) { + return 0; +} + +template +void DwarfFDECache::add(pint_t mh, pint_t ip_start, pint_t ip_end, + pint_t fde) { +} + +template void DwarfFDECache::removeAllIn(pint_t mh) { +} + +template +void DwarfFDECache::iterateCacheEntries(void (*func)( + unw_word_t ip_start, unw_word_t ip_end, unw_word_t fde, unw_word_t mh)) { +} + +#if 0 template typename DwarfFDECache::entry * DwarfFDECache::_buffer = _initialBuffer; @@ -226,6 +245,8 @@ void DwarfFDECache::iterateCacheEntries(void (*func)( } _LIBUNWIND_LOG_IF_FALSE(_lock.unlock()); } +#endif + #endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)