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.