Skip to content

Commit

Permalink
RISC-V: Mapping symbols with ISA string on disassembler
Browse files Browse the repository at this point in the history
The mapping symbols with ISA string is proposed to deal with so called
"ifunc issue".  It enables disassembling a certain range of the code with
a different architecture than the rest, even if conflicting.  This is useful
when there's "optimized" implementation is available but dynamically
switched only if a certain extension is available.

This commit implements the disassembler support to parse mapping symbols
with ISA string.

[1] Proposal: Extend .option directive for control enabled extensions on
specific code region,
riscv-non-isa/riscv-asm-manual#67

[2] Proposal: Add mapping symbol,
riscv-non-isa/riscv-elf-psabi-doc#196

This commit is based on Nelson Chu's proposal "RISC-V: Output mapping
symbols with ISA string once .option arch is used." but heavily modified to
reflect the intent of Kito's original proposal.  It is also made smarter so
that it no longer requires MAP_INSN_ARCH.

gas/ChangeLog:

	* testsuite/gas/riscv/option-arch-01a.d: Reflect the disassembler
	support of mapping symbols with ISA string.

opcodes/ChangeLog:

	* riscv-dis.c (initial_default_arch) Default architecture string if
	no ELF attributes are available.
	(default_arch): A copy of the default architecture string.
	(is_arch_mapping): New variable to keep track of whether the current
	architecture is deviced from a mapping symbol.
	(riscv_disassemble_insn): Update FPR names when a mapping symbol
	with ISA string is encountered.
	(riscv_get_map_state): Support mapping symbols with ISA string.
	Use `is_arch_mapping' to stop repeatedly parsing the default
	architecture.
	(riscv_get_disassembler): Safer architecture string handling.
	Copy the string to switch to the default while disassembling.
  • Loading branch information
a4lg committed Aug 11, 2022
1 parent 8f452c1 commit 20bb37e
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 5 deletions.
2 changes: 1 addition & 1 deletion gas/testsuite/gas/riscv/option-arch-01a.d
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ Disassembly of section .text:
0+000 <.text>:
[ ]+[0-9a-f]+:[ ]+952e[ ]+add[ ]+a0,a0,a1
[ ]+[0-9a-f]+:[ ]+00b50533[ ]+add[ ]+a0,a0,a1
[ ]+[0-9a-f]+:[ ]+00302573[ ]+csrr[ ]+a0,fcsr
[ ]+[0-9a-f]+:[ ]+00302573[ ]+frcsr[ ]+a0
#...
44 changes: 40 additions & 4 deletions opcodes/riscv-dis.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@
#include <stdint.h>
#include <ctype.h>

/* Default architecture string (if not available). */
static const char *initial_default_arch = "rv64gc";

/* Default architecture string
(as specified by the ELF attributes or `initial_default_arch'). */
static const char *default_arch = NULL;

/* True if the architecture is set from a mapping symbol. */
static bool is_arch_mapping = false;

static enum riscv_spec_class default_isa_spec = ISA_SPEC_CLASS_DRAFT - 1;
static enum riscv_spec_class default_priv_spec = PRIV_SPEC_CLASS_NONE;

Expand Down Expand Up @@ -638,8 +648,12 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
}

/* If arch has ZFINX flags, use gpr for disassemble. */
if(riscv_subset_supports (&riscv_rps_dis, "zfinx"))
if (riscv_subset_supports (&riscv_rps_dis, "zfinx"))
riscv_fpr_names = riscv_gpr_names;
else
riscv_fpr_names = riscv_gpr_names == riscv_gpr_names_abi
? riscv_fpr_names_abi
: riscv_fpr_names_numeric;

for (; op->name; op++)
{
Expand Down Expand Up @@ -750,8 +764,23 @@ riscv_get_map_state (int n,
return false;

name = bfd_asymbol_name(info->symtab[n]);
if (startswith (name, "$x"))
if (startswith (name, "$xrv"))
{
*state = MAP_INSN;
riscv_release_subset_list (&riscv_subsets);
riscv_parse_subset (&riscv_rps_dis, name + 2);
is_arch_mapping = true;
}
else if (strcmp (name, "$x") == 0)
{
*state = MAP_INSN;
if (is_arch_mapping)
{
riscv_release_subset_list (&riscv_subsets);
riscv_parse_subset (&riscv_rps_dis, default_arch);
is_arch_mapping = false;
}
}
else if (strcmp (name, "$d") == 0)
*state = MAP_DATA;
else
Expand Down Expand Up @@ -1000,7 +1029,7 @@ print_insn_riscv (bfd_vma memaddr, struct disassemble_info *info)
disassembler_ftype
riscv_get_disassembler (bfd *abfd)
{
const char *default_arch = "rv64gc";
const char *default_arch_next = initial_default_arch;

if (abfd && bfd_get_flavour (abfd) == bfd_target_elf_flavour)
{
Expand All @@ -1015,12 +1044,19 @@ riscv_get_disassembler (bfd *abfd)
attr[Tag_b].i,
attr[Tag_c].i,
&default_priv_spec);
default_arch = attr[Tag_RISCV_arch].s;
default_arch_next = attr[Tag_RISCV_arch].s;
/* For ELF files with (somehow) no architecture string
in the attributes, use the default value. */
if (!default_arch_next)
default_arch_next = initial_default_arch;
}
}
free ((void *) default_arch);
default_arch = xstrdup (default_arch_next);

riscv_release_subset_list (&riscv_subsets);
riscv_parse_subset (&riscv_rps_dis, default_arch);
is_arch_mapping = false;
return print_insn_riscv;
}

Expand Down

0 comments on commit 20bb37e

Please sign in to comment.