From owner-svn-src-vendor@freebsd.org Tue Feb 5 18:40:07 2019 Return-Path: Delivered-To: svn-src-vendor@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id CF91F14C4DA8; Tue, 5 Feb 2019 18:40:06 +0000 (UTC) (envelope-from dim@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 7837789864; Tue, 5 Feb 2019 18:40:06 +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 mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 6D21C21D1D; Tue, 5 Feb 2019 18:40:02 +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 x15Ie2lk063748; Tue, 5 Feb 2019 18:40:02 GMT (envelope-from dim@FreeBSD.org) Received: (from dim@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x15Idvsc063691; Tue, 5 Feb 2019 18:39:57 GMT (envelope-from dim@FreeBSD.org) Message-Id: <201902051839.x15Idvsc063691@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: dim set sender to dim@FreeBSD.org using -f From: Dimitry Andric Date: Tue, 5 Feb 2019 18:39:57 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org Subject: svn commit: r343802 - in vendor/lld/dist-release_80: COFF ELF MinGW docs test/COFF test/ELF X-SVN-Group: vendor X-SVN-Commit-Author: dim X-SVN-Commit-Paths: in vendor/lld/dist-release_80: COFF ELF MinGW docs test/COFF test/ELF X-SVN-Commit-Revision: 343802 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 7837789864 X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.98 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_MEDIUM(-1.00)[-0.999,0]; NEURAL_HAM_SHORT(-0.98)[-0.978,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US]; NEURAL_HAM_LONG(-1.00)[-0.999,0] X-BeenThere: svn-src-vendor@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for the vendor work area tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 05 Feb 2019 18:40:07 -0000 Author: dim Date: Tue Feb 5 18:39:57 2019 New Revision: 343802 URL: https://svnweb.freebsd.org/changeset/base/343802 Log: Vendor import of lld release_80 branch r353167: https://llvm.org/svn/llvm-project/lld/branches/release_80@353167 Added: vendor/lld/dist-release_80/test/COFF/arm-thumb-thunks-pdb.s vendor/lld/dist-release_80/test/COFF/arm64-thunks.s vendor/lld/dist-release_80/test/ELF/no-discard-this_module.s vendor/lld/dist-release_80/test/ELF/sht-group-empty.test Deleted: vendor/lld/dist-release_80/test/COFF/arm64-branch-range.test Modified: vendor/lld/dist-release_80/COFF/Chunks.cpp vendor/lld/dist-release_80/COFF/Chunks.h vendor/lld/dist-release_80/COFF/DLL.cpp vendor/lld/dist-release_80/COFF/ICF.cpp vendor/lld/dist-release_80/COFF/Writer.cpp vendor/lld/dist-release_80/ELF/ICF.cpp vendor/lld/dist-release_80/ELF/InputFiles.cpp vendor/lld/dist-release_80/ELF/InputFiles.h vendor/lld/dist-release_80/ELF/ScriptParser.cpp vendor/lld/dist-release_80/ELF/SyntheticSections.cpp vendor/lld/dist-release_80/MinGW/Options.td vendor/lld/dist-release_80/docs/ReleaseNotes.rst vendor/lld/dist-release_80/test/COFF/imports.test vendor/lld/dist-release_80/test/ELF/arm-gnu-ifunc.s vendor/lld/dist-release_80/test/ELF/comdat-linkonce.s vendor/lld/dist-release_80/test/ELF/emulation-aarch64.s vendor/lld/dist-release_80/test/ELF/emulation-ppc.s vendor/lld/dist-release_80/test/ELF/emulation-x86.s Modified: vendor/lld/dist-release_80/COFF/Chunks.cpp ============================================================================== --- vendor/lld/dist-release_80/COFF/Chunks.cpp Tue Feb 5 18:39:51 2019 (r343801) +++ vendor/lld/dist-release_80/COFF/Chunks.cpp Tue Feb 5 18:39:57 2019 (r343802) @@ -669,16 +669,36 @@ const uint8_t ArmThunk[] = { 0xe7, 0x44, // L1: add pc, ip }; -size_t RangeExtensionThunk::getSize() const { +size_t RangeExtensionThunkARM::getSize() const { assert(Config->Machine == ARMNT); return sizeof(ArmThunk); } -void RangeExtensionThunk::writeTo(uint8_t *Buf) const { +void RangeExtensionThunkARM::writeTo(uint8_t *Buf) const { assert(Config->Machine == ARMNT); uint64_t Offset = Target->getRVA() - RVA - 12; memcpy(Buf + OutputSectionOff, ArmThunk, sizeof(ArmThunk)); applyMOV32T(Buf + OutputSectionOff, uint32_t(Offset)); +} + +// A position independent ARM64 adrp+add thunk, with a maximum range of +// +/- 4 GB, which is enough for any PE-COFF. +const uint8_t Arm64Thunk[] = { + 0x10, 0x00, 0x00, 0x90, // adrp x16, Dest + 0x10, 0x02, 0x00, 0x91, // add x16, x16, :lo12:Dest + 0x00, 0x02, 0x1f, 0xd6, // br x16 +}; + +size_t RangeExtensionThunkARM64::getSize() const { + assert(Config->Machine == ARM64); + return sizeof(Arm64Thunk); +} + +void RangeExtensionThunkARM64::writeTo(uint8_t *Buf) const { + assert(Config->Machine == ARM64); + memcpy(Buf + OutputSectionOff, Arm64Thunk, sizeof(Arm64Thunk)); + applyArm64Addr(Buf + OutputSectionOff + 0, Target->getRVA(), RVA, 12); + applyArm64Imm(Buf + OutputSectionOff + 4, Target->getRVA() & 0xfff, 0); } void LocalImportChunk::getBaserels(std::vector *Res) { Modified: vendor/lld/dist-release_80/COFF/Chunks.h ============================================================================== --- vendor/lld/dist-release_80/COFF/Chunks.h Tue Feb 5 18:39:51 2019 (r343801) +++ vendor/lld/dist-release_80/COFF/Chunks.h Tue Feb 5 18:39:57 2019 (r343802) @@ -355,9 +355,18 @@ class ImportThunkChunkARM64 : public Chunk { (private) Defined *ImpSymbol; }; -class RangeExtensionThunk : public Chunk { +class RangeExtensionThunkARM : public Chunk { public: - explicit RangeExtensionThunk(Defined *T) : Target(T) {} + explicit RangeExtensionThunkARM(Defined *T) : Target(T) {} + size_t getSize() const override; + void writeTo(uint8_t *Buf) const override; + + Defined *Target; +}; + +class RangeExtensionThunkARM64 : public Chunk { +public: + explicit RangeExtensionThunkARM64(Defined *T) : Target(T) {} size_t getSize() const override; void writeTo(uint8_t *Buf) const override; Modified: vendor/lld/dist-release_80/COFF/DLL.cpp ============================================================================== --- vendor/lld/dist-release_80/COFF/DLL.cpp Tue Feb 5 18:39:51 2019 (r343801) +++ vendor/lld/dist-release_80/COFF/DLL.cpp Tue Feb 5 18:39:57 2019 (r343802) @@ -47,6 +47,7 @@ class HintNameChunk : public Chunk { (public) } void writeTo(uint8_t *Buf) const override { + memset(Buf + OutputSectionOff, 0, getSize()); write16le(Buf + OutputSectionOff, Hint); memcpy(Buf + OutputSectionOff + 2, Name.data(), Name.size()); } @@ -63,7 +64,10 @@ class LookupChunk : public Chunk { (public) size_t getSize() const override { return Config->Wordsize; } void writeTo(uint8_t *Buf) const override { - write32le(Buf + OutputSectionOff, HintName->getRVA()); + if (Config->is64()) + write64le(Buf + OutputSectionOff, HintName->getRVA()); + else + write32le(Buf + OutputSectionOff, HintName->getRVA()); } Chunk *HintName; @@ -99,6 +103,8 @@ class ImportDirectoryChunk : public Chunk { (public) size_t getSize() const override { return sizeof(ImportDirectoryTableEntry); } void writeTo(uint8_t *Buf) const override { + memset(Buf + OutputSectionOff, 0, getSize()); + auto *E = (coff_import_directory_table_entry *)(Buf + OutputSectionOff); E->ImportLookupTableRVA = LookupTab->getRVA(); E->NameRVA = DLLName->getRVA(); @@ -118,6 +124,10 @@ class NullChunk : public Chunk { (public) bool hasData() const override { return false; } size_t getSize() const override { return Size; } + void writeTo(uint8_t *Buf) const override { + memset(Buf + OutputSectionOff, 0, Size); + } + private: size_t Size; }; @@ -160,6 +170,8 @@ class DelayDirectoryChunk : public Chunk { (public) } void writeTo(uint8_t *Buf) const override { + memset(Buf + OutputSectionOff, 0, getSize()); + auto *E = (delay_import_directory_table_entry *)(Buf + OutputSectionOff); E->Attributes = 1; E->Name = DLLName->getRVA(); @@ -392,6 +404,8 @@ class ExportDirectoryChunk : public Chunk { (public) } void writeTo(uint8_t *Buf) const override { + memset(Buf + OutputSectionOff, 0, getSize()); + auto *E = (export_directory_table_entry *)(Buf + OutputSectionOff); E->NameRVA = DLLName->getRVA(); E->OrdinalBase = 0; Modified: vendor/lld/dist-release_80/COFF/ICF.cpp ============================================================================== --- vendor/lld/dist-release_80/COFF/ICF.cpp Tue Feb 5 18:39:51 2019 (r343801) +++ vendor/lld/dist-release_80/COFF/ICF.cpp Tue Feb 5 18:39:57 2019 (r343802) @@ -263,19 +263,21 @@ void ICF::run(ArrayRef Vec) { // Initially, we use hash values to partition sections. parallelForEach(Chunks, [&](SectionChunk *SC) { - SC->Class[1] = xxHash64(SC->getContents()); + SC->Class[0] = xxHash64(SC->getContents()); }); // Combine the hashes of the sections referenced by each section into its // hash. - parallelForEach(Chunks, [&](SectionChunk *SC) { - uint32_t Hash = SC->Class[1]; - for (Symbol *B : SC->symbols()) - if (auto *Sym = dyn_cast_or_null(B)) - Hash ^= Sym->getChunk()->Class[1]; - // Set MSB to 1 to avoid collisions with non-hash classs. - SC->Class[0] = Hash | (1U << 31); - }); + for (unsigned Cnt = 0; Cnt != 2; ++Cnt) { + parallelForEach(Chunks, [&](SectionChunk *SC) { + uint32_t Hash = SC->Class[Cnt % 2]; + for (Symbol *B : SC->symbols()) + if (auto *Sym = dyn_cast_or_null(B)) + Hash += Sym->getChunk()->Class[Cnt % 2]; + // Set MSB to 1 to avoid collisions with non-hash classs. + SC->Class[(Cnt + 1) % 2] = Hash | (1U << 31); + }); + } // From now on, sections in Chunks are ordered so that sections in // the same group are consecutive in the vector. Modified: vendor/lld/dist-release_80/COFF/Writer.cpp ============================================================================== --- vendor/lld/dist-release_80/COFF/Writer.cpp Tue Feb 5 18:39:51 2019 (r343801) +++ vendor/lld/dist-release_80/COFF/Writer.cpp Tue Feb 5 18:39:57 2019 (r343802) @@ -306,16 +306,31 @@ void OutputSection::writeHeaderTo(uint8_t *Buf) { // Check whether the target address S is in range from a relocation // of type RelType at address P. static bool isInRange(uint16_t RelType, uint64_t S, uint64_t P, int Margin) { - assert(Config->Machine == ARMNT); - int64_t Diff = AbsoluteDifference(S, P + 4) + Margin; - switch (RelType) { - case IMAGE_REL_ARM_BRANCH20T: - return isInt<21>(Diff); - case IMAGE_REL_ARM_BRANCH24T: - case IMAGE_REL_ARM_BLX23T: - return isInt<25>(Diff); - default: - return true; + if (Config->Machine == ARMNT) { + int64_t Diff = AbsoluteDifference(S, P + 4) + Margin; + switch (RelType) { + case IMAGE_REL_ARM_BRANCH20T: + return isInt<21>(Diff); + case IMAGE_REL_ARM_BRANCH24T: + case IMAGE_REL_ARM_BLX23T: + return isInt<25>(Diff); + default: + return true; + } + } else if (Config->Machine == ARM64) { + int64_t Diff = AbsoluteDifference(S, P) + Margin; + switch (RelType) { + case IMAGE_REL_ARM64_BRANCH26: + return isInt<28>(Diff); + case IMAGE_REL_ARM64_BRANCH19: + return isInt<21>(Diff); + case IMAGE_REL_ARM64_BRANCH14: + return isInt<16>(Diff); + default: + return true; + } + } else { + llvm_unreachable("Unexpected architecture"); } } @@ -327,7 +342,17 @@ getThunk(DenseMap &LastThunks, De Defined *&LastThunk = LastThunks[Target->getRVA()]; if (LastThunk && isInRange(Type, LastThunk->getRVA(), P, Margin)) return {LastThunk, false}; - RangeExtensionThunk *C = make(Target); + Chunk *C; + switch (Config->Machine) { + case ARMNT: + C = make(Target); + break; + case ARM64: + C = make(Target); + break; + default: + llvm_unreachable("Unexpected architecture"); + } Defined *D = make("", C); LastThunk = D; return {D, true}; @@ -344,14 +369,14 @@ getThunk(DenseMap &LastThunks, De // After adding thunks, we verify that all relocations are in range (with // no extra margin requirements). If this failed, we restart (throwing away // the previously created thunks) and retry with a wider margin. -static bool createThunks(std::vector &Chunks, int Margin) { +static bool createThunks(OutputSection *OS, int Margin) { bool AddressesChanged = false; DenseMap LastThunks; size_t ThunksSize = 0; // Recheck Chunks.size() each iteration, since we can insert more // elements into it. - for (size_t I = 0; I != Chunks.size(); ++I) { - SectionChunk *SC = dyn_cast_or_null(Chunks[I]); + for (size_t I = 0; I != OS->Chunks.size(); ++I) { + SectionChunk *SC = dyn_cast_or_null(OS->Chunks[I]); if (!SC) continue; size_t ThunkInsertionSpot = I + 1; @@ -388,7 +413,8 @@ static bool createThunks(std::vector &Chunks, Chunk *ThunkChunk = Thunk->getChunk(); ThunkChunk->setRVA( ThunkInsertionRVA); // Estimate of where it will be located. - Chunks.insert(Chunks.begin() + ThunkInsertionSpot, ThunkChunk); + ThunkChunk->setOutputSection(OS); + OS->Chunks.insert(OS->Chunks.begin() + ThunkInsertionSpot, ThunkChunk); ThunkInsertionSpot++; ThunksSize += ThunkChunk->getSize(); ThunkInsertionRVA += ThunkChunk->getSize(); @@ -428,7 +454,7 @@ static bool verifyRanges(const std::vector Ch // Assign addresses and add thunks if necessary. void Writer::finalizeAddresses() { assignAddresses(); - if (Config->Machine != ARMNT) + if (Config->Machine != ARMNT && Config->Machine != ARM64) return; size_t OrigNumChunks = 0; @@ -477,7 +503,7 @@ void Writer::finalizeAddresses() { // to avoid things going out of range due to the added thunks. bool AddressesChanged = false; for (OutputSection *Sec : OutputSections) - AddressesChanged |= createThunks(Sec->Chunks, Margin); + AddressesChanged |= createThunks(Sec, Margin); // If the verification above thought we needed thunks, we should have // added some. assert(AddressesChanged); Modified: vendor/lld/dist-release_80/ELF/ICF.cpp ============================================================================== --- vendor/lld/dist-release_80/ELF/ICF.cpp Tue Feb 5 18:39:51 2019 (r343801) +++ vendor/lld/dist-release_80/ELF/ICF.cpp Tue Feb 5 18:39:57 2019 (r343802) @@ -426,16 +426,17 @@ void ICF::forEachClass(llvm::function_ref -static void combineRelocHashes(InputSection *IS, ArrayRef Rels) { - uint32_t Hash = IS->Class[1]; +static void combineRelocHashes(unsigned Cnt, InputSection *IS, + ArrayRef Rels) { + uint32_t Hash = IS->Class[Cnt % 2]; for (RelTy Rel : Rels) { Symbol &S = IS->template getFile()->getRelocTargetSym(Rel); if (auto *D = dyn_cast(&S)) if (auto *RelSec = dyn_cast_or_null(D->Section)) - Hash ^= RelSec->Class[1]; + Hash += RelSec->Class[Cnt % 2]; } // Set MSB to 1 to avoid collisions with non-hash IDs. - IS->Class[0] = Hash | (1U << 31); + IS->Class[(Cnt + 1) % 2] = Hash | (1U << 31); } static void print(const Twine &S) { @@ -453,15 +454,17 @@ template void ICF::run() { // Initially, we use hash values to partition sections. parallelForEach(Sections, [&](InputSection *S) { - S->Class[1] = xxHash64(S->data()); + S->Class[0] = xxHash64(S->data()); }); - parallelForEach(Sections, [&](InputSection *S) { - if (S->AreRelocsRela) - combineRelocHashes(S, S->template relas()); - else - combineRelocHashes(S, S->template rels()); - }); + for (unsigned Cnt = 0; Cnt != 2; ++Cnt) { + parallelForEach(Sections, [&](InputSection *S) { + if (S->AreRelocsRela) + combineRelocHashes(Cnt, S, S->template relas()); + else + combineRelocHashes(Cnt, S, S->template rels()); + }); + } // From now on, sections in Sections vector are ordered so that sections // in the same equivalence class are consecutive in the vector. Modified: vendor/lld/dist-release_80/ELF/InputFiles.cpp ============================================================================== --- vendor/lld/dist-release_80/ELF/InputFiles.cpp Tue Feb 5 18:39:51 2019 (r343801) +++ vendor/lld/dist-release_80/ELF/InputFiles.cpp Tue Feb 5 18:39:57 2019 (r343802) @@ -320,17 +320,6 @@ StringRef ObjFile::getShtGroupSignature(ArrayRef return Signature; } -template -ArrayRef::Elf_Word> -ObjFile::getShtGroupEntries(const Elf_Shdr &Sec) { - const ELFFile &Obj = this->getObj(); - ArrayRef Entries = - CHECK(Obj.template getSectionContentsAsArray(&Sec), this); - if (Entries.empty() || Entries[0] != GRP_COMDAT) - fatal(toString(this) + ": unsupported SHT_GROUP format"); - return Entries.slice(1); -} - template bool ObjFile::shouldMerge(const Elf_Shdr &Sec) { // On a regular link we don't merge sections if -O0 (default is -O1). This // sometimes makes the linker significantly faster, although the output will @@ -440,26 +429,34 @@ void ObjFile::initializeSections( case SHT_GROUP: { // De-duplicate section groups by their signatures. StringRef Signature = getShtGroupSignature(ObjSections, Sec); - bool IsNew = ComdatGroups.insert(CachedHashStringRef(Signature)).second; this->Sections[I] = &InputSection::Discarded; - // We only support GRP_COMDAT type of group. Get the all entries of the - // section here to let getShtGroupEntries to check the type early for us. - ArrayRef Entries = getShtGroupEntries(Sec); - // If it is a new section group, we want to keep group members. - // Group leader sections, which contain indices of group members, are - // discarded because they are useless beyond this point. The only - // exception is the -r option because in order to produce re-linkable - // object files, we want to pass through basically everything. + ArrayRef Entries = + CHECK(Obj.template getSectionContentsAsArray(&Sec), this); + if (Entries.empty()) + fatal(toString(this) + ": empty SHT_GROUP"); + + // The first word of a SHT_GROUP section contains flags. Currently, + // the standard defines only "GRP_COMDAT" flag for the COMDAT group. + // An group with the empty flag doesn't define anything; such sections + // are just skipped. + if (Entries[0] == 0) + continue; + + if (Entries[0] != GRP_COMDAT) + fatal(toString(this) + ": unsupported SHT_GROUP format"); + + bool IsNew = ComdatGroups.insert(CachedHashStringRef(Signature)).second; if (IsNew) { if (Config->Relocatable) this->Sections[I] = createInputSection(Sec); - continue; + continue; } + // Otherwise, discard group members. - for (uint32_t SecIndex : Entries) { + for (uint32_t SecIndex : Entries.slice(1)) { if (SecIndex >= Size) fatal(toString(this) + ": invalid section index in group: " + Twine(SecIndex)); @@ -739,7 +736,8 @@ InputSectionBase *ObjFile::createInputSection(co // sections. Drop those sections to avoid duplicate symbol errors. // FIXME: This is glibc PR20543, we should remove this hack once that has been // fixed for a while. - if (Name.startswith(".gnu.linkonce.")) + if (Name == ".gnu.linkonce.t.__x86.get_pc_thunk.bx" || + Name == ".gnu.linkonce.t.__i686.get_pc_thunk.bx") return &InputSection::Discarded; // If we are creating a new .build-id section, strip existing .build-id Modified: vendor/lld/dist-release_80/ELF/InputFiles.h ============================================================================== --- vendor/lld/dist-release_80/ELF/InputFiles.h Tue Feb 5 18:39:51 2019 (r343801) +++ vendor/lld/dist-release_80/ELF/InputFiles.h Tue Feb 5 18:39:57 2019 (r343802) @@ -175,7 +175,6 @@ template class ObjFile : public ELFFileBa StringRef getShtGroupSignature(ArrayRef Sections, const Elf_Shdr &Sec); - ArrayRef getShtGroupEntries(const Elf_Shdr &Sec); public: static bool classof(const InputFile *F) { return F->kind() == Base::ObjKind; } Modified: vendor/lld/dist-release_80/ELF/ScriptParser.cpp ============================================================================== --- vendor/lld/dist-release_80/ELF/ScriptParser.cpp Tue Feb 5 18:39:51 2019 (r343801) +++ vendor/lld/dist-release_80/ELF/ScriptParser.cpp Tue Feb 5 18:39:57 2019 (r343802) @@ -94,7 +94,6 @@ class ScriptParser final : ScriptLexer { (private) SortSectionPolicy readSortKind(); SymbolAssignment *readProvideHidden(bool Provide, bool Hidden); SymbolAssignment *readAssignment(StringRef Tok); - std::tuple readBfdName(); void readSort(); Expr readAssert(); Expr readConstant(); @@ -385,39 +384,24 @@ void ScriptParser::readOutputArch() { skip(); } -std::tuple ScriptParser::readBfdName() { - StringRef S = unquote(next()); - if (S == "elf32-i386") - return std::make_tuple(ELF32LEKind, EM_386, false); - if (S == "elf32-iamcu") - return std::make_tuple(ELF32LEKind, EM_IAMCU, false); - if (S == "elf32-littlearm") - return std::make_tuple(ELF32LEKind, EM_ARM, false); - if (S == "elf32-x86-64") - return std::make_tuple(ELF32LEKind, EM_X86_64, false); - if (S == "elf64-littleaarch64") - return std::make_tuple(ELF64LEKind, EM_AARCH64, false); - if (S == "elf64-powerpc") - return std::make_tuple(ELF64BEKind, EM_PPC64, false); - if (S == "elf64-powerpcle") - return std::make_tuple(ELF64LEKind, EM_PPC64, false); - if (S == "elf64-x86-64") - return std::make_tuple(ELF64LEKind, EM_X86_64, false); - if (S == "elf32-tradbigmips") - return std::make_tuple(ELF32BEKind, EM_MIPS, false); - if (S == "elf32-ntradbigmips") - return std::make_tuple(ELF32BEKind, EM_MIPS, true); - if (S == "elf32-tradlittlemips") - return std::make_tuple(ELF32LEKind, EM_MIPS, false); - if (S == "elf32-ntradlittlemips") - return std::make_tuple(ELF32LEKind, EM_MIPS, true); - if (S == "elf64-tradbigmips") - return std::make_tuple(ELF64BEKind, EM_MIPS, false); - if (S == "elf64-tradlittlemips") - return std::make_tuple(ELF64LEKind, EM_MIPS, false); - - setError("unknown output format name: " + S); - return std::make_tuple(ELFNoneKind, EM_NONE, false); +static std::pair parseBfdName(StringRef S) { + return StringSwitch>(S) + .Case("elf32-i386", {ELF32LEKind, EM_386}) + .Case("elf32-iamcu", {ELF32LEKind, EM_IAMCU}) + .Case("elf32-littlearm", {ELF32LEKind, EM_ARM}) + .Case("elf32-x86-64", {ELF32LEKind, EM_X86_64}) + .Case("elf64-aarch64", {ELF64LEKind, EM_AARCH64}) + .Case("elf64-littleaarch64", {ELF64LEKind, EM_AARCH64}) + .Case("elf64-powerpc", {ELF64BEKind, EM_PPC64}) + .Case("elf64-powerpcle", {ELF64LEKind, EM_PPC64}) + .Case("elf64-x86-64", {ELF64LEKind, EM_X86_64}) + .Case("elf32-tradbigmips", {ELF32BEKind, EM_MIPS}) + .Case("elf32-ntradbigmips", {ELF32BEKind, EM_MIPS}) + .Case("elf32-tradlittlemips", {ELF32LEKind, EM_MIPS}) + .Case("elf32-ntradlittlemips", {ELF32LEKind, EM_MIPS}) + .Case("elf64-tradbigmips", {ELF64BEKind, EM_MIPS}) + .Case("elf64-tradlittlemips", {ELF64LEKind, EM_MIPS}) + .Default({ELFNoneKind, EM_NONE}); } // Parse OUTPUT_FORMAT(bfdname) or OUTPUT_FORMAT(bfdname, big, little). @@ -425,9 +409,16 @@ std::tuple ScriptParser::read void ScriptParser::readOutputFormat() { expect("("); - std::tuple BfdTuple = readBfdName(); - if (Config->EKind == ELFNoneKind) - std::tie(Config->EKind, Config->EMachine, Config->MipsN32Abi) = BfdTuple; + StringRef Name = unquote(next()); + StringRef S = Name; + if (S.consume_back("-freebsd")) + Config->OSABI = ELFOSABI_FREEBSD; + + std::tie(Config->EKind, Config->EMachine) = parseBfdName(S); + if (Config->EMachine == EM_NONE) + setError("unknown output format name: " + Name); + if (S == "elf32-ntradlittlemips" || S == "elf32-ntradbigmips") + Config->MipsN32Abi = true; if (consume(")")) return; Modified: vendor/lld/dist-release_80/ELF/SyntheticSections.cpp ============================================================================== --- vendor/lld/dist-release_80/ELF/SyntheticSections.cpp Tue Feb 5 18:39:51 2019 (r343801) +++ vendor/lld/dist-release_80/ELF/SyntheticSections.cpp Tue Feb 5 18:39:57 2019 (r343802) @@ -1513,8 +1513,10 @@ void RelocationBaseSection::finalizeContents() { else getParent()->Link = 0; - if (In.RelaIplt == this || In.RelaPlt == this) + if (In.RelaPlt == this) getParent()->Info = In.GotPlt->getParent()->SectionIndex; + if (In.RelaIplt == this) + getParent()->Info = In.IgotPlt->getParent()->SectionIndex; } RelrBaseSection::RelrBaseSection() Modified: vendor/lld/dist-release_80/MinGW/Options.td ============================================================================== --- vendor/lld/dist-release_80/MinGW/Options.td Tue Feb 5 18:39:51 2019 (r343801) +++ vendor/lld/dist-release_80/MinGW/Options.td Tue Feb 5 18:39:57 2019 (r343802) @@ -78,3 +78,9 @@ def version: F<"version">, HelpText<"Display the versi def alias_entry_e: JoinedOrSeparate<["-"], "e">, Alias; def alias_strip_s: Flag<["-"], "s">, Alias; def alias_strip_S: Flag<["-"], "S">, Alias; + +// Ignored options +def: S<"plugin">; +def: J<"plugin=">; +def: S<"plugin-opt">; +def: J<"plugin-opt=">; Modified: vendor/lld/dist-release_80/docs/ReleaseNotes.rst ============================================================================== --- vendor/lld/dist-release_80/docs/ReleaseNotes.rst Tue Feb 5 18:39:51 2019 (r343801) +++ vendor/lld/dist-release_80/docs/ReleaseNotes.rst Tue Feb 5 18:39:57 2019 (r343802) @@ -40,6 +40,9 @@ ELF Improvements * The following flags have been added: ``-z interpose``, ``-z global`` +* lld now uses the ``sigrie`` instruction as a trap instruction for + MIPS targets. + COFF Improvements ----------------- @@ -65,6 +68,13 @@ MinGW Improvements from GCC in setups with DWARF exceptions though, where object files are linked in a different order than with GNU ld, inserting a DWARF exception table terminator too early.) + +* lld now supports COFF embedded directives for linking to nondefault + libraries, just like for the normal COFF target. + +* Actually generate a codeview build id signature, even if not creating a PDB. + Previously, the ``--build-id`` option did not actually generate a build id + unless ``--pdb`` was specified. MachO Improvements ------------------ Added: vendor/lld/dist-release_80/test/COFF/arm-thumb-thunks-pdb.s ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/lld/dist-release_80/test/COFF/arm-thumb-thunks-pdb.s Tue Feb 5 18:39:57 2019 (r343802) @@ -0,0 +1,18 @@ +// REQUIRES: arm +// RUN: llvm-mc -filetype=obj -triple=thumbv7-windows %s -o %t.obj +// RUN: lld-link -entry:main -subsystem:console %t.obj -out:%t.exe -debug -pdb:%t.pdb -verbose 2>&1 | FileCheck %s --check-prefix=VERBOSE + +// VERBOSE: Added 1 thunks with margin {{.*}} in {{.*}} passes + + .syntax unified + .globl main + .globl func1 + .text +main: + bne func1 + bx lr + .section .text$a, "xr" + .space 0x100000 + .section .text$b, "xr" +func1: + bx lr Added: vendor/lld/dist-release_80/test/COFF/arm64-thunks.s ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/lld/dist-release_80/test/COFF/arm64-thunks.s Tue Feb 5 18:39:57 2019 (r343802) @@ -0,0 +1,27 @@ +// REQUIRES: aarch64 +// RUN: llvm-mc -filetype=obj -triple=aarch64-windows %s -o %t.obj +// RUN: lld-link -entry:main -subsystem:console %t.obj -out:%t.exe -verbose 2>&1 | FileCheck -check-prefix=VERBOSE %s +// RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=DISASM %s + +// VERBOSE: Added 1 thunks with margin {{.*}} in 1 passes + + .globl main + .globl func1 + .text +main: + tbz w0, #0, func1 + ret + .section .text$a, "xr" + .space 0x8000 + .section .text$b, "xr" +func1: + ret + +// DISASM: 0000000140001000 .text: +// DISASM: 140001000: 40 00 00 36 tbz w0, #0, #8 <.text+0x8> +// DISASM: 140001004: c0 03 5f d6 ret +// DISASM: 140001008: 50 00 00 90 adrp x16, #32768 +// DISASM: 14000100c: 10 52 00 91 add x16, x16, #20 +// DISASM: 140001010: 00 02 1f d6 br x16 + +// DISASM: 140009014: c0 03 5f d6 ret Modified: vendor/lld/dist-release_80/test/COFF/imports.test ============================================================================== --- vendor/lld/dist-release_80/test/COFF/imports.test Tue Feb 5 18:39:51 2019 (r343801) +++ vendor/lld/dist-release_80/test/COFF/imports.test Tue Feb 5 18:39:57 2019 (r343802) @@ -34,3 +34,16 @@ IMPORT-NEXT: Symbol: ExitProcess (0) IMPORT-NEXT: Symbol: (50) IMPORT-NEXT: Symbol: MessageBoxA (1) IMPORT-NEXT: } + +# RUN: lld-link /out:%t.exe /entry:main /subsystem:console /merge:.rdata=.text \ +# RUN: %p/Inputs/hello64.obj %p/Inputs/std64.lib /include:ExitProcess +# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=MERGE %s + +MERGE: Import { +MERGE-NEXT: Name: std64.dll +MERGE-NEXT: ImportLookupTableRVA: 0x1090 +MERGE-NEXT: ImportAddressTableRVA: 0x10B0 +MERGE-NEXT: Symbol: ExitProcess (0) +MERGE-NEXT: Symbol: (50) +MERGE-NEXT: Symbol: MessageBoxA (1) +MERGE-NEXT: } Modified: vendor/lld/dist-release_80/test/ELF/arm-gnu-ifunc.s ============================================================================== --- vendor/lld/dist-release_80/test/ELF/arm-gnu-ifunc.s Tue Feb 5 18:39:51 2019 (r343801) +++ vendor/lld/dist-release_80/test/ELF/arm-gnu-ifunc.s Tue Feb 5 18:39:57 2019 (r343802) @@ -35,6 +35,8 @@ _start: // CHECK-NEXT: Address: 0x100F4 // CHECK-NEXT: Offset: 0xF4 // CHECK-NEXT: Size: 16 +// CHECK-NEXT: Link: +// CHECK-NEXT: Info: 4 // CHECK: Name: .plt // CHECK-NEXT: Type: SHT_PROGBITS // CHECK-NEXT: Flags [ @@ -44,7 +46,8 @@ _start: // CHECK-NEXT: Address: 0x11020 // CHECK-NEXT: Offset: 0x1020 // CHECK-NEXT: Size: 32 -// CHECK: Name: .got +// CHECK: Index: 4 +// CHECK-NEXT: Name: .got // CHECK-NEXT: Type: SHT_PROGBITS // CHECK-NEXT: Flags [ // CHECK-NEXT: SHF_ALLOC Modified: vendor/lld/dist-release_80/test/ELF/comdat-linkonce.s ============================================================================== --- vendor/lld/dist-release_80/test/ELF/comdat-linkonce.s Tue Feb 5 18:39:51 2019 (r343801) +++ vendor/lld/dist-release_80/test/ELF/comdat-linkonce.s Tue Feb 5 18:39:57 2019 (r343802) @@ -4,7 +4,12 @@ // RUN: ld.lld -shared %t.o %t2.o -o %t // RUN: ld.lld -shared %t2.o %t.o -o %t -.section .gnu.linkonce.t.zed +.section .gnu.linkonce.t.__x86.get_pc_thunk.bx .globl abc abc: +nop + +.section .gnu.linkonce.t.__i686.get_pc_thunk.bx +.globl def +def: nop Modified: vendor/lld/dist-release_80/test/ELF/emulation-aarch64.s ============================================================================== --- vendor/lld/dist-release_80/test/ELF/emulation-aarch64.s Tue Feb 5 18:39:51 2019 (r343801) +++ vendor/lld/dist-release_80/test/ELF/emulation-aarch64.s Tue Feb 5 18:39:57 2019 (r343802) @@ -30,5 +30,28 @@ # AARCH64-NEXT: Flags [ (0x0) # AARCH64-NEXT: ] +# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %taarch64fbsd +# RUN: echo 'OUTPUT_FORMAT(elf64-aarch64-freebsd)' > %taarch64fbsd.script +# RUN: ld.lld %taarch64fbsd.script %taarch64fbsd -o %t2aarch64fbsd +# RUN: llvm-readobj -file-headers %t2aarch64fbsd | FileCheck --check-prefix=AARCH64-FBSD %s +# AARCH64-FBSD: ElfHeader { +# AARCH64-FBSD-NEXT: Ident { +# AARCH64-FBSD-NEXT: Magic: (7F 45 4C 46) +# AARCH64-FBSD-NEXT: Class: 64-bit (0x2) +# AARCH64-FBSD-NEXT: DataEncoding: LittleEndian (0x1) +# AARCH64-FBSD-NEXT: FileVersion: 1 +# AARCH64-FBSD-NEXT: OS/ABI: FreeBSD (0x9) +# AARCH64-FBSD-NEXT: ABIVersion: 0 +# AARCH64-FBSD-NEXT: Unused: (00 00 00 00 00 00 00) +# AARCH64-FBSD-NEXT: } +# AARCH64-FBSD-NEXT: Type: Executable (0x2) +# AARCH64-FBSD-NEXT: Machine: EM_AARCH64 (0xB7) +# AARCH64-FBSD-NEXT: Version: 1 +# AARCH64-FBSD-NEXT: Entry: +# AARCH64-FBSD-NEXT: ProgramHeaderOffset: 0x40 +# AARCH64-FBSD-NEXT: SectionHeaderOffset: +# AARCH64-FBSD-NEXT: Flags [ (0x0) +# AARCH64-FBSD-NEXT: ] + .globl _start _start: Modified: vendor/lld/dist-release_80/test/ELF/emulation-ppc.s ============================================================================== --- vendor/lld/dist-release_80/test/ELF/emulation-ppc.s Tue Feb 5 18:39:51 2019 (r343801) +++ vendor/lld/dist-release_80/test/ELF/emulation-ppc.s Tue Feb 5 18:39:57 2019 (r343802) @@ -35,6 +35,38 @@ # PPC64-NEXT: StringTableSectionIndex: # PPC64-NEXT: } +# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-freebsd %s -o %tppc64fbsd +# RUN: echo 'OUTPUT_FORMAT(elf64-powerpc-freebsd)' > %tppc64fbsd.script +# RUN: ld.lld %tppc64fbsd.script %tppc64fbsd -o %t2ppc64fbsd +# RUN: llvm-readobj -file-headers %t2ppc64fbsd | FileCheck --check-prefix=PPC64-FBSD %s + +# PPC64-FBSD: ElfHeader { +# PPC64-FBSD-NEXT: Ident { +# PPC64-FBSD-NEXT: Magic: (7F 45 4C 46) +# PPC64-FBSD-NEXT: Class: 64-bit (0x2) +# PPC64-FBSD-NEXT: DataEncoding: BigEndian (0x2) +# PPC64-FBSD-NEXT: FileVersion: 1 +# PPC64-FBSD-NEXT: OS/ABI: FreeBSD (0x9) +# PPC64-FBSD-NEXT: ABIVersion: 0 +# PPC64-FBSD-NEXT: Unused: (00 00 00 00 00 00 00) +# PPC64-FBSD-NEXT: } +# PPC64-FBSD-NEXT: Type: Executable (0x2) +# PPC64-FBSD-NEXT: Machine: EM_PPC64 (0x15) +# PPC64-FBSD-NEXT: Version: 1 +# PPC64-FBSD-NEXT: Entry: +# PPC64-FBSD-NEXT: ProgramHeaderOffset: 0x40 +# PPC64-FBSD-NEXT: SectionHeaderOffset: +# PPC64-FBSD-NEXT: Flags [ (0x2) +# PPC64-FBSD-NEXT: 0x2 +# PPC64-FBSD-NEXT: ] +# PPC64-FBSD-NEXT: HeaderSize: 64 +# PPC64-FBSD-NEXT: ProgramHeaderEntrySize: 56 +# PPC64-FBSD-NEXT: ProgramHeaderCount: +# PPC64-FBSD-NEXT: SectionHeaderEntrySize: 64 +# PPC64-FBSD-NEXT: SectionHeaderCount: +# PPC64-FBSD-NEXT: StringTableSectionIndex: +# PPC64-FBSD-NEXT: } + # RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %tppc64le # RUN: ld.lld -m elf64lppc %tppc64le -o %t2ppc64le # RUN: llvm-readobj -file-headers %t2ppc64le | FileCheck --check-prefix=PPC64LE %s Modified: vendor/lld/dist-release_80/test/ELF/emulation-x86.s ============================================================================== --- vendor/lld/dist-release_80/test/ELF/emulation-x86.s Tue Feb 5 18:39:51 2019 (r343801) +++ vendor/lld/dist-release_80/test/ELF/emulation-x86.s Tue Feb 5 18:39:57 2019 (r343802) @@ -7,6 +7,9 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.sysv # RUN: ld.lld -m elf_amd64_fbsd %t.sysv -o %t.freebsd # RUN: llvm-readobj -file-headers %t.freebsd | FileCheck --check-prefix=AMD64 %s +# RUN: echo 'OUTPUT_FORMAT(elf64-x86-64-freebsd)' > %t4x64.script +# RUN: ld.lld %t4x64.script %tx64 -o %t4x64 +# RUN: llvm-readobj -file-headers %t4x64 | FileCheck --check-prefix=AMD64 %s # AMD64: ElfHeader { # AMD64-NEXT: Ident { # AMD64-NEXT: Magic: (7F 45 4C 46) @@ -137,10 +140,13 @@ # X86-NEXT: } # RUN: llvm-mc -filetype=obj -triple=i686-unknown-freebsd %s -o %tx86fbsd -# RUN: ld.lld -m elf_i386_fbsd %tx86fbsd -o %t2x86_fbsd -# RUN: llvm-readobj -file-headers %t2x86_fbsd | FileCheck --check-prefix=X86FBSD %s +# RUN: ld.lld -m elf_i386_fbsd %tx86fbsd -o %t2x86fbsd +# RUN: llvm-readobj -file-headers %t2x86fbsd | FileCheck --check-prefix=X86FBSD %s # RUN: ld.lld %tx86fbsd -o %t3x86fbsd # RUN: llvm-readobj -file-headers %t3x86fbsd | FileCheck --check-prefix=X86FBSD %s +# RUN: echo 'OUTPUT_FORMAT(elf32-i386-freebsd)' > %t4x86fbsd.script +# RUN: ld.lld %t4x86fbsd.script %tx86fbsd -o %t4x86fbsd +# RUN: llvm-readobj -file-headers %t4x86fbsd | FileCheck --check-prefix=X86FBSD %s # X86FBSD: ElfHeader { # X86FBSD-NEXT: Ident { # X86FBSD-NEXT: Magic: (7F 45 4C 46) Added: vendor/lld/dist-release_80/test/ELF/no-discard-this_module.s ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/lld/dist-release_80/test/ELF/no-discard-this_module.s Tue Feb 5 18:39:57 2019 (r343802) @@ -0,0 +1,41 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-linux-gnu -save-temp-labels %s -o %t +// RUN: ld.lld %t -o %t2 +// RUN: llvm-readobj -s -sd -t %t2 | FileCheck %s + +.global _start +_start: + +// This section and symbol is used by Linux kernel modules. Ensure it's not +// accidentally discarded. +.section .gnu.linkonce.this_module: +__this_module: +.byte 0x00 + +// CHECK: Section { +// CHECK: Index: +// CHECK: Name: .gnu.linkonce.this_module +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: ] +// CHECK-NEXT: Address: +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: +// CHECK-NEXT: Link: +// CHECK-NEXT: Info: +// CHECK-NEXT: AddressAlignment: +// CHECK-NEXT: EntrySize: +// CHECK-NEXT: SectionData ( +// CHECK-NEXT: 0000: 00 |.| +// CHECK-NEXT: ) +// CHECK-NEXT: } + +// CHECK: Symbol { +// CHECK: Name: __this_module +// CHECK-NEXT: Value: +// CHECK-NEXT: Size: +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: +// CHECK-NEXT: Section: .gnu.linkonce.this_module: +// CHECK-NEXT: } Added: vendor/lld/dist-release_80/test/ELF/sht-group-empty.test ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/lld/dist-release_80/test/ELF/sht-group-empty.test Tue Feb 5 18:39:57 2019 (r343802) @@ -0,0 +1,55 @@ +# RUN: yaml2obj %s -o %t.o +# RUN: ld.lld %t.o %t.o -o %t -r +# RUN: llvm-readobj -s %t | FileCheck %s + +# CHECK: Name: .text.foo +# CHECK: Name: .rela.text.foo + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .group + Type: SHT_GROUP + Link: .symtab + Info: foo + Members: + - SectionOrType: GRP_COMDAT + - SectionOrType: .text.foo + - SectionOrType: .text.bar + - SectionOrType: .note + - Name: .note + Type: SHT_NOTE + Flags: [ SHF_GROUP ] + - Name: .text.foo + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ] + - Name: .text.bar + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ] + - Name: .rela.text.foo + Type: SHT_RELA + Flags: [ SHF_INFO_LINK, SHF_GROUP ] + Link: .symtab + Info: .text.foo + Relocations: + - Offset: 0x0000000000000000 + Symbol: foo + Type: R_X86_64_64 + - Name: .rela.text.bar + Type: SHT_RELA + Flags: [ SHF_INFO_LINK, SHF_GROUP ] + Link: .symtab + Info: .text.bar + Relocations: + - Offset: 0x0000000000000000 + Symbol: bar + Type: R_X86_64_64 +Symbols: + Global: + - Name: foo + - Name: bar +