[lld] r320390 - Create reserved symbols early so they can be versioned.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 11 09:23:28 PST 2017


Author: rafael
Date: Mon Dec 11 09:23:28 2017
New Revision: 320390

URL: http://llvm.org/viewvc/llvm-project?rev=320390&view=rev
Log:
Create reserved symbols early so they can be versioned.

This fixes pr35570.

We were creating these symbols after parsing version scripts, so they
could not be versioned.

We cannot move the version script parsing later because we need it for
lto.

One option is to move both addReservedSymbols and
createSyntheticSections earlier. The disadvantage is that some
sections created by createSyntheticSections replace other input
sections. For example, gdb index replaces .debug_gnu_pubnames, so it
wants to run after gc sections so that it can set S->Live to false.

What this patch does instead is to move just the ElfHeader creation
early.

Added:
    lld/trunk/test/ELF/linkerscript/version-linker-symbol.s
Modified:
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/Writer.cpp
    lld/trunk/ELF/Writer.h

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=320390&r1=320389&r2=320390&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Mon Dec 11 09:23:28 2017
@@ -1046,6 +1046,15 @@ template <class ELFT> void LinkerDriver:
   if (Args.hasArg(OPT_exclude_libs))
     excludeLibs<ELFT>(Args, Files);
 
+  // Create ElfHeader early. We need a dummy section in
+  // addReservedSymbols to mark the created symbols as not absolute.
+  Out::ElfHeader = make<OutputSection>("", 0, SHF_ALLOC);
+  Out::ElfHeader->Size = sizeof(typename ELFT::Ehdr);
+
+  // We need to create some reserved symbols such as _end. Create them.
+  if (!Config->Relocatable)
+    addReservedSymbols<ELFT>();
+
   // Apply version scripts.
   Symtab->scanVersionScript();
 

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=320390&r1=320389&r2=320390&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Mon Dec 11 09:23:28 2017
@@ -171,7 +171,7 @@ static Defined *addOptionalRegular(Strin
 
 // The linker is expected to define some symbols depending on
 // the linking result. This function defines such symbols.
-template <class ELFT> static void addReservedSymbols() {
+template <class ELFT> void elf::addReservedSymbols() {
   if (Config->EMachine == EM_MIPS) {
     // Define _gp for MIPS. st_value of _gp symbol will be updated by Writer
     // so that it points to an absolute address which by default is relative
@@ -195,13 +195,8 @@ template <class ELFT> static void addRes
           Symtab->addAbsolute<ELFT>("__gnu_local_gp", STV_HIDDEN, STB_GLOBAL);
   }
 
-  // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to
-  // be at some offset from the base of the .got section, usually 0 or the end
-  // of the .got
-  InputSection *GotSection = InX::MipsGot ? cast<InputSection>(InX::MipsGot)
-                                          : cast<InputSection>(InX::Got);
   ElfSym::GlobalOffsetTable = addOptionalRegular<ELFT>(
-      "_GLOBAL_OFFSET_TABLE_", GotSection, Target->GotBaseSymOff);
+      "_GLOBAL_OFFSET_TABLE_", Out::ElfHeader, Target->GotBaseSymOff);
 
   // __ehdr_start is the location of ELF file headers. Note that we define
   // this symbol unconditionally even when using a linker script, which
@@ -260,8 +255,6 @@ template <class ELFT> static void create
   }
   InX::ShStrTab = make<StringTableSection>(".shstrtab", false);
 
-  Out::ElfHeader = make<OutputSection>("", 0, SHF_ALLOC);
-  Out::ElfHeader->Size = sizeof(typename ELFT::Ehdr);
   Out::ProgramHeaders = make<OutputSection>("", 0, SHF_ALLOC);
   Out::ProgramHeaders->Alignment = Config->Wordsize;
 
@@ -407,10 +400,6 @@ template <class ELFT> void Writer<ELFT>:
   if (!Config->Relocatable)
     combineEhFrameSections<ELFT>();
 
-  // We need to create some reserved symbols such as _end. Create them.
-  if (!Config->Relocatable)
-    addReservedSymbols<ELFT>();
-
   // We want to process linker script commands. When SECTIONS command
   // is given we let it create sections.
   Script->processSectionCommands();
@@ -869,6 +858,15 @@ void Writer<ELFT>::forEachRelSec(std::fu
 // time any references to these symbols are processed and is equivalent to
 // defining these symbols explicitly in the linker script.
 template <class ELFT> void Writer<ELFT>::setReservedSymbolSections() {
+  if (ElfSym::GlobalOffsetTable) {
+    // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to
+    // be at some offset from the base of the .got section, usually 0 or the end
+    // of the .got
+    InputSection *GotSection = InX::MipsGot ? cast<InputSection>(InX::MipsGot)
+                                            : cast<InputSection>(InX::Got);
+    ElfSym::GlobalOffsetTable->Section = GotSection;
+  }
+
   PhdrEntry *Last = nullptr;
   PhdrEntry *LastRO = nullptr;
 
@@ -1935,3 +1933,8 @@ template void elf::writeResult<ELF32LE>(
 template void elf::writeResult<ELF32BE>();
 template void elf::writeResult<ELF64LE>();
 template void elf::writeResult<ELF64BE>();
+
+template void elf::addReservedSymbols<ELF32LE>();
+template void elf::addReservedSymbols<ELF32BE>();
+template void elf::addReservedSymbols<ELF64LE>();
+template void elf::addReservedSymbols<ELF64BE>();

Modified: lld/trunk/ELF/Writer.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.h?rev=320390&r1=320389&r2=320390&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.h (original)
+++ lld/trunk/ELF/Writer.h Mon Dec 11 09:23:28 2017
@@ -46,6 +46,7 @@ struct PhdrEntry {
   bool HasLMA = false;
 };
 
+template <class ELFT> void addReservedSymbols();
 llvm::StringRef getOutputSectionName(InputSectionBase *S);
 
 template <class ELFT> uint32_t calcMipsEFlags();

Added: lld/trunk/test/ELF/linkerscript/version-linker-symbol.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/version-linker-symbol.s?rev=320390&view=auto
==============================================================================
--- lld/trunk/test/ELF/linkerscript/version-linker-symbol.s (added)
+++ lld/trunk/test/ELF/linkerscript/version-linker-symbol.s Mon Dec 11 09:23:28 2017
@@ -0,0 +1,28 @@
+# REQUIRES: x86
+
+# RUN: echo "VER1 { global: _end; foo ; local: * ; } ;" > %t.script
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
+# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s
+
+# CHECK:      Name: _end@@VER1
+# CHECK-NEXT: Value: 0
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Global
+# CHECK-NEXT: Type: None
+# CHECK-NEXT: Other: 0
+# CHECK-NEXT: Section: .dynamic
+
+# CHECK:      Name: foo@@VER1
+# CHECK-NEXT: Value: 0
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Global
+# CHECK-NEXT: Type: None
+# CHECK-NEXT: Other: 0
+# CHECK-NEXT: Section: .text
+
+.global foo
+foo:
+        .data
+        .quad _end
+        .quad foo




More information about the llvm-commits mailing list