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