forked from OSchip/llvm-project
lld-link: Implement support for %_PDB% and %_EXT% for /pdbaltpath:.
Warn that references to regular env vars are ignored. Fixes PR38940. Differential Revision: https://reviews.llvm.org/D52942 llvm-svn: 344003
This commit is contained in:
parent
0f556f88c5
commit
9d7524160a
|
@ -830,6 +830,57 @@ static void findKeepUniqueSections() {
|
|||
}
|
||||
}
|
||||
|
||||
// link.exe replaces each %foo% in AltPath with the contents of environment
|
||||
// variable foo, and adds the two magic env vars _PDB (expands to the basename
|
||||
// of pdb's output path) and _EXT (expands to the extension of the output
|
||||
// binary).
|
||||
// lld only supports %_PDB% and %_EXT% and warns on references to all other env
|
||||
// vars.
|
||||
static void parsePDBAltPath(StringRef AltPath) {
|
||||
SmallString<128> Buf;
|
||||
StringRef PDBBasename =
|
||||
sys::path::filename(Config->PDBPath, sys::path::Style::windows);
|
||||
StringRef BinaryExtension =
|
||||
sys::path::extension(Config->OutputFile, sys::path::Style::windows);
|
||||
if (!BinaryExtension.empty())
|
||||
BinaryExtension = BinaryExtension.substr(1); // %_EXT% does not include '.'.
|
||||
|
||||
// Invariant:
|
||||
// +--------- Cursor ('a...' might be the empty string).
|
||||
// | +----- FirstMark
|
||||
// | | +- SecondMark
|
||||
// v v v
|
||||
// a...%...%...
|
||||
size_t Cursor = 0;
|
||||
while (Cursor < AltPath.size()) {
|
||||
size_t FirstMark, SecondMark;
|
||||
if ((FirstMark = AltPath.find('%', Cursor)) == StringRef::npos ||
|
||||
(SecondMark = AltPath.find('%', FirstMark + 1)) == StringRef::npos) {
|
||||
// Didn't find another full fragment, treat rest of string as literal.
|
||||
Buf.append(AltPath.substr(Cursor));
|
||||
break;
|
||||
}
|
||||
|
||||
// Found a full fragment. Append text in front of first %, and interpret
|
||||
// text between first and second % as variable name.
|
||||
Buf.append(AltPath.substr(Cursor, FirstMark - Cursor));
|
||||
StringRef Var = AltPath.substr(FirstMark, SecondMark - FirstMark + 1);
|
||||
if (Var.equals_lower("%_pdb%"))
|
||||
Buf.append(PDBBasename);
|
||||
else if (Var.equals_lower("%_ext%"))
|
||||
Buf.append(BinaryExtension);
|
||||
else {
|
||||
warn("only %_PDB% and %_EXT% supported in /pdbaltpath:, keeping " +
|
||||
Var + " as literal");
|
||||
Buf.append(Var);
|
||||
}
|
||||
|
||||
Cursor = SecondMark + 1;
|
||||
}
|
||||
|
||||
Config->PDBAltPath = Buf;
|
||||
}
|
||||
|
||||
void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
|
||||
// If the first command line argument is "/lib", link.exe acts like lib.exe.
|
||||
// We call our own implementation of lib.exe that understands bitcode files.
|
||||
|
@ -1411,6 +1462,9 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
|
|||
// tools won't work correctly if these assumptions are not held.
|
||||
sys::fs::make_absolute(Config->PDBAltPath);
|
||||
sys::path::remove_dots(Config->PDBAltPath);
|
||||
} else {
|
||||
// Don't do this earlier, so that Config->OutputFile is ready.
|
||||
parsePDBAltPath(Config->PDBAltPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
--- !COFF
|
||||
header:
|
||||
Machine: IMAGE_FILE_MACHINE_I386
|
||||
Characteristics: [ ]
|
||||
sections:
|
||||
- Name: .text
|
||||
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 4
|
||||
SectionData: 31C0C3
|
||||
- Name: .data
|
||||
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
|
||||
Alignment: 4
|
||||
SectionData: ''
|
||||
- Name: .bss
|
||||
Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
|
||||
Alignment: 4
|
||||
SectionData: ''
|
||||
symbols:
|
||||
- Name: .text
|
||||
Value: 0
|
||||
SectionNumber: 1
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 3
|
||||
NumberOfRelocations: 0
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 3963538403
|
||||
Number: 1
|
||||
- Name: .data
|
||||
Value: 0
|
||||
SectionNumber: 2
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 0
|
||||
NumberOfRelocations: 0
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 0
|
||||
Number: 2
|
||||
- Name: .bss
|
||||
Value: 0
|
||||
SectionNumber: 3
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 0
|
||||
NumberOfRelocations: 0
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 0
|
||||
Number: 3
|
||||
- Name: '@feat.00'
|
||||
Value: 1
|
||||
SectionNumber: -1
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
- Name: _main
|
||||
Value: 0
|
||||
SectionNumber: 1
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
...
|
|
@ -0,0 +1,39 @@
|
|||
# RUN: yaml2obj %p/Inputs/empty.yaml > %t.obj
|
||||
|
||||
# RUN: lld-link /entry:main %t.obj /out:%t.exe /debug /pdbaltpath:hello.pdb
|
||||
# RUN: llvm-readobj -coff-debug-directory %t.exe | FileCheck --check-prefix HELLO %s
|
||||
# HELLO: PDBFileName: hello.pdb
|
||||
|
||||
# RUN: lld-link /entry:main %t.obj /out:%t.exe /debug /pdbaltpath:%_Pdb%
|
||||
# RUN: llvm-readobj -coff-debug-directory %t.exe | FileCheck --check-prefix PDBVAR %s
|
||||
# PDBVAR: PDBFileName: pdbaltpath.test.tmp.pdb
|
||||
|
||||
# RUN: lld-link /entry:main %t.obj /out:%t.exe /debug /pdbaltpath:foo%_ExT%.pdb
|
||||
# RUN: llvm-readobj -coff-debug-directory %t.exe | FileCheck --check-prefix EXTVAR %s
|
||||
# EXTVAR: PDBFileName: fooexe.pdb
|
||||
|
||||
# RUN: lld-link /entry:main %t.obj /out:%t.exe /debug /pdbaltpath:%_PDB
|
||||
# RUN: llvm-readobj -coff-debug-directory %t.exe | FileCheck --check-prefix NOCLOSE %s
|
||||
# NOCLOSE: PDBFileName: %_PDB
|
||||
|
||||
# RUN: lld-link /entry:main %t.obj /out:%t.exe /debug /pdbaltpath:foo%_PDB
|
||||
# RUN: llvm-readobj -coff-debug-directory %t.exe | FileCheck --check-prefix NOCLOSE2 %s
|
||||
# NOCLOSE2: PDBFileName: foo%_PDB
|
||||
|
||||
# RUN: lld-link /entry:main %t.obj /out:%t.exe /debug /pdbaltpath:foo%_PDB%bar%_EXT
|
||||
# RUN: llvm-readobj -coff-debug-directory %t.exe | FileCheck --check-prefix CLOSEONE %s
|
||||
# CLOSEONE: PDBFileName: foopdbaltpath.test.tmp.pdbbar%_EXT
|
||||
|
||||
# RUN: lld-link /entry:main %t.obj /out:%t.exe /debug /pdbaltpath:foo%_PDB%bar%_EXT%
|
||||
# RUN: llvm-readobj -coff-debug-directory %t.exe | FileCheck --check-prefix CLOSETWO %s
|
||||
# CLOSETWO: PDBFileName: foopdbaltpath.test.tmp.pdbbarexe
|
||||
|
||||
# RUN: lld-link /entry:main %t.obj /out:%t.exe /debug /pdbaltpath:foo%_PDB%bar%_EXT%a
|
||||
# RUN: llvm-readobj -coff-debug-directory %t.exe | FileCheck --check-prefix CLOSETWO2 %s
|
||||
# CLOSETWO2: PDBFileName: foopdbaltpath.test.tmp.pdbbarexea
|
||||
|
||||
# RUN: lld-link /entry:main %t.obj /out:%t.exe /debug /pdbaltpath:foo%FoO%bar%r%a 2>&1 | FileCheck --check-prefix UNKNOWN-WARN %s
|
||||
# RUN: llvm-readobj -coff-debug-directory %t.exe | FileCheck --check-prefix ENVVARS %s
|
||||
# UNKNOWN-WARN: only %_PDB% and %_EXT% supported in /pdbaltpath:, keeping %FoO% as literal
|
||||
# UNKNOWN-WARN: only %_PDB% and %_EXT% supported in /pdbaltpath:, keeping %r% as literal
|
||||
# ENVVARS: PDBFileName: foo%FoO%bar%r%a
|
Loading…
Reference in New Issue