[ms] Add new /PDBSTREAM option to lld-link allowing injection of streams into PDB files.
Summary: /PDBSTREAM:<name>=<file> adds the contents of <file> to stream <name> 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:<PDB LOCATION> -s:<name> -i:<file> 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
This commit is contained in:
parent
3fefda6e57
commit
a39b14f0b4
|
|
@ -110,6 +110,7 @@ struct Configuration {
|
||||||
bool showSummary = false;
|
bool showSummary = false;
|
||||||
unsigned debugTypes = static_cast<unsigned>(DebugType::None);
|
unsigned debugTypes = static_cast<unsigned>(DebugType::None);
|
||||||
std::vector<std::string> natvisFiles;
|
std::vector<std::string> natvisFiles;
|
||||||
|
llvm::StringMap<std::string> namedStreams;
|
||||||
llvm::SmallString<128> pdbAltPath;
|
llvm::SmallString<128> pdbAltPath;
|
||||||
llvm::SmallString<128> pdbPath;
|
llvm::SmallString<128> pdbPath;
|
||||||
llvm::SmallString<128> pdbSourcePath;
|
llvm::SmallString<128> pdbSourcePath;
|
||||||
|
|
|
||||||
|
|
@ -1273,6 +1273,14 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr) {
|
||||||
config->pdbAltPath = arg->getValue();
|
config->pdbAltPath = arg->getValue();
|
||||||
if (args.hasArg(OPT_natvis))
|
if (args.hasArg(OPT_natvis))
|
||||||
config->natvisFiles = args.getAllArgValues(OPT_natvis);
|
config->natvisFiles = args.getAllArgValues(OPT_natvis);
|
||||||
|
if (args.hasArg(OPT_pdbstream)) {
|
||||||
|
for (const StringRef value : args.getAllArgValues(OPT_pdbstream)) {
|
||||||
|
const std::pair<StringRef, StringRef> 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))
|
if (auto *arg = args.getLastArg(OPT_pdb_source_path))
|
||||||
config->pdbSourcePath = arg->getValue();
|
config->pdbSourcePath = arg->getValue();
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,9 @@ def no_color_diagnostics: F<"no-color-diagnostics">,
|
||||||
def pdb : P<"pdb", "PDB file path">;
|
def pdb : P<"pdb", "PDB file path">;
|
||||||
def pdbstripped : P<"pdbstripped", "Stripped PDB file path">;
|
def pdbstripped : P<"pdbstripped", "Stripped PDB file path">;
|
||||||
def pdbaltpath : P<"pdbaltpath", "PDB file path to embed in the image">;
|
def pdbaltpath : P<"pdbaltpath", "PDB file path to embed in the image">;
|
||||||
|
def pdbstream : Joined<["/", "-", "/?", "-?"], "pdbstream:">,
|
||||||
|
MetaVarName<"<name>=<file>">,
|
||||||
|
HelpText<"Embed the contents of <file> in the PDB as named stream <name>">;
|
||||||
def section : P<"section", "Specify section attributes">;
|
def section : P<"section", "Specify section attributes">;
|
||||||
def stack : P<"stack", "Size of the stack">;
|
def stack : P<"stack", "Size of the stack">;
|
||||||
def stub : P<"stub", "Specify DOS stub file">;
|
def stub : P<"stub", "Specify DOS stub file">;
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,9 @@ public:
|
||||||
/// Add natvis files specified on the command line.
|
/// Add natvis files specified on the command line.
|
||||||
void addNatvisFiles();
|
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.
|
/// Link CodeView from each object file in the symbol table into the PDB.
|
||||||
void addObjectsToPDB();
|
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<std::unique_ptr<MemoryBuffer>> 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) {
|
static codeview::CPUType toCodeViewMachine(COFF::MachineTypes machine) {
|
||||||
switch (machine) {
|
switch (machine) {
|
||||||
case COFF::IMAGE_FILE_MACHINE_AMD64:
|
case COFF::IMAGE_FILE_MACHINE_AMD64:
|
||||||
|
|
@ -1692,6 +1708,7 @@ void lld::coff::createPDB(SymbolTable *symtab,
|
||||||
pdb.addImportFilesToPDB(outputSections);
|
pdb.addImportFilesToPDB(outputSections);
|
||||||
pdb.addSections(outputSections, sectionTable);
|
pdb.addSections(outputSections, sectionTable);
|
||||||
pdb.addNatvisFiles();
|
pdb.addNatvisFiles();
|
||||||
|
pdb.addNamedStreams();
|
||||||
|
|
||||||
ScopedTimer t2(diskCommitTimer);
|
ScopedTimer t2(diskCommitTimer);
|
||||||
codeview::GUID guid;
|
codeview::GUID guid;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
Stream contents
|
||||||
|
Line 2
|
||||||
|
Line 3
|
||||||
|
|
@ -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
|
||||||
Loading…
Reference in New Issue