Index: lld/trunk/COFF/InputFiles.cpp =================================================================== --- lld/trunk/COFF/InputFiles.cpp +++ lld/trunk/COFF/InputFiles.cpp @@ -19,7 +19,6 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Triple.h" #include "llvm/ADT/Twine.h" -#include "llvm/Bitcode/BitcodeReader.h" #include "llvm/Object/Binary.h" #include "llvm/Object/COFF.h" #include "llvm/Support/COFF.h" @@ -364,10 +363,7 @@ } MachineTypes BitcodeFile::getMachineType() { - Expected ET = getBitcodeTargetTriple(MB); - if (!ET) - return IMAGE_FILE_MACHINE_UNKNOWN; - switch (Triple(*ET).getArch()) { + switch (Triple(Obj->getTargetTriple()).getArch()) { case Triple::x86_64: return AMD64; case Triple::x86: Index: lld/trunk/ELF/InputFiles.h =================================================================== --- lld/trunk/ELF/InputFiles.h +++ lld/trunk/ELF/InputFiles.h @@ -260,19 +260,14 @@ class BitcodeFile : public InputFile { public: - BitcodeFile(MemoryBufferRef M, uint64_t OffsetInArchive); + BitcodeFile(MemoryBufferRef M, StringRef ArchiveName, + uint64_t OffsetInArchive); static bool classof(const InputFile *F) { return F->kind() == BitcodeKind; } template void parse(llvm::DenseSet &ComdatGroups); ArrayRef getSymbols() { return Symbols; } std::unique_ptr Obj; - // If this file is in an archive, the member contains the offset of - // the file in the archive. Otherwise, it's just zero. We store this - // field so that we can pass it to lib/LTO in order to disambiguate - // between objects. - uint64_t OffsetInArchive; - private: std::vector Symbols; }; Index: lld/trunk/ELF/InputFiles.cpp =================================================================== --- lld/trunk/ELF/InputFiles.cpp +++ lld/trunk/ELF/InputFiles.cpp @@ -16,7 +16,6 @@ #include "Symbols.h" #include "SyntheticSections.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/Bitcode/BitcodeReader.h" #include "llvm/CodeGen/Analysis.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/IR/LLVMContext.h" @@ -760,15 +759,13 @@ } } -static ELFKind getBitcodeELFKind(MemoryBufferRef MB) { - Triple T(check(getBitcodeTargetTriple(MB), MB.getBufferIdentifier())); +static ELFKind getBitcodeELFKind(const Triple &T) { if (T.isLittleEndian()) return T.isArch64Bit() ? ELF64LEKind : ELF32LEKind; return T.isArch64Bit() ? ELF64BEKind : ELF32BEKind; } -static uint8_t getBitcodeMachineKind(MemoryBufferRef MB) { - Triple T(check(getBitcodeTargetTriple(MB), MB.getBufferIdentifier())); +static uint8_t getBitcodeMachineKind(StringRef Path, const Triple &T) { switch (T.getArch()) { case Triple::aarch64: return EM_AARCH64; @@ -789,15 +786,32 @@ case Triple::x86_64: return EM_X86_64; default: - fatal(MB.getBufferIdentifier() + - ": could not infer e_machine from bitcode target triple " + T.str()); + fatal(Path + ": could not infer e_machine from bitcode target triple " + + T.str()); } } -BitcodeFile::BitcodeFile(MemoryBufferRef MB, uint64_t OffsetInArchive) - : InputFile(BitcodeKind, MB), OffsetInArchive(OffsetInArchive) { - EKind = getBitcodeELFKind(MB); - EMachine = getBitcodeMachineKind(MB); +BitcodeFile::BitcodeFile(MemoryBufferRef MB, StringRef ArchiveName, + uint64_t OffsetInArchive) + : InputFile(BitcodeKind, MB) { + this->ArchiveName = ArchiveName; + + // Here we pass a new MemoryBufferRef which is identified by ArchiveName + // (the fully resolved path of the archive) + member name + offset of the + // member in the archive. + // ThinLTO uses the MemoryBufferRef identifier to access its internal + // data structures and if two archives define two members with the same name, + // this causes a collision which result in only one of the objects being + // taken into consideration at LTO time (which very likely causes undefined + // symbols later in the link stage). + MemoryBufferRef MBRef(MB.getBuffer(), + Saver.save(ArchiveName + MB.getBufferIdentifier() + + utostr(OffsetInArchive))); + Obj = check(lto::InputFile::create(MBRef), toString(this)); + + Triple T(Obj->getTargetTriple()); + EKind = getBitcodeELFKind(T); + EMachine = getBitcodeMachineKind(MB.getBufferIdentifier(), T); } static uint8_t mapVisibility(GlobalValue::VisibilityTypes GvVisibility) { @@ -845,20 +859,6 @@ template void BitcodeFile::parse(DenseSet &ComdatGroups) { - - // Here we pass a new MemoryBufferRef which is identified by ArchiveName - // (the fully resolved path of the archive) + member name + offset of the - // member in the archive. - // ThinLTO uses the MemoryBufferRef identifier to access its internal - // data structures and if two archives define two members with the same name, - // this causes a collision which result in only one of the objects being - // taken into consideration at LTO time (which very likely causes undefined - // symbols later in the link stage). - MemoryBufferRef MBRef(MB.getBuffer(), - Saver.save(ArchiveName + MB.getBufferIdentifier() + - utostr(OffsetInArchive))); - Obj = check(lto::InputFile::create(MBRef), toString(this)); - std::vector KeptComdats; for (StringRef S : Obj->getComdatTable()) KeptComdats.push_back(ComdatGroups.insert(CachedHashStringRef(S)).second); @@ -931,8 +931,9 @@ InputFile *elf::createObjectFile(MemoryBufferRef MB, StringRef ArchiveName, uint64_t OffsetInArchive) { - InputFile *F = isBitcode(MB) ? make(MB, OffsetInArchive) - : createELFFile(MB); + InputFile *F = isBitcode(MB) + ? make(MB, ArchiveName, OffsetInArchive) + : createELFFile(MB); F->ArchiveName = ArchiveName; return F; } Index: llvm/trunk/include/llvm/LTO/LTO.h =================================================================== --- llvm/trunk/include/llvm/LTO/LTO.h +++ llvm/trunk/include/llvm/LTO/LTO.h @@ -97,7 +97,7 @@ // [begin, end) for each module std::vector> ModuleSymIndices; - StringRef SourceFileName, COFFLinkerOpts; + StringRef TargetTriple, SourceFileName, COFFLinkerOpts; std::vector ComdatTable; public: @@ -138,6 +138,9 @@ /// Returns the path to the InputFile. StringRef getName() const; + /// Returns the input file's target triple. + StringRef getTargetTriple() const { return TargetTriple; } + /// Returns the source file path specified at compile time. StringRef getSourceFileName() const { return SourceFileName; } Index: llvm/trunk/include/llvm/Object/IRSymtab.h =================================================================== --- llvm/trunk/include/llvm/Object/IRSymtab.h +++ llvm/trunk/include/llvm/Object/IRSymtab.h @@ -116,7 +116,7 @@ Range Symbols; Range Uncommons; - Str SourceFileName; + Str TargetTriple, SourceFileName; /// COFF-specific: linker directives. Str COFFLinkerOpts; @@ -227,6 +227,8 @@ /// copied into an irsymtab::Symbol object. symbol_range module_symbols(unsigned I) const; + StringRef getTargetTriple() const { return str(header().TargetTriple); } + /// Returns the source file path specified at compile time. StringRef getSourceFileName() const { return str(header().SourceFileName); } Index: llvm/trunk/lib/LTO/LTO.cpp =================================================================== --- llvm/trunk/lib/LTO/LTO.cpp +++ llvm/trunk/lib/LTO/LTO.cpp @@ -351,6 +351,7 @@ irsymtab::Reader R({Symtab.data(), Symtab.size()}, {File->Strtab.data(), File->Strtab.size()}); + File->TargetTriple = R.getTargetTriple(); File->SourceFileName = R.getSourceFileName(); File->COFFLinkerOpts = R.getCOFFLinkerOpts(); File->ComdatTable = R.getComdatTable(); Index: llvm/trunk/lib/Object/IRSymtab.cpp =================================================================== --- llvm/trunk/lib/Object/IRSymtab.cpp +++ llvm/trunk/lib/Object/IRSymtab.cpp @@ -190,6 +190,7 @@ storage::Header Hdr; assert(!IRMods.empty()); + setStr(Hdr.TargetTriple, IRMods[0]->getTargetTriple()); setStr(Hdr.SourceFileName, IRMods[0]->getSourceFileName()); TT = Triple(IRMods[0]->getTargetTriple()); Index: llvm/trunk/test/LTO/Resolution/X86/symtab-elf.ll =================================================================== --- llvm/trunk/test/LTO/Resolution/X86/symtab-elf.ll +++ llvm/trunk/test/LTO/Resolution/X86/symtab-elf.ll @@ -0,0 +1,15 @@ +; RUN: llvm-as -o %t %s +; RUN: llvm-lto2 dump-symtab %t | FileCheck %s + +; CHECK: target triple: x86_64-unknown-linux-gnu +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +; CHECK-NOT: linker opts: +!0 = !{i32 6, !"Linker Options", !{!{!"/include:foo"}}} +!llvm.module.flags = !{ !0 } + +@g1 = global i32 0 + +; CHECK-NOT: fallback g1 +@g2 = weak alias i32, i32* @g1 Index: llvm/trunk/test/LTO/Resolution/X86/symtab.ll =================================================================== --- llvm/trunk/test/LTO/Resolution/X86/symtab.ll +++ llvm/trunk/test/LTO/Resolution/X86/symtab.ll @@ -1,13 +1,14 @@ ; RUN: llvm-as -o %t %s ; RUN: llvm-lto2 dump-symtab %t | FileCheck %s +; CHECK: target triple: i686-pc-windows-msvc18.0.0 target triple = "i686-pc-windows-msvc18.0.0" target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32" ; CHECK: source filename: src.c source_filename = "src.c" -; CHECK: linker opts (COFF only): /include:foo +; CHECK: linker opts: /include:foo !0 = !{i32 6, !"Linker Options", !{!{!"/include:foo"}}} !llvm.module.flags = !{ !0 } Index: llvm/trunk/tools/llvm-lto2/llvm-lto2.cpp =================================================================== --- llvm/trunk/tools/llvm-lto2/llvm-lto2.cpp +++ llvm/trunk/tools/llvm-lto2/llvm-lto2.cpp @@ -293,8 +293,13 @@ std::unique_ptr Input = check(InputFile::create(MB->getMemBufferRef()), F); + outs() << "target triple: " << Input->getTargetTriple() << '\n'; + Triple TT(Input->getTargetTriple()); + outs() << "source filename: " << Input->getSourceFileName() << '\n'; - outs() << "linker opts (COFF only): " << Input->getCOFFLinkerOpts() << '\n'; + + if (TT.isOSBinFormatCOFF()) + outs() << "linker opts: " << Input->getCOFFLinkerOpts() << '\n'; std::vector ComdatTable = Input->getComdatTable(); for (const InputFile::Symbol &Sym : Input->symbols()) { @@ -328,7 +333,7 @@ if (Comdat != -1) outs() << " comdat " << ComdatTable[Comdat] << '\n'; - if (Sym.isWeak() && Sym.isIndirect()) + if (TT.isOSBinFormatCOFF() && Sym.isWeak() && Sym.isIndirect()) outs() << " fallback " << Sym.getCOFFWeakExternalFallback() << '\n'; }