Skip to content

Commit cbb60a3

Browse files
authored
[ELF] Add --print-gc-sections=<file> (#159706)
Add `--print-gc-sections=<file>` to redirect garbage collection section listing 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
1 parent 6119d1f commit cbb60a3

File tree

7 files changed

+39
-8
lines changed

7 files changed

+39
-8
lines changed

lld/ELF/Config.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ struct Config {
358358
bool optRemarksWithHotness;
359359
bool picThunk;
360360
bool pie;
361-
bool printGcSections;
361+
llvm::StringRef printGcSections;
362362
bool printIcfSections;
363363
bool printMemoryUsage;
364364
std::optional<uint64_t> randomizeSectionPadding;

lld/ELF/Driver.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1510,8 +1510,14 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
15101510
ctx.arg.pie = args.hasFlag(OPT_pie, OPT_no_pie, false);
15111511
ctx.arg.printIcfSections =
15121512
args.hasFlag(OPT_print_icf_sections, OPT_no_print_icf_sections, false);
1513-
ctx.arg.printGcSections =
1514-
args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false);
1513+
if (auto *arg =
1514+
args.getLastArg(OPT_print_gc_sections, OPT_no_print_gc_sections,
1515+
OPT_print_gc_sections_eq)) {
1516+
if (arg->getOption().matches(OPT_print_gc_sections))
1517+
ctx.arg.printGcSections = "-";
1518+
else if (arg->getOption().matches(OPT_print_gc_sections_eq))
1519+
ctx.arg.printGcSections = arg->getValue();
1520+
}
15151521
ctx.arg.printMemoryUsage = args.hasArg(OPT_print_memory_usage);
15161522
ctx.arg.printArchiveStats = args.getLastArgValue(OPT_print_archive_stats);
15171523
ctx.arg.printSymbolOrder = args.getLastArgValue(OPT_print_symbol_order);

lld/ELF/MarkLive.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -528,10 +528,18 @@ template <class ELFT> void elf::markLive(Ctx &ctx) {
528528
MarkLive<ELFT, false>(ctx, 1).moveToMain();
529529

530530
// Report garbage-collected sections.
531-
if (ctx.arg.printGcSections)
532-
for (InputSectionBase *sec : ctx.inputSections)
533-
if (!sec->isLive())
534-
Msg(ctx) << "removing unused section " << sec;
531+
if (ctx.arg.printGcSections.empty())
532+
return;
533+
std::error_code ec;
534+
raw_fd_ostream os = ctx.openAuxiliaryFile(ctx.arg.printGcSections, ec);
535+
if (ec) {
536+
Err(ctx) << "cannot open --print-gc-sections= file "
537+
<< ctx.arg.printGcSections << ": " << ec.message();
538+
return;
539+
}
540+
for (InputSectionBase *sec : ctx.inputSections)
541+
if (!sec->isLive())
542+
os << "removing unused section " << toStr(ctx, sec) << '\n';
535543
}
536544

537545
template void elf::markLive<ELF32LE>(Ctx &);

lld/ELF/Options.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,9 @@ defm pie: B<"pie",
388388
defm print_gc_sections: B<"print-gc-sections",
389389
"List removed unused sections",
390390
"Do not list removed unused sections (default)">;
391+
def print_gc_sections_eq: JJ<"print-gc-sections=">,
392+
HelpText<"List removed unused sections to <file>">,
393+
MetaVarName<"<file>">;
391394

392395
defm print_icf_sections: B<"print-icf-sections",
393396
"List identical folded sections",

lld/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ Non-comprehensive list of changes in this release
2929
ELF Improvements
3030
----------------
3131

32+
* ``--print-gc-sections=<file>`` prints garbage collection section listing to a file.
33+
(`#159706 <https://github.com/llvm/llvm-project/pull/159706>`_)
34+
3235
Breaking changes
3336
----------------
3437

lld/docs/ld.lld.1

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,8 @@ Don't use.
522522

523523
.It Fl -print-gc-sections
524524
List removed unused sections.
525+
.It Fl -print-gc-sections Ns = Ns Ar file
526+
List removed unused sections to the specified file.
525527
.It Fl -print-icf-sections
526528
List identical folded sections.
527529
.It Fl -print-map

lld/test/ELF/gc-sections-print.s

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,25 @@
11
# REQUIRES: x86
22
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
33
# RUN: ld.lld %t --gc-sections --print-gc-sections -o %t2 2>&1 | FileCheck -check-prefix=PRINT %s
4+
# RUN: ld.lld %t --gc-sections --print-gc-sections=- -o %t2 2>&1 | FileCheck -check-prefix=PRINT %s
5+
# RUN: ld.lld %t --gc-sections --print-gc-sections=%t.txt
6+
# RUN: FileCheck --check-prefix=PRINT %s --input-file=%t.txt
47

58
# PRINT: removing unused section {{.*}}:(.text.x)
69
# PRINT-NEXT: removing unused section {{.*}}:(.text.y)
710

8-
# RUN: ld.lld %t --gc-sections --print-gc-sections --no-print-gc-sections -o %t2 >& %t.log
11+
# RUN: rm %t.txt
12+
# RUN: ld.lld %t --gc-sections --print-gc-sections --print-gc-sections=%t.txt --no-print-gc-sections -o %t2 >& %t.log
13+
# RUN: not ls %t.txt
914
# RUN: echo >> %t.log
1015
# RUN: FileCheck -check-prefix=NOPRINT %s < %t.log
1116

1217
# NOPRINT-NOT: removing
1318

19+
# RUN: not ld.lld %t --gc-sections --print-gc-sections=/ -o %t2 2>&1 | FileCheck --check-prefix=ERR %s
20+
21+
# ERR: error: cannot open --print-gc-sections= file /: {{.*}}
22+
1423
.globl _start
1524
.protected a, x, y
1625
_start:

0 commit comments

Comments
 (0)