[PATCH] RISC-V: Clarify the behaviors of SET/ADD/SUB relocations.

Nelson Chu nelson@rivosinc.com
Fri Oct 27 00:37:02 GMT 2023


On Sat, Oct 21, 2023 at 1:58 AM Charlie Jenkins <charlie@rivosinc.com>
wrote:

> On Thu, Oct 19, 2023 at 05:17:26PM +0800, Nelson Chu wrote:
> > We are used to generate these kinds of relocations by data directives.
> > Considering the following example,
> > .word (A + 3) - (B + 2)
> > The GAS will generate a pair of ADD/SUB for this,
> > R_RISCV_ADD, A + 1
> > R_RISCV_SUB, 0
> >
> > The addend of R_RISCV_SUB will always be zero, and the summary of the
> > constants will be stored in the addend of R_RISCV_ADD/SET.  Therefore,
> > we can always add the addend of these data relocations when doing
> relocations.
> >
> > But unfortunately, I had heard that if we are using .reloc to generate
> > the data relocations will make the relocations failed.  Refer to this,
> > .reloc offset, R_RISCV_ADD32, A + 3
> > .reloc offset, R_RISCV_SUB32, B + 2
> > .word 0
> > Then we can get the relocations as follows,
> > R_RISCV_ADD, A + 3
> > R_RISCV_SUB, B + 2
> > Then...  Current LD does the relocation, B - A + 3 + 2, which is wrong
> > obviously...
> >
> > So first of all, this patch fixes the wrong relocation behavior of
> > R_RISCV_SUB* relocations.
> >
> > Afterwards, considering the uleb128 direcitve, we will get a pair of
> > SET_ULEB128/SUB_ULEB128 relocations for it for now,
> > .uleb128 (A + 3) - (B + 2)
> > R_RISCV_SET_ULEB128, A + 1
> > R_RISCV_SUB_ULEB128, B + 1
> >
> > Which looks also wrong obviously, the summary of the constants should
> only
> > be stored into the addend of SET_ULEB128, and the addend of SUB_ULEB128
> should
> > be zero like other SUB relocations.  But the current LD will still get
> the right
> > relocation values since we only add the addend of SUB_ULEB128 by
> accident...
> > Anyway, this patch also fixes the behaviors above, to make sure that no
> matter
> > using .uleb128 or .reloc directives, we should always get the right
> values.
> >
> > bfd/
> >       * elfnn-riscv.c (perform_relocation):  Clarify that SUB relocations
> >       should substract the addend, rather than add.
> >       (riscv_elf_relocate_section): Since SET_ULEB128 won't go into
> >       perform_relocation, we should add it's addend here in advance.
> > gas/
> >       * config/tc-riscv.c (riscv_insert_uleb128_fixes): Set the addend of
> >       SUB_ULEB128 to zero since it should already be added into the
> addend
> >       of SET_ULEB128.
> > ---
> >  bfd/elfnn-riscv.c     | 22 ++++++++++++++++------
> >  gas/config/tc-riscv.c |  1 +
> >  2 files changed, 17 insertions(+), 6 deletions(-)
>
> I am not familiar enough with the codebase to properly review, but this
> appears to fix the problem that I was having.
>
> Acked-by: Charlie Jenkins <charlie@rivosinc.com>
>

Thanks for the feedback, committed.

Nelson
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://sourceware.org/pipermail/binutils/attachments/20231027/a99bf953/attachment.htm>


More information about the Binutils mailing list