1f12b8282SRafael Espindola //===- IRObjectFile.cpp - IR object file implementation ---------*- C++ -*-===// 2f12b8282SRafael Espindola // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler 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" 14*e72c195fSserge-sans-paille #include "llvm/ADT/ArrayRef.h" 15*e72c195fSserge-sans-paille #include "llvm/ADT/DenseMapInfo.h" 16*e72c195fSserge-sans-paille #include "llvm/ADT/PointerUnion.h" 17264b5d9eSZachary Turner #include "llvm/BinaryFormat/Magic.h" 18ad17679aSTeresa Johnson #include "llvm/Bitcode/BitcodeReader.h" 19f12b8282SRafael Espindola #include "llvm/IR/Module.h" 2010039c02SPeter Collingbourne #include "llvm/Object/ObjectFile.h" 21f12b8282SRafael Espindola using namespace llvm; 22f12b8282SRafael Espindola using namespace object; 23f12b8282SRafael Espindola 24*e72c195fSserge-sans-paille namespace llvm { 25*e72c195fSserge-sans-paille class LLVMContext; 26*e72c195fSserge-sans-paille class raw_ostream; 27*e72c195fSserge-sans-paille } // namespace llvm 28*e72c195fSserge-sans-paille 2945102a24SPeter Collingbourne IRObjectFile::IRObjectFile(MemoryBufferRef Object, 3045102a24SPeter Collingbourne std::vector<std::unique_ptr<Module>> Mods) 3145102a24SPeter Collingbourne : SymbolicFile(Binary::ID_IR, Object), Mods(std::move(Mods)) { 3245102a24SPeter Collingbourne for (auto &M : this->Mods) 33863cbfbeSPeter Collingbourne SymTab.addModule(M.get()); 34f12b8282SRafael Espindola } 35f12b8282SRafael Espindola 363a3cb929SKazu Hirata IRObjectFile::~IRObjectFile() = default; 3713b69d63SRafael Espindola 38863cbfbeSPeter Collingbourne static ModuleSymbolTable::Symbol getSym(DataRefImpl &Symb) { 39863cbfbeSPeter Collingbourne return *reinterpret_cast<ModuleSymbolTable::Symbol *>(Symb.p); 40863cbfbeSPeter Collingbourne } 41863cbfbeSPeter Collingbourne 42f12b8282SRafael Espindola void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const { 43863cbfbeSPeter Collingbourne Symb.p += sizeof(ModuleSymbolTable::Symbol); 44f12b8282SRafael Espindola } 45f12b8282SRafael Espindola 46e357ca82SFangrui Song Error IRObjectFile::printSymbolName(raw_ostream &OS, DataRefImpl Symb) const { 47863cbfbeSPeter Collingbourne SymTab.printSymbolName(OS, getSym(Symb)); 48e357ca82SFangrui Song return Error::success(); 49f12b8282SRafael Espindola } 50f12b8282SRafael Espindola 51ac00376aSvgxbj Expected<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()) { 78e183340cSFangrui Song Expected<StringRef> Contents = Sec.getContents(); 79e183340cSFangrui Song if (!Contents) 80e183340cSFangrui Song return Contents.takeError(); 81e183340cSFangrui Song if (Contents->size() <= 1) 825a593547SSteven Wu return errorCodeToError(object_error::bitcode_section_not_found); 83e183340cSFangrui Song return MemoryBufferRef(*Contents, Obj.getFileName()); 8410039c02SPeter Collingbourne } 8510039c02SPeter Collingbourne } 8610039c02SPeter Collingbourne 873500f5e3SRafael Espindola return errorCodeToError(object_error::bitcode_section_not_found); 8810039c02SPeter Collingbourne } 8910039c02SPeter Collingbourne 903500f5e3SRafael Espindola Expected<MemoryBufferRef> 913500f5e3SRafael Espindola IRObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) { 92264b5d9eSZachary Turner file_magic Type = identify_magic(Object.getBuffer()); 9310039c02SPeter Collingbourne switch (Type) { 94264b5d9eSZachary Turner case file_magic::bitcode: 9510039c02SPeter Collingbourne return Object; 96264b5d9eSZachary Turner case file_magic::elf_relocatable: 97264b5d9eSZachary Turner case file_magic::macho_object: 982a68573aSSam Clegg case file_magic::wasm_object: 99264b5d9eSZachary Turner case file_magic::coff_object: { 1003fcdf6aeSKevin Enderby Expected<std::unique_ptr<ObjectFile>> ObjFile = 10110039c02SPeter Collingbourne ObjectFile::createObjectFile(Object, Type); 10210039c02SPeter Collingbourne if (!ObjFile) 1033500f5e3SRafael Espindola return ObjFile.takeError(); 10410039c02SPeter Collingbourne return findBitcodeInObject(*ObjFile->get()); 10510039c02SPeter Collingbourne } 10610039c02SPeter Collingbourne default: 1073500f5e3SRafael Espindola return errorCodeToError(object_error::invalid_file_type); 10810039c02SPeter Collingbourne } 10910039c02SPeter Collingbourne } 11010039c02SPeter Collingbourne 111d9445c49SPeter Collingbourne Expected<std::unique_ptr<IRObjectFile>> 11245102a24SPeter Collingbourne IRObjectFile::create(MemoryBufferRef Object, LLVMContext &Context) { 1133500f5e3SRafael Espindola Expected<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object); 11410039c02SPeter Collingbourne if (!BCOrErr) 1153500f5e3SRafael Espindola return BCOrErr.takeError(); 11648af1c2aSRafael Espindola 11745102a24SPeter Collingbourne Expected<std::vector<BitcodeModule>> BMsOrErr = 11845102a24SPeter Collingbourne getBitcodeModuleList(*BCOrErr); 11945102a24SPeter Collingbourne if (!BMsOrErr) 12045102a24SPeter Collingbourne return BMsOrErr.takeError(); 12145102a24SPeter Collingbourne 12245102a24SPeter Collingbourne std::vector<std::unique_ptr<Module>> Mods; 12345102a24SPeter Collingbourne for (auto BM : *BMsOrErr) { 124d9445c49SPeter Collingbourne Expected<std::unique_ptr<Module>> MOrErr = 125a61f5e37STeresa Johnson BM.getLazyModule(Context, /*ShouldLazyLoadMetadata*/ true, 126a61f5e37STeresa Johnson /*IsImporting*/ false); 127d9445c49SPeter Collingbourne if (!MOrErr) 128d9445c49SPeter Collingbourne return MOrErr.takeError(); 129dddd1fd9SRafael Espindola 13045102a24SPeter Collingbourne Mods.push_back(std::move(*MOrErr)); 13145102a24SPeter Collingbourne } 13245102a24SPeter Collingbourne 133c5fecb4fSPeter Collingbourne return std::unique_ptr<IRObjectFile>( 13445102a24SPeter Collingbourne new IRObjectFile(*BCOrErr, std::move(Mods))); 135f12b8282SRafael Espindola } 136c00c2b24SPeter Collingbourne 137c00c2b24SPeter Collingbourne Expected<IRSymtabFile> object::readIRSymtab(MemoryBufferRef MBRef) { 138c00c2b24SPeter Collingbourne IRSymtabFile F; 1393500f5e3SRafael Espindola Expected<MemoryBufferRef> BCOrErr = 140c00c2b24SPeter Collingbourne IRObjectFile::findBitcodeInMemBuffer(MBRef); 141c00c2b24SPeter Collingbourne if (!BCOrErr) 1423500f5e3SRafael Espindola return BCOrErr.takeError(); 143c00c2b24SPeter Collingbourne 1448dde4cbaSPeter Collingbourne Expected<BitcodeFileContents> BFCOrErr = getBitcodeFileContents(*BCOrErr); 1458dde4cbaSPeter Collingbourne if (!BFCOrErr) 1468dde4cbaSPeter Collingbourne return BFCOrErr.takeError(); 147c00c2b24SPeter Collingbourne 1488dde4cbaSPeter Collingbourne Expected<irsymtab::FileContents> FCOrErr = irsymtab::readBitcode(*BFCOrErr); 149c00c2b24SPeter Collingbourne if (!FCOrErr) 150c00c2b24SPeter Collingbourne return FCOrErr.takeError(); 151c00c2b24SPeter Collingbourne 1528dde4cbaSPeter Collingbourne F.Mods = std::move(BFCOrErr->Mods); 153c00c2b24SPeter Collingbourne F.Symtab = std::move(FCOrErr->Symtab); 154c00c2b24SPeter Collingbourne F.Strtab = std::move(FCOrErr->Strtab); 155c00c2b24SPeter Collingbourne F.TheReader = std::move(FCOrErr->TheReader); 156c55cf4afSBill Wendling return std::move(F); 157c00c2b24SPeter Collingbourne } 158