1 | //===- BitcodeAnalyzer.cpp - Internal BitcodeAnalyzer implementation ------===// |
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/Bitcode/BitcodeAnalyzer.h" |
10 | #include "llvm/Bitcode/BitcodeReader.h" |
11 | #include "llvm/Bitcode/LLVMBitCodes.h" |
12 | #include "llvm/Bitstream/BitCodes.h" |
13 | #include "llvm/Bitstream/BitstreamReader.h" |
14 | #include "llvm/Support/Format.h" |
15 | #include "llvm/Support/SHA1.h" |
16 | #include <optional> |
17 | |
18 | using namespace llvm; |
19 | |
20 | static Error reportError(StringRef Message) { |
21 | return createStringError(EC: std::errc::illegal_byte_sequence, Fmt: Message.data()); |
22 | } |
23 | |
24 | /// Return a symbolic block name if known, otherwise return null. |
25 | static std::optional<const char *> |
26 | GetBlockName(unsigned BlockID, const BitstreamBlockInfo &BlockInfo, |
27 | CurStreamTypeType CurStreamType) { |
28 | // Standard blocks for all bitcode files. |
29 | if (BlockID < bitc::FIRST_APPLICATION_BLOCKID) { |
30 | if (BlockID == bitc::BLOCKINFO_BLOCK_ID) |
31 | return "BLOCKINFO_BLOCK" ; |
32 | return std::nullopt; |
33 | } |
34 | |
35 | // Check to see if we have a blockinfo record for this block, with a name. |
36 | if (const BitstreamBlockInfo::BlockInfo *Info = |
37 | BlockInfo.getBlockInfo(BlockID)) { |
38 | if (!Info->Name.empty()) |
39 | return Info->Name.c_str(); |
40 | } |
41 | |
42 | if (CurStreamType != LLVMIRBitstream) |
43 | return std::nullopt; |
44 | |
45 | switch (BlockID) { |
46 | default: |
47 | return std::nullopt; |
48 | case bitc::OPERAND_BUNDLE_TAGS_BLOCK_ID: |
49 | return "OPERAND_BUNDLE_TAGS_BLOCK" ; |
50 | case bitc::MODULE_BLOCK_ID: |
51 | return "MODULE_BLOCK" ; |
52 | case bitc::PARAMATTR_BLOCK_ID: |
53 | return "PARAMATTR_BLOCK" ; |
54 | case bitc::PARAMATTR_GROUP_BLOCK_ID: |
55 | return "PARAMATTR_GROUP_BLOCK_ID" ; |
56 | case bitc::TYPE_BLOCK_ID_NEW: |
57 | return "TYPE_BLOCK_ID" ; |
58 | case bitc::CONSTANTS_BLOCK_ID: |
59 | return "CONSTANTS_BLOCK" ; |
60 | case bitc::FUNCTION_BLOCK_ID: |
61 | return "FUNCTION_BLOCK" ; |
62 | case bitc::IDENTIFICATION_BLOCK_ID: |
63 | return "IDENTIFICATION_BLOCK_ID" ; |
64 | case bitc::VALUE_SYMTAB_BLOCK_ID: |
65 | return "VALUE_SYMTAB" ; |
66 | case bitc::METADATA_BLOCK_ID: |
67 | return "METADATA_BLOCK" ; |
68 | case bitc::METADATA_KIND_BLOCK_ID: |
69 | return "METADATA_KIND_BLOCK" ; |
70 | case bitc::METADATA_ATTACHMENT_ID: |
71 | return "METADATA_ATTACHMENT_BLOCK" ; |
72 | case bitc::USELIST_BLOCK_ID: |
73 | return "USELIST_BLOCK_ID" ; |
74 | case bitc::GLOBALVAL_SUMMARY_BLOCK_ID: |
75 | return "GLOBALVAL_SUMMARY_BLOCK" ; |
76 | case bitc::FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID: |
77 | return "FULL_LTO_GLOBALVAL_SUMMARY_BLOCK" ; |
78 | case bitc::MODULE_STRTAB_BLOCK_ID: |
79 | return "MODULE_STRTAB_BLOCK" ; |
80 | case bitc::STRTAB_BLOCK_ID: |
81 | return "STRTAB_BLOCK" ; |
82 | case bitc::SYMTAB_BLOCK_ID: |
83 | return "SYMTAB_BLOCK" ; |
84 | } |
85 | } |
86 | |
87 | /// Return a symbolic code name if known, otherwise return null. |
88 | static std::optional<const char *> |
89 | GetCodeName(unsigned CodeID, unsigned BlockID, |
90 | const BitstreamBlockInfo &BlockInfo, |
91 | CurStreamTypeType CurStreamType) { |
92 | // Standard blocks for all bitcode files. |
93 | if (BlockID < bitc::FIRST_APPLICATION_BLOCKID) { |
94 | if (BlockID == bitc::BLOCKINFO_BLOCK_ID) { |
95 | switch (CodeID) { |
96 | default: |
97 | return std::nullopt; |
98 | case bitc::BLOCKINFO_CODE_SETBID: |
99 | return "SETBID" ; |
100 | case bitc::BLOCKINFO_CODE_BLOCKNAME: |
101 | return "BLOCKNAME" ; |
102 | case bitc::BLOCKINFO_CODE_SETRECORDNAME: |
103 | return "SETRECORDNAME" ; |
104 | } |
105 | } |
106 | return std::nullopt; |
107 | } |
108 | |
109 | // Check to see if we have a blockinfo record for this record, with a name. |
110 | if (const BitstreamBlockInfo::BlockInfo *Info = |
111 | BlockInfo.getBlockInfo(BlockID)) { |
112 | for (const std::pair<unsigned, std::string> &RN : Info->RecordNames) |
113 | if (RN.first == CodeID) |
114 | return RN.second.c_str(); |
115 | } |
116 | |
117 | if (CurStreamType != LLVMIRBitstream) |
118 | return std::nullopt; |
119 | |
120 | #define STRINGIFY_CODE(PREFIX, CODE) \ |
121 | case bitc::PREFIX##_##CODE: \ |
122 | return #CODE; |
123 | switch (BlockID) { |
124 | default: |
125 | return std::nullopt; |
126 | case bitc::MODULE_BLOCK_ID: |
127 | switch (CodeID) { |
128 | default: |
129 | return std::nullopt; |
130 | STRINGIFY_CODE(MODULE_CODE, VERSION) |
131 | STRINGIFY_CODE(MODULE_CODE, TRIPLE) |
132 | STRINGIFY_CODE(MODULE_CODE, DATALAYOUT) |
133 | STRINGIFY_CODE(MODULE_CODE, ASM) |
134 | STRINGIFY_CODE(MODULE_CODE, SECTIONNAME) |
135 | STRINGIFY_CODE(MODULE_CODE, DEPLIB) // Deprecated, present in old bitcode |
136 | STRINGIFY_CODE(MODULE_CODE, GLOBALVAR) |
137 | STRINGIFY_CODE(MODULE_CODE, FUNCTION) |
138 | STRINGIFY_CODE(MODULE_CODE, ALIAS) |
139 | STRINGIFY_CODE(MODULE_CODE, GCNAME) |
140 | STRINGIFY_CODE(MODULE_CODE, COMDAT) |
141 | STRINGIFY_CODE(MODULE_CODE, VSTOFFSET) |
142 | STRINGIFY_CODE(MODULE_CODE, METADATA_VALUES_UNUSED) |
143 | STRINGIFY_CODE(MODULE_CODE, SOURCE_FILENAME) |
144 | STRINGIFY_CODE(MODULE_CODE, HASH) |
145 | } |
146 | case bitc::IDENTIFICATION_BLOCK_ID: |
147 | switch (CodeID) { |
148 | default: |
149 | return std::nullopt; |
150 | STRINGIFY_CODE(IDENTIFICATION_CODE, STRING) |
151 | STRINGIFY_CODE(IDENTIFICATION_CODE, EPOCH) |
152 | } |
153 | case bitc::PARAMATTR_BLOCK_ID: |
154 | switch (CodeID) { |
155 | default: |
156 | return std::nullopt; |
157 | // FIXME: Should these be different? |
158 | case bitc::PARAMATTR_CODE_ENTRY_OLD: |
159 | return "ENTRY" ; |
160 | case bitc::PARAMATTR_CODE_ENTRY: |
161 | return "ENTRY" ; |
162 | } |
163 | case bitc::PARAMATTR_GROUP_BLOCK_ID: |
164 | switch (CodeID) { |
165 | default: |
166 | return std::nullopt; |
167 | case bitc::PARAMATTR_GRP_CODE_ENTRY: |
168 | return "ENTRY" ; |
169 | } |
170 | case bitc::TYPE_BLOCK_ID_NEW: |
171 | switch (CodeID) { |
172 | default: |
173 | return std::nullopt; |
174 | STRINGIFY_CODE(TYPE_CODE, NUMENTRY) |
175 | STRINGIFY_CODE(TYPE_CODE, VOID) |
176 | STRINGIFY_CODE(TYPE_CODE, FLOAT) |
177 | STRINGIFY_CODE(TYPE_CODE, DOUBLE) |
178 | STRINGIFY_CODE(TYPE_CODE, LABEL) |
179 | STRINGIFY_CODE(TYPE_CODE, OPAQUE) |
180 | STRINGIFY_CODE(TYPE_CODE, INTEGER) |
181 | STRINGIFY_CODE(TYPE_CODE, POINTER) |
182 | STRINGIFY_CODE(TYPE_CODE, HALF) |
183 | STRINGIFY_CODE(TYPE_CODE, ARRAY) |
184 | STRINGIFY_CODE(TYPE_CODE, VECTOR) |
185 | STRINGIFY_CODE(TYPE_CODE, X86_FP80) |
186 | STRINGIFY_CODE(TYPE_CODE, FP128) |
187 | STRINGIFY_CODE(TYPE_CODE, PPC_FP128) |
188 | STRINGIFY_CODE(TYPE_CODE, METADATA) |
189 | STRINGIFY_CODE(TYPE_CODE, X86_MMX) |
190 | STRINGIFY_CODE(TYPE_CODE, STRUCT_ANON) |
191 | STRINGIFY_CODE(TYPE_CODE, STRUCT_NAME) |
192 | STRINGIFY_CODE(TYPE_CODE, STRUCT_NAMED) |
193 | STRINGIFY_CODE(TYPE_CODE, FUNCTION) |
194 | STRINGIFY_CODE(TYPE_CODE, TOKEN) |
195 | STRINGIFY_CODE(TYPE_CODE, BFLOAT) |
196 | } |
197 | |
198 | case bitc::CONSTANTS_BLOCK_ID: |
199 | switch (CodeID) { |
200 | default: |
201 | return std::nullopt; |
202 | STRINGIFY_CODE(CST_CODE, SETTYPE) |
203 | STRINGIFY_CODE(CST_CODE, NULL) |
204 | STRINGIFY_CODE(CST_CODE, UNDEF) |
205 | STRINGIFY_CODE(CST_CODE, INTEGER) |
206 | STRINGIFY_CODE(CST_CODE, WIDE_INTEGER) |
207 | STRINGIFY_CODE(CST_CODE, FLOAT) |
208 | STRINGIFY_CODE(CST_CODE, AGGREGATE) |
209 | STRINGIFY_CODE(CST_CODE, STRING) |
210 | STRINGIFY_CODE(CST_CODE, CSTRING) |
211 | STRINGIFY_CODE(CST_CODE, CE_BINOP) |
212 | STRINGIFY_CODE(CST_CODE, CE_CAST) |
213 | STRINGIFY_CODE(CST_CODE, CE_GEP) |
214 | STRINGIFY_CODE(CST_CODE, CE_INBOUNDS_GEP) |
215 | STRINGIFY_CODE(CST_CODE, CE_SELECT) |
216 | STRINGIFY_CODE(CST_CODE, CE_EXTRACTELT) |
217 | STRINGIFY_CODE(CST_CODE, CE_INSERTELT) |
218 | STRINGIFY_CODE(CST_CODE, CE_SHUFFLEVEC) |
219 | STRINGIFY_CODE(CST_CODE, CE_CMP) |
220 | STRINGIFY_CODE(CST_CODE, INLINEASM) |
221 | STRINGIFY_CODE(CST_CODE, CE_SHUFVEC_EX) |
222 | STRINGIFY_CODE(CST_CODE, CE_UNOP) |
223 | STRINGIFY_CODE(CST_CODE, DSO_LOCAL_EQUIVALENT) |
224 | STRINGIFY_CODE(CST_CODE, NO_CFI_VALUE) |
225 | STRINGIFY_CODE(CST_CODE, PTRAUTH) |
226 | case bitc::CST_CODE_BLOCKADDRESS: |
227 | return "CST_CODE_BLOCKADDRESS" ; |
228 | STRINGIFY_CODE(CST_CODE, DATA) |
229 | } |
230 | case bitc::FUNCTION_BLOCK_ID: |
231 | switch (CodeID) { |
232 | default: |
233 | return std::nullopt; |
234 | STRINGIFY_CODE(FUNC_CODE, DECLAREBLOCKS) |
235 | STRINGIFY_CODE(FUNC_CODE, INST_BINOP) |
236 | STRINGIFY_CODE(FUNC_CODE, INST_CAST) |
237 | STRINGIFY_CODE(FUNC_CODE, INST_GEP_OLD) |
238 | STRINGIFY_CODE(FUNC_CODE, INST_INBOUNDS_GEP_OLD) |
239 | STRINGIFY_CODE(FUNC_CODE, INST_SELECT) |
240 | STRINGIFY_CODE(FUNC_CODE, INST_EXTRACTELT) |
241 | STRINGIFY_CODE(FUNC_CODE, INST_INSERTELT) |
242 | STRINGIFY_CODE(FUNC_CODE, INST_SHUFFLEVEC) |
243 | STRINGIFY_CODE(FUNC_CODE, INST_CMP) |
244 | STRINGIFY_CODE(FUNC_CODE, INST_RET) |
245 | STRINGIFY_CODE(FUNC_CODE, INST_BR) |
246 | STRINGIFY_CODE(FUNC_CODE, INST_SWITCH) |
247 | STRINGIFY_CODE(FUNC_CODE, INST_INVOKE) |
248 | STRINGIFY_CODE(FUNC_CODE, INST_UNOP) |
249 | STRINGIFY_CODE(FUNC_CODE, INST_UNREACHABLE) |
250 | STRINGIFY_CODE(FUNC_CODE, INST_CLEANUPRET) |
251 | STRINGIFY_CODE(FUNC_CODE, INST_CATCHRET) |
252 | STRINGIFY_CODE(FUNC_CODE, INST_CATCHPAD) |
253 | STRINGIFY_CODE(FUNC_CODE, INST_PHI) |
254 | STRINGIFY_CODE(FUNC_CODE, INST_ALLOCA) |
255 | STRINGIFY_CODE(FUNC_CODE, INST_LOAD) |
256 | STRINGIFY_CODE(FUNC_CODE, INST_VAARG) |
257 | STRINGIFY_CODE(FUNC_CODE, INST_STORE) |
258 | STRINGIFY_CODE(FUNC_CODE, INST_EXTRACTVAL) |
259 | STRINGIFY_CODE(FUNC_CODE, INST_INSERTVAL) |
260 | STRINGIFY_CODE(FUNC_CODE, INST_CMP2) |
261 | STRINGIFY_CODE(FUNC_CODE, INST_VSELECT) |
262 | STRINGIFY_CODE(FUNC_CODE, DEBUG_LOC_AGAIN) |
263 | STRINGIFY_CODE(FUNC_CODE, INST_CALL) |
264 | STRINGIFY_CODE(FUNC_CODE, DEBUG_LOC) |
265 | STRINGIFY_CODE(FUNC_CODE, INST_GEP) |
266 | STRINGIFY_CODE(FUNC_CODE, OPERAND_BUNDLE) |
267 | STRINGIFY_CODE(FUNC_CODE, INST_FENCE) |
268 | STRINGIFY_CODE(FUNC_CODE, INST_ATOMICRMW) |
269 | STRINGIFY_CODE(FUNC_CODE, INST_LOADATOMIC) |
270 | STRINGIFY_CODE(FUNC_CODE, INST_STOREATOMIC) |
271 | STRINGIFY_CODE(FUNC_CODE, INST_CMPXCHG) |
272 | STRINGIFY_CODE(FUNC_CODE, INST_CALLBR) |
273 | STRINGIFY_CODE(FUNC_CODE, BLOCKADDR_USERS) |
274 | STRINGIFY_CODE(FUNC_CODE, DEBUG_RECORD_DECLARE) |
275 | STRINGIFY_CODE(FUNC_CODE, DEBUG_RECORD_VALUE) |
276 | STRINGIFY_CODE(FUNC_CODE, DEBUG_RECORD_ASSIGN) |
277 | STRINGIFY_CODE(FUNC_CODE, DEBUG_RECORD_VALUE_SIMPLE) |
278 | STRINGIFY_CODE(FUNC_CODE, DEBUG_RECORD_LABEL) |
279 | } |
280 | case bitc::VALUE_SYMTAB_BLOCK_ID: |
281 | switch (CodeID) { |
282 | default: |
283 | return std::nullopt; |
284 | STRINGIFY_CODE(VST_CODE, ENTRY) |
285 | STRINGIFY_CODE(VST_CODE, BBENTRY) |
286 | STRINGIFY_CODE(VST_CODE, FNENTRY) |
287 | STRINGIFY_CODE(VST_CODE, COMBINED_ENTRY) |
288 | } |
289 | case bitc::MODULE_STRTAB_BLOCK_ID: |
290 | switch (CodeID) { |
291 | default: |
292 | return std::nullopt; |
293 | STRINGIFY_CODE(MST_CODE, ENTRY) |
294 | STRINGIFY_CODE(MST_CODE, HASH) |
295 | } |
296 | case bitc::GLOBALVAL_SUMMARY_BLOCK_ID: |
297 | case bitc::FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID: |
298 | switch (CodeID) { |
299 | default: |
300 | return std::nullopt; |
301 | STRINGIFY_CODE(FS, PERMODULE) |
302 | STRINGIFY_CODE(FS, PERMODULE_PROFILE) |
303 | STRINGIFY_CODE(FS, PERMODULE_RELBF) |
304 | STRINGIFY_CODE(FS, PERMODULE_GLOBALVAR_INIT_REFS) |
305 | STRINGIFY_CODE(FS, PERMODULE_VTABLE_GLOBALVAR_INIT_REFS) |
306 | STRINGIFY_CODE(FS, COMBINED) |
307 | STRINGIFY_CODE(FS, COMBINED_PROFILE) |
308 | STRINGIFY_CODE(FS, COMBINED_GLOBALVAR_INIT_REFS) |
309 | STRINGIFY_CODE(FS, ALIAS) |
310 | STRINGIFY_CODE(FS, COMBINED_ALIAS) |
311 | STRINGIFY_CODE(FS, COMBINED_ORIGINAL_NAME) |
312 | STRINGIFY_CODE(FS, VERSION) |
313 | STRINGIFY_CODE(FS, FLAGS) |
314 | STRINGIFY_CODE(FS, TYPE_TESTS) |
315 | STRINGIFY_CODE(FS, TYPE_TEST_ASSUME_VCALLS) |
316 | STRINGIFY_CODE(FS, TYPE_CHECKED_LOAD_VCALLS) |
317 | STRINGIFY_CODE(FS, TYPE_TEST_ASSUME_CONST_VCALL) |
318 | STRINGIFY_CODE(FS, TYPE_CHECKED_LOAD_CONST_VCALL) |
319 | STRINGIFY_CODE(FS, VALUE_GUID) |
320 | STRINGIFY_CODE(FS, CFI_FUNCTION_DEFS) |
321 | STRINGIFY_CODE(FS, CFI_FUNCTION_DECLS) |
322 | STRINGIFY_CODE(FS, TYPE_ID) |
323 | STRINGIFY_CODE(FS, TYPE_ID_METADATA) |
324 | STRINGIFY_CODE(FS, BLOCK_COUNT) |
325 | STRINGIFY_CODE(FS, PARAM_ACCESS) |
326 | STRINGIFY_CODE(FS, PERMODULE_CALLSITE_INFO) |
327 | STRINGIFY_CODE(FS, PERMODULE_ALLOC_INFO) |
328 | STRINGIFY_CODE(FS, COMBINED_CALLSITE_INFO) |
329 | STRINGIFY_CODE(FS, COMBINED_ALLOC_INFO) |
330 | STRINGIFY_CODE(FS, STACK_IDS) |
331 | } |
332 | case bitc::METADATA_ATTACHMENT_ID: |
333 | switch (CodeID) { |
334 | default: |
335 | return std::nullopt; |
336 | STRINGIFY_CODE(METADATA, ATTACHMENT) |
337 | } |
338 | case bitc::METADATA_BLOCK_ID: |
339 | switch (CodeID) { |
340 | default: |
341 | return std::nullopt; |
342 | STRINGIFY_CODE(METADATA, STRING_OLD) |
343 | STRINGIFY_CODE(METADATA, VALUE) |
344 | STRINGIFY_CODE(METADATA, NODE) |
345 | STRINGIFY_CODE(METADATA, NAME) |
346 | STRINGIFY_CODE(METADATA, DISTINCT_NODE) |
347 | STRINGIFY_CODE(METADATA, KIND) // Older bitcode has it in a MODULE_BLOCK |
348 | STRINGIFY_CODE(METADATA, LOCATION) |
349 | STRINGIFY_CODE(METADATA, OLD_NODE) |
350 | STRINGIFY_CODE(METADATA, OLD_FN_NODE) |
351 | STRINGIFY_CODE(METADATA, NAMED_NODE) |
352 | STRINGIFY_CODE(METADATA, GENERIC_DEBUG) |
353 | STRINGIFY_CODE(METADATA, SUBRANGE) |
354 | STRINGIFY_CODE(METADATA, ENUMERATOR) |
355 | STRINGIFY_CODE(METADATA, BASIC_TYPE) |
356 | STRINGIFY_CODE(METADATA, FILE) |
357 | STRINGIFY_CODE(METADATA, DERIVED_TYPE) |
358 | STRINGIFY_CODE(METADATA, COMPOSITE_TYPE) |
359 | STRINGIFY_CODE(METADATA, SUBROUTINE_TYPE) |
360 | STRINGIFY_CODE(METADATA, COMPILE_UNIT) |
361 | STRINGIFY_CODE(METADATA, SUBPROGRAM) |
362 | STRINGIFY_CODE(METADATA, LEXICAL_BLOCK) |
363 | STRINGIFY_CODE(METADATA, LEXICAL_BLOCK_FILE) |
364 | STRINGIFY_CODE(METADATA, NAMESPACE) |
365 | STRINGIFY_CODE(METADATA, TEMPLATE_TYPE) |
366 | STRINGIFY_CODE(METADATA, TEMPLATE_VALUE) |
367 | STRINGIFY_CODE(METADATA, GLOBAL_VAR) |
368 | STRINGIFY_CODE(METADATA, LOCAL_VAR) |
369 | STRINGIFY_CODE(METADATA, EXPRESSION) |
370 | STRINGIFY_CODE(METADATA, OBJC_PROPERTY) |
371 | STRINGIFY_CODE(METADATA, IMPORTED_ENTITY) |
372 | STRINGIFY_CODE(METADATA, MODULE) |
373 | STRINGIFY_CODE(METADATA, MACRO) |
374 | STRINGIFY_CODE(METADATA, MACRO_FILE) |
375 | STRINGIFY_CODE(METADATA, STRINGS) |
376 | STRINGIFY_CODE(METADATA, GLOBAL_DECL_ATTACHMENT) |
377 | STRINGIFY_CODE(METADATA, GLOBAL_VAR_EXPR) |
378 | STRINGIFY_CODE(METADATA, INDEX_OFFSET) |
379 | STRINGIFY_CODE(METADATA, INDEX) |
380 | STRINGIFY_CODE(METADATA, ARG_LIST) |
381 | } |
382 | case bitc::METADATA_KIND_BLOCK_ID: |
383 | switch (CodeID) { |
384 | default: |
385 | return std::nullopt; |
386 | STRINGIFY_CODE(METADATA, KIND) |
387 | } |
388 | case bitc::USELIST_BLOCK_ID: |
389 | switch (CodeID) { |
390 | default: |
391 | return std::nullopt; |
392 | case bitc::USELIST_CODE_DEFAULT: |
393 | return "USELIST_CODE_DEFAULT" ; |
394 | case bitc::USELIST_CODE_BB: |
395 | return "USELIST_CODE_BB" ; |
396 | } |
397 | |
398 | case bitc::OPERAND_BUNDLE_TAGS_BLOCK_ID: |
399 | switch (CodeID) { |
400 | default: |
401 | return std::nullopt; |
402 | case bitc::OPERAND_BUNDLE_TAG: |
403 | return "OPERAND_BUNDLE_TAG" ; |
404 | } |
405 | case bitc::STRTAB_BLOCK_ID: |
406 | switch (CodeID) { |
407 | default: |
408 | return std::nullopt; |
409 | case bitc::STRTAB_BLOB: |
410 | return "BLOB" ; |
411 | } |
412 | case bitc::SYMTAB_BLOCK_ID: |
413 | switch (CodeID) { |
414 | default: |
415 | return std::nullopt; |
416 | case bitc::SYMTAB_BLOB: |
417 | return "BLOB" ; |
418 | } |
419 | } |
420 | #undef STRINGIFY_CODE |
421 | } |
422 | |
423 | static void printSize(raw_ostream &OS, double Bits) { |
424 | OS << format(Fmt: "%.2f/%.2fB/%luW" , Vals: Bits, Vals: Bits / 8, Vals: (unsigned long)(Bits / 32)); |
425 | } |
426 | static void printSize(raw_ostream &OS, uint64_t Bits) { |
427 | OS << format(Fmt: "%lub/%.2fB/%luW" , Vals: (unsigned long)Bits, Vals: (double)Bits / 8, |
428 | Vals: (unsigned long)(Bits / 32)); |
429 | } |
430 | |
431 | static Expected<CurStreamTypeType> ReadSignature(BitstreamCursor &Stream) { |
432 | auto tryRead = [&Stream](char &Dest, size_t size) -> Error { |
433 | if (Expected<SimpleBitstreamCursor::word_t> MaybeWord = Stream.Read(NumBits: size)) |
434 | Dest = MaybeWord.get(); |
435 | else |
436 | return MaybeWord.takeError(); |
437 | return Error::success(); |
438 | }; |
439 | |
440 | char Signature[6]; |
441 | if (Error Err = tryRead(Signature[0], 8)) |
442 | return std::move(Err); |
443 | if (Error Err = tryRead(Signature[1], 8)) |
444 | return std::move(Err); |
445 | |
446 | // Autodetect the file contents, if it is one we know. |
447 | if (Signature[0] == 'C' && Signature[1] == 'P') { |
448 | if (Error Err = tryRead(Signature[2], 8)) |
449 | return std::move(Err); |
450 | if (Error Err = tryRead(Signature[3], 8)) |
451 | return std::move(Err); |
452 | if (Signature[2] == 'C' && Signature[3] == 'H') |
453 | return ClangSerializedASTBitstream; |
454 | } else if (Signature[0] == 'D' && Signature[1] == 'I') { |
455 | if (Error Err = tryRead(Signature[2], 8)) |
456 | return std::move(Err); |
457 | if (Error Err = tryRead(Signature[3], 8)) |
458 | return std::move(Err); |
459 | if (Signature[2] == 'A' && Signature[3] == 'G') |
460 | return ClangSerializedDiagnosticsBitstream; |
461 | } else if (Signature[0] == 'R' && Signature[1] == 'M') { |
462 | if (Error Err = tryRead(Signature[2], 8)) |
463 | return std::move(Err); |
464 | if (Error Err = tryRead(Signature[3], 8)) |
465 | return std::move(Err); |
466 | if (Signature[2] == 'R' && Signature[3] == 'K') |
467 | return LLVMBitstreamRemarks; |
468 | } else { |
469 | if (Error Err = tryRead(Signature[2], 4)) |
470 | return std::move(Err); |
471 | if (Error Err = tryRead(Signature[3], 4)) |
472 | return std::move(Err); |
473 | if (Error Err = tryRead(Signature[4], 4)) |
474 | return std::move(Err); |
475 | if (Error Err = tryRead(Signature[5], 4)) |
476 | return std::move(Err); |
477 | if (Signature[0] == 'B' && Signature[1] == 'C' && Signature[2] == 0x0 && |
478 | Signature[3] == 0xC && Signature[4] == 0xE && Signature[5] == 0xD) |
479 | return LLVMIRBitstream; |
480 | } |
481 | return UnknownBitstream; |
482 | } |
483 | |
484 | static Expected<CurStreamTypeType> (std::optional<BCDumpOptions> O, |
485 | BitstreamCursor &Stream) { |
486 | ArrayRef<uint8_t> Bytes = Stream.getBitcodeBytes(); |
487 | const unsigned char *BufPtr = (const unsigned char *)Bytes.data(); |
488 | const unsigned char *EndBufPtr = BufPtr + Bytes.size(); |
489 | |
490 | // If we have a wrapper header, parse it and ignore the non-bc file |
491 | // contents. The magic number is 0x0B17C0DE stored in little endian. |
492 | if (isBitcodeWrapper(BufPtr, BufEnd: EndBufPtr)) { |
493 | if (Bytes.size() < BWH_HeaderSize) |
494 | return reportError(Message: "Invalid bitcode wrapper header" ); |
495 | |
496 | if (O) { |
497 | unsigned Magic = support::endian::read32le(P: &BufPtr[BWH_MagicField]); |
498 | unsigned Version = support::endian::read32le(P: &BufPtr[BWH_VersionField]); |
499 | unsigned Offset = support::endian::read32le(P: &BufPtr[BWH_OffsetField]); |
500 | unsigned Size = support::endian::read32le(P: &BufPtr[BWH_SizeField]); |
501 | unsigned CPUType = support::endian::read32le(P: &BufPtr[BWH_CPUTypeField]); |
502 | |
503 | O->OS << "<BITCODE_WRAPPER_HEADER" |
504 | << " Magic=" << format_hex(N: Magic, Width: 10) |
505 | << " Version=" << format_hex(N: Version, Width: 10) |
506 | << " Offset=" << format_hex(N: Offset, Width: 10) |
507 | << " Size=" << format_hex(N: Size, Width: 10) |
508 | << " CPUType=" << format_hex(N: CPUType, Width: 10) << "/>\n" ; |
509 | } |
510 | |
511 | if (SkipBitcodeWrapperHeader(BufPtr, BufEnd&: EndBufPtr, VerifyBufferSize: true)) |
512 | return reportError(Message: "Invalid bitcode wrapper header" ); |
513 | } |
514 | |
515 | // Use the cursor modified by skipping the wrapper header. |
516 | Stream = BitstreamCursor(ArrayRef<uint8_t>(BufPtr, EndBufPtr)); |
517 | |
518 | return ReadSignature(Stream); |
519 | } |
520 | |
521 | static bool canDecodeBlob(unsigned Code, unsigned BlockID) { |
522 | return BlockID == bitc::METADATA_BLOCK_ID && Code == bitc::METADATA_STRINGS; |
523 | } |
524 | |
525 | Error BitcodeAnalyzer::decodeMetadataStringsBlob(StringRef Indent, |
526 | ArrayRef<uint64_t> Record, |
527 | StringRef Blob, |
528 | raw_ostream &OS) { |
529 | if (Blob.empty()) |
530 | return reportError(Message: "Cannot decode empty blob." ); |
531 | |
532 | if (Record.size() != 2) |
533 | return reportError( |
534 | Message: "Decoding metadata strings blob needs two record entries." ); |
535 | |
536 | unsigned NumStrings = Record[0]; |
537 | unsigned StringsOffset = Record[1]; |
538 | OS << " num-strings = " << NumStrings << " {\n" ; |
539 | |
540 | StringRef Lengths = Blob.slice(Start: 0, End: StringsOffset); |
541 | SimpleBitstreamCursor R(Lengths); |
542 | StringRef Strings = Blob.drop_front(N: StringsOffset); |
543 | do { |
544 | if (R.AtEndOfStream()) |
545 | return reportError(Message: "bad length" ); |
546 | |
547 | uint32_t Size; |
548 | if (Error E = R.ReadVBR(NumBits: 6).moveInto(Value&: Size)) |
549 | return E; |
550 | if (Strings.size() < Size) |
551 | return reportError(Message: "truncated chars" ); |
552 | |
553 | OS << Indent << " '" ; |
554 | OS.write_escaped(Str: Strings.slice(Start: 0, End: Size), /*hex=*/UseHexEscapes: true); |
555 | OS << "'\n" ; |
556 | Strings = Strings.drop_front(N: Size); |
557 | } while (--NumStrings); |
558 | |
559 | OS << Indent << " }" ; |
560 | return Error::success(); |
561 | } |
562 | |
563 | BitcodeAnalyzer::BitcodeAnalyzer(StringRef Buffer, |
564 | std::optional<StringRef> BlockInfoBuffer) |
565 | : Stream(Buffer) { |
566 | if (BlockInfoBuffer) |
567 | BlockInfoStream.emplace(args&: *BlockInfoBuffer); |
568 | } |
569 | |
570 | Error BitcodeAnalyzer::analyze(std::optional<BCDumpOptions> O, |
571 | std::optional<StringRef> CheckHash) { |
572 | if (Error E = analyzeHeader(O, Stream).moveInto(Value&: CurStreamType)) |
573 | return E; |
574 | |
575 | Stream.setBlockInfo(&BlockInfo); |
576 | |
577 | // Read block info from BlockInfoStream, if specified. |
578 | // The block info must be a top-level block. |
579 | if (BlockInfoStream) { |
580 | BitstreamCursor BlockInfoCursor(*BlockInfoStream); |
581 | if (Error E = analyzeHeader(O, Stream&: BlockInfoCursor).takeError()) |
582 | return E; |
583 | |
584 | while (!BlockInfoCursor.AtEndOfStream()) { |
585 | Expected<unsigned> MaybeCode = BlockInfoCursor.ReadCode(); |
586 | if (!MaybeCode) |
587 | return MaybeCode.takeError(); |
588 | if (MaybeCode.get() != bitc::ENTER_SUBBLOCK) |
589 | return reportError(Message: "Invalid record at top-level in block info file" ); |
590 | |
591 | Expected<unsigned> MaybeBlockID = BlockInfoCursor.ReadSubBlockID(); |
592 | if (!MaybeBlockID) |
593 | return MaybeBlockID.takeError(); |
594 | if (MaybeBlockID.get() == bitc::BLOCKINFO_BLOCK_ID) { |
595 | std::optional<BitstreamBlockInfo> NewBlockInfo; |
596 | if (Error E = |
597 | BlockInfoCursor.ReadBlockInfoBlock(/*ReadBlockInfoNames=*/true) |
598 | .moveInto(Value&: NewBlockInfo)) |
599 | return E; |
600 | if (!NewBlockInfo) |
601 | return reportError(Message: "Malformed BlockInfoBlock in block info file" ); |
602 | BlockInfo = std::move(*NewBlockInfo); |
603 | break; |
604 | } |
605 | |
606 | if (Error Err = BlockInfoCursor.SkipBlock()) |
607 | return Err; |
608 | } |
609 | } |
610 | |
611 | // Parse the top-level structure. We only allow blocks at the top-level. |
612 | while (!Stream.AtEndOfStream()) { |
613 | Expected<unsigned> MaybeCode = Stream.ReadCode(); |
614 | if (!MaybeCode) |
615 | return MaybeCode.takeError(); |
616 | if (MaybeCode.get() != bitc::ENTER_SUBBLOCK) |
617 | return reportError(Message: "Invalid record at top-level" ); |
618 | |
619 | Expected<unsigned> MaybeBlockID = Stream.ReadSubBlockID(); |
620 | if (!MaybeBlockID) |
621 | return MaybeBlockID.takeError(); |
622 | |
623 | if (Error E = parseBlock(BlockID: MaybeBlockID.get(), IndentLevel: 0, O, CheckHash)) |
624 | return E; |
625 | ++NumTopBlocks; |
626 | } |
627 | |
628 | return Error::success(); |
629 | } |
630 | |
631 | void BitcodeAnalyzer::printStats(BCDumpOptions O, |
632 | std::optional<StringRef> Filename) { |
633 | uint64_t BufferSizeBits = Stream.getBitcodeBytes().size() * CHAR_BIT; |
634 | // Print a summary of the read file. |
635 | O.OS << "Summary " ; |
636 | if (Filename) |
637 | O.OS << "of " << Filename->data() << ":\n" ; |
638 | O.OS << " Total size: " ; |
639 | printSize(OS&: O.OS, Bits: BufferSizeBits); |
640 | O.OS << "\n" ; |
641 | O.OS << " Stream type: " ; |
642 | switch (CurStreamType) { |
643 | case UnknownBitstream: |
644 | O.OS << "unknown\n" ; |
645 | break; |
646 | case LLVMIRBitstream: |
647 | O.OS << "LLVM IR\n" ; |
648 | break; |
649 | case ClangSerializedASTBitstream: |
650 | O.OS << "Clang Serialized AST\n" ; |
651 | break; |
652 | case ClangSerializedDiagnosticsBitstream: |
653 | O.OS << "Clang Serialized Diagnostics\n" ; |
654 | break; |
655 | case LLVMBitstreamRemarks: |
656 | O.OS << "LLVM Remarks\n" ; |
657 | break; |
658 | } |
659 | O.OS << " # Toplevel Blocks: " << NumTopBlocks << "\n" ; |
660 | O.OS << "\n" ; |
661 | |
662 | // Emit per-block stats. |
663 | O.OS << "Per-block Summary:\n" ; |
664 | for (const auto &Stat : BlockIDStats) { |
665 | O.OS << " Block ID #" << Stat.first; |
666 | if (std::optional<const char *> BlockName = |
667 | GetBlockName(BlockID: Stat.first, BlockInfo, CurStreamType)) |
668 | O.OS << " (" << *BlockName << ")" ; |
669 | O.OS << ":\n" ; |
670 | |
671 | const PerBlockIDStats &Stats = Stat.second; |
672 | O.OS << " Num Instances: " << Stats.NumInstances << "\n" ; |
673 | O.OS << " Total Size: " ; |
674 | printSize(OS&: O.OS, Bits: Stats.NumBits); |
675 | O.OS << "\n" ; |
676 | double pct = (Stats.NumBits * 100.0) / BufferSizeBits; |
677 | O.OS << " Percent of file: " << format(Fmt: "%2.4f%%" , Vals: pct) << "\n" ; |
678 | if (Stats.NumInstances > 1) { |
679 | O.OS << " Average Size: " ; |
680 | printSize(OS&: O.OS, Bits: Stats.NumBits / (double)Stats.NumInstances); |
681 | O.OS << "\n" ; |
682 | O.OS << " Tot/Avg SubBlocks: " << Stats.NumSubBlocks << "/" |
683 | << Stats.NumSubBlocks / (double)Stats.NumInstances << "\n" ; |
684 | O.OS << " Tot/Avg Abbrevs: " << Stats.NumAbbrevs << "/" |
685 | << Stats.NumAbbrevs / (double)Stats.NumInstances << "\n" ; |
686 | O.OS << " Tot/Avg Records: " << Stats.NumRecords << "/" |
687 | << Stats.NumRecords / (double)Stats.NumInstances << "\n" ; |
688 | } else { |
689 | O.OS << " Num SubBlocks: " << Stats.NumSubBlocks << "\n" ; |
690 | O.OS << " Num Abbrevs: " << Stats.NumAbbrevs << "\n" ; |
691 | O.OS << " Num Records: " << Stats.NumRecords << "\n" ; |
692 | } |
693 | if (Stats.NumRecords) { |
694 | double pct = (Stats.NumAbbreviatedRecords * 100.0) / Stats.NumRecords; |
695 | O.OS << " Percent Abbrevs: " << format(Fmt: "%2.4f%%" , Vals: pct) << "\n" ; |
696 | } |
697 | O.OS << "\n" ; |
698 | |
699 | // Print a histogram of the codes we see. |
700 | if (O.Histogram && !Stats.CodeFreq.empty()) { |
701 | std::vector<std::pair<unsigned, unsigned>> FreqPairs; // <freq,code> |
702 | for (unsigned i = 0, e = Stats.CodeFreq.size(); i != e; ++i) |
703 | if (unsigned Freq = Stats.CodeFreq[i].NumInstances) |
704 | FreqPairs.push_back(x: std::make_pair(x&: Freq, y&: i)); |
705 | llvm::stable_sort(Range&: FreqPairs); |
706 | std::reverse(first: FreqPairs.begin(), last: FreqPairs.end()); |
707 | |
708 | O.OS << "\tRecord Histogram:\n" ; |
709 | O.OS << "\t\t Count # Bits b/Rec % Abv Record Kind\n" ; |
710 | for (const auto &FreqPair : FreqPairs) { |
711 | const PerRecordStats &RecStats = Stats.CodeFreq[FreqPair.second]; |
712 | |
713 | O.OS << format(Fmt: "\t\t%7d %9lu" , Vals: RecStats.NumInstances, |
714 | Vals: (unsigned long)RecStats.TotalBits); |
715 | |
716 | if (RecStats.NumInstances > 1) |
717 | O.OS << format(Fmt: " %9.1f" , |
718 | Vals: (double)RecStats.TotalBits / RecStats.NumInstances); |
719 | else |
720 | O.OS << " " ; |
721 | |
722 | if (RecStats.NumAbbrev) |
723 | O.OS << format(Fmt: " %7.2f" , Vals: (double)RecStats.NumAbbrev / |
724 | RecStats.NumInstances * 100); |
725 | else |
726 | O.OS << " " ; |
727 | |
728 | O.OS << " " ; |
729 | if (std::optional<const char *> CodeName = GetCodeName( |
730 | CodeID: FreqPair.second, BlockID: Stat.first, BlockInfo, CurStreamType)) |
731 | O.OS << *CodeName << "\n" ; |
732 | else |
733 | O.OS << "UnknownCode" << FreqPair.second << "\n" ; |
734 | } |
735 | O.OS << "\n" ; |
736 | } |
737 | } |
738 | } |
739 | |
740 | Error BitcodeAnalyzer::parseBlock(unsigned BlockID, unsigned IndentLevel, |
741 | std::optional<BCDumpOptions> O, |
742 | std::optional<StringRef> CheckHash) { |
743 | std::string Indent(IndentLevel * 2, ' '); |
744 | uint64_t BlockBitStart = Stream.GetCurrentBitNo(); |
745 | |
746 | // Get the statistics for this BlockID. |
747 | PerBlockIDStats &BlockStats = BlockIDStats[BlockID]; |
748 | |
749 | BlockStats.NumInstances++; |
750 | |
751 | // BLOCKINFO is a special part of the stream. |
752 | bool DumpRecords = O.has_value(); |
753 | if (BlockID == bitc::BLOCKINFO_BLOCK_ID) { |
754 | if (O && !O->DumpBlockinfo) |
755 | O->OS << Indent << "<BLOCKINFO_BLOCK/>\n" ; |
756 | std::optional<BitstreamBlockInfo> NewBlockInfo; |
757 | if (Error E = Stream.ReadBlockInfoBlock(/*ReadBlockInfoNames=*/true) |
758 | .moveInto(Value&: NewBlockInfo)) |
759 | return E; |
760 | if (!NewBlockInfo) |
761 | return reportError(Message: "Malformed BlockInfoBlock" ); |
762 | BlockInfo = std::move(*NewBlockInfo); |
763 | if (Error Err = Stream.JumpToBit(BitNo: BlockBitStart)) |
764 | return Err; |
765 | // It's not really interesting to dump the contents of the blockinfo |
766 | // block, so only do it if the user explicitly requests it. |
767 | DumpRecords = O && O->DumpBlockinfo; |
768 | } |
769 | |
770 | unsigned NumWords = 0; |
771 | if (Error Err = Stream.EnterSubBlock(BlockID, NumWordsP: &NumWords)) |
772 | return Err; |
773 | |
774 | // Keep it for later, when we see a MODULE_HASH record |
775 | uint64_t BlockEntryPos = Stream.getCurrentByteNo(); |
776 | |
777 | std::optional<const char *> BlockName; |
778 | if (DumpRecords) { |
779 | O->OS << Indent << "<" ; |
780 | if ((BlockName = GetBlockName(BlockID, BlockInfo, CurStreamType))) |
781 | O->OS << *BlockName; |
782 | else |
783 | O->OS << "UnknownBlock" << BlockID; |
784 | |
785 | if (!O->Symbolic && BlockName) |
786 | O->OS << " BlockID=" << BlockID; |
787 | |
788 | O->OS << " NumWords=" << NumWords |
789 | << " BlockCodeSize=" << Stream.getAbbrevIDWidth() << ">\n" ; |
790 | } |
791 | |
792 | SmallVector<uint64_t, 64> Record; |
793 | |
794 | // Keep the offset to the metadata index if seen. |
795 | uint64_t MetadataIndexOffset = 0; |
796 | |
797 | // Read all the records for this block. |
798 | while (true) { |
799 | if (Stream.AtEndOfStream()) |
800 | return reportError(Message: "Premature end of bitstream" ); |
801 | |
802 | uint64_t RecordStartBit = Stream.GetCurrentBitNo(); |
803 | |
804 | BitstreamEntry Entry; |
805 | if (Error E = Stream.advance(Flags: BitstreamCursor::AF_DontAutoprocessAbbrevs) |
806 | .moveInto(Value&: Entry)) |
807 | return E; |
808 | |
809 | switch (Entry.Kind) { |
810 | case BitstreamEntry::Error: |
811 | return reportError(Message: "malformed bitcode file" ); |
812 | case BitstreamEntry::EndBlock: { |
813 | uint64_t BlockBitEnd = Stream.GetCurrentBitNo(); |
814 | BlockStats.NumBits += BlockBitEnd - BlockBitStart; |
815 | if (DumpRecords) { |
816 | O->OS << Indent << "</" ; |
817 | if (BlockName) |
818 | O->OS << *BlockName << ">\n" ; |
819 | else |
820 | O->OS << "UnknownBlock" << BlockID << ">\n" ; |
821 | } |
822 | return Error::success(); |
823 | } |
824 | |
825 | case BitstreamEntry::SubBlock: { |
826 | uint64_t SubBlockBitStart = Stream.GetCurrentBitNo(); |
827 | if (Error E = parseBlock(BlockID: Entry.ID, IndentLevel: IndentLevel + 1, O, CheckHash)) |
828 | return E; |
829 | ++BlockStats.NumSubBlocks; |
830 | uint64_t SubBlockBitEnd = Stream.GetCurrentBitNo(); |
831 | |
832 | // Don't include subblock sizes in the size of this block. |
833 | BlockBitStart += SubBlockBitEnd - SubBlockBitStart; |
834 | continue; |
835 | } |
836 | case BitstreamEntry::Record: |
837 | // The interesting case. |
838 | break; |
839 | } |
840 | |
841 | if (Entry.ID == bitc::DEFINE_ABBREV) { |
842 | if (Error Err = Stream.ReadAbbrevRecord()) |
843 | return Err; |
844 | ++BlockStats.NumAbbrevs; |
845 | continue; |
846 | } |
847 | |
848 | Record.clear(); |
849 | |
850 | ++BlockStats.NumRecords; |
851 | |
852 | StringRef Blob; |
853 | uint64_t CurrentRecordPos = Stream.GetCurrentBitNo(); |
854 | unsigned Code; |
855 | if (Error E = Stream.readRecord(AbbrevID: Entry.ID, Vals&: Record, Blob: &Blob).moveInto(Value&: Code)) |
856 | return E; |
857 | |
858 | // Increment the # occurrences of this code. |
859 | if (BlockStats.CodeFreq.size() <= Code) |
860 | BlockStats.CodeFreq.resize(new_size: Code + 1); |
861 | BlockStats.CodeFreq[Code].NumInstances++; |
862 | BlockStats.CodeFreq[Code].TotalBits += |
863 | Stream.GetCurrentBitNo() - RecordStartBit; |
864 | if (Entry.ID != bitc::UNABBREV_RECORD) { |
865 | BlockStats.CodeFreq[Code].NumAbbrev++; |
866 | ++BlockStats.NumAbbreviatedRecords; |
867 | } |
868 | |
869 | if (DumpRecords) { |
870 | O->OS << Indent << " <" ; |
871 | std::optional<const char *> CodeName = |
872 | GetCodeName(CodeID: Code, BlockID, BlockInfo, CurStreamType); |
873 | if (CodeName) |
874 | O->OS << *CodeName; |
875 | else |
876 | O->OS << "UnknownCode" << Code; |
877 | if (!O->Symbolic && CodeName) |
878 | O->OS << " codeid=" << Code; |
879 | const BitCodeAbbrev *Abbv = nullptr; |
880 | if (Entry.ID != bitc::UNABBREV_RECORD) { |
881 | Expected<const BitCodeAbbrev *> MaybeAbbv = Stream.getAbbrev(AbbrevID: Entry.ID); |
882 | if (!MaybeAbbv) |
883 | return MaybeAbbv.takeError(); |
884 | Abbv = MaybeAbbv.get(); |
885 | O->OS << " abbrevid=" << Entry.ID; |
886 | } |
887 | |
888 | for (unsigned i = 0, e = Record.size(); i != e; ++i) |
889 | O->OS << " op" << i << "=" << (int64_t)Record[i]; |
890 | |
891 | // If we found a metadata index, let's verify that we had an offset |
892 | // before and validate its forward reference offset was correct! |
893 | if (BlockID == bitc::METADATA_BLOCK_ID) { |
894 | if (Code == bitc::METADATA_INDEX_OFFSET) { |
895 | if (Record.size() != 2) |
896 | O->OS << "(Invalid record)" ; |
897 | else { |
898 | auto Offset = Record[0] + (Record[1] << 32); |
899 | MetadataIndexOffset = Stream.GetCurrentBitNo() + Offset; |
900 | } |
901 | } |
902 | if (Code == bitc::METADATA_INDEX) { |
903 | O->OS << " (offset " ; |
904 | if (MetadataIndexOffset == RecordStartBit) |
905 | O->OS << "match)" ; |
906 | else |
907 | O->OS << "mismatch: " << MetadataIndexOffset << " vs " |
908 | << RecordStartBit << ")" ; |
909 | } |
910 | } |
911 | |
912 | // If we found a module hash, let's verify that it matches! |
913 | if (BlockID == bitc::MODULE_BLOCK_ID && Code == bitc::MODULE_CODE_HASH && |
914 | CheckHash) { |
915 | if (Record.size() != 5) |
916 | O->OS << " (invalid)" ; |
917 | else { |
918 | // Recompute the hash and compare it to the one in the bitcode |
919 | SHA1 Hasher; |
920 | std::array<uint8_t, 20> Hash; |
921 | Hasher.update(Str: *CheckHash); |
922 | { |
923 | int BlockSize = (CurrentRecordPos / 8) - BlockEntryPos; |
924 | auto Ptr = Stream.getPointerToByte(ByteNo: BlockEntryPos, NumBytes: BlockSize); |
925 | Hasher.update(Data: ArrayRef<uint8_t>(Ptr, BlockSize)); |
926 | Hash = Hasher.result(); |
927 | } |
928 | std::array<uint8_t, 20> RecordedHash; |
929 | int Pos = 0; |
930 | for (auto &Val : Record) { |
931 | assert(!(Val >> 32) && "Unexpected high bits set" ); |
932 | support::endian::write32be(P: &RecordedHash[Pos], V: Val); |
933 | Pos += 4; |
934 | } |
935 | if (Hash == RecordedHash) |
936 | O->OS << " (match)" ; |
937 | else |
938 | O->OS << " (!mismatch!)" ; |
939 | } |
940 | } |
941 | |
942 | O->OS << "/>" ; |
943 | |
944 | if (Abbv) { |
945 | for (unsigned i = 1, e = Abbv->getNumOperandInfos(); i != e; ++i) { |
946 | const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(N: i); |
947 | if (!Op.isEncoding() || Op.getEncoding() != BitCodeAbbrevOp::Array) |
948 | continue; |
949 | assert(i + 2 == e && "Array op not second to last" ); |
950 | std::string Str; |
951 | bool ArrayIsPrintable = true; |
952 | for (unsigned j = i - 1, je = Record.size(); j != je; ++j) { |
953 | if (!isPrint(C: static_cast<unsigned char>(Record[j]))) { |
954 | ArrayIsPrintable = false; |
955 | break; |
956 | } |
957 | Str += (char)Record[j]; |
958 | } |
959 | if (ArrayIsPrintable) |
960 | O->OS << " record string = '" << Str << "'" ; |
961 | break; |
962 | } |
963 | } |
964 | |
965 | if (Blob.data()) { |
966 | if (canDecodeBlob(Code, BlockID)) { |
967 | if (Error E = decodeMetadataStringsBlob(Indent, Record, Blob, OS&: O->OS)) |
968 | return E; |
969 | } else { |
970 | O->OS << " blob data = " ; |
971 | if (O->ShowBinaryBlobs) { |
972 | O->OS << "'" ; |
973 | O->OS.write_escaped(Str: Blob, /*hex=*/UseHexEscapes: true) << "'" ; |
974 | } else { |
975 | bool BlobIsPrintable = true; |
976 | for (char C : Blob) |
977 | if (!isPrint(C: static_cast<unsigned char>(C))) { |
978 | BlobIsPrintable = false; |
979 | break; |
980 | } |
981 | |
982 | if (BlobIsPrintable) |
983 | O->OS << "'" << Blob << "'" ; |
984 | else |
985 | O->OS << "unprintable, " << Blob.size() << " bytes." ; |
986 | } |
987 | } |
988 | } |
989 | |
990 | O->OS << "\n" ; |
991 | } |
992 | |
993 | // Make sure that we can skip the current record. |
994 | if (Error Err = Stream.JumpToBit(BitNo: CurrentRecordPos)) |
995 | return Err; |
996 | if (Expected<unsigned> Skipped = Stream.skipRecord(AbbrevID: Entry.ID)) |
997 | ; // Do nothing. |
998 | else |
999 | return Skipped.takeError(); |
1000 | } |
1001 | } |
1002 | |
1003 | |