COFF: Create an empty but valid PDF file.
authorRui Ueyama <ruiu@google.com>
Tue, 8 Dec 2015 18:39:55 +0000 (18:39 +0000)
committerRui Ueyama <ruiu@google.com>
Tue, 8 Dec 2015 18:39:55 +0000 (18:39 +0000)
MSVC linker considers PDB files created with this patch valid.
So you don't have to remove PDB files created by lld before
running MSVC linker.

This patch has no test since llvm-pdbdump dislikes PDB files
with no metadata streams.

llvm-svn: 255039

lld/COFF/PDB.cpp

index 62f9ba4..786d287 100644 (file)
 #include "Driver.h"
 #include "Error.h"
 #include "Symbols.h"
+#include "llvm/Support/Endian.h"
 #include "llvm/Support/FileOutputBuffer.h"
 #include <memory>
 
 using namespace llvm;
+using namespace llvm::support;
+using namespace llvm::support::endian;
 
 const int PageSize = 4096;
 const uint8_t Magic[32] = "Microsoft C/C++ MSF 7.00\r\n\032DS\0\0";
 
+namespace {
+struct PDBHeader {
+  uint8_t Magic[32];
+  ulittle32_t PageSize;
+  ulittle32_t FpmPage;
+  ulittle32_t PageCount;
+  ulittle32_t RootSize;
+  ulittle32_t Reserved;
+  ulittle32_t RootPointer;
+};
+}
+
 void lld::coff::createPDB(StringRef Path) {
   // Create a file.
   size_t FileSize = PageSize * 3;
-  ErrorOr<std::unique_ptr<FileOutputBuffer>> BufOrErr =
+  ErrorOr<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
       FileOutputBuffer::create(Path, FileSize);
-  error(BufOrErr, Twine("failed to open ") + Path);
-  std::unique_ptr<FileOutputBuffer> Buf = std::move(*BufOrErr);
+  error(BufferOrErr, Twine("failed to open ") + Path);
+  std::unique_ptr<FileOutputBuffer> Buffer = std::move(*BufferOrErr);
+
+  // Write the file header.
+  uint8_t *Buf = Buffer->getBufferStart();
+  auto *Hdr = reinterpret_cast<PDBHeader *>(Buf);
+  memcpy(Hdr->Magic, Magic, sizeof(Magic));
+  Hdr->PageSize = PageSize;
+  // I don't know what FpmPage field means, but it must not be 0.
+  Hdr->FpmPage = 1;
+  Hdr->PageCount = FileSize / PageSize;
+  // Root directory is empty, containing only the length field.
+  Hdr->RootSize = 4;
+  // Root directory is on page 1.
+  Hdr->RootPointer = 1;
 
-  // Write the file magic.
-  uint8_t *P = Buf->getBufferStart();
-  memcpy(P, Magic, sizeof(Magic));
+  // Write the root directory. Root stream is on page 2.
+  write32le(Buf + PageSize, 2);
+  Buffer->commit();
 }