1274955Ssvnmir//===- IRObjectFile.cpp - IR object file implementation ---------*- C++ -*-===// 2274955Ssvnmir// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6274955Ssvnmir// 7274955Ssvnmir//===----------------------------------------------------------------------===// 8274955Ssvnmir// 9274955Ssvnmir// Part of the IRObjectFile class implementation. 10274955Ssvnmir// 11274955Ssvnmir//===----------------------------------------------------------------------===// 12274955Ssvnmir 13274955Ssvnmir#include "llvm/Object/IRObjectFile.h" 14288943Sdim#include "llvm/ADT/STLExtras.h" 15321369Sdim#include "llvm/BinaryFormat/Magic.h" 16314564Sdim#include "llvm/Bitcode/BitcodeReader.h" 17280031Sdim#include "llvm/IR/GVMaterializer.h" 18274955Ssvnmir#include "llvm/IR/LLVMContext.h" 19274955Ssvnmir#include "llvm/IR/Mangler.h" 20274955Ssvnmir#include "llvm/IR/Module.h" 21280031Sdim#include "llvm/Object/ObjectFile.h" 22274955Ssvnmir#include "llvm/Support/MemoryBuffer.h" 23274955Ssvnmir#include "llvm/Support/TargetRegistry.h" 24274955Ssvnmir#include "llvm/Support/raw_ostream.h" 25274955Ssvnmirusing namespace llvm; 26274955Ssvnmirusing namespace object; 27274955Ssvnmir 28314564SdimIRObjectFile::IRObjectFile(MemoryBufferRef Object, 29314564Sdim std::vector<std::unique_ptr<Module>> Mods) 30314564Sdim : SymbolicFile(Binary::ID_IR, Object), Mods(std::move(Mods)) { 31314564Sdim for (auto &M : this->Mods) 32314564Sdim SymTab.addModule(M.get()); 33309124Sdim} 34274955Ssvnmir 35314564SdimIRObjectFile::~IRObjectFile() {} 36274955Ssvnmir 37314564Sdimstatic ModuleSymbolTable::Symbol getSym(DataRefImpl &Symb) { 38314564Sdim return *reinterpret_cast<ModuleSymbolTable::Symbol *>(Symb.p); 39274955Ssvnmir} 40274955Ssvnmir 41274955Ssvnmirvoid IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const { 42314564Sdim Symb.p += sizeof(ModuleSymbolTable::Symbol); 43274955Ssvnmir} 44274955Ssvnmir 45353358SdimError IRObjectFile::printSymbolName(raw_ostream &OS, DataRefImpl Symb) const { 46314564Sdim SymTab.printSymbolName(OS, getSym(Symb)); 47353358Sdim return Error::success(); 48274955Ssvnmir} 49274955Ssvnmir 50274955Ssvnmiruint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const { 51314564Sdim return SymTab.getSymbolFlags(getSym(Symb)); 52274955Ssvnmir} 53274955Ssvnmir 54314564Sdimbasic_symbol_iterator IRObjectFile::symbol_begin() const { 55274955Ssvnmir DataRefImpl Ret; 56314564Sdim Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data()); 57274955Ssvnmir return basic_symbol_iterator(BasicSymbolRef(Ret, this)); 58274955Ssvnmir} 59274955Ssvnmir 60314564Sdimbasic_symbol_iterator IRObjectFile::symbol_end() const { 61274955Ssvnmir DataRefImpl Ret; 62314564Sdim Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data() + 63314564Sdim SymTab.symbols().size()); 64274955Ssvnmir return basic_symbol_iterator(BasicSymbolRef(Ret, this)); 65274955Ssvnmir} 66274955Ssvnmir 67314564SdimStringRef IRObjectFile::getTargetTriple() const { 68314564Sdim // Each module must have the same target triple, so we arbitrarily access the 69314564Sdim // first one. 70314564Sdim return Mods[0]->getTargetTriple(); 71314564Sdim} 72314564Sdim 73327952SdimExpected<MemoryBufferRef> 74327952SdimIRObjectFile::findBitcodeInObject(const ObjectFile &Obj) { 75280031Sdim for (const SectionRef &Sec : Obj.sections()) { 76309124Sdim if (Sec.isBitcode()) { 77353358Sdim Expected<StringRef> Contents = Sec.getContents(); 78353358Sdim if (!Contents) 79353358Sdim return Contents.takeError(); 80353358Sdim if (Contents->size() <= 1) 81353358Sdim return errorCodeToError(object_error::bitcode_section_not_found); 82353358Sdim return MemoryBufferRef(*Contents, Obj.getFileName()); 83280031Sdim } 84280031Sdim } 85280031Sdim 86327952Sdim return errorCodeToError(object_error::bitcode_section_not_found); 87280031Sdim} 88280031Sdim 89327952SdimExpected<MemoryBufferRef> 90327952SdimIRObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) { 91321369Sdim file_magic Type = identify_magic(Object.getBuffer()); 92280031Sdim switch (Type) { 93321369Sdim case file_magic::bitcode: 94280031Sdim return Object; 95321369Sdim case file_magic::elf_relocatable: 96321369Sdim case file_magic::macho_object: 97321369Sdim case file_magic::coff_object: { 98309124Sdim Expected<std::unique_ptr<ObjectFile>> ObjFile = 99280031Sdim ObjectFile::createObjectFile(Object, Type); 100280031Sdim if (!ObjFile) 101327952Sdim return ObjFile.takeError(); 102280031Sdim return findBitcodeInObject(*ObjFile->get()); 103280031Sdim } 104280031Sdim default: 105327952Sdim return errorCodeToError(object_error::invalid_file_type); 106280031Sdim } 107280031Sdim} 108280031Sdim 109314564SdimExpected<std::unique_ptr<IRObjectFile>> 110314564SdimIRObjectFile::create(MemoryBufferRef Object, LLVMContext &Context) { 111327952Sdim Expected<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object); 112280031Sdim if (!BCOrErr) 113327952Sdim return BCOrErr.takeError(); 114280031Sdim 115314564Sdim Expected<std::vector<BitcodeModule>> BMsOrErr = 116314564Sdim getBitcodeModuleList(*BCOrErr); 117314564Sdim if (!BMsOrErr) 118314564Sdim return BMsOrErr.takeError(); 119280031Sdim 120314564Sdim std::vector<std::unique_ptr<Module>> Mods; 121314564Sdim for (auto BM : *BMsOrErr) { 122314564Sdim Expected<std::unique_ptr<Module>> MOrErr = 123314564Sdim BM.getLazyModule(Context, /*ShouldLazyLoadMetadata*/ true, 124314564Sdim /*IsImporting*/ false); 125314564Sdim if (!MOrErr) 126314564Sdim return MOrErr.takeError(); 127274955Ssvnmir 128314564Sdim Mods.push_back(std::move(*MOrErr)); 129314564Sdim } 130314564Sdim 131314564Sdim return std::unique_ptr<IRObjectFile>( 132314564Sdim new IRObjectFile(*BCOrErr, std::move(Mods))); 133274955Ssvnmir} 134321369Sdim 135321369SdimExpected<IRSymtabFile> object::readIRSymtab(MemoryBufferRef MBRef) { 136321369Sdim IRSymtabFile F; 137327952Sdim Expected<MemoryBufferRef> BCOrErr = 138321369Sdim IRObjectFile::findBitcodeInMemBuffer(MBRef); 139321369Sdim if (!BCOrErr) 140327952Sdim return BCOrErr.takeError(); 141321369Sdim 142321369Sdim Expected<BitcodeFileContents> BFCOrErr = getBitcodeFileContents(*BCOrErr); 143321369Sdim if (!BFCOrErr) 144321369Sdim return BFCOrErr.takeError(); 145321369Sdim 146321369Sdim Expected<irsymtab::FileContents> FCOrErr = irsymtab::readBitcode(*BFCOrErr); 147321369Sdim if (!FCOrErr) 148321369Sdim return FCOrErr.takeError(); 149321369Sdim 150321369Sdim F.Mods = std::move(BFCOrErr->Mods); 151321369Sdim F.Symtab = std::move(FCOrErr->Symtab); 152321369Sdim F.Strtab = std::move(FCOrErr->Strtab); 153321369Sdim F.TheReader = std::move(FCOrErr->TheReader); 154321369Sdim return std::move(F); 155321369Sdim} 156