diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp --- a/lld/MachO/InputFiles.cpp +++ b/lld/MachO/InputFiles.cpp @@ -1301,17 +1301,37 @@ static uint8_t pointerEncodingToSize(uint8_t enc) { switch (enc & 0xf) { case dwarf::DW_EH_PE_absptr: + case dwarf::DW_EH_PE_signed: return target->wordSize; + case dwarf::DW_EH_PE_udata2: + case dwarf::DW_EH_PE_sdata2: + return 2; case dwarf::DW_EH_PE_sdata4: + case dwarf::DW_EH_PE_udata4: return 4; case dwarf::DW_EH_PE_sdata8: + case dwarf::DW_EH_PE_udata8: // ld64 doesn't actually support sdata8, but this seems simple enough... return 8; + case dwarf::DW_EH_PE_uleb128: + return 128; + default: return 0; }; } +static bool supportedEnc(uint8_t enc) { + switch (enc & 0xf) { + case dwarf::DW_EH_PE_uleb128: + case dwarf::DW_EH_PE_udata2: + case dwarf::DW_EH_PE_sleb128: + case dwarf::DW_EH_PE_sdata2: + return false; + } + return true; +} + static CIE parseCIE(const InputSection *isec, const EhReader &reader, size_t off) { // Handling the full generality of possible DWARF encodings would be a major @@ -1355,9 +1375,15 @@ case 'R': { uint8_t pointerEnc = reader.readByte(&off); cie.funcPtrSize = pointerEncodingToSize(pointerEnc); - if (cie.funcPtrSize == 0 || !(pointerEnc & dwarf::DW_EH_PE_pcrel)) + + // If the encoding is unsupported, we just ignore it (similar to LD64), + // rather than crashing here. + + if (supportedEnc(pointerEnc) && + (cie.funcPtrSize == 0 || !(pointerEnc & dwarf::DW_EH_PE_pcrel))) reader.failOn(off, "unexpected pointer encoding 0x" + Twine::utohexstr(pointerEnc)); + break; } default: diff --git a/lld/test/MachO/eh-frame-uleb128.s b/lld/test/MachO/eh-frame-uleb128.s new file mode 100644 --- /dev/null +++ b/lld/test/MachO/eh-frame-uleb128.s @@ -0,0 +1,37 @@ +# REQUIRES: x86 + +## Test that we correctly ignore unsupported uleb128 DWARF pointer encoding, rather than crashing. +## Similarly to the 3h-frame-sdata4.s test, this test uses hand-roll EH frames. + +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o +# RUN: %lld %t.o -o %t.out +# RUN: llvm-objdump --macho --syms --dwarf=frames + +## There should be no eh_frame contents. + +.globl _main +_main: + retq + +.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support +EHFrame0: + .balign 8 +LCIE: + .set Lset0,LECIE-LSCIE + .long Lset0 +LSCIE: + .long 0 + .byte 1 + .ascii "zR\0" + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 1 + .byte 0x80+16, 1 + + .balign 8 +LECIE: + + .subsections_via_symbols