Index: contrib/llvm/tools/lld/ELF/Driver.cpp =================================================================== --- contrib/llvm/tools/lld/ELF/Driver.cpp +++ contrib/llvm/tools/lld/ELF/Driver.cpp @@ -1010,6 +1010,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: contrib/llvm/tools/lld/ELF/Writer.h =================================================================== --- contrib/llvm/tools/lld/ELF/Writer.h +++ contrib/llvm/tools/lld/ELF/Writer.h @@ -47,6 +47,7 @@ bool HasLMA = false; }; +template void addReservedSymbols(); llvm::StringRef getOutputSectionName(llvm::StringRef Name); template uint32_t getMipsEFlags(); Index: contrib/llvm/tools/lld/ELF/Writer.cpp =================================================================== --- contrib/llvm/tools/lld/ELF/Writer.cpp +++ contrib/llvm/tools/lld/ELF/Writer.cpp @@ -50,7 +50,6 @@ void createSyntheticSections(); void copyLocalSymbols(); void addSectionSymbols(); - void addReservedSymbols(); void createSections(); void forEachRelSec(std::function Fn); void sortSections(); @@ -168,10 +167,6 @@ if (!Config->Relocatable) combineEhFrameSections(); - // We need to create some reserved symbols such as _end. Create them. - if (!Config->Relocatable) - addReservedSymbols(); - // Create output sections. if (Script->Opt.HasSections) { // If linker script contains SECTIONS commands, let it create sections. @@ -286,8 +281,6 @@ Config->IsRela ? ".rela.dyn" : ".rel.dyn", Config->ZCombreloc); InX::ShStrTab = make(".shstrtab", false); - Out::ElfHeader = make("", 0, SHF_ALLOC); - Out::ElfHeader->Size = sizeof(Elf_Ehdr); Out::ProgramHeaders = make("", 0, SHF_ALLOC); Out::ProgramHeaders->updateAlignment(Config->Wordsize); @@ -796,7 +789,7 @@ // The linker is expected to define some symbols depending on // the linking result. This function defines such symbols. -template void Writer::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 @@ -820,21 +813,9 @@ Symtab::X->addAbsolute("__gnu_local_gp", STV_HIDDEN, STB_LOCAL); } - // 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); - // __tls_get_addr is defined by the dynamic linker for dynamic ELFs. For - // static linking the linker is required to optimize away any references to - // __tls_get_addr, so it's not defined anywhere. Create a hidden definition - // to avoid the undefined symbol error. - if (!InX::DynSymTab) - Symtab::X->addIgnored("__tls_get_addr"); - // __ehdr_start is the location of ELF file headers. Note that we define // this symbol unconditionally even when using a linker script, which // differs from the behavior implemented by GNU linker which only define @@ -1721,6 +1702,15 @@ // to each section. This function fixes some predefined // symbol values that depend on section address and size. template void Writer::fixPredefinedSymbols() { + 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; + } + // _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. @@ -1911,3 +1901,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();