LLVM: lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

29

30#include

31

32using namespace llvm;

37

38namespace llvm {

40}

41

43 : Allocator(Allocator), InjectedSourceHashTraits(Strings),

44 InjectedSourceTable(2) {}

45

47

50 if (!ExpectedMsf)

51 return ExpectedMsf.takeError();

52 Msf = std::make_unique(std::move(*ExpectedMsf));

54}

55

57

59 if (!Info)

60 Info = std::make_unique(*Msf, NamedStreams);

61 return *Info;

62}

63

65 if (!Dbi)

66 Dbi = std::make_unique(*Msf);

67 return *Dbi;

68}

69

71 if (!Tpi)

72 Tpi = std::make_unique(*Msf, StreamTPI);

73 return *Tpi;

74}

75

77 if (!Ipi)

78 Ipi = std::make_unique(*Msf, StreamIPI);

79 return *Ipi;

80}

81

85

87 if (!Gsi)

88 Gsi = std::make_unique(*Msf);

89 return *Gsi;

90}

91

94 auto ExpectedStream = Msf->addStream(Size);

95 if (ExpectedStream)

96 NamedStreams.set(Name, *ExpectedStream);

97 return ExpectedStream;

98}

99

102 if (!ExpectedIndex)

103 return ExpectedIndex.takeError();

104 assert(NamedStreamData.count(*ExpectedIndex) == 0);

105 NamedStreamData[*ExpectedIndex] = std::string(Data);

107}

108

110 std::unique_ptr Buffer) {

111

112

113

116

119

120 InjectedSourceDescriptor Desc;

121 Desc.Content = std::move(Buffer);

122 Desc.NameIndex = NI;

123 Desc.VNameIndex = VNI;

124 Desc.StreamName = "/src/files/";

125

126 Desc.StreamName += VName;

127

129}

130

131Error PDBFileBuilder::finalizeMsfLayout() {

133

134 if (Ipi && Ipi->getRecordCount() > 0) {

135

136

137

138

141 }

142

144

146 if (!SN)

148

149 if (Gsi) {

150 if (auto EC = Gsi->finalizeMsfLayout())

151 return EC;

152 if (Dbi) {

153 Dbi->setPublicsStreamIndex(Gsi->getPublicsStreamIndex());

154 Dbi->setGlobalsStreamIndex(Gsi->getGlobalsStreamIndex());

155 Dbi->setSymbolRecordStreamIndex(Gsi->getRecordStreamIndex());

156 }

157 }

158 if (Tpi) {

159 if (auto EC = Tpi->finalizeMsfLayout())

160 return EC;

161 }

162 if (Dbi) {

163 if (auto EC = Dbi->finalizeMsfLayout())

164 return EC;

165 }

166 SN = allocateNamedStream("/names", StringsLen);

167 if (!SN)

169

170 if (Ipi) {

171 if (auto EC = Ipi->finalizeMsfLayout())

172 return EC;

173 }

174

175

176

177 if (Info) {

178 if (auto EC = Info->finalizeMsfLayout())

179 return EC;

180 }

181

182 if (!InjectedSources.empty()) {

183 for (const auto &IS : InjectedSources) {

184 JamCRC CRC(0);

186

187 SrcHeaderBlockEntry Entry;

188 ::memset(&Entry, 0, sizeof(SrcHeaderBlockEntry));

189 Entry.Size = sizeof(SrcHeaderBlockEntry);

190 Entry.FileSize = IS.Content->getBufferSize();

191 Entry.FileNI = IS.NameIndex;

192 Entry.VFileNI = IS.VNameIndex;

194 Entry.IsVirtual = 0;

197 Entry.CRC = CRC.getCRC();

199 InjectedSourceTable.set_as(VName, std::move(Entry),

200 InjectedSourceHashTraits);

201 }

202

203 uint32_t SrcHeaderBlockSize =

204 sizeof(SrcHeaderBlockHeader) +

205 InjectedSourceTable.calculateSerializedLength();

206 SN = allocateNamedStream("/src/headerblock", SrcHeaderBlockSize);

207 if (!SN)

209 for (const auto &IS : InjectedSources) {

210 SN = allocateNamedStream(IS.StreamName, IS.Content->getBufferSize());

211 if (!SN)

213 }

214 }

215

216

217

218 if (Info) {

219 if (auto EC = Info->finalizeMsfLayout())

220 return EC;

221 }

222

224}

