-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[ELF] Add --print-gc-sections=<file> #159706
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
[ELF] Add --print-gc-sections=<file> #159706
Conversation
Created using spr 1.3.5-bogner
@llvm/pr-subscribers-lld @llvm/pr-subscribers-lld-elf Author: Fangrui Song (MaskRay) ChangesAdd Full diff: https://github.com/llvm/llvm-project/pull/159706.diff 5 Files Affected:
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index a83a4c1176f6f..fd57967a1d21f 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -358,7 +358,7 @@ struct Config {
bool optRemarksWithHotness;
bool picThunk;
bool pie;
- bool printGcSections;
+ llvm::StringRef printGcSections;
bool printIcfSections;
bool printMemoryUsage;
std::optional<uint64_t> randomizeSectionPadding;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 6c2f318ffe469..1beab8d33f4ba 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -1510,8 +1510,14 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
ctx.arg.pie = args.hasFlag(OPT_pie, OPT_no_pie, false);
ctx.arg.printIcfSections =
args.hasFlag(OPT_print_icf_sections, OPT_no_print_icf_sections, false);
- ctx.arg.printGcSections =
- args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false);
+ if (auto *arg =
+ args.getLastArg(OPT_print_gc_sections, OPT_no_print_gc_sections,
+ OPT_print_gc_sections_eq)) {
+ if (arg->getOption().matches(OPT_print_gc_sections))
+ ctx.arg.printGcSections = "-";
+ else if (arg->getOption().matches(OPT_print_gc_sections_eq))
+ ctx.arg.printGcSections = arg->getValue();
+ }
ctx.arg.printMemoryUsage = args.hasArg(OPT_print_memory_usage);
ctx.arg.printArchiveStats = args.getLastArgValue(OPT_print_archive_stats);
ctx.arg.printSymbolOrder = args.getLastArgValue(OPT_print_symbol_order);
diff --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp
index 8dd341b79c8fc..464df98285e38 100644
--- a/lld/ELF/MarkLive.cpp
+++ b/lld/ELF/MarkLive.cpp
@@ -528,10 +528,18 @@ template <class ELFT> void elf::markLive(Ctx &ctx) {
MarkLive<ELFT, false>(ctx, 1).moveToMain();
// Report garbage-collected sections.
- if (ctx.arg.printGcSections)
- for (InputSectionBase *sec : ctx.inputSections)
- if (!sec->isLive())
- Msg(ctx) << "removing unused section " << sec;
+ if (ctx.arg.printGcSections.empty())
+ return;
+ std::error_code ec;
+ raw_fd_ostream os = ctx.openAuxiliaryFile(ctx.arg.printGcSections, ec);
+ if (ec) {
+ ErrAlways(ctx) << "--print-gc-sections=: cannot open "
+ << ctx.arg.printGcSections << ": " << ec.message();
+ return;
+ }
+ for (InputSectionBase *sec : ctx.inputSections)
+ if (!sec->isLive())
+ os << "removing unused section " << toStr(ctx, sec) << '\n';
}
template void elf::markLive<ELF32LE>(Ctx &);
diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td
index cc91680550b4b..f0523185a0a31 100644
--- a/lld/ELF/Options.td
+++ b/lld/ELF/Options.td
@@ -388,6 +388,9 @@ defm pie: B<"pie",
defm print_gc_sections: B<"print-gc-sections",
"List removed unused sections",
"Do not list removed unused sections (default)">;
+def print_gc_sections_eq: JJ<"print-gc-sections=">,
+ HelpText<"List removed unused sections to <file>">,
+ MetaVarName<"<file>">;
defm print_icf_sections: B<"print-icf-sections",
"List identical folded sections",
diff --git a/lld/test/ELF/gc-sections-print.s b/lld/test/ELF/gc-sections-print.s
index a822e9ef34793..191af74de3aaa 100644
--- a/lld/test/ELF/gc-sections-print.s
+++ b/lld/test/ELF/gc-sections-print.s
@@ -1,11 +1,16 @@
# REQUIRES: x86
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
# RUN: ld.lld %t --gc-sections --print-gc-sections -o %t2 2>&1 | FileCheck -check-prefix=PRINT %s
+# RUN: ld.lld %t --gc-sections --print-gc-sections=- -o %t2 2>&1 | FileCheck -check-prefix=PRINT %s
+# RUN: ld.lld %t --gc-sections --print-gc-sections=%t.txt
+# RUN: FileCheck --check-prefix=PRINT %s --input-file=%t.txt
# PRINT: removing unused section {{.*}}:(.text.x)
# PRINT-NEXT: removing unused section {{.*}}:(.text.y)
-# RUN: ld.lld %t --gc-sections --print-gc-sections --no-print-gc-sections -o %t2 >& %t.log
+# RUN: rm %t.txt
+# RUN: ld.lld %t --gc-sections --print-gc-sections --print-gc-sections=%t.txt --no-print-gc-sections -o %t2 >& %t.log
+# RUN: not ls %t.txt
# RUN: echo >> %t.log
# RUN: FileCheck -check-prefix=NOPRINT %s < %t.log
|
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.
LGTM. Always good to have the flexibility to write to a file.
Above printGCSections, there is printIcfSections. Although not for this patch, would it be useful to apply the same logic to that too?
Created using spr 1.3.5-bogner
Thanks for the review! Yes:) Will create a separate patch for --print-icf-sections= |
Add
--print-gc-sections=<file>
to redirect garbage collection sectionlisting to a file, avoiding contamination of stdout with other linker
output. mold has recently added the option.
GNU ld feature request: https://sourceware.org/bugzilla/show_bug.cgi?id=33331