1f12b8282SRafael Espindola //===- IRObjectFile.cpp - IR object file implementation ---------*- C++ -*-===// 2f12b8282SRafael Espindola // 3f12b8282SRafael Espindola // The LLVM Compiler Infrastructure 4f12b8282SRafael Espindola // 5f12b8282SRafael Espindola // This file is distributed under the University of Illinois Open Source 6f12b8282SRafael Espindola // License. See LICENSE.TXT for details. 7f12b8282SRafael Espindola // 8f12b8282SRafael Espindola //===----------------------------------------------------------------------===// 9f12b8282SRafael Espindola // 10f12b8282SRafael Espindola // Part of the IRObjectFile class implementation. 11f12b8282SRafael Espindola // 12f12b8282SRafael Espindola //===----------------------------------------------------------------------===// 13f12b8282SRafael Espindola 14ba79dba8SRafael Espindola #include "llvm/Object/IRObjectFile.h" 15ba79dba8SRafael Espindola #include "RecordStreamer.h" 160a446fd5SBenjamin Kramer #include "llvm/ADT/STLExtras.h" 17ad17679aSTeresa Johnson #include "llvm/Bitcode/BitcodeReader.h" 18c3f9b5a5SRafael Espindola #include "llvm/IR/GVMaterializer.h" 19d9903888SChandler Carruth #include "llvm/IR/LLVMContext.h" 20a51f0f83SRafael Espindola #include "llvm/IR/Mangler.h" 21f12b8282SRafael Espindola #include "llvm/IR/Module.h" 2213b69d63SRafael Espindola #include "llvm/MC/MCAsmInfo.h" 2313b69d63SRafael Espindola #include "llvm/MC/MCContext.h" 2413b69d63SRafael Espindola #include "llvm/MC/MCInstrInfo.h" 2513b69d63SRafael Espindola #include "llvm/MC/MCObjectFileInfo.h" 2613b69d63SRafael Espindola #include "llvm/MC/MCParser/MCAsmParser.h" 27b3e8a6d2SBenjamin Kramer #include "llvm/MC/MCParser/MCTargetAsmParser.h" 28d9903888SChandler Carruth #include "llvm/MC/MCRegisterInfo.h" 2981902a3aSPete Cooper #include "llvm/MC/MCSubtargetInfo.h" 3010039c02SPeter Collingbourne #include "llvm/Object/ObjectFile.h" 312e60ca96SRafael Espindola #include "llvm/Support/MemoryBuffer.h" 3213b69d63SRafael Espindola #include "llvm/Support/SourceMgr.h" 3313b69d63SRafael Espindola #include "llvm/Support/TargetRegistry.h" 3423f04061SRafael Espindola #include "llvm/Support/raw_ostream.h" 35f12b8282SRafael Espindola using namespace llvm; 36f12b8282SRafael Espindola using namespace object; 37f12b8282SRafael Espindola 3848af1c2aSRafael Espindola IRObjectFile::IRObjectFile(MemoryBufferRef Object, std::unique_ptr<Module> Mod) 3948af1c2aSRafael Espindola : SymbolicFile(Binary::ID_IR, Object), M(std::move(Mod)) { 40*863cbfbeSPeter Collingbourne SymTab.addModule(M.get()); 41f12b8282SRafael Espindola } 42f12b8282SRafael Espindola 43e32baa0cSPeter Collingbourne IRObjectFile::~IRObjectFile() {} 4413b69d63SRafael Espindola 45*863cbfbeSPeter Collingbourne static ModuleSymbolTable::Symbol getSym(DataRefImpl &Symb) { 46*863cbfbeSPeter Collingbourne return *reinterpret_cast<ModuleSymbolTable::Symbol *>(Symb.p); 47*863cbfbeSPeter Collingbourne } 48*863cbfbeSPeter Collingbourne 49f12b8282SRafael Espindola void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const { 50*863cbfbeSPeter Collingbourne Symb.p += sizeof(ModuleSymbolTable::Symbol); 51f12b8282SRafael Espindola } 52f12b8282SRafael Espindola 53db4ed0bdSRafael Espindola std::error_code IRObjectFile::printSymbolName(raw_ostream &OS, 54f12b8282SRafael Espindola DataRefImpl Symb) const { 55*863cbfbeSPeter Collingbourne SymTab.printSymbolName(OS, getSym(Symb)); 567d099195SRui Ueyama return std::error_code(); 57f12b8282SRafael Espindola } 58f12b8282SRafael Espindola 59f12b8282SRafael Espindola uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const { 60*863cbfbeSPeter Collingbourne return SymTab.getSymbolFlags(getSym(Symb)); 61f12b8282SRafael Espindola } 62f12b8282SRafael Espindola 63e32baa0cSPeter Collingbourne GlobalValue *IRObjectFile::getSymbolGV(DataRefImpl Symb) { 64e32baa0cSPeter Collingbourne return getSym(Symb).dyn_cast<GlobalValue *>(); 65e32baa0cSPeter Collingbourne } 66f12b8282SRafael Espindola 6725a7e0a8SRafael Espindola std::unique_ptr<Module> IRObjectFile::takeModule() { return std::move(M); } 6825a7e0a8SRafael Espindola 69435890a4SPeter Collingbourne basic_symbol_iterator IRObjectFile::symbol_begin() const { 70f12b8282SRafael Espindola DataRefImpl Ret; 71*863cbfbeSPeter Collingbourne Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data()); 72f12b8282SRafael Espindola return basic_symbol_iterator(BasicSymbolRef(Ret, this)); 73f12b8282SRafael Espindola } 74f12b8282SRafael Espindola 75435890a4SPeter Collingbourne basic_symbol_iterator IRObjectFile::symbol_end() const { 76f12b8282SRafael Espindola DataRefImpl Ret; 77*863cbfbeSPeter Collingbourne Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data() + 78*863cbfbeSPeter Collingbourne SymTab.symbols().size()); 79f12b8282SRafael Espindola return basic_symbol_iterator(BasicSymbolRef(Ret, this)); 80f12b8282SRafael Espindola } 81f12b8282SRafael Espindola 82debb6f6cSPeter Collingbourne StringRef IRObjectFile::getTargetTriple() const { return M->getTargetTriple(); } 83debb6f6cSPeter Collingbourne 8410039c02SPeter Collingbourne ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInObject(const ObjectFile &Obj) { 8510039c02SPeter Collingbourne for (const SectionRef &Sec : Obj.sections()) { 86f2fe0141SSteven Wu if (Sec.isBitcode()) { 8710039c02SPeter Collingbourne StringRef SecContents; 8810039c02SPeter Collingbourne if (std::error_code EC = Sec.getContents(SecContents)) 8910039c02SPeter Collingbourne return EC; 9010039c02SPeter Collingbourne return MemoryBufferRef(SecContents, Obj.getFileName()); 9110039c02SPeter Collingbourne } 9210039c02SPeter Collingbourne } 9310039c02SPeter Collingbourne 9410039c02SPeter Collingbourne return object_error::bitcode_section_not_found; 9510039c02SPeter Collingbourne } 9610039c02SPeter Collingbourne 9710039c02SPeter Collingbourne ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) { 9810039c02SPeter Collingbourne sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer()); 9910039c02SPeter Collingbourne switch (Type) { 10010039c02SPeter Collingbourne case sys::fs::file_magic::bitcode: 10110039c02SPeter Collingbourne return Object; 10210039c02SPeter Collingbourne case sys::fs::file_magic::elf_relocatable: 10310039c02SPeter Collingbourne case sys::fs::file_magic::macho_object: 10410039c02SPeter Collingbourne case sys::fs::file_magic::coff_object: { 1053fcdf6aeSKevin Enderby Expected<std::unique_ptr<ObjectFile>> ObjFile = 10610039c02SPeter Collingbourne ObjectFile::createObjectFile(Object, Type); 10710039c02SPeter Collingbourne if (!ObjFile) 1083fcdf6aeSKevin Enderby return errorToErrorCode(ObjFile.takeError()); 10910039c02SPeter Collingbourne return findBitcodeInObject(*ObjFile->get()); 11010039c02SPeter Collingbourne } 11110039c02SPeter Collingbourne default: 11210039c02SPeter Collingbourne return object_error::invalid_file_type; 11310039c02SPeter Collingbourne } 11410039c02SPeter Collingbourne } 11510039c02SPeter Collingbourne 116d9445c49SPeter Collingbourne Expected<std::unique_ptr<IRObjectFile>> 1175dec7eaaSRafael Espindola llvm::object::IRObjectFile::create(MemoryBufferRef Object, 11848af1c2aSRafael Espindola LLVMContext &Context) { 11910039c02SPeter Collingbourne ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object); 12010039c02SPeter Collingbourne if (!BCOrErr) 121d9445c49SPeter Collingbourne return errorCodeToError(BCOrErr.getError()); 12248af1c2aSRafael Espindola 123d9445c49SPeter Collingbourne Expected<std::unique_ptr<Module>> MOrErr = 124e2dcf7c3SPeter Collingbourne getLazyBitcodeModule(*BCOrErr, Context, 125cba833a0SRafael Espindola /*ShouldLazyLoadMetadata*/ true); 126d9445c49SPeter Collingbourne if (!MOrErr) 127d9445c49SPeter Collingbourne return MOrErr.takeError(); 128dddd1fd9SRafael Espindola 129dcd1dca2SRafael Espindola std::unique_ptr<Module> &M = MOrErr.get(); 1309ba95f99STeresa Johnson return llvm::make_unique<IRObjectFile>(BCOrErr.get(), std::move(M)); 131f12b8282SRafael Espindola } 132