blob: 023e03cc9d594fb803c870da55b9f92afe88a8bd [file] [log] [blame]
Rui Ueyamae7378242015-12-04 23:11:05 +00001//===- 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"
Rui Ueyama1763c0d2015-12-08 18:39:55 +000013#include "llvm/Support/Endian.h"
Rui Ueyamae7378242015-12-04 23:11:05 +000014#include "llvm/Support/FileOutputBuffer.h"
15#include <memory>
16
17using namespace llvm;
Rui Ueyama1763c0d2015-12-08 18:39:55 +000018using namespace llvm::support;
19using namespace llvm::support::endian;
Rui Ueyamae7378242015-12-04 23:11:05 +000020
21const int PageSize = 4096;
22const uint8_t Magic[32] = "Microsoft C/C++ MSF 7.00\r\n\032DS\0\0";
23
Rui Ueyama1763c0d2015-12-08 18:39:55 +000024namespace {
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
Rui Ueyamae7378242015-12-04 23:11:05 +000036void lld::coff::createPDB(StringRef Path) {
37 // Create a file.
38 size_t FileSize = PageSize * 3;
Rui Ueyama1763c0d2015-12-08 18:39:55 +000039 ErrorOr<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
Rui Ueyamae7378242015-12-04 23:11:05 +000040 FileOutputBuffer::create(Path, FileSize);
Rui Ueyama1a3fd132016-07-14 23:43:36 +000041 check(BufferOrErr, "failed to open " + Path);
Rui Ueyama1763c0d2015-12-08 18:39:55 +000042 std::unique_ptr<FileOutputBuffer> Buffer = std::move(*BufferOrErr);
Rui Ueyamae7378242015-12-04 23:11:05 +000043
Rui Ueyama1763c0d2015-12-08 18:39:55 +000044 // 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();
Rui Ueyamae7378242015-12-04 23:11:05 +000060}