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: 97264b5d9eSZachary Turner case file_magic::coff_object: { 983fcdf6aeSKevin Enderby Expected<std::unique_ptr<ObjectFile>> ObjFile = 9910039c02SPeter Collingbourne ObjectFile::createObjectFile(Object, Type); 10010039c02SPeter Collingbourne if (!ObjFile) 1013500f5e3SRafael Espindola return ObjFile.takeError(); 10210039c02SPeter Collingbourne return findBitcodeInObject(*ObjFile->get()); 10310039c02SPeter Collingbourne } 10410039c02SPeter Collingbourne default: 1053500f5e3SRafael Espindola return errorCodeToError(object_error::invalid_file_type); 10610039c02SPeter Collingbourne } 10710039c02SPeter Collingbourne } 10810039c02SPeter Collingbourne 109d9445c49SPeter Collingbourne Expected<std::unique_ptr<IRObjectFile>> 11045102a24SPeter Collingbourne IRObjectFile::create(MemoryBufferRef Object, LLVMContext &Context) { 1113500f5e3SRafael Espindola Expected<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object); 11210039c02SPeter Collingbourne if (!BCOrErr) 1133500f5e3SRafael Espindola return BCOrErr.takeError(); 11448af1c2aSRafael Espindola 11545102a24SPeter Collingbourne Expected<std::vector<BitcodeModule>> BMsOrErr = 11645102a24SPeter Collingbourne getBitcodeModuleList(*BCOrErr); 11745102a24SPeter Collingbourne if (!BMsOrErr) 11845102a24SPeter Collingbourne return BMsOrErr.takeError(); 11945102a24SPeter Collingbourne 12045102a24SPeter Collingbourne std::vector<std::unique_ptr<Module>> Mods; 12145102a24SPeter Collingbourne for (auto BM : *BMsOrErr) { 122d9445c49SPeter Collingbourne Expected<std::unique_ptr<Module>> MOrErr = 123a61f5e37STeresa Johnson BM.getLazyModule(Context, /*ShouldLazyLoadMetadata*/ true, 124a61f5e37STeresa Johnson /*IsImporting*/ false); 125d9445c49SPeter Collingbourne if (!MOrErr) 126d9445c49SPeter Collingbourne return MOrErr.takeError(); 127dddd1fd9SRafael Espindola 12845102a24SPeter Collingbourne Mods.push_back(std::move(*MOrErr)); 12945102a24SPeter Collingbourne } 13045102a24SPeter Collingbourne 131c5fecb4fSPeter Collingbourne return std::unique_ptr<IRObjectFile>( 13245102a24SPeter Collingbourne new IRObjectFile(*BCOrErr, std::move(Mods))); 133f12b8282SRafael Espindola } 134c00c2b24SPeter Collingbourne 135c00c2b24SPeter Collingbourne Expected<IRSymtabFile> object::readIRSymtab(MemoryBufferRef MBRef) { 136c00c2b24SPeter Collingbourne IRSymtabFile F; 1373500f5e3SRafael Espindola Expected<MemoryBufferRef> BCOrErr = 138c00c2b24SPeter Collingbourne IRObjectFile::findBitcodeInMemBuffer(MBRef); 139c00c2b24SPeter Collingbourne if (!BCOrErr) 1403500f5e3SRafael Espindola return BCOrErr.takeError(); 141c00c2b24SPeter Collingbourne 1428dde4cbaSPeter Collingbourne Expected<BitcodeFileContents> BFCOrErr = getBitcodeFileContents(*BCOrErr); 1438dde4cbaSPeter Collingbourne if (!BFCOrErr) 1448dde4cbaSPeter Collingbourne return BFCOrErr.takeError(); 145c00c2b24SPeter Collingbourne 1468dde4cbaSPeter Collingbourne Expected<irsymtab::FileContents> FCOrErr = irsymtab::readBitcode(*BFCOrErr); 147c00c2b24SPeter Collingbourne if (!FCOrErr) 148c00c2b24SPeter Collingbourne return FCOrErr.takeError(); 149c00c2b24SPeter Collingbourne 1508dde4cbaSPeter Collingbourne F.Mods = std::move(BFCOrErr->Mods); 151c00c2b24SPeter Collingbourne F.Symtab = std::move(FCOrErr->Symtab); 152c00c2b24SPeter Collingbourne F.Strtab = std::move(FCOrErr->Strtab); 153c00c2b24SPeter Collingbourne F.TheReader = std::move(FCOrErr->TheReader); 154*c55cf4afSBill Wendling return std::move(F); 155c00c2b24SPeter Collingbourne } 156