Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:44

0001 //===- GSIStreamBuilder.h - PDB Publics/Globals Stream Creation -*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
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 } // namespace codeview
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 } // namespace msf
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   // Add public symbols in bulk.
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   // Add a pre-serialized global symbol record. The caller must ensure that the
0071   // symbol data remains alive until the global stream is committed to disk.
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   // List of all of the public records. These are stored unserialized so that we
0094   // can defer copying the names until we are ready to commit the PDB.
0095   std::vector<BulkPublic> Publics;
0096 
0097   // List of all of the global records.
0098   std::vector<codeview::CVSymbol> Globals;
0099 
0100   // Hash table for deduplicating global typedef and constant records. Only used
0101   // for globals.
0102   llvm::DenseSet<codeview::CVSymbol, SymbolDenseMapInfo> GlobalsSeen;
0103 };
0104 
0105 /// This struct is equivalent to codeview::PublicSym32, but it has been
0106 /// optimized for size to speed up bulk serialization and sorting operations
0107 /// during PDB writing.
0108 struct BulkPublic {
0109   BulkPublic() : Flags(0), BucketIdx(0) {}
0110 
0111   const char *Name = nullptr;
0112   uint32_t NameLen = 0;
0113 
0114   // Offset of the symbol record in the publics stream.
0115   uint32_t SymOffset = 0;
0116 
0117   // Section offset of the symbol in the image.
0118   uint32_t Offset = 0;
0119 
0120   // Section index of the section containing the symbol.
0121   uint16_t Segment = 0;
0122 
0123   // PublicSymFlags.
0124   uint16_t Flags : 4;
0125 
0126   // GSI hash table bucket index. The maximum value is IPHR_HASH.
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 } // namespace pdb
0148 } // namespace llvm
0149 
0150 #endif