https://sourceware.org/bugzilla/show_bug.cgi?id=32961
Bug ID: 32961
Summary: ".pushsection" may introduce unnecessary section
dependency which impacts "--gc-sections"
Product: binutils
Version: 2.42
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: ld
Assignee: unassigned at sourceware dot org
Reporter: zhiyuan.lv at linux dot intel.com
Target Milestone: ---
While compiling some Linux kernel files with "-ffunction-sections" and linker
parameter "--gc-sections", I found that several unused functions were not
removed as expected, and the root cause is unnecessary section dependencies
introduced by ".pushsection" directive. I simplified the case as below and
would like to get feedback from binutils developers of any existing workable
ways, or we could consider a new feature request to ld. Appreciate all the
input!
The case of test.c:
static inline __attribute__((always_inline)) void test_section(void)
{
asm goto(
"jmp 1f\n"
".pushsection .alt_section, \"ax\"\n"
"1:\n"
" jmp %l[t_label]\n"
".popsection\n"
: :
: : t_label);
t_label:
return;
}
void foo1(void)
{
}
void foo2(void)
{
test_section();
}
void foo3(void)
{
test_section();
}
void entry_func(void)
{
foo1();
foo3();
}
The build command: gcc test.c -ffunction-sections -Wl,-e entry_func
-Wl,--gc-sections -o test -nostdlib -O0
My environment is Ubuntu 24.04, with LD version 2.42.
The expected result is that foo2() is optimized away in generated binary by
linker, but it can still be seen with "objdump -S test".
The root cause is at ".alt_section". If we check the section dependency from
relocation table in test.o generated by "gcc test.c -c -ffunction-sections -o
test.o", foo3 has relocation entry pointing to ".alt_section" and
".alt_section" has relocation try to ".foo2", which prevents LD from removing
foo2.
If I remove the inline attribute of test_section(), the function foo2() can be
removed by linker, because relocation entry of .alt_section will not link to
foo2 or foo3. Also, if there is no "test_section()" call in foo3(), foo2() can
be removed as well.
The linker does not do anything wrong, but in my case of Linux kernel from
"_static_cpu_has()" in arch/x86/include/asm/cpufeature.h, I cannot simply
remove inline and there does not seem to be a good solution.
If all above is correct, could we consider below two options?
1. Add a new type of ".pushsection", say, ".pushnewsection", which will always
create a new section.
2. Let LD be able to ignore some given sections while doing the section
dependency calculation. If a symbol is deleted, simply remove the relocation
entry in the specified "ignored section".
Either one can address above case of test.c. Any comments? Thanks!
--
You are receiving this mail because:
You are on the CC list for the bug.