bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug ld/28709] New: [RISC-V] a unused section can't be removed with -gc-


From: address@hidden
Subject: [Bug ld/28709] New: [RISC-V] a unused section can't be removed with -gc-sections
Date: Fri, 17 Dec 2021 06:47:58 +0000

https://sourceware.org/bugzilla/show_bug.cgi?id=28709

            Bug ID: 28709
           Summary: [RISC-V] a unused section can't be removed with
                    -gc-sections
           Product: binutils
           Version: 2.38 (HEAD)
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: ld
          Assignee: unassigned at sourceware dot org
          Reporter: lifang_xia@c-sky.com
  Target Milestone: ---

Created attachment 13860
  --> https://sourceware.org/bugzilla/attachment.cgi?id=13860&action=edit
source code and command

I have met a situation, but I think it should be bug for ld in RISC-V.
A unused section can't be removed with gc-section.

The attachment contains the sources and command to run:
a.c: a main entry, which only prints "HelloWorld", it does not depend on b.cpp.
a.s: a asm file created by compiling a.c
b.cpp: a cpp with a class, and a function
b.s: a asm file created by compiling b.cpp
b.simple.s: delete some sections from b.s
===================
BUILD
riscv64-unknown-elf-gcc -ffunction-sections -fdata-sections -o a.o a.c -c
riscv64-unknown-elf-g++ -ffunction-sections -fdata-sections -o b.o b.cpp -c
riscv64-unknown-elf-g++ -Wl,-gc-sections -o a a.o b.o

I can find the test111111 in the output with "readelf -sW a".
Obviously, test111111 should be removed. I have tested on ARM and x86, both of
them can remove test111111.

b.simple.s is simpler than b.s, I use the gas and ld to do test:
./gas/as-new -o a.o a.s
./gas/as-new -o b.o b.simple.s
./ld/ld-new  -o a a.o b.o -e main --defsym=puts=0 -gc-section
--print-gc-sections

==========================================
the reason why test111111 can't be removed is that there is a init_array in
b.simple.s which holds a entry _GLOBAL__sub_I__ZN3Box3getEv,
and _GLOBAL__sub_I__ZN3Box3getEv have a eh_frame. there are only one eh_frame
in b.o, so eh_frame also contains the dwarf about test111111.

The gas create some relocs for DW_CFA_advance_loc* which used in linker relax.
The dest symbol of relocs belongs to .text.test111111.

So ld can't remove the .text.test111111.

=========================================
How to solve

1. Skip gc_mark in riscv_elf_gc_mark_hook
+  /* Ignore the reloc which are used for eh_frame. */
+  if (strcmp(sec->name, ".eh_frame") == 0)
+    {
+      switch (ELFNN_R_TYPE (rel->r_info))
+      {
+      case R_RISCV_SET6:
+      case R_RISCV_SUB6:
+      case R_RISCV_SET8:
+      case R_RISCV_SUB8:
+      case R_RISCV_SET16:
+      case R_RISCV_SUB16:
+      case R_RISCV_SET32:
+      case R_RISCV_SUB32:
+        return NULL;
+      }
+    }

2, Split .eh_frame to .eh_frame.function. It is a good choice, but the dwarf
may not be suitable for that.

-- 
You are receiving this mail because:
You are on the CC list for the bug.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]