xref: /src/contrib/llvm-project/llvm/lib/Object/IRObjectFile.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
15ca98fd9SDimitry Andric //===- IRObjectFile.cpp - IR object file implementation ---------*- C++ -*-===//
25ca98fd9SDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65ca98fd9SDimitry Andric //
75ca98fd9SDimitry Andric //===----------------------------------------------------------------------===//
85ca98fd9SDimitry Andric //
95ca98fd9SDimitry Andric // Part of the IRObjectFile class implementation.
105ca98fd9SDimitry Andric //
115ca98fd9SDimitry Andric //===----------------------------------------------------------------------===//
125ca98fd9SDimitry Andric 
135ca98fd9SDimitry Andric #include "llvm/Object/IRObjectFile.h"
14145449b1SDimitry Andric #include "llvm/ADT/ArrayRef.h"
157ab83427SDimitry Andric #include "llvm/BinaryFormat/Magic.h"
16b915e9e0SDimitry Andric #include "llvm/Bitcode/BitcodeReader.h"
175ca98fd9SDimitry Andric #include "llvm/IR/Module.h"
1867c32a98SDimitry Andric #include "llvm/Object/ObjectFile.h"
195ca98fd9SDimitry Andric using namespace llvm;
205ca98fd9SDimitry Andric using namespace object;
215ca98fd9SDimitry Andric 
22145449b1SDimitry Andric namespace llvm {
23145449b1SDimitry Andric class LLVMContext;
24145449b1SDimitry Andric class raw_ostream;
25145449b1SDimitry Andric } // namespace llvm
26145449b1SDimitry Andric 
IRObjectFile(MemoryBufferRef Object,std::vector<std::unique_ptr<Module>> Mods)27b915e9e0SDimitry Andric IRObjectFile::IRObjectFile(MemoryBufferRef Object,
28b915e9e0SDimitry Andric                            std::vector<std::unique_ptr<Module>> Mods)
29b915e9e0SDimitry Andric     : SymbolicFile(Binary::ID_IR, Object), Mods(std::move(Mods)) {
30b915e9e0SDimitry Andric   for (auto &M : this->Mods)
31b915e9e0SDimitry Andric     SymTab.addModule(M.get());
3201095a5dSDimitry Andric }
335ca98fd9SDimitry Andric 
34145449b1SDimitry Andric IRObjectFile::~IRObjectFile() = default;
355ca98fd9SDimitry Andric 
getSym(DataRefImpl & Symb)36b915e9e0SDimitry Andric static ModuleSymbolTable::Symbol getSym(DataRefImpl &Symb) {
37b915e9e0SDimitry Andric   return *reinterpret_cast<ModuleSymbolTable::Symbol *>(Symb.p);
385ca98fd9SDimitry Andric }
395ca98fd9SDimitry Andric 
moveSymbolNext(DataRefImpl & Symb) const405ca98fd9SDimitry Andric void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
41b915e9e0SDimitry Andric   Symb.p += sizeof(ModuleSymbolTable::Symbol);
425ca98fd9SDimitry Andric }
435ca98fd9SDimitry Andric 
printSymbolName(raw_ostream & OS,DataRefImpl Symb) const44e6d15924SDimitry Andric Error IRObjectFile::printSymbolName(raw_ostream &OS, DataRefImpl Symb) const {
45b915e9e0SDimitry Andric   SymTab.printSymbolName(OS, getSym(Symb));
46e6d15924SDimitry Andric   return Error::success();
475ca98fd9SDimitry Andric }
485ca98fd9SDimitry Andric 
getSymbolFlags(DataRefImpl Symb) const49cfca06d7SDimitry Andric Expected<uint32_t> IRObjectFile::getSymbolFlags(DataRefImpl Symb) const {
50b915e9e0SDimitry Andric   return SymTab.getSymbolFlags(getSym(Symb));
515ca98fd9SDimitry Andric }
525ca98fd9SDimitry Andric 
symbol_begin() const53b915e9e0SDimitry Andric basic_symbol_iterator IRObjectFile::symbol_begin() const {
545ca98fd9SDimitry Andric   DataRefImpl Ret;
55b915e9e0SDimitry Andric   Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data());
565ca98fd9SDimitry Andric   return basic_symbol_iterator(BasicSymbolRef(Ret, this));
575ca98fd9SDimitry Andric }
585ca98fd9SDimitry Andric 
symbol_end() const59b915e9e0SDimitry Andric basic_symbol_iterator IRObjectFile::symbol_end() const {
605ca98fd9SDimitry Andric   DataRefImpl Ret;
61b915e9e0SDimitry Andric   Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data() +
62b915e9e0SDimitry Andric                                       SymTab.symbols().size());
635ca98fd9SDimitry Andric   return basic_symbol_iterator(BasicSymbolRef(Ret, this));
645ca98fd9SDimitry Andric }
655ca98fd9SDimitry Andric 
getTargetTriple() const66b915e9e0SDimitry Andric StringRef IRObjectFile::getTargetTriple() const {
67b915e9e0SDimitry Andric   // Each module must have the same target triple, so we arbitrarily access the
68b915e9e0SDimitry Andric   // first one.
69b915e9e0SDimitry Andric   return Mods[0]->getTargetTriple();
70b915e9e0SDimitry Andric }
71b915e9e0SDimitry Andric 
72044eb2f6SDimitry Andric Expected<MemoryBufferRef>
findBitcodeInObject(const ObjectFile & Obj)73044eb2f6SDimitry Andric IRObjectFile::findBitcodeInObject(const ObjectFile &Obj) {
7467c32a98SDimitry Andric   for (const SectionRef &Sec : Obj.sections()) {
7501095a5dSDimitry Andric     if (Sec.isBitcode()) {
76e6d15924SDimitry Andric       Expected<StringRef> Contents = Sec.getContents();
77e6d15924SDimitry Andric       if (!Contents)
78e6d15924SDimitry Andric         return Contents.takeError();
79e6d15924SDimitry Andric       if (Contents->size() <= 1)
80e6d15924SDimitry Andric         return errorCodeToError(object_error::bitcode_section_not_found);
81e6d15924SDimitry Andric       return MemoryBufferRef(*Contents, Obj.getFileName());
8267c32a98SDimitry Andric     }
8367c32a98SDimitry Andric   }
8467c32a98SDimitry Andric 
85044eb2f6SDimitry Andric   return errorCodeToError(object_error::bitcode_section_not_found);
8667c32a98SDimitry Andric }
8767c32a98SDimitry Andric 
88044eb2f6SDimitry Andric Expected<MemoryBufferRef>
findBitcodeInMemBuffer(MemoryBufferRef Object)89044eb2f6SDimitry Andric IRObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) {
907ab83427SDimitry Andric   file_magic Type = identify_magic(Object.getBuffer());
9167c32a98SDimitry Andric   switch (Type) {
927ab83427SDimitry Andric   case file_magic::bitcode:
9367c32a98SDimitry Andric     return Object;
947ab83427SDimitry Andric   case file_magic::elf_relocatable:
957ab83427SDimitry Andric   case file_magic::macho_object:
96cfca06d7SDimitry Andric   case file_magic::wasm_object:
977ab83427SDimitry Andric   case file_magic::coff_object: {
9801095a5dSDimitry Andric     Expected<std::unique_ptr<ObjectFile>> ObjFile =
9967c32a98SDimitry Andric         ObjectFile::createObjectFile(Object, Type);
10067c32a98SDimitry Andric     if (!ObjFile)
101044eb2f6SDimitry Andric       return ObjFile.takeError();
10267c32a98SDimitry Andric     return findBitcodeInObject(*ObjFile->get());
10367c32a98SDimitry Andric   }
10467c32a98SDimitry Andric   default:
105044eb2f6SDimitry Andric     return errorCodeToError(object_error::invalid_file_type);
10667c32a98SDimitry Andric   }
10767c32a98SDimitry Andric }
10867c32a98SDimitry Andric 
109b915e9e0SDimitry Andric Expected<std::unique_ptr<IRObjectFile>>
create(MemoryBufferRef Object,LLVMContext & Context)110b915e9e0SDimitry Andric IRObjectFile::create(MemoryBufferRef Object, LLVMContext &Context) {
111044eb2f6SDimitry Andric   Expected<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
11267c32a98SDimitry Andric   if (!BCOrErr)
113044eb2f6SDimitry Andric     return BCOrErr.takeError();
11467c32a98SDimitry Andric 
115b915e9e0SDimitry Andric   Expected<std::vector<BitcodeModule>> BMsOrErr =
116b915e9e0SDimitry Andric       getBitcodeModuleList(*BCOrErr);
117b915e9e0SDimitry Andric   if (!BMsOrErr)
118b915e9e0SDimitry Andric     return BMsOrErr.takeError();
11967c32a98SDimitry Andric 
120b915e9e0SDimitry Andric   std::vector<std::unique_ptr<Module>> Mods;
121b915e9e0SDimitry Andric   for (auto BM : *BMsOrErr) {
122b915e9e0SDimitry Andric     Expected<std::unique_ptr<Module>> MOrErr =
123b915e9e0SDimitry Andric         BM.getLazyModule(Context, /*ShouldLazyLoadMetadata*/ true,
124b915e9e0SDimitry Andric                          /*IsImporting*/ false);
125b915e9e0SDimitry Andric     if (!MOrErr)
126b915e9e0SDimitry Andric       return MOrErr.takeError();
1275ca98fd9SDimitry Andric 
128b915e9e0SDimitry Andric     Mods.push_back(std::move(*MOrErr));
129b915e9e0SDimitry Andric   }
130b915e9e0SDimitry Andric 
131b915e9e0SDimitry Andric   return std::unique_ptr<IRObjectFile>(
132b915e9e0SDimitry Andric       new IRObjectFile(*BCOrErr, std::move(Mods)));
1335ca98fd9SDimitry Andric }
1347ab83427SDimitry Andric 
readIRSymtab(MemoryBufferRef MBRef)1357ab83427SDimitry Andric Expected<IRSymtabFile> object::readIRSymtab(MemoryBufferRef MBRef) {
1367ab83427SDimitry Andric   IRSymtabFile F;
137044eb2f6SDimitry Andric   Expected<MemoryBufferRef> BCOrErr =
1387ab83427SDimitry Andric       IRObjectFile::findBitcodeInMemBuffer(MBRef);
1397ab83427SDimitry Andric   if (!BCOrErr)
140044eb2f6SDimitry Andric     return BCOrErr.takeError();
1417ab83427SDimitry Andric 
1427ab83427SDimitry Andric   Expected<BitcodeFileContents> BFCOrErr = getBitcodeFileContents(*BCOrErr);
1437ab83427SDimitry Andric   if (!BFCOrErr)
1447ab83427SDimitry Andric     return BFCOrErr.takeError();
1457ab83427SDimitry Andric 
1467ab83427SDimitry Andric   Expected<irsymtab::FileContents> FCOrErr = irsymtab::readBitcode(*BFCOrErr);
1477ab83427SDimitry Andric   if (!FCOrErr)
1487ab83427SDimitry Andric     return FCOrErr.takeError();
1497ab83427SDimitry Andric 
1507ab83427SDimitry Andric   F.Mods = std::move(BFCOrErr->Mods);
1517ab83427SDimitry Andric   F.Symtab = std::move(FCOrErr->Symtab);
1527ab83427SDimitry Andric   F.Strtab = std::move(FCOrErr->Strtab);
1537ab83427SDimitry Andric   F.TheReader = std::move(FCOrErr->TheReader);
1547ab83427SDimitry Andric   return std::move(F);
1557ab83427SDimitry Andric }
156