1f12b8282SRafael Espindola //===- IRObjectFile.cpp - IR object file implementation ---------*- C++ -*-===// 2f12b8282SRafael Espindola // 3*2946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*2946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 5*2946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6f12b8282SRafael Espindola // 7f12b8282SRafael Espindola //===----------------------------------------------------------------------===// 8f12b8282SRafael Espindola // 9f12b8282SRafael Espindola // Part of the IRObjectFile class implementation. 10f12b8282SRafael Espindola // 11f12b8282SRafael Espindola //===----------------------------------------------------------------------===// 12f12b8282SRafael Espindola 13ba79dba8SRafael Espindola #include "llvm/Object/IRObjectFile.h" 140a446fd5SBenjamin Kramer #include "llvm/ADT/STLExtras.h" 15264b5d9eSZachary Turner #include "llvm/BinaryFormat/Magic.h" 16ad17679aSTeresa Johnson #include "llvm/Bitcode/BitcodeReader.h" 17c3f9b5a5SRafael Espindola #include "llvm/IR/GVMaterializer.h" 18d9903888SChandler Carruth #include "llvm/IR/LLVMContext.h" 19a51f0f83SRafael Espindola #include "llvm/IR/Mangler.h" 20f12b8282SRafael Espindola #include "llvm/IR/Module.h" 2110039c02SPeter Collingbourne #include "llvm/Object/ObjectFile.h" 222e60ca96SRafael Espindola #include "llvm/Support/MemoryBuffer.h" 2313b69d63SRafael Espindola #include "llvm/Support/TargetRegistry.h" 2423f04061SRafael Espindola #include "llvm/Support/raw_ostream.h" 25f12b8282SRafael Espindola using namespace llvm; 26f12b8282SRafael Espindola using namespace object; 27f12b8282SRafael Espindola 2845102a24SPeter Collingbourne IRObjectFile::IRObjectFile(MemoryBufferRef Object, 2945102a24SPeter Collingbourne std::vector<std::unique_ptr<Module>> Mods) 3045102a24SPeter Collingbourne : SymbolicFile(Binary::ID_IR, Object), Mods(std::move(Mods)) { 3145102a24SPeter Collingbourne for (auto &M : this->Mods) 32863cbfbeSPeter Collingbourne SymTab.addModule(M.get()); 33f12b8282SRafael Espindola } 34f12b8282SRafael Espindola 35e32baa0cSPeter Collingbourne IRObjectFile::~IRObjectFile() {} 3613b69d63SRafael Espindola 37863cbfbeSPeter Collingbourne static ModuleSymbolTable::Symbol getSym(DataRefImpl &Symb) { 38863cbfbeSPeter Collingbourne return *reinterpret_cast<ModuleSymbolTable::Symbol *>(Symb.p); 39863cbfbeSPeter Collingbourne } 40863cbfbeSPeter Collingbourne 41f12b8282SRafael Espindola void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const { 42863cbfbeSPeter Collingbourne Symb.p += sizeof(ModuleSymbolTable::Symbol); 43f12b8282SRafael Espindola } 44f12b8282SRafael Espindola 45db4ed0bdSRafael Espindola std::error_code IRObjectFile::printSymbolName(raw_ostream &OS, 46f12b8282SRafael Espindola DataRefImpl Symb) const { 47863cbfbeSPeter Collingbourne SymTab.printSymbolName(OS, getSym(Symb)); 487d099195SRui Ueyama return std::error_code(); 49f12b8282SRafael Espindola } 50f12b8282SRafael Espindola 51f12b8282SRafael Espindola uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const { 52863cbfbeSPeter Collingbourne return SymTab.getSymbolFlags(getSym(Symb)); 53f12b8282SRafael Espindola } 54f12b8282SRafael Espindola 55435890a4SPeter Collingbourne basic_symbol_iterator IRObjectFile::symbol_begin() const { 56f12b8282SRafael Espindola DataRefImpl Ret; 57863cbfbeSPeter Collingbourne Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data()); 58f12b8282SRafael Espindola return basic_symbol_iterator(BasicSymbolRef(Ret, this)); 59f12b8282SRafael Espindola } 60f12b8282SRafael Espindola 61435890a4SPeter Collingbourne basic_symbol_iterator IRObjectFile::symbol_end() const { 62f12b8282SRafael Espindola DataRefImpl Ret; 63863cbfbeSPeter Collingbourne Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data() + 64863cbfbeSPeter Collingbourne SymTab.symbols().size()); 65f12b8282SRafael Espindola return basic_symbol_iterator(BasicSymbolRef(Ret, this)); 66f12b8282SRafael Espindola } 67f12b8282SRafael Espindola 6845102a24SPeter Collingbourne StringRef IRObjectFile::getTargetTriple() const { 6945102a24SPeter Collingbourne // Each module must have the same target triple, so we arbitrarily access the 7045102a24SPeter Collingbourne // first one. 7145102a24SPeter Collingbourne return Mods[0]->getTargetTriple(); 7245102a24SPeter Collingbourne } 73debb6f6cSPeter Collingbourne 743500f5e3SRafael Espindola Expected<MemoryBufferRef> 753500f5e3SRafael Espindola IRObjectFile::findBitcodeInObject(const ObjectFile &Obj) { 7610039c02SPeter Collingbourne for (const SectionRef &Sec : Obj.sections()) { 77f2fe0141SSteven Wu if (Sec.isBitcode()) { 7810039c02SPeter Collingbourne StringRef SecContents; 7910039c02SPeter Collingbourne if (std::error_code EC = Sec.getContents(SecContents)) 803500f5e3SRafael Espindola return errorCodeToError(EC); 8110039c02SPeter Collingbourne return MemoryBufferRef(SecContents, Obj.getFileName()); 8210039c02SPeter Collingbourne } 8310039c02SPeter Collingbourne } 8410039c02SPeter Collingbourne 853500f5e3SRafael Espindola return errorCodeToError(object_error::bitcode_section_not_found); 8610039c02SPeter Collingbourne } 8710039c02SPeter Collingbourne 883500f5e3SRafael Espindola Expected<MemoryBufferRef> 893500f5e3SRafael Espindola IRObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) { 90264b5d9eSZachary Turner file_magic Type = identify_magic(Object.getBuffer()); 9110039c02SPeter Collingbourne switch (Type) { 92264b5d9eSZachary Turner case file_magic::bitcode: 9310039c02SPeter Collingbourne return Object; 94264b5d9eSZachary Turner case file_magic::elf_relocatable: 95264b5d9eSZachary Turner case file_magic::macho_object: 96264b5d9eSZachary Turner case file_magic::coff_object: { 973fcdf6aeSKevin Enderby Expected<std::unique_ptr<ObjectFile>> ObjFile = 9810039c02SPeter Collingbourne ObjectFile::createObjectFile(Object, Type); 9910039c02SPeter Collingbourne if (!ObjFile) 1003500f5e3SRafael Espindola return ObjFile.takeError(); 10110039c02SPeter Collingbourne return findBitcodeInObject(*ObjFile->get()); 10210039c02SPeter Collingbourne } 10310039c02SPeter Collingbourne default: 1043500f5e3SRafael Espindola return errorCodeToError(object_error::invalid_file_type); 10510039c02SPeter Collingbourne } 10610039c02SPeter Collingbourne } 10710039c02SPeter Collingbourne 108d9445c49SPeter Collingbourne Expected<std::unique_ptr<IRObjectFile>> 10945102a24SPeter Collingbourne IRObjectFile::create(MemoryBufferRef Object, LLVMContext &Context) { 1103500f5e3SRafael Espindola Expected<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object); 11110039c02SPeter Collingbourne if (!BCOrErr) 1123500f5e3SRafael Espindola return BCOrErr.takeError(); 11348af1c2aSRafael Espindola 11445102a24SPeter Collingbourne Expected<std::vector<BitcodeModule>> BMsOrErr = 11545102a24SPeter Collingbourne getBitcodeModuleList(*BCOrErr); 11645102a24SPeter Collingbourne if (!BMsOrErr) 11745102a24SPeter Collingbourne return BMsOrErr.takeError(); 11845102a24SPeter Collingbourne 11945102a24SPeter Collingbourne std::vector<std::unique_ptr<Module>> Mods; 12045102a24SPeter Collingbourne for (auto BM : *BMsOrErr) { 121d9445c49SPeter Collingbourne Expected<std::unique_ptr<Module>> MOrErr = 122a61f5e37STeresa Johnson BM.getLazyModule(Context, /*ShouldLazyLoadMetadata*/ true, 123a61f5e37STeresa Johnson /*IsImporting*/ false); 124d9445c49SPeter Collingbourne if (!MOrErr) 125d9445c49SPeter Collingbourne return MOrErr.takeError(); 126dddd1fd9SRafael Espindola 12745102a24SPeter Collingbourne Mods.push_back(std::move(*MOrErr)); 12845102a24SPeter Collingbourne } 12945102a24SPeter Collingbourne 130c5fecb4fSPeter Collingbourne return std::unique_ptr<IRObjectFile>( 13145102a24SPeter Collingbourne new IRObjectFile(*BCOrErr, std::move(Mods))); 132f12b8282SRafael Espindola } 133c00c2b24SPeter Collingbourne 134c00c2b24SPeter Collingbourne Expected<IRSymtabFile> object::readIRSymtab(MemoryBufferRef MBRef) { 135c00c2b24SPeter Collingbourne IRSymtabFile F; 1363500f5e3SRafael Espindola Expected<MemoryBufferRef> BCOrErr = 137c00c2b24SPeter Collingbourne IRObjectFile::findBitcodeInMemBuffer(MBRef); 138c00c2b24SPeter Collingbourne if (!BCOrErr) 1393500f5e3SRafael Espindola return BCOrErr.takeError(); 140c00c2b24SPeter Collingbourne 1418dde4cbaSPeter Collingbourne Expected<BitcodeFileContents> BFCOrErr = getBitcodeFileContents(*BCOrErr); 1428dde4cbaSPeter Collingbourne if (!BFCOrErr) 1438dde4cbaSPeter Collingbourne return BFCOrErr.takeError(); 144c00c2b24SPeter Collingbourne 1458dde4cbaSPeter Collingbourne Expected<irsymtab::FileContents> FCOrErr = irsymtab::readBitcode(*BFCOrErr); 146c00c2b24SPeter Collingbourne if (!FCOrErr) 147c00c2b24SPeter Collingbourne return FCOrErr.takeError(); 148c00c2b24SPeter Collingbourne 1498dde4cbaSPeter Collingbourne F.Mods = std::move(BFCOrErr->Mods); 150c00c2b24SPeter Collingbourne F.Symtab = std::move(FCOrErr->Symtab); 151c00c2b24SPeter Collingbourne F.Strtab = std::move(FCOrErr->Strtab); 152c00c2b24SPeter Collingbourne F.TheReader = std::move(FCOrErr->TheReader); 153c00c2b24SPeter Collingbourne return std::move(F); 154c00c2b24SPeter Collingbourne } 155