[RFC PATCH v2 2/2] RISC-V: Add isa disassembler option
Tsukasa OI
research_trasio@irq.a4lg.com
Sun Feb 6 02:10:37 GMT 2022
This commit adds isa=ISA disassembler option to objdump and gdb.
ISA string given has a higher precedence than ELF header but lower than
BFD architecture with specific XLEN (riscv:rv32 and riscv:rv64).
opcodes/ChangeLog:
* riscv-dis.c (default_isa): Rename from local `default_arch'.
(xlen_by_isa) New. (set_default_riscv_dis_options): Initialize
default ISA and RISC-V subset.
(parse_riscv_dis_option): Parse isa=ISA option with resetting
previous XLEN.
(riscv_disassemble_insn): Update XLEN precedence rules.
(riscv_get_disassembler): Stop setting default ISA here.
Instead, pass default ISA for later initialization.
(riscv_option_arg_t): Add arguments for isa=ISA option.
(riscv_options): Add isa=ISA option.
(disassembler_options_riscv): Add handling for isa=ISA.
---
opcodes/riscv-dis.c | 33 ++++++++++++++++++++++++++-------
1 file changed, 26 insertions(+), 7 deletions(-)
diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index 13ddff01c52..ae4c5893063 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -34,8 +34,10 @@
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;
+static const char *default_isa = "rv64gc";
unsigned xlen = 0;
+static unsigned xlen_by_isa = 0;
static riscv_subset_list_t riscv_subsets;
static riscv_parse_subset_t riscv_rps_dis =
@@ -71,6 +73,9 @@ set_default_riscv_dis_options (void)
riscv_gpr_names = riscv_gpr_names_abi;
riscv_fpr_names = riscv_fpr_names_abi;
no_aliases = 0;
+ riscv_release_subset_list (&riscv_subsets);
+ riscv_parse_subset (&riscv_rps_dis, default_isa);
+ xlen_by_isa = 0;
}
static bool
@@ -134,6 +139,13 @@ parse_riscv_dis_option (const char *option)
option, value, name);
}
}
+ else if (strcmp (option, "isa") == 0)
+ {
+ xlen = 0;
+ riscv_release_subset_list (&riscv_subsets);
+ riscv_parse_subset (&riscv_rps_dis, value);
+ xlen_by_isa = xlen;
+ }
else
{
/* xgettext:c-format */
@@ -592,11 +604,16 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
op = riscv_hash[OP_HASH_IDX (word)];
if (op != NULL)
{
- /* If XLEN is not known, get its value from the ELF class. */
+ /* Set XLEN with following precedence rules:
+ 1. -m riscv:rv[32|64] option (gdb: set arch riscv:rv[32|64])
+ 2. -M isa=rv[32|64]... option (gdb: set disassembler-options isa=...)
+ 3. ELF class in the ELF header. */
if (info->mach == bfd_mach_riscv64)
xlen = 64;
else if (info->mach == bfd_mach_riscv32)
xlen = 32;
+ else if (xlen_by_isa)
+ xlen = xlen_by_isa;
else if (info->section != NULL)
{
Elf_Internal_Ehdr *ehdr = elf_elfheader (info->section->owner);
@@ -947,8 +964,6 @@ print_insn_riscv (bfd_vma memaddr, struct disassemble_info *info)
disassembler_ftype
riscv_get_disassembler (bfd *abfd)
{
- const char *default_arch = "rv64gc";
-
if (abfd)
{
const struct elf_backend_data *ebd = get_elf_backend_data (abfd);
@@ -965,13 +980,10 @@ riscv_get_disassembler (bfd *abfd)
attr[Tag_b].i,
attr[Tag_c].i,
&default_priv_spec);
- default_arch = attr[Tag_RISCV_arch].s;
+ default_isa = attr[Tag_RISCV_arch].s;
}
}
}
-
- riscv_release_subset_list (&riscv_subsets);
- riscv_parse_subset (&riscv_rps_dis, default_arch);
return print_insn_riscv;
}
@@ -1000,6 +1012,7 @@ riscv_symbol_is_valid (asymbol * sym,
typedef enum
{
RISCV_OPTION_ARG_NONE = -1,
+ RISCV_OPTION_ARG_ISA,
RISCV_OPTION_ARG_PRIV_SPEC,
RISCV_OPTION_ARG_COUNT
@@ -1020,6 +1033,9 @@ static struct
{ "no-aliases",
N_("Disassemble only into canonical instructions."),
RISCV_OPTION_ARG_NONE },
+ { "isa=",
+ N_("Disassemble using chosen ISA and extensions."),
+ RISCV_OPTION_ARG_ISA },
{ "priv-spec=",
N_("Print the CSR according to the chosen privilege spec."),
RISCV_OPTION_ARG_PRIV_SPEC }
@@ -1044,6 +1060,9 @@ disassembler_options_riscv (void)
args = XNEWVEC (disasm_option_arg_t, num_args + 1);
+ args[RISCV_OPTION_ARG_ISA].name = "ISA";
+ args[RISCV_OPTION_ARG_ISA].values = NULL;
+
args[RISCV_OPTION_ARG_PRIV_SPEC].name = "SPEC";
priv_spec_count = PRIV_SPEC_CLASS_DRAFT - PRIV_SPEC_CLASS_NONE - 1;
args[RISCV_OPTION_ARG_PRIV_SPEC].values
--
2.32.0
More information about the Binutils
mailing list