Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disassembler: Add arch disassembler option to RISC-V #1

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions gas/testsuite/gas/riscv/dis-arch-override-1.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#as: -march=rv64imfd_zbb
#source: dis-arch-override.s
#objdump: -d

.*:[ ]+file format .*

Disassembly of section .text:

0+000 <target>:
[ ]+[0-9a-f]+:[ ]+00c5f053[ ]+fadd.s[ ]+ft0,fa1,fa2
[ ]+[0-9a-f]+:[ ]+02c5f053[ ]+fadd.d[ ]+ft0,fa1,fa2
[ ]+[0-9a-f]+:[ ]+30102573[ ]+csrr[ ]+a0,misa
[ ]+[0-9a-f]+:[ ]+0805c53b[ ]+zext.h[ ]+a0,a1
13 changes: 13 additions & 0 deletions gas/testsuite/gas/riscv/dis-arch-override-2.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#as: -march=rv64imfd_zbb
#source: dis-arch-override.s
#objdump: -d -M arch=rv32im_zfinx_zbkb

.*:[ ]+file format .*

Disassembly of section .text:

0+000 <target>:
[ ]+[0-9a-f]+:[ ]+00c5f053[ ]+fadd.s[ ]+zero,a1,a2
[ ]+[0-9a-f]+:[ ]+02c5f053[ ]+\.4byte[ ]+0x2c5f053
[ ]+[0-9a-f]+:[ ]+30102573[ ]+csrr[ ]+a0,misa
[ ]+[0-9a-f]+:[ ]+0805c53b[ ]+packw[ ]+a0,a1,zero
13 changes: 13 additions & 0 deletions gas/testsuite/gas/riscv/dis-arch-override-3.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#as: -march=rv64imfd_zbb
#source: dis-arch-override.s
#objdump: -d -m riscv -M arch=rv32im_zfinx_zbkb,numeric

.*:[ ]+file format .*

Disassembly of section .text:

0+000 <target>:
[ ]+[0-9a-f]+:[ ]+00c5f053[ ]+fadd.s[ ]+x0,x11,x12
[ ]+[0-9a-f]+:[ ]+02c5f053[ ]+\.4byte[ ]+0x2c5f053
[ ]+[0-9a-f]+:[ ]+30102573[ ]+csrr[ ]+x10,misa
[ ]+[0-9a-f]+:[ ]+0805c53b[ ]+\.4byte[ ]+0x805c53b
45 changes: 45 additions & 0 deletions gas/testsuite/gas/riscv/dis-arch-override.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Assembler configuration:
# -march=rv64imfd_zbb
# Disassembler configurations:
# Test 1: -d
# Test 2: -d -M arch=rv32im_zfinx_zbkb
# Test 3: -d -m riscv -M arch=rv32im_zfinx_zbkb,numeric

target:
# Assembler : fadd.s (F)
# Disassembler (test 2/3) : fadd.s (Zfinx)
# Test that all three operands point to GPRs.
fadd.s ft0, fa1, fa2

# Assembler : fadd.d (D)
# Disassembler (test 2/3) : (invalid)
# On disassembler option on test 2, Zdinx is not present. So,
# it should be disassembled as an invalid instruction.
fadd.d ft0, fa1, fa2

# Assembler : csrr (Zicsr)
# Disassembler (test 2/3) : csrr (Zicsr)
# When assembling, Zicsr is implied by F. When disassembling,
# Zicsr is implied by Zfinx. On both cases, csrr should be
# disassembled as csrr.
csrr a0, misa

