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