1 //===- IRObjectFile.cpp - IR object file implementation ---------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Part of the IRObjectFile class implementation.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/Object/IRObjectFile.h"
15 #include "RecordStreamer.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/Bitcode/BitcodeReader.h"
18 #include "llvm/IR/GVMaterializer.h"
19 #include "llvm/IR/LLVMContext.h"
20 #include "llvm/IR/Mangler.h"
21 #include "llvm/IR/Module.h"
22 #include "llvm/MC/MCAsmInfo.h"
23 #include "llvm/MC/MCContext.h"
24 #include "llvm/MC/MCInstrInfo.h"
25 #include "llvm/MC/MCObjectFileInfo.h"
26 #include "llvm/MC/MCParser/MCAsmParser.h"
27 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
28 #include "llvm/MC/MCRegisterInfo.h"
29 #include "llvm/MC/MCSubtargetInfo.h"
30 #include "llvm/Object/ObjectFile.h"
31 #include "llvm/Support/MemoryBuffer.h"
32 #include "llvm/Support/SourceMgr.h"
33 #include "llvm/Support/TargetRegistry.h"
34 #include "llvm/Support/raw_ostream.h"
36 using namespace object;
38 IRObjectFile::IRObjectFile(MemoryBufferRef Object,
39 std::vector<std::unique_ptr<Module>> Mods)
40 : SymbolicFile(Binary::ID_IR, Object), Mods(std::move(Mods)) {
41 for (auto &M : this->Mods)
42 SymTab.addModule(M.get());
45 IRObjectFile::~IRObjectFile() {}
47 static ModuleSymbolTable::Symbol getSym(DataRefImpl &Symb) {
48 return *reinterpret_cast<ModuleSymbolTable::Symbol *>(Symb.p);
51 void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
52 Symb.p += sizeof(ModuleSymbolTable::Symbol);
55 std::error_code IRObjectFile::printSymbolName(raw_ostream &OS,
56 DataRefImpl Symb) const {
57 SymTab.printSymbolName(OS, getSym(Symb));
58 return std::error_code();
61 uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const {
62 return SymTab.getSymbolFlags(getSym(Symb));
65 basic_symbol_iterator IRObjectFile::symbol_begin() const {
67 Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data());
68 return basic_symbol_iterator(BasicSymbolRef(Ret, this));
71 basic_symbol_iterator IRObjectFile::symbol_end() const {
73 Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data() +
74 SymTab.symbols().size());
75 return basic_symbol_iterator(BasicSymbolRef(Ret, this));
78 StringRef IRObjectFile::getTargetTriple() const {
79 // Each module must have the same target triple, so we arbitrarily access the
81 return Mods[0]->getTargetTriple();
84 ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInObject(const ObjectFile &Obj) {
85 for (const SectionRef &Sec : Obj.sections()) {
86 if (Sec.isBitcode()) {
87 StringRef SecContents;
88 if (std::error_code EC = Sec.getContents(SecContents))
90 return MemoryBufferRef(SecContents, Obj.getFileName());
94 return object_error::bitcode_section_not_found;
97 ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) {
98 sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer());
100 case sys::fs::file_magic::bitcode:
102 case sys::fs::file_magic::elf_relocatable:
103 case sys::fs::file_magic::macho_object:
104 case sys::fs::file_magic::coff_object: {
105 Expected<std::unique_ptr<ObjectFile>> ObjFile =
106 ObjectFile::createObjectFile(Object, Type);
108 return errorToErrorCode(ObjFile.takeError());
109 return findBitcodeInObject(*ObjFile->get());
112 return object_error::invalid_file_type;
116 Expected<std::unique_ptr<IRObjectFile>>
117 IRObjectFile::create(MemoryBufferRef Object, LLVMContext &Context) {
118 ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
120 return errorCodeToError(BCOrErr.getError());
122 Expected<std::vector<BitcodeModule>> BMsOrErr =
123 getBitcodeModuleList(*BCOrErr);
125 return BMsOrErr.takeError();
127 std::vector<std::unique_ptr<Module>> Mods;
128 for (auto BM : *BMsOrErr) {
129 Expected<std::unique_ptr<Module>> MOrErr =
130 BM.getLazyModule(Context, /*ShouldLazyLoadMetadata*/ true,
131 /*IsImporting*/ false);
133 return MOrErr.takeError();
135 Mods.push_back(std::move(*MOrErr));
138 return std::unique_ptr<IRObjectFile>(
139 new IRObjectFile(*BCOrErr, std::move(Mods)));