On Sat, Oct 21, 2023 at 1:58 AM Charlie Jenkins 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 > Thanks for the feedback, committed. Nelson