225

228 if (!NamedStreams.get(Name, SN))

230 return SN;

231}

232

236

239 Layout, MsfBuffer, SN, Allocator);

241

243 ::memset(&Header, 0, sizeof(Header));

245 Header.Size = Writer.bytesRemaining();

246

247 cantFail(Writer.writeObject(Header));

249

250 assert(Writer.bytesRemaining() == 0);

251}

252

255 if (InjectedSourceTable.empty())

256 return;

257

259 commitSrcHeaderBlock(MsfBuffer, Layout);

260

263

265 Layout, MsfBuffer, SN, Allocator);

267 assert(SourceWriter.bytesRemaining() == IS.Content->getBufferSize());

268 cantFail(SourceWriter.writeBytes(

270 }

271}

272

274 assert(!Filename.empty());

275 if (auto EC = finalizeMsfLayout())

276 return EC;

277

280 Msf->commit(Filename, Layout);

281 if (!ExpectedMsfBuffer)

282 return ExpectedMsfBuffer.takeError();

284

286 if (!ExpectedSN)

287 return ExpectedSN.takeError();

288

290 Layout, Buffer, *ExpectedSN, Allocator);

292 if (auto EC = Strings.commit(NSWriter))

293 return EC;

294

295 {

297 for (const auto &NSE : NamedStreamData) {

298 if (NSE.second.empty())

299 continue;

300

302 Layout, Buffer, NSE.first, Allocator);

305 return EC;

306 }

307 }

308

309 if (Info) {

310 if (auto EC = Info->commit(Layout, Buffer))

311 return EC;

312 }

313

314 if (Dbi) {

315 if (auto EC = Dbi->commit(Layout, Buffer))

316 return EC;

317 }

318

319 if (Tpi) {

320 if (auto EC = Tpi->commit(Layout, Buffer))

321 return EC;

322 }

323

324 if (Ipi) {

325 if (auto EC = Ipi->commit(Layout, Buffer))

326 return EC;

327 }

328

329 if (Gsi) {

330 if (auto EC = Gsi->commit(Layout, Buffer))

331 return EC;

332 }

333

335 assert(!InfoStreamBlocks.empty());

336 uint64_t InfoStreamFileOffset =

340

341 commitInjectedSources(Buffer, Layout);

342

343

344

345 if (Info->hashPDBContentsToGUID()) {

347

348

351

352 H->Age = 1;

353

354 memcpy(H->Guid.Guid, &Digest, 8);

355

356 memcpy(H->Guid.Guid + 8, "LLD PDB.", 8);

357

358

359 H->Signature = static_cast<uint32_t>(Digest);

360

361

362 memcpy(Guid, H->Guid.Guid, 16);

363 } else {

364 H->Age = Info->getAge();

365 H->Guid = Info->getGuid();

366 std::optional<uint32_t> Sig = Info->getSignature();

367 H->Signature = Sig ? *Sig : time(nullptr);

368 }

369

370 return Buffer.commit();

371}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

This file defines the SmallString class.

static const int BlockSize

Provides write only access to a subclass of WritableBinaryStream.

LLVM_ABI Error writeBytes(ArrayRef< uint8_t > Buffer)

Write the bytes specified in Buffer to the underlying stream.

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

Tagged union holding either a T or a Error.

Error takeError()

Take ownership of the stored error.

