IRObjectFile.cpp revision 314564
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" 35using namespace llvm; 36using namespace object; 37 38IRObjectFile::IRObjectFile(MemoryBufferRef Object, 39 std::vector<std::unique_ptr<Module>> Mods) 40 : SymbolicFile(Binary::ID_IR, Object), Mods(std::move(Mods)) { 41 for (auto &M : this->Mods) 42 SymTab.addModule(M.get()); 43} 44 45IRObjectFile::~IRObjectFile() {} 46 47static ModuleSymbolTable::Symbol getSym(DataRefImpl &Symb) { 48 return *reinterpret_cast<ModuleSymbolTable::Symbol *>(Symb.p); 49} 50 51void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const { 52 Symb.p += sizeof(ModuleSymbolTable::Symbol); 53} 54 55std::error_code IRObjectFile::printSymbolName(raw_ostream &OS, 56 DataRefImpl Symb) const { 57 SymTab.printSymbolName(OS, getSym(Symb)); 58 return std::error_code(); 59} 60 61uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const { 62 return SymTab.getSymbolFlags(getSym(Symb)); 63} 64 65basic_symbol_iterator IRObjectFile::symbol_begin() const { 66 DataRefImpl Ret; 67 Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data()); 68 return basic_symbol_iterator(BasicSymbolRef(Ret, this)); 69} 70 71basic_symbol_iterator IRObjectFile::symbol_end() const { 72 DataRefImpl Ret; 73 Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data() + 74 SymTab.symbols().size()); 75 return basic_symbol_iterator(BasicSymbolRef(Ret, this)); 76} 77 78StringRef IRObjectFile::getTargetTriple() const { 79 // Each module must have the same target triple, so we arbitrarily access the 80 // first one. 81 return Mods[0]->getTargetTriple(); 82} 83 84ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInObject(const ObjectFile &Obj) { 85 for (const SectionRef &Sec : Obj.sections()) { 86 if (Sec.isBitcode()) { 87 StringRef SecContents; 88 if (std::error_code EC = Sec.getContents(SecContents)) 89 return EC; 90 return MemoryBufferRef(SecContents, Obj.getFileName()); 91 } 92 } 93 94 return object_error::bitcode_section_not_found; 95} 96 97ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) { 98 sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer()); 99 switch (Type) { 100 case sys::fs::file_magic::bitcode: 101 return Object; 102 case sys::fs::file_magic::elf_relocatable: 103 case sys::fs::file_magic::macho_object: 104 case sys::fs::file_magic::coff_object: { 105 Expected<std::unique_ptr<ObjectFile>> ObjFile = 106 ObjectFile::createObjectFile(Object, Type); 107 if (!ObjFile) 108 return errorToErrorCode(ObjFile.takeError()); 109 return findBitcodeInObject(*ObjFile->get()); 110 } 111 default: 112 return object_error::invalid_file_type; 113 } 114} 115 116Expected<std::unique_ptr<IRObjectFile>> 117IRObjectFile::create(MemoryBufferRef Object, LLVMContext &Context) { 118 ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object); 119 if (!BCOrErr) 120 return errorCodeToError(BCOrErr.getError()); 121 122 Expected<std::vector<BitcodeModule>> BMsOrErr = 123 getBitcodeModuleList(*BCOrErr); 124 if (!BMsOrErr) 125 return BMsOrErr.takeError(); 126 127 std::vector<std::unique_ptr<Module>> Mods; 128 for (auto BM : *BMsOrErr) { 129 Expected<std::unique_ptr<Module>> MOrErr = 130 BM.getLazyModule(Context, /*ShouldLazyLoadMetadata*/ true, 131 /*IsImporting*/ false); 132 if (!MOrErr) 133 return MOrErr.takeError(); 134 135 Mods.push_back(std::move(*MOrErr)); 136 } 137 138 return std::unique_ptr<IRObjectFile>( 139 new IRObjectFile(*BCOrErr, std::move(Mods))); 140} 141