[lld] r293385 - Fix a few symbols that are not actually ABS.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Sat Jan 28 09:48:22 PST 2017


Author: rafael
Date: Sat Jan 28 11:48:21 2017
New Revision: 293385

URL: http://llvm.org/viewvc/llvm-project?rev=293385&view=rev
Log:
Fix a few symbols that are not actually ABS.

The symbols _end, end, _etext, etext, _edata, edata and __ehdr_start
refer to positions in the file and are therefore not absolute. Making
them absolute was on unfortunate cargo cult of what bfd was doing.

Changing the symbols allows for pc relocations to them to be resolved,
which should fix the wine build.

Added:
    lld/trunk/test/ELF/end-abs.s
Modified:
    lld/trunk/ELF/Symbols.h
    lld/trunk/ELF/Writer.cpp
    lld/trunk/test/ELF/edata-etext.s
    lld/trunk/test/ELF/ehdr_start.s

Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=293385&r1=293384&r2=293385&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Sat Jan 28 11:48:21 2017
@@ -352,19 +352,19 @@ public:
 // DefinedRegular symbols.
 template <class ELFT> struct ElfSym {
   // The content for __ehdr_start symbol.
-  static DefinedRegular<ELFT> *EhdrStart;
+  static DefinedSynthetic *EhdrStart;
 
   // The content for _etext and etext symbols.
-  static DefinedRegular<ELFT> *Etext;
-  static DefinedRegular<ELFT> *Etext2;
+  static DefinedSynthetic *Etext;
+  static DefinedSynthetic *Etext2;
 
   // The content for _edata and edata symbols.
-  static DefinedRegular<ELFT> *Edata;
-  static DefinedRegular<ELFT> *Edata2;
+  static DefinedSynthetic *Edata;
+  static DefinedSynthetic *Edata2;
 
   // The content for _end and end symbols.
-  static DefinedRegular<ELFT> *End;
-  static DefinedRegular<ELFT> *End2;
+  static DefinedSynthetic *End;
+  static DefinedSynthetic *End2;
 
   // The content for _gp_disp/__gnu_local_gp symbols for MIPS target.
   static DefinedRegular<ELFT> *MipsGpDisp;
@@ -372,13 +372,13 @@ template <class ELFT> struct ElfSym {
   static DefinedRegular<ELFT> *MipsGp;
 };
 
-template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::EhdrStart;
-template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::Etext;
-template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::Etext2;
-template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::Edata;
-template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::Edata2;
-template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::End;
-template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::End2;
+template <class ELFT> DefinedSynthetic *ElfSym<ELFT>::EhdrStart;
+template <class ELFT> DefinedSynthetic *ElfSym<ELFT>::Etext;
+template <class ELFT> DefinedSynthetic *ElfSym<ELFT>::Etext2;
+template <class ELFT> DefinedSynthetic *ElfSym<ELFT>::Edata;
+template <class ELFT> DefinedSynthetic *ElfSym<ELFT>::Edata2;
+template <class ELFT> DefinedSynthetic *ElfSym<ELFT>::End;
+template <class ELFT> DefinedSynthetic *ElfSym<ELFT>::End2;
 template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::MipsGpDisp;
 template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::MipsLocalGp;
 template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::MipsGp;

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=293385&r1=293384&r2=293385&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Sat Jan 28 11:48:21 2017
@@ -68,7 +68,7 @@ private:
   void setPhdrs();
   void fixHeaders();
   void fixSectionAlignments();
-  void fixAbsoluteSymbols();
+  void fixPredefinedSymbols();
   void openFile();
   void writeHeader();
   void writeSections();
@@ -208,7 +208,7 @@ template <class ELFT> void Writer<ELFT>:
       assignFileOffsetsBinary();
 
     setPhdrs();
-    fixAbsoluteSymbols();
+    fixPredefinedSymbols();
   }
 
   // It does not make sense try to open the file if we have error already.
@@ -648,12 +648,14 @@ void PhdrEntry::add(OutputSectionBase *S
 }
 
 template <class ELFT>
