1 //===- IRObjectFile.cpp - IR object file implementation ---------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Part of the IRObjectFile class implementation. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/Object/IRObjectFile.h" 15 #include "RecordStreamer.h" 16 #include "llvm/ADT/STLExtras.h" 17 #include "llvm/Bitcode/BitcodeReader.h" 18 #include "llvm/IR/GVMaterializer.h" 19 #include "llvm/IR/LLVMContext.h" 20 #include "llvm/IR/Mangler.h" 21 #include "llvm/IR/Module.h" 22 #include "llvm/MC/MCAsmInfo.h" 23 #include "llvm/MC/MCContext.h" 24 #include "llvm/MC/MCInstrInfo.h" 25 #include "llvm/MC/MCObjectFileInfo.h" 26 #include "llvm/MC/MCParser/MCAsmParser.h" 27 #include "llvm/MC/MCParser/MCTargetAsmParser.h" 28 #include "llvm/MC/MCRegisterInfo.h" 29 #include "llvm/MC/MCSubtargetInfo.h" 30 #include "llvm/Object/ObjectFile.h" 31 #include "llvm/Support/MemoryBuffer.h" 32 #include "llvm/Support/SourceMgr.h" 33 #include "llvm/Support/TargetRegistry.h" 34 #include "llvm/Support/raw_ostream.h" 35 using namespace llvm; 36 using namespace object; 37 38 IRObjectFile::IRObjectFile(MemoryBufferRef Object, std::unique_ptr<Module> Mod) 39 : SymbolicFile(Binary::ID_IR, Object), M(std::move(Mod)) { 40 SymTab.addModule(M.get()); 41 } 42 43 IRObjectFile::~IRObjectFile() {} 44 45 static ModuleSymbolTable::Symbol getSym(DataRefImpl &Symb) { 46 return *reinterpret_cast<ModuleSymbolTable::Symbol *>(Symb.p); 47 } 48 49 void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const { 50 Symb.p += sizeof(ModuleSymbolTable::Symbol); 51 } 52 53 std::error_code IRObjectFile::printSymbolName(raw_ostream &OS, 54 DataRefImpl Symb) const { 55 SymTab.printSymbolName(OS, getSym(Symb)); 56 return std::error_code(); 57 } 58 59 uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const { 60 return SymTab.getSymbolFlags(getSym(Symb)); 61 } 62 63 basic_symbol_iterator IRObjectFile::symbol_begin() const { 64 DataRefImpl Ret; 65 Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data()); 66 return basic_symbol_iterator(BasicSymbolRef(Ret, this)); 67 } 68 69 basic_symbol_iterator IRObjectFile::symbol_end() const { 70 DataRefImpl Ret; 71 Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data() + 72 SymTab.symbols().size()); 73 return basic_symbol_iterator(BasicSymbolRef(Ret, this)); 74 } 75 76 StringRef IRObjectFile::getTargetTriple() const { return M->getTargetTriple(); } 77 78 ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInObject(const ObjectFile &Obj) { 79 for (const SectionRef &Sec : Obj.sections()) { 80 if (Sec.isBitcode()) { 81 StringRef SecContents; 82 if (std::error_code EC = Sec.getContents(SecContents)) 83 return EC; 84 return MemoryBufferRef(SecContents, Obj.getFileName()); 85 } 86 } 87 88 return object_error::bitcode_section_not_found; 89 } 90 91 ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) { 92 sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer()); 93 switch (Type) { 94 case sys::fs::file_magic::bitcode: 95 return Object; 96 case sys::fs::file_magic::elf_relocatable: 97 case sys::fs::file_magic::macho_object: 98 case sys::fs::file_magic::coff_object: { 99 Expected<std::unique_ptr<ObjectFile>> ObjFile = 100 ObjectFile::createObjectFile(Object, Type); 101 if (!ObjFile) 102 return errorToErrorCode(ObjFile.takeError()); 103 return findBitcodeInObject(*ObjFile->get()); 104 } 105 default: 106 return object_error::invalid_file_type; 107 } 108 } 109 110 Expected<std::unique_ptr<IRObjectFile>> 111 llvm::object::IRObjectFile::create(MemoryBufferRef Object, 112 LLVMContext &Context) { 113 ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object); 114 if (!BCOrErr) 115 return errorCodeToError(BCOrErr.getError()); 116 117 Expected<std::unique_ptr<Module>> MOrErr = 118 getLazyBitcodeModule(*BCOrErr, Context, 119 /*ShouldLazyLoadMetadata*/ true); 120 if (!MOrErr) 121 return MOrErr.takeError(); 122 123 std::unique_ptr<Module> &M = MOrErr.get(); 124 return std::unique_ptr<IRObjectFile>( 125 new IRObjectFile(*BCOrErr, std::move(M))); 126 } 127