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