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