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" 17264b5d9eSZachary Turner #include "llvm/BinaryFormat/Magic.h" 18ad17679aSTeresa Johnson #include "llvm/Bitcode/BitcodeReader.h" 19c3f9b5a5SRafael Espindola #include "llvm/IR/GVMaterializer.h" 20d9903888SChandler Carruth #include "llvm/IR/LLVMContext.h" 21a51f0f83SRafael Espindola #include "llvm/IR/Mangler.h" 22f12b8282SRafael Espindola #include "llvm/IR/Module.h" 2313b69d63SRafael Espindola #include "llvm/MC/MCAsmInfo.h" 2413b69d63SRafael Espindola #include "llvm/MC/MCContext.h" 2513b69d63SRafael Espindola #include "llvm/MC/MCInstrInfo.h" 2613b69d63SRafael Espindola #include "llvm/MC/MCObjectFileInfo.h" 2713b69d63SRafael Espindola #include "llvm/MC/MCParser/MCAsmParser.h" 28b3e8a6d2SBenjamin Kramer #include "llvm/MC/MCParser/MCTargetAsmParser.h" 29d9903888SChandler Carruth #include "llvm/MC/MCRegisterInfo.h" 3081902a3aSPete Cooper #include "llvm/MC/MCSubtargetInfo.h" 3110039c02SPeter Collingbourne #include "llvm/Object/ObjectFile.h" 322e60ca96SRafael Espindola #include "llvm/Support/MemoryBuffer.h" 3313b69d63SRafael Espindola #include "llvm/Support/SourceMgr.h" 3413b69d63SRafael Espindola #include "llvm/Support/TargetRegistry.h" 3523f04061SRafael Espindola #include "llvm/Support/raw_ostream.h" 36f12b8282SRafael Espindola using namespace llvm; 37f12b8282SRafael Espindola using namespace object; 38f12b8282SRafael Espindola 3945102a24SPeter Collingbourne IRObjectFile::IRObjectFile(MemoryBufferRef Object, 4045102a24SPeter Collingbourne std::vector<std::unique_ptr<Module>> Mods) 4145102a24SPeter Collingbourne : SymbolicFile(Binary::ID_IR, Object), Mods(std::move(Mods)) { 4245102a24SPeter Collingbourne for (auto &M : this->Mods) 43863cbfbeSPeter Collingbourne SymTab.addModule(M.get()); 44f12b8282SRafael Espindola } 45f12b8282SRafael Espindola 46e32baa0cSPeter Collingbourne IRObjectFile::~IRObjectFile() {} 4713b69d63SRafael Espindola 48863cbfbeSPeter Collingbourne static ModuleSymbolTable::Symbol getSym(DataRefImpl &Symb) { 49863cbfbeSPeter Collingbourne return *reinterpret_cast<ModuleSymbolTable::Symbol *>(Symb.p); 50863cbfbeSPeter Collingbourne } 51863cbfbeSPeter Collingbourne 52f12b8282SRafael Espindola void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const { 53863cbfbeSPeter Collingbourne Symb.p += sizeof(ModuleSymbolTable::Symbol); 54f12b8282SRafael Espindola } 55f12b8282SRafael Espindola 56db4ed0bdSRafael Espindola std::error_code IRObjectFile::printSymbolName(raw_ostream &OS, 57f12b8282SRafael Espindola DataRefImpl Symb) const { 58863cbfbeSPeter Collingbourne SymTab.printSymbolName(OS, getSym(Symb)); 597d099195SRui Ueyama return std::error_code(); 60f12b8282SRafael Espindola } 61f12b8282SRafael Espindola 62f12b8282SRafael Espindola uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const { 63863cbfbeSPeter Collingbourne return SymTab.getSymbolFlags(getSym(Symb)); 64f12b8282SRafael Espindola } 65f12b8282SRafael Espindola 66435890a4SPeter Collingbourne basic_symbol_iterator IRObjectFile::symbol_begin() const { 67f12b8282SRafael Espindola DataRefImpl Ret; 68863cbfbeSPeter Collingbourne Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data()); 69f12b8282SRafael Espindola return basic_symbol_iterator(BasicSymbolRef(Ret, this)); 70f12b8282SRafael Espindola } 71f12b8282SRafael Espindola 72435890a4SPeter Collingbourne basic_symbol_iterator IRObjectFile::symbol_end() const { 73f12b8282SRafael Espindola DataRefImpl Ret; 74863cbfbeSPeter Collingbourne Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data() + 75863cbfbeSPeter Collingbourne SymTab.symbols().size()); 76f12b8282SRafael Espindola return basic_symbol_iterator(BasicSymbolRef(Ret, this)); 77f12b8282SRafael Espindola } 78f12b8282SRafael Espindola 7945102a24SPeter Collingbourne StringRef IRObjectFile::getTargetTriple() const { 8045102a24SPeter Collingbourne // Each module must have the same target triple, so we arbitrarily access the 8145102a24SPeter Collingbourne // first one. 8245102a24SPeter Collingbourne return Mods[0]->getTargetTriple(); 8345102a24SPeter Collingbourne } 84debb6f6cSPeter Collingbourne 85*3500f5e3SRafael Espindola Expected<MemoryBufferRef> 86*3500f5e3SRafael Espindola IRObjectFile::findBitcodeInObject(const ObjectFile &Obj) { 8710039c02SPeter Collingbourne for (const SectionRef &Sec : Obj.sections()) { 88f2fe0141SSteven Wu if (Sec.isBitcode()) { 8910039c02SPeter Collingbourne StringRef SecContents; 9010039c02SPeter Collingbourne if (std::error_code EC = Sec.getContents(SecContents)) 91*3500f5e3SRafael Espindola return errorCodeToError(EC); 9210039c02SPeter Collingbourne return MemoryBufferRef(SecContents, Obj.getFileName()); 9310039c02SPeter Collingbourne } 9410039c02SPeter Collingbourne } 9510039c02SPeter Collingbourne 96*3500f5e3SRafael Espindola return errorCodeToError(object_error::bitcode_section_not_found); 9710039c02SPeter Collingbourne } 9810039c02SPeter Collingbourne 99*3500f5e3SRafael Espindola Expected<MemoryBufferRef> 100*3500f5e3SRafael Espindola IRObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) { 101264b5d9eSZachary Turner file_magic Type = identify_magic(Object.getBuffer()); 10210039c02SPeter Collingbourne switch (Type) { 103264b5d9eSZachary Turner case file_magic::bitcode: 10410039c02SPeter Collingbourne return Object; 105264b5d9eSZachary Turner case file_magic::elf_relocatable: 106264b5d9eSZachary Turner case file_magic::macho_object: 107264b5d9eSZachary Turner case file_magic::coff_object: { 1083fcdf6aeSKevin Enderby Expected<std::unique_ptr<ObjectFile>> ObjFile = 10910039c02SPeter Collingbourne ObjectFile::createObjectFile(Object, Type); 11010039c02SPeter Collingbourne if (!ObjFile) 111*3500f5e3SRafael Espindola return ObjFile.takeError(); 11210039c02SPeter Collingbourne return findBitcodeInObject(*ObjFile->get()); 11310039c02SPeter Collingbourne } 11410039c02SPeter Collingbourne default: 115*3500f5e3SRafael Espindola return errorCodeToError(object_error::invalid_file_type); 11610039c02SPeter Collingbourne } 11710039c02SPeter Collingbourne } 11810039c02SPeter Collingbourne 119d9445c49SPeter Collingbourne Expected<std::unique_ptr<IRObjectFile>> 12045102a24SPeter Collingbourne IRObjectFile::create(MemoryBufferRef Object, LLVMContext &Context) { 121*3500f5e3SRafael Espindola Expected<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object); 12210039c02SPeter Collingbourne if (!BCOrErr) 123*3500f5e3SRafael Espindola return BCOrErr.takeError(); 12448af1c2aSRafael Espindola 12545102a24SPeter Collingbourne Expected<std::vector<BitcodeModule>> BMsOrErr = 12645102a24SPeter Collingbourne getBitcodeModuleList(*BCOrErr); 12745102a24SPeter Collingbourne if (!BMsOrErr) 12845102a24SPeter Collingbourne return BMsOrErr.takeError(); 12945102a24SPeter Collingbourne 13045102a24SPeter Collingbourne std::vector<std::unique_ptr<Module>> Mods; 13145102a24SPeter Collingbourne for (auto BM : *BMsOrErr) { 132d9445c49SPeter Collingbourne Expected<std::unique_ptr<Module>> MOrErr = 133a61f5e37STeresa Johnson BM.getLazyModule(Context, /*ShouldLazyLoadMetadata*/ true, 134a61f5e37STeresa Johnson /*IsImporting*/ false); 135d9445c49SPeter Collingbourne if (!MOrErr) 136d9445c49SPeter Collingbourne return MOrErr.takeError(); 137dddd1fd9SRafael Espindola 13845102a24SPeter Collingbourne Mods.push_back(std::move(*MOrErr)); 13945102a24SPeter Collingbourne } 14045102a24SPeter Collingbourne 141c5fecb4fSPeter Collingbourne return std::unique_ptr<IRObjectFile>( 14245102a24SPeter Collingbourne new IRObjectFile(*BCOrErr, std::move(Mods))); 143f12b8282SRafael Espindola } 144c00c2b24SPeter Collingbourne 145c00c2b24SPeter Collingbourne Expected<IRSymtabFile> object::readIRSymtab(MemoryBufferRef MBRef) { 146c00c2b24SPeter Collingbourne IRSymtabFile F; 147*3500f5e3SRafael Espindola Expected<MemoryBufferRef> BCOrErr = 148c00c2b24SPeter Collingbourne IRObjectFile::findBitcodeInMemBuffer(MBRef); 149c00c2b24SPeter Collingbourne if (!BCOrErr) 150*3500f5e3SRafael Espindola return BCOrErr.takeError(); 151c00c2b24SPeter Collingbourne 1528dde4cbaSPeter Collingbourne Expected<BitcodeFileContents> BFCOrErr = getBitcodeFileContents(*BCOrErr); 1538dde4cbaSPeter Collingbourne if (!BFCOrErr) 1548dde4cbaSPeter Collingbourne return BFCOrErr.takeError(); 155c00c2b24SPeter Collingbourne 1568dde4cbaSPeter Collingbourne Expected<irsymtab::FileContents> FCOrErr = irsymtab::readBitcode(*BFCOrErr); 157c00c2b24SPeter Collingbourne if (!FCOrErr) 158c00c2b24SPeter Collingbourne return FCOrErr.takeError(); 159c00c2b24SPeter Collingbourne 1608dde4cbaSPeter Collingbourne F.Mods = std::move(BFCOrErr->Mods); 161c00c2b24SPeter Collingbourne F.Symtab = std::move(FCOrErr->Symtab); 162c00c2b24SPeter Collingbourne F.Strtab = std::move(FCOrErr->Strtab); 163c00c2b24SPeter Collingbourne F.TheReader = std::move(FCOrErr->TheReader); 164c00c2b24SPeter Collingbourne return std::move(F); 165c00c2b24SPeter Collingbourne } 166