diff options
Diffstat (limited to 'contrib/llvm/lib/Object/IRObjectFile.cpp')
-rw-r--r-- | contrib/llvm/lib/Object/IRObjectFile.cpp | 276 |
1 files changed, 44 insertions, 232 deletions
diff --git a/contrib/llvm/lib/Object/IRObjectFile.cpp b/contrib/llvm/lib/Object/IRObjectFile.cpp index 42c8ecd..adbf0de 100644 --- a/contrib/llvm/lib/Object/IRObjectFile.cpp +++ b/contrib/llvm/lib/Object/IRObjectFile.cpp @@ -14,7 +14,7 @@ #include "llvm/Object/IRObjectFile.h" #include "RecordStreamer.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/Bitcode/ReaderWriter.h" +#include "llvm/Bitcode/BitcodeReader.h" #include "llvm/IR/GVMaterializer.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Mangler.h" @@ -35,246 +35,52 @@ using namespace llvm; using namespace object; -IRObjectFile::IRObjectFile(MemoryBufferRef Object, std::unique_ptr<Module> Mod) - : SymbolicFile(Binary::ID_IR, Object), M(std::move(Mod)) { - Mang.reset(new Mangler()); - CollectAsmUndefinedRefs(Triple(M->getTargetTriple()), M->getModuleInlineAsm(), - [this](StringRef Name, BasicSymbolRef::Flags Flags) { - AsmSymbols.emplace_back(Name, std::move(Flags)); - }); +IRObjectFile::IRObjectFile(MemoryBufferRef Object, + std::vector<std::unique_ptr<Module>> Mods) + : SymbolicFile(Binary::ID_IR, Object), Mods(std::move(Mods)) { + for (auto &M : this->Mods) + SymTab.addModule(M.get()); } -// Parse inline ASM and collect the list of symbols that are not defined in -// the current module. This is inspired from IRObjectFile. -void IRObjectFile::CollectAsmUndefinedRefs( - const Triple &TT, StringRef InlineAsm, - function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmUndefinedRefs) { - if (InlineAsm.empty()) - return; +IRObjectFile::~IRObjectFile() {} - std::string Err; - const Target *T = TargetRegistry::lookupTarget(TT.str(), Err); - if (!T) - return; - - std::unique_ptr<MCRegisterInfo> MRI(T->createMCRegInfo(TT.str())); - if (!MRI) - return; - - std::unique_ptr<MCAsmInfo> MAI(T->createMCAsmInfo(*MRI, TT.str())); - if (!MAI) - return; - - std::unique_ptr<MCSubtargetInfo> STI( - T->createMCSubtargetInfo(TT.str(), "", "")); - if (!STI) - return; - - std::unique_ptr<MCInstrInfo> MCII(T->createMCInstrInfo()); - if (!MCII) - return; - - MCObjectFileInfo MOFI; - MCContext MCCtx(MAI.get(), MRI.get(), &MOFI); - MOFI.InitMCObjectFileInfo(TT, /*PIC*/ false, CodeModel::Default, MCCtx); - std::unique_ptr<RecordStreamer> Streamer(new RecordStreamer(MCCtx)); - T->createNullTargetStreamer(*Streamer); - - std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm)); - SourceMgr SrcMgr; - SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc()); - std::unique_ptr<MCAsmParser> Parser( - createMCAsmParser(SrcMgr, MCCtx, *Streamer, *MAI)); - - MCTargetOptions MCOptions; - std::unique_ptr<MCTargetAsmParser> TAP( - T->createMCAsmParser(*STI, *Parser, *MCII, MCOptions)); - if (!TAP) - return; - - Parser->setTargetParser(*TAP); - if (Parser->Run(false)) - return; - - for (auto &KV : *Streamer) { - StringRef Key = KV.first(); - RecordStreamer::State Value = KV.second; - uint32_t Res = BasicSymbolRef::SF_None; - switch (Value) { - case RecordStreamer::NeverSeen: - llvm_unreachable("foo"); - case RecordStreamer::DefinedGlobal: - Res |= BasicSymbolRef::SF_Global; - break; - case RecordStreamer::Defined: - break; - case RecordStreamer::Global: - case RecordStreamer::Used: - Res |= BasicSymbolRef::SF_Undefined; - Res |= BasicSymbolRef::SF_Global; - break; - case RecordStreamer::GlobalWeak: - Res |= BasicSymbolRef::SF_Weak; - Res |= BasicSymbolRef::SF_Global; - break; - } - AsmUndefinedRefs(Key, BasicSymbolRef::Flags(Res)); - } -} - -IRObjectFile::~IRObjectFile() { - } - -static GlobalValue *getGV(DataRefImpl &Symb) { - if ((Symb.p & 3) == 3) - return nullptr; - - return reinterpret_cast<GlobalValue*>(Symb.p & ~uintptr_t(3)); -} - -static uintptr_t skipEmpty(Module::const_alias_iterator I, const Module &M) { - if (I == M.alias_end()) - return 3; - const GlobalValue *GV = &*I; - return reinterpret_cast<uintptr_t>(GV) | 2; -} - -static uintptr_t skipEmpty(Module::const_global_iterator I, const Module &M) { - if (I == M.global_end()) - return skipEmpty(M.alias_begin(), M); - const GlobalValue *GV = &*I; - return reinterpret_cast<uintptr_t>(GV) | 1; -} - -static uintptr_t skipEmpty(Module::const_iterator I, const Module &M) { - if (I == M.end()) - return skipEmpty(M.global_begin(), M); - const GlobalValue *GV = &*I; - return reinterpret_cast<uintptr_t>(GV) | 0; -} - -static unsigned getAsmSymIndex(DataRefImpl Symb) { - assert((Symb.p & uintptr_t(3)) == 3); - uintptr_t Index = Symb.p & ~uintptr_t(3); - Index >>= 2; - return Index; +static ModuleSymbolTable::Symbol getSym(DataRefImpl &Symb) { + return *reinterpret_cast<ModuleSymbolTable::Symbol *>(Symb.p); } void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const { - const GlobalValue *GV = getGV(Symb); - uintptr_t Res; - - switch (Symb.p & 3) { - case 0: { - Module::const_iterator Iter(static_cast<const Function*>(GV)); - ++Iter; - Res = skipEmpty(Iter, *M); - break; - } - case 1: { - Module::const_global_iterator Iter(static_cast<const GlobalVariable*>(GV)); - ++Iter; - Res = skipEmpty(Iter, *M); - break; - } - case 2: { - Module::const_alias_iterator Iter(static_cast<const GlobalAlias*>(GV)); - ++Iter; - Res = skipEmpty(Iter, *M); - break; - } - case 3: { - unsigned Index = getAsmSymIndex(Symb); - assert(Index < AsmSymbols.size()); - ++Index; - Res = (Index << 2) | 3; - break; - } - default: - llvm_unreachable("unreachable case"); - } - - Symb.p = Res; + Symb.p += sizeof(ModuleSymbolTable::Symbol); } std::error_code IRObjectFile::printSymbolName(raw_ostream &OS, DataRefImpl Symb) const { - const GlobalValue *GV = getGV(Symb); - if (!GV) { - unsigned Index = getAsmSymIndex(Symb); - assert(Index <= AsmSymbols.size()); - OS << AsmSymbols[Index].first; - return std::error_code(); - } - - if (GV->hasDLLImportStorageClass()) - OS << "__imp_"; - - if (Mang) - Mang->getNameWithPrefix(OS, GV, false); - else - OS << GV->getName(); - + SymTab.printSymbolName(OS, getSym(Symb)); return std::error_code(); } uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const { - const GlobalValue *GV = getGV(Symb); - - if (!GV) { - unsigned Index = getAsmSymIndex(Symb); - assert(Index <= AsmSymbols.size()); - return AsmSymbols[Index].second; - } - - uint32_t Res = BasicSymbolRef::SF_None; - if (GV->isDeclarationForLinker()) - Res |= BasicSymbolRef::SF_Undefined; - else if (GV->hasHiddenVisibility() && !GV->hasLocalLinkage()) - Res |= BasicSymbolRef::SF_Hidden; - if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) { - if (GVar->isConstant()) - Res |= BasicSymbolRef::SF_Const; - } - if (GV->hasPrivateLinkage()) - Res |= BasicSymbolRef::SF_FormatSpecific; - if (!GV->hasLocalLinkage()) - Res |= BasicSymbolRef::SF_Global; - if (GV->hasCommonLinkage()) - Res |= BasicSymbolRef::SF_Common; - if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage() || - GV->hasExternalWeakLinkage()) - Res |= BasicSymbolRef::SF_Weak; - - if (GV->getName().startswith("llvm.")) - Res |= BasicSymbolRef::SF_FormatSpecific; - else if (auto *Var = dyn_cast<GlobalVariable>(GV)) { - if (Var->getSection() == "llvm.metadata") - Res |= BasicSymbolRef::SF_FormatSpecific; - } - - return Res; + return SymTab.getSymbolFlags(getSym(Symb)); } -GlobalValue *IRObjectFile::getSymbolGV(DataRefImpl Symb) { return getGV(Symb); } - -std::unique_ptr<Module> IRObjectFile::takeModule() { return std::move(M); } - -basic_symbol_iterator IRObjectFile::symbol_begin_impl() const { - Module::const_iterator I = M->begin(); +basic_symbol_iterator IRObjectFile::symbol_begin() const { DataRefImpl Ret; - Ret.p = skipEmpty(I, *M); + Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data()); return basic_symbol_iterator(BasicSymbolRef(Ret, this)); } -basic_symbol_iterator IRObjectFile::symbol_end_impl() const { +basic_symbol_iterator IRObjectFile::symbol_end() const { DataRefImpl Ret; - uint64_t NumAsm = AsmSymbols.size(); - NumAsm <<= 2; - Ret.p = 3 | NumAsm; + Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data() + + SymTab.symbols().size()); return basic_symbol_iterator(BasicSymbolRef(Ret, this)); } +StringRef IRObjectFile::getTargetTriple() const { + // Each module must have the same target triple, so we arbitrarily access the + // first one. + return Mods[0]->getTargetTriple(); +} + ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInObject(const ObjectFile &Obj) { for (const SectionRef &Sec : Obj.sections()) { if (Sec.isBitcode()) { @@ -307,22 +113,28 @@ ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Ob } } -ErrorOr<std::unique_ptr<IRObjectFile>> -llvm::object::IRObjectFile::create(MemoryBufferRef Object, - LLVMContext &Context) { +Expected<std::unique_ptr<IRObjectFile>> +IRObjectFile::create(MemoryBufferRef Object, LLVMContext &Context) { ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object); if (!BCOrErr) - return BCOrErr.getError(); - - std::unique_ptr<MemoryBuffer> Buff = - MemoryBuffer::getMemBuffer(BCOrErr.get(), false); - - ErrorOr<std::unique_ptr<Module>> MOrErr = - getLazyBitcodeModule(std::move(Buff), Context, - /*ShouldLazyLoadMetadata*/ true); - if (std::error_code EC = MOrErr.getError()) - return EC; + return errorCodeToError(BCOrErr.getError()); + + Expected<std::vector<BitcodeModule>> BMsOrErr = + getBitcodeModuleList(*BCOrErr); + if (!BMsOrErr) + return BMsOrErr.takeError(); + + std::vector<std::unique_ptr<Module>> Mods; + for (auto BM : *BMsOrErr) { + Expected<std::unique_ptr<Module>> MOrErr = + BM.getLazyModule(Context, /*ShouldLazyLoadMetadata*/ true, + /*IsImporting*/ false); + if (!MOrErr) + return MOrErr.takeError(); + + Mods.push_back(std::move(*MOrErr)); + } - std::unique_ptr<Module> &M = MOrErr.get(); - return llvm::make_unique<IRObjectFile>(Object, std::move(M)); + return std::unique_ptr<IRObjectFile>( + new IRObjectFile(*BCOrErr, std::move(Mods))); } |