PDB.cpp revision 305067
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
17using namespace llvm;
18using namespace llvm::support;
19using namespace llvm::support::endian;
20
21const int PageSize = 4096;
22const uint8_t Magic[32] = "Microsoft C/C++ MSF 7.00\r\n\032DS\0\0";
23
24namespace {
25struct 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
36void 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  if (auto EC = BufferOrErr.getError())
42    fatal(EC, "failed to open " + Path);
43  std::unique_ptr<FileOutputBuffer> Buffer = std::move(*BufferOrErr);
44
45  // Write the file header.
46  uint8_t *Buf = Buffer->getBufferStart();
47  auto *Hdr = reinterpret_cast<PDBHeader *>(Buf);
48  memcpy(Hdr->Magic, Magic, sizeof(Magic));
49  Hdr->PageSize = PageSize;
50  // I don't know what FpmPage field means, but it must not be 0.
51  Hdr->FpmPage = 1;
52  Hdr->PageCount = FileSize / PageSize;
53  // Root directory is empty, containing only the length field.
54  Hdr->RootSize = 4;
55  // Root directory is on page 1.
56  Hdr->RootPointer = 1;
57
58  // Write the root directory. Root stream is on page 2.
59  write32le(Buf + PageSize, 2);
60  Buffer->commit();
61}
62