[lld] r295133 - Handle .eh_frame pointing to discarded section in -r.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 14 16:59:50 PST 2017


Author: rafael
Date: Tue Feb 14 18:59:50 2017
New Revision: 295133

URL: http://llvm.org/viewvc/llvm-project?rev=295133&view=rev
Log:
Handle .eh_frame pointing to discarded section in -r.

This is a really horrible case. If a .eh_frame points to a discarded
section, it is not clear what is the correct thing to do.

It looks like ld.bfd discards the entire .eh_frame content and gold
discards the second relocation, leaving one frame with an fde that
refers to a bogus location. This is similar to what gold does.

Added:
    lld/trunk/test/ELF/relocatable-eh-frame.s
Modified:
    lld/trunk/ELF/InputSection.cpp

Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=295133&r1=295132&r2=295133&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Tue Feb 14 18:59:50 2017
@@ -241,9 +241,20 @@ void InputSection<ELFT>::copyRelocations
       // 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<ELFT> *Section =
+          cast<DefinedRegular<ELFT>>(Body).Section;
+      if (Section == &InputSection<ELFT>::Discarded) {
+        P->setSymbolAndType(0, 0, false);
+        continue;
+      }
+
       if (Config->Rela) {
-        P->r_addend += Body.getVA<ELFT>() -
-                       cast<DefinedRegular<ELFT>>(Body).Section->OutSec->Addr;
+        P->r_addend += Body.getVA<ELFT>() - Section->OutSec->Addr;
       } else if (Config->Relocatable) {
         const uint8_t *BufLoc = RelocatedSection->Data.begin() + Rel.r_offset;
         uint64_t Implicit = Target->getImplicitAddend(BufLoc, Type);

Added: lld/trunk/test/ELF/relocatable-eh-frame.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/relocatable-eh-frame.s?rev=295133&view=auto
==============================================================================
--- lld/trunk/test/ELF/relocatable-eh-frame.s (added)
+++ lld/trunk/test/ELF/relocatable-eh-frame.s Tue Feb 14 18:59:50 2017
@@ -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", at progbits,bar,comdat
+.cfi_startproc
+.cfi_endproc




More information about the llvm-commits mailing list