14cdb68ebSFrancis Visoiu Mistrih //===- BitcodeAnalyzer.cpp - Internal BitcodeAnalyzer implementation ------===// 24cdb68ebSFrancis Visoiu Mistrih // 34cdb68ebSFrancis Visoiu Mistrih // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 44cdb68ebSFrancis Visoiu Mistrih // See https://llvm.org/LICENSE.txt for license information. 54cdb68ebSFrancis Visoiu Mistrih // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 64cdb68ebSFrancis Visoiu Mistrih // 74cdb68ebSFrancis Visoiu Mistrih //===----------------------------------------------------------------------===// 84cdb68ebSFrancis Visoiu Mistrih 94cdb68ebSFrancis Visoiu Mistrih #include "llvm/Bitcode/BitcodeAnalyzer.h" 104cdb68ebSFrancis Visoiu Mistrih #include "llvm/Bitcode/BitcodeReader.h" 114cdb68ebSFrancis Visoiu Mistrih #include "llvm/Bitcode/LLVMBitCodes.h" 121a697aa6SFrancis Visoiu Mistrih #include "llvm/Bitstream/BitCodes.h" 131a697aa6SFrancis Visoiu Mistrih #include "llvm/Bitstream/BitstreamReader.h" 144cdb68ebSFrancis Visoiu Mistrih #include "llvm/Support/Format.h" 154cdb68ebSFrancis Visoiu Mistrih #include "llvm/Support/SHA1.h" 164cdb68ebSFrancis Visoiu Mistrih 174cdb68ebSFrancis Visoiu Mistrih using namespace llvm; 184cdb68ebSFrancis Visoiu Mistrih 194cdb68ebSFrancis Visoiu Mistrih static Error reportError(StringRef Message) { 204cdb68ebSFrancis Visoiu Mistrih return createStringError(std::errc::illegal_byte_sequence, Message.data()); 214cdb68ebSFrancis Visoiu Mistrih } 224cdb68ebSFrancis Visoiu Mistrih 234cdb68ebSFrancis Visoiu Mistrih /// Return a symbolic block name if known, otherwise return null. 244cdb68ebSFrancis Visoiu Mistrih static Optional<const char *> GetBlockName(unsigned BlockID, 254cdb68ebSFrancis Visoiu Mistrih const BitstreamBlockInfo &BlockInfo, 264cdb68ebSFrancis Visoiu Mistrih CurStreamTypeType CurStreamType) { 274cdb68ebSFrancis Visoiu Mistrih // Standard blocks for all bitcode files. 284cdb68ebSFrancis Visoiu Mistrih if (BlockID < bitc::FIRST_APPLICATION_BLOCKID) { 294cdb68ebSFrancis Visoiu Mistrih if (BlockID == bitc::BLOCKINFO_BLOCK_ID) 304cdb68ebSFrancis Visoiu Mistrih return "BLOCKINFO_BLOCK"; 314cdb68ebSFrancis Visoiu Mistrih return None; 324cdb68ebSFrancis Visoiu Mistrih } 334cdb68ebSFrancis Visoiu Mistrih 344cdb68ebSFrancis Visoiu Mistrih // Check to see if we have a blockinfo record for this block, with a name. 354cdb68ebSFrancis Visoiu Mistrih if (const BitstreamBlockInfo::BlockInfo *Info = 364cdb68ebSFrancis Visoiu Mistrih BlockInfo.getBlockInfo(BlockID)) { 374cdb68ebSFrancis Visoiu Mistrih if (!Info->Name.empty()) 384cdb68ebSFrancis Visoiu Mistrih return Info->Name.c_str(); 394cdb68ebSFrancis Visoiu Mistrih } 404cdb68ebSFrancis Visoiu Mistrih 414cdb68ebSFrancis Visoiu Mistrih if (CurStreamType != LLVMIRBitstream) 424cdb68ebSFrancis Visoiu Mistrih return None; 434cdb68ebSFrancis Visoiu Mistrih 444cdb68ebSFrancis Visoiu Mistrih switch (BlockID) { 454cdb68ebSFrancis Visoiu Mistrih default: 464cdb68ebSFrancis Visoiu Mistrih return None; 474cdb68ebSFrancis Visoiu Mistrih case bitc::OPERAND_BUNDLE_TAGS_BLOCK_ID: 484cdb68ebSFrancis Visoiu Mistrih return "OPERAND_BUNDLE_TAGS_BLOCK"; 494cdb68ebSFrancis Visoiu Mistrih case bitc::MODULE_BLOCK_ID: 504cdb68ebSFrancis Visoiu Mistrih return "MODULE_BLOCK"; 514cdb68ebSFrancis Visoiu Mistrih case bitc::PARAMATTR_BLOCK_ID: 524cdb68ebSFrancis Visoiu Mistrih return "PARAMATTR_BLOCK"; 534cdb68ebSFrancis Visoiu Mistrih case bitc::PARAMATTR_GROUP_BLOCK_ID: 544cdb68ebSFrancis Visoiu Mistrih return "PARAMATTR_GROUP_BLOCK_ID"; 554cdb68ebSFrancis Visoiu Mistrih case bitc::TYPE_BLOCK_ID_NEW: 564cdb68ebSFrancis Visoiu Mistrih return "TYPE_BLOCK_ID"; 574cdb68ebSFrancis Visoiu Mistrih case bitc::CONSTANTS_BLOCK_ID: 584cdb68ebSFrancis Visoiu Mistrih return "CONSTANTS_BLOCK"; 594cdb68ebSFrancis Visoiu Mistrih case bitc::FUNCTION_BLOCK_ID: 604cdb68ebSFrancis Visoiu Mistrih return "FUNCTION_BLOCK"; 614cdb68ebSFrancis Visoiu Mistrih case bitc::IDENTIFICATION_BLOCK_ID: 624cdb68ebSFrancis Visoiu Mistrih return "IDENTIFICATION_BLOCK_ID"; 634cdb68ebSFrancis Visoiu Mistrih case bitc::VALUE_SYMTAB_BLOCK_ID: 644cdb68ebSFrancis Visoiu Mistrih return "VALUE_SYMTAB"; 654cdb68ebSFrancis Visoiu Mistrih case bitc::METADATA_BLOCK_ID: 664cdb68ebSFrancis Visoiu Mistrih return "METADATA_BLOCK"; 674cdb68ebSFrancis Visoiu Mistrih case bitc::METADATA_KIND_BLOCK_ID: 684cdb68ebSFrancis Visoiu Mistrih return "METADATA_KIND_BLOCK"; 694cdb68ebSFrancis Visoiu Mistrih case bitc::METADATA_ATTACHMENT_ID: 704cdb68ebSFrancis Visoiu Mistrih return "METADATA_ATTACHMENT_BLOCK"; 714cdb68ebSFrancis Visoiu Mistrih case bitc::USELIST_BLOCK_ID: 724cdb68ebSFrancis Visoiu Mistrih return "USELIST_BLOCK_ID"; 734cdb68ebSFrancis Visoiu Mistrih case bitc::GLOBALVAL_SUMMARY_BLOCK_ID: 744cdb68ebSFrancis Visoiu Mistrih return "GLOBALVAL_SUMMARY_BLOCK"; 754cdb68ebSFrancis Visoiu Mistrih case bitc::FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID: 764cdb68ebSFrancis Visoiu Mistrih return "FULL_LTO_GLOBALVAL_SUMMARY_BLOCK"; 774cdb68ebSFrancis Visoiu Mistrih case bitc::MODULE_STRTAB_BLOCK_ID: 784cdb68ebSFrancis Visoiu Mistrih return "MODULE_STRTAB_BLOCK"; 794cdb68ebSFrancis Visoiu Mistrih case bitc::STRTAB_BLOCK_ID: 804cdb68ebSFrancis Visoiu Mistrih return "STRTAB_BLOCK"; 814cdb68ebSFrancis Visoiu Mistrih case bitc::SYMTAB_BLOCK_ID: 824cdb68ebSFrancis Visoiu Mistrih return "SYMTAB_BLOCK"; 834cdb68ebSFrancis Visoiu Mistrih } 844cdb68ebSFrancis Visoiu Mistrih } 854cdb68ebSFrancis Visoiu Mistrih 864cdb68ebSFrancis Visoiu Mistrih /// Return a symbolic code name if known, otherwise return null. 874cdb68ebSFrancis Visoiu Mistrih static Optional<const char *> GetCodeName(unsigned CodeID, unsigned BlockID, 884cdb68ebSFrancis Visoiu Mistrih const BitstreamBlockInfo &BlockInfo, 894cdb68ebSFrancis Visoiu Mistrih CurStreamTypeType CurStreamType) { 904cdb68ebSFrancis Visoiu Mistrih // Standard blocks for all bitcode files. 914cdb68ebSFrancis Visoiu Mistrih if (BlockID < bitc::FIRST_APPLICATION_BLOCKID) { 924cdb68ebSFrancis Visoiu Mistrih if (BlockID == bitc::BLOCKINFO_BLOCK_ID) { 934cdb68ebSFrancis Visoiu Mistrih switch (CodeID) { 944cdb68ebSFrancis Visoiu Mistrih default: 954cdb68ebSFrancis Visoiu Mistrih return None; 964cdb68ebSFrancis Visoiu Mistrih case bitc::BLOCKINFO_CODE_SETBID: 974cdb68ebSFrancis Visoiu Mistrih return "SETBID"; 984cdb68ebSFrancis Visoiu Mistrih case bitc::BLOCKINFO_CODE_BLOCKNAME: 994cdb68ebSFrancis Visoiu Mistrih return "BLOCKNAME"; 1004cdb68ebSFrancis Visoiu Mistrih case bitc::BLOCKINFO_CODE_SETRECORDNAME: 1014cdb68ebSFrancis Visoiu Mistrih return "SETRECORDNAME"; 1024cdb68ebSFrancis Visoiu Mistrih } 1034cdb68ebSFrancis Visoiu Mistrih } 1044cdb68ebSFrancis Visoiu Mistrih return None; 1054cdb68ebSFrancis Visoiu Mistrih } 1064cdb68ebSFrancis Visoiu Mistrih 1074cdb68ebSFrancis Visoiu Mistrih // Check to see if we have a blockinfo record for this record, with a name. 1084cdb68ebSFrancis Visoiu Mistrih if (const BitstreamBlockInfo::BlockInfo *Info = 1094cdb68ebSFrancis Visoiu Mistrih BlockInfo.getBlockInfo(BlockID)) { 1104cdb68ebSFrancis Visoiu Mistrih for (unsigned i = 0, e = Info->RecordNames.size(); i != e; ++i) 1114cdb68ebSFrancis Visoiu Mistrih if (Info->RecordNames[i].first == CodeID) 1124cdb68ebSFrancis Visoiu Mistrih return Info->RecordNames[i].second.c_str(); 1134cdb68ebSFrancis Visoiu Mistrih } 1144cdb68ebSFrancis Visoiu Mistrih 1154cdb68ebSFrancis Visoiu Mistrih if (CurStreamType != LLVMIRBitstream) 1164cdb68ebSFrancis Visoiu Mistrih return None; 1174cdb68ebSFrancis Visoiu Mistrih 1184cdb68ebSFrancis Visoiu Mistrih #define STRINGIFY_CODE(PREFIX, CODE) \ 1194cdb68ebSFrancis Visoiu Mistrih case bitc::PREFIX##_##CODE: \ 1204cdb68ebSFrancis Visoiu Mistrih return #CODE; 1214cdb68ebSFrancis Visoiu Mistrih switch (BlockID) { 1224cdb68ebSFrancis Visoiu Mistrih default: 1234cdb68ebSFrancis Visoiu Mistrih return None; 1244cdb68ebSFrancis Visoiu Mistrih case bitc::MODULE_BLOCK_ID: 1254cdb68ebSFrancis Visoiu Mistrih switch (CodeID) { 1264cdb68ebSFrancis Visoiu Mistrih default: 1274cdb68ebSFrancis Visoiu Mistrih return None; 1284cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(MODULE_CODE, VERSION) 1294cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(MODULE_CODE, TRIPLE) 1304cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(MODULE_CODE, DATALAYOUT) 1314cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(MODULE_CODE, ASM) 1324cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(MODULE_CODE, SECTIONNAME) 1334cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(MODULE_CODE, DEPLIB) // FIXME: Remove in 4.0 1344cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(MODULE_CODE, GLOBALVAR) 1354cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(MODULE_CODE, FUNCTION) 1364cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(MODULE_CODE, ALIAS) 1374cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(MODULE_CODE, GCNAME) 1384cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(MODULE_CODE, VSTOFFSET) 1394cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(MODULE_CODE, METADATA_VALUES_UNUSED) 1404cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(MODULE_CODE, SOURCE_FILENAME) 1414cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(MODULE_CODE, HASH) 1424cdb68ebSFrancis Visoiu Mistrih } 1434cdb68ebSFrancis Visoiu Mistrih case bitc::IDENTIFICATION_BLOCK_ID: 1444cdb68ebSFrancis Visoiu Mistrih switch (CodeID) { 1454cdb68ebSFrancis Visoiu Mistrih default: 1464cdb68ebSFrancis Visoiu Mistrih return None; 1474cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(IDENTIFICATION_CODE, STRING) 1484cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(IDENTIFICATION_CODE, EPOCH) 1494cdb68ebSFrancis Visoiu Mistrih } 1504cdb68ebSFrancis Visoiu Mistrih case bitc::PARAMATTR_BLOCK_ID: 1514cdb68ebSFrancis Visoiu Mistrih switch (CodeID) { 1524cdb68ebSFrancis Visoiu Mistrih default: 1534cdb68ebSFrancis Visoiu Mistrih return None; 1544cdb68ebSFrancis Visoiu Mistrih // FIXME: Should these be different? 1554cdb68ebSFrancis Visoiu Mistrih case bitc::PARAMATTR_CODE_ENTRY_OLD: 1564cdb68ebSFrancis Visoiu Mistrih return "ENTRY"; 1574cdb68ebSFrancis Visoiu Mistrih case bitc::PARAMATTR_CODE_ENTRY: 1584cdb68ebSFrancis Visoiu Mistrih return "ENTRY"; 1594cdb68ebSFrancis Visoiu Mistrih } 1604cdb68ebSFrancis Visoiu Mistrih case bitc::PARAMATTR_GROUP_BLOCK_ID: 1614cdb68ebSFrancis Visoiu Mistrih switch (CodeID) { 1624cdb68ebSFrancis Visoiu Mistrih default: 1634cdb68ebSFrancis Visoiu Mistrih return None; 1644cdb68ebSFrancis Visoiu Mistrih case bitc::PARAMATTR_GRP_CODE_ENTRY: 1654cdb68ebSFrancis Visoiu Mistrih return "ENTRY"; 1664cdb68ebSFrancis Visoiu Mistrih } 1674cdb68ebSFrancis Visoiu Mistrih case bitc::TYPE_BLOCK_ID_NEW: 1684cdb68ebSFrancis Visoiu Mistrih switch (CodeID) { 1694cdb68ebSFrancis Visoiu Mistrih default: 1704cdb68ebSFrancis Visoiu Mistrih return None; 1714cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(TYPE_CODE, NUMENTRY) 1724cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(TYPE_CODE, VOID) 1734cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(TYPE_CODE, FLOAT) 1744cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(TYPE_CODE, DOUBLE) 1754cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(TYPE_CODE, LABEL) 1764cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(TYPE_CODE, OPAQUE) 1774cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(TYPE_CODE, INTEGER) 1784cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(TYPE_CODE, POINTER) 1794cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(TYPE_CODE, ARRAY) 1804cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(TYPE_CODE, VECTOR) 1814cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(TYPE_CODE, X86_FP80) 1824cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(TYPE_CODE, FP128) 1834cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(TYPE_CODE, PPC_FP128) 1844cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(TYPE_CODE, METADATA) 1854cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(TYPE_CODE, STRUCT_ANON) 1864cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(TYPE_CODE, STRUCT_NAME) 1874cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(TYPE_CODE, STRUCT_NAMED) 1884cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(TYPE_CODE, FUNCTION) 1894cdb68ebSFrancis Visoiu Mistrih } 1904cdb68ebSFrancis Visoiu Mistrih 1914cdb68ebSFrancis Visoiu Mistrih case bitc::CONSTANTS_BLOCK_ID: 1924cdb68ebSFrancis Visoiu Mistrih switch (CodeID) { 1934cdb68ebSFrancis Visoiu Mistrih default: 1944cdb68ebSFrancis Visoiu Mistrih return None; 1954cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(CST_CODE, SETTYPE) 1964cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(CST_CODE, NULL) 1974cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(CST_CODE, UNDEF) 1984cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(CST_CODE, INTEGER) 1994cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(CST_CODE, WIDE_INTEGER) 2004cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(CST_CODE, FLOAT) 2014cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(CST_CODE, AGGREGATE) 2024cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(CST_CODE, STRING) 2034cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(CST_CODE, CSTRING) 2044cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(CST_CODE, CE_BINOP) 2054cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(CST_CODE, CE_CAST) 2064cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(CST_CODE, CE_GEP) 2074cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(CST_CODE, CE_INBOUNDS_GEP) 2084cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(CST_CODE, CE_SELECT) 2094cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(CST_CODE, CE_EXTRACTELT) 2104cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(CST_CODE, CE_INSERTELT) 2114cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(CST_CODE, CE_SHUFFLEVEC) 2124cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(CST_CODE, CE_CMP) 2134cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(CST_CODE, INLINEASM) 2144cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(CST_CODE, CE_SHUFVEC_EX) 2154cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(CST_CODE, CE_UNOP) 2164cdb68ebSFrancis Visoiu Mistrih case bitc::CST_CODE_BLOCKADDRESS: 2174cdb68ebSFrancis Visoiu Mistrih return "CST_CODE_BLOCKADDRESS"; 2184cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(CST_CODE, DATA) 2194cdb68ebSFrancis Visoiu Mistrih } 2204cdb68ebSFrancis Visoiu Mistrih case bitc::FUNCTION_BLOCK_ID: 2214cdb68ebSFrancis Visoiu Mistrih switch (CodeID) { 2224cdb68ebSFrancis Visoiu Mistrih default: 2234cdb68ebSFrancis Visoiu Mistrih return None; 2244cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, DECLAREBLOCKS) 2254cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_BINOP) 2264cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_CAST) 2274cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_GEP_OLD) 2284cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_INBOUNDS_GEP_OLD) 2294cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_SELECT) 2304cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_EXTRACTELT) 2314cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_INSERTELT) 2324cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_SHUFFLEVEC) 2334cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_CMP) 2344cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_RET) 2354cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_BR) 2364cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_SWITCH) 2374cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_INVOKE) 2384cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_UNOP) 2394cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_UNREACHABLE) 2404cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_CLEANUPRET) 2414cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_CATCHRET) 2424cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_CATCHPAD) 2434cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_PHI) 2444cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_ALLOCA) 2454cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_LOAD) 2464cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_VAARG) 2474cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_STORE) 2484cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_EXTRACTVAL) 2494cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_INSERTVAL) 2504cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_CMP2) 2514cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_VSELECT) 2524cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, DEBUG_LOC_AGAIN) 2534cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_CALL) 2544cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, DEBUG_LOC) 2554cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_GEP) 2564cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, OPERAND_BUNDLE) 2574cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_FENCE) 2584cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_ATOMICRMW) 2594cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_LOADATOMIC) 2604cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_STOREATOMIC) 2614cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_CMPXCHG) 2624cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FUNC_CODE, INST_CALLBR) 2634cdb68ebSFrancis Visoiu Mistrih } 2644cdb68ebSFrancis Visoiu Mistrih case bitc::VALUE_SYMTAB_BLOCK_ID: 2654cdb68ebSFrancis Visoiu Mistrih switch (CodeID) { 2664cdb68ebSFrancis Visoiu Mistrih default: 2674cdb68ebSFrancis Visoiu Mistrih return None; 2684cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(VST_CODE, ENTRY) 2694cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(VST_CODE, BBENTRY) 2704cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(VST_CODE, FNENTRY) 2714cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(VST_CODE, COMBINED_ENTRY) 2724cdb68ebSFrancis Visoiu Mistrih } 2734cdb68ebSFrancis Visoiu Mistrih case bitc::MODULE_STRTAB_BLOCK_ID: 2744cdb68ebSFrancis Visoiu Mistrih switch (CodeID) { 2754cdb68ebSFrancis Visoiu Mistrih default: 2764cdb68ebSFrancis Visoiu Mistrih return None; 2774cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(MST_CODE, ENTRY) 2784cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(MST_CODE, HASH) 2794cdb68ebSFrancis Visoiu Mistrih } 2804cdb68ebSFrancis Visoiu Mistrih case bitc::GLOBALVAL_SUMMARY_BLOCK_ID: 2814cdb68ebSFrancis Visoiu Mistrih case bitc::FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID: 2824cdb68ebSFrancis Visoiu Mistrih switch (CodeID) { 2834cdb68ebSFrancis Visoiu Mistrih default: 2844cdb68ebSFrancis Visoiu Mistrih return None; 2854cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FS, PERMODULE) 2864cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FS, PERMODULE_PROFILE) 2874cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FS, PERMODULE_RELBF) 2884cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FS, PERMODULE_GLOBALVAR_INIT_REFS) 2894cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FS, PERMODULE_VTABLE_GLOBALVAR_INIT_REFS) 2904cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FS, COMBINED) 2914cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FS, COMBINED_PROFILE) 2924cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FS, COMBINED_GLOBALVAR_INIT_REFS) 2934cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FS, ALIAS) 2944cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FS, COMBINED_ALIAS) 2954cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FS, COMBINED_ORIGINAL_NAME) 2964cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FS, VERSION) 2974cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FS, FLAGS) 2984cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FS, TYPE_TESTS) 2994cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FS, TYPE_TEST_ASSUME_VCALLS) 3004cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FS, TYPE_CHECKED_LOAD_VCALLS) 3014cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FS, TYPE_TEST_ASSUME_CONST_VCALL) 3024cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FS, TYPE_CHECKED_LOAD_CONST_VCALL) 3034cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FS, VALUE_GUID) 3044cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FS, CFI_FUNCTION_DEFS) 3054cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FS, CFI_FUNCTION_DECLS) 3064cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FS, TYPE_ID) 3074cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(FS, TYPE_ID_METADATA) 308*a7fa35a6SHiroshi Yamauchi STRINGIFY_CODE(FS, BLOCK_COUNT) 3094cdb68ebSFrancis Visoiu Mistrih } 3104cdb68ebSFrancis Visoiu Mistrih case bitc::METADATA_ATTACHMENT_ID: 3114cdb68ebSFrancis Visoiu Mistrih switch (CodeID) { 3124cdb68ebSFrancis Visoiu Mistrih default: 3134cdb68ebSFrancis Visoiu Mistrih return None; 3144cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, ATTACHMENT) 3154cdb68ebSFrancis Visoiu Mistrih } 3164cdb68ebSFrancis Visoiu Mistrih case bitc::METADATA_BLOCK_ID: 3174cdb68ebSFrancis Visoiu Mistrih switch (CodeID) { 3184cdb68ebSFrancis Visoiu Mistrih default: 3194cdb68ebSFrancis Visoiu Mistrih return None; 3204cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, STRING_OLD) 3214cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, VALUE) 3224cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, NODE) 3234cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, NAME) 3244cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, DISTINCT_NODE) 3254cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, KIND) // Older bitcode has it in a MODULE_BLOCK 3264cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, LOCATION) 3274cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, OLD_NODE) 3284cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, OLD_FN_NODE) 3294cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, NAMED_NODE) 3304cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, GENERIC_DEBUG) 3314cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, SUBRANGE) 3324cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, ENUMERATOR) 3334cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, BASIC_TYPE) 3344cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, FILE) 3354cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, DERIVED_TYPE) 3364cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, COMPOSITE_TYPE) 3374cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, SUBROUTINE_TYPE) 3384cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, COMPILE_UNIT) 3394cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, SUBPROGRAM) 3404cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, LEXICAL_BLOCK) 3414cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, LEXICAL_BLOCK_FILE) 3424cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, NAMESPACE) 3434cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, TEMPLATE_TYPE) 3444cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, TEMPLATE_VALUE) 3454cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, GLOBAL_VAR) 3464cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, LOCAL_VAR) 3474cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, EXPRESSION) 3484cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, OBJC_PROPERTY) 3494cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, IMPORTED_ENTITY) 3504cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, MODULE) 3514cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, MACRO) 3524cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, MACRO_FILE) 3534cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, STRINGS) 3544cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, GLOBAL_DECL_ATTACHMENT) 3554cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, GLOBAL_VAR_EXPR) 3564cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, INDEX_OFFSET) 3574cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, INDEX) 3584cdb68ebSFrancis Visoiu Mistrih } 3594cdb68ebSFrancis Visoiu Mistrih case bitc::METADATA_KIND_BLOCK_ID: 3604cdb68ebSFrancis Visoiu Mistrih switch (CodeID) { 3614cdb68ebSFrancis Visoiu Mistrih default: 3624cdb68ebSFrancis Visoiu Mistrih return None; 3634cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, KIND) 3644cdb68ebSFrancis Visoiu Mistrih } 3654cdb68ebSFrancis Visoiu Mistrih case bitc::USELIST_BLOCK_ID: 3664cdb68ebSFrancis Visoiu Mistrih switch (CodeID) { 3674cdb68ebSFrancis Visoiu Mistrih default: 3684cdb68ebSFrancis Visoiu Mistrih return None; 3694cdb68ebSFrancis Visoiu Mistrih case bitc::USELIST_CODE_DEFAULT: 3704cdb68ebSFrancis Visoiu Mistrih return "USELIST_CODE_DEFAULT"; 3714cdb68ebSFrancis Visoiu Mistrih case bitc::USELIST_CODE_BB: 3724cdb68ebSFrancis Visoiu Mistrih return "USELIST_CODE_BB"; 3734cdb68ebSFrancis Visoiu Mistrih } 3744cdb68ebSFrancis Visoiu Mistrih 3754cdb68ebSFrancis Visoiu Mistrih case bitc::OPERAND_BUNDLE_TAGS_BLOCK_ID: 3764cdb68ebSFrancis Visoiu Mistrih switch (CodeID) { 3774cdb68ebSFrancis Visoiu Mistrih default: 3784cdb68ebSFrancis Visoiu Mistrih return None; 3794cdb68ebSFrancis Visoiu Mistrih case bitc::OPERAND_BUNDLE_TAG: 3804cdb68ebSFrancis Visoiu Mistrih return "OPERAND_BUNDLE_TAG"; 3814cdb68ebSFrancis Visoiu Mistrih } 3824cdb68ebSFrancis Visoiu Mistrih case bitc::STRTAB_BLOCK_ID: 3834cdb68ebSFrancis Visoiu Mistrih switch (CodeID) { 3844cdb68ebSFrancis Visoiu Mistrih default: 3854cdb68ebSFrancis Visoiu Mistrih return None; 3864cdb68ebSFrancis Visoiu Mistrih case bitc::STRTAB_BLOB: 3874cdb68ebSFrancis Visoiu Mistrih return "BLOB"; 3884cdb68ebSFrancis Visoiu Mistrih } 3894cdb68ebSFrancis Visoiu Mistrih case bitc::SYMTAB_BLOCK_ID: 3904cdb68ebSFrancis Visoiu Mistrih switch (CodeID) { 3914cdb68ebSFrancis Visoiu Mistrih default: 3924cdb68ebSFrancis Visoiu Mistrih return None; 3934cdb68ebSFrancis Visoiu Mistrih case bitc::SYMTAB_BLOB: 3944cdb68ebSFrancis Visoiu Mistrih return "BLOB"; 3954cdb68ebSFrancis Visoiu Mistrih } 3964cdb68ebSFrancis Visoiu Mistrih } 3974cdb68ebSFrancis Visoiu Mistrih #undef STRINGIFY_CODE 3984cdb68ebSFrancis Visoiu Mistrih } 3994cdb68ebSFrancis Visoiu Mistrih 4004cdb68ebSFrancis Visoiu Mistrih static void printSize(raw_ostream &OS, double Bits) { 4014cdb68ebSFrancis Visoiu Mistrih OS << format("%.2f/%.2fB/%luW", Bits, Bits / 8, (unsigned long)(Bits / 32)); 4024cdb68ebSFrancis Visoiu Mistrih } 4034cdb68ebSFrancis Visoiu Mistrih static void printSize(raw_ostream &OS, uint64_t Bits) { 4044cdb68ebSFrancis Visoiu Mistrih OS << format("%lub/%.2fB/%luW", (unsigned long)Bits, (double)Bits / 8, 4054cdb68ebSFrancis Visoiu Mistrih (unsigned long)(Bits / 32)); 4064cdb68ebSFrancis Visoiu Mistrih } 4074cdb68ebSFrancis Visoiu Mistrih 4084cdb68ebSFrancis Visoiu Mistrih static Expected<CurStreamTypeType> ReadSignature(BitstreamCursor &Stream) { 4094cdb68ebSFrancis Visoiu Mistrih auto tryRead = [&Stream](char &Dest, size_t size) -> Error { 4104cdb68ebSFrancis Visoiu Mistrih if (Expected<SimpleBitstreamCursor::word_t> MaybeWord = Stream.Read(size)) 4114cdb68ebSFrancis Visoiu Mistrih Dest = MaybeWord.get(); 4124cdb68ebSFrancis Visoiu Mistrih else 4134cdb68ebSFrancis Visoiu Mistrih return MaybeWord.takeError(); 4144cdb68ebSFrancis Visoiu Mistrih return Error::success(); 4154cdb68ebSFrancis Visoiu Mistrih }; 4164cdb68ebSFrancis Visoiu Mistrih 4174cdb68ebSFrancis Visoiu Mistrih char Signature[6]; 4184cdb68ebSFrancis Visoiu Mistrih if (Error Err = tryRead(Signature[0], 8)) 419c55cf4afSBill Wendling return std::move(Err); 4204cdb68ebSFrancis Visoiu Mistrih if (Error Err = tryRead(Signature[1], 8)) 421c55cf4afSBill Wendling return std::move(Err); 4224cdb68ebSFrancis Visoiu Mistrih 4234cdb68ebSFrancis Visoiu Mistrih // Autodetect the file contents, if it is one we know. 4244cdb68ebSFrancis Visoiu Mistrih if (Signature[0] == 'C' && Signature[1] == 'P') { 4254cdb68ebSFrancis Visoiu Mistrih if (Error Err = tryRead(Signature[2], 8)) 426c55cf4afSBill Wendling return std::move(Err); 4274cdb68ebSFrancis Visoiu Mistrih if (Error Err = tryRead(Signature[3], 8)) 428c55cf4afSBill Wendling return std::move(Err); 4294cdb68ebSFrancis Visoiu Mistrih if (Signature[2] == 'C' && Signature[3] == 'H') 4304cdb68ebSFrancis Visoiu Mistrih return ClangSerializedASTBitstream; 4314cdb68ebSFrancis Visoiu Mistrih } else if (Signature[0] == 'D' && Signature[1] == 'I') { 4324cdb68ebSFrancis Visoiu Mistrih if (Error Err = tryRead(Signature[2], 8)) 433c55cf4afSBill Wendling return std::move(Err); 4344cdb68ebSFrancis Visoiu Mistrih if (Error Err = tryRead(Signature[3], 8)) 435c55cf4afSBill Wendling return std::move(Err); 4364cdb68ebSFrancis Visoiu Mistrih if (Signature[2] == 'A' && Signature[3] == 'G') 4374cdb68ebSFrancis Visoiu Mistrih return ClangSerializedDiagnosticsBitstream; 43884e80979SFrancis Visoiu Mistrih } else if (Signature[0] == 'R' && Signature[1] == 'M') { 43984e80979SFrancis Visoiu Mistrih if (Error Err = tryRead(Signature[2], 8)) 440c55cf4afSBill Wendling return std::move(Err); 44184e80979SFrancis Visoiu Mistrih if (Error Err = tryRead(Signature[3], 8)) 442c55cf4afSBill Wendling return std::move(Err); 44384e80979SFrancis Visoiu Mistrih if (Signature[2] == 'R' && Signature[3] == 'K') 44484e80979SFrancis Visoiu Mistrih return LLVMBitstreamRemarks; 4454cdb68ebSFrancis Visoiu Mistrih } else { 4464cdb68ebSFrancis Visoiu Mistrih if (Error Err = tryRead(Signature[2], 4)) 447c55cf4afSBill Wendling return std::move(Err); 4484cdb68ebSFrancis Visoiu Mistrih if (Error Err = tryRead(Signature[3], 4)) 449c55cf4afSBill Wendling return std::move(Err); 4504cdb68ebSFrancis Visoiu Mistrih if (Error Err = tryRead(Signature[4], 4)) 451c55cf4afSBill Wendling return std::move(Err); 4524cdb68ebSFrancis Visoiu Mistrih if (Error Err = tryRead(Signature[5], 4)) 453c55cf4afSBill Wendling return std::move(Err); 4544cdb68ebSFrancis Visoiu Mistrih if (Signature[0] == 'B' && Signature[1] == 'C' && Signature[2] == 0x0 && 4554cdb68ebSFrancis Visoiu Mistrih Signature[3] == 0xC && Signature[4] == 0xE && Signature[5] == 0xD) 4564cdb68ebSFrancis Visoiu Mistrih return LLVMIRBitstream; 4574cdb68ebSFrancis Visoiu Mistrih } 4584cdb68ebSFrancis Visoiu Mistrih return UnknownBitstream; 4594cdb68ebSFrancis Visoiu Mistrih } 4604cdb68ebSFrancis Visoiu Mistrih 4614cdb68ebSFrancis Visoiu Mistrih static Expected<CurStreamTypeType> analyzeHeader(Optional<BCDumpOptions> O, 4624cdb68ebSFrancis Visoiu Mistrih BitstreamCursor &Stream) { 4634cdb68ebSFrancis Visoiu Mistrih ArrayRef<uint8_t> Bytes = Stream.getBitcodeBytes(); 4644cdb68ebSFrancis Visoiu Mistrih const unsigned char *BufPtr = (const unsigned char *)Bytes.data(); 4654cdb68ebSFrancis Visoiu Mistrih const unsigned char *EndBufPtr = BufPtr + Bytes.size(); 4664cdb68ebSFrancis Visoiu Mistrih 4674cdb68ebSFrancis Visoiu Mistrih // If we have a wrapper header, parse it and ignore the non-bc file 4684cdb68ebSFrancis Visoiu Mistrih // contents. The magic number is 0x0B17C0DE stored in little endian. 4694cdb68ebSFrancis Visoiu Mistrih if (isBitcodeWrapper(BufPtr, EndBufPtr)) { 4704cdb68ebSFrancis Visoiu Mistrih if (Bytes.size() < BWH_HeaderSize) 4714cdb68ebSFrancis Visoiu Mistrih return reportError("Invalid bitcode wrapper header"); 4724cdb68ebSFrancis Visoiu Mistrih 4734cdb68ebSFrancis Visoiu Mistrih if (O) { 4744cdb68ebSFrancis Visoiu Mistrih unsigned Magic = support::endian::read32le(&BufPtr[BWH_MagicField]); 4754cdb68ebSFrancis Visoiu Mistrih unsigned Version = support::endian::read32le(&BufPtr[BWH_VersionField]); 4764cdb68ebSFrancis Visoiu Mistrih unsigned Offset = support::endian::read32le(&BufPtr[BWH_OffsetField]); 4774cdb68ebSFrancis Visoiu Mistrih unsigned Size = support::endian::read32le(&BufPtr[BWH_SizeField]); 4784cdb68ebSFrancis Visoiu Mistrih unsigned CPUType = support::endian::read32le(&BufPtr[BWH_CPUTypeField]); 4794cdb68ebSFrancis Visoiu Mistrih 4804cdb68ebSFrancis Visoiu Mistrih O->OS << "<BITCODE_WRAPPER_HEADER" 4814cdb68ebSFrancis Visoiu Mistrih << " Magic=" << format_hex(Magic, 10) 4824cdb68ebSFrancis Visoiu Mistrih << " Version=" << format_hex(Version, 10) 4834cdb68ebSFrancis Visoiu Mistrih << " Offset=" << format_hex(Offset, 10) 4844cdb68ebSFrancis Visoiu Mistrih << " Size=" << format_hex(Size, 10) 4854cdb68ebSFrancis Visoiu Mistrih << " CPUType=" << format_hex(CPUType, 10) << "/>\n"; 4864cdb68ebSFrancis Visoiu Mistrih } 4874cdb68ebSFrancis Visoiu Mistrih 4884cdb68ebSFrancis Visoiu Mistrih if (SkipBitcodeWrapperHeader(BufPtr, EndBufPtr, true)) 4894cdb68ebSFrancis Visoiu Mistrih return reportError("Invalid bitcode wrapper header"); 4904cdb68ebSFrancis Visoiu Mistrih } 4914cdb68ebSFrancis Visoiu Mistrih 4924cdb68ebSFrancis Visoiu Mistrih // Use the cursor modified by skipping the wrapper header. 4934cdb68ebSFrancis Visoiu Mistrih Stream = BitstreamCursor(ArrayRef<uint8_t>(BufPtr, EndBufPtr)); 4944cdb68ebSFrancis Visoiu Mistrih 4954cdb68ebSFrancis Visoiu Mistrih return ReadSignature(Stream); 4964cdb68ebSFrancis Visoiu Mistrih } 4974cdb68ebSFrancis Visoiu Mistrih 4984cdb68ebSFrancis Visoiu Mistrih static bool canDecodeBlob(unsigned Code, unsigned BlockID) { 4994cdb68ebSFrancis Visoiu Mistrih return BlockID == bitc::METADATA_BLOCK_ID && Code == bitc::METADATA_STRINGS; 5004cdb68ebSFrancis Visoiu Mistrih } 5014cdb68ebSFrancis Visoiu Mistrih 5024cdb68ebSFrancis Visoiu Mistrih Error BitcodeAnalyzer::decodeMetadataStringsBlob(StringRef Indent, 5034cdb68ebSFrancis Visoiu Mistrih ArrayRef<uint64_t> Record, 5044cdb68ebSFrancis Visoiu Mistrih StringRef Blob, 5054cdb68ebSFrancis Visoiu Mistrih raw_ostream &OS) { 5064cdb68ebSFrancis Visoiu Mistrih if (Blob.empty()) 5074cdb68ebSFrancis Visoiu Mistrih return reportError("Cannot decode empty blob."); 5084cdb68ebSFrancis Visoiu Mistrih 5094cdb68ebSFrancis Visoiu Mistrih if (Record.size() != 2) 5104cdb68ebSFrancis Visoiu Mistrih return reportError( 5114cdb68ebSFrancis Visoiu Mistrih "Decoding metadata strings blob needs two record entries."); 5124cdb68ebSFrancis Visoiu Mistrih 5134cdb68ebSFrancis Visoiu Mistrih unsigned NumStrings = Record[0]; 5144cdb68ebSFrancis Visoiu Mistrih unsigned StringsOffset = Record[1]; 5154cdb68ebSFrancis Visoiu Mistrih OS << " num-strings = " << NumStrings << " {\n"; 5164cdb68ebSFrancis Visoiu Mistrih 5174cdb68ebSFrancis Visoiu Mistrih StringRef Lengths = Blob.slice(0, StringsOffset); 5184cdb68ebSFrancis Visoiu Mistrih SimpleBitstreamCursor R(Lengths); 5194cdb68ebSFrancis Visoiu Mistrih StringRef Strings = Blob.drop_front(StringsOffset); 5204cdb68ebSFrancis Visoiu Mistrih do { 5214cdb68ebSFrancis Visoiu Mistrih if (R.AtEndOfStream()) 5224cdb68ebSFrancis Visoiu Mistrih return reportError("bad length"); 5234cdb68ebSFrancis Visoiu Mistrih 5244cdb68ebSFrancis Visoiu Mistrih Expected<uint32_t> MaybeSize = R.ReadVBR(6); 5254cdb68ebSFrancis Visoiu Mistrih if (!MaybeSize) 5264cdb68ebSFrancis Visoiu Mistrih return MaybeSize.takeError(); 5274cdb68ebSFrancis Visoiu Mistrih uint32_t Size = MaybeSize.get(); 5284cdb68ebSFrancis Visoiu Mistrih if (Strings.size() < Size) 5294cdb68ebSFrancis Visoiu Mistrih return reportError("truncated chars"); 5304cdb68ebSFrancis Visoiu Mistrih 5314cdb68ebSFrancis Visoiu Mistrih OS << Indent << " '"; 5324cdb68ebSFrancis Visoiu Mistrih OS.write_escaped(Strings.slice(0, Size), /*hex=*/true); 5334cdb68ebSFrancis Visoiu Mistrih OS << "'\n"; 5344cdb68ebSFrancis Visoiu Mistrih Strings = Strings.drop_front(Size); 5354cdb68ebSFrancis Visoiu Mistrih } while (--NumStrings); 5364cdb68ebSFrancis Visoiu Mistrih 5374cdb68ebSFrancis Visoiu Mistrih OS << Indent << " }"; 5384cdb68ebSFrancis Visoiu Mistrih return Error::success(); 5394cdb68ebSFrancis Visoiu Mistrih } 5404cdb68ebSFrancis Visoiu Mistrih 5414cdb68ebSFrancis Visoiu Mistrih BitcodeAnalyzer::BitcodeAnalyzer(StringRef Buffer, 5424cdb68ebSFrancis Visoiu Mistrih Optional<StringRef> BlockInfoBuffer) 5434cdb68ebSFrancis Visoiu Mistrih : Stream(Buffer) { 5444cdb68ebSFrancis Visoiu Mistrih if (BlockInfoBuffer) 5454cdb68ebSFrancis Visoiu Mistrih BlockInfoStream.emplace(*BlockInfoBuffer); 5464cdb68ebSFrancis Visoiu Mistrih } 5474cdb68ebSFrancis Visoiu Mistrih 5484cdb68ebSFrancis Visoiu Mistrih Error BitcodeAnalyzer::analyze(Optional<BCDumpOptions> O, 5494cdb68ebSFrancis Visoiu Mistrih Optional<StringRef> CheckHash) { 5503eab4819SDenis Bakhvalov Expected<CurStreamTypeType> MaybeType = analyzeHeader(O, Stream); 5513eab4819SDenis Bakhvalov if (!MaybeType) 5523eab4819SDenis Bakhvalov return MaybeType.takeError(); 5533eab4819SDenis Bakhvalov else 5543eab4819SDenis Bakhvalov CurStreamType = *MaybeType; 5554cdb68ebSFrancis Visoiu Mistrih 5564cdb68ebSFrancis Visoiu Mistrih Stream.setBlockInfo(&BlockInfo); 5574cdb68ebSFrancis Visoiu Mistrih 5584cdb68ebSFrancis Visoiu Mistrih // Read block info from BlockInfoStream, if specified. 5594cdb68ebSFrancis Visoiu Mistrih // The block info must be a top-level block. 5604cdb68ebSFrancis Visoiu Mistrih if (BlockInfoStream) { 5614cdb68ebSFrancis Visoiu Mistrih BitstreamCursor BlockInfoCursor(*BlockInfoStream); 5624cdb68ebSFrancis Visoiu Mistrih Expected<CurStreamTypeType> H = analyzeHeader(O, BlockInfoCursor); 5634cdb68ebSFrancis Visoiu Mistrih if (!H) 5644cdb68ebSFrancis Visoiu Mistrih return H.takeError(); 5654cdb68ebSFrancis Visoiu Mistrih 5664cdb68ebSFrancis Visoiu Mistrih while (!BlockInfoCursor.AtEndOfStream()) { 5674cdb68ebSFrancis Visoiu Mistrih Expected<unsigned> MaybeCode = BlockInfoCursor.ReadCode(); 5684cdb68ebSFrancis Visoiu Mistrih if (!MaybeCode) 5694cdb68ebSFrancis Visoiu Mistrih return MaybeCode.takeError(); 5704cdb68ebSFrancis Visoiu Mistrih if (MaybeCode.get() != bitc::ENTER_SUBBLOCK) 5714cdb68ebSFrancis Visoiu Mistrih return reportError("Invalid record at top-level in block info file"); 5724cdb68ebSFrancis Visoiu Mistrih 5734cdb68ebSFrancis Visoiu Mistrih Expected<unsigned> MaybeBlockID = BlockInfoCursor.ReadSubBlockID(); 5744cdb68ebSFrancis Visoiu Mistrih if (!MaybeBlockID) 5754cdb68ebSFrancis Visoiu Mistrih return MaybeBlockID.takeError(); 5764cdb68ebSFrancis Visoiu Mistrih if (MaybeBlockID.get() == bitc::BLOCKINFO_BLOCK_ID) { 5774cdb68ebSFrancis Visoiu Mistrih Expected<Optional<BitstreamBlockInfo>> MaybeNewBlockInfo = 5784cdb68ebSFrancis Visoiu Mistrih BlockInfoCursor.ReadBlockInfoBlock(/*ReadBlockInfoNames=*/true); 5794cdb68ebSFrancis Visoiu Mistrih if (!MaybeNewBlockInfo) 5804cdb68ebSFrancis Visoiu Mistrih return MaybeNewBlockInfo.takeError(); 5814cdb68ebSFrancis Visoiu Mistrih Optional<BitstreamBlockInfo> NewBlockInfo = 5824cdb68ebSFrancis Visoiu Mistrih std::move(MaybeNewBlockInfo.get()); 5834cdb68ebSFrancis Visoiu Mistrih if (!NewBlockInfo) 5844cdb68ebSFrancis Visoiu Mistrih return reportError("Malformed BlockInfoBlock in block info file"); 5854cdb68ebSFrancis Visoiu Mistrih BlockInfo = std::move(*NewBlockInfo); 5864cdb68ebSFrancis Visoiu Mistrih break; 5874cdb68ebSFrancis Visoiu Mistrih } 5884cdb68ebSFrancis Visoiu Mistrih 5894cdb68ebSFrancis Visoiu Mistrih if (Error Err = BlockInfoCursor.SkipBlock()) 5904cdb68ebSFrancis Visoiu Mistrih return Err; 5914cdb68ebSFrancis Visoiu Mistrih } 5924cdb68ebSFrancis Visoiu Mistrih } 5934cdb68ebSFrancis Visoiu Mistrih 5944cdb68ebSFrancis Visoiu Mistrih // Parse the top-level structure. We only allow blocks at the top-level. 5954cdb68ebSFrancis Visoiu Mistrih while (!Stream.AtEndOfStream()) { 5964cdb68ebSFrancis Visoiu Mistrih Expected<unsigned> MaybeCode = Stream.ReadCode(); 5974cdb68ebSFrancis Visoiu Mistrih if (!MaybeCode) 5984cdb68ebSFrancis Visoiu Mistrih return MaybeCode.takeError(); 5994cdb68ebSFrancis Visoiu Mistrih if (MaybeCode.get() != bitc::ENTER_SUBBLOCK) 6004cdb68ebSFrancis Visoiu Mistrih return reportError("Invalid record at top-level"); 6014cdb68ebSFrancis Visoiu Mistrih 6024cdb68ebSFrancis Visoiu Mistrih Expected<unsigned> MaybeBlockID = Stream.ReadSubBlockID(); 6034cdb68ebSFrancis Visoiu Mistrih if (!MaybeBlockID) 6044cdb68ebSFrancis Visoiu Mistrih return MaybeBlockID.takeError(); 6054cdb68ebSFrancis Visoiu Mistrih 6064cdb68ebSFrancis Visoiu Mistrih if (Error E = parseBlock(MaybeBlockID.get(), 0, O, CheckHash)) 6074cdb68ebSFrancis Visoiu Mistrih return E; 6084cdb68ebSFrancis Visoiu Mistrih ++NumTopBlocks; 6094cdb68ebSFrancis Visoiu Mistrih } 6104cdb68ebSFrancis Visoiu Mistrih 6114cdb68ebSFrancis Visoiu Mistrih return Error::success(); 6124cdb68ebSFrancis Visoiu Mistrih } 6134cdb68ebSFrancis Visoiu Mistrih 6144cdb68ebSFrancis Visoiu Mistrih void BitcodeAnalyzer::printStats(BCDumpOptions O, 6154cdb68ebSFrancis Visoiu Mistrih Optional<StringRef> Filename) { 6164cdb68ebSFrancis Visoiu Mistrih uint64_t BufferSizeBits = Stream.getBitcodeBytes().size() * CHAR_BIT; 6174cdb68ebSFrancis Visoiu Mistrih // Print a summary of the read file. 6184cdb68ebSFrancis Visoiu Mistrih O.OS << "Summary "; 6194cdb68ebSFrancis Visoiu Mistrih if (Filename) 6204cdb68ebSFrancis Visoiu Mistrih O.OS << "of " << Filename->data() << ":\n"; 6214cdb68ebSFrancis Visoiu Mistrih O.OS << " Total size: "; 6224cdb68ebSFrancis Visoiu Mistrih printSize(O.OS, BufferSizeBits); 6234cdb68ebSFrancis Visoiu Mistrih O.OS << "\n"; 6244cdb68ebSFrancis Visoiu Mistrih O.OS << " Stream type: "; 6254cdb68ebSFrancis Visoiu Mistrih switch (CurStreamType) { 6264cdb68ebSFrancis Visoiu Mistrih case UnknownBitstream: 6274cdb68ebSFrancis Visoiu Mistrih O.OS << "unknown\n"; 6284cdb68ebSFrancis Visoiu Mistrih break; 6294cdb68ebSFrancis Visoiu Mistrih case LLVMIRBitstream: 6304cdb68ebSFrancis Visoiu Mistrih O.OS << "LLVM IR\n"; 6314cdb68ebSFrancis Visoiu Mistrih break; 6324cdb68ebSFrancis Visoiu Mistrih case ClangSerializedASTBitstream: 6334cdb68ebSFrancis Visoiu Mistrih O.OS << "Clang Serialized AST\n"; 6344cdb68ebSFrancis Visoiu Mistrih break; 6354cdb68ebSFrancis Visoiu Mistrih case ClangSerializedDiagnosticsBitstream: 6364cdb68ebSFrancis Visoiu Mistrih O.OS << "Clang Serialized Diagnostics\n"; 6374cdb68ebSFrancis Visoiu Mistrih break; 63884e80979SFrancis Visoiu Mistrih case LLVMBitstreamRemarks: 63984e80979SFrancis Visoiu Mistrih O.OS << "LLVM Remarks\n"; 64084e80979SFrancis Visoiu Mistrih break; 6414cdb68ebSFrancis Visoiu Mistrih } 6424cdb68ebSFrancis Visoiu Mistrih O.OS << " # Toplevel Blocks: " << NumTopBlocks << "\n"; 6434cdb68ebSFrancis Visoiu Mistrih O.OS << "\n"; 6444cdb68ebSFrancis Visoiu Mistrih 6454cdb68ebSFrancis Visoiu Mistrih // Emit per-block stats. 6464cdb68ebSFrancis Visoiu Mistrih O.OS << "Per-block Summary:\n"; 6474cdb68ebSFrancis Visoiu Mistrih for (std::map<unsigned, PerBlockIDStats>::iterator I = BlockIDStats.begin(), 6484cdb68ebSFrancis Visoiu Mistrih E = BlockIDStats.end(); 6494cdb68ebSFrancis Visoiu Mistrih I != E; ++I) { 6504cdb68ebSFrancis Visoiu Mistrih O.OS << " Block ID #" << I->first; 6514cdb68ebSFrancis Visoiu Mistrih if (Optional<const char *> BlockName = 6524cdb68ebSFrancis Visoiu Mistrih GetBlockName(I->first, BlockInfo, CurStreamType)) 6534cdb68ebSFrancis Visoiu Mistrih O.OS << " (" << *BlockName << ")"; 6544cdb68ebSFrancis Visoiu Mistrih O.OS << ":\n"; 6554cdb68ebSFrancis Visoiu Mistrih 6564cdb68ebSFrancis Visoiu Mistrih const PerBlockIDStats &Stats = I->second; 6574cdb68ebSFrancis Visoiu Mistrih O.OS << " Num Instances: " << Stats.NumInstances << "\n"; 6584cdb68ebSFrancis Visoiu Mistrih O.OS << " Total Size: "; 6594cdb68ebSFrancis Visoiu Mistrih printSize(O.OS, Stats.NumBits); 6604cdb68ebSFrancis Visoiu Mistrih O.OS << "\n"; 6614cdb68ebSFrancis Visoiu Mistrih double pct = (Stats.NumBits * 100.0) / BufferSizeBits; 6624cdb68ebSFrancis Visoiu Mistrih O.OS << " Percent of file: " << format("%2.4f%%", pct) << "\n"; 6634cdb68ebSFrancis Visoiu Mistrih if (Stats.NumInstances > 1) { 6644cdb68ebSFrancis Visoiu Mistrih O.OS << " Average Size: "; 6654cdb68ebSFrancis Visoiu Mistrih printSize(O.OS, Stats.NumBits / (double)Stats.NumInstances); 6664cdb68ebSFrancis Visoiu Mistrih O.OS << "\n"; 6674cdb68ebSFrancis Visoiu Mistrih O.OS << " Tot/Avg SubBlocks: " << Stats.NumSubBlocks << "/" 6684cdb68ebSFrancis Visoiu Mistrih << Stats.NumSubBlocks / (double)Stats.NumInstances << "\n"; 6694cdb68ebSFrancis Visoiu Mistrih O.OS << " Tot/Avg Abbrevs: " << Stats.NumAbbrevs << "/" 6704cdb68ebSFrancis Visoiu Mistrih << Stats.NumAbbrevs / (double)Stats.NumInstances << "\n"; 6714cdb68ebSFrancis Visoiu Mistrih O.OS << " Tot/Avg Records: " << Stats.NumRecords << "/" 6724cdb68ebSFrancis Visoiu Mistrih << Stats.NumRecords / (double)Stats.NumInstances << "\n"; 6734cdb68ebSFrancis Visoiu Mistrih } else { 6744cdb68ebSFrancis Visoiu Mistrih O.OS << " Num SubBlocks: " << Stats.NumSubBlocks << "\n"; 6754cdb68ebSFrancis Visoiu Mistrih O.OS << " Num Abbrevs: " << Stats.NumAbbrevs << "\n"; 6764cdb68ebSFrancis Visoiu Mistrih O.OS << " Num Records: " << Stats.NumRecords << "\n"; 6774cdb68ebSFrancis Visoiu Mistrih } 6784cdb68ebSFrancis Visoiu Mistrih if (Stats.NumRecords) { 6794cdb68ebSFrancis Visoiu Mistrih double pct = (Stats.NumAbbreviatedRecords * 100.0) / Stats.NumRecords; 6804cdb68ebSFrancis Visoiu Mistrih O.OS << " Percent Abbrevs: " << format("%2.4f%%", pct) << "\n"; 6814cdb68ebSFrancis Visoiu Mistrih } 6824cdb68ebSFrancis Visoiu Mistrih O.OS << "\n"; 6834cdb68ebSFrancis Visoiu Mistrih 6844cdb68ebSFrancis Visoiu Mistrih // Print a histogram of the codes we see. 6854cdb68ebSFrancis Visoiu Mistrih if (O.Histogram && !Stats.CodeFreq.empty()) { 6864cdb68ebSFrancis Visoiu Mistrih std::vector<std::pair<unsigned, unsigned>> FreqPairs; // <freq,code> 6874cdb68ebSFrancis Visoiu Mistrih for (unsigned i = 0, e = Stats.CodeFreq.size(); i != e; ++i) 6884cdb68ebSFrancis Visoiu Mistrih if (unsigned Freq = Stats.CodeFreq[i].NumInstances) 6894cdb68ebSFrancis Visoiu Mistrih FreqPairs.push_back(std::make_pair(Freq, i)); 6904cdb68ebSFrancis Visoiu Mistrih llvm::stable_sort(FreqPairs); 6914cdb68ebSFrancis Visoiu Mistrih std::reverse(FreqPairs.begin(), FreqPairs.end()); 6924cdb68ebSFrancis Visoiu Mistrih 6934cdb68ebSFrancis Visoiu Mistrih O.OS << "\tRecord Histogram:\n"; 6944cdb68ebSFrancis Visoiu Mistrih O.OS << "\t\t Count # Bits b/Rec % Abv Record Kind\n"; 6954cdb68ebSFrancis Visoiu Mistrih for (unsigned i = 0, e = FreqPairs.size(); i != e; ++i) { 6964cdb68ebSFrancis Visoiu Mistrih const PerRecordStats &RecStats = Stats.CodeFreq[FreqPairs[i].second]; 6974cdb68ebSFrancis Visoiu Mistrih 6984cdb68ebSFrancis Visoiu Mistrih O.OS << format("\t\t%7d %9lu", RecStats.NumInstances, 6994cdb68ebSFrancis Visoiu Mistrih (unsigned long)RecStats.TotalBits); 7004cdb68ebSFrancis Visoiu Mistrih 7014cdb68ebSFrancis Visoiu Mistrih if (RecStats.NumInstances > 1) 7024cdb68ebSFrancis Visoiu Mistrih O.OS << format(" %9.1f", 7034cdb68ebSFrancis Visoiu Mistrih (double)RecStats.TotalBits / RecStats.NumInstances); 7044cdb68ebSFrancis Visoiu Mistrih else 7054cdb68ebSFrancis Visoiu Mistrih O.OS << " "; 7064cdb68ebSFrancis Visoiu Mistrih 7074cdb68ebSFrancis Visoiu Mistrih if (RecStats.NumAbbrev) 7084cdb68ebSFrancis Visoiu Mistrih O.OS << format(" %7.2f", (double)RecStats.NumAbbrev / 7094cdb68ebSFrancis Visoiu Mistrih RecStats.NumInstances * 100); 7104cdb68ebSFrancis Visoiu Mistrih else 7114cdb68ebSFrancis Visoiu Mistrih O.OS << " "; 7124cdb68ebSFrancis Visoiu Mistrih 7134cdb68ebSFrancis Visoiu Mistrih O.OS << " "; 7144cdb68ebSFrancis Visoiu Mistrih if (Optional<const char *> CodeName = GetCodeName( 7154cdb68ebSFrancis Visoiu Mistrih FreqPairs[i].second, I->first, BlockInfo, CurStreamType)) 7164cdb68ebSFrancis Visoiu Mistrih O.OS << *CodeName << "\n"; 7174cdb68ebSFrancis Visoiu Mistrih else 7184cdb68ebSFrancis Visoiu Mistrih O.OS << "UnknownCode" << FreqPairs[i].second << "\n"; 7194cdb68ebSFrancis Visoiu Mistrih } 7204cdb68ebSFrancis Visoiu Mistrih O.OS << "\n"; 7214cdb68ebSFrancis Visoiu Mistrih } 7224cdb68ebSFrancis Visoiu Mistrih } 7234cdb68ebSFrancis Visoiu Mistrih } 7244cdb68ebSFrancis Visoiu Mistrih 7254cdb68ebSFrancis Visoiu Mistrih Error BitcodeAnalyzer::parseBlock(unsigned BlockID, unsigned IndentLevel, 7264cdb68ebSFrancis Visoiu Mistrih Optional<BCDumpOptions> O, 7274cdb68ebSFrancis Visoiu Mistrih Optional<StringRef> CheckHash) { 7284cdb68ebSFrancis Visoiu Mistrih std::string Indent(IndentLevel * 2, ' '); 7294cdb68ebSFrancis Visoiu Mistrih uint64_t BlockBitStart = Stream.GetCurrentBitNo(); 7304cdb68ebSFrancis Visoiu Mistrih 7314cdb68ebSFrancis Visoiu Mistrih // Get the statistics for this BlockID. 7324cdb68ebSFrancis Visoiu Mistrih PerBlockIDStats &BlockStats = BlockIDStats[BlockID]; 7334cdb68ebSFrancis Visoiu Mistrih 7344cdb68ebSFrancis Visoiu Mistrih BlockStats.NumInstances++; 7354cdb68ebSFrancis Visoiu Mistrih 7364cdb68ebSFrancis Visoiu Mistrih // BLOCKINFO is a special part of the stream. 7374cdb68ebSFrancis Visoiu Mistrih bool DumpRecords = O.hasValue(); 7384cdb68ebSFrancis Visoiu Mistrih if (BlockID == bitc::BLOCKINFO_BLOCK_ID) { 7394cdb68ebSFrancis Visoiu Mistrih if (O) 7404cdb68ebSFrancis Visoiu Mistrih O->OS << Indent << "<BLOCKINFO_BLOCK/>\n"; 7414cdb68ebSFrancis Visoiu Mistrih Expected<Optional<BitstreamBlockInfo>> MaybeNewBlockInfo = 7424cdb68ebSFrancis Visoiu Mistrih Stream.ReadBlockInfoBlock(/*ReadBlockInfoNames=*/true); 7434cdb68ebSFrancis Visoiu Mistrih if (!MaybeNewBlockInfo) 7444cdb68ebSFrancis Visoiu Mistrih return MaybeNewBlockInfo.takeError(); 7454cdb68ebSFrancis Visoiu Mistrih Optional<BitstreamBlockInfo> NewBlockInfo = 7464cdb68ebSFrancis Visoiu Mistrih std::move(MaybeNewBlockInfo.get()); 7474cdb68ebSFrancis Visoiu Mistrih if (!NewBlockInfo) 7484cdb68ebSFrancis Visoiu Mistrih return reportError("Malformed BlockInfoBlock"); 7494cdb68ebSFrancis Visoiu Mistrih BlockInfo = std::move(*NewBlockInfo); 7504cdb68ebSFrancis Visoiu Mistrih if (Error Err = Stream.JumpToBit(BlockBitStart)) 7514cdb68ebSFrancis Visoiu Mistrih return Err; 7524cdb68ebSFrancis Visoiu Mistrih // It's not really interesting to dump the contents of the blockinfo 7534cdb68ebSFrancis Visoiu Mistrih // block. 7544cdb68ebSFrancis Visoiu Mistrih DumpRecords = false; 7554cdb68ebSFrancis Visoiu Mistrih } 7564cdb68ebSFrancis Visoiu Mistrih 7574cdb68ebSFrancis Visoiu Mistrih unsigned NumWords = 0; 7584cdb68ebSFrancis Visoiu Mistrih if (Error Err = Stream.EnterSubBlock(BlockID, &NumWords)) 7594cdb68ebSFrancis Visoiu Mistrih return Err; 7604cdb68ebSFrancis Visoiu Mistrih 7614cdb68ebSFrancis Visoiu Mistrih // Keep it for later, when we see a MODULE_HASH record 7624cdb68ebSFrancis Visoiu Mistrih uint64_t BlockEntryPos = Stream.getCurrentByteNo(); 7634cdb68ebSFrancis Visoiu Mistrih 7644cdb68ebSFrancis Visoiu Mistrih Optional<const char *> BlockName = None; 7654cdb68ebSFrancis Visoiu Mistrih if (DumpRecords) { 7664cdb68ebSFrancis Visoiu Mistrih O->OS << Indent << "<"; 7674cdb68ebSFrancis Visoiu Mistrih if ((BlockName = GetBlockName(BlockID, BlockInfo, CurStreamType))) 7684cdb68ebSFrancis Visoiu Mistrih O->OS << *BlockName; 7694cdb68ebSFrancis Visoiu Mistrih else 7704cdb68ebSFrancis Visoiu Mistrih O->OS << "UnknownBlock" << BlockID; 7714cdb68ebSFrancis Visoiu Mistrih 7724cdb68ebSFrancis Visoiu Mistrih if (!O->Symbolic && BlockName) 7734cdb68ebSFrancis Visoiu Mistrih O->OS << " BlockID=" << BlockID; 7744cdb68ebSFrancis Visoiu Mistrih 7754cdb68ebSFrancis Visoiu Mistrih O->OS << " NumWords=" << NumWords 7764cdb68ebSFrancis Visoiu Mistrih << " BlockCodeSize=" << Stream.getAbbrevIDWidth() << ">\n"; 7774cdb68ebSFrancis Visoiu Mistrih } 7784cdb68ebSFrancis Visoiu Mistrih 7794cdb68ebSFrancis Visoiu Mistrih SmallVector<uint64_t, 64> Record; 7804cdb68ebSFrancis Visoiu Mistrih 7814cdb68ebSFrancis Visoiu Mistrih // Keep the offset to the metadata index if seen. 7824cdb68ebSFrancis Visoiu Mistrih uint64_t MetadataIndexOffset = 0; 7834cdb68ebSFrancis Visoiu Mistrih 7844cdb68ebSFrancis Visoiu Mistrih // Read all the records for this block. 7854cdb68ebSFrancis Visoiu Mistrih while (1) { 7864cdb68ebSFrancis Visoiu Mistrih if (Stream.AtEndOfStream()) 7874cdb68ebSFrancis Visoiu Mistrih return reportError("Premature end of bitstream"); 7884cdb68ebSFrancis Visoiu Mistrih 7894cdb68ebSFrancis Visoiu Mistrih uint64_t RecordStartBit = Stream.GetCurrentBitNo(); 7904cdb68ebSFrancis Visoiu Mistrih 7914cdb68ebSFrancis Visoiu Mistrih Expected<BitstreamEntry> MaybeEntry = 7924cdb68ebSFrancis Visoiu Mistrih Stream.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs); 7934cdb68ebSFrancis Visoiu Mistrih if (!MaybeEntry) 7944cdb68ebSFrancis Visoiu Mistrih return MaybeEntry.takeError(); 7954cdb68ebSFrancis Visoiu Mistrih BitstreamEntry Entry = MaybeEntry.get(); 7964cdb68ebSFrancis Visoiu Mistrih 7974cdb68ebSFrancis Visoiu Mistrih switch (Entry.Kind) { 7984cdb68ebSFrancis Visoiu Mistrih case BitstreamEntry::Error: 7994cdb68ebSFrancis Visoiu Mistrih return reportError("malformed bitcode file"); 8004cdb68ebSFrancis Visoiu Mistrih case BitstreamEntry::EndBlock: { 8014cdb68ebSFrancis Visoiu Mistrih uint64_t BlockBitEnd = Stream.GetCurrentBitNo(); 8024cdb68ebSFrancis Visoiu Mistrih BlockStats.NumBits += BlockBitEnd - BlockBitStart; 8034cdb68ebSFrancis Visoiu Mistrih if (DumpRecords) { 8044cdb68ebSFrancis Visoiu Mistrih O->OS << Indent << "</"; 8054cdb68ebSFrancis Visoiu Mistrih if (BlockName) 8064cdb68ebSFrancis Visoiu Mistrih O->OS << *BlockName << ">\n"; 8074cdb68ebSFrancis Visoiu Mistrih else 8084cdb68ebSFrancis Visoiu Mistrih O->OS << "UnknownBlock" << BlockID << ">\n"; 8094cdb68ebSFrancis Visoiu Mistrih } 8104cdb68ebSFrancis Visoiu Mistrih return Error::success(); 8114cdb68ebSFrancis Visoiu Mistrih } 8124cdb68ebSFrancis Visoiu Mistrih 8134cdb68ebSFrancis Visoiu Mistrih case BitstreamEntry::SubBlock: { 8144cdb68ebSFrancis Visoiu Mistrih uint64_t SubBlockBitStart = Stream.GetCurrentBitNo(); 8154cdb68ebSFrancis Visoiu Mistrih if (Error E = parseBlock(Entry.ID, IndentLevel + 1, O, CheckHash)) 8164cdb68ebSFrancis Visoiu Mistrih return E; 8174cdb68ebSFrancis Visoiu Mistrih ++BlockStats.NumSubBlocks; 8184cdb68ebSFrancis Visoiu Mistrih uint64_t SubBlockBitEnd = Stream.GetCurrentBitNo(); 8194cdb68ebSFrancis Visoiu Mistrih 8204cdb68ebSFrancis Visoiu Mistrih // Don't include subblock sizes in the size of this block. 8214cdb68ebSFrancis Visoiu Mistrih BlockBitStart += SubBlockBitEnd - SubBlockBitStart; 8224cdb68ebSFrancis Visoiu Mistrih continue; 8234cdb68ebSFrancis Visoiu Mistrih } 8244cdb68ebSFrancis Visoiu Mistrih case BitstreamEntry::Record: 8254cdb68ebSFrancis Visoiu Mistrih // The interesting case. 8264cdb68ebSFrancis Visoiu Mistrih break; 8274cdb68ebSFrancis Visoiu Mistrih } 8284cdb68ebSFrancis Visoiu Mistrih 8294cdb68ebSFrancis Visoiu Mistrih if (Entry.ID == bitc::DEFINE_ABBREV) { 8304cdb68ebSFrancis Visoiu Mistrih if (Error Err = Stream.ReadAbbrevRecord()) 8314cdb68ebSFrancis Visoiu Mistrih return Err; 8324cdb68ebSFrancis Visoiu Mistrih ++BlockStats.NumAbbrevs; 8334cdb68ebSFrancis Visoiu Mistrih continue; 8344cdb68ebSFrancis Visoiu Mistrih } 8354cdb68ebSFrancis Visoiu Mistrih 8364cdb68ebSFrancis Visoiu Mistrih Record.clear(); 8374cdb68ebSFrancis Visoiu Mistrih 8384cdb68ebSFrancis Visoiu Mistrih ++BlockStats.NumRecords; 8394cdb68ebSFrancis Visoiu Mistrih 8404cdb68ebSFrancis Visoiu Mistrih StringRef Blob; 8414cdb68ebSFrancis Visoiu Mistrih uint64_t CurrentRecordPos = Stream.GetCurrentBitNo(); 8424cdb68ebSFrancis Visoiu Mistrih Expected<unsigned> MaybeCode = Stream.readRecord(Entry.ID, Record, &Blob); 8434cdb68ebSFrancis Visoiu Mistrih if (!MaybeCode) 8444cdb68ebSFrancis Visoiu Mistrih return MaybeCode.takeError(); 8454cdb68ebSFrancis Visoiu Mistrih unsigned Code = MaybeCode.get(); 8464cdb68ebSFrancis Visoiu Mistrih 8474cdb68ebSFrancis Visoiu Mistrih // Increment the # occurrences of this code. 8484cdb68ebSFrancis Visoiu Mistrih if (BlockStats.CodeFreq.size() <= Code) 8494cdb68ebSFrancis Visoiu Mistrih BlockStats.CodeFreq.resize(Code + 1); 8504cdb68ebSFrancis Visoiu Mistrih BlockStats.CodeFreq[Code].NumInstances++; 8514cdb68ebSFrancis Visoiu Mistrih BlockStats.CodeFreq[Code].TotalBits += 8524cdb68ebSFrancis Visoiu Mistrih Stream.GetCurrentBitNo() - RecordStartBit; 8534cdb68ebSFrancis Visoiu Mistrih if (Entry.ID != bitc::UNABBREV_RECORD) { 8544cdb68ebSFrancis Visoiu Mistrih BlockStats.CodeFreq[Code].NumAbbrev++; 8554cdb68ebSFrancis Visoiu Mistrih ++BlockStats.NumAbbreviatedRecords; 8564cdb68ebSFrancis Visoiu Mistrih } 8574cdb68ebSFrancis Visoiu Mistrih 8584cdb68ebSFrancis Visoiu Mistrih if (DumpRecords) { 8594cdb68ebSFrancis Visoiu Mistrih O->OS << Indent << " <"; 8604cdb68ebSFrancis Visoiu Mistrih Optional<const char *> CodeName = 8614cdb68ebSFrancis Visoiu Mistrih GetCodeName(Code, BlockID, BlockInfo, CurStreamType); 8624cdb68ebSFrancis Visoiu Mistrih if (CodeName) 8634cdb68ebSFrancis Visoiu Mistrih O->OS << *CodeName; 8644cdb68ebSFrancis Visoiu Mistrih else 8654cdb68ebSFrancis Visoiu Mistrih O->OS << "UnknownCode" << Code; 8664cdb68ebSFrancis Visoiu Mistrih if (!O->Symbolic && CodeName) 8674cdb68ebSFrancis Visoiu Mistrih O->OS << " codeid=" << Code; 8684cdb68ebSFrancis Visoiu Mistrih const BitCodeAbbrev *Abbv = nullptr; 8694cdb68ebSFrancis Visoiu Mistrih if (Entry.ID != bitc::UNABBREV_RECORD) { 8704cdb68ebSFrancis Visoiu Mistrih Abbv = Stream.getAbbrev(Entry.ID); 8714cdb68ebSFrancis Visoiu Mistrih O->OS << " abbrevid=" << Entry.ID; 8724cdb68ebSFrancis Visoiu Mistrih } 8734cdb68ebSFrancis Visoiu Mistrih 8744cdb68ebSFrancis Visoiu Mistrih for (unsigned i = 0, e = Record.size(); i != e; ++i) 8754cdb68ebSFrancis Visoiu Mistrih O->OS << " op" << i << "=" << (int64_t)Record[i]; 8764cdb68ebSFrancis Visoiu Mistrih 8774cdb68ebSFrancis Visoiu Mistrih // If we found a metadata index, let's verify that we had an offset 8784cdb68ebSFrancis Visoiu Mistrih // before and validate its forward reference offset was correct! 8794cdb68ebSFrancis Visoiu Mistrih if (BlockID == bitc::METADATA_BLOCK_ID) { 8804cdb68ebSFrancis Visoiu Mistrih if (Code == bitc::METADATA_INDEX_OFFSET) { 8814cdb68ebSFrancis Visoiu Mistrih if (Record.size() != 2) 8824cdb68ebSFrancis Visoiu Mistrih O->OS << "(Invalid record)"; 8834cdb68ebSFrancis Visoiu Mistrih else { 8844cdb68ebSFrancis Visoiu Mistrih auto Offset = Record[0] + (Record[1] << 32); 8854cdb68ebSFrancis Visoiu Mistrih MetadataIndexOffset = Stream.GetCurrentBitNo() + Offset; 8864cdb68ebSFrancis Visoiu Mistrih } 8874cdb68ebSFrancis Visoiu Mistrih } 8884cdb68ebSFrancis Visoiu Mistrih if (Code == bitc::METADATA_INDEX) { 8894cdb68ebSFrancis Visoiu Mistrih O->OS << " (offset "; 8904cdb68ebSFrancis Visoiu Mistrih if (MetadataIndexOffset == RecordStartBit) 8914cdb68ebSFrancis Visoiu Mistrih O->OS << "match)"; 8924cdb68ebSFrancis Visoiu Mistrih else 8934cdb68ebSFrancis Visoiu Mistrih O->OS << "mismatch: " << MetadataIndexOffset << " vs " 8944cdb68ebSFrancis Visoiu Mistrih << RecordStartBit << ")"; 8954cdb68ebSFrancis Visoiu Mistrih } 8964cdb68ebSFrancis Visoiu Mistrih } 8974cdb68ebSFrancis Visoiu Mistrih 8984cdb68ebSFrancis Visoiu Mistrih // If we found a module hash, let's verify that it matches! 8994cdb68ebSFrancis Visoiu Mistrih if (BlockID == bitc::MODULE_BLOCK_ID && Code == bitc::MODULE_CODE_HASH && 9004cdb68ebSFrancis Visoiu Mistrih CheckHash.hasValue()) { 9014cdb68ebSFrancis Visoiu Mistrih if (Record.size() != 5) 9024cdb68ebSFrancis Visoiu Mistrih O->OS << " (invalid)"; 9034cdb68ebSFrancis Visoiu Mistrih else { 9044cdb68ebSFrancis Visoiu Mistrih // Recompute the hash and compare it to the one in the bitcode 9054cdb68ebSFrancis Visoiu Mistrih SHA1 Hasher; 9064cdb68ebSFrancis Visoiu Mistrih StringRef Hash; 9074cdb68ebSFrancis Visoiu Mistrih Hasher.update(*CheckHash); 9084cdb68ebSFrancis Visoiu Mistrih { 9094cdb68ebSFrancis Visoiu Mistrih int BlockSize = (CurrentRecordPos / 8) - BlockEntryPos; 9104cdb68ebSFrancis Visoiu Mistrih auto Ptr = Stream.getPointerToByte(BlockEntryPos, BlockSize); 9114cdb68ebSFrancis Visoiu Mistrih Hasher.update(ArrayRef<uint8_t>(Ptr, BlockSize)); 9124cdb68ebSFrancis Visoiu Mistrih Hash = Hasher.result(); 9134cdb68ebSFrancis Visoiu Mistrih } 9149a9bc236SBenjamin Kramer std::array<char, 20> RecordedHash; 9154cdb68ebSFrancis Visoiu Mistrih int Pos = 0; 9164cdb68ebSFrancis Visoiu Mistrih for (auto &Val : Record) { 9174cdb68ebSFrancis Visoiu Mistrih assert(!(Val >> 32) && "Unexpected high bits set"); 9189a9bc236SBenjamin Kramer support::endian::write32be(&RecordedHash[Pos], Val); 9199a9bc236SBenjamin Kramer Pos += 4; 9204cdb68ebSFrancis Visoiu Mistrih } 9219a9bc236SBenjamin Kramer if (Hash == StringRef(RecordedHash.data(), RecordedHash.size())) 9224cdb68ebSFrancis Visoiu Mistrih O->OS << " (match)"; 9234cdb68ebSFrancis Visoiu Mistrih else 9244cdb68ebSFrancis Visoiu Mistrih O->OS << " (!mismatch!)"; 9254cdb68ebSFrancis Visoiu Mistrih } 9264cdb68ebSFrancis Visoiu Mistrih } 9274cdb68ebSFrancis Visoiu Mistrih 9284cdb68ebSFrancis Visoiu Mistrih O->OS << "/>"; 9294cdb68ebSFrancis Visoiu Mistrih 9304cdb68ebSFrancis Visoiu Mistrih if (Abbv) { 9314cdb68ebSFrancis Visoiu Mistrih for (unsigned i = 1, e = Abbv->getNumOperandInfos(); i != e; ++i) { 9324cdb68ebSFrancis Visoiu Mistrih const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); 9334cdb68ebSFrancis Visoiu Mistrih if (!Op.isEncoding() || Op.getEncoding() != BitCodeAbbrevOp::Array) 9344cdb68ebSFrancis Visoiu Mistrih continue; 9354cdb68ebSFrancis Visoiu Mistrih assert(i + 2 == e && "Array op not second to last"); 9364cdb68ebSFrancis Visoiu Mistrih std::string Str; 9374cdb68ebSFrancis Visoiu Mistrih bool ArrayIsPrintable = true; 9384cdb68ebSFrancis Visoiu Mistrih for (unsigned j = i - 1, je = Record.size(); j != je; ++j) { 9394cdb68ebSFrancis Visoiu Mistrih if (!isPrint(static_cast<unsigned char>(Record[j]))) { 9404cdb68ebSFrancis Visoiu Mistrih ArrayIsPrintable = false; 9414cdb68ebSFrancis Visoiu Mistrih break; 9424cdb68ebSFrancis Visoiu Mistrih } 9434cdb68ebSFrancis Visoiu Mistrih Str += (char)Record[j]; 9444cdb68ebSFrancis Visoiu Mistrih } 9454cdb68ebSFrancis Visoiu Mistrih if (ArrayIsPrintable) 9464cdb68ebSFrancis Visoiu Mistrih O->OS << " record string = '" << Str << "'"; 9474cdb68ebSFrancis Visoiu Mistrih break; 9484cdb68ebSFrancis Visoiu Mistrih } 9494cdb68ebSFrancis Visoiu Mistrih } 9504cdb68ebSFrancis Visoiu Mistrih 9514cdb68ebSFrancis Visoiu Mistrih if (Blob.data()) { 9524cdb68ebSFrancis Visoiu Mistrih if (canDecodeBlob(Code, BlockID)) { 9534cdb68ebSFrancis Visoiu Mistrih if (Error E = decodeMetadataStringsBlob(Indent, Record, Blob, O->OS)) 9544cdb68ebSFrancis Visoiu Mistrih return E; 9554cdb68ebSFrancis Visoiu Mistrih } else { 9564cdb68ebSFrancis Visoiu Mistrih O->OS << " blob data = "; 9574cdb68ebSFrancis Visoiu Mistrih if (O->ShowBinaryBlobs) { 9584cdb68ebSFrancis Visoiu Mistrih O->OS << "'"; 9594cdb68ebSFrancis Visoiu Mistrih O->OS.write_escaped(Blob, /*hex=*/true) << "'"; 9604cdb68ebSFrancis Visoiu Mistrih } else { 9614cdb68ebSFrancis Visoiu Mistrih bool BlobIsPrintable = true; 9624cdb68ebSFrancis Visoiu Mistrih for (unsigned i = 0, e = Blob.size(); i != e; ++i) 9634cdb68ebSFrancis Visoiu Mistrih if (!isPrint(static_cast<unsigned char>(Blob[i]))) { 9644cdb68ebSFrancis Visoiu Mistrih BlobIsPrintable = false; 9654cdb68ebSFrancis Visoiu Mistrih break; 9664cdb68ebSFrancis Visoiu Mistrih } 9674cdb68ebSFrancis Visoiu Mistrih 9684cdb68ebSFrancis Visoiu Mistrih if (BlobIsPrintable) 9694cdb68ebSFrancis Visoiu Mistrih O->OS << "'" << Blob << "'"; 9704cdb68ebSFrancis Visoiu Mistrih else 9714cdb68ebSFrancis Visoiu Mistrih O->OS << "unprintable, " << Blob.size() << " bytes."; 9724cdb68ebSFrancis Visoiu Mistrih } 9734cdb68ebSFrancis Visoiu Mistrih } 9744cdb68ebSFrancis Visoiu Mistrih } 9754cdb68ebSFrancis Visoiu Mistrih 9764cdb68ebSFrancis Visoiu Mistrih O->OS << "\n"; 9774cdb68ebSFrancis Visoiu Mistrih } 9784cdb68ebSFrancis Visoiu Mistrih 9794cdb68ebSFrancis Visoiu Mistrih // Make sure that we can skip the current record. 9804cdb68ebSFrancis Visoiu Mistrih if (Error Err = Stream.JumpToBit(CurrentRecordPos)) 9814cdb68ebSFrancis Visoiu Mistrih return Err; 9824cdb68ebSFrancis Visoiu Mistrih if (Expected<unsigned> Skipped = Stream.skipRecord(Entry.ID)) 9834cdb68ebSFrancis Visoiu Mistrih ; // Do nothing. 9844cdb68ebSFrancis Visoiu Mistrih else 9854cdb68ebSFrancis Visoiu Mistrih return Skipped.takeError(); 9864cdb68ebSFrancis Visoiu Mistrih } 9874cdb68ebSFrancis Visoiu Mistrih } 9884cdb68ebSFrancis Visoiu Mistrih 989