Date: Wed, 13 Dec 2017 19:03:48 +0000 (UTC) From: Dimitry Andric <dim@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r326831 - head/contrib/llvm/tools/lld/ELF Message-ID: <201712131903.vBDJ3m5p020237@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: dim Date: Wed Dec 13 19:03:48 2017 New Revision: 326831 URL: https://svnweb.freebsd.org/changeset/base/326831 Log: Pull in r315334 from upstream lld trunk (by Rafael Espindola): Don't create a dummy __tls_get_addr. We just don't need one with the current setup. We only error on undefined references that are used by some relocation. If we managed to relax all uses of __tls_get_addr, no relocation uses it and we don't produce an error. This is less code and fixes the case were we fail to relax. Before we would produce a broken output, but now we produce an error. Pull in r320390 from upstream lld trunk (by Rafael Espindola): 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. Pull in r320412 from upstream lld trunk (by Rafael Espindola): Handle symbols pointing to output sections. Now that gc sections runs after linker defined symbols are added it can see symbols that point to an OutputSection. Should fix a bot failure. Pull in r320431 from upstream lld trunk (by Peter Collingbourne): ELF: Do not follow relocation edges to output sections during GC. This fixes an assertion error introduced by r320390. Differential Revision: https://reviews.llvm.org/D41095 Together these fix handling of reserved symbols, in particular _end, which is needed to make brk(2) and sbrk(2) work correctly. This unbreaks the emacs ports on amd64, and also appears to unbreak most of world on i386. MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D13466 Modified: head/contrib/llvm/tools/lld/ELF/Driver.cpp head/contrib/llvm/tools/lld/ELF/MarkLive.cpp head/contrib/llvm/tools/lld/ELF/Writer.cpp head/contrib/llvm/tools/lld/ELF/Writer.h Modified: head/contrib/llvm/tools/lld/ELF/Driver.cpp ============================================================================== --- head/contrib/llvm/tools/lld/ELF/Driver.cpp Wed Dec 13 18:38:02 2017 (r326830) +++ head/contrib/llvm/tools/lld/ELF/Driver.cpp Wed Dec 13 19:03:48 2017 (r326831) @@ -1010,6 +1010,15 @@ template <class ELFT> void LinkerDriver::link(opt::Inp 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<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: head/contrib/llvm/tools/lld/ELF/MarkLive.cpp ============================================================================== --- head/contrib/llvm/tools/lld/ELF/MarkLive.cpp Wed Dec 13 18:38:02 2017 (r326830) +++ head/contrib/llvm/tools/lld/ELF/MarkLive.cpp Wed Dec 13 19:03:48 2017 (r326831) @@ -73,12 +73,13 @@ static void resolveReloc(InputSectionBase &Sec, RelT & std::function<void(ResolvedReloc)> Fn) { SymbolBody &B = Sec.getFile<ELFT>()->getRelocTargetSym(Rel); if (auto *D = dyn_cast<DefinedRegular>(&B)) { - if (!D->Section) + auto *RelSec = dyn_cast_or_null<InputSectionBase>(D->Section); + if (!RelSec) return; typename ELFT::uint Offset = D->Value; if (D->isSection()) Offset += getAddend<ELFT>(Sec, Rel); - Fn({cast<InputSectionBase>(D->Section), Offset}); + Fn({RelSec, Offset}); } else if (auto *U = dyn_cast<Undefined>(&B)) { for (InputSectionBase *Sec : CNamedSections.lookup(U->getName())) Fn({Sec, 0}); @@ -220,7 +221,7 @@ template <class ELFT> void elf::markLive() { auto MarkSymbol = [&](const SymbolBody *Sym) { if (auto *D = dyn_cast_or_null<DefinedRegular>(Sym)) - if (auto *IS = cast_or_null<InputSectionBase>(D->Section)) + if (auto *IS = dyn_cast_or_null<InputSectionBase>(D->Section)) Enqueue({IS, D->Value}); }; Modified: head/contrib/llvm/tools/lld/ELF/Writer.cpp ============================================================================== --- head/contrib/llvm/tools/lld/ELF/Writer.cpp Wed Dec 13 18:38:02 2017 (r326830) +++ head/contrib/llvm/tools/lld/ELF/Writer.cpp Wed Dec 13 19:03:48 2017 (r326831) @@ -50,7 +50,6 @@ template <class ELFT> class Writer { (private) void createSyntheticSections(); void copyLocalSymbols(); void addSectionSymbols(); - void addReservedSymbols(); void createSections(); void forEachRelSec(std::function<void(InputSectionBase &)> Fn); void sortSections(); @@ -168,10 +167,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(); - // Create output sections. if (Script->Opt.HasSections) { // If linker script contains SECTIONS commands, let it create sections. @@ -286,8 +281,6 @@ template <class ELFT> void Writer<ELFT>::createSynthet Config->IsRela ? ".rela.dyn" : ".rel.dyn", Config->ZCombreloc); InX::ShStrTab = make<StringTableSection>(".shstrtab", false); - Out::ElfHeader = make<OutputSection>("", 0, SHF_ALLOC); - Out::ElfHeader->Size = sizeof(Elf_Ehdr); Out::ProgramHeaders = make<OutputSection>("", 0, SHF_ALLOC); Out::ProgramHeaders->updateAlignment(Config->Wordsize); @@ -796,7 +789,7 @@ template <class ELFT> void Writer<ELFT>::addRelIpltSym // The linker is expected to define some symbols depending on // the linking result. This function defines such symbols. -template <class ELFT> void Writer<ELFT>::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 @@ -820,21 +813,9 @@ template <class ELFT> void Writer<ELFT>::addReservedSy Symtab<ELFT>::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<InputSection>(InX::MipsGot) - : cast<InputSection>(InX::Got); ElfSym::GlobalOffsetTable = addOptionalRegular<ELFT>( - "_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<ELFT>::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 @@ static uint16_t getELFType() { // to each section. This function fixes some predefined // symbol values that depend on section address and size. template <class ELFT> void Writer<ELFT>::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<InputSection>(InX::MipsGot) + : cast<InputSection>(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<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: head/contrib/llvm/tools/lld/ELF/Writer.h ============================================================================== --- head/contrib/llvm/tools/lld/ELF/Writer.h Wed Dec 13 18:38:02 2017 (r326830) +++ head/contrib/llvm/tools/lld/ELF/Writer.h Wed Dec 13 19:03:48 2017 (r326831) @@ -47,6 +47,7 @@ struct PhdrEntry { bool HasLMA = false; }; +template <class ELFT> void addReservedSymbols(); llvm::StringRef getOutputSectionName(llvm::StringRef Name); template <class ELFT> uint32_t getMipsEFlags();
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201712131903.vBDJ3m5p020237>