From owner-svn-src-head@freebsd.org Wed Dec 13 19:03:49 2017 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id E2C8DE83A4B; Wed, 13 Dec 2017 19:03:49 +0000 (UTC) (envelope-from dim@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id B48EE7E526; Wed, 13 Dec 2017 19:03:49 +0000 (UTC) (envelope-from dim@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id vBDJ3mkl020242; Wed, 13 Dec 2017 19:03:48 GMT (envelope-from dim@FreeBSD.org) Received: (from dim@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id vBDJ3m5p020237; Wed, 13 Dec 2017 19:03:48 GMT (envelope-from dim@FreeBSD.org) Message-Id: <201712131903.vBDJ3m5p020237@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: dim set sender to dim@FreeBSD.org using -f From: Dimitry Andric Date: Wed, 13 Dec 2017 19:03:48 +0000 (UTC) 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 X-SVN-Group: head X-SVN-Commit-Author: dim X-SVN-Commit-Paths: head/contrib/llvm/tools/lld/ELF X-SVN-Commit-Revision: 326831 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Dec 2017 19:03:50 -0000 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 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("", 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(); 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 Fn) { SymbolBody &B = Sec.getFile()->getRelocTargetSym(Rel); if (auto *D = dyn_cast(&B)) { - if (!D->Section) + auto *RelSec = dyn_cast_or_null(D->Section); + if (!RelSec) return; typename ELFT::uint Offset = D->Value; if (D->isSection()) Offset += getAddend(Sec, Rel); - Fn({cast(D->Section), Offset}); + Fn({RelSec, Offset}); } else if (auto *U = dyn_cast(&B)) { for (InputSectionBase *Sec : CNamedSections.lookup(U->getName())) Fn({Sec, 0}); @@ -220,7 +221,7 @@ template void elf::markLive() { auto MarkSymbol = [&](const SymbolBody *Sym) { if (auto *D = dyn_cast_or_null(Sym)) - if (auto *IS = cast_or_null(D->Section)) + if (auto *IS = dyn_cast_or_null(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 Writer { (private) void createSyntheticSections(); void copyLocalSymbols(); void addSectionSymbols(); - void addReservedSymbols(); void createSections(); void forEachRelSec(std::function Fn); void sortSections(); @@ -168,10 +167,6 @@ template void Writer::run() { 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 @@ template void Writer::createSynthet 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 @@ template void Writer::addRelIpltSym // 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 @@ template void Writer::addReservedSy 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 @@ static uint16_t getELFType() { // 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::writeResult(); + +template void elf::addReservedSymbols(); +template void elf::addReservedSymbols(); +template void elf::addReservedSymbols(); +template void elf::addReservedSymbols(); 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 void addReservedSymbols(); llvm::StringRef getOutputSectionName(llvm::StringRef Name); template uint32_t getMipsEFlags();