# Assembler : zext.h (Zbb)
# Disassembler (test 2) : packw (Zbkb)
# Disassembler (test 3) : (invalid)
# Since zext.h specialized instruction does not exist in Zbkb
# and we disassemble the output with Zbkb, this instruction
# should be disassembled as a packw instruction (on RV64).
#
# We specify arch=rv32im_zfinx_zbkb on disassembling on test
# 2 and 3. But, XLEN part of the ISA string is effective
# only if XLEN-neutral machine is specified by `-m riscv' option
# (because we are disassembling 64-bit RISC-V ELF file, BFD
# architecture is set to `riscv:rv64' unless `-m' option
# is specified).
#
# As a result, test 3 (with `-m riscv' option) disassembles with
# RV32 but test 2 (without it) does with RV64.
# It changes the result of disassembling since packw instruction
# is invalid on RV32.
zext.h a0, a1
4 changes: 4 additions & 0 deletions gdb/disasm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1269,6 +1269,8 @@ set_disassembler_options (const char *prospective_options)
if (memcmp (opt, valid_options->name[i], len) != 0)
continue;
arg = opt + len;
if (valid_options->arg[i]->values == NULL)
break;
for (j = 0; valid_options->arg[i]->values[j] != NULL; j++)
if (disassembler_options_cmp
(arg, valid_options->arg[i]->values[j]) == 0)
Expand Down Expand Up @@ -1390,6 +1392,8 @@ The following disassembler options are supported for use with the\n\

for (i = 0; valid_args[i].name != NULL; i++)
{
if (valid_args[i].values == NULL)
continue;
gdb_printf (file, _("\n\
For the options above, the following values are supported for \"%s\":\n "),
valid_args[i].name);
Expand Down
3 changes: 2 additions & 1 deletion include/dis-asm.h
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,8 @@ typedef struct
/* Option argument name to use in descriptions. */
const char *name;

/* Vector of acceptable option argument values, NULL-terminated. */
/* Vector of acceptable option argument values, NULL-terminated.
NULL if any values are accepted. */
const char **values;
} disasm_option_arg_t;

Expand Down
2 changes: 2 additions & 0 deletions opcodes/arc-dis.c
Original file line number Diff line number Diff line change
Expand Up @@ -1611,6 +1611,8 @@ print_arc_disassembler_options (FILE *stream)
for (i = 0; args[i].name != NULL; ++i)
{
size_t len = 3;
if (args[i].values == NULL)
continue;
fprintf (stream, _("\n\
For the options above, the following values are supported for \"%s\":\n "),
args[i].name);
Expand Down
2 changes: 2 additions & 0 deletions opcodes/mips-dis.c
Original file line number Diff line number Diff line change
Expand Up @@ -2809,6 +2809,8 @@ with the -M switch (multiple options should be separated by commas):\n\n"));

for (i = 0; args[i].name != NULL; i++)
{
if (args[i].values == NULL)
continue;
fprintf (stream, _("\n\
For the options above, the following values are supported for \"%s\":\n "),
args[i].name);
Expand Down
44 changes: 42 additions & 2 deletions opcodes/riscv-dis.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ static const char *default_arch = NULL;
/* Current XLEN for the disassembler. */
static unsigned xlen = 0;

/* Current XLEN, as specified by the `arch' option. */
static unsigned xlen_by_arch = 0;

/* Default ISA specification version (constant as of now). */
static enum riscv_spec_class default_isa_spec = ISA_SPEC_CLASS_DRAFT - 1;

Expand Down Expand Up @@ -84,6 +87,9 @@ static bool is_numeric = false;
/* Reset when reinitializing the CSR table is required. */
static bool is_init_csr = false;

/* If set, a custom arch option is specified. */
static bool is_custom_arch = false;


/* Initialization (for arch and options). */

Expand Down Expand Up @@ -130,6 +136,7 @@ set_default_riscv_dis_options (void)
{
no_aliases = false;
is_numeric = false;
is_custom_arch = false;
}

/* Update current architecture string
Expand All @@ -138,8 +145,11 @@ set_default_riscv_dis_options (void)
static void
update_riscv_dis_current_arch (const char *arch)
{
xlen = 0;
riscv_release_subset_list (&riscv_subsets);
riscv_parse_subset (&riscv_rps_dis, arch);
/* Ignore XLEN by arch string if arch is the initial default value. */
xlen_by_arch = (arch == initial_default_arch) ? 0 : xlen;
init_riscv_dis_state_for_arch ();
}

Expand Down Expand Up @@ -224,6 +234,11 @@ parse_riscv_dis_option (const char *option)
option, value, name);
}
}
else if (strcmp (option, "arch") == 0)
{
is_custom_arch = true;
update_riscv_dis_current_arch (value);
}
else
{
/* xgettext:c-format */
Expand All @@ -235,6 +250,7 @@ static void
parse_riscv_dis_options (const char *opts_in)
{
char *opts = xstrdup (opts_in), *opt = opts, *opt_end = opts;
bool prev_is_custom_arch = is_custom_arch;

set_default_riscv_dis_options ();

Expand All @@ -246,6 +262,8 @@ parse_riscv_dis_options (const char *opts_in)
}

free (opts);
if (prev_is_custom_arch && !is_custom_arch)
update_riscv_dis_current_arch (default_arch);
}

