Home | History | Annotate | Line # | Download | only in Native
      1 //===- DbiModuleDescriptorBuilder.h - PDB module information ----*- 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_DBIMODULEDESCRIPTORBUILDER_H
     10 #define LLVM_DEBUGINFO_PDB_NATIVE_DBIMODULEDESCRIPTORBUILDER_H
     11 
     12 #include "llvm/ADT/StringRef.h"
     13 #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
     14 #include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
     15 #include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
     16 #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
     17 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
     18 #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
     19 #include "llvm/Support/Error.h"
     20 #include <cstdint>
     21 #include <string>
     22 #include <vector>
     23 
     24 namespace llvm {
     25 class BinaryStreamWriter;
     26 
     27 namespace codeview {
     28 class DebugSubsectionRecordBuilder;
     29 }
     30 
     31 namespace msf {
     32 class MSFBuilder;
     33 struct MSFLayout;
     34 }
     35 namespace pdb {
     36 
     37 // Represents merged or unmerged symbols. Merged symbols can be written to the
     38 // output file as is, but unmerged symbols must be rewritten first. In either
     39 // case, the size must be known up front.
     40 struct SymbolListWrapper {
     41   explicit SymbolListWrapper(ArrayRef<uint8_t> Syms)
     42       : SymPtr(const_cast<uint8_t *>(Syms.data())), SymSize(Syms.size()),
     43         NeedsToBeMerged(false) {}
     44   explicit SymbolListWrapper(void *SymSrc, uint32_t Length)
     45       : SymPtr(SymSrc), SymSize(Length), NeedsToBeMerged(true) {}
     46 
     47   ArrayRef<uint8_t> asArray() const {
     48     return ArrayRef<uint8_t>(static_cast<const uint8_t *>(SymPtr), SymSize);
     49   }
     50 
     51   uint32_t size() const { return SymSize; }
     52 
     53   void *SymPtr = nullptr;
     54   uint32_t SymSize = 0;
     55   bool NeedsToBeMerged = false;
     56 };
     57 
     58 /// Represents a string table reference at some offset in the module symbol
     59 /// stream.
     60 struct StringTableFixup {
     61   uint32_t StrTabOffset = 0;
     62   uint32_t SymOffsetOfReference = 0;
     63 };
     64 
     65 class DbiModuleDescriptorBuilder {
     66   friend class DbiStreamBuilder;
     67 
     68 public:
     69   DbiModuleDescriptorBuilder(StringRef ModuleName, uint32_t ModIndex,
     70                              msf::MSFBuilder &Msf);
     71   ~DbiModuleDescriptorBuilder();
     72 
     73   DbiModuleDescriptorBuilder(const DbiModuleDescriptorBuilder &) = delete;
     74   DbiModuleDescriptorBuilder &
     75   operator=(const DbiModuleDescriptorBuilder &) = delete;
     76 
     77   void setPdbFilePathNI(uint32_t NI);
     78   void setObjFileName(StringRef Name);
     79 
     80   // Callback to merge one source of unmerged symbols.
     81   using MergeSymbolsCallback = Error (*)(void *Ctx, void *Symbols,
     82                                          BinaryStreamWriter &Writer);
     83 
     84   void setMergeSymbolsCallback(void *Ctx, MergeSymbolsCallback Callback) {
     85     MergeSymsCtx = Ctx;
     86     MergeSymsCallback = Callback;
     87   }
     88 
     89   void setStringTableFixups(std::vector<StringTableFixup> &&Fixups) {
     90     StringTableFixups = std::move(Fixups);
     91   }
     92 
     93   void setFirstSectionContrib(const SectionContrib &SC);
     94   void addSymbol(codeview::CVSymbol Symbol);
     95   void addSymbolsInBulk(ArrayRef<uint8_t> BulkSymbols);
     96 
     97   // Add symbols of known size which will be merged (rewritten) when committing
     98   // the PDB to disk.
     99   void addUnmergedSymbols(void *SymSrc, uint32_t SymLength);
    100 
    101   void
    102   addDebugSubsection(std::shared_ptr<codeview::DebugSubsection> Subsection);
    103 
    104   void
    105   addDebugSubsection(const codeview::DebugSubsectionRecord &SubsectionContents);
    106 
    107   uint16_t getStreamIndex() const;
    108   StringRef getModuleName() const { return ModuleName; }
    109   StringRef getObjFileName() const { return ObjFileName; }
    110 
    111   unsigned getModuleIndex() const { return Layout.Mod; }
    112 
    113   ArrayRef<std::string> source_files() const {
    114     return makeArrayRef(SourceFiles);
    115   }
    116 
    117   uint32_t calculateSerializedLength() const;
    118 
    119   /// Return the offset within the module symbol stream of the next symbol
    120   /// record passed to addSymbol. Add four to account for the signature.
    121   uint32_t getNextSymbolOffset() const { return SymbolByteSize + 4; }
    122 
    123   void finalize();
    124   Error finalizeMsfLayout();
    125 
    126   /// Commit the DBI descriptor to the DBI stream.
    127   Error commit(BinaryStreamWriter &ModiWriter);
    128 
    129   /// Commit the accumulated symbols to the module symbol stream. Safe to call
    130   /// in parallel on different DbiModuleDescriptorBuilder objects. Only modifies
    131   /// the pre-allocated stream in question.
    132   Error commitSymbolStream(const msf::MSFLayout &MsfLayout,
    133                            WritableBinaryStreamRef MsfBuffer);
    134 
    135 private:
    136   uint32_t calculateC13DebugInfoSize() const;
    137 
    138   void addSourceFile(StringRef Path);
    139   msf::MSFBuilder &MSF;
    140 
    141   uint32_t SymbolByteSize = 0;
    142   uint32_t PdbFilePathNI = 0;
    143   std::string ModuleName;
    144   std::string ObjFileName;
    145   std::vector<std::string> SourceFiles;
    146   std::vector<SymbolListWrapper> Symbols;
    147 
    148   void *MergeSymsCtx = nullptr;
    149   MergeSymbolsCallback MergeSymsCallback = nullptr;
    150 
    151   std::vector<StringTableFixup> StringTableFixups;
    152 
    153   std::vector<codeview::DebugSubsectionRecordBuilder> C13Builders;
    154 
    155   ModuleInfoHeader Layout;
    156 };
    157 
    158 } // end namespace pdb
    159 
    160 } // end namespace llvm
    161 
    162 #endif // LLVM_DEBUGINFO_PDB_NATIVE_DBIMODULEDESCRIPTORBUILDER_H
    163