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