Skip to content
Closed
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
64 changes: 64 additions & 0 deletions src/native/external/llvm-libunwind/src/EHHeaderParser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,67 @@ bool EHHeaderParser<A>::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<A>::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;

Expand All @@ -134,6 +195,9 @@ bool EHHeaderParser<A>::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)
Expand Down
21 changes: 21 additions & 0 deletions src/native/external/llvm-libunwind/src/UnwindCursor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,25 @@ class _LIBUNWIND_HIDDEN DwarfFDECache {
static entry _initialBuffer[64];
};

template <typename A>
typename A::pint_t DwarfFDECache<A>::findFDE(pint_t mh, pint_t pc) {
return 0;
}

template <typename A>
void DwarfFDECache<A>::add(pint_t mh, pint_t ip_start, pint_t ip_end,
pint_t fde) {
}

template <typename A> void DwarfFDECache<A>::removeAllIn(pint_t mh) {
}

template <typename A>
void DwarfFDECache<A>::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 A>
typename DwarfFDECache<A>::entry *
DwarfFDECache<A>::_buffer = _initialBuffer;
Expand Down Expand Up @@ -226,6 +245,8 @@ void DwarfFDECache<A>::iterateCacheEntries(void (*func)(
}
_LIBUNWIND_LOG_IF_FALSE(_lock.unlock());
}
#endif

#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)


Expand Down