Skip to content

Commit

Permalink
RISC-V: Print top GP-relative addresses on the disassembler
Browse files Browse the repository at this point in the history
This patch makes possible to print the address relative to the global
pointer even if the corresponding symbol is the highest address (0xffffffff
on RV32, 0xffffffff_ffffffff on RV64).

Despite that it is very rare to have GP the highest address, it would be
nice because we enabled highest address printing on regular cases.

opcodes/ChangeLog:

	* riscv-dis.c (struct riscv_private_data): Add `has_gp' to enable
	printing the addresses relative to GP with the highest address.
	(maybe_print_address): Utilize `has_gp'.
	(riscv_disassemble_insn): Likewise.

gas/ChangeLog:

	* testsuite/gas/riscv/dis-addr-topaddr-gp.s: New test for GP-
	relative addressing when GP is the highest address.
	* testsuite/gas/riscv/dis-addr-topaddr-gp-32.d: Likewise.
	* testsuite/gas/riscv/dis-addr-topaddr-gp-64.d: Likewise.
  • Loading branch information
a4lg committed Sep 1, 2022
1 parent b6e5117 commit 154e28c
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 3 deletions.
12 changes: 12 additions & 0 deletions gas/testsuite/gas/riscv/dis-addr-topaddr-gp-32.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#as: -march=rv32i
#source: dis-addr-topaddr-gp.s
#objdump: -d

.*: file format elf32-(little|big)riscv


Disassembly of section .text:

0+000 <target>:
[ ]+[0-9a-f]+:[ ]+0051a283[ ]+lw[ ]+t0,5\(gp\) # 4 <addr_rel_gp_pos>
[ ]+[0-9a-f]+:[ ]+ffd1a303[ ]+lw[ ]+t1,-3\(gp\) # fffffffc <addr_rel_gp_neg>
12 changes: 12 additions & 0 deletions gas/testsuite/gas/riscv/dis-addr-topaddr-gp-64.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#as: -march=rv64i -defsym rv64=1
#source: dis-addr-topaddr-gp.s
#objdump: -d

.*: file format elf64-(little|big)riscv


Disassembly of section .text:

0+000 <target>:
[ ]+[0-9a-f]+:[ ]+0051a283[ ]+lw[ ]+t0,5\(gp\) # 4 <addr_rel_gp_pos>
[ ]+[0-9a-f]+:[ ]+ffd1a303[ ]+lw[ ]+t1,-3\(gp\) # fffffffffffffffc <addr_rel_gp_neg>
15 changes: 15 additions & 0 deletions gas/testsuite/gas/riscv/dis-addr-topaddr-gp.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.ifdef rv64
topbase = 0xffffffff00000000
.else
topbase = 0
.endif

.set __global_pointer$, topbase + 0xffffffff # -1
.set addr_rel_gp_pos, 0x00000004 # +4
.set addr_rel_gp_neg, topbase + 0xfffffffc # -4

target:
# Use addresses relative to gp
# (gp is the highest address)
lw t0, +5(gp)
lw t1, -3(gp)
11 changes: 8 additions & 3 deletions opcodes/riscv-dis.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ struct riscv_private_data
bfd_vma print_addr;
bfd_vma hi_addr[OP_MASK_RD + 1];
bool to_print_addr;
bool has_gp;
};

/* Used for mapping symbols. */
Expand Down Expand Up @@ -178,7 +179,7 @@ maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset,
pd->print_addr = (base_reg != 0 ? pd->hi_addr[base_reg] : 0) + offset;
pd->hi_addr[base_reg] = -1;
}
else if (base_reg == X_GP && pd->gp != (bfd_vma)-1)
else if (base_reg == X_GP && pd->has_gp)
pd->print_addr = pd->gp + offset;
else if (base_reg == X_TP || base_reg == 0)
pd->print_addr = offset;
Expand Down Expand Up @@ -603,15 +604,19 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
int i;

pd = info->private_data = xcalloc (1, sizeof (struct riscv_private_data));
pd->gp = -1;
pd->gp = 0;
pd->print_addr = 0;
for (i = 0; i < (int)ARRAY_SIZE (pd->hi_addr); i++)
pd->hi_addr[i] = -1;
pd->to_print_addr = false;
pd->has_gp = false;

for (i = 0; i < info->symtab_size; i++)
if (strcmp (bfd_asymbol_name (info->symtab[i]), RISCV_GP_SYMBOL) == 0)
pd->gp = bfd_asymbol_value (info->symtab[i]);
{
pd->gp = bfd_asymbol_value (info->symtab[i]);
pd->has_gp = true;
}
}
else
pd = info->private_data;
Expand Down

0 comments on commit 154e28c

Please sign in to comment.