Index: lld/ELF/Error.h =================================================================== --- lld/ELF/Error.h +++ lld/ELF/Error.h @@ -12,6 +12,8 @@ #include "lld/Core/LLVM.h" +#include "llvm/Support/Error.h" + namespace lld { namespace elf { @@ -31,6 +33,13 @@ LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg); LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg, const Twine &Prefix); +inline void check(Error E) { + handleAllErrors(std::move(E), [&](llvm::ErrorInfoBase &EIB) { + error(EIB.message().c_str()); + return Error::success(); + }); +} + template T check(ErrorOr E) { if (auto EC = E.getError()) fatal(EC.message()); Index: lld/ELF/InputFiles.h =================================================================== --- lld/ELF/InputFiles.h +++ lld/ELF/InputFiles.h @@ -27,6 +27,12 @@ #include +namespace llvm { +namespace lto { +class InputFile; +} +} + namespace lld { namespace elf { @@ -247,17 +253,12 @@ template void parse(llvm::DenseSet &ComdatGroups); ArrayRef getSymbols() { return Symbols; } - static bool shouldSkip(uint32_t Flags); - std::unique_ptr Obj; + std::unique_ptr Obj; private: std::vector Symbols; llvm::BumpPtrAllocator Alloc; llvm::StringSaver Saver{Alloc}; - template - Symbol *createSymbol(const llvm::DenseSet &KeptComdats, - const llvm::object::IRObjectFile &Obj, - const llvm::object::BasicSymbolRef &Sym); }; // .so file. Index: lld/ELF/InputFiles.cpp =================================================================== --- lld/ELF/InputFiles.cpp +++ lld/ELF/InputFiles.cpp @@ -9,10 +9,10 @@ #include "InputFiles.h" #include "Driver.h" +#include "ELFCreator.h" #include "Error.h" #include "InputSection.h" #include "LinkerScript.h" -#include "ELFCreator.h" #include "SymbolTable.h" #include "Symbols.h" #include "llvm/ADT/STLExtras.h" @@ -20,6 +20,7 @@ #include "llvm/CodeGen/Analysis.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" +#include "llvm/LTO/LTO.h" #include "llvm/MC/StringTableBuilder.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" @@ -392,13 +393,12 @@ case SHN_UNDEF: return elf::Symtab::X ->addUndefined(Name, Binding, Sym->st_other, Sym->getType(), - /*CanOmitFromDynSym*/ false, /*HasUnnamedAddr*/ false, - this) + /*CanOmitFromDynSym*/ false, this) ->body(); case SHN_COMMON: return elf::Symtab::X ->addCommon(Name, Sym->st_size, Sym->st_value, Binding, Sym->st_other, - Sym->getType(), /*HasUnnamedAddr*/ false, this) + Sym->getType(), this) ->body(); } @@ -411,8 +411,7 @@ if (Sec == &InputSection::Discarded) return elf::Symtab::X ->addUndefined(Name, Binding, Sym->st_other, Sym->getType(), - /*CanOmitFromDynSym*/ false, - /*HasUnnamedAddr*/ false, this) + /*CanOmitFromDynSym*/ false, this) ->body(); return elf::Symtab::X->addRegular(Name, *Sym, Sec)->body(); } @@ -625,8 +624,8 @@ EMachine = getBitcodeMachineKind(MB); } -static uint8_t getGvVisibility(const GlobalValue *GV) { - switch (GV->getVisibility()) { +static uint8_t mapVisibility(GlobalValue::VisibilityTypes GvVisibility) { + switch (GvVisibility) { case GlobalValue::DefaultVisibility: return STV_DEFAULT; case GlobalValue::HiddenVisibility: @@ -638,84 +637,49 @@ } template -Symbol *BitcodeFile::createSymbol(const DenseSet &KeptComdats, - const IRObjectFile &Obj, - const BasicSymbolRef &Sym) { - const GlobalValue *GV = Obj.getSymbolGV(Sym.getRawDataRefImpl()); - - SmallString<64> Name; - raw_svector_ostream OS(Name); - Sym.printName(OS); - StringRef NameRef = Saver.save(StringRef(Name)); - - uint32_t Flags = Sym.getFlags(); +static Symbol *createBitcodeSymbol(const DenseSet &KeptComdats, + const lto::InputFile &Obj, + const lto::InputFile::Symbol &ObjSym, + llvm::StringSaver &Saver, BitcodeFile *F) { + StringRef NameRef = Saver.save(ObjSym.getName()); + uint32_t Flags = ObjSym.getFlags(); uint32_t Binding = (Flags & BasicSymbolRef::SF_Weak) ? STB_WEAK : STB_GLOBAL; - uint8_t Type = STT_NOTYPE; - uint8_t Visibility; - bool CanOmitFromDynSym = false; - bool HasUnnamedAddr = false; - - // FIXME: Expose a thread-local flag for module asm symbols. - if (GV) { - if (GV->isThreadLocal()) - Type = STT_TLS; - CanOmitFromDynSym = canBeOmittedFromSymbolTable(GV); - Visibility = getGvVisibility(GV); - HasUnnamedAddr = - GV->getUnnamedAddr() == llvm::GlobalValue::UnnamedAddr::Global; - } else { - // FIXME: Set SF_Hidden flag correctly for module asm symbols, and expose - // protected visibility. - Visibility = STV_DEFAULT; - } + uint8_t Type = (ObjSym.isTLS()) ? STT_TLS : STT_NOTYPE; + uint8_t Visibility = mapVisibility(ObjSym.getVisibility()); + bool CanOmitFromDynSym = ObjSym.canBeOmittedFromSymbolTable(); - if (GV) - if (const Comdat *C = GV->getComdat()) - if (!KeptComdats.count(C)) - return Symtab::X->addUndefined(NameRef, Binding, Visibility, Type, - CanOmitFromDynSym, HasUnnamedAddr, - this); + if (const Comdat *C = check(ObjSym.getComdat())) + if (!KeptComdats.count(C)) + return Symtab::X->addUndefined(NameRef, Binding, Visibility, Type, + CanOmitFromDynSym, F); - const Module &M = Obj.getModule(); if (Flags & BasicSymbolRef::SF_Undefined) return Symtab::X->addUndefined(NameRef, Binding, Visibility, Type, - CanOmitFromDynSym, HasUnnamedAddr, - this); - if (Flags & BasicSymbolRef::SF_Common) { - // FIXME: Set SF_Common flag correctly for module asm symbols, and expose - // size and alignment. - assert(GV); - const DataLayout &DL = M.getDataLayout(); - uint64_t Size = DL.getTypeAllocSize(GV->getValueType()); - return Symtab::X->addCommon(NameRef, Size, GV->getAlignment(), - Binding, Visibility, STT_OBJECT, - HasUnnamedAddr, this); - } - return Symtab::X->addBitcode(NameRef, Binding, Visibility, Type, - CanOmitFromDynSym, HasUnnamedAddr, this); -} + CanOmitFromDynSym, F); + + if (Flags & BasicSymbolRef::SF_Common) + return Symtab::X->addCommon(NameRef, ObjSym.getCommonSize(), + ObjSym.getCommonAlignment(), Binding, + Visibility, STT_OBJECT, F); -bool BitcodeFile::shouldSkip(uint32_t Flags) { - return !(Flags & BasicSymbolRef::SF_Global) || - (Flags & BasicSymbolRef::SF_FormatSpecific); + return Symtab::X->addBitcode(NameRef, Binding, Visibility, Type, + CanOmitFromDynSym, F); } template void BitcodeFile::parse(DenseSet &ComdatGroups) { - Obj = check(IRObjectFile::create(MB, Driver->Context)); - const Module &M = Obj->getModule(); - + Obj = check(llvm::lto::InputFile::create(MB)); DenseSet KeptComdats; - for (const auto &P : M.getComdatSymbolTable()) { + for (const auto &P : Obj->getComdatSymbolTable()) { StringRef N = Saver.save(P.first()); if (ComdatGroups.insert(N).second) KeptComdats.insert(&P.second); } - for (const BasicSymbolRef &Sym : Obj->symbols()) - if (!shouldSkip(Sym.getFlags())) - Symbols.push_back(createSymbol(KeptComdats, *Obj, Sym)); + for (auto &ObjSym : Obj->symbols()) + Symbols.push_back( + createBitcodeSymbol(KeptComdats, *Obj, ObjSym, Saver, this)); } template