1*0b57cec5SDimitry Andric //===- IRObjectFile.cpp - IR object file implementation ---------*- C++ -*-===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // Part of the IRObjectFile class implementation. 10*0b57cec5SDimitry Andric // 11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 12*0b57cec5SDimitry Andric 13*0b57cec5SDimitry Andric #include "llvm/Object/IRObjectFile.h" 14*0b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 15*0b57cec5SDimitry Andric #include "llvm/BinaryFormat/Magic.h" 16*0b57cec5SDimitry Andric #include "llvm/Bitcode/BitcodeReader.h" 17*0b57cec5SDimitry Andric #include "llvm/IR/GVMaterializer.h" 18*0b57cec5SDimitry Andric #include "llvm/IR/LLVMContext.h" 19*0b57cec5SDimitry Andric #include "llvm/IR/Mangler.h" 20*0b57cec5SDimitry Andric #include "llvm/IR/Module.h" 21*0b57cec5SDimitry Andric #include "llvm/Object/ObjectFile.h" 22*0b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 23*0b57cec5SDimitry Andric #include "llvm/Support/TargetRegistry.h" 24*0b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 25*0b57cec5SDimitry Andric using namespace llvm; 26*0b57cec5SDimitry Andric using namespace object; 27*0b57cec5SDimitry Andric 28*0b57cec5SDimitry Andric IRObjectFile::IRObjectFile(MemoryBufferRef Object, 29*0b57cec5SDimitry Andric std::vector<std::unique_ptr<Module>> Mods) 30*0b57cec5SDimitry Andric : SymbolicFile(Binary::ID_IR, Object), Mods(std::move(Mods)) { 31*0b57cec5SDimitry Andric for (auto &M : this->Mods) 32*0b57cec5SDimitry Andric SymTab.addModule(M.get()); 33*0b57cec5SDimitry Andric } 34*0b57cec5SDimitry Andric 35*0b57cec5SDimitry Andric IRObjectFile::~IRObjectFile() {} 36*0b57cec5SDimitry Andric 37*0b57cec5SDimitry Andric static ModuleSymbolTable::Symbol getSym(DataRefImpl &Symb) { 38*0b57cec5SDimitry Andric return *reinterpret_cast<ModuleSymbolTable::Symbol *>(Symb.p); 39*0b57cec5SDimitry Andric } 40*0b57cec5SDimitry Andric 41*0b57cec5SDimitry Andric void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const { 42*0b57cec5SDimitry Andric Symb.p += sizeof(ModuleSymbolTable::Symbol); 43*0b57cec5SDimitry Andric } 44*0b57cec5SDimitry Andric 45*0b57cec5SDimitry Andric Error IRObjectFile::printSymbolName(raw_ostream &OS, DataRefImpl Symb) const { 46*0b57cec5SDimitry Andric SymTab.printSymbolName(OS, getSym(Symb)); 47*0b57cec5SDimitry Andric return Error::success(); 48*0b57cec5SDimitry Andric } 49*0b57cec5SDimitry Andric 50*0b57cec5SDimitry Andric uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const { 51*0b57cec5SDimitry Andric return SymTab.getSymbolFlags(getSym(Symb)); 52*0b57cec5SDimitry Andric } 53*0b57cec5SDimitry Andric 54*0b57cec5SDimitry Andric basic_symbol_iterator IRObjectFile::symbol_begin() const { 55*0b57cec5SDimitry Andric DataRefImpl Ret; 56*0b57cec5SDimitry Andric Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data()); 57*0b57cec5SDimitry Andric return basic_symbol_iterator(BasicSymbolRef(Ret, this)); 58*0b57cec5SDimitry Andric } 59*0b57cec5SDimitry Andric 60*0b57cec5SDimitry Andric basic_symbol_iterator IRObjectFile::symbol_end() const { 61*0b57cec5SDimitry Andric DataRefImpl Ret; 62*0b57cec5SDimitry Andric Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data() + 63*0b57cec5SDimitry Andric SymTab.symbols().size()); 64*0b57cec5SDimitry Andric return basic_symbol_iterator(BasicSymbolRef(Ret, this)); 65*0b57cec5SDimitry Andric } 66*0b57cec5SDimitry Andric 67*0b57cec5SDimitry Andric StringRef IRObjectFile::getTargetTriple() const { 68*0b57cec5SDimitry Andric // Each module must have the same target triple, so we arbitrarily access the 69*0b57cec5SDimitry Andric // first one. 70*0b57cec5SDimitry Andric return Mods[0]->getTargetTriple(); 71*0b57cec5SDimitry Andric } 72*0b57cec5SDimitry Andric 73*0b57cec5SDimitry Andric Expected<MemoryBufferRef> 74*0b57cec5SDimitry Andric IRObjectFile::findBitcodeInObject(const ObjectFile &Obj) { 75*0b57cec5SDimitry Andric for (const SectionRef &Sec : Obj.sections()) { 76*0b57cec5SDimitry Andric if (Sec.isBitcode()) { 77*0b57cec5SDimitry Andric Expected<StringRef> Contents = Sec.getContents(); 78*0b57cec5SDimitry Andric if (!Contents) 79*0b57cec5SDimitry Andric return Contents.takeError(); 80*0b57cec5SDimitry Andric if (Contents->size() <= 1) 81*0b57cec5SDimitry Andric return errorCodeToError(object_error::bitcode_section_not_found); 82*0b57cec5SDimitry Andric return MemoryBufferRef(*Contents, Obj.getFileName()); 83*0b57cec5SDimitry Andric } 84*0b57cec5SDimitry Andric } 85*0b57cec5SDimitry Andric 86*0b57cec5SDimitry Andric return errorCodeToError(object_error::bitcode_section_not_found); 87*0b57cec5SDimitry Andric } 88*0b57cec5SDimitry Andric 89*0b57cec5SDimitry Andric Expected<MemoryBufferRef> 90*0b57cec5SDimitry Andric IRObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) { 91*0b57cec5SDimitry Andric file_magic Type = identify_magic(Object.getBuffer()); 92*0b57cec5SDimitry Andric switch (Type) { 93*0b57cec5SDimitry Andric case file_magic::bitcode: 94*0b57cec5SDimitry Andric return Object; 95*0b57cec5SDimitry Andric case file_magic::elf_relocatable: 96*0b57cec5SDimitry Andric case file_magic::macho_object: 97*0b57cec5SDimitry Andric case file_magic::coff_object: { 98*0b57cec5SDimitry Andric Expected<std::unique_ptr<ObjectFile>> ObjFile = 99*0b57cec5SDimitry Andric ObjectFile::createObjectFile(Object, Type); 100*0b57cec5SDimitry Andric if (!ObjFile) 101*0b57cec5SDimitry Andric return ObjFile.takeError(); 102*0b57cec5SDimitry Andric return findBitcodeInObject(*ObjFile->get()); 103*0b57cec5SDimitry Andric } 104*0b57cec5SDimitry Andric default: 105*0b57cec5SDimitry Andric return errorCodeToError(object_error::invalid_file_type); 106*0b57cec5SDimitry Andric } 107*0b57cec5SDimitry Andric } 108*0b57cec5SDimitry Andric 109*0b57cec5SDimitry Andric Expected<std::unique_ptr<IRObjectFile>> 110*0b57cec5SDimitry Andric IRObjectFile::create(MemoryBufferRef Object, LLVMContext &Context) { 111*0b57cec5SDimitry Andric Expected<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object); 112*0b57cec5SDimitry Andric if (!BCOrErr) 113*0b57cec5SDimitry Andric return BCOrErr.takeError(); 114*0b57cec5SDimitry Andric 115*0b57cec5SDimitry Andric Expected<std::vector<BitcodeModule>> BMsOrErr = 116*0b57cec5SDimitry Andric getBitcodeModuleList(*BCOrErr); 117*0b57cec5SDimitry Andric if (!BMsOrErr) 118*0b57cec5SDimitry Andric return BMsOrErr.takeError(); 119*0b57cec5SDimitry Andric 120*0b57cec5SDimitry Andric std::vector<std::unique_ptr<Module>> Mods; 121*0b57cec5SDimitry Andric for (auto BM : *BMsOrErr) { 122*0b57cec5SDimitry Andric Expected<std::unique_ptr<Module>> MOrErr = 123*0b57cec5SDimitry Andric BM.getLazyModule(Context, /*ShouldLazyLoadMetadata*/ true, 124*0b57cec5SDimitry Andric /*IsImporting*/ false); 125*0b57cec5SDimitry Andric if (!MOrErr) 126*0b57cec5SDimitry Andric return MOrErr.takeError(); 127*0b57cec5SDimitry Andric 128*0b57cec5SDimitry Andric Mods.push_back(std::move(*MOrErr)); 129*0b57cec5SDimitry Andric } 130*0b57cec5SDimitry Andric 131*0b57cec5SDimitry Andric return std::unique_ptr<IRObjectFile>( 132*0b57cec5SDimitry Andric new IRObjectFile(*BCOrErr, std::move(Mods))); 133*0b57cec5SDimitry Andric } 134*0b57cec5SDimitry Andric 135*0b57cec5SDimitry Andric Expected<IRSymtabFile> object::readIRSymtab(MemoryBufferRef MBRef) { 136*0b57cec5SDimitry Andric IRSymtabFile F; 137*0b57cec5SDimitry Andric Expected<MemoryBufferRef> BCOrErr = 138*0b57cec5SDimitry Andric IRObjectFile::findBitcodeInMemBuffer(MBRef); 139*0b57cec5SDimitry Andric if (!BCOrErr) 140*0b57cec5SDimitry Andric return BCOrErr.takeError(); 141*0b57cec5SDimitry Andric 142*0b57cec5SDimitry Andric Expected<BitcodeFileContents> BFCOrErr = getBitcodeFileContents(*BCOrErr); 143*0b57cec5SDimitry Andric if (!BFCOrErr) 144*0b57cec5SDimitry Andric return BFCOrErr.takeError(); 145*0b57cec5SDimitry Andric 146*0b57cec5SDimitry Andric Expected<irsymtab::FileContents> FCOrErr = irsymtab::readBitcode(*BFCOrErr); 147*0b57cec5SDimitry Andric if (!FCOrErr) 148*0b57cec5SDimitry Andric return FCOrErr.takeError(); 149*0b57cec5SDimitry Andric 150*0b57cec5SDimitry Andric F.Mods = std::move(BFCOrErr->Mods); 151*0b57cec5SDimitry Andric F.Symtab = std::move(FCOrErr->Symtab); 152*0b57cec5SDimitry Andric F.Strtab = std::move(FCOrErr->Strtab); 153*0b57cec5SDimitry Andric F.TheReader = std::move(FCOrErr->TheReader); 154*0b57cec5SDimitry Andric return std::move(F); 155*0b57cec5SDimitry Andric } 156