From a39b14f0b42d6bd835dec448506660d77bbbb7c7 Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Tue, 7 Apr 2020 16:16:22 -0400 Subject: [PATCH] [ms] Add new /PDBSTREAM option to lld-link allowing injection of streams into PDB files. Summary: /PDBSTREAM:= adds the contents of to stream in the resulting PDB. This allows native uses with workflows that (for example) add srcsrv streams to PDB files to provide a location for the build's source files. Results should be equivalent to linking with lld-link, then running Microsoft's pdbstr tool with the command line: pdbstr.exe -w -p: -s: -i: except in cases where the named stream overlaps with a default named stream, such as "/names". In those cases, the added stream will be overridden, making the /pdbstream option a no-op. Reviewers: thakis, rnk Reviewed By: thakis Differential Revision: https://reviews.llvm.org/D77310 --- lld/COFF/Config.h | 1 + lld/COFF/Driver.cpp | 8 ++++++++ lld/COFF/Options.td | 3 +++ lld/COFF/PDB.cpp | 17 +++++++++++++++++ lld/test/COFF/Inputs/stream.txt | 3 +++ lld/test/COFF/pdbstream.test | 8 ++++++++ 6 files changed, 40 insertions(+) create mode 100644 lld/test/COFF/Inputs/stream.txt create mode 100644 lld/test/COFF/pdbstream.test diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h index 93b732e..4d7d9e2 100644 --- a/lld/COFF/Config.h +++ b/lld/COFF/Config.h @@ -110,6 +110,7 @@ struct Configuration { bool showSummary = false; unsigned debugTypes = static_cast(DebugType::None); std::vector natvisFiles; + llvm::StringMap namedStreams; llvm::SmallString<128> pdbAltPath; llvm::SmallString<128> pdbPath; llvm::SmallString<128> pdbSourcePath; diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index 931b8cf..08415fa 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -1273,6 +1273,14 @@ void LinkerDriver::link(ArrayRef argsArr) { config->pdbAltPath = arg->getValue(); if (args.hasArg(OPT_natvis)) config->natvisFiles = args.getAllArgValues(OPT_natvis); + if (args.hasArg(OPT_pdbstream)) { + for (const StringRef value : args.getAllArgValues(OPT_pdbstream)) { + const std::pair nameFile = value.split("="); + const StringRef name = nameFile.first; + const std::string file = nameFile.second.str(); + config->namedStreams[name] = file; + } + } if (auto *arg = args.getLastArg(OPT_pdb_source_path)) config->pdbSourcePath = arg->getValue(); diff --git a/lld/COFF/Options.td b/lld/COFF/Options.td index f8fe6f9..a6181e2 100644 --- a/lld/COFF/Options.td +++ b/lld/COFF/Options.td @@ -66,6 +66,9 @@ def no_color_diagnostics: F<"no-color-diagnostics">, 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 pdbstream : Joined<["/", "-", "/?", "-?"], "pdbstream:">, + MetaVarName<"=">, + HelpText<"Embed the contents of in the PDB as named stream ">; def section : P<"section", "Specify section attributes">; def stack : P<"stack", "Size of the stack">; def stub : P<"stub", "Specify DOS stub file">; diff --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp index 8ecfdca..a182ed3 100644 --- a/lld/COFF/PDB.cpp +++ b/lld/COFF/PDB.cpp @@ -100,6 +100,9 @@ public: /// Add natvis files specified on the command line. void addNatvisFiles(); + /// Add named streams specified on the command line. + void addNamedStreams(); + /// Link CodeView from each object file in the symbol table into the PDB. void addObjectsToPDB(); @@ -1437,6 +1440,19 @@ void PDBLinker::addNatvisFiles() { } } +void PDBLinker::addNamedStreams() { + for (const auto &streamFile : config->namedStreams) { + const StringRef stream = streamFile.getKey(), file = streamFile.getValue(); + ErrorOr> dataOrErr = + MemoryBuffer::getFile(file); + if (!dataOrErr) { + warn("Cannot open input file: " + file); + continue; + } + exitOnErr(builder.addNamedStream(stream, (*dataOrErr)->getBuffer())); + } +} + static codeview::CPUType toCodeViewMachine(COFF::MachineTypes machine) { switch (machine) { case COFF::IMAGE_FILE_MACHINE_AMD64: @@ -1692,6 +1708,7 @@ void lld::coff::createPDB(SymbolTable *symtab, pdb.addImportFilesToPDB(outputSections); pdb.addSections(outputSections, sectionTable); pdb.addNatvisFiles(); + pdb.addNamedStreams(); ScopedTimer t2(diskCommitTimer); codeview::GUID guid; diff --git a/lld/test/COFF/Inputs/stream.txt b/lld/test/COFF/Inputs/stream.txt new file mode 100644 index 0000000..6d35deb --- /dev/null +++ b/lld/test/COFF/Inputs/stream.txt @@ -0,0 +1,3 @@ +Stream contents +Line 2 +Line 3 diff --git a/lld/test/COFF/pdbstream.test b/lld/test/COFF/pdbstream.test new file mode 100644 index 0000000..a44f548 --- /dev/null +++ b/lld/test/COFF/pdbstream.test @@ -0,0 +1,8 @@ +# RUN: yaml2obj %p/Inputs/empty.yaml > %t.obj + +# RUN: lld-link /entry:main %t.obj /out:%t.exe /debug /pdbstream:srcsrv=%p/Inputs/stream.txt +# RUN: llvm-pdbutil export -stream=srcsrv -out=- %t.pdb | FileCheck %s + +CHECK: Stream contents +CHECK-NEXT: Line 2 +CHECK-NEXT: Line 3 -- 2.7.4