File indexing completed on 2026-05-10 08:43:44
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_DEBUGINFO_PDB_NATIVE_GSISTREAMBUILDER_H
0010 #define LLVM_DEBUGINFO_PDB_NATIVE_GSISTREAMBUILDER_H
0011
0012 #include "llvm/ADT/DenseSet.h"
0013 #include "llvm/DebugInfo/CodeView/CVRecord.h"
0014 #include "llvm/DebugInfo/CodeView/CodeView.h"
0015 #include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
0016 #include "llvm/DebugInfo/PDB/Native/RawConstants.h"
0017 #include "llvm/Support/BinaryStreamRef.h"
0018 #include "llvm/Support/Error.h"
0019
0020 namespace llvm {
0021 namespace codeview {
0022 class ConstantSym;
0023 class DataSym;
0024 class ProcRefSym;
0025 }
0026 template <typename T> struct BinaryItemTraits;
0027
0028 template <> struct BinaryItemTraits<codeview::CVSymbol> {
0029 static size_t length(const codeview::CVSymbol &Item) {
0030 return Item.RecordData.size();
0031 }
0032 static ArrayRef<uint8_t> bytes(const codeview::CVSymbol &Item) {
0033 return Item.RecordData;
0034 }
0035 };
0036
0037 namespace msf {
0038 class MSFBuilder;
0039 struct MSFLayout;
0040 }
0041 namespace pdb {
0042 struct GSIHashStreamBuilder;
0043 struct BulkPublic;
0044 struct SymbolDenseMapInfo;
0045
0046 class GSIStreamBuilder {
0047
0048 public:
0049 explicit GSIStreamBuilder(msf::MSFBuilder &Msf);
0050 ~GSIStreamBuilder();
0051
0052 GSIStreamBuilder(const GSIStreamBuilder &) = delete;
0053 GSIStreamBuilder &operator=(const GSIStreamBuilder &) = delete;
0054
0055 Error finalizeMsfLayout();
0056
0057 Error commit(const msf::MSFLayout &Layout, WritableBinaryStreamRef Buffer);
0058
0059 uint32_t getPublicsStreamIndex() const { return PublicsStreamIndex; }
0060 uint32_t getGlobalsStreamIndex() const { return GlobalsStreamIndex; }
0061 uint32_t getRecordStreamIndex() const { return RecordStreamIndex; }
0062
0063
0064 void addPublicSymbols(std::vector<BulkPublic> &&PublicsIn);
0065
0066 void addGlobalSymbol(const codeview::ProcRefSym &Sym);
0067 void addGlobalSymbol(const codeview::DataSym &Sym);
0068 void addGlobalSymbol(const codeview::ConstantSym &Sym);
0069
0070
0071
0072 void addGlobalSymbol(const codeview::CVSymbol &Sym);
0073
0074 private:
0075 void finalizePublicBuckets();
0076 void finalizeGlobalBuckets(uint32_t RecordZeroOffset);
0077
0078 template <typename T> void serializeAndAddGlobal(const T &Symbol);
0079
0080 uint32_t calculatePublicsHashStreamSize() const;
0081 uint32_t calculateGlobalsHashStreamSize() const;
0082 Error commitSymbolRecordStream(WritableBinaryStreamRef Stream);
0083 Error commitPublicsHashStream(WritableBinaryStreamRef Stream);
0084 Error commitGlobalsHashStream(WritableBinaryStreamRef Stream);
0085
0086 uint32_t PublicsStreamIndex = kInvalidStreamIndex;
0087 uint32_t GlobalsStreamIndex = kInvalidStreamIndex;
0088 uint32_t RecordStreamIndex = kInvalidStreamIndex;
0089 msf::MSFBuilder &Msf;
0090 std::unique_ptr<GSIHashStreamBuilder> PSH;
0091 std::unique_ptr<GSIHashStreamBuilder> GSH;
0092
0093
0094
0095 std::vector<BulkPublic> Publics;
0096
0097
0098 std::vector<codeview::CVSymbol> Globals;
0099
0100
0101
0102 llvm::DenseSet<codeview::CVSymbol, SymbolDenseMapInfo> GlobalsSeen;
0103 };
0104
0105
0106
0107
0108 struct BulkPublic {
0109 BulkPublic() : Flags(0), BucketIdx(0) {}
0110
0111 const char *Name = nullptr;
0112 uint32_t NameLen = 0;
0113
0114
0115 uint32_t SymOffset = 0;
0116
0117
0118 uint32_t Offset = 0;
0119
0120
0121 uint16_t Segment = 0;
0122
0123
0124 uint16_t Flags : 4;
0125
0126
0127 uint16_t BucketIdx : 12;
0128 static_assert(IPHR_HASH <= 1 << 12, "bitfield too small");
0129
0130 void setFlags(codeview::PublicSymFlags F) {
0131 Flags = uint32_t(F);
0132 assert(Flags == uint32_t(F) && "truncated");
0133 }
0134
0135 void setBucketIdx(uint16_t B) {
0136 assert(B < IPHR_HASH);
0137 BucketIdx = B;
0138 }
0139
0140 StringRef getName() const { return StringRef(Name, NameLen); }
0141 };
0142
0143 static_assert(sizeof(BulkPublic) <= 24, "unexpected size increase");
0144 static_assert(std::is_trivially_copyable<BulkPublic>::value,
0145 "should be trivial");
0146
0147 }
0148 }
0149
0150 #endif