public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Tsukasa OI <research_trasio@irq.a4lg.com>
To: Tsukasa OI <research_trasio@irq.a4lg.com>,
	Nelson Chu <nelson@rivosinc.com>,
	Kito Cheng <kito.cheng@sifive.com>,
	Palmer Dabbelt <palmer@dabbelt.com>
Cc: binutils@sourceware.org, gdb-patches@sourceware.org
Subject: [PATCH v3 1/3] RISC-V: Make "priv-spec" overridable
Date: Sun, 20 Nov 2022 02:23:27 +0000	[thread overview]
Message-ID: <94304c8d9174ae7e9cf52abc3af6ccf5e3e0ecd9.1668910970.git.research_trasio@irq.a4lg.com> (raw)
In-Reply-To: <cover.1668910970.git.research_trasio@irq.a4lg.com>

From: Tsukasa OI <research_trasio@irq.a4lg.com>

This commit makes existing disassembler option "priv-spec" overridable on
ELF files with attributes.

Existing implementation is helpful on debugging binary files but on ELF
files, the value specified by "priv-spec" option must match the attributes.

However, there's a case where privileged specification ELF attributes and
actual CSRs as used in the program differs.  For instance, OpenSBI is the
prime example.

This commit enables objdump and GDB to ignore ELF attributes but instead
use custom specification (e.g. even if OpenSBI is compiled with priv-spec
1.11 toolchain, we can correctly disassemble with priv-spec=1.12 option).

gas/ChangeLog:

	* testsuite/gas/riscv/dis-priv-spec-override.s: New privileged
	specification override tests.
	* testsuite/gas/riscv/dis-priv-spec-override-1.d: Likewise.
	* testsuite/gas/riscv/dis-priv-spec-override-2.d: Likewise.

opcodes/ChangeLog:

	* riscv-dis.c (default_priv_spec) Set to initial default version.
	(priv_spec, is_custom_priv_spec) New.
	(is_init_csr): Define as a file-scope variable instead a local
	variable of print_insn_args.
	(init_riscv_dis_state_for_arch_and_options): Keep track of
	"priv-spec" changes.
	(set_default_riscv_dis_options): Initialize "priv-spec".
	(parse_riscv_dis_option): Make "priv-spec" overridable.
	(print_insn_args): Use file-scope is_init_csr variable.
	(riscv_get_disassembler): Move fallback of default_priv_spec
	from print_insn_args.  Initialize "priv-spec".
---
 .../gas/riscv/dis-priv-spec-override-1.d      | 10 +++
 .../gas/riscv/dis-priv-spec-override-2.d      | 10 +++
 .../gas/riscv/dis-priv-spec-override.s        |  2 +
 opcodes/riscv-dis.c                           | 70 ++++++++++++-------
 4 files changed, 68 insertions(+), 24 deletions(-)
 create mode 100644 gas/testsuite/gas/riscv/dis-priv-spec-override-1.d
 create mode 100644 gas/testsuite/gas/riscv/dis-priv-spec-override-2.d
 create mode 100644 gas/testsuite/gas/riscv/dis-priv-spec-override.s