-static void addOptionalSynthetic(StringRef Name, OutputSectionBase *Sec,
-                                 typename ELFT::uint Val,
-                                 uint8_t StOther = STV_HIDDEN) {
+static DefinedSynthetic *
+addOptionalSynthetic(StringRef Name, OutputSectionBase *Sec,
+                     typename ELFT::uint Val, uint8_t StOther = STV_HIDDEN) {
   if (SymbolBody *S = Symtab<ELFT>::X->find(Name))
     if (!S->isInCurrentDSO())
-      Symtab<ELFT>::X->addSynthetic(Name, Sec, Val, StOther);
+      return cast<DefinedSynthetic>(
+          Symtab<ELFT>::X->addSynthetic(Name, Sec, Val, StOther)->body());
+  return nullptr;
 }
 
 template <class ELFT>
@@ -750,14 +752,16 @@ template <class ELFT> void Writer<ELFT>:
   if (ScriptConfig->HasSections)
     return;
 
-  ElfSym<ELFT>::EhdrStart = Symtab<ELFT>::X->addIgnored("__ehdr_start");
+  // __ehdr_start is the location of program headers.
+  ElfSym<ELFT>::EhdrStart =
+      addOptionalSynthetic<ELFT>("__ehdr_start", Out<ELFT>::ProgramHeaders, 0);
 
-  auto Define = [this](StringRef S, DefinedRegular<ELFT> *&Sym1,
-                       DefinedRegular<ELFT> *&Sym2) {
-    Sym1 = Symtab<ELFT>::X->addIgnored(S, STV_DEFAULT);
+  auto Define = [this](StringRef S, DefinedSynthetic *&Sym1,
+                       DefinedSynthetic *&Sym2) {
+    Sym1 = addOptionalSynthetic<ELFT>(S, nullptr, 0, STV_DEFAULT);
     assert(S.startswith("_"));
     S = S.substr(1);
-    Sym2 = Symtab<ELFT>::X->addIgnored(S, STV_DEFAULT);
+    Sym2 = addOptionalSynthetic<ELFT>(S, nullptr, 0, STV_DEFAULT);
   };
 
   Define("_end", ElfSym<ELFT>::End, ElfSym<ELFT>::End2);
@@ -1056,6 +1060,11 @@ template <class ELFT> void Writer<ELFT>:
 
   sortSections();
 
+  // This is a bit of a hack. A value of 0 means undef, so we set it
+  // to 1 t make __ehdr_start defined. The section number is not
+  // particularly relevant.
+  Out<ELFT>::ProgramHeaders->SectionIndex = 1;
+
   unsigned I = 1;
   for (OutputSectionBase *Sec : OutputSections) {
     Sec->SectionIndex = I++;
@@ -1548,34 +1557,44 @@ static uint16_t getELFType() {
 }
 
 // This function is called after we have assigned address and size
-// to each section. This function fixes some predefined absolute
+// to each section. This function fixes some predefined
 // symbol values that depend on section address and size.
-template <class ELFT> void Writer<ELFT>::fixAbsoluteSymbols() {
-  // __ehdr_start is the location of program headers.
-  if (ElfSym<ELFT>::EhdrStart)
-    ElfSym<ELFT>::EhdrStart->Value = Out<ELFT>::ProgramHeaders->Addr;
-
-  auto Set = [](DefinedRegular<ELFT> *S1, DefinedRegular<ELFT> *S2, uintX_t V) {
-    if (S1)
-      S1->Value = V;
-    if (S2)
-      S2->Value = V;
+template <class ELFT> void Writer<ELFT>::fixPredefinedSymbols() {
+  auto Set = [](DefinedSynthetic *S1, DefinedSynthetic *S2,
+                OutputSectionBase *Sec, uint64_t Value) {
+    if (S1) {
+      S1->Section = Sec;
+      S1->Value = Value;
+    }
+    if (S2) {
+      S2->Section = Sec;
+      S2->Value = Value;
+    }
   };
 
   // _etext is the first location after the last read-only loadable segment.
   // _edata is the first location after the last read-write loadable segment.
   // _end is the first location after the uninitialized data region.
+  PhdrEntry *Last = nullptr;
+  PhdrEntry *LastRO = nullptr;
+  PhdrEntry *LastRW = nullptr;
   for (PhdrEntry &P : Phdrs) {
     if (P.p_type != PT_LOAD)
       continue;
-    Set(ElfSym<ELFT>::End, ElfSym<ELFT>::End2, P.p_vaddr + P.p_memsz);
-
-    uintX_t Val = P.p_vaddr + P.p_filesz;
+    Last = &P;
     if (P.p_flags & PF_W)
-      Set(ElfSym<ELFT>::Edata, ElfSym<ELFT>::Edata2, Val);
+      LastRW = &P;
     else
-      Set(ElfSym<ELFT>::Etext, ElfSym<ELFT>::Etext2, Val);
+      LastRO = &P;
   }
+  if (Last)
+    Set(ElfSym<ELFT>::End, ElfSym<ELFT>::End2, Last->First, Last->p_memsz);
+  if (LastRO)
+    Set(ElfSym<ELFT>::Etext, ElfSym<ELFT>::Etext2, LastRO->First,
+        LastRO->p_filesz);
+  if (LastRW)
+    Set(ElfSym<ELFT>::Edata, ElfSym<ELFT>::Edata2, LastRW->First,
+        LastRW->p_filesz);
 
   // Setup MIPS _gp_disp/__gnu_local_gp symbols which should
   // be equal to the _gp symbol's value.

Modified: lld/trunk/test/ELF/edata-etext.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/edata-etext.s?rev=293385&r1=293384&r2=293385&view=diff
==============================================================================
--- lld/trunk/test/ELF/edata-etext.s (original)
+++ lld/trunk/test/ELF/edata-etext.s Sat Jan 28 11:48:21 2017
@@ -18,9 +18,9 @@
 # CHECK-NEXT:    3 .bss          00000006 0000000000202004 BSS
 # CHECK:      SYMBOL TABLE:
 # CHECK-NEXT:  0000000000000000         *UND* 00000000
-# CHECK-NEXT:  0000000000202002         *ABS* 00000000 _edata
-# CHECK-NEXT:  000000000020200a         *ABS* 00000000 _end
-# CHECK-NEXT:  0000000000201001         *ABS* 00000000 _etext
+# CHECK-NEXT:  0000000000202002         .data 00000000 _edata
+# CHECK-NEXT:  000000000020200a         .data 00000000 _end
+# CHECK-NEXT:  0000000000201001         .text 00000000 _etext
 # CHECK-NEXT:  0000000000201000         .text 00000000 _start
 
 # RUN: ld.lld -r %t.o -o %t2

Modified: lld/trunk/test/ELF/ehdr_start.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/ehdr_start.s?rev=293385&r1=293384&r2=293385&view=diff
==============================================================================
--- lld/trunk/test/ELF/ehdr_start.s (original)
+++ lld/trunk/test/ELF/ehdr_start.s Sat Jan 28 11:48:21 2017
@@ -3,7 +3,7 @@
 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
 # RUN: ld.lld %t.o -o %t
 # RUN: llvm-objdump -t %t | FileCheck %s
-# CHECK: 0000000000200040 *ABS* 00000000 .hidden __ehdr_start
+# CHECK: 0000000000200040 .text 00000000 .hidden __ehdr_start
 
 .text
 .global _start, __ehdr_start

Added: lld/trunk/test/ELF/end-abs.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/end-abs.s?rev=293385&view=auto
==============================================================================
--- lld/trunk/test/ELF/end-abs.s (added)
+++ lld/trunk/test/ELF/end-abs.s Sat Jan 28 11:48:21 2017
@@ -0,0 +1,11 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld %t.o -o %t -pie
+# RUN: llvm-readobj -r %t | FileCheck %s
+
+# CHECK:      Relocations [
+# CHECK-NEXT: ]
+
+.global _start
+_start:
+.long _end - .




More information about the llvm-commits mailing list