-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[LLD] [COFF] Add /debug: options nodwarf and nosymtab #75180
Conversation
@llvm/pr-subscribers-lld @llvm/pr-subscribers-lld-coff Author: Martin Storsjö (mstorsjo) ChangesThese allow tweaking what gets implied by /debug and /debug:dwarf. Full diff: https://github.com/llvm/llvm-project/pull/75180.diff 7 Files Affected:
diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h
index 24126f635a06f2..48c48cefe91d8e 100644
--- a/lld/COFF/Config.h
+++ b/lld/COFF/Config.h
@@ -130,9 +130,9 @@ struct Configuration {
bool forceMultipleRes = false;
bool forceUnresolved = false;
bool debug = false;
- bool debugDwarf = false;
+ bool includeDwarfChunks = false;
bool debugGHashes = false;
- bool debugSymtab = false;
+ bool writeSymtab = false;
bool driver = false;
bool driverUponly = false;
bool driverWdm = false;
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index 99c1a60735adc5..826022e7450292 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -858,46 +858,6 @@ static std::string createResponseFile(const opt::InputArgList &args,
return std::string(data.str());
}
-enum class DebugKind {
- Unknown,
- None,
- Full,
- FastLink,
- GHash,
- NoGHash,
- Dwarf,
- Symtab
-};
-
-static DebugKind parseDebugKind(const opt::InputArgList &args) {
- auto *a = args.getLastArg(OPT_debug, OPT_debug_opt);
- if (!a)
- return DebugKind::None;
- if (a->getNumValues() == 0)
- return DebugKind::Full;
-
- DebugKind debug = StringSwitch<DebugKind>(a->getValue())
- .CaseLower("none", DebugKind::None)
- .CaseLower("full", DebugKind::Full)
- .CaseLower("fastlink", DebugKind::FastLink)
- // LLD extensions
- .CaseLower("ghash", DebugKind::GHash)
- .CaseLower("noghash", DebugKind::NoGHash)
- .CaseLower("dwarf", DebugKind::Dwarf)
- .CaseLower("symtab", DebugKind::Symtab)
- .Default(DebugKind::Unknown);
-
- if (debug == DebugKind::FastLink) {
- warn("/debug:fastlink unsupported; using /debug:full");
- return DebugKind::Full;
- }
- if (debug == DebugKind::Unknown) {
- error("/debug: unknown option: " + Twine(a->getValue()));
- return DebugKind::None;
- }
- return debug;
-}
-
static unsigned parseDebugTypes(const opt::InputArgList &args) {
unsigned debugTypes = static_cast<unsigned>(DebugType::None);
@@ -1647,12 +1607,62 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
if (args.hasArg(OPT_force, OPT_force_multipleres))
config->forceMultipleRes = true;
+ // Don't warn about long section names, such as .debug_info, for mingw (or
+ // when -debug:dwarf is requested, handled below).
+ if (config->mingw)
+ config->warnLongSectionNames = false;
+
+ bool doGC = true;
+
// Handle /debug
- DebugKind debug = parseDebugKind(args);
- if (debug == DebugKind::Full || debug == DebugKind::Dwarf ||
- debug == DebugKind::GHash || debug == DebugKind::NoGHash) {
- config->debug = true;
- config->incremental = true;
+ bool shouldCreatePDB = false;
+ for (auto *arg : args.filtered(OPT_debug, OPT_debug_opt)) {
+ std::string str;
+ if (arg->getOption().getID() == OPT_debug)
+ str = "full";
+ else
+ str = StringRef(arg->getValue()).lower();
+ SmallVector<StringRef, 1> vec;
+ StringRef(str).split(vec, ',');
+ for (StringRef s : vec) {
+ if (s == "fastlink") {
+ warn("/debug:fastlink unsupported; using /debug:full");
+ s = "full";
+ }
+ if (s == "none") {
+ config->debug = false;
+ config->incremental = false;
+ config->includeDwarfChunks = false;
+ config->debugGHashes = false;
+ config->writeSymtab = false;
+ shouldCreatePDB = false;
+ doGC = true;
+ } else if (s == "full" || s == "ghash" || s == "noghash") {
+ config->debug = true;
+ config->incremental = true;
+ config->includeDwarfChunks = true;
+ if (s == "full" || s == "ghash")
+ config->debugGHashes = true;
+ shouldCreatePDB = true;
+ doGC = false;
+ } else if (s == "dwarf") {
+ config->debug = true;
+ config->incremental = true;
+ config->includeDwarfChunks = true;
+ config->writeSymtab = true;
+ config->warnLongSectionNames = false;
+ doGC = false;
+ } else if (s == "nodwarf") {
+ config->includeDwarfChunks = false;
+ } else if (s == "symtab") {
+ config->writeSymtab = true;
+ doGC = false;
+ } else if (s == "nosymtab") {
+ config->writeSymtab = false;
+ } else {
+ error("/debug: unknown option: " + s);
+ }
+ }
}
// Handle /demangle
@@ -1672,9 +1682,6 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
config->driverUponly || config->driverWdm || args.hasArg(OPT_driver);
// Handle /pdb
- bool shouldCreatePDB =
- (debug == DebugKind::Full || debug == DebugKind::GHash ||
- debug == DebugKind::NoGHash);
if (shouldCreatePDB) {
if (auto *arg = args.getLastArg(OPT_pdb))
config->pdbPath = arg->getValue();
@@ -1837,8 +1844,9 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
config->noimplib = args.hasArg(OPT_noimplib);
+ if (args.hasArg(OPT_profile))
+ doGC = true;
// Handle /opt.
- bool doGC = debug == DebugKind::None || args.hasArg(OPT_profile);
std::optional<ICFLevel> icfLevel;
if (args.hasArg(OPT_profile))
icfLevel = ICFLevel::None;
@@ -2028,9 +2036,6 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
parseSwaprun(arg->getValue());
config->terminalServerAware =
!config->dll && args.hasFlag(OPT_tsaware, OPT_tsaware_no, true);
- config->debugDwarf = debug == DebugKind::Dwarf;
- config->debugGHashes = debug == DebugKind::GHash || debug == DebugKind::Full;
- config->debugSymtab = debug == DebugKind::Symtab;
config->autoImport =
args.hasFlag(OPT_auto_import, OPT_auto_import_no, config->mingw);
config->pseudoRelocs = args.hasFlag(
@@ -2047,11 +2052,6 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
if (args.hasFlag(OPT_inferasanlibs, OPT_inferasanlibs_no, false))
warn("ignoring '/inferasanlibs', this flag is not supported");
- // Don't warn about long section names, such as .debug_info, for mingw or
- // when -debug:dwarf is requested.
- if (config->mingw || config->debugDwarf)
- config->warnLongSectionNames = false;
-
if (config->incremental && args.hasArg(OPT_profile)) {
warn("ignoring '/incremental' due to '/profile' specification");
config->incremental = false;
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index dd2e1419bb10a6..cd744800cb0dec 100644
--- a/lld/COFF/InputFiles.cpp
+++ b/lld/COFF/InputFiles.cpp
@@ -236,8 +236,8 @@ SectionChunk *ObjFile::readSection(uint32_t sectionNumber,
// CodeView needs linker support. We need to interpret debug info,
// and then write it to a separate .pdb file.
- // Ignore DWARF debug info unless /debug is given.
- if (!ctx.config.debug && name.starts_with(".debug_"))
+ // Ignore DWARF debug info unless requested to be included.
+ if (!ctx.config.includeDwarfChunks && name.starts_with(".debug_"))
return nullptr;
if (sec->Characteristics & llvm::COFF::IMAGE_SCN_LNK_REMOVE)
diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index 7b1ff8071e2e3d..ec5d10ed990325 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -1376,7 +1376,7 @@ void Writer::createSymbolAndStringTable() {
sec->setStringTableOff(addEntryToStringTable(sec->name));
}
- if (ctx.config.debugDwarf || ctx.config.debugSymtab) {
+ if (ctx.config.writeSymtab) {
for (ObjFile *file : ctx.objFileInstances) {
for (Symbol *b : file->getSymbols()) {
auto *d = dyn_cast_or_null<Defined>(b);
diff --git a/lld/test/COFF/debug-dwarf.test b/lld/test/COFF/debug-dwarf.test
index 156b2f58f64e31..c52e7c6067fa78 100644
--- a/lld/test/COFF/debug-dwarf.test
+++ b/lld/test/COFF/debug-dwarf.test
@@ -17,3 +17,16 @@
# RUN: rm -f %t.pdb
# RUN: lld-link /debug:dwarf /pdb:%t.pdb /entry:main /out:%t.exe %p/Inputs/ret42.obj
# RUN: not ls %t.pdb
+
+# Check that /debug /debug:dwarf or /debug:full,dwarf creates %t.pdb.
+# RUN: rm -f %t.pdb
+# RUN: lld-link /debug /debug:dwarf /entry:main /out:%t.exe %p/Inputs/ret42.obj
+# RUN: ls %t.pdb
+# RUN: rm -f %t.pdb
+# RUN: lld-link /debug:full,dwarf /entry:main /out:%t.exe %p/Inputs/ret42.obj
+# RUN: ls %t.pdb
+
+# Check that /debug /debug:full,nodwarf creates %t.pdb.
+# RUN: rm -f %t.pdb
+# RUN: lld-link /debug:full,nodwarf /entry:main /out:%t.exe %p/Inputs/ret42.obj
+# RUN: ls %t.pdb
diff --git a/lld/test/COFF/sort-debug.test b/lld/test/COFF/sort-debug.test
index bbe2ecd0efd8df..30cad394665489 100644
--- a/lld/test/COFF/sort-debug.test
+++ b/lld/test/COFF/sort-debug.test
@@ -7,6 +7,10 @@
# RUN: llvm-readobj --sections %t.exe | FileCheck -check-prefix=NODEBUG %s
# RUN: lld-link /debug:symtab /out:%t.exe /entry:main %t.obj
# RUN: llvm-readobj --sections %t.exe | FileCheck -check-prefix=NODEBUG %s
+# RUN: lld-link /debug:full,nodwarf /out:%t.exe /entry:main %t.obj
+# RUN: llvm-readobj --sections %t.exe | FileCheck -check-prefix=NODEBUG %s
+# RUN: lld-link /debug:full /debug:nodwarf /out:%t.exe /entry:main %t.obj
+# RUN: llvm-readobj --sections %t.exe | FileCheck -check-prefix=NODEBUG %s
# CHECK: Name: .text
# CHECK: Name: .reloc
diff --git a/lld/test/COFF/symtab.test b/lld/test/COFF/symtab.test
index 48c749957a422a..45e8ed39737a46 100644
--- a/lld/test/COFF/symtab.test
+++ b/lld/test/COFF/symtab.test
@@ -5,9 +5,13 @@
# RUN: llvm-readobj --symbols %t.exe | FileCheck %s
# RUN: lld-link /debug:symtab /opt:noref /out:%t.exe /entry:main %t.obj %p/Inputs/std64.lib
# RUN: llvm-readobj --symbols %t.exe | FileCheck %s
+# RUN: lld-link /debug:full,symtab /opt:noref /out:%t.exe /entry:main %t.obj %p/Inputs/std64.lib
+# RUN: llvm-readobj --symbols %t.exe | FileCheck %s
# RUN: lld-link /debug /out:%t.exe /entry:main %t.obj %p/Inputs/std64.lib
# RUN: llvm-readobj --symbols %t.exe | FileCheck -check-prefix=NO %s
+# RUN: lld-link /debug:dwarf,nosymtab /out:%t.exe /entry:main %t.obj %p/Inputs/std64.lib
+# RUN: llvm-readobj --symbols %t.exe | FileCheck -check-prefix=NO %s
# CHECK: Symbols [
# CHECK-NEXT: Symbol {
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For a non-list option, I think it is very uncommon for a second occurrence of an option to override partial effects done by the first occurrence. Actually, I cannot think of an example off my head.
ELF linkers have an example of -z defs
, -z undefs
, --allow-shlib-undefined
, --unresolved-symbols
where --unresolved-symbols
overrides both diagRegular/diagShlib
while other options may override one of diagRegular/diagShlib.
That said, if this /debug:
is useful, I think it is fine to be a special case...
Yes, it's a bit of an uncommon case. On the other hand, this is mostly internal api, as the main/only user outside of tests, is the lld mingw interface. I guess we could make the options more orthogonal by not implicitly enable including DWARF, when enabling the regular PDB |
These allow tweaking what gets implied by /debug and /debug:dwarf.
c30da26
to
46c3616
Compare
These allow tweaking what gets implied by /debug and /debug:dwarf.