Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- GSIStreamBuilder.h - PDB Publics/Globals Stream Creation -*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8.  
  9. #ifndef LLVM_DEBUGINFO_PDB_NATIVE_GSISTREAMBUILDER_H
  10. #define LLVM_DEBUGINFO_PDB_NATIVE_GSISTREAMBUILDER_H
  11.  
  12. #include "llvm/ADT/DenseSet.h"
  13. #include "llvm/DebugInfo/CodeView/CVRecord.h"
  14. #include "llvm/DebugInfo/CodeView/CodeView.h"
  15. #include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
  16. #include "llvm/DebugInfo/PDB/Native/RawConstants.h"
  17. #include "llvm/Support/BinaryStreamRef.h"
  18. #include "llvm/Support/Error.h"
  19.  
  20. namespace llvm {
  21. namespace codeview {
  22. class ConstantSym;
  23. class DataSym;
  24. class ProcRefSym;
  25. } // namespace codeview
  26. template <typename T> struct BinaryItemTraits;
  27.  
  28. template <> struct BinaryItemTraits<codeview::CVSymbol> {
  29.   static size_t length(const codeview::CVSymbol &Item) {
  30.     return Item.RecordData.size();
  31.   }
  32.   static ArrayRef<uint8_t> bytes(const codeview::CVSymbol &Item) {
  33.     return Item.RecordData;
  34.   }
  35. };
  36.  
  37. namespace msf {
  38. class MSFBuilder;
  39. struct MSFLayout;
  40. } // namespace msf
  41. namespace pdb {
  42. struct GSIHashStreamBuilder;
  43. struct BulkPublic;
  44. struct SymbolDenseMapInfo;
  45.  
  46. class GSIStreamBuilder {
  47.  
  48. public:
  49.   explicit GSIStreamBuilder(msf::MSFBuilder &Msf);
  50.   ~GSIStreamBuilder();
  51.  
  52.   GSIStreamBuilder(const GSIStreamBuilder &) = delete;
  53.   GSIStreamBuilder &operator=(const GSIStreamBuilder &) = delete;
  54.  
  55.   Error finalizeMsfLayout();
  56.  
  57.   Error commit(const msf::MSFLayout &Layout, WritableBinaryStreamRef Buffer);
  58.  
  59.   uint32_t getPublicsStreamIndex() const { return PublicsStreamIndex; }
  60.   uint32_t getGlobalsStreamIndex() const { return GlobalsStreamIndex; }
  61.   uint32_t getRecordStreamIndex() const { return RecordStreamIndex; }
  62.  
  63.   // Add public symbols in bulk.
  64.   void addPublicSymbols(std::vector<BulkPublic> &&PublicsIn);
  65.  
  66.   void addGlobalSymbol(const codeview::ProcRefSym &Sym);
  67.   void addGlobalSymbol(const codeview::DataSym &Sym);
  68.   void addGlobalSymbol(const codeview::ConstantSym &Sym);
  69.  
  70.   // Add a pre-serialized global symbol record. The caller must ensure that the
  71.   // symbol data remains alive until the global stream is committed to disk.
  72.   void addGlobalSymbol(const codeview::CVSymbol &Sym);
  73.  
  74. private:
  75.   void finalizePublicBuckets();
  76.   void finalizeGlobalBuckets(uint32_t RecordZeroOffset);
  77.  
  78.   template <typename T> void serializeAndAddGlobal(const T &Symbol);
  79.  
  80.   uint32_t calculatePublicsHashStreamSize() const;
  81.   uint32_t calculateGlobalsHashStreamSize() const;
  82.   Error commitSymbolRecordStream(WritableBinaryStreamRef Stream);
  83.   Error commitPublicsHashStream(WritableBinaryStreamRef Stream);
  84.   Error commitGlobalsHashStream(WritableBinaryStreamRef Stream);
  85.  
  86.   uint32_t PublicsStreamIndex = kInvalidStreamIndex;
  87.   uint32_t GlobalsStreamIndex = kInvalidStreamIndex;
  88.   uint32_t RecordStreamIndex = kInvalidStreamIndex;
  89.   msf::MSFBuilder &Msf;
  90.   std::unique_ptr<GSIHashStreamBuilder> PSH;
  91.   std::unique_ptr<GSIHashStreamBuilder> GSH;
  92.  
  93.   // List of all of the public records. These are stored unserialized so that we
  94.   // can defer copying the names until we are ready to commit the PDB.
  95.   std::vector<BulkPublic> Publics;
  96.  
  97.   // List of all of the global records.
  98.   std::vector<codeview::CVSymbol> Globals;
  99.  
  100.   // Hash table for deduplicating global typedef and constant records. Only used
  101.   // for globals.
  102.   llvm::DenseSet<codeview::CVSymbol, SymbolDenseMapInfo> GlobalsSeen;
  103. };
  104.  
  105. /// This struct is equivalent to codeview::PublicSym32, but it has been
  106. /// optimized for size to speed up bulk serialization and sorting operations
  107. /// during PDB writing.
  108. struct BulkPublic {
  109.   BulkPublic() : Flags(0), BucketIdx(0) {}
  110.  
  111.   const char *Name = nullptr;
  112.   uint32_t NameLen = 0;
  113.  
  114.   // Offset of the symbol record in the publics stream.
  115.   uint32_t SymOffset = 0;
  116.  
  117.   // Section offset of the symbol in the image.
  118.   uint32_t Offset = 0;
  119.  
  120.   // Section index of the section containing the symbol.
  121.   uint16_t Segment = 0;
  122.  
  123.   // PublicSymFlags.
  124.   uint16_t Flags : 4;
  125.  
  126.   // GSI hash table bucket index. The maximum value is IPHR_HASH.
  127.   uint16_t BucketIdx : 12;
  128.   static_assert(IPHR_HASH <= 1 << 12, "bitfield too small");
  129.  
  130.   void setFlags(codeview::PublicSymFlags F) {
  131.     Flags = uint32_t(F);
  132.     assert(Flags == uint32_t(F) && "truncated");
  133.   }
  134.  
  135.   void setBucketIdx(uint16_t B) {
  136.     assert(B < IPHR_HASH);
  137.     BucketIdx = B;
  138.   }
  139.  
  140.   StringRef getName() const { return StringRef(Name, NameLen); }
  141. };
  142.  
  143. static_assert(sizeof(BulkPublic) <= 24, "unexpected size increase");
  144. static_assert(std::is_trivially_copyable<BulkPublic>::value,
  145.               "should be trivial");
  146.  
  147. } // namespace pdb
  148. } // namespace llvm
  149.  
  150. #endif
  151.