diff options
| author | Rafael Espindola <rafael.espindola@gmail.com> | 2017-12-11 17:23:28 +0000 |
|---|---|---|
| committer | Rafael Espindola <rafael.espindola@gmail.com> | 2017-12-11 17:23:28 +0000 |
| commit | 63fcc5cccc8aa124858a9a79e275bdc5955bf5c0 (patch) | |
| tree | 4bfa8092c5c021652cfeeaee994cbe899df548a6 | |
| parent | 6d89f407db60a17ba723fba2ec2d72864b7a0177 (diff) | |
| download | bcm5719-llvm-63fcc5cccc8aa124858a9a79e275bdc5955bf5c0.tar.gz bcm5719-llvm-63fcc5cccc8aa124858a9a79e275bdc5955bf5c0.zip | |
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.
llvm-svn: 320390
| -rw-r--r-- | lld/ELF/Driver.cpp | 9 | ||||
| -rw-r--r-- | lld/ELF/Writer.cpp | 29 | ||||
| -rw-r--r-- | lld/ELF/Writer.h | 1 | ||||
| -rw-r--r-- | lld/test/ELF/linkerscript/version-linker-symbol.s | 28 |
4 files changed, 54 insertions, 13 deletions
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 12466e00b46..0e7d02e349e 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -1046,6 +1046,15 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) { 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(); diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index de826412301..531071a4909 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -171,7 +171,7 @@ static Defined *addOptionalRegular(StringRef Name, SectionBase *Sec, // 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 addReservedSymbols() { 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 createSyntheticSections() { } 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>::run() { 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::function<void(InputSectionBase &)> Fn) { // 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>(); diff --git a/lld/ELF/Writer.h b/lld/ELF/Writer.h index 49490baa518..32d3c23047d 100644 --- a/lld/ELF/Writer.h +++ b/lld/ELF/Writer.h @@ -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(); diff --git a/lld/test/ELF/linkerscript/version-linker-symbol.s b/lld/test/ELF/linkerscript/version-linker-symbol.s new file mode 100644 index 00000000000..de30cf5c2ed --- /dev/null +++ b/lld/test/ELF/linkerscript/version-linker-symbol.s @@ -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 |