diff --git a/gas/testsuite/gas/riscv/dis-priv-spec-override-1.d b/gas/testsuite/gas/riscv/dis-priv-spec-override-1.d
new file mode 100644
index 000000000000..2cceebbf35a4
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-priv-spec-override-1.d
@@ -0,0 +1,10 @@
+#as: -march=rv64i_zicsr -mpriv-spec=1.11
+#source: dis-priv-spec-override.s
+#objdump: -d -M priv-spec=1.12
+
+.*:[ 	]+file format .*
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+3d002573[ 	]+csrr[ 	]+a0,pmpaddr32
diff --git a/gas/testsuite/gas/riscv/dis-priv-spec-override-2.d b/gas/testsuite/gas/riscv/dis-priv-spec-override-2.d
new file mode 100644
index 000000000000..200955e0ffe5
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-priv-spec-override-2.d
@@ -0,0 +1,10 @@
+#as: -march=rv64i_zicsr -mpriv-spec=1.12
+#source: dis-priv-spec-override.s
+#objdump: -d -M priv-spec=1.11
+
+.*:[ 	]+file format .*
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+3d002573[ 	]+csrr[ 	]+a0,0x3d0
diff --git a/gas/testsuite/gas/riscv/dis-priv-spec-override.s b/gas/testsuite/gas/riscv/dis-priv-spec-override.s
new file mode 100644
index 000000000000..c3d1726e0b5a
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-priv-spec-override.s
@@ -0,0 +1,2 @@
+target:
+	csrr	a0, 0x3d0
diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index 328a34501549..e7dded63c402 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -49,7 +49,16 @@ static enum riscv_spec_class default_isa_spec = ISA_SPEC_CLASS_DRAFT - 1;
 
 /* Default privileged specification
    (as specified by the ELF attributes or the `priv-spec' option).  */
-static enum riscv_spec_class default_priv_spec = PRIV_SPEC_CLASS_NONE;
+static enum riscv_spec_class default_priv_spec = PRIV_SPEC_CLASS_DRAFT - 1;
+
+/* Current privileged specification version.  */
+static enum riscv_spec_class priv_spec = PRIV_SPEC_CLASS_DRAFT - 1;
+
+/* If set, a custom privileged specification is specified.  */
+static bool is_custom_priv_spec = false;
+
+/* Reset when reinitializing the CSR hash table is required.  */
+static bool is_init_csr = false;
 
 /* RISC-V disassembler architecture context type.  */
 typedef struct
@@ -205,6 +214,18 @@ init_riscv_dis_state_for_arch (void)
 static void
 init_riscv_dis_state_for_arch_and_options (void)
 {
+  static bool init = false;
+  static enum riscv_spec_class prev_priv_spec;
+  /* Set current privileged specification.  */
+  if (!is_custom_priv_spec)
+    priv_spec = default_priv_spec;
+  /* First call to this function.  */
+  if (!init)
+    {
+      init = true;
+      /* Save initial options.  */
+      prev_priv_spec = priv_spec;
+    }
   /* If the architecture string is changed, update XLEN.  */
   if (is_arch_changed)
     update_riscv_dis_xlen (NULL);
@@ -215,7 +236,12 @@ init_riscv_dis_state_for_arch_and_options (void)
       = !riscv_subset_supports (&riscv_rps_dis, "zfinx")
 	    ? (is_numeric ? riscv_fpr_names_numeric : riscv_fpr_names_abi)
 	    : riscv_gpr_names;
+  /* Reset CSR hash table if either the architecture or the privileged
+     specification version is changed.  */
+  if (prev_priv_spec != priv_spec)
+    is_init_csr = false;
   /* Save previous options and mark them "unchanged".  */
+  prev_priv_spec = priv_spec;
   is_arch_changed = false;
 }
 
@@ -267,6 +293,7 @@ set_default_riscv_dis_options (void)
 {
   no_aliases = false;
   is_numeric = false;
+  is_custom_priv_spec = false;
 }
 
 /* Parse RISC-V disassembler option (without arguments).  */
