diff options
Diffstat (limited to 'lib/Object/IRObjectFile.cpp')
-rw-r--r-- | lib/Object/IRObjectFile.cpp | 91 |
1 files changed, 61 insertions, 30 deletions
diff --git a/lib/Object/IRObjectFile.cpp b/lib/Object/IRObjectFile.cpp index 5323d9277eee..423ed9e9a64d 100644 --- a/lib/Object/IRObjectFile.cpp +++ b/lib/Object/IRObjectFile.cpp @@ -14,17 +14,18 @@ #include "llvm/Object/IRObjectFile.h" #include "RecordStreamer.h" #include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/IR/LLVMContext.h" #include "llvm/IR/GVMaterializer.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/IR/Mangler.h" #include "llvm/IR/Module.h" -#include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCObjectFileInfo.h" -#include "llvm/MC/MCTargetAsmParser.h" #include "llvm/MC/MCParser/MCAsmParser.h" +#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/MC/MCTargetAsmParser.h" +#include "llvm/Object/ObjectFile.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/TargetRegistry.h" @@ -32,9 +33,8 @@ using namespace llvm; using namespace object; -IRObjectFile::IRObjectFile(std::unique_ptr<MemoryBuffer> Object, - std::unique_ptr<Module> Mod) - : SymbolicFile(Binary::ID_IR, std::move(Object)), M(std::move(Mod)) { +IRObjectFile::IRObjectFile(MemoryBufferRef Object, std::unique_ptr<Module> Mod) + : SymbolicFile(Binary::ID_IR, Object), M(std::move(Mod)) { // If we have a DataLayout, setup a mangler. const DataLayout *DL = M->getDataLayout(); if (!DL) @@ -76,7 +76,7 @@ IRObjectFile::IRObjectFile(std::unique_ptr<MemoryBuffer> Object, std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm)); SourceMgr SrcMgr; - SrcMgr.AddNewSourceBuffer(Buffer.release(), SMLoc()); + SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc()); std::unique_ptr<MCAsmParser> Parser( createMCAsmParser(SrcMgr, MCCtx, *Streamer, *MAI)); @@ -114,12 +114,9 @@ IRObjectFile::IRObjectFile(std::unique_ptr<MemoryBuffer> Object, } IRObjectFile::~IRObjectFile() { - GVMaterializer *GVM = M->getMaterializer(); - if (GVM) - GVM->releaseBuffer(); } -static const GlobalValue *getGV(DataRefImpl &Symb) { +static GlobalValue *getGV(DataRefImpl &Symb) { if ((Symb.p & 3) == 3) return nullptr; @@ -184,6 +181,8 @@ void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const { Res = (Index << 2) | 3; break; } + default: + llvm_unreachable("unreachable case"); } Symb.p = Res; @@ -207,16 +206,6 @@ std::error_code IRObjectFile::printSymbolName(raw_ostream &OS, return object_error::success; } -static bool isDeclaration(const GlobalValue &V) { - if (V.hasAvailableExternallyLinkage()) - return true; - - if (V.isMaterializable()) - return false; - - return V.isDeclaration(); -} - uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const { const GlobalValue *GV = getGV(Symb); @@ -227,7 +216,7 @@ uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const { } uint32_t Res = BasicSymbolRef::SF_None; - if (isDeclaration(*GV)) + if (GV->isDeclarationForLinker()) Res |= BasicSymbolRef::SF_Undefined; if (GV->hasPrivateLinkage()) Res |= BasicSymbolRef::SF_FormatSpecific; @@ -248,10 +237,9 @@ uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const { return Res; } -const GlobalValue *IRObjectFile::getSymbolGV(DataRefImpl Symb) const { - const GlobalValue *GV = getGV(Symb); - return GV; -} +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(); @@ -268,12 +256,55 @@ basic_symbol_iterator IRObjectFile::symbol_end_impl() const { return basic_symbol_iterator(BasicSymbolRef(Ret, this)); } -ErrorOr<IRObjectFile *> llvm::object::IRObjectFile::createIRObjectFile( - std::unique_ptr<MemoryBuffer> Object, LLVMContext &Context) { - ErrorOr<Module *> MOrErr = getLazyBitcodeModule(Object.get(), Context); +ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInObject(const ObjectFile &Obj) { + for (const SectionRef &Sec : Obj.sections()) { + StringRef SecName; + if (std::error_code EC = Sec.getName(SecName)) + return EC; + if (SecName == ".llvmbc") { + StringRef SecContents; + if (std::error_code EC = Sec.getContents(SecContents)) + return EC; + return MemoryBufferRef(SecContents, Obj.getFileName()); + } + } + + return object_error::bitcode_section_not_found; +} + +ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) { + sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer()); + switch (Type) { + case sys::fs::file_magic::bitcode: + return Object; + case sys::fs::file_magic::elf_relocatable: + case sys::fs::file_magic::macho_object: + case sys::fs::file_magic::coff_object: { + ErrorOr<std::unique_ptr<ObjectFile>> ObjFile = + ObjectFile::createObjectFile(Object, Type); + if (!ObjFile) + return ObjFile.getError(); + return findBitcodeInObject(*ObjFile->get()); + } + default: + return object_error::invalid_file_type; + } +} + +ErrorOr<std::unique_ptr<IRObjectFile>> +llvm::object::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<Module *> MOrErr = getLazyBitcodeModule(std::move(Buff), Context); if (std::error_code EC = MOrErr.getError()) return EC; std::unique_ptr<Module> M(MOrErr.get()); - return new IRObjectFile(std::move(Object), std::move(M)); + return llvm::make_unique<IRObjectFile>(Object, std::move(M)); } |