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