@@ -314,21 +341,18 @@ parse_riscv_dis_option (const char *option)
   value = equal + 1;
   if (strcmp (option, "priv-spec") == 0)
     {
-      enum riscv_spec_class priv_spec = PRIV_SPEC_CLASS_NONE;
-      const char *name = NULL;
-
-      RISCV_GET_PRIV_SPEC_CLASS (value, priv_spec);
-      if (priv_spec == PRIV_SPEC_CLASS_NONE)
-	opcodes_error_handler (_("unknown privileged spec set by %s=%s"),
-			       option, value);
-      else if (default_priv_spec == PRIV_SPEC_CLASS_NONE)
-	default_priv_spec = priv_spec;
-      else if (default_priv_spec != priv_spec)
+      enum riscv_spec_class priv_spec_new = PRIV_SPEC_CLASS_NONE;
+      RISCV_GET_PRIV_SPEC_CLASS (value, priv_spec_new);
+      if (priv_spec_new == PRIV_SPEC_CLASS_NONE)
 	{
-	  RISCV_GET_PRIV_SPEC_NAME (name, default_priv_spec);
-	  opcodes_error_handler (_("mis-matched privilege spec set by %s=%s, "
-				   "the elf privilege attribute is %s"),
-				 option, value, name);
+	  opcodes_error_handler (_ ("unknown privileged spec set by %s=%s."
+				    "not overriding"),
+				 option, value);
+	}
+      else
+	{
+	  is_custom_priv_spec = true;
+	  priv_spec = priv_spec_new;
 	}
     }
   else
@@ -721,31 +745,26 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 	case 'E':
 	  {
 	    static const char *riscv_csr_hash[4096]; /* Total 2^12 CSRs.  */
-	    static bool init_csr = false;
 	    unsigned int csr = EXTRACT_OPERAND (CSR, l);
 
-	    if (!init_csr)
+	    if (!is_init_csr)
 	      {
 		unsigned int i;
 		for (i = 0; i < 4096; i++)
 		  riscv_csr_hash[i] = NULL;
 
-		/* Set to the newest privileged version.  */
-		if (default_priv_spec == PRIV_SPEC_CLASS_NONE)
-		  default_priv_spec = PRIV_SPEC_CLASS_DRAFT - 1;
-
 #define DECLARE_CSR(name, num, class, define_version, abort_version)	\
 		if (riscv_csr_hash[num] == NULL 			\
 		    && ((define_version == PRIV_SPEC_CLASS_NONE 	\
 			 && abort_version == PRIV_SPEC_CLASS_NONE)	\
-			|| (default_priv_spec >= define_version 	\
-			    && default_priv_spec < abort_version)))	\
+			|| (priv_spec >= define_version 	\
+			    && priv_spec < abort_version)))	\
 		  riscv_csr_hash[num] = #name;
 #define DECLARE_CSR_ALIAS(name, num, class, define_version, abort_version) \
 		DECLARE_CSR (name, num, class, define_version, abort_version)
 #include "opcode/riscv-opc.h"
 #undef DECLARE_CSR
-		init_csr = true;
+		is_init_csr = true;
 	      }
 
 	    if (riscv_csr_hash[csr] != NULL)
@@ -1283,6 +1302,9 @@ riscv_get_disassembler (bfd *abfd)
 	     in the attributes, use the default value.  */
 	  if (!default_arch)
 	    default_arch = initial_default_arch;
+	  /* By default, set to the newest privileged version.  */
+	  if (default_priv_spec == PRIV_SPEC_CLASS_NONE)
+	    default_priv_spec = PRIV_SPEC_CLASS_DRAFT - 1;
 	}
     }
 
-- 
2.38.1


  reply	other threads:[~2022-11-20  2:24 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-20  2:23 [PATCH v3 0/3] RISC-V: Add overridable "priv-spec" and "arch" disassembler options Tsukasa OI
2022-11-20  2:23 ` Tsukasa OI [this message]
2022-11-20  2:23 ` [PATCH v3 2/3] RISC-V: Add "arch" disassembler option Tsukasa OI
2022-11-20  2:23 ` [PATCH v3 3/3] gdb/testsuite: RISC-V disassembler option tests Tsukasa OI

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=94304c8d9174ae7e9cf52abc3af6ccf5e3e0ecd9.1668910970.git.research_trasio@irq.a4lg.com \
    --to=research_trasio@irq.a4lg.com \
    --cc=binutils@sourceware.org \
    --cc=gdb-patches@sourceware.org \
    --cc=kito.cheng@sifive.com \
    --cc=nelson@rivosinc.com \
    --cc=palmer@dabbelt.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).