Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lld/COFF/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ struct Configuration {
bool largeAddressAware = false;
bool highEntropyVA = false;
bool appContainer = false;
bool mergeDebugDirectory = true;
bool mingw = false;
bool warnMissingOrderSymbol = true;
bool warnLocallyDefinedImported = true;
Expand Down
3 changes: 3 additions & 0 deletions lld/COFF/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2338,6 +2338,9 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
config->is64() &&
args.hasFlag(OPT_highentropyva, OPT_highentropyva_no, true);

// Handle /nodbgdirmerge
config->mergeDebugDirectory = !args.hasArg(OPT_nodbgdirmerge);

if (!config->dynamicBase &&
(config->machine == ARMNT || isAnyArm64(config->machine)))
Err(ctx) << "/dynamicbase:no is not compatible with "
Expand Down
2 changes: 2 additions & 0 deletions lld/COFF/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ def machine : P<"machine", "Specify target platform">;
def merge : P<"merge", "Combine sections">;
def mllvm : P<"mllvm", "Options to pass to LLVM">;
def nodefaultlib : P<"nodefaultlib", "Remove a default library">;
def nodbgdirmerge : F<"nodbgdirmerge">,
HelpText<"Emit the debug directory in a separate section">;
def opt : P<"opt", "Control optimizations">;
def order : P<"order", "Put functions in order">;
def out : P<"out", "Path to file to write output">;
Expand Down
10 changes: 9 additions & 1 deletion lld/COFF/Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ class Writer {
OutputSection *bssSec;
OutputSection *rdataSec;
OutputSection *buildidSec;
OutputSection *cvinfoSec;
OutputSection *dataSec;
OutputSection *pdataSec;
OutputSection *idataSec;
Expand Down Expand Up @@ -1092,6 +1093,7 @@ void Writer::createSections() {
bssSec = createSection(".bss", bss | r | w);
rdataSec = createSection(".rdata", data | r);
buildidSec = createSection(".buildid", data | r);
cvinfoSec = createSection(".cvinfo", data | r);
dataSec = createSection(".data", data | r | w);
pdataSec = createSection(".pdata", data | r);
idataSec = createSection(".idata", data | r);
Expand Down Expand Up @@ -1228,7 +1230,13 @@ void Writer::createMiscChunks() {
});

// Create Debug Information Chunks
debugInfoSec = config->mingw ? buildidSec : rdataSec;
if (config->mingw) {
debugInfoSec = buildidSec;
} else if (!config->mergeDebugDirectory) {
debugInfoSec = cvinfoSec;
} else {
debugInfoSec = rdataSec;
}
if (config->buildIDHash != BuildIDHash::None || config->debug ||
config->repro || config->cetCompat || config->cetCompatStrict ||
config->cetCompatIpValidationRelaxed ||
Expand Down
33 changes: 33 additions & 0 deletions lld/test/COFF/nodbgdirmerge.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
RUN: yaml2obj %p/Inputs/pdb1.yaml -o %t1.obj
RUN: yaml2obj %p/Inputs/pdb2.yaml -o %t2.obj
RUN: rm -f %t.dll %t.pdb

## Check that it emits the debug directory in .cvinfo section when
## /nodbgdirmerge is specified
RUN: lld-link /debug /pdb:%t.pdb /pdbaltpath:test.pdb /dll /out:%t.dll \
RUN: /entry:main /nodefaultlib /nodbgdirmerge %t1.obj %t2.obj
RUN: llvm-readobj --sections %t.dll | FileCheck -check-prefix=CHECKNOTMERGED %s

CHECKNOTMERGED: Section {
CHECKNOTMERGED: Number: 3
CHECKNOTMERGED-NEXT: Name: .cvinfo
CHECKNOTMERGED-NEXT: VirtualSize: 0x3D
CHECKNOTMERGED-NEXT: VirtualAddress: 0x3000
CHECKNOTMERGED-NEXT: RawDataSize: 512
CHECKNOTMERGED-NEXT: PointerToRawData: 0x800
CHECKNOTMERGED-NEXT: PointerToRelocations: 0
CHECKNOTMERGED-NEXT: PointerToLineNumbers: 0
CHECKNOTMERGED-NEXT: RelocationCount: 0
CHECKNOTMERGED-NEXT: LineNumberCount: 0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine as is - but as a general comment; it's also possible to make the test less prone to breaking on unrelated changes, by entirely omitting the values on the lines we're not interested in - it still matches the line so we can use -NEXT to keep things connected, but still matching those lines fuzzily.

Another potential approach is to skip -NEXT for the section we're not that interested in, then have e.g. CHECKNOTMERGED: LineNumberCount: CHECKNOTMERGED-NEXT: Characteristics [ (0x40000040), so the check for LineNumberCount: certainly will match the next such line, and force the full exact match on Characteristics to still be the next one (i.e. in the same section).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We just need to check the presense of .cvinfo section and that's all, perhaps it should suffice we just have single line CHECKNOTMERGED: Name: .cvinfo as well as the negate test?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that would probably also suffice. I guess technically we maybe also could want to check the contents of the section (not only that the section exists but also contains roughly the expected contents), but you're right that the rest of these checks here are kinda redundant.

CHECKNOTMERGED-NEXT: Characteristics [ (0x40000040)
CHECKNOTMERGED-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)
CHECKNOTMERGED-NEXT: IMAGE_SCN_MEM_READ (0x40000000)
CHECKNOTMERGED-NEXT: ]
CHECKNOTMERGED-NEXT: }

## Check that it triggers merge on when /nodbgdirmerge is not specified
RUN: lld-link /debug /pdb:%t.pdb /pdbaltpath:test.pdb /dll /out:%t.dll \
RUN: /entry:main /nodefaultlib %t1.obj %t2.obj
RUN: llvm-readobj --sections %t.dll | FileCheck -check-prefix=CHECKMERGED %s

CHECKMERGED-NOT: Name: .cvinfo