Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -1045,6 +1045,15 @@ if (Args.hasArg(OPT_exclude_libs)) excludeLibs(Args, Files); + // Create ElfHeader early. We need a dummy section in + // addReservedSymbols to mark the created symbols as not absolute. + Out::ElfHeader = make("", 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(); + // Apply version scripts. Symtab->scanVersionScript(); Index: ELF/Writer.h =================================================================== --- ELF/Writer.h +++ ELF/Writer.h @@ -46,6 +46,7 @@ bool HasLMA = false; }; +template void addReservedSymbols(); llvm::StringRef getOutputSectionName(InputSectionBase *S); template uint32_t calcMipsEFlags(); Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -170,7 +170,7 @@ // The linker is expected to define some symbols depending on // the linking result. This function defines such symbols. -template static void addReservedSymbols() { +template 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 @@ -194,13 +194,8 @@ Symtab->addAbsolute("__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(InX::MipsGot) - : cast(InX::Got); ElfSym::GlobalOffsetTable = addOptionalRegular( - "_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 @@ -259,8 +254,6 @@ } InX::ShStrTab = make(".shstrtab", false); - Out::ElfHeader = make("", 0, SHF_ALLOC); - Out::ElfHeader->Size = sizeof(typename ELFT::Ehdr); Out::ProgramHeaders = make("", 0, SHF_ALLOC); Out::ProgramHeaders->Alignment = Config->Wordsize; @@ -406,10 +399,6 @@ if (!Config->Relocatable) combineEhFrameSections(); - // We need to create some reserved symbols such as _end. Create them. - if (!Config->Relocatable) - addReservedSymbols(); - // We want to process linker script commands. When SECTIONS command // is given we let it create sections. Script->processSectionCommands(); @@ -868,6 +857,15 @@ // time any references to these symbols are processed and is equivalent to // defining these symbols explicitly in the linker script. template void Writer::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(InX::MipsGot) + : cast(InX::Got); + ElfSym::GlobalOffsetTable->Section = GotSection; + } + PhdrEntry *Last = nullptr; PhdrEntry *LastRO = nullptr; @@ -1935,3 +1933,8 @@ template void elf::writeResult(); template void elf::writeResult(); template void elf::writeResult(); + +template void elf::addReservedSymbols(); +template void elf::addReservedSymbols(); +template void elf::addReservedSymbols(); +template void elf::addReservedSymbols(); Index: test/ELF/linkerscript/version-linker-symbol.s =================================================================== --- /dev/null +++ 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