/* Print one argument from an array. */
Expand Down Expand Up @@ -759,11 +777,24 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
info->target = 0;
info->target2 = 0;

/* If XLEN is not known, get its value from the ELF class. */
/* Set XLEN with following precedence rules:
1. BFD architecture set by either:
a. -m riscv:rv[32|64] option (gdb: set arch riscv:rv[32|64])
b. ELF class in actual ELF header (only on RISC-V ELF)
This is only effective if XLEN-specific BFD architecture is
chosen. If chosen BFD architecture is XLEN-neutral
(like riscv), BFD architecture is ignored on XLEN selection.
2. RISC-V ISA string set by either:
a. -M arch=rv[32|64]... option
(gdb: set disassembler-options arch=...)
b. RISC-V ELF attributes (only on RISC-V ELF)
3. ELF class in dummy ELF header */
if (info->mach == bfd_mach_riscv64)
xlen = 64;
else if (info->mach == bfd_mach_riscv32)
xlen = 32;
else if (xlen_by_arch)
xlen = xlen_by_arch;
else if (info->section != NULL)
{
Elf_Internal_Ehdr *ehdr = elf_elfheader (info->section->owner);
Expand Down Expand Up @@ -1161,7 +1192,7 @@ riscv_get_disassembler (bfd *abfd)
}
}

if (update_riscv_dis_default_arch (default_arch_next))
if (update_riscv_dis_default_arch (default_arch_next) && !is_custom_arch)
update_riscv_dis_current_arch (default_arch_next);
init_riscv_dis_state_for_arch_and_options ();
return print_insn_riscv;
Expand Down Expand Up @@ -1192,6 +1223,7 @@ riscv_symbol_is_valid (asymbol * sym,
typedef enum
{
RISCV_OPTION_ARG_NONE = -1,
RISCV_OPTION_ARG_ARCH,
RISCV_OPTION_ARG_PRIV_SPEC,

RISCV_OPTION_ARG_COUNT
Expand All @@ -1212,6 +1244,9 @@ static struct
{ "no-aliases",
N_("Disassemble only into canonical instructions."),
RISCV_OPTION_ARG_NONE },
{ "arch=",
N_("Disassemble using chosen ISA and extensions."),
RISCV_OPTION_ARG_ARCH },
{ "priv-spec=",
N_("Print the CSR according to the chosen privilege spec."),
RISCV_OPTION_ARG_PRIV_SPEC }
Expand All @@ -1236,6 +1271,9 @@ disassembler_options_riscv (void)

args = XNEWVEC (disasm_option_arg_t, num_args + 1);

args[RISCV_OPTION_ARG_ARCH].name = "ARCH";
args[RISCV_OPTION_ARG_ARCH].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
Expand Down Expand Up @@ -1324,6 +1362,8 @@ with the -M switch (multiple options should be separated by commas):\n"));

for (i = 0; args[i].name != NULL; i++)
{
if (args[i].values == NULL)
continue;
fprintf (stream, _("\n\
For the options above, the following values are supported for \"%s\":\n "),
args[i].name);
Expand Down