Skip to content

Commit 67244da

Browse files
kkent030315namazso
andauthored
[LLD][COFF] Add /nodbgdirmerge to control debug directory section (llvm#159235)
Resolves llvm#141712. As described in the issue, this PR adds support for `/nodbgdirmerge` flag in LLD to align with MS link. When the flag is specified, the linker will emit the debug directory section in `.cvinfo` section, instead of merging it to the `.rdata`. The flag will be ignored on MinGW. --------- Co-authored-by: namazso <[email protected]>
1 parent d8a4c61 commit 67244da

File tree

5 files changed

+48
-1
lines changed

5 files changed

+48
-1
lines changed

lld/COFF/Config.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@ struct Configuration {
322322
bool largeAddressAware = false;
323323
bool highEntropyVA = false;
324324
bool appContainer = false;
325+
bool mergeDebugDirectory = true;
325326
bool mingw = false;
326327
bool warnMissingOrderSymbol = true;
327328
bool warnLocallyDefinedImported = true;

lld/COFF/Driver.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2338,6 +2338,9 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
23382338
config->is64() &&
23392339
args.hasFlag(OPT_highentropyva, OPT_highentropyva_no, true);
23402340

2341+
// Handle /nodbgdirmerge
2342+
config->mergeDebugDirectory = !args.hasArg(OPT_nodbgdirmerge);
2343+
23412344
if (!config->dynamicBase &&
23422345
(config->machine == ARMNT || isAnyArm64(config->machine)))
23432346
Err(ctx) << "/dynamicbase:no is not compatible with "

lld/COFF/Options.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ def machine : P<"machine", "Specify target platform">;
9090
def merge : P<"merge", "Combine sections">;
9191
def mllvm : P<"mllvm", "Options to pass to LLVM">;
9292
def nodefaultlib : P<"nodefaultlib", "Remove a default library">;
93+
def nodbgdirmerge : F<"nodbgdirmerge">,
94+
HelpText<"Emit the debug directory in a separate section">;
9395
def opt : P<"opt", "Control optimizations">;
9496
def order : P<"order", "Put functions in order">;
9597
def out : P<"out", "Path to file to write output">;

lld/COFF/Writer.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,7 @@ class Writer {
324324
OutputSection *bssSec;
325325
OutputSection *rdataSec;
326326
OutputSection *buildidSec;
327+
OutputSection *cvinfoSec;
327328
OutputSection *dataSec;
328329
OutputSection *pdataSec;
329330
OutputSection *idataSec;
@@ -1092,6 +1093,7 @@ void Writer::createSections() {
10921093
bssSec = createSection(".bss", bss | r | w);
10931094
rdataSec = createSection(".rdata", data | r);
10941095
buildidSec = createSection(".buildid", data | r);
1096+
cvinfoSec = createSection(".cvinfo", data | r);
10951097
dataSec = createSection(".data", data | r | w);
10961098
pdataSec = createSection(".pdata", data | r);
10971099
idataSec = createSection(".idata", data | r);
@@ -1228,7 +1230,13 @@ void Writer::createMiscChunks() {
12281230
});
12291231

12301232
// Create Debug Information Chunks
1231-
debugInfoSec = config->mingw ? buildidSec : rdataSec;
1233+
if (config->mingw) {
1234+
debugInfoSec = buildidSec;
1235+
} else if (!config->mergeDebugDirectory) {
1236+
debugInfoSec = cvinfoSec;
1237+
} else {
1238+
debugInfoSec = rdataSec;
1239+
}
12321240
if (config->buildIDHash != BuildIDHash::None || config->debug ||
12331241
config->repro || config->cetCompat || config->cetCompatStrict ||
12341242
config->cetCompatIpValidationRelaxed ||

lld/test/COFF/nodbgdirmerge.test

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
RUN: yaml2obj %p/Inputs/pdb1.yaml -o %t1.obj
2+
RUN: yaml2obj %p/Inputs/pdb2.yaml -o %t2.obj
3+
RUN: rm -f %t.dll %t.pdb
4+
5+
## Check that it emits the debug directory in .cvinfo section when
6+
## /nodbgdirmerge is specified
7+
RUN: lld-link /debug /pdb:%t.pdb /pdbaltpath:test.pdb /dll /out:%t.dll \
8+
RUN: /entry:main /nodefaultlib /nodbgdirmerge %t1.obj %t2.obj
9+
RUN: llvm-readobj --sections %t.dll | FileCheck -check-prefix=CHECKNOTMERGED %s
10+
11+
CHECKNOTMERGED: Section {
12+
CHECKNOTMERGED: Number: 3
13+
CHECKNOTMERGED-NEXT: Name: .cvinfo
14+
CHECKNOTMERGED-NEXT: VirtualSize: 0x3D
15+
CHECKNOTMERGED-NEXT: VirtualAddress: 0x3000
16+
CHECKNOTMERGED-NEXT: RawDataSize: 512
17+
CHECKNOTMERGED-NEXT: PointerToRawData: 0x800
18+
CHECKNOTMERGED-NEXT: PointerToRelocations: 0
19+
CHECKNOTMERGED-NEXT: PointerToLineNumbers: 0
20+
CHECKNOTMERGED-NEXT: RelocationCount: 0
21+
CHECKNOTMERGED-NEXT: LineNumberCount: 0
22+
CHECKNOTMERGED-NEXT: Characteristics [ (0x40000040)
23+
CHECKNOTMERGED-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)
24+
CHECKNOTMERGED-NEXT: IMAGE_SCN_MEM_READ (0x40000000)
25+
CHECKNOTMERGED-NEXT: ]
26+
CHECKNOTMERGED-NEXT: }
27+
28+
## Check that it triggers merge on when /nodbgdirmerge is not specified
29+
RUN: lld-link /debug /pdb:%t.pdb /pdbaltpath:test.pdb /dll /out:%t.dll \
30+
RUN: /entry:main /nodefaultlib %t1.obj %t2.obj
31+
RUN: llvm-readobj --sections %t.dll | FileCheck -check-prefix=CHECKMERGED %s
32+
33+
CHECKMERGED-NOT: Name: .cvinfo

0 commit comments

Comments
 (0)