[lld] r282495 - [ELF] - Fixed linkage error when using -g --gc-sections together.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 27 08:55:30 PDT 2016


Author: grimar
Date: Tue Sep 27 10:55:29 2016
New Revision: 282495

URL: http://llvm.org/viewvc/llvm-project?rev=282495&view=rev
Log:
[ELF] - Fixed linkage error when using -g --gc-sections together.

r282444 introduced new issue, sample program below
fails to link on

assert(Piece.Live);
int main() { return 0; }
clang test.cpp -c -o out.o -g
ld.lld -flavor gnu --gc-sections out.o -o out

Problem is that .debug_info contains relocations to .debug_str:
Section (7) .rela.debug_info {
..

0xC R_X86_64_32 .debug_str 0x0
0x12 R_X86_64_32 .debug_str 0x37
..
But we do not preserve .debug_str in a right way now.

To fix this we should ignore relocations from non-allocatable sections to allocatable
to allow GC work at full power, but still should proccess relocations from non-allocatable to non-allocatable sections
as usual to mark some parts of debug sections alive to keep them so we do not end 
up with such assert when trying to access dead pieces. That looks like what gold/ld do, they do 
not strip .debug_str section from what I saw using sample provided.

Thanks to Evgeny Leviant for suggestions about how to fix this.

Differential revision: https://reviews.llvm.org/D24967

Added:
    lld/trunk/test/ELF/debug-gc.s
Modified:
    lld/trunk/ELF/MarkLive.cpp

Modified: lld/trunk/ELF/MarkLive.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/MarkLive.cpp?rev=282495&r1=282494&r2=282495&view=diff
==============================================================================
--- lld/trunk/ELF/MarkLive.cpp (original)
+++ lld/trunk/ELF/MarkLive.cpp Tue Sep 27 10:55:29 2016
@@ -64,6 +64,11 @@ static typename ELFT::uint getAddend(Inp
   return Rel.r_addend;
 }
 
+template <class ELFT> static bool IsAlloc(InputSectionBase<ELFT> &Sec) {
+  return (&Sec != &InputSection<ELFT>::Discarded) &&
+         (Sec.getSectionHdr()->sh_flags & SHF_ALLOC);
+}
+
 template <class ELFT, class RelT>
 static ResolvedReloc<ELFT> resolveReloc(InputSectionBase<ELFT> &Sec,
                                         RelT &Rel) {
@@ -71,6 +76,8 @@ static ResolvedReloc<ELFT> resolveReloc(
   auto *D = dyn_cast<DefinedRegular<ELFT>>(&B);
   if (!D || !D->Section)
     return {nullptr, 0};
+  if (!IsAlloc<ELFT>(Sec) && IsAlloc<ELFT>(*D->Section))
+    return {nullptr, 0};
   typename ELFT::uint Offset = D->Value;
   if (D->isSection())
     Offset += getAddend(Sec, Rel);
@@ -208,8 +215,7 @@ template <class ELFT> void elf::markLive
       return;
     R.Sec->Live = true;
     if (InputSection<ELFT> *S = dyn_cast<InputSection<ELFT>>(R.Sec))
-      if (S->getSectionHdr()->sh_flags & SHF_ALLOC)
-        Q.push_back(S);
+      Q.push_back(S);
   };
 
   auto MarkSymbol = [&](const SymbolBody *Sym) {

Added: lld/trunk/test/ELF/debug-gc.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/debug-gc.s?rev=282495&view=auto
==============================================================================
--- lld/trunk/test/ELF/debug-gc.s (added)
+++ lld/trunk/test/ELF/debug-gc.s Tue Sep 27 10:55:29 2016
@@ -0,0 +1,24 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.o -o %t1 --gc-sections
+# RUN: llvm-objdump -s %t1 | FileCheck %s
+
+# CHECK:      Contents of section .debug_str:
+# CHECK-NEXT:  0000 41414100 42424200   AAA.BBB.
+# CHECK:      Contents of section .debug_info:
+# CHECK-NEXT:  0000 00000000 04000000
+
+.globl _start
+_start:
+
+.section .debug_str,"MS", at progbits,1
+.Linfo_string0:
+  .asciz "AAA"
+.Linfo_string1:
+  .asciz "BBB"
+.Linfo_string2:
+  .asciz "ÑÑÑ"
+  
+.section  .debug_info,"", at progbits
+  .long .Linfo_string0
+  .long .Linfo_string1




More information about the llvm-commits mailing list