From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-sender-0.a4lg.com (mail-sender.a4lg.com [153.120.152.154]) by sourceware.org (Postfix) with ESMTPS id A4119389850F; Sun, 20 Nov 2022 02:24:15 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org A4119389850F Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=irq.a4lg.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=irq.a4lg.com Received: from [127.0.0.1] (localhost [127.0.0.1]) by mail-sender-0.a4lg.com (Postfix) with ESMTPSA id F2F56300089; Sun, 20 Nov 2022 02:24:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=irq.a4lg.com; s=2017s01; t=1668911054; bh=i/OcYqt9FaY8kwx6z12Y1Ri6Um4hxoYATCnQMmTy8KE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: Mime-Version:Content-Transfer-Encoding; b=SRAXK0ZZjvi7JhV1FFopTm3iRd6DpjIIQQ5wKj8eg+gI4DScwmXayxOKwGdUYP0qf DQU8eE+yi0RCkPE/xr9yUP067/vlY6pCDbjOnOuSx7hsadbMMH5nwxZrYKGT4u0dwA vNw/MklkvcFtXZWUtza/AjqWkso1o8I566JOWyPc= From: Tsukasa OI To: Tsukasa OI , Nelson Chu , Kito Cheng , Palmer Dabbelt Cc: binutils@sourceware.org, gdb-patches@sourceware.org Subject: [PATCH v3 2/3] RISC-V: Add "arch" disassembler option Date: Sun, 20 Nov 2022 02:23:28 +0000 Message-Id: <9d6008e38402c4e60ada6f3d3db14b92815177d8.1668910970.git.research_trasio@irq.a4lg.com> In-Reply-To: References: Mime-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,GIT_PATCH_0,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: From: Tsukasa OI This commit adds new disassembler option "arch" to override architecture string. Existing implementations is helpful on regular ELF files but for instance, when debugging a binary with OpenOCD + GDB, there's a case where such information is not available. Also, there's a case where changing the architecture to disassemble is helpful, even on ELF files. For instance, OpenSBI is the prime example. This commit enables objdump and GDB to use custom architecture string instead of ELF attributes and mapping symbols (e.g. even if OpenSBI is compiled with -march=rv64gc, we can enable H extension when disassembling OpenSBI by specifying an architecture string: rv64gch). It can be also helpful to test overwrapping encodings (e.g. standard hints). gas/ChangeLog: * testsuite/gas/riscv/dis-arch-override.s: New arch override tests. * testsuite/gas/riscv/dis-arch-override-1.d: Likewise. * testsuite/gas/riscv/dis-arch-override-2.d: Likewise. * testsuite/gas/riscv/dis-arch-override-3.d: Likewise. opcodes/ChangeLog: * riscv-dis.c (is_custom_arch) New. (update_riscv_dis_xlen): Update XLEN precedence rules. (set_default_riscv_dis_options): Initialize "arch". (parse_riscv_dis_option): Add the "arch" option. (riscv_get_map_state): Ignore ISA string from mapping symbols if custom "arch" is specified. (riscv_get_disassembler): Update the architecture depending on the custom "arch" option. (riscv_option_arg_t) Add RISCV_OPTION_ARG_ARCH. (riscv_options): Add the "arch" option. (disassembler_options_riscv): Add the "arch" option. --- gas/testsuite/gas/riscv/dis-arch-override-1.d | 13 ++++++ gas/testsuite/gas/riscv/dis-arch-override-2.d | 13 ++++++ gas/testsuite/gas/riscv/dis-arch-override-3.d | 13 ++++++ gas/testsuite/gas/riscv/dis-arch-override.s | 45 +++++++++++++++++++ opcodes/riscv-dis.c | 30 +++++++++++-- 5 files changed, 111 insertions(+), 3 deletions(-) create mode 100644 gas/testsuite/gas/riscv/dis-arch-override-1.d create mode 100644 gas/testsuite/gas/riscv/dis-arch-override-2.d create mode 100644 gas/testsuite/gas/riscv/dis-arch-override-3.d create mode 100644 gas/testsuite/gas/riscv/dis-arch-override.s diff --git a/gas/testsuite/gas/riscv/dis-arch-override-1.d b/gas/testsuite/gas/riscv/dis-arch-override-1.d new file mode 100644 index 000000000000..1df81236e2aa --- /dev/null +++ b/gas/testsuite/gas/riscv/dis-arch-override-1.d @@ -0,0 +1,13 @@ +#as: -march=rv64imfd_zbb +#source: dis-arch-override.s +#objdump: -d + +.*:[ ]+file format .* + +Disassembly of section .text: + +0+000 : +[ ]+[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 diff --git a/gas/testsuite/gas/riscv/dis-arch-override-2.d b/gas/testsuite/gas/riscv/dis-arch-override-2.d new file mode 100644 index 000000000000..a556f293fb52 --- /dev/null +++ b/gas/testsuite/gas/riscv/dis-arch-override-2.d @@ -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 : +[ ]+[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 diff --git a/gas/testsuite/gas/riscv/dis-arch-override-3.d b/gas/testsuite/gas/riscv/dis-arch-override-3.d new file mode 100644 index 000000000000..924da72b2797 --- /dev/null +++ b/gas/testsuite/gas/riscv/dis-arch-override-3.d @@ -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 : +[ ]+[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 diff --git a/gas/testsuite/gas/riscv/dis-arch-override.s b/gas/testsuite/gas/riscv/dis-arch-override.s new file mode 100644 index 000000000000..0c2fec44ed3a --- /dev/null +++ b/gas/testsuite/gas/riscv/dis-arch-override.s @@ -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 diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c index e7dded63c402..03272d4f64ce 100644 --- a/opcodes/riscv-dis.c +++ b/opcodes/riscv-dis.c @@ -35,6 +35,9 @@ /* Default architecture string (if not available). */ static const char *const initial_default_arch = "rv64gc"; +/* If set, a custom architecture string is specified. */ +static bool is_custom_arch = false; + /* Current XLEN for the disassembler. */ static unsigned xlen = 0; @@ -183,8 +186,10 @@ update_riscv_dis_xlen (struct disassemble_info *info) This is only effective if XLEN-specific BFD machine architecture is chosen. If XLEN-neutral (like riscv), BFD machine architecture is ignored on XLEN selection. - 2. Non-default RISC-V architecture string set by either an ELF - attribute or a mapping symbol with ISA string. + 2. Non-default RISC-V architecture string set by either: + a. -M arch=... option (GDB: set disassembler-options arch=...), + b. A mapping symbol with ISA string or + c. An ELF attribute 3. ELF class in dummy ELF header. */ if (xlen_by_mach != 0) xlen = xlen_by_mach; @@ -294,6 +299,7 @@ set_default_riscv_dis_options (void) no_aliases = false; is_numeric = false; is_custom_priv_spec = false; + is_custom_arch = false; } /* Parse RISC-V disassembler option (without arguments). */ @@ -355,6 +361,11 @@ parse_riscv_dis_option (const char *option) priv_spec = priv_spec_new; } } + else if (strcmp (option, "arch") == 0) + { + is_custom_arch = true; + update_riscv_dis_arch (&dis_arch_context_override, value); + } else { /* xgettext:c-format */ @@ -1024,6 +1035,9 @@ riscv_get_map_state (int n, *state = newstate; if (newstate == MAP_INSN && update) { + /* Skip if a custom architecture is specified. */ + if (is_custom_arch) + return true; if (arch) { /* Override the architecture. */ @@ -1308,7 +1322,10 @@ riscv_get_disassembler (bfd *abfd) } } - update_riscv_dis_arch (&dis_arch_context_default, default_arch); + if (is_custom_arch) + set_riscv_dis_arch_context (&dis_arch_context_default, default_arch); + else + update_riscv_dis_arch (&dis_arch_context_default, default_arch); return print_insn_riscv; } @@ -1359,6 +1376,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 @@ -1376,6 +1394,9 @@ static struct { "numeric", N_("Print numeric register names, rather than ABI names."), RISCV_OPTION_ARG_NONE }, + { "arch=", + N_("Disassemble using specified ISA and extensions."), + RISCV_OPTION_ARG_ARCH }, { "no-aliases", N_("Disassemble only into canonical instructions."), RISCV_OPTION_ARG_NONE }, @@ -1403,6 +1424,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 -- 2.38.1