bug-binutils
[Top][All Lists]
Advanced

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

[Bug ld/28410] Prevent region check failures when relaxation is not fina


From: nelsonc1225 at sourceware dot org
Subject: [Bug ld/28410] Prevent region check failures when relaxation is not final
Date: Tue, 05 Oct 2021 02:29:29 +0000

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

--- Comment #4 from Nelson Chu <nelsonc1225 at sourceware dot org> ---
> I had thought about a possible approach to rewrite the commit, such that we
> can restart the relaxation process again without modifying the `again`
> pointer. Perhaps its worth me working on this if that's a preferable
> solution to this, the only caveat is that the exact behaviour of what gets
> repeated wouldn't be preserved - though this may be fine to achieve the same
> result.

I assume we are talking about the option 3?  If so, then there are some
thoughts that might help:

Since the pcrel low parts are attached to the corresponding auipc by the
r_symbol in low part relocation, we used to build tables to record these
information, and then use these tables to relocate them later.  The problem
caused in commit abd20c is that - we should update these pcrel tables once we
actually deleted the code.  We need to update three things at least,

1. The pc value (address) of auipc in riscv_pcrel_hi_reloc.
2. The pc value (address) of auipc in riscv_pcrel_lo_reloc.
3. The relocation value with addend of auipc in riscv_pcrel_hi_reloc.

For 3. we probably should record the whole auipc relocation rather than the
counted relocation values.  So that we don't need to additional update it,
since all relocation should already be modified in the
riscv_relax_delete_bytes.  Just that we need to count the relocation of auipc
again in the riscv_resolve_pcrel_lo_relocs.  What I mean is this,

      if (r_symndx < symtab_hdr->sh_info)
        {
          sym = local_syms + r_symndx;
          sec = local_sections[r_symndx];
          relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);

          /* Relocate against local STT_GNU_IFUNC symbol.  */
          if (!bfd_link_relocatable (info)
              && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
            {
              h = riscv_elf_get_local_sym_hash (htab, input_bfd, rel, false);
              if (h == NULL)
                abort ();

              /* Set STT_GNU_IFUNC symbol value.  */
              h->root.u.def.value = sym->st_value;
              h->root.u.def.section = sec;
            }
        }
      else
        {
          bool warned, ignored;

          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
                                   r_symndx, symtab_hdr, sym_hashes,
                                   h, sec, relocation,
                                   unresolved_reloc, warned, ignored);
          if (warned)
            {
              /* To avoid generating warning messages about truncated
                 relocations, set the relocation's address to be the same as
                 the start of this section.  */
              if (input_section->output_section != NULL)
                relocation = input_section->output_section->vma;
              else
                relocation = 0;
            }
        }

Not sure the details.  Anyway, this should be a big project, and I think it
might be worth to do, since we don't need to modify any generic code.

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