blob: 7606ccc680d383ba59fa144ed834a278d02b1eb0 [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 Ueyama0d09a862016-07-15 00:40:46 +000041 if (auto EC = BufferOrErr.getError())
42 fatal(EC, "failed to open " + Path);
Rui Ueyama1763c0d2015-12-08 18:39:55 +000043 std::unique_ptr<FileOutputBuffer> Buffer = std::move(*BufferOrErr);
Rui Ueyamae7378242015-12-04 23:11:05 +000044
Rui Ueyama1763c0d2015-12-08 18:39:55 +000045 // 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();
Rui Ueyamae7378242015-12-04 23:11:05 +000061}