/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Object/IRSymtab.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===- IRSymtab.cpp - implementation of IR symbol tables ------------------===// |
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 | | #include "llvm/Object/IRSymtab.h" |
10 | | #include "llvm/ADT/ArrayRef.h" |
11 | | #include "llvm/ADT/DenseMap.h" |
12 | | #include "llvm/ADT/SmallPtrSet.h" |
13 | | #include "llvm/ADT/SmallString.h" |
14 | | #include "llvm/ADT/SmallVector.h" |
15 | | #include "llvm/ADT/StringRef.h" |
16 | | #include "llvm/ADT/Triple.h" |
17 | | #include "llvm/Config/llvm-config.h" |
18 | | #include "llvm/IR/Comdat.h" |
19 | | #include "llvm/IR/DataLayout.h" |
20 | | #include "llvm/IR/GlobalAlias.h" |
21 | | #include "llvm/IR/GlobalObject.h" |
22 | | #include "llvm/IR/Mangler.h" |
23 | | #include "llvm/IR/Metadata.h" |
24 | | #include "llvm/IR/Module.h" |
25 | | #include "llvm/Bitcode/BitcodeReader.h" |
26 | | #include "llvm/MC/StringTableBuilder.h" |
27 | | #include "llvm/Object/IRObjectFile.h" |
28 | | #include "llvm/Object/ModuleSymbolTable.h" |
29 | | #include "llvm/Object/SymbolicFile.h" |
30 | | #include "llvm/Support/Allocator.h" |
31 | | #include "llvm/Support/Casting.h" |
32 | | #include "llvm/Support/Error.h" |
33 | | #include "llvm/Support/StringSaver.h" |
34 | | #include "llvm/Support/VCSRevision.h" |
35 | | #include "llvm/Support/raw_ostream.h" |
36 | | #include <cassert> |
37 | | #include <string> |
38 | | #include <utility> |
39 | | #include <vector> |
40 | | |
41 | | using namespace llvm; |
42 | | using namespace irsymtab; |
43 | | |
44 | | static const char *LibcallRoutineNames[] = { |
45 | | #define HANDLE_LIBCALL(code, name) name, |
46 | | #include "llvm/IR/RuntimeLibcalls.def" |
47 | | #undef HANDLE_LIBCALL |
48 | | }; |
49 | | |
50 | | namespace { |
51 | | |
52 | 118k | const char *getExpectedProducerName() { |
53 | 118k | static char DefaultName[] = LLVM_VERSION_STRING |
54 | | #ifdef LLVM_REVISION |
55 | | " " LLVM_REVISION |
56 | | #endif |
57 | | ; |
58 | 118k | // Allows for testing of the irsymtab writer and upgrade mechanism. This |
59 | 118k | // environment variable should not be set by users. |
60 | 118k | if (char *OverrideName = getenv("LLVM_OVERRIDE_PRODUCER")) |
61 | 3 | return OverrideName; |
62 | 118k | return DefaultName; |
63 | 118k | } |
64 | | |
65 | | const char *kExpectedProducerName = getExpectedProducerName(); |
66 | | |
67 | | /// Stores the temporary state that is required to build an IR symbol table. |
68 | | struct Builder { |
69 | | SmallVector<char, 0> &Symtab; |
70 | | StringTableBuilder &StrtabBuilder; |
71 | | StringSaver Saver; |
72 | | |
73 | | // This ctor initializes a StringSaver using the passed in BumpPtrAllocator. |
74 | | // The StringTableBuilder does not create a copy of any strings added to it, |
75 | | // so this provides somewhere to store any strings that we create. |
76 | | Builder(SmallVector<char, 0> &Symtab, StringTableBuilder &StrtabBuilder, |
77 | | BumpPtrAllocator &Alloc) |
78 | 4.92k | : Symtab(Symtab), StrtabBuilder(StrtabBuilder), Saver(Alloc) {} |
79 | | |
80 | | DenseMap<const Comdat *, int> ComdatMap; |
81 | | Mangler Mang; |
82 | | Triple TT; |
83 | | |
84 | | std::vector<storage::Comdat> Comdats; |
85 | | std::vector<storage::Module> Mods; |
86 | | std::vector<storage::Symbol> Syms; |
87 | | std::vector<storage::Uncommon> Uncommons; |
88 | | |
89 | | std::string COFFLinkerOpts; |
90 | | raw_string_ostream COFFLinkerOptsOS{COFFLinkerOpts}; |
91 | | |
92 | | std::vector<storage::Str> DependentLibraries; |
93 | | |
94 | 68.0k | void setStr(storage::Str &S, StringRef Value) { |
95 | 68.0k | S.Offset = StrtabBuilder.add(Value); |
96 | 68.0k | S.Size = Value.size(); |
97 | 68.0k | } |
98 | | |
99 | | template <typename T> |
100 | 12.9k | void writeRange(storage::Range<T> &R, const std::vector<T> &Objs) { |
101 | 12.9k | R.Offset = Symtab.size(); |
102 | 12.9k | R.Size = Objs.size(); |
103 | 12.9k | Symtab.insert(Symtab.end(), reinterpret_cast<const char *>(Objs.data()), |
104 | 12.9k | reinterpret_cast<const char *>(Objs.data() + Objs.size())); |
105 | 12.9k | } IRSymtab.cpp:void (anonymous namespace)::Builder::writeRange<llvm::irsymtab::storage::Module>(llvm::irsymtab::storage::Range<llvm::irsymtab::storage::Module>&, std::__1::vector<llvm::irsymtab::storage::Module, std::__1::allocator<llvm::irsymtab::storage::Module> > const&) Line | Count | Source | 100 | 2.59k | void writeRange(storage::Range<T> &R, const std::vector<T> &Objs) { | 101 | 2.59k | R.Offset = Symtab.size(); | 102 | 2.59k | R.Size = Objs.size(); | 103 | 2.59k | Symtab.insert(Symtab.end(), reinterpret_cast<const char *>(Objs.data()), | 104 | 2.59k | reinterpret_cast<const char *>(Objs.data() + Objs.size())); | 105 | 2.59k | } |
IRSymtab.cpp:void (anonymous namespace)::Builder::writeRange<llvm::irsymtab::storage::Comdat>(llvm::irsymtab::storage::Range<llvm::irsymtab::storage::Comdat>&, std::__1::vector<llvm::irsymtab::storage::Comdat, std::__1::allocator<llvm::irsymtab::storage::Comdat> > const&) Line | Count | Source | 100 | 2.59k | void writeRange(storage::Range<T> &R, const std::vector<T> &Objs) { | 101 | 2.59k | R.Offset = Symtab.size(); | 102 | 2.59k | R.Size = Objs.size(); | 103 | 2.59k | Symtab.insert(Symtab.end(), reinterpret_cast<const char *>(Objs.data()), | 104 | 2.59k | reinterpret_cast<const char *>(Objs.data() + Objs.size())); | 105 | 2.59k | } |
IRSymtab.cpp:void (anonymous namespace)::Builder::writeRange<llvm::irsymtab::storage::Symbol>(llvm::irsymtab::storage::Range<llvm::irsymtab::storage::Symbol>&, std::__1::vector<llvm::irsymtab::storage::Symbol, std::__1::allocator<llvm::irsymtab::storage::Symbol> > const&) Line | Count | Source | 100 | 2.59k | void writeRange(storage::Range<T> &R, const std::vector<T> &Objs) { | 101 | 2.59k | R.Offset = Symtab.size(); | 102 | 2.59k | R.Size = Objs.size(); | 103 | 2.59k | Symtab.insert(Symtab.end(), reinterpret_cast<const char *>(Objs.data()), | 104 | 2.59k | reinterpret_cast<const char *>(Objs.data() + Objs.size())); | 105 | 2.59k | } |
IRSymtab.cpp:void (anonymous namespace)::Builder::writeRange<llvm::irsymtab::storage::Uncommon>(llvm::irsymtab::storage::Range<llvm::irsymtab::storage::Uncommon>&, std::__1::vector<llvm::irsymtab::storage::Uncommon, std::__1::allocator<llvm::irsymtab::storage::Uncommon> > const&) Line | Count | Source | 100 | 2.59k | void writeRange(storage::Range<T> &R, const std::vector<T> &Objs) { | 101 | 2.59k | R.Offset = Symtab.size(); | 102 | 2.59k | R.Size = Objs.size(); | 103 | 2.59k | Symtab.insert(Symtab.end(), reinterpret_cast<const char *>(Objs.data()), | 104 | 2.59k | reinterpret_cast<const char *>(Objs.data() + Objs.size())); | 105 | 2.59k | } |
IRSymtab.cpp:void (anonymous namespace)::Builder::writeRange<llvm::irsymtab::storage::Str>(llvm::irsymtab::storage::Range<llvm::irsymtab::storage::Str>&, std::__1::vector<llvm::irsymtab::storage::Str, std::__1::allocator<llvm::irsymtab::storage::Str> > const&) Line | Count | Source | 100 | 2.59k | void writeRange(storage::Range<T> &R, const std::vector<T> &Objs) { | 101 | 2.59k | R.Offset = Symtab.size(); | 102 | 2.59k | R.Size = Objs.size(); | 103 | 2.59k | Symtab.insert(Symtab.end(), reinterpret_cast<const char *>(Objs.data()), | 104 | 2.59k | reinterpret_cast<const char *>(Objs.data() + Objs.size())); | 105 | 2.59k | } |
|
106 | | |
107 | | Expected<int> getComdatIndex(const Comdat *C, const Module *M); |
108 | | |
109 | | Error addModule(Module *M); |
110 | | Error addSymbol(const ModuleSymbolTable &Msymtab, |
111 | | const SmallPtrSet<GlobalValue *, 8> &Used, |
112 | | ModuleSymbolTable::Symbol Sym); |
113 | | |
114 | | Error build(ArrayRef<Module *> Mods); |
115 | | }; |
116 | | |
117 | 4.94k | Error Builder::addModule(Module *M) { |
118 | 4.94k | if (M->getDataLayoutStr().empty()) |
119 | 2.30k | return make_error<StringError>("input module has no datalayout", |
120 | 2.30k | inconvertibleErrorCode()); |
121 | 2.63k | |
122 | 2.63k | SmallPtrSet<GlobalValue *, 8> Used; |
123 | 2.63k | collectUsedGlobalVariables(*M, Used, /*CompilerUsed*/ false); |
124 | 2.63k | |
125 | 2.63k | ModuleSymbolTable Msymtab; |
126 | 2.63k | Msymtab.addModule(M); |
127 | 2.63k | |
128 | 2.63k | storage::Module Mod; |
129 | 2.63k | Mod.Begin = Syms.size(); |
130 | 2.63k | Mod.End = Syms.size() + Msymtab.symbols().size(); |
131 | 2.63k | Mod.UncBegin = Uncommons.size(); |
132 | 2.63k | Mods.push_back(Mod); |
133 | 2.63k | |
134 | 2.63k | if (TT.isOSBinFormatCOFF()) { |
135 | 165 | if (auto E = M->materializeMetadata()) |
136 | 0 | return E; |
137 | 165 | if (NamedMDNode *LinkerOptions = |
138 | 6 | M->getNamedMetadata("llvm.linker.options")) { |
139 | 6 | for (MDNode *MDOptions : LinkerOptions->operands()) |
140 | 9 | for (const MDOperand &MDOption : cast<MDNode>(MDOptions)->operands()) |
141 | 9 | COFFLinkerOptsOS << " " << cast<MDString>(MDOption)->getString(); |
142 | 6 | } |
143 | 165 | } |
144 | 2.63k | |
145 | 2.63k | if (TT.isOSBinFormatELF()) { |
146 | 2.14k | if (auto E = M->materializeMetadata()) |
147 | 0 | return E; |
148 | 2.14k | if (NamedMDNode *N = M->getNamedMetadata("llvm.dependent-libraries")) { |
149 | 13 | for (MDNode *MDOptions : N->operands()) { |
150 | 13 | const auto OperandStr = |
151 | 13 | cast<MDString>(cast<MDNode>(MDOptions)->getOperand(0))->getString(); |
152 | 13 | storage::Str Specifier; |
153 | 13 | setStr(Specifier, OperandStr); |
154 | 13 | DependentLibraries.emplace_back(Specifier); |
155 | 13 | } |
156 | 6 | } |
157 | 2.14k | } |
158 | 2.63k | |
159 | 2.63k | for (ModuleSymbolTable::Symbol Msym : Msymtab.symbols()) |
160 | 22.2k | if (Error Err = addSymbol(Msymtab, Used, Msym)) |
161 | 18 | return Err; |
162 | 2.63k | |
163 | 2.63k | return Error::success()2.61k ; |
164 | 2.63k | } |
165 | | |
166 | 2.79k | Expected<int> Builder::getComdatIndex(const Comdat *C, const Module *M) { |
167 | 2.79k | auto P = ComdatMap.insert(std::make_pair(C, Comdats.size())); |
168 | 2.79k | if (P.second) { |
169 | 2.15k | std::string Name; |
170 | 2.15k | if (TT.isOSBinFormatCOFF()) { |
171 | 33 | const GlobalValue *GV = M->getNamedValue(C->getName()); |
172 | 33 | if (!GV) |
173 | 0 | return make_error<StringError>("Could not find leader", |
174 | 0 | inconvertibleErrorCode()); |
175 | 33 | // Internal leaders do not affect symbol resolution, therefore they do not |
176 | 33 | // appear in the symbol table. |
177 | 33 | if (GV->hasLocalLinkage()) { |
178 | 5 | P.first->second = -1; |
179 | 5 | return -1; |
180 | 5 | } |
181 | 28 | llvm::raw_string_ostream OS(Name); |
182 | 28 | Mang.getNameWithPrefix(OS, GV, false); |
183 | 2.12k | } else { |
184 | 2.12k | Name = C->getName(); |
185 | 2.12k | } |
186 | 2.15k | |
187 | 2.15k | storage::Comdat Comdat; |
188 | 2.15k | setStr(Comdat.Name, Saver.save(Name)); |
189 | 2.15k | Comdats.push_back(Comdat); |
190 | 2.15k | } |
191 | 2.79k | |
192 | 2.79k | return P.first->second2.79k ; |
193 | 2.79k | } |
194 | | |
195 | | Error Builder::addSymbol(const ModuleSymbolTable &Msymtab, |
196 | | const SmallPtrSet<GlobalValue *, 8> &Used, |
197 | 22.2k | ModuleSymbolTable::Symbol Msym) { |
198 | 22.2k | Syms.emplace_back(); |
199 | 22.2k | storage::Symbol &Sym = Syms.back(); |
200 | 22.2k | Sym = {}; |
201 | 22.2k | |
202 | 22.2k | storage::Uncommon *Unc = nullptr; |
203 | 22.2k | auto Uncommon = [&]() -> storage::Uncommon & { |
204 | 1.45k | if (Unc) |
205 | 108 | return *Unc; |
206 | 1.34k | Sym.Flags |= 1 << storage::Symbol::FB_has_uncommon; |
207 | 1.34k | Uncommons.emplace_back(); |
208 | 1.34k | Unc = &Uncommons.back(); |
209 | 1.34k | *Unc = {}; |
210 | 1.34k | setStr(Unc->COFFWeakExternFallbackName, ""); |
211 | 1.34k | setStr(Unc->SectionName, ""); |
212 | 1.34k | return *Unc; |
213 | 1.34k | }; |
214 | 22.2k | |
215 | 22.2k | SmallString<64> Name; |
216 | 22.2k | { |
217 | 22.2k | raw_svector_ostream OS(Name); |
218 | 22.2k | Msymtab.printSymbolName(OS, Msym); |
219 | 22.2k | } |
220 | 22.2k | setStr(Sym.Name, Saver.save(StringRef(Name))); |
221 | 22.2k | |
222 | 22.2k | auto Flags = Msymtab.getSymbolFlags(Msym); |
223 | 22.2k | if (Flags & object::BasicSymbolRef::SF_Undefined) |
224 | 5.30k | Sym.Flags |= 1 << storage::Symbol::FB_undefined; |
225 | 22.2k | if (Flags & object::BasicSymbolRef::SF_Weak) |
226 | 5.05k | Sym.Flags |= 1 << storage::Symbol::FB_weak; |
227 | 22.2k | if (Flags & object::BasicSymbolRef::SF_Common) |
228 | 108 | Sym.Flags |= 1 << storage::Symbol::FB_common; |
229 | 22.2k | if (Flags & object::BasicSymbolRef::SF_Indirect) |
230 | 420 | Sym.Flags |= 1 << storage::Symbol::FB_indirect; |
231 | 22.2k | if (Flags & object::BasicSymbolRef::SF_Global) |
232 | 14.7k | Sym.Flags |= 1 << storage::Symbol::FB_global; |
233 | 22.2k | if (Flags & object::BasicSymbolRef::SF_FormatSpecific) |
234 | 2.67k | Sym.Flags |= 1 << storage::Symbol::FB_format_specific; |
235 | 22.2k | if (Flags & object::BasicSymbolRef::SF_Executable) |
236 | 13.1k | Sym.Flags |= 1 << storage::Symbol::FB_executable; |
237 | 22.2k | |
238 | 22.2k | Sym.ComdatIndex = -1; |
239 | 22.2k | auto *GV = Msym.dyn_cast<GlobalValue *>(); |
240 | 22.2k | if (!GV) { |
241 | 168 | // Undefined module asm symbols act as GC roots and are implicitly used. |
242 | 168 | if (Flags & object::BasicSymbolRef::SF_Undefined) |
243 | 46 | Sym.Flags |= 1 << storage::Symbol::FB_used; |
244 | 168 | setStr(Sym.IRName, ""); |
245 | 168 | return Error::success(); |
246 | 168 | } |
247 | 22.1k | |
248 | 22.1k | setStr(Sym.IRName, GV->getName()); |
249 | 22.1k | |
250 | 22.1k | bool IsBuiltinFunc = false; |
251 | 22.1k | |
252 | 22.1k | for (const char *LibcallName : LibcallRoutineNames) |
253 | 10.8M | if (GV->getName() == LibcallName) |
254 | 6.73k | IsBuiltinFunc = true; |
255 | 22.1k | |
256 | 22.1k | if (Used.count(GV) || IsBuiltinFunc22.0k ) |
257 | 397 | Sym.Flags |= 1 << storage::Symbol::FB_used; |
258 | 22.1k | if (GV->isThreadLocal()) |
259 | 6 | Sym.Flags |= 1 << storage::Symbol::FB_tls; |
260 | 22.1k | if (GV->hasGlobalUnnamedAddr()) |
261 | 4.81k | Sym.Flags |= 1 << storage::Symbol::FB_unnamed_addr; |
262 | 22.1k | if (GV->canBeOmittedFromSymbolTable()) |
263 | 1.38k | Sym.Flags |= 1 << storage::Symbol::FB_may_omit; |
264 | 22.1k | Sym.Flags |= unsigned(GV->getVisibility()) << storage::Symbol::FB_visibility; |
265 | 22.1k | |
266 | 22.1k | if (Flags & object::BasicSymbolRef::SF_Common) { |
267 | 108 | Uncommon().CommonSize = GV->getParent()->getDataLayout().getTypeAllocSize( |
268 | 108 | GV->getType()->getElementType()); |
269 | 108 | Uncommon().CommonAlign = GV->getAlignment(); |
270 | 108 | } |
271 | 22.1k | |
272 | 22.1k | const GlobalObject *Base = GV->getBaseObject(); |
273 | 22.1k | if (!Base) |
274 | 16 | return make_error<StringError>("Unable to determine comdat of alias!", |
275 | 16 | inconvertibleErrorCode()); |
276 | 22.0k | if (const Comdat *C = Base->getComdat()) { |
277 | 2.79k | Expected<int> ComdatIndexOrErr = getComdatIndex(C, GV->getParent()); |
278 | 2.79k | if (!ComdatIndexOrErr) |
279 | 0 | return ComdatIndexOrErr.takeError(); |
280 | 2.79k | Sym.ComdatIndex = *ComdatIndexOrErr; |
281 | 2.79k | } |
282 | 22.0k | |
283 | 22.0k | if (TT.isOSBinFormatCOFF()) { |
284 | 314 | emitLinkerFlagsForGlobalCOFF(COFFLinkerOptsOS, GV, TT, Mang); |
285 | 314 | |
286 | 314 | if ((Flags & object::BasicSymbolRef::SF_Weak) && |
287 | 314 | (Flags & object::BasicSymbolRef::SF_Indirect)18 ) { |
288 | 4 | auto *Fallback = dyn_cast<GlobalValue>( |
289 | 4 | cast<GlobalAlias>(GV)->getAliasee()->stripPointerCasts()); |
290 | 4 | if (!Fallback) |
291 | 2 | return make_error<StringError>("Invalid weak external", |
292 | 2 | inconvertibleErrorCode()); |
293 | 2 | std::string FallbackName; |
294 | 2 | raw_string_ostream OS(FallbackName); |
295 | 2 | Msymtab.printSymbolName(OS, Fallback); |
296 | 2 | OS.flush(); |
297 | 2 | setStr(Uncommon().COFFWeakExternFallbackName, Saver.save(FallbackName)); |
298 | 2 | } |
299 | 314 | } |
300 | 22.0k | |
301 | 22.0k | if (22.0k !Base->getSection().empty()22.0k ) |
302 | 1.23k | setStr(Uncommon().SectionName, Saver.save(Base->getSection())); |
303 | 22.0k | |
304 | 22.0k | return Error::success(); |
305 | 22.0k | } |
306 | | |
307 | 4.92k | Error Builder::build(ArrayRef<Module *> IRMods) { |
308 | 4.92k | storage::Header Hdr; |
309 | 4.92k | |
310 | 4.92k | assert(!IRMods.empty()); |
311 | 4.92k | Hdr.Version = storage::Header::kCurrentVersion; |
312 | 4.92k | setStr(Hdr.Producer, kExpectedProducerName); |
313 | 4.92k | setStr(Hdr.TargetTriple, IRMods[0]->getTargetTriple()); |
314 | 4.92k | setStr(Hdr.SourceFileName, IRMods[0]->getSourceFileName()); |
315 | 4.92k | TT = Triple(IRMods[0]->getTargetTriple()); |
316 | 4.92k | |
317 | 4.92k | for (auto *M : IRMods) |
318 | 4.94k | if (Error Err = addModule(M)) |
319 | 2.32k | return Err; |
320 | 4.92k | |
321 | 4.92k | COFFLinkerOptsOS.flush(); |
322 | 2.59k | setStr(Hdr.COFFLinkerOpts, Saver.save(COFFLinkerOpts)); |
323 | 2.59k | |
324 | 2.59k | // We are about to fill in the header's range fields, so reserve space for it |
325 | 2.59k | // and copy it in afterwards. |
326 | 2.59k | Symtab.resize(sizeof(storage::Header)); |
327 | 2.59k | writeRange(Hdr.Modules, Mods); |
328 | 2.59k | writeRange(Hdr.Comdats, Comdats); |
329 | 2.59k | writeRange(Hdr.Symbols, Syms); |
330 | 2.59k | writeRange(Hdr.Uncommons, Uncommons); |
331 | 2.59k | writeRange(Hdr.DependentLibraries, DependentLibraries); |
332 | 2.59k | *reinterpret_cast<storage::Header *>(Symtab.data()) = Hdr; |
333 | 2.59k | return Error::success(); |
334 | 4.92k | } |
335 | | |
336 | | } // end anonymous namespace |
337 | | |
338 | | Error irsymtab::build(ArrayRef<Module *> Mods, SmallVector<char, 0> &Symtab, |
339 | | StringTableBuilder &StrtabBuilder, |
340 | 4.92k | BumpPtrAllocator &Alloc) { |
341 | 4.92k | return Builder(Symtab, StrtabBuilder, Alloc).build(Mods); |
342 | 4.92k | } |
343 | | |
344 | | // Upgrade a vector of bitcode modules created by an old version of LLVM by |
345 | | // creating an irsymtab for them in the current format. |
346 | 14 | static Expected<FileContents> upgrade(ArrayRef<BitcodeModule> BMs) { |
347 | 14 | FileContents FC; |
348 | 14 | |
349 | 14 | LLVMContext Ctx; |
350 | 14 | std::vector<Module *> Mods; |
351 | 14 | std::vector<std::unique_ptr<Module>> OwnedMods; |
352 | 16 | for (auto BM : BMs) { |
353 | 16 | Expected<std::unique_ptr<Module>> MOrErr = |
354 | 16 | BM.getLazyModule(Ctx, /*ShouldLazyLoadMetadata*/ true, |
355 | 16 | /*IsImporting*/ false); |
356 | 16 | if (!MOrErr) |
357 | 0 | return MOrErr.takeError(); |
358 | 16 | |
359 | 16 | Mods.push_back(MOrErr->get()); |
360 | 16 | OwnedMods.push_back(std::move(*MOrErr)); |
361 | 16 | } |
362 | 14 | |
363 | 14 | StringTableBuilder StrtabBuilder(StringTableBuilder::RAW); |
364 | 14 | BumpPtrAllocator Alloc; |
365 | 14 | if (Error E = build(Mods, FC.Symtab, StrtabBuilder, Alloc)) |
366 | 2 | return std::move(E); |
367 | 12 | |
368 | 12 | StrtabBuilder.finalizeInOrder(); |
369 | 12 | FC.Strtab.resize(StrtabBuilder.getSize()); |
370 | 12 | StrtabBuilder.write((uint8_t *)FC.Strtab.data()); |
371 | 12 | |
372 | 12 | FC.TheReader = {{FC.Symtab.data(), FC.Symtab.size()}, |
373 | 12 | {FC.Strtab.data(), FC.Strtab.size()}}; |
374 | 12 | return std::move(FC); |
375 | 12 | } |
376 | | |
377 | 941 | Expected<FileContents> irsymtab::readBitcode(const BitcodeFileContents &BFC) { |
378 | 941 | if (BFC.Mods.empty()) |
379 | 1 | return make_error<StringError>("Bitcode file does not contain any modules", |
380 | 1 | inconvertibleErrorCode()); |
381 | 940 | |
382 | 940 | if (BFC.StrtabForSymtab.empty() || |
383 | 940 | BFC.Symtab.size() < sizeof(storage::Header)927 ) |
384 | 13 | return upgrade(BFC.Mods); |
385 | 927 | |
386 | 927 | // We cannot use the regular reader to read the version and producer, because |
387 | 927 | // it will expect the header to be in the current format. The only thing we |
388 | 927 | // can rely on is that the version and producer will be present as the first |
389 | 927 | // struct elements. |
390 | 927 | auto *Hdr = reinterpret_cast<const storage::Header *>(BFC.Symtab.data()); |
391 | 927 | unsigned Version = Hdr->Version; |
392 | 927 | StringRef Producer = Hdr->Producer.get(BFC.StrtabForSymtab); |
393 | 927 | if (Version != storage::Header::kCurrentVersion || |
394 | 927 | Producer != kExpectedProducerName) |
395 | 1 | return upgrade(BFC.Mods); |
396 | 926 | |
397 | 926 | FileContents FC; |
398 | 926 | FC.TheReader = {{BFC.Symtab.data(), BFC.Symtab.size()}, |
399 | 926 | {BFC.StrtabForSymtab.data(), BFC.StrtabForSymtab.size()}}; |
400 | 926 | |
401 | 926 | // Finally, make sure that the number of modules in the symbol table matches |
402 | 926 | // the number of modules in the bitcode file. If they differ, it may mean that |
403 | 926 | // the bitcode file was created by binary concatenation, so we need to create |
404 | 926 | // a new symbol table from scratch. |
405 | 926 | if (FC.TheReader.getNumModules() != BFC.Mods.size()) |
406 | 0 | return upgrade(std::move(BFC.Mods)); |
407 | 926 | |
408 | 926 | return std::move(FC); |
409 | 926 | } |