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) 3084cdb68ebSFrancis Visoiu Mistrih } 3094cdb68ebSFrancis Visoiu Mistrih case bitc::METADATA_ATTACHMENT_ID: 3104cdb68ebSFrancis Visoiu Mistrih switch (CodeID) { 3114cdb68ebSFrancis Visoiu Mistrih default: 3124cdb68ebSFrancis Visoiu Mistrih return None; 3134cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, ATTACHMENT) 3144cdb68ebSFrancis Visoiu Mistrih } 3154cdb68ebSFrancis Visoiu Mistrih case bitc::METADATA_BLOCK_ID: 3164cdb68ebSFrancis Visoiu Mistrih switch (CodeID) { 3174cdb68ebSFrancis Visoiu Mistrih default: 3184cdb68ebSFrancis Visoiu Mistrih return None; 3194cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, STRING_OLD) 3204cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, VALUE) 3214cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, NODE) 3224cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, NAME) 3234cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, DISTINCT_NODE) 3244cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, KIND) // Older bitcode has it in a MODULE_BLOCK 3254cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, LOCATION) 3264cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, OLD_NODE) 3274cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, OLD_FN_NODE) 3284cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, NAMED_NODE) 3294cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, GENERIC_DEBUG) 3304cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, SUBRANGE) 3314cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, ENUMERATOR) 3324cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, BASIC_TYPE) 3334cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, FILE) 3344cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, DERIVED_TYPE) 3354cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, COMPOSITE_TYPE) 3364cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, SUBROUTINE_TYPE) 3374cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, COMPILE_UNIT) 3384cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, SUBPROGRAM) 3394cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, LEXICAL_BLOCK) 3404cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, LEXICAL_BLOCK_FILE) 3414cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, NAMESPACE) 3424cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, TEMPLATE_TYPE) 3434cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, TEMPLATE_VALUE) 3444cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, GLOBAL_VAR) 3454cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, LOCAL_VAR) 3464cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, EXPRESSION) 3474cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, OBJC_PROPERTY) 3484cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, IMPORTED_ENTITY) 3494cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, MODULE) 3504cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, MACRO) 3514cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, MACRO_FILE) 3524cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, STRINGS) 3534cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, GLOBAL_DECL_ATTACHMENT) 3544cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, GLOBAL_VAR_EXPR) 3554cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, INDEX_OFFSET) 3564cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, INDEX) 3574cdb68ebSFrancis Visoiu Mistrih } 3584cdb68ebSFrancis Visoiu Mistrih case bitc::METADATA_KIND_BLOCK_ID: 3594cdb68ebSFrancis Visoiu Mistrih switch (CodeID) { 3604cdb68ebSFrancis Visoiu Mistrih default: 3614cdb68ebSFrancis Visoiu Mistrih return None; 3624cdb68ebSFrancis Visoiu Mistrih STRINGIFY_CODE(METADATA, KIND) 3634cdb68ebSFrancis Visoiu Mistrih } 3644cdb68ebSFrancis Visoiu Mistrih case bitc::USELIST_BLOCK_ID: 3654cdb68ebSFrancis Visoiu Mistrih switch (CodeID) { 3664cdb68ebSFrancis Visoiu Mistrih default: 3674cdb68ebSFrancis Visoiu Mistrih return None; 3684cdb68ebSFrancis Visoiu Mistrih case bitc::USELIST_CODE_DEFAULT: 3694cdb68ebSFrancis Visoiu Mistrih return "USELIST_CODE_DEFAULT"; 3704cdb68ebSFrancis Visoiu Mistrih case bitc::USELIST_CODE_BB: 3714cdb68ebSFrancis Visoiu Mistrih return "USELIST_CODE_BB"; 3724cdb68ebSFrancis Visoiu Mistrih } 3734cdb68ebSFrancis Visoiu Mistrih 3744cdb68ebSFrancis Visoiu Mistrih case bitc::OPERAND_BUNDLE_TAGS_BLOCK_ID: 3754cdb68ebSFrancis Visoiu Mistrih switch (CodeID) { 3764cdb68ebSFrancis Visoiu Mistrih default: 3774cdb68ebSFrancis Visoiu Mistrih return None; 3784cdb68ebSFrancis Visoiu Mistrih case bitc::OPERAND_BUNDLE_TAG: 3794cdb68ebSFrancis Visoiu Mistrih return "OPERAND_BUNDLE_TAG"; 3804cdb68ebSFrancis Visoiu Mistrih } 3814cdb68ebSFrancis Visoiu Mistrih case bitc::STRTAB_BLOCK_ID: 3824cdb68ebSFrancis Visoiu Mistrih switch (CodeID) { 3834cdb68ebSFrancis Visoiu Mistrih default: 3844cdb68ebSFrancis Visoiu Mistrih return None; 3854cdb68ebSFrancis Visoiu Mistrih case bitc::STRTAB_BLOB: 3864cdb68ebSFrancis Visoiu Mistrih return "BLOB"; 3874cdb68ebSFrancis Visoiu Mistrih } 3884cdb68ebSFrancis Visoiu Mistrih case bitc::SYMTAB_BLOCK_ID: 3894cdb68ebSFrancis Visoiu Mistrih switch (CodeID) { 3904cdb68ebSFrancis Visoiu Mistrih default: 3914cdb68ebSFrancis Visoiu Mistrih return None; 3924cdb68ebSFrancis Visoiu Mistrih case bitc::SYMTAB_BLOB: 3934cdb68ebSFrancis Visoiu Mistrih return "BLOB"; 3944cdb68ebSFrancis Visoiu Mistrih } 3954cdb68ebSFrancis Visoiu Mistrih } 3964cdb68ebSFrancis Visoiu Mistrih #undef STRINGIFY_CODE 3974cdb68ebSFrancis Visoiu Mistrih } 3984cdb68ebSFrancis Visoiu Mistrih 3994cdb68ebSFrancis Visoiu Mistrih static void printSize(raw_ostream &OS, double Bits) { 4004cdb68ebSFrancis Visoiu Mistrih OS << format("%.2f/%.2fB/%luW", Bits, Bits / 8, (unsigned long)(Bits / 32)); 4014cdb68ebSFrancis Visoiu Mistrih } 4024cdb68ebSFrancis Visoiu Mistrih static void printSize(raw_ostream &OS, uint64_t Bits) { 4034cdb68ebSFrancis Visoiu Mistrih OS << format("%lub/%.2fB/%luW", (unsigned long)Bits, (double)Bits / 8, 4044cdb68ebSFrancis Visoiu Mistrih (unsigned long)(Bits / 32)); 4054cdb68ebSFrancis Visoiu Mistrih } 4064cdb68ebSFrancis Visoiu Mistrih 4074cdb68ebSFrancis Visoiu Mistrih static Expected<CurStreamTypeType> ReadSignature(BitstreamCursor &Stream) { 4084cdb68ebSFrancis Visoiu Mistrih auto tryRead = [&Stream](char &Dest, size_t size) -> Error { 4094cdb68ebSFrancis Visoiu Mistrih if (Expected<SimpleBitstreamCursor::word_t> MaybeWord = Stream.Read(size)) 4104cdb68ebSFrancis Visoiu Mistrih Dest = MaybeWord.get(); 4114cdb68ebSFrancis Visoiu Mistrih else 4124cdb68ebSFrancis Visoiu Mistrih return MaybeWord.takeError(); 4134cdb68ebSFrancis Visoiu Mistrih return Error::success(); 4144cdb68ebSFrancis Visoiu Mistrih }; 4154cdb68ebSFrancis Visoiu Mistrih 4164cdb68ebSFrancis Visoiu Mistrih char Signature[6]; 4174cdb68ebSFrancis Visoiu Mistrih if (Error Err = tryRead(Signature[0], 8)) 4184cdb68ebSFrancis Visoiu Mistrih return std::move(Err); 4194cdb68ebSFrancis Visoiu Mistrih if (Error Err = tryRead(Signature[1], 8)) 4204cdb68ebSFrancis Visoiu Mistrih return std::move(Err); 4214cdb68ebSFrancis Visoiu Mistrih 4224cdb68ebSFrancis Visoiu Mistrih // Autodetect the file contents, if it is one we know. 4234cdb68ebSFrancis Visoiu Mistrih if (Signature[0] == 'C' && Signature[1] == 'P') { 4244cdb68ebSFrancis Visoiu Mistrih if (Error Err = tryRead(Signature[2], 8)) 4254cdb68ebSFrancis Visoiu Mistrih return std::move(Err); 4264cdb68ebSFrancis Visoiu Mistrih if (Error Err = tryRead(Signature[3], 8)) 4274cdb68ebSFrancis Visoiu Mistrih return std::move(Err); 4284cdb68ebSFrancis Visoiu Mistrih if (Signature[2] == 'C' && Signature[3] == 'H') 4294cdb68ebSFrancis Visoiu Mistrih return ClangSerializedASTBitstream; 4304cdb68ebSFrancis Visoiu Mistrih } else if (Signature[0] == 'D' && Signature[1] == 'I') { 4314cdb68ebSFrancis Visoiu Mistrih if (Error Err = tryRead(Signature[2], 8)) 4324cdb68ebSFrancis Visoiu Mistrih return std::move(Err); 4334cdb68ebSFrancis Visoiu Mistrih if (Error Err = tryRead(Signature[3], 8)) 4344cdb68ebSFrancis Visoiu Mistrih return std::move(Err); 4354cdb68ebSFrancis Visoiu Mistrih if (Signature[2] == 'A' && Signature[3] == 'G') 4364cdb68ebSFrancis Visoiu Mistrih return ClangSerializedDiagnosticsBitstream; 437*84e80979SFrancis Visoiu Mistrih } else if (Signature[0] == 'R' && Signature[1] == 'M') { 438*84e80979SFrancis Visoiu Mistrih if (Error Err = tryRead(Signature[2], 8)) 439*84e80979SFrancis Visoiu Mistrih return std::move(Err); 440*84e80979SFrancis Visoiu Mistrih if (Error Err = tryRead(Signature[3], 8)) 441*84e80979SFrancis Visoiu Mistrih return std::move(Err); 442*84e80979SFrancis Visoiu Mistrih if (Signature[2] == 'R' && Signature[3] == 'K') 443*84e80979SFrancis Visoiu Mistrih return LLVMBitstreamRemarks; 4444cdb68ebSFrancis Visoiu Mistrih } else { 4454cdb68ebSFrancis Visoiu Mistrih if (Error Err = tryRead(Signature[2], 4)) 4464cdb68ebSFrancis Visoiu Mistrih return std::move(Err); 4474cdb68ebSFrancis Visoiu Mistrih if (Error Err = tryRead(Signature[3], 4)) 4484cdb68ebSFrancis Visoiu Mistrih return std::move(Err); 4494cdb68ebSFrancis Visoiu Mistrih if (Error Err = tryRead(Signature[4], 4)) 4504cdb68ebSFrancis Visoiu Mistrih return std::move(Err); 4514cdb68ebSFrancis Visoiu Mistrih if (Error Err = tryRead(Signature[5], 4)) 4524cdb68ebSFrancis Visoiu Mistrih return std::move(Err); 4534cdb68ebSFrancis Visoiu Mistrih if (Signature[0] == 'B' && Signature[1] == 'C' && Signature[2] == 0x0 && 4544cdb68ebSFrancis Visoiu Mistrih Signature[3] == 0xC && Signature[4] == 0xE && Signature[5] == 0xD) 4554cdb68ebSFrancis Visoiu Mistrih return LLVMIRBitstream; 4564cdb68ebSFrancis Visoiu Mistrih } 4574cdb68ebSFrancis Visoiu Mistrih return UnknownBitstream; 4584cdb68ebSFrancis Visoiu Mistrih } 4594cdb68ebSFrancis Visoiu Mistrih 4604cdb68ebSFrancis Visoiu Mistrih static Expected<CurStreamTypeType> analyzeHeader(Optional<BCDumpOptions> O, 4614cdb68ebSFrancis Visoiu Mistrih BitstreamCursor &Stream) { 4624cdb68ebSFrancis Visoiu Mistrih ArrayRef<uint8_t> Bytes = Stream.getBitcodeBytes(); 4634cdb68ebSFrancis Visoiu Mistrih const unsigned char *BufPtr = (const unsigned char *)Bytes.data(); 4644cdb68ebSFrancis Visoiu Mistrih const unsigned char *EndBufPtr = BufPtr + Bytes.size(); 4654cdb68ebSFrancis Visoiu Mistrih 4664cdb68ebSFrancis Visoiu Mistrih // If we have a wrapper header, parse it and ignore the non-bc file 4674cdb68ebSFrancis Visoiu Mistrih // contents. The magic number is 0x0B17C0DE stored in little endian. 4684cdb68ebSFrancis Visoiu Mistrih if (isBitcodeWrapper(BufPtr, EndBufPtr)) { 4694cdb68ebSFrancis Visoiu Mistrih if (Bytes.size() < BWH_HeaderSize) 4704cdb68ebSFrancis Visoiu Mistrih return reportError("Invalid bitcode wrapper header"); 4714cdb68ebSFrancis Visoiu Mistrih 4724cdb68ebSFrancis Visoiu Mistrih if (O) { 4734cdb68ebSFrancis Visoiu Mistrih unsigned Magic = support::endian::read32le(&BufPtr[BWH_MagicField]); 4744cdb68ebSFrancis Visoiu Mistrih unsigned Version = support::endian::read32le(&BufPtr[BWH_VersionField]); 4754cdb68ebSFrancis Visoiu Mistrih unsigned Offset = support::endian::read32le(&BufPtr[BWH_OffsetField]); 4764cdb68ebSFrancis Visoiu Mistrih unsigned Size = support::endian::read32le(&BufPtr[BWH_SizeField]); 4774cdb68ebSFrancis Visoiu Mistrih unsigned CPUType = support::endian::read32le(&BufPtr[BWH_CPUTypeField]); 4784cdb68ebSFrancis Visoiu Mistrih 4794cdb68ebSFrancis Visoiu Mistrih O->OS << "<BITCODE_WRAPPER_HEADER" 4804cdb68ebSFrancis Visoiu Mistrih << " Magic=" << format_hex(Magic, 10) 4814cdb68ebSFrancis Visoiu Mistrih << " Version=" << format_hex(Version, 10) 4824cdb68ebSFrancis Visoiu Mistrih << " Offset=" << format_hex(Offset, 10) 4834cdb68ebSFrancis Visoiu Mistrih << " Size=" << format_hex(Size, 10) 4844cdb68ebSFrancis Visoiu Mistrih << " CPUType=" << format_hex(CPUType, 10) << "/>\n"; 4854cdb68ebSFrancis Visoiu Mistrih } 4864cdb68ebSFrancis Visoiu Mistrih 4874cdb68ebSFrancis Visoiu Mistrih if (SkipBitcodeWrapperHeader(BufPtr, EndBufPtr, true)) 4884cdb68ebSFrancis Visoiu Mistrih return reportError("Invalid bitcode wrapper header"); 4894cdb68ebSFrancis Visoiu Mistrih } 4904cdb68ebSFrancis Visoiu Mistrih 4914cdb68ebSFrancis Visoiu Mistrih // Use the cursor modified by skipping the wrapper header. 4924cdb68ebSFrancis Visoiu Mistrih Stream = BitstreamCursor(ArrayRef<uint8_t>(BufPtr, EndBufPtr)); 4934cdb68ebSFrancis Visoiu Mistrih 4944cdb68ebSFrancis Visoiu Mistrih return ReadSignature(Stream); 4954cdb68ebSFrancis Visoiu Mistrih } 4964cdb68ebSFrancis Visoiu Mistrih 4974cdb68ebSFrancis Visoiu Mistrih static bool canDecodeBlob(unsigned Code, unsigned BlockID) { 4984cdb68ebSFrancis Visoiu Mistrih return BlockID == bitc::METADATA_BLOCK_ID && Code == bitc::METADATA_STRINGS; 4994cdb68ebSFrancis Visoiu Mistrih } 5004cdb68ebSFrancis Visoiu Mistrih 5014cdb68ebSFrancis Visoiu Mistrih Error BitcodeAnalyzer::decodeMetadataStringsBlob(StringRef Indent, 5024cdb68ebSFrancis Visoiu Mistrih ArrayRef<uint64_t> Record, 5034cdb68ebSFrancis Visoiu Mistrih StringRef Blob, 5044cdb68ebSFrancis Visoiu Mistrih raw_ostream &OS) { 5054cdb68ebSFrancis Visoiu Mistrih if (Blob.empty()) 5064cdb68ebSFrancis Visoiu Mistrih return reportError("Cannot decode empty blob."); 5074cdb68ebSFrancis Visoiu Mistrih 5084cdb68ebSFrancis Visoiu Mistrih if (Record.size() != 2) 5094cdb68ebSFrancis Visoiu Mistrih return reportError( 5104cdb68ebSFrancis Visoiu Mistrih "Decoding metadata strings blob needs two record entries."); 5114cdb68ebSFrancis Visoiu Mistrih 5124cdb68ebSFrancis Visoiu Mistrih unsigned NumStrings = Record[0]; 5134cdb68ebSFrancis Visoiu Mistrih unsigned StringsOffset = Record[1]; 5144cdb68ebSFrancis Visoiu Mistrih OS << " num-strings = " << NumStrings << " {\n"; 5154cdb68ebSFrancis Visoiu Mistrih 5164cdb68ebSFrancis Visoiu Mistrih StringRef Lengths = Blob.slice(0, StringsOffset); 5174cdb68ebSFrancis Visoiu Mistrih SimpleBitstreamCursor R(Lengths); 5184cdb68ebSFrancis Visoiu Mistrih StringRef Strings = Blob.drop_front(StringsOffset); 5194cdb68ebSFrancis Visoiu Mistrih do { 5204cdb68ebSFrancis Visoiu Mistrih if (R.AtEndOfStream()) 5214cdb68ebSFrancis Visoiu Mistrih return reportError("bad length"); 5224cdb68ebSFrancis Visoiu Mistrih 5234cdb68ebSFrancis Visoiu Mistrih Expected<uint32_t> MaybeSize = R.ReadVBR(6); 5244cdb68ebSFrancis Visoiu Mistrih if (!MaybeSize) 5254cdb68ebSFrancis Visoiu Mistrih return MaybeSize.takeError(); 5264cdb68ebSFrancis Visoiu Mistrih uint32_t Size = MaybeSize.get(); 5274cdb68ebSFrancis Visoiu Mistrih if (Strings.size() < Size) 5284cdb68ebSFrancis Visoiu Mistrih return reportError("truncated chars"); 5294cdb68ebSFrancis Visoiu Mistrih 5304cdb68ebSFrancis Visoiu Mistrih OS << Indent << " '"; 5314cdb68ebSFrancis Visoiu Mistrih OS.write_escaped(Strings.slice(0, Size), /*hex=*/true); 5324cdb68ebSFrancis Visoiu Mistrih OS << "'\n"; 5334cdb68ebSFrancis Visoiu Mistrih Strings = Strings.drop_front(Size); 5344cdb68ebSFrancis Visoiu Mistrih } while (--NumStrings); 5354cdb68ebSFrancis Visoiu Mistrih 5364cdb68ebSFrancis Visoiu Mistrih OS << Indent << " }"; 5374cdb68ebSFrancis Visoiu Mistrih return Error::success(); 5384cdb68ebSFrancis Visoiu Mistrih } 5394cdb68ebSFrancis Visoiu Mistrih 5404cdb68ebSFrancis Visoiu Mistrih BitcodeAnalyzer::BitcodeAnalyzer(StringRef Buffer, 5414cdb68ebSFrancis Visoiu Mistrih Optional<StringRef> BlockInfoBuffer) 5424cdb68ebSFrancis Visoiu Mistrih : Stream(Buffer) { 5434cdb68ebSFrancis Visoiu Mistrih if (BlockInfoBuffer) 5444cdb68ebSFrancis Visoiu Mistrih BlockInfoStream.emplace(*BlockInfoBuffer); 5454cdb68ebSFrancis Visoiu Mistrih } 5464cdb68ebSFrancis Visoiu Mistrih 5474cdb68ebSFrancis Visoiu Mistrih Error BitcodeAnalyzer::analyze(Optional<BCDumpOptions> O, 5484cdb68ebSFrancis Visoiu Mistrih Optional<StringRef> CheckHash) { 5493eab4819SDenis Bakhvalov Expected<CurStreamTypeType> MaybeType = analyzeHeader(O, Stream); 5503eab4819SDenis Bakhvalov if (!MaybeType) 5513eab4819SDenis Bakhvalov return MaybeType.takeError(); 5523eab4819SDenis Bakhvalov else 5533eab4819SDenis Bakhvalov CurStreamType = *MaybeType; 5544cdb68ebSFrancis Visoiu Mistrih 5554cdb68ebSFrancis Visoiu Mistrih Stream.setBlockInfo(&BlockInfo); 5564cdb68ebSFrancis Visoiu Mistrih 5574cdb68ebSFrancis Visoiu Mistrih // Read block info from BlockInfoStream, if specified. 5584cdb68ebSFrancis Visoiu Mistrih // The block info must be a top-level block. 5594cdb68ebSFrancis Visoiu Mistrih if (BlockInfoStream) { 5604cdb68ebSFrancis Visoiu Mistrih BitstreamCursor BlockInfoCursor(*BlockInfoStream); 5614cdb68ebSFrancis Visoiu Mistrih Expected<CurStreamTypeType> H = analyzeHeader(O, BlockInfoCursor); 5624cdb68ebSFrancis Visoiu Mistrih if (!H) 5634cdb68ebSFrancis Visoiu Mistrih return H.takeError(); 5644cdb68ebSFrancis Visoiu Mistrih 5654cdb68ebSFrancis Visoiu Mistrih while (!BlockInfoCursor.AtEndOfStream()) { 5664cdb68ebSFrancis Visoiu Mistrih Expected<unsigned> MaybeCode = BlockInfoCursor.ReadCode(); 5674cdb68ebSFrancis Visoiu Mistrih if (!MaybeCode) 5684cdb68ebSFrancis Visoiu Mistrih return MaybeCode.takeError(); 5694cdb68ebSFrancis Visoiu Mistrih if (MaybeCode.get() != bitc::ENTER_SUBBLOCK) 5704cdb68ebSFrancis Visoiu Mistrih return reportError("Invalid record at top-level in block info file"); 5714cdb68ebSFrancis Visoiu Mistrih 5724cdb68ebSFrancis Visoiu Mistrih Expected<unsigned> MaybeBlockID = BlockInfoCursor.ReadSubBlockID(); 5734cdb68ebSFrancis Visoiu Mistrih if (!MaybeBlockID) 5744cdb68ebSFrancis Visoiu Mistrih return MaybeBlockID.takeError(); 5754cdb68ebSFrancis Visoiu Mistrih if (MaybeBlockID.get() == bitc::BLOCKINFO_BLOCK_ID) { 5764cdb68ebSFrancis Visoiu Mistrih Expected<Optional<BitstreamBlockInfo>> MaybeNewBlockInfo = 5774cdb68ebSFrancis Visoiu Mistrih BlockInfoCursor.ReadBlockInfoBlock(/*ReadBlockInfoNames=*/true); 5784cdb68ebSFrancis Visoiu Mistrih if (!MaybeNewBlockInfo) 5794cdb68ebSFrancis Visoiu Mistrih return MaybeNewBlockInfo.takeError(); 5804cdb68ebSFrancis Visoiu Mistrih Optional<BitstreamBlockInfo> NewBlockInfo = 5814cdb68ebSFrancis Visoiu Mistrih std::move(MaybeNewBlockInfo.get()); 5824cdb68ebSFrancis Visoiu Mistrih if (!NewBlockInfo) 5834cdb68ebSFrancis Visoiu Mistrih return reportError("Malformed BlockInfoBlock in block info file"); 5844cdb68ebSFrancis Visoiu Mistrih BlockInfo = std::move(*NewBlockInfo); 5854cdb68ebSFrancis Visoiu Mistrih break; 5864cdb68ebSFrancis Visoiu Mistrih } 5874cdb68ebSFrancis Visoiu Mistrih 5884cdb68ebSFrancis Visoiu Mistrih if (Error Err = BlockInfoCursor.SkipBlock()) 5894cdb68ebSFrancis Visoiu Mistrih return Err; 5904cdb68ebSFrancis Visoiu Mistrih } 5914cdb68ebSFrancis Visoiu Mistrih } 5924cdb68ebSFrancis Visoiu Mistrih 5934cdb68ebSFrancis Visoiu Mistrih // Parse the top-level structure. We only allow blocks at the top-level. 5944cdb68ebSFrancis Visoiu Mistrih while (!Stream.AtEndOfStream()) { 5954cdb68ebSFrancis Visoiu Mistrih Expected<unsigned> MaybeCode = Stream.ReadCode(); 5964cdb68ebSFrancis Visoiu Mistrih if (!MaybeCode) 5974cdb68ebSFrancis Visoiu Mistrih return MaybeCode.takeError(); 5984cdb68ebSFrancis Visoiu Mistrih if (MaybeCode.get() != bitc::ENTER_SUBBLOCK) 5994cdb68ebSFrancis Visoiu Mistrih return reportError("Invalid record at top-level"); 6004cdb68ebSFrancis Visoiu Mistrih 6014cdb68ebSFrancis Visoiu Mistrih Expected<unsigned> MaybeBlockID = Stream.ReadSubBlockID(); 6024cdb68ebSFrancis Visoiu Mistrih if (!MaybeBlockID) 6034cdb68ebSFrancis Visoiu Mistrih return MaybeBlockID.takeError(); 6044cdb68ebSFrancis Visoiu Mistrih 6054cdb68ebSFrancis Visoiu Mistrih if (Error E = parseBlock(MaybeBlockID.get(), 0, O, CheckHash)) 6064cdb68ebSFrancis Visoiu Mistrih return E; 6074cdb68ebSFrancis Visoiu Mistrih ++NumTopBlocks; 6084cdb68ebSFrancis Visoiu Mistrih } 6094cdb68ebSFrancis Visoiu Mistrih 6104cdb68ebSFrancis Visoiu Mistrih return Error::success(); 6114cdb68ebSFrancis Visoiu Mistrih } 6124cdb68ebSFrancis Visoiu Mistrih 6134cdb68ebSFrancis Visoiu Mistrih void BitcodeAnalyzer::printStats(BCDumpOptions O, 6144cdb68ebSFrancis Visoiu Mistrih Optional<StringRef> Filename) { 6154cdb68ebSFrancis Visoiu Mistrih uint64_t BufferSizeBits = Stream.getBitcodeBytes().size() * CHAR_BIT; 6164cdb68ebSFrancis Visoiu Mistrih // Print a summary of the read file. 6174cdb68ebSFrancis Visoiu Mistrih O.OS << "Summary "; 6184cdb68ebSFrancis Visoiu Mistrih if (Filename) 6194cdb68ebSFrancis Visoiu Mistrih O.OS << "of " << Filename->data() << ":\n"; 6204cdb68ebSFrancis Visoiu Mistrih O.OS << " Total size: "; 6214cdb68ebSFrancis Visoiu Mistrih printSize(O.OS, BufferSizeBits); 6224cdb68ebSFrancis Visoiu Mistrih O.OS << "\n"; 6234cdb68ebSFrancis Visoiu Mistrih O.OS << " Stream type: "; 6244cdb68ebSFrancis Visoiu Mistrih switch (CurStreamType) { 6254cdb68ebSFrancis Visoiu Mistrih case UnknownBitstream: 6264cdb68ebSFrancis Visoiu Mistrih O.OS << "unknown\n"; 6274cdb68ebSFrancis Visoiu Mistrih break; 6284cdb68ebSFrancis Visoiu Mistrih case LLVMIRBitstream: 6294cdb68ebSFrancis Visoiu Mistrih O.OS << "LLVM IR\n"; 6304cdb68ebSFrancis Visoiu Mistrih break; 6314cdb68ebSFrancis Visoiu Mistrih case ClangSerializedASTBitstream: 6324cdb68ebSFrancis Visoiu Mistrih O.OS << "Clang Serialized AST\n"; 6334cdb68ebSFrancis Visoiu Mistrih break; 6344cdb68ebSFrancis Visoiu Mistrih case ClangSerializedDiagnosticsBitstream: 6354cdb68ebSFrancis Visoiu Mistrih O.OS << "Clang Serialized Diagnostics\n"; 6364cdb68ebSFrancis Visoiu Mistrih break; 637*84e80979SFrancis Visoiu Mistrih case LLVMBitstreamRemarks: 638*84e80979SFrancis Visoiu Mistrih O.OS << "LLVM Remarks\n"; 639*84e80979SFrancis Visoiu Mistrih break; 6404cdb68ebSFrancis Visoiu Mistrih } 6414cdb68ebSFrancis Visoiu Mistrih O.OS << " # Toplevel Blocks: " << NumTopBlocks << "\n"; 6424cdb68ebSFrancis Visoiu Mistrih O.OS << "\n"; 6434cdb68ebSFrancis Visoiu Mistrih 6444cdb68ebSFrancis Visoiu Mistrih // Emit per-block stats. 6454cdb68ebSFrancis Visoiu Mistrih O.OS << "Per-block Summary:\n"; 6464cdb68ebSFrancis Visoiu Mistrih for (std::map<unsigned, PerBlockIDStats>::iterator I = BlockIDStats.begin(), 6474cdb68ebSFrancis Visoiu Mistrih E = BlockIDStats.end(); 6484cdb68ebSFrancis Visoiu Mistrih I != E; ++I) { 6494cdb68ebSFrancis Visoiu Mistrih O.OS << " Block ID #" << I->first; 6504cdb68ebSFrancis Visoiu Mistrih if (Optional<const char *> BlockName = 6514cdb68ebSFrancis Visoiu Mistrih GetBlockName(I->first, BlockInfo, CurStreamType)) 6524cdb68ebSFrancis Visoiu Mistrih O.OS << " (" << *BlockName << ")"; 6534cdb68ebSFrancis Visoiu Mistrih O.OS << ":\n"; 6544cdb68ebSFrancis Visoiu Mistrih 6554cdb68ebSFrancis Visoiu Mistrih const PerBlockIDStats &Stats = I->second; 6564cdb68ebSFrancis Visoiu Mistrih O.OS << " Num Instances: " << Stats.NumInstances << "\n"; 6574cdb68ebSFrancis Visoiu Mistrih O.OS << " Total Size: "; 6584cdb68ebSFrancis Visoiu Mistrih printSize(O.OS, Stats.NumBits); 6594cdb68ebSFrancis Visoiu Mistrih O.OS << "\n"; 6604cdb68ebSFrancis Visoiu Mistrih double pct = (Stats.NumBits * 100.0) / BufferSizeBits; 6614cdb68ebSFrancis Visoiu Mistrih O.OS << " Percent of file: " << format("%2.4f%%", pct) << "\n"; 6624cdb68ebSFrancis Visoiu Mistrih if (Stats.NumInstances > 1) { 6634cdb68ebSFrancis Visoiu Mistrih O.OS << " Average Size: "; 6644cdb68ebSFrancis Visoiu Mistrih printSize(O.OS, Stats.NumBits / (double)Stats.NumInstances); 6654cdb68ebSFrancis Visoiu Mistrih O.OS << "\n"; 6664cdb68ebSFrancis Visoiu Mistrih O.OS << " Tot/Avg SubBlocks: " << Stats.NumSubBlocks << "/" 6674cdb68ebSFrancis Visoiu Mistrih << Stats.NumSubBlocks / (double)Stats.NumInstances << "\n"; 6684cdb68ebSFrancis Visoiu Mistrih O.OS << " Tot/Avg Abbrevs: " << Stats.NumAbbrevs << "/" 6694cdb68ebSFrancis Visoiu Mistrih << Stats.NumAbbrevs / (double)Stats.NumInstances << "\n"; 6704cdb68ebSFrancis Visoiu Mistrih O.OS << " Tot/Avg Records: " << Stats.NumRecords << "/" 6714cdb68ebSFrancis Visoiu Mistrih << Stats.NumRecords / (double)Stats.NumInstances << "\n"; 6724cdb68ebSFrancis Visoiu Mistrih } else { 6734cdb68ebSFrancis Visoiu Mistrih O.OS << " Num SubBlocks: " << Stats.NumSubBlocks << "\n"; 6744cdb68ebSFrancis Visoiu Mistrih O.OS << " Num Abbrevs: " << Stats.NumAbbrevs << "\n"; 6754cdb68ebSFrancis Visoiu Mistrih O.OS << " Num Records: " << Stats.NumRecords << "\n"; 6764cdb68ebSFrancis Visoiu Mistrih } 6774cdb68ebSFrancis Visoiu Mistrih if (Stats.NumRecords) { 6784cdb68ebSFrancis Visoiu Mistrih double pct = (Stats.NumAbbreviatedRecords * 100.0) / Stats.NumRecords; 6794cdb68ebSFrancis Visoiu Mistrih O.OS << " Percent Abbrevs: " << format("%2.4f%%", pct) << "\n"; 6804cdb68ebSFrancis Visoiu Mistrih } 6814cdb68ebSFrancis Visoiu Mistrih O.OS << "\n"; 6824cdb68ebSFrancis Visoiu Mistrih 6834cdb68ebSFrancis Visoiu Mistrih // Print a histogram of the codes we see. 6844cdb68ebSFrancis Visoiu Mistrih if (O.Histogram && !Stats.CodeFreq.empty()) { 6854cdb68ebSFrancis Visoiu Mistrih std::vector<std::pair<unsigned, unsigned>> FreqPairs; // <freq,code> 6864cdb68ebSFrancis Visoiu Mistrih for (unsigned i = 0, e = Stats.CodeFreq.size(); i != e; ++i) 6874cdb68ebSFrancis Visoiu Mistrih if (unsigned Freq = Stats.CodeFreq[i].NumInstances) 6884cdb68ebSFrancis Visoiu Mistrih FreqPairs.push_back(std::make_pair(Freq, i)); 6894cdb68ebSFrancis Visoiu Mistrih llvm::stable_sort(FreqPairs); 6904cdb68ebSFrancis Visoiu Mistrih std::reverse(FreqPairs.begin(), FreqPairs.end()); 6914cdb68ebSFrancis Visoiu Mistrih 6924cdb68ebSFrancis Visoiu Mistrih O.OS << "\tRecord Histogram:\n"; 6934cdb68ebSFrancis Visoiu Mistrih O.OS << "\t\t Count # Bits b/Rec % Abv Record Kind\n"; 6944cdb68ebSFrancis Visoiu Mistrih for (unsigned i = 0, e = FreqPairs.size(); i != e; ++i) { 6954cdb68ebSFrancis Visoiu Mistrih const PerRecordStats &RecStats = Stats.CodeFreq[FreqPairs[i].second]; 6964cdb68ebSFrancis Visoiu Mistrih 6974cdb68ebSFrancis Visoiu Mistrih O.OS << format("\t\t%7d %9lu", RecStats.NumInstances, 6984cdb68ebSFrancis Visoiu Mistrih (unsigned long)RecStats.TotalBits); 6994cdb68ebSFrancis Visoiu Mistrih 7004cdb68ebSFrancis Visoiu Mistrih if (RecStats.NumInstances > 1) 7014cdb68ebSFrancis Visoiu Mistrih O.OS << format(" %9.1f", 7024cdb68ebSFrancis Visoiu Mistrih (double)RecStats.TotalBits / RecStats.NumInstances); 7034cdb68ebSFrancis Visoiu Mistrih else 7044cdb68ebSFrancis Visoiu Mistrih O.OS << " "; 7054cdb68ebSFrancis Visoiu Mistrih 7064cdb68ebSFrancis Visoiu Mistrih if (RecStats.NumAbbrev) 7074cdb68ebSFrancis Visoiu Mistrih O.OS << format(" %7.2f", (double)RecStats.NumAbbrev / 7084cdb68ebSFrancis Visoiu Mistrih RecStats.NumInstances * 100); 7094cdb68ebSFrancis Visoiu Mistrih else 7104cdb68ebSFrancis Visoiu Mistrih O.OS << " "; 7114cdb68ebSFrancis Visoiu Mistrih 7124cdb68ebSFrancis Visoiu Mistrih O.OS << " "; 7134cdb68ebSFrancis Visoiu Mistrih if (Optional<const char *> CodeName = GetCodeName( 7144cdb68ebSFrancis Visoiu Mistrih FreqPairs[i].second, I->first, BlockInfo, CurStreamType)) 7154cdb68ebSFrancis Visoiu Mistrih O.OS << *CodeName << "\n"; 7164cdb68ebSFrancis Visoiu Mistrih else 7174cdb68ebSFrancis Visoiu Mistrih O.OS << "UnknownCode" << FreqPairs[i].second << "\n"; 7184cdb68ebSFrancis Visoiu Mistrih } 7194cdb68ebSFrancis Visoiu Mistrih O.OS << "\n"; 7204cdb68ebSFrancis Visoiu Mistrih } 7214cdb68ebSFrancis Visoiu Mistrih } 7224cdb68ebSFrancis Visoiu Mistrih } 7234cdb68ebSFrancis Visoiu Mistrih 7244cdb68ebSFrancis Visoiu Mistrih Error BitcodeAnalyzer::parseBlock(unsigned BlockID, unsigned IndentLevel, 7254cdb68ebSFrancis Visoiu Mistrih Optional<BCDumpOptions> O, 7264cdb68ebSFrancis Visoiu Mistrih Optional<StringRef> CheckHash) { 7274cdb68ebSFrancis Visoiu Mistrih std::string Indent(IndentLevel * 2, ' '); 7284cdb68ebSFrancis Visoiu Mistrih uint64_t BlockBitStart = Stream.GetCurrentBitNo(); 7294cdb68ebSFrancis Visoiu Mistrih 7304cdb68ebSFrancis Visoiu Mistrih // Get the statistics for this BlockID. 7314cdb68ebSFrancis Visoiu Mistrih PerBlockIDStats &BlockStats = BlockIDStats[BlockID]; 7324cdb68ebSFrancis Visoiu Mistrih 7334cdb68ebSFrancis Visoiu Mistrih BlockStats.NumInstances++; 7344cdb68ebSFrancis Visoiu Mistrih 7354cdb68ebSFrancis Visoiu Mistrih // BLOCKINFO is a special part of the stream. 7364cdb68ebSFrancis Visoiu Mistrih bool DumpRecords = O.hasValue(); 7374cdb68ebSFrancis Visoiu Mistrih if (BlockID == bitc::BLOCKINFO_BLOCK_ID) { 7384cdb68ebSFrancis Visoiu Mistrih if (O) 7394cdb68ebSFrancis Visoiu Mistrih O->OS << Indent << "<BLOCKINFO_BLOCK/>\n"; 7404cdb68ebSFrancis Visoiu Mistrih Expected<Optional<BitstreamBlockInfo>> MaybeNewBlockInfo = 7414cdb68ebSFrancis Visoiu Mistrih Stream.ReadBlockInfoBlock(/*ReadBlockInfoNames=*/true); 7424cdb68ebSFrancis Visoiu Mistrih if (!MaybeNewBlockInfo) 7434cdb68ebSFrancis Visoiu Mistrih return MaybeNewBlockInfo.takeError(); 7444cdb68ebSFrancis Visoiu Mistrih Optional<BitstreamBlockInfo> NewBlockInfo = 7454cdb68ebSFrancis Visoiu Mistrih std::move(MaybeNewBlockInfo.get()); 7464cdb68ebSFrancis Visoiu Mistrih if (!NewBlockInfo) 7474cdb68ebSFrancis Visoiu Mistrih return reportError("Malformed BlockInfoBlock"); 7484cdb68ebSFrancis Visoiu Mistrih BlockInfo = std::move(*NewBlockInfo); 7494cdb68ebSFrancis Visoiu Mistrih if (Error Err = Stream.JumpToBit(BlockBitStart)) 7504cdb68ebSFrancis Visoiu Mistrih return Err; 7514cdb68ebSFrancis Visoiu Mistrih // It's not really interesting to dump the contents of the blockinfo 7524cdb68ebSFrancis Visoiu Mistrih // block. 7534cdb68ebSFrancis Visoiu Mistrih DumpRecords = false; 7544cdb68ebSFrancis Visoiu Mistrih } 7554cdb68ebSFrancis Visoiu Mistrih 7564cdb68ebSFrancis Visoiu Mistrih unsigned NumWords = 0; 7574cdb68ebSFrancis Visoiu Mistrih if (Error Err = Stream.EnterSubBlock(BlockID, &NumWords)) 7584cdb68ebSFrancis Visoiu Mistrih return Err; 7594cdb68ebSFrancis Visoiu Mistrih 7604cdb68ebSFrancis Visoiu Mistrih // Keep it for later, when we see a MODULE_HASH record 7614cdb68ebSFrancis Visoiu Mistrih uint64_t BlockEntryPos = Stream.getCurrentByteNo(); 7624cdb68ebSFrancis Visoiu Mistrih 7634cdb68ebSFrancis Visoiu Mistrih Optional<const char *> BlockName = None; 7644cdb68ebSFrancis Visoiu Mistrih if (DumpRecords) { 7654cdb68ebSFrancis Visoiu Mistrih O->OS << Indent << "<"; 7664cdb68ebSFrancis Visoiu Mistrih if ((BlockName = GetBlockName(BlockID, BlockInfo, CurStreamType))) 7674cdb68ebSFrancis Visoiu Mistrih O->OS << *BlockName; 7684cdb68ebSFrancis Visoiu Mistrih else 7694cdb68ebSFrancis Visoiu Mistrih O->OS << "UnknownBlock" << BlockID; 7704cdb68ebSFrancis Visoiu Mistrih 7714cdb68ebSFrancis Visoiu Mistrih if (!O->Symbolic && BlockName) 7724cdb68ebSFrancis Visoiu Mistrih O->OS << " BlockID=" << BlockID; 7734cdb68ebSFrancis Visoiu Mistrih 7744cdb68ebSFrancis Visoiu Mistrih O->OS << " NumWords=" << NumWords 7754cdb68ebSFrancis Visoiu Mistrih << " BlockCodeSize=" << Stream.getAbbrevIDWidth() << ">\n"; 7764cdb68ebSFrancis Visoiu Mistrih } 7774cdb68ebSFrancis Visoiu Mistrih 7784cdb68ebSFrancis Visoiu Mistrih SmallVector<uint64_t, 64> Record; 7794cdb68ebSFrancis Visoiu Mistrih 7804cdb68ebSFrancis Visoiu Mistrih // Keep the offset to the metadata index if seen. 7814cdb68ebSFrancis Visoiu Mistrih uint64_t MetadataIndexOffset = 0; 7824cdb68ebSFrancis Visoiu Mistrih 7834cdb68ebSFrancis Visoiu Mistrih // Read all the records for this block. 7844cdb68ebSFrancis Visoiu Mistrih while (1) { 7854cdb68ebSFrancis Visoiu Mistrih if (Stream.AtEndOfStream()) 7864cdb68ebSFrancis Visoiu Mistrih return reportError("Premature end of bitstream"); 7874cdb68ebSFrancis Visoiu Mistrih 7884cdb68ebSFrancis Visoiu Mistrih uint64_t RecordStartBit = Stream.GetCurrentBitNo(); 7894cdb68ebSFrancis Visoiu Mistrih 7904cdb68ebSFrancis Visoiu Mistrih Expected<BitstreamEntry> MaybeEntry = 7914cdb68ebSFrancis Visoiu Mistrih Stream.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs); 7924cdb68ebSFrancis Visoiu Mistrih if (!MaybeEntry) 7934cdb68ebSFrancis Visoiu Mistrih return MaybeEntry.takeError(); 7944cdb68ebSFrancis Visoiu Mistrih BitstreamEntry Entry = MaybeEntry.get(); 7954cdb68ebSFrancis Visoiu Mistrih 7964cdb68ebSFrancis Visoiu Mistrih switch (Entry.Kind) { 7974cdb68ebSFrancis Visoiu Mistrih case BitstreamEntry::Error: 7984cdb68ebSFrancis Visoiu Mistrih return reportError("malformed bitcode file"); 7994cdb68ebSFrancis Visoiu Mistrih case BitstreamEntry::EndBlock: { 8004cdb68ebSFrancis Visoiu Mistrih uint64_t BlockBitEnd = Stream.GetCurrentBitNo(); 8014cdb68ebSFrancis Visoiu Mistrih BlockStats.NumBits += BlockBitEnd - BlockBitStart; 8024cdb68ebSFrancis Visoiu Mistrih if (DumpRecords) { 8034cdb68ebSFrancis Visoiu Mistrih O->OS << Indent << "</"; 8044cdb68ebSFrancis Visoiu Mistrih if (BlockName) 8054cdb68ebSFrancis Visoiu Mistrih O->OS << *BlockName << ">\n"; 8064cdb68ebSFrancis Visoiu Mistrih else 8074cdb68ebSFrancis Visoiu Mistrih O->OS << "UnknownBlock" << BlockID << ">\n"; 8084cdb68ebSFrancis Visoiu Mistrih } 8094cdb68ebSFrancis Visoiu Mistrih return Error::success(); 8104cdb68ebSFrancis Visoiu Mistrih } 8114cdb68ebSFrancis Visoiu Mistrih 8124cdb68ebSFrancis Visoiu Mistrih case BitstreamEntry::SubBlock: { 8134cdb68ebSFrancis Visoiu Mistrih uint64_t SubBlockBitStart = Stream.GetCurrentBitNo(); 8144cdb68ebSFrancis Visoiu Mistrih if (Error E = parseBlock(Entry.ID, IndentLevel + 1, O, CheckHash)) 8154cdb68ebSFrancis Visoiu Mistrih return E; 8164cdb68ebSFrancis Visoiu Mistrih ++BlockStats.NumSubBlocks; 8174cdb68ebSFrancis Visoiu Mistrih uint64_t SubBlockBitEnd = Stream.GetCurrentBitNo(); 8184cdb68ebSFrancis Visoiu Mistrih 8194cdb68ebSFrancis Visoiu Mistrih // Don't include subblock sizes in the size of this block. 8204cdb68ebSFrancis Visoiu Mistrih BlockBitStart += SubBlockBitEnd - SubBlockBitStart; 8214cdb68ebSFrancis Visoiu Mistrih continue; 8224cdb68ebSFrancis Visoiu Mistrih } 8234cdb68ebSFrancis Visoiu Mistrih case BitstreamEntry::Record: 8244cdb68ebSFrancis Visoiu Mistrih // The interesting case. 8254cdb68ebSFrancis Visoiu Mistrih break; 8264cdb68ebSFrancis Visoiu Mistrih } 8274cdb68ebSFrancis Visoiu Mistrih 8284cdb68ebSFrancis Visoiu Mistrih if (Entry.ID == bitc::DEFINE_ABBREV) { 8294cdb68ebSFrancis Visoiu Mistrih if (Error Err = Stream.ReadAbbrevRecord()) 8304cdb68ebSFrancis Visoiu Mistrih return Err; 8314cdb68ebSFrancis Visoiu Mistrih ++BlockStats.NumAbbrevs; 8324cdb68ebSFrancis Visoiu Mistrih continue; 8334cdb68ebSFrancis Visoiu Mistrih } 8344cdb68ebSFrancis Visoiu Mistrih 8354cdb68ebSFrancis Visoiu Mistrih Record.clear(); 8364cdb68ebSFrancis Visoiu Mistrih 8374cdb68ebSFrancis Visoiu Mistrih ++BlockStats.NumRecords; 8384cdb68ebSFrancis Visoiu Mistrih 8394cdb68ebSFrancis Visoiu Mistrih StringRef Blob; 8404cdb68ebSFrancis Visoiu Mistrih uint64_t CurrentRecordPos = Stream.GetCurrentBitNo(); 8414cdb68ebSFrancis Visoiu Mistrih Expected<unsigned> MaybeCode = Stream.readRecord(Entry.ID, Record, &Blob); 8424cdb68ebSFrancis Visoiu Mistrih if (!MaybeCode) 8434cdb68ebSFrancis Visoiu Mistrih return MaybeCode.takeError(); 8444cdb68ebSFrancis Visoiu Mistrih unsigned Code = MaybeCode.get(); 8454cdb68ebSFrancis Visoiu Mistrih 8464cdb68ebSFrancis Visoiu Mistrih // Increment the # occurrences of this code. 8474cdb68ebSFrancis Visoiu Mistrih if (BlockStats.CodeFreq.size() <= Code) 8484cdb68ebSFrancis Visoiu Mistrih BlockStats.CodeFreq.resize(Code + 1); 8494cdb68ebSFrancis Visoiu Mistrih BlockStats.CodeFreq[Code].NumInstances++; 8504cdb68ebSFrancis Visoiu Mistrih BlockStats.CodeFreq[Code].TotalBits += 8514cdb68ebSFrancis Visoiu Mistrih Stream.GetCurrentBitNo() - RecordStartBit; 8524cdb68ebSFrancis Visoiu Mistrih if (Entry.ID != bitc::UNABBREV_RECORD) { 8534cdb68ebSFrancis Visoiu Mistrih BlockStats.CodeFreq[Code].NumAbbrev++; 8544cdb68ebSFrancis Visoiu Mistrih ++BlockStats.NumAbbreviatedRecords; 8554cdb68ebSFrancis Visoiu Mistrih } 8564cdb68ebSFrancis Visoiu Mistrih 8574cdb68ebSFrancis Visoiu Mistrih if (DumpRecords) { 8584cdb68ebSFrancis Visoiu Mistrih O->OS << Indent << " <"; 8594cdb68ebSFrancis Visoiu Mistrih Optional<const char *> CodeName = 8604cdb68ebSFrancis Visoiu Mistrih GetCodeName(Code, BlockID, BlockInfo, CurStreamType); 8614cdb68ebSFrancis Visoiu Mistrih if (CodeName) 8624cdb68ebSFrancis Visoiu Mistrih O->OS << *CodeName; 8634cdb68ebSFrancis Visoiu Mistrih else 8644cdb68ebSFrancis Visoiu Mistrih O->OS << "UnknownCode" << Code; 8654cdb68ebSFrancis Visoiu Mistrih if (!O->Symbolic && CodeName) 8664cdb68ebSFrancis Visoiu Mistrih O->OS << " codeid=" << Code; 8674cdb68ebSFrancis Visoiu Mistrih const BitCodeAbbrev *Abbv = nullptr; 8684cdb68ebSFrancis Visoiu Mistrih if (Entry.ID != bitc::UNABBREV_RECORD) { 8694cdb68ebSFrancis Visoiu Mistrih Abbv = Stream.getAbbrev(Entry.ID); 8704cdb68ebSFrancis Visoiu Mistrih O->OS << " abbrevid=" << Entry.ID; 8714cdb68ebSFrancis Visoiu Mistrih } 8724cdb68ebSFrancis Visoiu Mistrih 8734cdb68ebSFrancis Visoiu Mistrih for (unsigned i = 0, e = Record.size(); i != e; ++i) 8744cdb68ebSFrancis Visoiu Mistrih O->OS << " op" << i << "=" << (int64_t)Record[i]; 8754cdb68ebSFrancis Visoiu Mistrih 8764cdb68ebSFrancis Visoiu Mistrih // If we found a metadata index, let's verify that we had an offset 8774cdb68ebSFrancis Visoiu Mistrih // before and validate its forward reference offset was correct! 8784cdb68ebSFrancis Visoiu Mistrih if (BlockID == bitc::METADATA_BLOCK_ID) { 8794cdb68ebSFrancis Visoiu Mistrih if (Code == bitc::METADATA_INDEX_OFFSET) { 8804cdb68ebSFrancis Visoiu Mistrih if (Record.size() != 2) 8814cdb68ebSFrancis Visoiu Mistrih O->OS << "(Invalid record)"; 8824cdb68ebSFrancis Visoiu Mistrih else { 8834cdb68ebSFrancis Visoiu Mistrih auto Offset = Record[0] + (Record[1] << 32); 8844cdb68ebSFrancis Visoiu Mistrih MetadataIndexOffset = Stream.GetCurrentBitNo() + Offset; 8854cdb68ebSFrancis Visoiu Mistrih } 8864cdb68ebSFrancis Visoiu Mistrih } 8874cdb68ebSFrancis Visoiu Mistrih if (Code == bitc::METADATA_INDEX) { 8884cdb68ebSFrancis Visoiu Mistrih O->OS << " (offset "; 8894cdb68ebSFrancis Visoiu Mistrih if (MetadataIndexOffset == RecordStartBit) 8904cdb68ebSFrancis Visoiu Mistrih O->OS << "match)"; 8914cdb68ebSFrancis Visoiu Mistrih else 8924cdb68ebSFrancis Visoiu Mistrih O->OS << "mismatch: " << MetadataIndexOffset << " vs " 8934cdb68ebSFrancis Visoiu Mistrih << RecordStartBit << ")"; 8944cdb68ebSFrancis Visoiu Mistrih } 8954cdb68ebSFrancis Visoiu Mistrih } 8964cdb68ebSFrancis Visoiu Mistrih 8974cdb68ebSFrancis Visoiu Mistrih // If we found a module hash, let's verify that it matches! 8984cdb68ebSFrancis Visoiu Mistrih if (BlockID == bitc::MODULE_BLOCK_ID && Code == bitc::MODULE_CODE_HASH && 8994cdb68ebSFrancis Visoiu Mistrih CheckHash.hasValue()) { 9004cdb68ebSFrancis Visoiu Mistrih if (Record.size() != 5) 9014cdb68ebSFrancis Visoiu Mistrih O->OS << " (invalid)"; 9024cdb68ebSFrancis Visoiu Mistrih else { 9034cdb68ebSFrancis Visoiu Mistrih // Recompute the hash and compare it to the one in the bitcode 9044cdb68ebSFrancis Visoiu Mistrih SHA1 Hasher; 9054cdb68ebSFrancis Visoiu Mistrih StringRef Hash; 9064cdb68ebSFrancis Visoiu Mistrih Hasher.update(*CheckHash); 9074cdb68ebSFrancis Visoiu Mistrih { 9084cdb68ebSFrancis Visoiu Mistrih int BlockSize = (CurrentRecordPos / 8) - BlockEntryPos; 9094cdb68ebSFrancis Visoiu Mistrih auto Ptr = Stream.getPointerToByte(BlockEntryPos, BlockSize); 9104cdb68ebSFrancis Visoiu Mistrih Hasher.update(ArrayRef<uint8_t>(Ptr, BlockSize)); 9114cdb68ebSFrancis Visoiu Mistrih Hash = Hasher.result(); 9124cdb68ebSFrancis Visoiu Mistrih } 9134cdb68ebSFrancis Visoiu Mistrih SmallString<20> RecordedHash; 9144cdb68ebSFrancis Visoiu Mistrih RecordedHash.resize(20); 9154cdb68ebSFrancis Visoiu Mistrih int Pos = 0; 9164cdb68ebSFrancis Visoiu Mistrih for (auto &Val : Record) { 9174cdb68ebSFrancis Visoiu Mistrih assert(!(Val >> 32) && "Unexpected high bits set"); 9184cdb68ebSFrancis Visoiu Mistrih RecordedHash[Pos++] = (Val >> 24) & 0xFF; 9194cdb68ebSFrancis Visoiu Mistrih RecordedHash[Pos++] = (Val >> 16) & 0xFF; 9204cdb68ebSFrancis Visoiu Mistrih RecordedHash[Pos++] = (Val >> 8) & 0xFF; 9214cdb68ebSFrancis Visoiu Mistrih RecordedHash[Pos++] = (Val >> 0) & 0xFF; 9224cdb68ebSFrancis Visoiu Mistrih } 9234cdb68ebSFrancis Visoiu Mistrih if (Hash == RecordedHash) 9244cdb68ebSFrancis Visoiu Mistrih O->OS << " (match)"; 9254cdb68ebSFrancis Visoiu Mistrih else 9264cdb68ebSFrancis Visoiu Mistrih O->OS << " (!mismatch!)"; 9274cdb68ebSFrancis Visoiu Mistrih } 9284cdb68ebSFrancis Visoiu Mistrih } 9294cdb68ebSFrancis Visoiu Mistrih 9304cdb68ebSFrancis Visoiu Mistrih O->OS << "/>"; 9314cdb68ebSFrancis Visoiu Mistrih 9324cdb68ebSFrancis Visoiu Mistrih if (Abbv) { 9334cdb68ebSFrancis Visoiu Mistrih for (unsigned i = 1, e = Abbv->getNumOperandInfos(); i != e; ++i) { 9344cdb68ebSFrancis Visoiu Mistrih const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); 9354cdb68ebSFrancis Visoiu Mistrih if (!Op.isEncoding() || Op.getEncoding() != BitCodeAbbrevOp::Array) 9364cdb68ebSFrancis Visoiu Mistrih continue; 9374cdb68ebSFrancis Visoiu Mistrih assert(i + 2 == e && "Array op not second to last"); 9384cdb68ebSFrancis Visoiu Mistrih std::string Str; 9394cdb68ebSFrancis Visoiu Mistrih bool ArrayIsPrintable = true; 9404cdb68ebSFrancis Visoiu Mistrih for (unsigned j = i - 1, je = Record.size(); j != je; ++j) { 9414cdb68ebSFrancis Visoiu Mistrih if (!isPrint(static_cast<unsigned char>(Record[j]))) { 9424cdb68ebSFrancis Visoiu Mistrih ArrayIsPrintable = false; 9434cdb68ebSFrancis Visoiu Mistrih break; 9444cdb68ebSFrancis Visoiu Mistrih } 9454cdb68ebSFrancis Visoiu Mistrih Str += (char)Record[j]; 9464cdb68ebSFrancis Visoiu Mistrih } 9474cdb68ebSFrancis Visoiu Mistrih if (ArrayIsPrintable) 9484cdb68ebSFrancis Visoiu Mistrih O->OS << " record string = '" << Str << "'"; 9494cdb68ebSFrancis Visoiu Mistrih break; 9504cdb68ebSFrancis Visoiu Mistrih } 9514cdb68ebSFrancis Visoiu Mistrih } 9524cdb68ebSFrancis Visoiu Mistrih 9534cdb68ebSFrancis Visoiu Mistrih if (Blob.data()) { 9544cdb68ebSFrancis Visoiu Mistrih if (canDecodeBlob(Code, BlockID)) { 9554cdb68ebSFrancis Visoiu Mistrih if (Error E = decodeMetadataStringsBlob(Indent, Record, Blob, O->OS)) 9564cdb68ebSFrancis Visoiu Mistrih return E; 9574cdb68ebSFrancis Visoiu Mistrih } else { 9584cdb68ebSFrancis Visoiu Mistrih O->OS << " blob data = "; 9594cdb68ebSFrancis Visoiu Mistrih if (O->ShowBinaryBlobs) { 9604cdb68ebSFrancis Visoiu Mistrih O->OS << "'"; 9614cdb68ebSFrancis Visoiu Mistrih O->OS.write_escaped(Blob, /*hex=*/true) << "'"; 9624cdb68ebSFrancis Visoiu Mistrih } else { 9634cdb68ebSFrancis Visoiu Mistrih bool BlobIsPrintable = true; 9644cdb68ebSFrancis Visoiu Mistrih for (unsigned i = 0, e = Blob.size(); i != e; ++i) 9654cdb68ebSFrancis Visoiu Mistrih if (!isPrint(static_cast<unsigned char>(Blob[i]))) { 9664cdb68ebSFrancis Visoiu Mistrih BlobIsPrintable = false; 9674cdb68ebSFrancis Visoiu Mistrih break; 9684cdb68ebSFrancis Visoiu Mistrih } 9694cdb68ebSFrancis Visoiu Mistrih 9704cdb68ebSFrancis Visoiu Mistrih if (BlobIsPrintable) 9714cdb68ebSFrancis Visoiu Mistrih O->OS << "'" << Blob << "'"; 9724cdb68ebSFrancis Visoiu Mistrih else 9734cdb68ebSFrancis Visoiu Mistrih O->OS << "unprintable, " << Blob.size() << " bytes."; 9744cdb68ebSFrancis Visoiu Mistrih } 9754cdb68ebSFrancis Visoiu Mistrih } 9764cdb68ebSFrancis Visoiu Mistrih } 9774cdb68ebSFrancis Visoiu Mistrih 9784cdb68ebSFrancis Visoiu Mistrih O->OS << "\n"; 9794cdb68ebSFrancis Visoiu Mistrih } 9804cdb68ebSFrancis Visoiu Mistrih 9814cdb68ebSFrancis Visoiu Mistrih // Make sure that we can skip the current record. 9824cdb68ebSFrancis Visoiu Mistrih if (Error Err = Stream.JumpToBit(CurrentRecordPos)) 9834cdb68ebSFrancis Visoiu Mistrih return Err; 9844cdb68ebSFrancis Visoiu Mistrih if (Expected<unsigned> Skipped = Stream.skipRecord(Entry.ID)) 9854cdb68ebSFrancis Visoiu Mistrih ; // Do nothing. 9864cdb68ebSFrancis Visoiu Mistrih else 9874cdb68ebSFrancis Visoiu Mistrih return Skipped.takeError(); 9884cdb68ebSFrancis Visoiu Mistrih } 9894cdb68ebSFrancis Visoiu Mistrih } 9904cdb68ebSFrancis Visoiu Mistrih 991