Skip to content

Commit 5581990

Browse files
committed
Merging r352016:
------------------------------------------------------------------------ r352016 | phosek | 2019-01-24 04:04:42 +0100 (Thu, 24 Jan 2019) | 12 lines [libunwind] Don't abort if encoutering invalid .eh_frame_hdr Recent Linux kernel release has introduced a bug as part of the ORC rollout where the vDSO has a valid .eh_frame section, but it's missing the .eh_frame_hdr section and GNU_EH_FRAME segment has zero size. This causes libunwind to abort which breaks programs that use libunwind. The other unwinder implementation (libgcc, non-gnu) instead silently bail out unless being compiled as debug. This change modifies libunwind to use the same strategy. Differential Revision: https://reviews.llvm.org/D57081 ------------------------------------------------------------------------ llvm-svn: 353287
1 parent 35f4f2f commit 5581990

File tree

2 files changed

+14
-8
lines changed

2 files changed

+14
-8
lines changed

libunwind/src/AddressSpace.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -534,11 +534,11 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
534534
#endif
535535
cbdata->sects->dwarf_index_section = eh_frame_hdr_start;
536536
cbdata->sects->dwarf_index_section_length = phdr->p_memsz;
537-
EHHeaderParser<LocalAddressSpace>::decodeEHHdr(
537+
found_hdr = EHHeaderParser<LocalAddressSpace>::decodeEHHdr(
538538
*cbdata->addressSpace, eh_frame_hdr_start, phdr->p_memsz,
539539
hdrInfo);
540-
cbdata->sects->dwarf_section = hdrInfo.eh_frame_ptr;
541-
found_hdr = true;
540+
if (found_hdr)
541+
cbdata->sects->dwarf_section = hdrInfo.eh_frame_ptr;
542542
}
543543
}
544544

libunwind/src/EHHeaderParser.hpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ template <typename A> class EHHeaderParser {
3636
uint8_t table_enc;
3737
};
3838

39-
static void decodeEHHdr(A &addressSpace, pint_t ehHdrStart, pint_t ehHdrEnd,
39+
static bool decodeEHHdr(A &addressSpace, pint_t ehHdrStart, pint_t ehHdrEnd,
4040
EHHeaderInfo &ehHdrInfo);
4141
static bool findFDE(A &addressSpace, pint_t pc, pint_t ehHdrStart,
4242
uint32_t sectionLength,
@@ -53,12 +53,14 @@ template <typename A> class EHHeaderParser {
5353
};
5454

5555
template <typename A>
56-
void EHHeaderParser<A>::decodeEHHdr(A &addressSpace, pint_t ehHdrStart,
56+
bool EHHeaderParser<A>::decodeEHHdr(A &addressSpace, pint_t ehHdrStart,
5757
pint_t ehHdrEnd, EHHeaderInfo &ehHdrInfo) {
5858
pint_t p = ehHdrStart;
5959
uint8_t version = addressSpace.get8(p++);
60-
if (version != 1)
61-
_LIBUNWIND_ABORT("Unsupported .eh_frame_hdr version");
60+
if (version != 1) {
61+
_LIBUNWIND_LOG0("Unsupported .eh_frame_hdr version");
62+
return false;
63+
}
6264

6365
uint8_t eh_frame_ptr_enc = addressSpace.get8(p++);
6466
uint8_t fde_count_enc = addressSpace.get8(p++);
@@ -71,6 +73,8 @@ void EHHeaderParser<A>::decodeEHHdr(A &addressSpace, pint_t ehHdrStart,
7173
? 0
7274
: addressSpace.getEncodedP(p, ehHdrEnd, fde_count_enc, ehHdrStart);
7375
ehHdrInfo.table = p;
76+
77+
return true;
7478
}
7579

7680
template <typename A>
@@ -102,7 +106,9 @@ bool EHHeaderParser<A>::findFDE(A &addressSpace, pint_t pc, pint_t ehHdrStart,
102106
pint_t ehHdrEnd = ehHdrStart + sectionLength;
103107

104108
EHHeaderParser<A>::EHHeaderInfo hdrInfo;
105-
EHHeaderParser<A>::decodeEHHdr(addressSpace, ehHdrStart, ehHdrEnd, hdrInfo);
109+
if (!EHHeaderParser<A>::decodeEHHdr(addressSpace, ehHdrStart, ehHdrEnd,
110+
hdrInfo))
111+
return false;
106112

107113
size_t tableEntrySize = getTableEntrySize(hdrInfo.table_enc);
108114
pint_t tableEntry;

0 commit comments

Comments
 (0)