109467b48Spatrick //===- BitcodeAnalyzer.cpp - Internal BitcodeAnalyzer implementation ------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick
909467b48Spatrick #include "llvm/Bitcode/BitcodeAnalyzer.h"
1009467b48Spatrick #include "llvm/Bitcode/BitcodeReader.h"
1109467b48Spatrick #include "llvm/Bitcode/LLVMBitCodes.h"
1209467b48Spatrick #include "llvm/Bitstream/BitCodes.h"
1309467b48Spatrick #include "llvm/Bitstream/BitstreamReader.h"
1409467b48Spatrick #include "llvm/Support/Format.h"
1509467b48Spatrick #include "llvm/Support/SHA1.h"
16*d415bd75Srobert #include <optional>
1709467b48Spatrick
1809467b48Spatrick using namespace llvm;
1909467b48Spatrick
reportError(StringRef Message)2009467b48Spatrick static Error reportError(StringRef Message) {
2109467b48Spatrick return createStringError(std::errc::illegal_byte_sequence, Message.data());
2209467b48Spatrick }
2309467b48Spatrick
2409467b48Spatrick /// Return a symbolic block name if known, otherwise return null.
25*d415bd75Srobert static std::optional<const char *>
GetBlockName(unsigned BlockID,const BitstreamBlockInfo & BlockInfo,CurStreamTypeType CurStreamType)26*d415bd75Srobert GetBlockName(unsigned BlockID, const BitstreamBlockInfo &BlockInfo,
2709467b48Spatrick CurStreamTypeType CurStreamType) {
2809467b48Spatrick // Standard blocks for all bitcode files.
2909467b48Spatrick if (BlockID < bitc::FIRST_APPLICATION_BLOCKID) {
3009467b48Spatrick if (BlockID == bitc::BLOCKINFO_BLOCK_ID)
3109467b48Spatrick return "BLOCKINFO_BLOCK";
32*d415bd75Srobert return std::nullopt;
3309467b48Spatrick }
3409467b48Spatrick
3509467b48Spatrick // Check to see if we have a blockinfo record for this block, with a name.
3609467b48Spatrick if (const BitstreamBlockInfo::BlockInfo *Info =
3709467b48Spatrick BlockInfo.getBlockInfo(BlockID)) {
3809467b48Spatrick if (!Info->Name.empty())
3909467b48Spatrick return Info->Name.c_str();
4009467b48Spatrick }
4109467b48Spatrick
4209467b48Spatrick if (CurStreamType != LLVMIRBitstream)
43*d415bd75Srobert return std::nullopt;
4409467b48Spatrick
4509467b48Spatrick switch (BlockID) {
4609467b48Spatrick default:
47*d415bd75Srobert return std::nullopt;
4809467b48Spatrick case bitc::OPERAND_BUNDLE_TAGS_BLOCK_ID:
4909467b48Spatrick return "OPERAND_BUNDLE_TAGS_BLOCK";
5009467b48Spatrick case bitc::MODULE_BLOCK_ID:
5109467b48Spatrick return "MODULE_BLOCK";
5209467b48Spatrick case bitc::PARAMATTR_BLOCK_ID:
5309467b48Spatrick return "PARAMATTR_BLOCK";
5409467b48Spatrick case bitc::PARAMATTR_GROUP_BLOCK_ID:
5509467b48Spatrick return "PARAMATTR_GROUP_BLOCK_ID";
5609467b48Spatrick case bitc::TYPE_BLOCK_ID_NEW:
5709467b48Spatrick return "TYPE_BLOCK_ID";
5809467b48Spatrick case bitc::CONSTANTS_BLOCK_ID:
5909467b48Spatrick return "CONSTANTS_BLOCK";
6009467b48Spatrick case bitc::FUNCTION_BLOCK_ID:
6109467b48Spatrick return "FUNCTION_BLOCK";
6209467b48Spatrick case bitc::IDENTIFICATION_BLOCK_ID:
6309467b48Spatrick return "IDENTIFICATION_BLOCK_ID";
6409467b48Spatrick case bitc::VALUE_SYMTAB_BLOCK_ID:
6509467b48Spatrick return "VALUE_SYMTAB";
6609467b48Spatrick case bitc::METADATA_BLOCK_ID:
6709467b48Spatrick return "METADATA_BLOCK";
6809467b48Spatrick case bitc::METADATA_KIND_BLOCK_ID:
6909467b48Spatrick return "METADATA_KIND_BLOCK";
7009467b48Spatrick case bitc::METADATA_ATTACHMENT_ID:
7109467b48Spatrick return "METADATA_ATTACHMENT_BLOCK";
7209467b48Spatrick case bitc::USELIST_BLOCK_ID:
7309467b48Spatrick return "USELIST_BLOCK_ID";
7409467b48Spatrick case bitc::GLOBALVAL_SUMMARY_BLOCK_ID:
7509467b48Spatrick return "GLOBALVAL_SUMMARY_BLOCK";
7609467b48Spatrick case bitc::FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID:
7709467b48Spatrick return "FULL_LTO_GLOBALVAL_SUMMARY_BLOCK";
7809467b48Spatrick case bitc::MODULE_STRTAB_BLOCK_ID:
7909467b48Spatrick return "MODULE_STRTAB_BLOCK";
8009467b48Spatrick case bitc::STRTAB_BLOCK_ID:
8109467b48Spatrick return "STRTAB_BLOCK";
8209467b48Spatrick case bitc::SYMTAB_BLOCK_ID:
8309467b48Spatrick return "SYMTAB_BLOCK";
8409467b48Spatrick }
8509467b48Spatrick }
8609467b48Spatrick
8709467b48Spatrick /// Return a symbolic code name if known, otherwise return null.
88*d415bd75Srobert static std::optional<const char *>
GetCodeName(unsigned CodeID,unsigned BlockID,const BitstreamBlockInfo & BlockInfo,CurStreamTypeType CurStreamType)89*d415bd75Srobert GetCodeName(unsigned CodeID, unsigned BlockID,
9009467b48Spatrick const BitstreamBlockInfo &BlockInfo,
9109467b48Spatrick CurStreamTypeType CurStreamType) {
9209467b48Spatrick // Standard blocks for all bitcode files.
9309467b48Spatrick if (BlockID < bitc::FIRST_APPLICATION_BLOCKID) {
9409467b48Spatrick if (BlockID == bitc::BLOCKINFO_BLOCK_ID) {
9509467b48Spatrick switch (CodeID) {
9609467b48Spatrick default:
97*d415bd75Srobert return std::nullopt;
9809467b48Spatrick case bitc::BLOCKINFO_CODE_SETBID:
9909467b48Spatrick return "SETBID";
10009467b48Spatrick case bitc::BLOCKINFO_CODE_BLOCKNAME:
10109467b48Spatrick return "BLOCKNAME";
10209467b48Spatrick case bitc::BLOCKINFO_CODE_SETRECORDNAME:
10309467b48Spatrick return "SETRECORDNAME";
10409467b48Spatrick }
10509467b48Spatrick }
106*d415bd75Srobert return std::nullopt;
10709467b48Spatrick }
10809467b48Spatrick
10909467b48Spatrick // Check to see if we have a blockinfo record for this record, with a name.
11009467b48Spatrick if (const BitstreamBlockInfo::BlockInfo *Info =
11109467b48Spatrick BlockInfo.getBlockInfo(BlockID)) {
112*d415bd75Srobert for (const std::pair<unsigned, std::string> &RN : Info->RecordNames)
113*d415bd75Srobert if (RN.first == CodeID)
114*d415bd75Srobert return RN.second.c_str();
11509467b48Spatrick }
11609467b48Spatrick
11709467b48Spatrick if (CurStreamType != LLVMIRBitstream)
118*d415bd75Srobert return std::nullopt;
11909467b48Spatrick
12009467b48Spatrick #define STRINGIFY_CODE(PREFIX, CODE) \
12109467b48Spatrick case bitc::PREFIX##_##CODE: \
12209467b48Spatrick return #CODE;
12309467b48Spatrick switch (BlockID) {
12409467b48Spatrick default:
125*d415bd75Srobert return std::nullopt;
12609467b48Spatrick case bitc::MODULE_BLOCK_ID:
12709467b48Spatrick switch (CodeID) {
12809467b48Spatrick default:
129*d415bd75Srobert return std::nullopt;
13009467b48Spatrick STRINGIFY_CODE(MODULE_CODE, VERSION)
13109467b48Spatrick STRINGIFY_CODE(MODULE_CODE, TRIPLE)
13209467b48Spatrick STRINGIFY_CODE(MODULE_CODE, DATALAYOUT)
13309467b48Spatrick STRINGIFY_CODE(MODULE_CODE, ASM)
13409467b48Spatrick STRINGIFY_CODE(MODULE_CODE, SECTIONNAME)
135097a140dSpatrick STRINGIFY_CODE(MODULE_CODE, DEPLIB) // Deprecated, present in old bitcode
13609467b48Spatrick STRINGIFY_CODE(MODULE_CODE, GLOBALVAR)
13709467b48Spatrick STRINGIFY_CODE(MODULE_CODE, FUNCTION)
13809467b48Spatrick STRINGIFY_CODE(MODULE_CODE, ALIAS)
13909467b48Spatrick STRINGIFY_CODE(MODULE_CODE, GCNAME)
14073471bf0Spatrick STRINGIFY_CODE(MODULE_CODE, COMDAT)
14109467b48Spatrick STRINGIFY_CODE(MODULE_CODE, VSTOFFSET)
14209467b48Spatrick STRINGIFY_CODE(MODULE_CODE, METADATA_VALUES_UNUSED)
14309467b48Spatrick STRINGIFY_CODE(MODULE_CODE, SOURCE_FILENAME)
14409467b48Spatrick STRINGIFY_CODE(MODULE_CODE, HASH)
14509467b48Spatrick }
14609467b48Spatrick case bitc::IDENTIFICATION_BLOCK_ID:
14709467b48Spatrick switch (CodeID) {
14809467b48Spatrick default:
149*d415bd75Srobert return std::nullopt;
15009467b48Spatrick STRINGIFY_CODE(IDENTIFICATION_CODE, STRING)
15109467b48Spatrick STRINGIFY_CODE(IDENTIFICATION_CODE, EPOCH)
15209467b48Spatrick }
15309467b48Spatrick case bitc::PARAMATTR_BLOCK_ID:
15409467b48Spatrick switch (CodeID) {
15509467b48Spatrick default:
156*d415bd75Srobert return std::nullopt;
15709467b48Spatrick // FIXME: Should these be different?
15809467b48Spatrick case bitc::PARAMATTR_CODE_ENTRY_OLD:
15909467b48Spatrick return "ENTRY";
16009467b48Spatrick case bitc::PARAMATTR_CODE_ENTRY:
16109467b48Spatrick return "ENTRY";
16209467b48Spatrick }
16309467b48Spatrick case bitc::PARAMATTR_GROUP_BLOCK_ID:
16409467b48Spatrick switch (CodeID) {
16509467b48Spatrick default:
166*d415bd75Srobert return std::nullopt;
16709467b48Spatrick case bitc::PARAMATTR_GRP_CODE_ENTRY:
16809467b48Spatrick return "ENTRY";
16909467b48Spatrick }
17009467b48Spatrick case bitc::TYPE_BLOCK_ID_NEW:
17109467b48Spatrick switch (CodeID) {
17209467b48Spatrick default:
173*d415bd75Srobert return std::nullopt;
17409467b48Spatrick STRINGIFY_CODE(TYPE_CODE, NUMENTRY)
17509467b48Spatrick STRINGIFY_CODE(TYPE_CODE, VOID)
17609467b48Spatrick STRINGIFY_CODE(TYPE_CODE, FLOAT)
17709467b48Spatrick STRINGIFY_CODE(TYPE_CODE, DOUBLE)
17809467b48Spatrick STRINGIFY_CODE(TYPE_CODE, LABEL)
17909467b48Spatrick STRINGIFY_CODE(TYPE_CODE, OPAQUE)
18009467b48Spatrick STRINGIFY_CODE(TYPE_CODE, INTEGER)
18109467b48Spatrick STRINGIFY_CODE(TYPE_CODE, POINTER)
18273471bf0Spatrick STRINGIFY_CODE(TYPE_CODE, HALF)
18309467b48Spatrick STRINGIFY_CODE(TYPE_CODE, ARRAY)
18409467b48Spatrick STRINGIFY_CODE(TYPE_CODE, VECTOR)
18509467b48Spatrick STRINGIFY_CODE(TYPE_CODE, X86_FP80)
18609467b48Spatrick STRINGIFY_CODE(TYPE_CODE, FP128)
18709467b48Spatrick STRINGIFY_CODE(TYPE_CODE, PPC_FP128)
18809467b48Spatrick STRINGIFY_CODE(TYPE_CODE, METADATA)
18973471bf0Spatrick STRINGIFY_CODE(TYPE_CODE, X86_MMX)
19009467b48Spatrick STRINGIFY_CODE(TYPE_CODE, STRUCT_ANON)
19109467b48Spatrick STRINGIFY_CODE(TYPE_CODE, STRUCT_NAME)
19209467b48Spatrick STRINGIFY_CODE(TYPE_CODE, STRUCT_NAMED)
19309467b48Spatrick STRINGIFY_CODE(TYPE_CODE, FUNCTION)
19473471bf0Spatrick STRINGIFY_CODE(TYPE_CODE, TOKEN)
19573471bf0Spatrick STRINGIFY_CODE(TYPE_CODE, BFLOAT)
19609467b48Spatrick }
19709467b48Spatrick
19809467b48Spatrick case bitc::CONSTANTS_BLOCK_ID:
19909467b48Spatrick switch (CodeID) {
20009467b48Spatrick default:
201*d415bd75Srobert return std::nullopt;
20209467b48Spatrick STRINGIFY_CODE(CST_CODE, SETTYPE)
20309467b48Spatrick STRINGIFY_CODE(CST_CODE, NULL)
20409467b48Spatrick STRINGIFY_CODE(CST_CODE, UNDEF)
20509467b48Spatrick STRINGIFY_CODE(CST_CODE, INTEGER)
20609467b48Spatrick STRINGIFY_CODE(CST_CODE, WIDE_INTEGER)
20709467b48Spatrick STRINGIFY_CODE(CST_CODE, FLOAT)
20809467b48Spatrick STRINGIFY_CODE(CST_CODE, AGGREGATE)
20909467b48Spatrick STRINGIFY_CODE(CST_CODE, STRING)
21009467b48Spatrick STRINGIFY_CODE(CST_CODE, CSTRING)
21109467b48Spatrick STRINGIFY_CODE(CST_CODE, CE_BINOP)
21209467b48Spatrick STRINGIFY_CODE(CST_CODE, CE_CAST)
21309467b48Spatrick STRINGIFY_CODE(CST_CODE, CE_GEP)
21409467b48Spatrick STRINGIFY_CODE(CST_CODE, CE_INBOUNDS_GEP)
21509467b48Spatrick STRINGIFY_CODE(CST_CODE, CE_SELECT)
21609467b48Spatrick STRINGIFY_CODE(CST_CODE, CE_EXTRACTELT)
21709467b48Spatrick STRINGIFY_CODE(CST_CODE, CE_INSERTELT)
21809467b48Spatrick STRINGIFY_CODE(CST_CODE, CE_SHUFFLEVEC)
21909467b48Spatrick STRINGIFY_CODE(CST_CODE, CE_CMP)
22009467b48Spatrick STRINGIFY_CODE(CST_CODE, INLINEASM)
22109467b48Spatrick STRINGIFY_CODE(CST_CODE, CE_SHUFVEC_EX)
22209467b48Spatrick STRINGIFY_CODE(CST_CODE, CE_UNOP)
22373471bf0Spatrick STRINGIFY_CODE(CST_CODE, DSO_LOCAL_EQUIVALENT)
224*d415bd75Srobert STRINGIFY_CODE(CST_CODE, NO_CFI_VALUE)
22509467b48Spatrick case bitc::CST_CODE_BLOCKADDRESS:
22609467b48Spatrick return "CST_CODE_BLOCKADDRESS";
22709467b48Spatrick STRINGIFY_CODE(CST_CODE, DATA)
22809467b48Spatrick }
22909467b48Spatrick case bitc::FUNCTION_BLOCK_ID:
23009467b48Spatrick switch (CodeID) {
23109467b48Spatrick default:
232*d415bd75Srobert return std::nullopt;
23309467b48Spatrick STRINGIFY_CODE(FUNC_CODE, DECLAREBLOCKS)
23409467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_BINOP)
23509467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_CAST)
23609467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_GEP_OLD)
23709467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_INBOUNDS_GEP_OLD)
23809467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_SELECT)
23909467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_EXTRACTELT)
24009467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_INSERTELT)
24109467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_SHUFFLEVEC)
24209467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_CMP)
24309467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_RET)
24409467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_BR)
24509467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_SWITCH)
24609467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_INVOKE)
24709467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_UNOP)
24809467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_UNREACHABLE)
24909467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_CLEANUPRET)
25009467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_CATCHRET)
25109467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_CATCHPAD)
25209467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_PHI)
25309467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_ALLOCA)
25409467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_LOAD)
25509467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_VAARG)
25609467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_STORE)
25709467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_EXTRACTVAL)
25809467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_INSERTVAL)
25909467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_CMP2)
26009467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_VSELECT)
26109467b48Spatrick STRINGIFY_CODE(FUNC_CODE, DEBUG_LOC_AGAIN)
26209467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_CALL)
26309467b48Spatrick STRINGIFY_CODE(FUNC_CODE, DEBUG_LOC)
26409467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_GEP)
26509467b48Spatrick STRINGIFY_CODE(FUNC_CODE, OPERAND_BUNDLE)
26609467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_FENCE)
26709467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_ATOMICRMW)
26809467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_LOADATOMIC)
26909467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_STOREATOMIC)
27009467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_CMPXCHG)
27109467b48Spatrick STRINGIFY_CODE(FUNC_CODE, INST_CALLBR)
272*d415bd75Srobert STRINGIFY_CODE(FUNC_CODE, BLOCKADDR_USERS)
27309467b48Spatrick }
27409467b48Spatrick case bitc::VALUE_SYMTAB_BLOCK_ID:
27509467b48Spatrick switch (CodeID) {
27609467b48Spatrick default:
277*d415bd75Srobert return std::nullopt;
27809467b48Spatrick STRINGIFY_CODE(VST_CODE, ENTRY)
27909467b48Spatrick STRINGIFY_CODE(VST_CODE, BBENTRY)
28009467b48Spatrick STRINGIFY_CODE(VST_CODE, FNENTRY)
28109467b48Spatrick STRINGIFY_CODE(VST_CODE, COMBINED_ENTRY)
28209467b48Spatrick }
28309467b48Spatrick case bitc::MODULE_STRTAB_BLOCK_ID:
28409467b48Spatrick switch (CodeID) {
28509467b48Spatrick default:
286*d415bd75Srobert return std::nullopt;
28709467b48Spatrick STRINGIFY_CODE(MST_CODE, ENTRY)
28809467b48Spatrick STRINGIFY_CODE(MST_CODE, HASH)
28909467b48Spatrick }
29009467b48Spatrick case bitc::GLOBALVAL_SUMMARY_BLOCK_ID:
29109467b48Spatrick case bitc::FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID:
29209467b48Spatrick switch (CodeID) {
29309467b48Spatrick default:
294*d415bd75Srobert return std::nullopt;
29509467b48Spatrick STRINGIFY_CODE(FS, PERMODULE)
29609467b48Spatrick STRINGIFY_CODE(FS, PERMODULE_PROFILE)
29709467b48Spatrick STRINGIFY_CODE(FS, PERMODULE_RELBF)
29809467b48Spatrick STRINGIFY_CODE(FS, PERMODULE_GLOBALVAR_INIT_REFS)
29909467b48Spatrick STRINGIFY_CODE(FS, PERMODULE_VTABLE_GLOBALVAR_INIT_REFS)
30009467b48Spatrick STRINGIFY_CODE(FS, COMBINED)
30109467b48Spatrick STRINGIFY_CODE(FS, COMBINED_PROFILE)
30209467b48Spatrick STRINGIFY_CODE(FS, COMBINED_GLOBALVAR_INIT_REFS)
30309467b48Spatrick STRINGIFY_CODE(FS, ALIAS)
30409467b48Spatrick STRINGIFY_CODE(FS, COMBINED_ALIAS)
30509467b48Spatrick STRINGIFY_CODE(FS, COMBINED_ORIGINAL_NAME)
30609467b48Spatrick STRINGIFY_CODE(FS, VERSION)
30709467b48Spatrick STRINGIFY_CODE(FS, FLAGS)
30809467b48Spatrick STRINGIFY_CODE(FS, TYPE_TESTS)
30909467b48Spatrick STRINGIFY_CODE(FS, TYPE_TEST_ASSUME_VCALLS)
31009467b48Spatrick STRINGIFY_CODE(FS, TYPE_CHECKED_LOAD_VCALLS)
31109467b48Spatrick STRINGIFY_CODE(FS, TYPE_TEST_ASSUME_CONST_VCALL)
31209467b48Spatrick STRINGIFY_CODE(FS, TYPE_CHECKED_LOAD_CONST_VCALL)
31309467b48Spatrick STRINGIFY_CODE(FS, VALUE_GUID)
31409467b48Spatrick STRINGIFY_CODE(FS, CFI_FUNCTION_DEFS)
31509467b48Spatrick STRINGIFY_CODE(FS, CFI_FUNCTION_DECLS)
31609467b48Spatrick STRINGIFY_CODE(FS, TYPE_ID)
31709467b48Spatrick STRINGIFY_CODE(FS, TYPE_ID_METADATA)
318097a140dSpatrick STRINGIFY_CODE(FS, BLOCK_COUNT)
319097a140dSpatrick STRINGIFY_CODE(FS, PARAM_ACCESS)
320*d415bd75Srobert STRINGIFY_CODE(FS, PERMODULE_CALLSITE_INFO)
321*d415bd75Srobert STRINGIFY_CODE(FS, PERMODULE_ALLOC_INFO)
322*d415bd75Srobert STRINGIFY_CODE(FS, COMBINED_CALLSITE_INFO)
323*d415bd75Srobert STRINGIFY_CODE(FS, COMBINED_ALLOC_INFO)
324*d415bd75Srobert STRINGIFY_CODE(FS, STACK_IDS)
32509467b48Spatrick }
32609467b48Spatrick case bitc::METADATA_ATTACHMENT_ID:
32709467b48Spatrick switch (CodeID) {
32809467b48Spatrick default:
329*d415bd75Srobert return std::nullopt;
33009467b48Spatrick STRINGIFY_CODE(METADATA, ATTACHMENT)
33109467b48Spatrick }
33209467b48Spatrick case bitc::METADATA_BLOCK_ID:
33309467b48Spatrick switch (CodeID) {
33409467b48Spatrick default:
335*d415bd75Srobert return std::nullopt;
33609467b48Spatrick STRINGIFY_CODE(METADATA, STRING_OLD)
33709467b48Spatrick STRINGIFY_CODE(METADATA, VALUE)
33809467b48Spatrick STRINGIFY_CODE(METADATA, NODE)
33909467b48Spatrick STRINGIFY_CODE(METADATA, NAME)
34009467b48Spatrick STRINGIFY_CODE(METADATA, DISTINCT_NODE)
34109467b48Spatrick STRINGIFY_CODE(METADATA, KIND) // Older bitcode has it in a MODULE_BLOCK
34209467b48Spatrick STRINGIFY_CODE(METADATA, LOCATION)
34309467b48Spatrick STRINGIFY_CODE(METADATA, OLD_NODE)
34409467b48Spatrick STRINGIFY_CODE(METADATA, OLD_FN_NODE)
34509467b48Spatrick STRINGIFY_CODE(METADATA, NAMED_NODE)
34609467b48Spatrick STRINGIFY_CODE(METADATA, GENERIC_DEBUG)
34709467b48Spatrick STRINGIFY_CODE(METADATA, SUBRANGE)
34809467b48Spatrick STRINGIFY_CODE(METADATA, ENUMERATOR)
34909467b48Spatrick STRINGIFY_CODE(METADATA, BASIC_TYPE)
35009467b48Spatrick STRINGIFY_CODE(METADATA, FILE)
35109467b48Spatrick STRINGIFY_CODE(METADATA, DERIVED_TYPE)
35209467b48Spatrick STRINGIFY_CODE(METADATA, COMPOSITE_TYPE)
35309467b48Spatrick STRINGIFY_CODE(METADATA, SUBROUTINE_TYPE)
35409467b48Spatrick STRINGIFY_CODE(METADATA, COMPILE_UNIT)
35509467b48Spatrick STRINGIFY_CODE(METADATA, SUBPROGRAM)
35609467b48Spatrick STRINGIFY_CODE(METADATA, LEXICAL_BLOCK)
35709467b48Spatrick STRINGIFY_CODE(METADATA, LEXICAL_BLOCK_FILE)
35809467b48Spatrick STRINGIFY_CODE(METADATA, NAMESPACE)
35909467b48Spatrick STRINGIFY_CODE(METADATA, TEMPLATE_TYPE)
36009467b48Spatrick STRINGIFY_CODE(METADATA, TEMPLATE_VALUE)
36109467b48Spatrick STRINGIFY_CODE(METADATA, GLOBAL_VAR)
36209467b48Spatrick STRINGIFY_CODE(METADATA, LOCAL_VAR)
36309467b48Spatrick STRINGIFY_CODE(METADATA, EXPRESSION)
36409467b48Spatrick STRINGIFY_CODE(METADATA, OBJC_PROPERTY)
36509467b48Spatrick STRINGIFY_CODE(METADATA, IMPORTED_ENTITY)
36609467b48Spatrick STRINGIFY_CODE(METADATA, MODULE)
36709467b48Spatrick STRINGIFY_CODE(METADATA, MACRO)
36809467b48Spatrick STRINGIFY_CODE(METADATA, MACRO_FILE)
36909467b48Spatrick STRINGIFY_CODE(METADATA, STRINGS)
37009467b48Spatrick STRINGIFY_CODE(METADATA, GLOBAL_DECL_ATTACHMENT)
37109467b48Spatrick STRINGIFY_CODE(METADATA, GLOBAL_VAR_EXPR)
37209467b48Spatrick STRINGIFY_CODE(METADATA, INDEX_OFFSET)
37309467b48Spatrick STRINGIFY_CODE(METADATA, INDEX)
37473471bf0Spatrick STRINGIFY_CODE(METADATA, ARG_LIST)
37509467b48Spatrick }
37609467b48Spatrick case bitc::METADATA_KIND_BLOCK_ID:
37709467b48Spatrick switch (CodeID) {
37809467b48Spatrick default:
379*d415bd75Srobert return std::nullopt;
38009467b48Spatrick STRINGIFY_CODE(METADATA, KIND)
38109467b48Spatrick }
38209467b48Spatrick case bitc::USELIST_BLOCK_ID:
38309467b48Spatrick switch (CodeID) {
38409467b48Spatrick default:
385*d415bd75Srobert return std::nullopt;
38609467b48Spatrick case bitc::USELIST_CODE_DEFAULT:
38709467b48Spatrick return "USELIST_CODE_DEFAULT";
38809467b48Spatrick case bitc::USELIST_CODE_BB:
38909467b48Spatrick return "USELIST_CODE_BB";
39009467b48Spatrick }
39109467b48Spatrick
39209467b48Spatrick case bitc::OPERAND_BUNDLE_TAGS_BLOCK_ID:
39309467b48Spatrick switch (CodeID) {
39409467b48Spatrick default:
395*d415bd75Srobert return std::nullopt;
39609467b48Spatrick case bitc::OPERAND_BUNDLE_TAG:
39709467b48Spatrick return "OPERAND_BUNDLE_TAG";
39809467b48Spatrick }
39909467b48Spatrick case bitc::STRTAB_BLOCK_ID:
40009467b48Spatrick switch (CodeID) {
40109467b48Spatrick default:
402*d415bd75Srobert return std::nullopt;
40309467b48Spatrick case bitc::STRTAB_BLOB:
40409467b48Spatrick return "BLOB";
40509467b48Spatrick }
40609467b48Spatrick case bitc::SYMTAB_BLOCK_ID:
40709467b48Spatrick switch (CodeID) {
40809467b48Spatrick default:
409*d415bd75Srobert return std::nullopt;
41009467b48Spatrick case bitc::SYMTAB_BLOB:
41109467b48Spatrick return "BLOB";
41209467b48Spatrick }
41309467b48Spatrick }
41409467b48Spatrick #undef STRINGIFY_CODE
41509467b48Spatrick }
41609467b48Spatrick
printSize(raw_ostream & OS,double Bits)41709467b48Spatrick static void printSize(raw_ostream &OS, double Bits) {
41809467b48Spatrick OS << format("%.2f/%.2fB/%luW", Bits, Bits / 8, (unsigned long)(Bits / 32));
41909467b48Spatrick }
printSize(raw_ostream & OS,uint64_t Bits)42009467b48Spatrick static void printSize(raw_ostream &OS, uint64_t Bits) {
42109467b48Spatrick OS << format("%lub/%.2fB/%luW", (unsigned long)Bits, (double)Bits / 8,
42209467b48Spatrick (unsigned long)(Bits / 32));
42309467b48Spatrick }
42409467b48Spatrick
ReadSignature(BitstreamCursor & Stream)42509467b48Spatrick static Expected<CurStreamTypeType> ReadSignature(BitstreamCursor &Stream) {
42609467b48Spatrick auto tryRead = [&Stream](char &Dest, size_t size) -> Error {
42709467b48Spatrick if (Expected<SimpleBitstreamCursor::word_t> MaybeWord = Stream.Read(size))
42809467b48Spatrick Dest = MaybeWord.get();
42909467b48Spatrick else
43009467b48Spatrick return MaybeWord.takeError();
43109467b48Spatrick return Error::success();
43209467b48Spatrick };
43309467b48Spatrick
43409467b48Spatrick char Signature[6];
43509467b48Spatrick if (Error Err = tryRead(Signature[0], 8))
43609467b48Spatrick return std::move(Err);
43709467b48Spatrick if (Error Err = tryRead(Signature[1], 8))
43809467b48Spatrick return std::move(Err);
43909467b48Spatrick
44009467b48Spatrick // Autodetect the file contents, if it is one we know.
44109467b48Spatrick if (Signature[0] == 'C' && Signature[1] == 'P') {
44209467b48Spatrick if (Error Err = tryRead(Signature[2], 8))
44309467b48Spatrick return std::move(Err);
44409467b48Spatrick if (Error Err = tryRead(Signature[3], 8))
44509467b48Spatrick return std::move(Err);
44609467b48Spatrick if (Signature[2] == 'C' && Signature[3] == 'H')
44709467b48Spatrick return ClangSerializedASTBitstream;
44809467b48Spatrick } else if (Signature[0] == 'D' && Signature[1] == 'I') {
44909467b48Spatrick if (Error Err = tryRead(Signature[2], 8))
45009467b48Spatrick return std::move(Err);
45109467b48Spatrick if (Error Err = tryRead(Signature[3], 8))
45209467b48Spatrick return std::move(Err);
45309467b48Spatrick if (Signature[2] == 'A' && Signature[3] == 'G')
45409467b48Spatrick return ClangSerializedDiagnosticsBitstream;
45509467b48Spatrick } else if (Signature[0] == 'R' && Signature[1] == 'M') {
45609467b48Spatrick if (Error Err = tryRead(Signature[2], 8))
45709467b48Spatrick return std::move(Err);
45809467b48Spatrick if (Error Err = tryRead(Signature[3], 8))
45909467b48Spatrick return std::move(Err);
46009467b48Spatrick if (Signature[2] == 'R' && Signature[3] == 'K')
46109467b48Spatrick return LLVMBitstreamRemarks;
46209467b48Spatrick } else {
46309467b48Spatrick if (Error Err = tryRead(Signature[2], 4))
46409467b48Spatrick return std::move(Err);
46509467b48Spatrick if (Error Err = tryRead(Signature[3], 4))
46609467b48Spatrick return std::move(Err);
46709467b48Spatrick if (Error Err = tryRead(Signature[4], 4))
46809467b48Spatrick return std::move(Err);
46909467b48Spatrick if (Error Err = tryRead(Signature[5], 4))
47009467b48Spatrick return std::move(Err);
47109467b48Spatrick if (Signature[0] == 'B' && Signature[1] == 'C' && Signature[2] == 0x0 &&
47209467b48Spatrick Signature[3] == 0xC && Signature[4] == 0xE && Signature[5] == 0xD)
47309467b48Spatrick return LLVMIRBitstream;
47409467b48Spatrick }
47509467b48Spatrick return UnknownBitstream;
47609467b48Spatrick }
47709467b48Spatrick
analyzeHeader(std::optional<BCDumpOptions> O,BitstreamCursor & Stream)478*d415bd75Srobert static Expected<CurStreamTypeType> analyzeHeader(std::optional<BCDumpOptions> O,
47909467b48Spatrick BitstreamCursor &Stream) {
48009467b48Spatrick ArrayRef<uint8_t> Bytes = Stream.getBitcodeBytes();
48109467b48Spatrick const unsigned char *BufPtr = (const unsigned char *)Bytes.data();
48209467b48Spatrick const unsigned char *EndBufPtr = BufPtr + Bytes.size();
48309467b48Spatrick
48409467b48Spatrick // If we have a wrapper header, parse it and ignore the non-bc file
48509467b48Spatrick // contents. The magic number is 0x0B17C0DE stored in little endian.
48609467b48Spatrick if (isBitcodeWrapper(BufPtr, EndBufPtr)) {
48709467b48Spatrick if (Bytes.size() < BWH_HeaderSize)
48809467b48Spatrick return reportError("Invalid bitcode wrapper header");
48909467b48Spatrick
49009467b48Spatrick if (O) {
49109467b48Spatrick unsigned Magic = support::endian::read32le(&BufPtr[BWH_MagicField]);
49209467b48Spatrick unsigned Version = support::endian::read32le(&BufPtr[BWH_VersionField]);
49309467b48Spatrick unsigned Offset = support::endian::read32le(&BufPtr[BWH_OffsetField]);
49409467b48Spatrick unsigned Size = support::endian::read32le(&BufPtr[BWH_SizeField]);
49509467b48Spatrick unsigned CPUType = support::endian::read32le(&BufPtr[BWH_CPUTypeField]);
49609467b48Spatrick
49709467b48Spatrick O->OS << "<BITCODE_WRAPPER_HEADER"
49809467b48Spatrick << " Magic=" << format_hex(Magic, 10)
49909467b48Spatrick << " Version=" << format_hex(Version, 10)
50009467b48Spatrick << " Offset=" << format_hex(Offset, 10)
50109467b48Spatrick << " Size=" << format_hex(Size, 10)
50209467b48Spatrick << " CPUType=" << format_hex(CPUType, 10) << "/>\n";
50309467b48Spatrick }
50409467b48Spatrick
50509467b48Spatrick if (SkipBitcodeWrapperHeader(BufPtr, EndBufPtr, true))
50609467b48Spatrick return reportError("Invalid bitcode wrapper header");
50709467b48Spatrick }
50809467b48Spatrick
50909467b48Spatrick // Use the cursor modified by skipping the wrapper header.
51009467b48Spatrick Stream = BitstreamCursor(ArrayRef<uint8_t>(BufPtr, EndBufPtr));
51109467b48Spatrick
51209467b48Spatrick return ReadSignature(Stream);
51309467b48Spatrick }
51409467b48Spatrick
canDecodeBlob(unsigned Code,unsigned BlockID)51509467b48Spatrick static bool canDecodeBlob(unsigned Code, unsigned BlockID) {
51609467b48Spatrick return BlockID == bitc::METADATA_BLOCK_ID && Code == bitc::METADATA_STRINGS;
51709467b48Spatrick }
51809467b48Spatrick
decodeMetadataStringsBlob(StringRef Indent,ArrayRef<uint64_t> Record,StringRef Blob,raw_ostream & OS)51909467b48Spatrick Error BitcodeAnalyzer::decodeMetadataStringsBlob(StringRef Indent,
52009467b48Spatrick ArrayRef<uint64_t> Record,
52109467b48Spatrick StringRef Blob,
52209467b48Spatrick raw_ostream &OS) {
52309467b48Spatrick if (Blob.empty())
52409467b48Spatrick return reportError("Cannot decode empty blob.");
52509467b48Spatrick
52609467b48Spatrick if (Record.size() != 2)
52709467b48Spatrick return reportError(
52809467b48Spatrick "Decoding metadata strings blob needs two record entries.");
52909467b48Spatrick
53009467b48Spatrick unsigned NumStrings = Record[0];
53109467b48Spatrick unsigned StringsOffset = Record[1];
53209467b48Spatrick OS << " num-strings = " << NumStrings << " {\n";
53309467b48Spatrick
53409467b48Spatrick StringRef Lengths = Blob.slice(0, StringsOffset);
53509467b48Spatrick SimpleBitstreamCursor R(Lengths);
53609467b48Spatrick StringRef Strings = Blob.drop_front(StringsOffset);
53709467b48Spatrick do {
53809467b48Spatrick if (R.AtEndOfStream())
53909467b48Spatrick return reportError("bad length");
54009467b48Spatrick
541*d415bd75Srobert uint32_t Size;
542*d415bd75Srobert if (Error E = R.ReadVBR(6).moveInto(Size))
543*d415bd75Srobert return E;
54409467b48Spatrick if (Strings.size() < Size)
54509467b48Spatrick return reportError("truncated chars");
54609467b48Spatrick
54709467b48Spatrick OS << Indent << " '";
54809467b48Spatrick OS.write_escaped(Strings.slice(0, Size), /*hex=*/true);
54909467b48Spatrick OS << "'\n";
55009467b48Spatrick Strings = Strings.drop_front(Size);
55109467b48Spatrick } while (--NumStrings);
55209467b48Spatrick
55309467b48Spatrick OS << Indent << " }";
55409467b48Spatrick return Error::success();
55509467b48Spatrick }
55609467b48Spatrick
BitcodeAnalyzer(StringRef Buffer,std::optional<StringRef> BlockInfoBuffer)55709467b48Spatrick BitcodeAnalyzer::BitcodeAnalyzer(StringRef Buffer,
558*d415bd75Srobert std::optional<StringRef> BlockInfoBuffer)
55909467b48Spatrick : Stream(Buffer) {
56009467b48Spatrick if (BlockInfoBuffer)
56109467b48Spatrick BlockInfoStream.emplace(*BlockInfoBuffer);
56209467b48Spatrick }
56309467b48Spatrick
analyze(std::optional<BCDumpOptions> O,std::optional<StringRef> CheckHash)564*d415bd75Srobert Error BitcodeAnalyzer::analyze(std::optional<BCDumpOptions> O,
565*d415bd75Srobert std::optional<StringRef> CheckHash) {
566*d415bd75Srobert if (Error E = analyzeHeader(O, Stream).moveInto(CurStreamType))
567*d415bd75Srobert return E;
56809467b48Spatrick
56909467b48Spatrick Stream.setBlockInfo(&BlockInfo);
57009467b48Spatrick
57109467b48Spatrick // Read block info from BlockInfoStream, if specified.
57209467b48Spatrick // The block info must be a top-level block.
57309467b48Spatrick if (BlockInfoStream) {
57409467b48Spatrick BitstreamCursor BlockInfoCursor(*BlockInfoStream);
575*d415bd75Srobert if (Error E = analyzeHeader(O, BlockInfoCursor).takeError())
576*d415bd75Srobert return E;
57709467b48Spatrick
57809467b48Spatrick while (!BlockInfoCursor.AtEndOfStream()) {
57909467b48Spatrick Expected<unsigned> MaybeCode = BlockInfoCursor.ReadCode();
58009467b48Spatrick if (!MaybeCode)
58109467b48Spatrick return MaybeCode.takeError();
58209467b48Spatrick if (MaybeCode.get() != bitc::ENTER_SUBBLOCK)
58309467b48Spatrick return reportError("Invalid record at top-level in block info file");
58409467b48Spatrick
58509467b48Spatrick Expected<unsigned> MaybeBlockID = BlockInfoCursor.ReadSubBlockID();
58609467b48Spatrick if (!MaybeBlockID)
58709467b48Spatrick return MaybeBlockID.takeError();
58809467b48Spatrick if (MaybeBlockID.get() == bitc::BLOCKINFO_BLOCK_ID) {
589*d415bd75Srobert std::optional<BitstreamBlockInfo> NewBlockInfo;
590*d415bd75Srobert if (Error E =
591*d415bd75Srobert BlockInfoCursor.ReadBlockInfoBlock(/*ReadBlockInfoNames=*/true)
592*d415bd75Srobert .moveInto(NewBlockInfo))
593*d415bd75Srobert return E;
59409467b48Spatrick if (!NewBlockInfo)
59509467b48Spatrick return reportError("Malformed BlockInfoBlock in block info file");
59609467b48Spatrick BlockInfo = std::move(*NewBlockInfo);
59709467b48Spatrick break;
59809467b48Spatrick }
59909467b48Spatrick
60009467b48Spatrick if (Error Err = BlockInfoCursor.SkipBlock())
60109467b48Spatrick return Err;
60209467b48Spatrick }
60309467b48Spatrick }
60409467b48Spatrick
60509467b48Spatrick // Parse the top-level structure. We only allow blocks at the top-level.
60609467b48Spatrick while (!Stream.AtEndOfStream()) {
60709467b48Spatrick Expected<unsigned> MaybeCode = Stream.ReadCode();
60809467b48Spatrick if (!MaybeCode)
60909467b48Spatrick return MaybeCode.takeError();
61009467b48Spatrick if (MaybeCode.get() != bitc::ENTER_SUBBLOCK)
61109467b48Spatrick return reportError("Invalid record at top-level");
61209467b48Spatrick
61309467b48Spatrick Expected<unsigned> MaybeBlockID = Stream.ReadSubBlockID();
61409467b48Spatrick if (!MaybeBlockID)
61509467b48Spatrick return MaybeBlockID.takeError();
61609467b48Spatrick
61709467b48Spatrick if (Error E = parseBlock(MaybeBlockID.get(), 0, O, CheckHash))
61809467b48Spatrick return E;
61909467b48Spatrick ++NumTopBlocks;
62009467b48Spatrick }
62109467b48Spatrick
62209467b48Spatrick return Error::success();
62309467b48Spatrick }
62409467b48Spatrick
printStats(BCDumpOptions O,std::optional<StringRef> Filename)62509467b48Spatrick void BitcodeAnalyzer::printStats(BCDumpOptions O,
626*d415bd75Srobert std::optional<StringRef> Filename) {
62709467b48Spatrick uint64_t BufferSizeBits = Stream.getBitcodeBytes().size() * CHAR_BIT;
62809467b48Spatrick // Print a summary of the read file.
62909467b48Spatrick O.OS << "Summary ";
63009467b48Spatrick if (Filename)
63109467b48Spatrick O.OS << "of " << Filename->data() << ":\n";
63209467b48Spatrick O.OS << " Total size: ";
63309467b48Spatrick printSize(O.OS, BufferSizeBits);
63409467b48Spatrick O.OS << "\n";
63509467b48Spatrick O.OS << " Stream type: ";
63609467b48Spatrick switch (CurStreamType) {
63709467b48Spatrick case UnknownBitstream:
63809467b48Spatrick O.OS << "unknown\n";
63909467b48Spatrick break;
64009467b48Spatrick case LLVMIRBitstream:
64109467b48Spatrick O.OS << "LLVM IR\n";
64209467b48Spatrick break;
64309467b48Spatrick case ClangSerializedASTBitstream:
64409467b48Spatrick O.OS << "Clang Serialized AST\n";
64509467b48Spatrick break;
64609467b48Spatrick case ClangSerializedDiagnosticsBitstream:
64709467b48Spatrick O.OS << "Clang Serialized Diagnostics\n";
64809467b48Spatrick break;
64909467b48Spatrick case LLVMBitstreamRemarks:
65009467b48Spatrick O.OS << "LLVM Remarks\n";
65109467b48Spatrick break;
65209467b48Spatrick }
65309467b48Spatrick O.OS << " # Toplevel Blocks: " << NumTopBlocks << "\n";
65409467b48Spatrick O.OS << "\n";
65509467b48Spatrick
65609467b48Spatrick // Emit per-block stats.
65709467b48Spatrick O.OS << "Per-block Summary:\n";
658*d415bd75Srobert for (const auto &Stat : BlockIDStats) {
659*d415bd75Srobert O.OS << " Block ID #" << Stat.first;
660*d415bd75Srobert if (std::optional<const char *> BlockName =
661*d415bd75Srobert GetBlockName(Stat.first, BlockInfo, CurStreamType))
66209467b48Spatrick O.OS << " (" << *BlockName << ")";
66309467b48Spatrick O.OS << ":\n";
66409467b48Spatrick
665*d415bd75Srobert const PerBlockIDStats &Stats = Stat.second;
66609467b48Spatrick O.OS << " Num Instances: " << Stats.NumInstances << "\n";
66709467b48Spatrick O.OS << " Total Size: ";
66809467b48Spatrick printSize(O.OS, Stats.NumBits);
66909467b48Spatrick O.OS << "\n";
67009467b48Spatrick double pct = (Stats.NumBits * 100.0) / BufferSizeBits;
67109467b48Spatrick O.OS << " Percent of file: " << format("%2.4f%%", pct) << "\n";
67209467b48Spatrick if (Stats.NumInstances > 1) {
67309467b48Spatrick O.OS << " Average Size: ";
67409467b48Spatrick printSize(O.OS, Stats.NumBits / (double)Stats.NumInstances);
67509467b48Spatrick O.OS << "\n";
67609467b48Spatrick O.OS << " Tot/Avg SubBlocks: " << Stats.NumSubBlocks << "/"
67709467b48Spatrick << Stats.NumSubBlocks / (double)Stats.NumInstances << "\n";
67809467b48Spatrick O.OS << " Tot/Avg Abbrevs: " << Stats.NumAbbrevs << "/"
67909467b48Spatrick << Stats.NumAbbrevs / (double)Stats.NumInstances << "\n";
68009467b48Spatrick O.OS << " Tot/Avg Records: " << Stats.NumRecords << "/"
68109467b48Spatrick << Stats.NumRecords / (double)Stats.NumInstances << "\n";
68209467b48Spatrick } else {
68309467b48Spatrick O.OS << " Num SubBlocks: " << Stats.NumSubBlocks << "\n";
68409467b48Spatrick O.OS << " Num Abbrevs: " << Stats.NumAbbrevs << "\n";
68509467b48Spatrick O.OS << " Num Records: " << Stats.NumRecords << "\n";
68609467b48Spatrick }
68709467b48Spatrick if (Stats.NumRecords) {
68809467b48Spatrick double pct = (Stats.NumAbbreviatedRecords * 100.0) / Stats.NumRecords;
68909467b48Spatrick O.OS << " Percent Abbrevs: " << format("%2.4f%%", pct) << "\n";
69009467b48Spatrick }
69109467b48Spatrick O.OS << "\n";
69209467b48Spatrick
69309467b48Spatrick // Print a histogram of the codes we see.
69409467b48Spatrick if (O.Histogram && !Stats.CodeFreq.empty()) {
69509467b48Spatrick std::vector<std::pair<unsigned, unsigned>> FreqPairs; // <freq,code>
69609467b48Spatrick for (unsigned i = 0, e = Stats.CodeFreq.size(); i != e; ++i)
69709467b48Spatrick if (unsigned Freq = Stats.CodeFreq[i].NumInstances)
69809467b48Spatrick FreqPairs.push_back(std::make_pair(Freq, i));
69909467b48Spatrick llvm::stable_sort(FreqPairs);
70009467b48Spatrick std::reverse(FreqPairs.begin(), FreqPairs.end());
70109467b48Spatrick
70209467b48Spatrick O.OS << "\tRecord Histogram:\n";
70309467b48Spatrick O.OS << "\t\t Count # Bits b/Rec % Abv Record Kind\n";
704*d415bd75Srobert for (const auto &FreqPair : FreqPairs) {
705*d415bd75Srobert const PerRecordStats &RecStats = Stats.CodeFreq[FreqPair.second];
70609467b48Spatrick
70709467b48Spatrick O.OS << format("\t\t%7d %9lu", RecStats.NumInstances,
70809467b48Spatrick (unsigned long)RecStats.TotalBits);
70909467b48Spatrick
71009467b48Spatrick if (RecStats.NumInstances > 1)
71109467b48Spatrick O.OS << format(" %9.1f",
71209467b48Spatrick (double)RecStats.TotalBits / RecStats.NumInstances);
71309467b48Spatrick else
71409467b48Spatrick O.OS << " ";
71509467b48Spatrick
71609467b48Spatrick if (RecStats.NumAbbrev)
71709467b48Spatrick O.OS << format(" %7.2f", (double)RecStats.NumAbbrev /
71809467b48Spatrick RecStats.NumInstances * 100);
71909467b48Spatrick else
72009467b48Spatrick O.OS << " ";
72109467b48Spatrick
72209467b48Spatrick O.OS << " ";
723*d415bd75Srobert if (std::optional<const char *> CodeName = GetCodeName(
724*d415bd75Srobert FreqPair.second, Stat.first, BlockInfo, CurStreamType))
72509467b48Spatrick O.OS << *CodeName << "\n";
72609467b48Spatrick else
727*d415bd75Srobert O.OS << "UnknownCode" << FreqPair.second << "\n";
72809467b48Spatrick }
72909467b48Spatrick O.OS << "\n";
73009467b48Spatrick }
73109467b48Spatrick }
73209467b48Spatrick }
73309467b48Spatrick
parseBlock(unsigned BlockID,unsigned IndentLevel,std::optional<BCDumpOptions> O,std::optional<StringRef> CheckHash)73409467b48Spatrick Error BitcodeAnalyzer::parseBlock(unsigned BlockID, unsigned IndentLevel,
735*d415bd75Srobert std::optional<BCDumpOptions> O,
736*d415bd75Srobert std::optional<StringRef> CheckHash) {
73709467b48Spatrick std::string Indent(IndentLevel * 2, ' ');
73809467b48Spatrick uint64_t BlockBitStart = Stream.GetCurrentBitNo();
73909467b48Spatrick
74009467b48Spatrick // Get the statistics for this BlockID.
74109467b48Spatrick PerBlockIDStats &BlockStats = BlockIDStats[BlockID];
74209467b48Spatrick
74309467b48Spatrick BlockStats.NumInstances++;
74409467b48Spatrick
74509467b48Spatrick // BLOCKINFO is a special part of the stream.
746*d415bd75Srobert bool DumpRecords = O.has_value();
74709467b48Spatrick if (BlockID == bitc::BLOCKINFO_BLOCK_ID) {
748*d415bd75Srobert if (O && !O->DumpBlockinfo)
74909467b48Spatrick O->OS << Indent << "<BLOCKINFO_BLOCK/>\n";
750*d415bd75Srobert std::optional<BitstreamBlockInfo> NewBlockInfo;
751*d415bd75Srobert if (Error E = Stream.ReadBlockInfoBlock(/*ReadBlockInfoNames=*/true)
752*d415bd75Srobert .moveInto(NewBlockInfo))
753*d415bd75Srobert return E;
75409467b48Spatrick if (!NewBlockInfo)
75509467b48Spatrick return reportError("Malformed BlockInfoBlock");
75609467b48Spatrick BlockInfo = std::move(*NewBlockInfo);
75709467b48Spatrick if (Error Err = Stream.JumpToBit(BlockBitStart))
75809467b48Spatrick return Err;
75909467b48Spatrick // It's not really interesting to dump the contents of the blockinfo
760*d415bd75Srobert // block, so only do it if the user explicitly requests it.
761*d415bd75Srobert DumpRecords = O && O->DumpBlockinfo;
76209467b48Spatrick }
76309467b48Spatrick
76409467b48Spatrick unsigned NumWords = 0;
76509467b48Spatrick if (Error Err = Stream.EnterSubBlock(BlockID, &NumWords))
76609467b48Spatrick return Err;
76709467b48Spatrick
76809467b48Spatrick // Keep it for later, when we see a MODULE_HASH record
76909467b48Spatrick uint64_t BlockEntryPos = Stream.getCurrentByteNo();
77009467b48Spatrick
771*d415bd75Srobert std::optional<const char *> BlockName;
77209467b48Spatrick if (DumpRecords) {
77309467b48Spatrick O->OS << Indent << "<";
77409467b48Spatrick if ((BlockName = GetBlockName(BlockID, BlockInfo, CurStreamType)))
77509467b48Spatrick O->OS << *BlockName;
77609467b48Spatrick else
77709467b48Spatrick O->OS << "UnknownBlock" << BlockID;
77809467b48Spatrick
77909467b48Spatrick if (!O->Symbolic && BlockName)
78009467b48Spatrick O->OS << " BlockID=" << BlockID;
78109467b48Spatrick
78209467b48Spatrick O->OS << " NumWords=" << NumWords
78309467b48Spatrick << " BlockCodeSize=" << Stream.getAbbrevIDWidth() << ">\n";
78409467b48Spatrick }
78509467b48Spatrick
78609467b48Spatrick SmallVector<uint64_t, 64> Record;
78709467b48Spatrick
78809467b48Spatrick // Keep the offset to the metadata index if seen.
78909467b48Spatrick uint64_t MetadataIndexOffset = 0;
79009467b48Spatrick
79109467b48Spatrick // Read all the records for this block.
792*d415bd75Srobert while (true) {
79309467b48Spatrick if (Stream.AtEndOfStream())
79409467b48Spatrick return reportError("Premature end of bitstream");
79509467b48Spatrick
79609467b48Spatrick uint64_t RecordStartBit = Stream.GetCurrentBitNo();
79709467b48Spatrick
798*d415bd75Srobert BitstreamEntry Entry;
799*d415bd75Srobert if (Error E = Stream.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs)
800*d415bd75Srobert .moveInto(Entry))
801*d415bd75Srobert return E;
80209467b48Spatrick
80309467b48Spatrick switch (Entry.Kind) {
80409467b48Spatrick case BitstreamEntry::Error:
80509467b48Spatrick return reportError("malformed bitcode file");
80609467b48Spatrick case BitstreamEntry::EndBlock: {
80709467b48Spatrick uint64_t BlockBitEnd = Stream.GetCurrentBitNo();
80809467b48Spatrick BlockStats.NumBits += BlockBitEnd - BlockBitStart;
80909467b48Spatrick if (DumpRecords) {
81009467b48Spatrick O->OS << Indent << "</";
81109467b48Spatrick if (BlockName)
81209467b48Spatrick O->OS << *BlockName << ">\n";
81309467b48Spatrick else
81409467b48Spatrick O->OS << "UnknownBlock" << BlockID << ">\n";
81509467b48Spatrick }
81609467b48Spatrick return Error::success();
81709467b48Spatrick }
81809467b48Spatrick
81909467b48Spatrick case BitstreamEntry::SubBlock: {
82009467b48Spatrick uint64_t SubBlockBitStart = Stream.GetCurrentBitNo();
82109467b48Spatrick if (Error E = parseBlock(Entry.ID, IndentLevel + 1, O, CheckHash))
82209467b48Spatrick return E;
82309467b48Spatrick ++BlockStats.NumSubBlocks;
82409467b48Spatrick uint64_t SubBlockBitEnd = Stream.GetCurrentBitNo();
82509467b48Spatrick
82609467b48Spatrick // Don't include subblock sizes in the size of this block.
82709467b48Spatrick BlockBitStart += SubBlockBitEnd - SubBlockBitStart;
82809467b48Spatrick continue;
82909467b48Spatrick }
83009467b48Spatrick case BitstreamEntry::Record:
83109467b48Spatrick // The interesting case.
83209467b48Spatrick break;
83309467b48Spatrick }
83409467b48Spatrick
83509467b48Spatrick if (Entry.ID == bitc::DEFINE_ABBREV) {
83609467b48Spatrick if (Error Err = Stream.ReadAbbrevRecord())
83709467b48Spatrick return Err;
83809467b48Spatrick ++BlockStats.NumAbbrevs;
83909467b48Spatrick continue;
84009467b48Spatrick }
84109467b48Spatrick
84209467b48Spatrick Record.clear();
84309467b48Spatrick
84409467b48Spatrick ++BlockStats.NumRecords;
84509467b48Spatrick
84609467b48Spatrick StringRef Blob;
84709467b48Spatrick uint64_t CurrentRecordPos = Stream.GetCurrentBitNo();
848*d415bd75Srobert unsigned Code;
849*d415bd75Srobert if (Error E = Stream.readRecord(Entry.ID, Record, &Blob).moveInto(Code))
850*d415bd75Srobert return E;
85109467b48Spatrick
85209467b48Spatrick // Increment the # occurrences of this code.
85309467b48Spatrick if (BlockStats.CodeFreq.size() <= Code)
85409467b48Spatrick BlockStats.CodeFreq.resize(Code + 1);
85509467b48Spatrick BlockStats.CodeFreq[Code].NumInstances++;
85609467b48Spatrick BlockStats.CodeFreq[Code].TotalBits +=
85709467b48Spatrick Stream.GetCurrentBitNo() - RecordStartBit;
85809467b48Spatrick if (Entry.ID != bitc::UNABBREV_RECORD) {
85909467b48Spatrick BlockStats.CodeFreq[Code].NumAbbrev++;
86009467b48Spatrick ++BlockStats.NumAbbreviatedRecords;
86109467b48Spatrick }
86209467b48Spatrick
86309467b48Spatrick if (DumpRecords) {
86409467b48Spatrick O->OS << Indent << " <";
865*d415bd75Srobert std::optional<const char *> CodeName =
86609467b48Spatrick GetCodeName(Code, BlockID, BlockInfo, CurStreamType);
86709467b48Spatrick if (CodeName)
86809467b48Spatrick O->OS << *CodeName;
86909467b48Spatrick else
87009467b48Spatrick O->OS << "UnknownCode" << Code;
87109467b48Spatrick if (!O->Symbolic && CodeName)
87209467b48Spatrick O->OS << " codeid=" << Code;
87309467b48Spatrick const BitCodeAbbrev *Abbv = nullptr;
87409467b48Spatrick if (Entry.ID != bitc::UNABBREV_RECORD) {
875*d415bd75Srobert Expected<const BitCodeAbbrev *> MaybeAbbv = Stream.getAbbrev(Entry.ID);
876*d415bd75Srobert if (!MaybeAbbv)
877*d415bd75Srobert return MaybeAbbv.takeError();
878*d415bd75Srobert Abbv = MaybeAbbv.get();
87909467b48Spatrick O->OS << " abbrevid=" << Entry.ID;
88009467b48Spatrick }
88109467b48Spatrick
88209467b48Spatrick for (unsigned i = 0, e = Record.size(); i != e; ++i)
88309467b48Spatrick O->OS << " op" << i << "=" << (int64_t)Record[i];
88409467b48Spatrick
88509467b48Spatrick // If we found a metadata index, let's verify that we had an offset
88609467b48Spatrick // before and validate its forward reference offset was correct!
88709467b48Spatrick if (BlockID == bitc::METADATA_BLOCK_ID) {
88809467b48Spatrick if (Code == bitc::METADATA_INDEX_OFFSET) {
88909467b48Spatrick if (Record.size() != 2)
89009467b48Spatrick O->OS << "(Invalid record)";
89109467b48Spatrick else {
89209467b48Spatrick auto Offset = Record[0] + (Record[1] << 32);
89309467b48Spatrick MetadataIndexOffset = Stream.GetCurrentBitNo() + Offset;
89409467b48Spatrick }
89509467b48Spatrick }
89609467b48Spatrick if (Code == bitc::METADATA_INDEX) {
89709467b48Spatrick O->OS << " (offset ";
89809467b48Spatrick if (MetadataIndexOffset == RecordStartBit)
89909467b48Spatrick O->OS << "match)";
90009467b48Spatrick else
90109467b48Spatrick O->OS << "mismatch: " << MetadataIndexOffset << " vs "
90209467b48Spatrick << RecordStartBit << ")";
90309467b48Spatrick }
90409467b48Spatrick }
90509467b48Spatrick
90609467b48Spatrick // If we found a module hash, let's verify that it matches!
90709467b48Spatrick if (BlockID == bitc::MODULE_BLOCK_ID && Code == bitc::MODULE_CODE_HASH &&
908*d415bd75Srobert CheckHash) {
90909467b48Spatrick if (Record.size() != 5)
91009467b48Spatrick O->OS << " (invalid)";
91109467b48Spatrick else {
91209467b48Spatrick // Recompute the hash and compare it to the one in the bitcode
91309467b48Spatrick SHA1 Hasher;
914*d415bd75Srobert std::array<uint8_t, 20> Hash;
91509467b48Spatrick Hasher.update(*CheckHash);
91609467b48Spatrick {
91709467b48Spatrick int BlockSize = (CurrentRecordPos / 8) - BlockEntryPos;
91809467b48Spatrick auto Ptr = Stream.getPointerToByte(BlockEntryPos, BlockSize);
91909467b48Spatrick Hasher.update(ArrayRef<uint8_t>(Ptr, BlockSize));
92009467b48Spatrick Hash = Hasher.result();
92109467b48Spatrick }
922*d415bd75Srobert std::array<uint8_t, 20> RecordedHash;
92309467b48Spatrick int Pos = 0;
92409467b48Spatrick for (auto &Val : Record) {
92509467b48Spatrick assert(!(Val >> 32) && "Unexpected high bits set");
926097a140dSpatrick support::endian::write32be(&RecordedHash[Pos], Val);
927097a140dSpatrick Pos += 4;
92809467b48Spatrick }
929*d415bd75Srobert if (Hash == RecordedHash)
93009467b48Spatrick O->OS << " (match)";
93109467b48Spatrick else
93209467b48Spatrick O->OS << " (!mismatch!)";
93309467b48Spatrick }
93409467b48Spatrick }
93509467b48Spatrick
93609467b48Spatrick O->OS << "/>";
93709467b48Spatrick
93809467b48Spatrick if (Abbv) {
93909467b48Spatrick for (unsigned i = 1, e = Abbv->getNumOperandInfos(); i != e; ++i) {
94009467b48Spatrick const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
94109467b48Spatrick if (!Op.isEncoding() || Op.getEncoding() != BitCodeAbbrevOp::Array)
94209467b48Spatrick continue;
94309467b48Spatrick assert(i + 2 == e && "Array op not second to last");
94409467b48Spatrick std::string Str;
94509467b48Spatrick bool ArrayIsPrintable = true;
94609467b48Spatrick for (unsigned j = i - 1, je = Record.size(); j != je; ++j) {
94709467b48Spatrick if (!isPrint(static_cast<unsigned char>(Record[j]))) {
94809467b48Spatrick ArrayIsPrintable = false;
94909467b48Spatrick break;
95009467b48Spatrick }
95109467b48Spatrick Str += (char)Record[j];
95209467b48Spatrick }
95309467b48Spatrick if (ArrayIsPrintable)
95409467b48Spatrick O->OS << " record string = '" << Str << "'";
95509467b48Spatrick break;
95609467b48Spatrick }
95709467b48Spatrick }
95809467b48Spatrick
95909467b48Spatrick if (Blob.data()) {
96009467b48Spatrick if (canDecodeBlob(Code, BlockID)) {
96109467b48Spatrick if (Error E = decodeMetadataStringsBlob(Indent, Record, Blob, O->OS))
96209467b48Spatrick return E;
96309467b48Spatrick } else {
96409467b48Spatrick O->OS << " blob data = ";
96509467b48Spatrick if (O->ShowBinaryBlobs) {
96609467b48Spatrick O->OS << "'";
96709467b48Spatrick O->OS.write_escaped(Blob, /*hex=*/true) << "'";
96809467b48Spatrick } else {
96909467b48Spatrick bool BlobIsPrintable = true;
970*d415bd75Srobert for (char C : Blob)
971*d415bd75Srobert if (!isPrint(static_cast<unsigned char>(C))) {
97209467b48Spatrick BlobIsPrintable = false;
97309467b48Spatrick break;
97409467b48Spatrick }
97509467b48Spatrick
97609467b48Spatrick if (BlobIsPrintable)
97709467b48Spatrick O->OS << "'" << Blob << "'";
97809467b48Spatrick else
97909467b48Spatrick O->OS << "unprintable, " << Blob.size() << " bytes.";
98009467b48Spatrick }
98109467b48Spatrick }
98209467b48Spatrick }
98309467b48Spatrick
98409467b48Spatrick O->OS << "\n";
98509467b48Spatrick }
98609467b48Spatrick
98709467b48Spatrick // Make sure that we can skip the current record.
98809467b48Spatrick if (Error Err = Stream.JumpToBit(CurrentRecordPos))
98909467b48Spatrick return Err;
99009467b48Spatrick if (Expected<unsigned> Skipped = Stream.skipRecord(Entry.ID))
99109467b48Spatrick ; // Do nothing.
99209467b48Spatrick else
99309467b48Spatrick return Skipped.takeError();
99409467b48Spatrick }
99509467b48Spatrick }
99609467b48Spatrick
997