Index: ELF/InputSection.cpp =================================================================== --- ELF/InputSection.cpp +++ ELF/InputSection.cpp @@ -241,9 +241,20 @@ // section. This means we have to update the addend. That is // trivial for Elf_Rela, but for Elf_Rel we have to write to the // section data. We do that by adding to the Relocation vector. + + // .eh_frame is horribly special and can reference discarded sections. To + // avoid having to parse and recreate .eh_frame, we just replace any + // relocation in it pointing to discarded sections with R_*_NONE, which + // hopefully creates a frame that is ignored at runtime. + InputSectionBase *Section = + cast>(Body).Section; + if (Section == &InputSection::Discarded) { + P->setSymbolAndType(0, 0, false); + continue; + } + if (Config->Rela) { - P->r_addend += Body.getVA() - - cast>(Body).Section->OutSec->Addr; + P->r_addend += Body.getVA() - Section->OutSec->Addr; } else if (Config->Relocatable) { const uint8_t *BufLoc = RelocatedSection->Data.begin() + Rel.r_offset; uint64_t Implicit = Target->getImplicitAddend(BufLoc, Type); Index: test/ELF/relocatable-eh-frame.s =================================================================== --- /dev/null +++ test/ELF/relocatable-eh-frame.s @@ -0,0 +1,15 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: ld.lld -r %t.o %t.o -o %t +# RUN: llvm-readobj -r %t | FileCheck %s + +# CHECK: Relocations [ +# CHECK-NEXT: Section ({{.*}}) .rela.eh_frame { +# CHECK-NEXT: 0x20 R_X86_64_PC32 .foo 0x0 +# CHECK-NEXT: 0x0 R_X86_64_NONE - 0x0 +# CHECK-NEXT: } +# CHECK-NEXT: ] + +.section .foo,"aG",@progbits,bar,comdat +.cfi_startproc +.cfi_endproc