aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/llvm14/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h
blob: b5c2ad4e81d8bf1a0c02198df9153c4442e4877f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#pragma once

#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif

//===- DbiModuleDescriptorBuilder.h - PDB module information ----*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_DEBUGINFO_PDB_NATIVE_DBIMODULEDESCRIPTORBUILDER_H
#define LLVM_DEBUGINFO_PDB_NATIVE_DBIMODULEDESCRIPTORBUILDER_H

#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
#include "llvm/Support/Error.h"
#include <cstdint>
#include <string>
#include <vector>

namespace llvm {
class BinaryStreamWriter;

namespace codeview {
class DebugSubsectionRecordBuilder;
}

namespace msf {
class MSFBuilder;
struct MSFLayout;
}
namespace pdb {

// Represents merged or unmerged symbols. Merged symbols can be written to the
// output file as is, but unmerged symbols must be rewritten first. In either
// case, the size must be known up front.
struct SymbolListWrapper {
  explicit SymbolListWrapper(ArrayRef<uint8_t> Syms)
      : SymPtr(const_cast<uint8_t *>(Syms.data())), SymSize(Syms.size()),
        NeedsToBeMerged(false) {}
  explicit SymbolListWrapper(void *SymSrc, uint32_t Length)
      : SymPtr(SymSrc), SymSize(Length), NeedsToBeMerged(true) {}

  ArrayRef<uint8_t> asArray() const {
    return ArrayRef<uint8_t>(static_cast<const uint8_t *>(SymPtr), SymSize);
  }

  uint32_t size() const { return SymSize; }

  void *SymPtr = nullptr;
  uint32_t SymSize = 0;
  bool NeedsToBeMerged = false;
};

/// Represents a string table reference at some offset in the module symbol
/// stream.
struct StringTableFixup {
  uint32_t StrTabOffset = 0;
  uint32_t SymOffsetOfReference = 0;
};

class DbiModuleDescriptorBuilder {
  friend class DbiStreamBuilder;

public:
  DbiModuleDescriptorBuilder(StringRef ModuleName, uint32_t ModIndex,
                             msf::MSFBuilder &Msf);
  ~DbiModuleDescriptorBuilder();

  DbiModuleDescriptorBuilder(const DbiModuleDescriptorBuilder &) = delete;
  DbiModuleDescriptorBuilder &
  operator=(const DbiModuleDescriptorBuilder &) = delete;

  void setPdbFilePathNI(uint32_t NI);
  void setObjFileName(StringRef Name);

  // Callback to merge one source of unmerged symbols.
  using MergeSymbolsCallback = Error (*)(void *Ctx, void *Symbols,
                                         BinaryStreamWriter &Writer);

  void setMergeSymbolsCallback(void *Ctx, MergeSymbolsCallback Callback) {
    MergeSymsCtx = Ctx;
    MergeSymsCallback = Callback;
  }

  void setStringTableFixups(std::vector<StringTableFixup> &&Fixups) {
    StringTableFixups = std::move(Fixups);
  }

  void setFirstSectionContrib(const SectionContrib &SC);
  void addSymbol(codeview::CVSymbol Symbol);
  void addSymbolsInBulk(ArrayRef<uint8_t> BulkSymbols);

  // Add symbols of known size which will be merged (rewritten) when committing
  // the PDB to disk.
  void addUnmergedSymbols(void *SymSrc, uint32_t SymLength);

  void
  addDebugSubsection(std::shared_ptr<codeview::DebugSubsection> Subsection);

  void
  addDebugSubsection(const codeview::DebugSubsectionRecord &SubsectionContents);

  uint16_t getStreamIndex() const;
  StringRef getModuleName() const { return ModuleName; }
  StringRef getObjFileName() const { return ObjFileName; }

  unsigned getModuleIndex() const { return Layout.Mod; }

  ArrayRef<std::string> source_files() const {
    return makeArrayRef(SourceFiles);
  }

  uint32_t calculateSerializedLength() const;

  /// Return the offset within the module symbol stream of the next symbol
  /// record passed to addSymbol. Add four to account for the signature.
  uint32_t getNextSymbolOffset() const { return SymbolByteSize + 4; }

  void finalize();
  Error finalizeMsfLayout();

  /// Commit the DBI descriptor to the DBI stream.
  Error commit(BinaryStreamWriter &ModiWriter);

  /// Commit the accumulated symbols to the module symbol stream. Safe to call
  /// in parallel on different DbiModuleDescriptorBuilder objects. Only modifies
  /// the pre-allocated stream in question.
  Error commitSymbolStream(const msf::MSFLayout &MsfLayout,
                           WritableBinaryStreamRef MsfBuffer);

private:
  uint32_t calculateC13DebugInfoSize() const;

  void addSourceFile(StringRef Path);
  msf::MSFBuilder &MSF;

  uint32_t SymbolByteSize = 0;
  uint32_t PdbFilePathNI = 0;
  std::string ModuleName;
  std::string ObjFileName;
  std::vector<std::string> SourceFiles;
  std::vector<SymbolListWrapper> Symbols;

  void *MergeSymsCtx = nullptr;
  MergeSymbolsCallback MergeSymsCallback = nullptr;

  std::vector<StringTableFixup> StringTableFixups;

  std::vector<codeview::DebugSubsectionRecordBuilder> C13Builders;

  ModuleInfoHeader Layout;
};

} // end namespace pdb

} // end namespace llvm

#endif // LLVM_DEBUGINFO_PDB_NATIVE_DBIMODULEDESCRIPTORBUILDER_H

#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif