diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h --- a/lld/COFF/Config.h +++ b/lld/COFF/Config.h @@ -124,6 +124,7 @@ std::vector natvisFiles; llvm::StringMap namedStreams; llvm::SmallString<128> pdbAltPath; + int pdbPageSize = 4096; llvm::SmallString<128> pdbPath; llvm::SmallString<128> pdbSourcePath; std::vector argv; diff --git a/lld/COFF/Driver.h b/lld/COFF/Driver.h --- a/lld/COFF/Driver.h +++ b/lld/COFF/Driver.h @@ -176,6 +176,7 @@ void parseAlternateName(StringRef); void parseMerge(StringRef); +void parsePDBPageSize(StringRef); void parseSection(StringRef); void parseAligncomm(StringRef); diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -1428,6 +1428,8 @@ config->pdbPath = arg->getValue(); if (auto *arg = args.getLastArg(OPT_pdbaltpath)) config->pdbAltPath = arg->getValue(); + if (auto *arg = args.getLastArg(OPT_pdbpagesize)) + parsePDBPageSize(arg->getValue()); if (args.hasArg(OPT_natvis)) config->natvisFiles = args.getAllArgValues(OPT_natvis); if (args.hasArg(OPT_pdbstream)) { diff --git a/lld/COFF/DriverUtils.cpp b/lld/COFF/DriverUtils.cpp --- a/lld/COFF/DriverUtils.cpp +++ b/lld/COFF/DriverUtils.cpp @@ -175,6 +175,26 @@ } } +void parsePDBPageSize(StringRef s) { + int v; + if (s.getAsInteger(0, v)) { + error("/pdbpagesize: invalid argument: " + s); + return; + } + if (v != 4096 && v != 8192 && v != 16384 && v != 32768) { + error("/pdbpagesize: invalid argument: " + s); + return; + } + + // FIXME: Remove this once other page sizes work. + if (v != 4096) { + warn("/pdbpagesize: page sizes != 4096 not yet implemented, ignoring flag"); + v = 4096; + } + + config->pdbPageSize = v; +} + static uint32_t parseSectionAttributes(StringRef s) { uint32_t ret = 0; for (char c : s.lower()) { diff --git a/lld/COFF/Options.td b/lld/COFF/Options.td --- a/lld/COFF/Options.td +++ b/lld/COFF/Options.td @@ -78,8 +78,9 @@ def out : P<"out", "Path to file to write output">; def natvis : P<"natvis", "Path to natvis file to embed in the PDB">; def pdb : P<"pdb", "PDB file path">; -def pdbstripped : P<"pdbstripped", "Stripped PDB file path">; def pdbaltpath : P<"pdbaltpath", "PDB file path to embed in the image">; +def pdbpagesize : P<"pdbpagesize", "PDB page size">; +def pdbstripped : P<"pdbstripped", "Stripped PDB file path">; def pdbstream : Joined<["/", "-", "/?", "-?"], "pdbstream:">, MetaVarName<"=">, HelpText<"Embed the contents of in the PDB as named stream ">; diff --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp --- a/lld/COFF/PDB.cpp +++ b/lld/COFF/PDB.cpp @@ -1588,7 +1588,7 @@ } void PDBLinker::initialize(llvm::codeview::DebugInfo *buildId) { - exitOnErr(builder.initialize(4096)); // 4096 is blocksize + exitOnErr(builder.initialize(config->pdbPageSize)); buildId->Signature.CVSignature = OMF::Signature::PDB70; // Signature is set to a hash of the PDB contents when the PDB is done. diff --git a/lld/test/COFF/pdbpagesize.test b/lld/test/COFF/pdbpagesize.test new file mode 100644 --- /dev/null +++ b/lld/test/COFF/pdbpagesize.test @@ -0,0 +1,15 @@ +# RUN: yaml2obj %p/Inputs/empty.yaml -o %t.obj + +# RUN: not lld-link /entry:main %t.obj /out:%t.exe /debug /pdbpagesize:hi 2>&1 \ +# RUN: | FileCheck --check-prefix=INVALID %s +# RUN: not lld-link /entry:main %t.obj /out:%t.exe /debug /pdbpagesize:15 2>&1 \ +# RUN: | FileCheck --check-prefix=INVALID %s +# INVALID: error: /pdbpagesize: invalid argument: + +# RUN: lld-link /entry:main %t.obj /out:%t.exe /debug /pdbpagesize:4096 +# RUN: llvm-pdbutil pdb2yaml %t.pdb | FileCheck --check-prefix=PAGE4096 %s +# PAGE4096: BlockSize: 4096 + +# RUN: lld-link /entry:main %t.obj /out:%t.exe /debug /pdbpagesize:8192 2>&1 \ +# RUN: | FileCheck --check-prefix=TODO %s +# TODO: warning: /pdbpagesize: page sizes != 4096 not yet implemented, ignoring flag diff --git a/llvm/include/llvm/DebugInfo/MSF/MSFCommon.h b/llvm/include/llvm/DebugInfo/MSF/MSFCommon.h --- a/llvm/include/llvm/DebugInfo/MSF/MSFCommon.h +++ b/llvm/include/llvm/DebugInfo/MSF/MSFCommon.h @@ -93,6 +93,9 @@ case 1024: case 2048: case 4096: + case 8192: + case 16384: + case 32768: return true; } return false;