xref: /llvm-project-15.0.7/lld/COFF/PDB.cpp (revision 2de44e65)
1 //===- PDB.cpp ------------------------------------------------------------===//
2 //
3 //                             The LLVM Linker
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "Driver.h"
11 #include "Error.h"
12 #include "Symbols.h"
13 #include "llvm/Support/Endian.h"
14 #include "llvm/Support/FileOutputBuffer.h"
15 #include <memory>
16 
17 using namespace llvm;
18 using namespace llvm::support;
19 using namespace llvm::support::endian;
20 
21 const int PageSize = 4096;
22 const uint8_t Magic[32] = "Microsoft C/C++ MSF 7.00\r\n\032DS\0\0";
23 
24 namespace {
25 struct PDBHeader {
26   uint8_t Magic[32];
27   ulittle32_t PageSize;
28   ulittle32_t FpmPage;
29   ulittle32_t PageCount;
30   ulittle32_t RootSize;
31   ulittle32_t Reserved;
32   ulittle32_t RootPointer;
33 };
34 }
35 
36 void lld::coff::createPDB(StringRef Path) {
37   // Create a file.
38   size_t FileSize = PageSize * 3;
39   ErrorOr<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
40       FileOutputBuffer::create(Path, FileSize);
41   error(BufferOrErr, Twine("failed to open ") + Path);
42   std::unique_ptr<FileOutputBuffer> Buffer = std::move(*BufferOrErr);
43 
44   // Write the file header.
45   uint8_t *Buf = Buffer->getBufferStart();
46   auto *Hdr = reinterpret_cast<PDBHeader *>(Buf);
47   memcpy(Hdr->Magic, Magic, sizeof(Magic));
48   Hdr->PageSize = PageSize;
49   // I don't know what FpmPage field means, but it must not be 0.
50   Hdr->FpmPage = 1;
51   Hdr->PageCount = FileSize / PageSize;
52   // Root directory is empty, containing only the length field.
53   Hdr->RootSize = 4;
54   // Root directory is on page 1.
55   Hdr->RootPointer = 1;
56 
57   // Write the root directory. Root stream is on page 2.
58   write32le(Buf + PageSize, 2);
59   Buffer->commit();
60 }
61