Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lld/ELF/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
10 changes: 8 additions & 2 deletions lld/ELF/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
16 changes: 12 additions & 4 deletions lld/ELF/MarkLive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 &);
Expand Down
3 changes: 3 additions & 0 deletions lld/ELF/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
3 changes: 3 additions & 0 deletions lld/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ Non-comprehensive list of changes in this release
ELF Improvements
----------------

* ``--print-gc-sections=<file>`` prints garbage collection section listing to a file.
(`#159706 <https://github.com/llvm/llvm-project/pull/159706>`_)

Breaking changes
----------------

Expand Down
2 changes: 2 additions & 0 deletions lld/docs/ld.lld.1
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,8 @@ Don't use.

.It Fl -print-gc-sections
List removed unused sections.
.It Fl -print-gc-sections Ns = Ns Ar file
List removed unused sections to the specified file.
.It Fl -print-icf-sections
List identical folded sections.
.It Fl -print-map
Expand Down
7 changes: 6 additions & 1 deletion lld/test/ELF/gc-sections-print.s
Original file line number Diff line number Diff line change
@@ -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

Expand Down