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" 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 45e357ca82SFangrui Song Error IRObjectFile::printSymbolName(raw_ostream &OS, DataRefImpl Symb) const { 46863cbfbeSPeter Collingbourne SymTab.printSymbolName(OS, getSym(Symb)); 47e357ca82SFangrui Song return Error::success(); 48f12b8282SRafael Espindola } 49f12b8282SRafael Espindola 50f12b8282SRafael Espindola uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const { 51863cbfbeSPeter Collingbourne return SymTab.getSymbolFlags(getSym(Symb)); 52f12b8282SRafael Espindola } 53f12b8282SRafael Espindola 54435890a4SPeter Collingbourne basic_symbol_iterator IRObjectFile::symbol_begin() const { 55f12b8282SRafael Espindola DataRefImpl Ret; 56863cbfbeSPeter Collingbourne Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data()); 57f12b8282SRafael Espindola return basic_symbol_iterator(BasicSymbolRef(Ret, this)); 58f12b8282SRafael Espindola } 59f12b8282SRafael Espindola 60435890a4SPeter Collingbourne basic_symbol_iterator IRObjectFile::symbol_end() const { 61f12b8282SRafael Espindola DataRefImpl Ret; 62863cbfbeSPeter Collingbourne Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data() + 63863cbfbeSPeter Collingbourne SymTab.symbols().size()); 64f12b8282SRafael Espindola return basic_symbol_iterator(BasicSymbolRef(Ret, this)); 65f12b8282SRafael Espindola } 66f12b8282SRafael Espindola 6745102a24SPeter Collingbourne StringRef IRObjectFile::getTargetTriple() const { 6845102a24SPeter Collingbourne // Each module must have the same target triple, so we arbitrarily access the 6945102a24SPeter Collingbourne // first one. 7045102a24SPeter Collingbourne return Mods[0]->getTargetTriple(); 7145102a24SPeter Collingbourne } 72debb6f6cSPeter Collingbourne 733500f5e3SRafael Espindola Expected<MemoryBufferRef> 743500f5e3SRafael Espindola IRObjectFile::findBitcodeInObject(const ObjectFile &Obj) { 7510039c02SPeter Collingbourne for (const SectionRef &Sec : Obj.sections()) { 76f2fe0141SSteven Wu if (Sec.isBitcode()) { 77e183340cSFangrui Song Expected<StringRef> Contents = Sec.getContents(); 78e183340cSFangrui Song if (!Contents) 79e183340cSFangrui Song return Contents.takeError(); 80e183340cSFangrui Song if (Contents->size() <= 1) 815a593547SSteven Wu return errorCodeToError(object_error::bitcode_section_not_found); 82e183340cSFangrui Song return MemoryBufferRef(*Contents, Obj.getFileName()); 8310039c02SPeter Collingbourne } 8410039c02SPeter Collingbourne } 8510039c02SPeter Collingbourne 863500f5e3SRafael Espindola return errorCodeToError(object_error::bitcode_section_not_found); 8710039c02SPeter Collingbourne } 8810039c02SPeter Collingbourne 893500f5e3SRafael Espindola Expected<MemoryBufferRef> 903500f5e3SRafael Espindola IRObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) { 91264b5d9eSZachary Turner file_magic Type = identify_magic(Object.getBuffer()); 9210039c02SPeter Collingbourne switch (Type) { 93264b5d9eSZachary Turner case file_magic::bitcode: 9410039c02SPeter Collingbourne return Object; 95264b5d9eSZachary Turner case file_magic::elf_relocatable: 96264b5d9eSZachary Turner case file_magic::macho_object: 97*2a68573aSSam Clegg case file_magic::wasm_object: 98264b5d9eSZachary Turner case file_magic::coff_object: { 993fcdf6aeSKevin Enderby Expected<std::unique_ptr<ObjectFile>> ObjFile = 10010039c02SPeter Collingbourne ObjectFile::createObjectFile(Object, Type); 10110039c02SPeter Collingbourne if (!ObjFile) 1023500f5e3SRafael Espindola return ObjFile.takeError(); 10310039c02SPeter Collingbourne return findBitcodeInObject(*ObjFile->get()); 10410039c02SPeter Collingbourne } 10510039c02SPeter Collingbourne default: 1063500f5e3SRafael Espindola return errorCodeToError(object_error::invalid_file_type); 10710039c02SPeter Collingbourne } 10810039c02SPeter Collingbourne } 10910039c02SPeter Collingbourne 110d9445c49SPeter Collingbourne Expected<std::unique_ptr<IRObjectFile>> 11145102a24SPeter Collingbourne IRObjectFile::create(MemoryBufferRef Object, LLVMContext &Context) { 1123500f5e3SRafael Espindola Expected<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object); 11310039c02SPeter Collingbourne if (!BCOrErr) 1143500f5e3SRafael Espindola return BCOrErr.takeError(); 11548af1c2aSRafael Espindola 11645102a24SPeter Collingbourne Expected<std::vector<BitcodeModule>> BMsOrErr = 11745102a24SPeter Collingbourne getBitcodeModuleList(*BCOrErr); 11845102a24SPeter Collingbourne if (!BMsOrErr) 11945102a24SPeter Collingbourne return BMsOrErr.takeError(); 12045102a24SPeter Collingbourne 12145102a24SPeter Collingbourne std::vector<std::unique_ptr<Module>> Mods; 12245102a24SPeter Collingbourne for (auto BM : *BMsOrErr) { 123d9445c49SPeter Collingbourne Expected<std::unique_ptr<Module>> MOrErr = 124a61f5e37STeresa Johnson BM.getLazyModule(Context, /*ShouldLazyLoadMetadata*/ true, 125a61f5e37STeresa Johnson /*IsImporting*/ false); 126d9445c49SPeter Collingbourne if (!MOrErr) 127d9445c49SPeter Collingbourne return MOrErr.takeError(); 128dddd1fd9SRafael Espindola 12945102a24SPeter Collingbourne Mods.push_back(std::move(*MOrErr)); 13045102a24SPeter Collingbourne } 13145102a24SPeter Collingbourne 132c5fecb4fSPeter Collingbourne return std::unique_ptr<IRObjectFile>( 13345102a24SPeter Collingbourne new IRObjectFile(*BCOrErr, std::move(Mods))); 134f12b8282SRafael Espindola } 135c00c2b24SPeter Collingbourne 136c00c2b24SPeter Collingbourne Expected<IRSymtabFile> object::readIRSymtab(MemoryBufferRef MBRef) { 137c00c2b24SPeter Collingbourne IRSymtabFile F; 1383500f5e3SRafael Espindola Expected<MemoryBufferRef> BCOrErr = 139c00c2b24SPeter Collingbourne IRObjectFile::findBitcodeInMemBuffer(MBRef); 140c00c2b24SPeter Collingbourne if (!BCOrErr) 1413500f5e3SRafael Espindola return BCOrErr.takeError(); 142c00c2b24SPeter Collingbourne 1438dde4cbaSPeter Collingbourne Expected<BitcodeFileContents> BFCOrErr = getBitcodeFileContents(*BCOrErr); 1448dde4cbaSPeter Collingbourne if (!BFCOrErr) 1458dde4cbaSPeter Collingbourne return BFCOrErr.takeError(); 146c00c2b24SPeter Collingbourne 1478dde4cbaSPeter Collingbourne Expected<irsymtab::FileContents> FCOrErr = irsymtab::readBitcode(*BFCOrErr); 148c00c2b24SPeter Collingbourne if (!FCOrErr) 149c00c2b24SPeter Collingbourne return FCOrErr.takeError(); 150c00c2b24SPeter Collingbourne 1518dde4cbaSPeter Collingbourne F.Mods = std::move(BFCOrErr->Mods); 152c00c2b24SPeter Collingbourne F.Symtab = std::move(FCOrErr->Symtab); 153c00c2b24SPeter Collingbourne F.Strtab = std::move(FCOrErr->Strtab); 154c00c2b24SPeter Collingbourne F.TheReader = std::move(FCOrErr->TheReader); 155c55cf4afSBill Wendling return std::move(F); 156c00c2b24SPeter Collingbourne } 157