bug-binutils
[Top][All Lists]
Advanced

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

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


From: lifang_xia at linux dot alibaba.com
Subject: [Bug ld/28709] [RISC-V] a unused section can't be removed with -gc-sections
Date: Wed, 22 Dec 2021 03:03:39 +0000

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

--- Comment #3 from lifang_xia at linux dot alibaba.com ---
The gas of riscv will split frag in md_assemble if the insn could be relaxed in
linker.tc-riscv.c:1372 (append_insn)
------------------------
/* We need to start a new frag after any instruction that can be
   optimized away or compressed by the linker during relaxation, to prevent
   the assembler from computing static offsets across such an instruction.
   This is necessary to get correct EH info.  */
if (reloc_type == BFD_RELOC_RISCV_CALL
    || reloc_type == BFD_RELOC_RISCV_CALL_PLT
    || reloc_type == BFD_RELOC_RISCV_HI20
    || reloc_type == BFD_RELOC_RISCV_PCREL_HI20
    || reloc_type == BFD_RELOC_RISCV_TPREL_HI20
    || reloc_type == BFD_RELOC_RISCV_TPREL_ADD)
  {
    frag_wane (frag_now);
    frag_new (0);
  }
--------------------------
The cfi_add_advance_loc will record the last symbol and current symbol, both of
the symbols are temp symbol which named .L0. And both of them are in the
section .test111111 which should be removed in linker. I name then to and from.

Because of the frag are splited, the to and from not the same frag.

Therefore, the gas will create a rs_cfa frag in .eh_frame for
DW_CFA_advance_loc while dw2cfi.c(output_cfi_insn). The symbol to(.L0) and
from(.L0) are in the section should be removed in linker.
--------------------------
static void
output_cfi_insn (struct cfi_insn_data *insn)
{
  offsetT offset;
  unsigned int regno;

  switch (insn->insn)
    {
    case DW_CFA_advance_loc:
      {
        symbolS *from = insn->u.ll.lab1;
        symbolS *to = insn->u.ll.lab2;

        if (symbol_get_frag (to) == symbol_get_frag (from))
          {
            ...
          }
        else
          {
            expressionS exp;

            exp.X_op = O_subtract;
            exp.X_add_symbol = to;
            exp.X_op_symbol = from;
            exp.X_add_number = 0;

            /* The code in ehopt.c expects that one byte of the encoding
               is already allocated to the frag.  This comes from the way
               that it scans the .eh_frame section looking first for the
               .byte DW_CFA_advance_loc4.  Call frag_grow with the sum of
               room needed by frag_more and frag_var to preallocate space
               ensuring that the DW_CFA_advance_loc4 is in the fixed part
               of the rs_cfa frag, so that the relax machinery can remove
               the advance_loc should it advance by zero.  */
            frag_grow (5);
            *frag_more (1) = DW_CFA_advance_loc4;

            frag_var (rs_cfa, 4, 0, DWARF2_LINE_MIN_INSN_LENGTH << 3,
                      make_expr_symbol (&exp), frag_now_fix () - 1,
                      (char *) frag_now);
          }
      }
      break; 
--------------------------------

The riscv backend will create a reloc named BFD_RELOC_RISCV_CFA in
riscv_pre_output_hook. The reloc  depends on the symbol to(.L0) and from(.L0).

And riscv backend will convert BFD_RELOC_RISCV_CFA  to R_RISCV_SET6 and
R_RISCV_SUB6 in md_apply_fix.

That's why .eh_frame depends on .text.test1111111

-- 
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]