blob: 9445dcb69380f63071e21bc2fe89549ff9962661 [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
Rui Ueyama1d99ab32016-09-15 22:24:51 +000010#include "PDB.h"
Rui Ueyamae7378242015-12-04 23:11:05 +000011#include "Error.h"
Rui Ueyama7f382992016-09-15 18:55:18 +000012#include "llvm/DebugInfo/MSF/MSFCommon.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
Rui Ueyama1d99ab32016-09-15 22:24:51 +000017using namespace lld;
Rui Ueyamae7378242015-12-04 23:11:05 +000018using namespace llvm;
Rui Ueyama1763c0d2015-12-08 18:39:55 +000019using namespace llvm::support;
20using namespace llvm::support::endian;
Rui Ueyamae7378242015-12-04 23:11:05 +000021
Rui Ueyama7f382992016-09-15 18:55:18 +000022const int BlockSize = 4096;
Rui Ueyama1763c0d2015-12-08 18:39:55 +000023
Rui Ueyama1d99ab32016-09-15 22:24:51 +000024void coff::createPDB(StringRef Path) {
Rui Ueyamae7378242015-12-04 23:11:05 +000025 // Create a file.
Rui Ueyama7f382992016-09-15 18:55:18 +000026 size_t FileSize = BlockSize * 3;
Rui Ueyama1763c0d2015-12-08 18:39:55 +000027 ErrorOr<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
Rui Ueyamae7378242015-12-04 23:11:05 +000028 FileOutputBuffer::create(Path, FileSize);
Rui Ueyama0d09a862016-07-15 00:40:46 +000029 if (auto EC = BufferOrErr.getError())
30 fatal(EC, "failed to open " + Path);
Rui Ueyama1763c0d2015-12-08 18:39:55 +000031 std::unique_ptr<FileOutputBuffer> Buffer = std::move(*BufferOrErr);
Rui Ueyamae7378242015-12-04 23:11:05 +000032
Rui Ueyama1763c0d2015-12-08 18:39:55 +000033 // Write the file header.
34 uint8_t *Buf = Buffer->getBufferStart();
Rui Ueyama7f382992016-09-15 18:55:18 +000035 auto *SB = reinterpret_cast<msf::SuperBlock *>(Buf);
36 memcpy(SB->MagicBytes, msf::Magic, sizeof(msf::Magic));
37 SB->BlockSize = BlockSize;
38
39 // FreeBlockMap is a page number containing free page map bitmap.
40 // Set a dummy value for now.
41 SB->FreeBlockMapBlock = 1;
42
43 SB->NumBlocks = FileSize / BlockSize;
44
Rui Ueyama1763c0d2015-12-08 18:39:55 +000045 // Root directory is empty, containing only the length field.
Rui Ueyama7f382992016-09-15 18:55:18 +000046 SB->NumDirectoryBytes = 4;
47
Rui Ueyama1763c0d2015-12-08 18:39:55 +000048 // Root directory is on page 1.
Rui Ueyama7f382992016-09-15 18:55:18 +000049 SB->BlockMapAddr = 1;
Rui Ueyama1763c0d2015-12-08 18:39:55 +000050
51 // Write the root directory. Root stream is on page 2.
Rui Ueyama7f382992016-09-15 18:55:18 +000052 write32le(Buf + BlockSize, 2);
Rui Ueyama1763c0d2015-12-08 18:39:55 +000053 Buffer->commit();
Rui Ueyamae7378242015-12-04 23:11:05 +000054}