An implementation of WritableBinaryStream backed by an llvm FileOutputBuffer.

Error commit() override

For buffered streams, commits changes to the backing store.

uint8_t * getBufferEnd() const

Returns a pointer to the end of the buffer.

uint8_t * getBufferStart() const

Returns a pointer to the start of the buffer.

SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...

void push_back(const T &Elt)

StringRef - Represent a constant reference to a string, i.e.

The TimeTraceScope is a helper class to call the begin and end functions of the time trace profiler.

A BinaryStream which can be read from as well as written to.

static LLVM_ABI Expected< MSFBuilder > create(BumpPtrAllocator &Allocator, uint32_t BlockSize, uint32_t MinBlockCount=0, bool CanGrow=true)

Create a new MSFBuilder.

static std::unique_ptr< WritableMappedBlockStream > createIndexedStream(const MSFLayout &Layout, WritableBinaryStreamRef MsfData, uint32_t StreamIndex, BumpPtrAllocator &Allocator)

Error commit(BinaryStreamWriter &Writer) const

LLVM_ABI void set(StringRef Stream, uint32_t StreamNo)

LLVM_ABI TpiStreamBuilder & getTpiBuilder()

Definition PDBFileBuilder.cpp:70

LLVM_ABI msf::MSFBuilder & getMsfBuilder()

Definition PDBFileBuilder.cpp:56

LLVM_ABI PDBStringTableBuilder & getStringTableBuilder()

Definition PDBFileBuilder.cpp:82

LLVM_ABI Error addNamedStream(StringRef Name, StringRef Data)

Definition PDBFileBuilder.cpp:100

LLVM_ABI DbiStreamBuilder & getDbiBuilder()

Definition PDBFileBuilder.cpp:64

LLVM_ABI TpiStreamBuilder & getIpiBuilder()

Definition PDBFileBuilder.cpp:76

LLVM_ABI GSIStreamBuilder & getGsiBuilder()

Definition PDBFileBuilder.cpp:86

LLVM_ABI InfoStreamBuilder & getInfoBuilder()

Definition PDBFileBuilder.cpp:58

LLVM_ABI ~PDBFileBuilder()

LLVM_ABI Error initialize(uint32_t BlockSize)

Definition PDBFileBuilder.cpp:48

LLVM_ABI PDBFileBuilder(BumpPtrAllocator &Allocator)

Definition PDBFileBuilder.cpp:42

LLVM_ABI Error commit(StringRef Filename, codeview::GUID *Guid)

Definition PDBFileBuilder.cpp:273

LLVM_ABI void addInjectedSource(StringRef Name, std::unique_ptr< MemoryBuffer > Buffer)

Definition PDBFileBuilder.cpp:109

LLVM_ABI Expected< uint32_t > getNamedStreamIndex(StringRef Name) const

Definition PDBFileBuilder.cpp:226

LLVM_ABI uint32_t insert(StringRef S)

LLVM_ABI uint32_t calculateSerializedSize() const

LLVM_ABI StringRef getStringForId(uint32_t Id) const

uint64_t blockToOffset(uint64_t BlockNumber, uint64_t BlockSize)

This is an optimization pass for GlobalISel generic memory operations.

ArrayRef< CharT > arrayRefFromStringRef(StringRef Input)

Construct a string ref from an array ref of unsigned chars.

LLVM_ABI uint64_t xxh3_64bits(ArrayRef< uint8_t > data)

Error make_error(ArgTs &&... Args)

Make a Error instance representing failure using the given error info type.

void cantFail(Error Err, const char *Msg=nullptr)

Report a fatal error if Err is a failure value.

BumpPtrAllocatorImpl<> BumpPtrAllocator

The standard BumpPtrAllocator which just uses the default template parameters.

This represents the 'GUID' type from windows.h.

std::vector< ArrayRef< support::ulittle32_t > > StreamMap

support::ulittle32_t BlockSize