[lld] 67244da - [LLD][COFF] Add /nodbgdirmerge to control debug directory section (#159235)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 19 14:20:36 PDT 2025
Author: kkent030315
Date: 2025-09-20T00:20:32+03:00
New Revision: 67244da08e1aa83f34358a32e3fa3b2e1722bc65
URL: https://github.com/llvm/llvm-project/commit/67244da08e1aa83f34358a32e3fa3b2e1722bc65
DIFF: https://github.com/llvm/llvm-project/commit/67244da08e1aa83f34358a32e3fa3b2e1722bc65.diff
LOG: [LLD][COFF] Add /nodbgdirmerge to control debug directory section (#159235)
Resolves #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 <admin at namazso.eu>
Added:
lld/test/COFF/nodbgdirmerge.test
Modified:
lld/COFF/Config.h
lld/COFF/Driver.cpp
lld/COFF/Options.td
lld/COFF/Writer.cpp
Removed:
################################################################################
diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h
index a71476adcc493..76b7c1f61cd25 100644
--- a/lld/COFF/Config.h
+++ b/lld/COFF/Config.h
@@ -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;
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index acba156ce341d..948dd7a96c7a5 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -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 "
diff --git a/lld/COFF/Options.td b/lld/COFF/Options.td
index b5334de87b6a7..485db5a8b21c1 100644
--- a/lld/COFF/Options.td
+++ b/lld/COFF/Options.td
@@ -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">;
diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index e0d0ac18ea5d5..b4f00996319b1 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -324,6 +324,7 @@ class Writer {
OutputSection *bssSec;
OutputSection *rdataSec;
OutputSection *buildidSec;
+ OutputSection *cvinfoSec;
OutputSection *dataSec;
OutputSection *pdataSec;
OutputSection *idataSec;
@@ -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);
@@ -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 ||
diff --git a/lld/test/COFF/nodbgdirmerge.test b/lld/test/COFF/nodbgdirmerge.test
new file mode 100644
index 0000000000000..1ad697402a6a2
--- /dev/null
+++ b/lld/test/COFF/nodbgdirmerge.test
@@ -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
+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
More information about the llvm-commits
mailing list