[PATCH] RISC-V: Dump CSR according to the elf privileged spec attributes.

Nelson Chu nelson.chu@sifive.com
Tue Dec 8 09:59:46 GMT 2020


opcodes/
    * disassemble.h (riscv_get_disassembler): Declare.
    * disassemble.c (disassembler): Changed to riscv_get_disassembler.
    * riscv-dis.c (riscv_get_disassembler): Check the elf privileged spec
    attributes before calling print_insn_riscv.
    (parse_riscv_dis_option): Same as the assembler, the priority of elf
    attributes are higher than the options.  If we find the privileged
    attributes, but the -Mpriv-spec= is different, then output error/warning
    and still use the elf attributes set.
---
 opcodes/disassemble.c |  2 +-
 opcodes/disassemble.h |  1 +
 opcodes/riscv-dis.c   | 37 ++++++++++++++++++++++++++++++++++---
 3 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/opcodes/disassemble.c b/opcodes/disassemble.c
index 290dcdd..48bc558 100644
--- a/opcodes/disassemble.c
+++ b/opcodes/disassemble.c
@@ -402,7 +402,7 @@ disassembler (enum bfd_architecture a,
 #endif
 #ifdef ARCH_riscv
     case bfd_arch_riscv:
-      disassemble = print_insn_riscv;
+      disassemble = riscv_get_disassembler (abfd);
       break;
 #endif
 #ifdef ARCH_rl78
diff --git a/opcodes/disassemble.h b/opcodes/disassemble.h
index 89db886..a47071f 100644
--- a/opcodes/disassemble.h
+++ b/opcodes/disassemble.h
@@ -103,6 +103,7 @@ extern int print_insn_z8002		(bfd_vma, disassemble_info *);
 
 extern disassembler_ftype csky_get_disassembler (bfd *);
 extern disassembler_ftype rl78_get_disassembler (bfd *);
+extern disassembler_ftype riscv_get_disassembler (bfd *);
 
 extern void ATTRIBUTE_NORETURN opcodes_assert (const char *, int);
 
diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index 655ce4a..ca3b110 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -99,9 +99,17 @@ parse_riscv_dis_option (const char *option)
   value = equal + 1;
   if (strcmp (option, "priv-spec") == 0)
     {
-      if (!riscv_get_priv_spec_class (value, &default_priv_spec))
-       opcodes_error_handler (_("unknown privilege spec set by %s=%s"),
-                              option, value);
+      enum riscv_priv_spec_class priv_spec = PRIV_SPEC_CLASS_NONE;
+      if (!riscv_get_priv_spec_class (value, &priv_spec))
+	opcodes_error_handler (_("unknown privilege 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)
+	opcodes_error_handler (_("mis-matched privilege spec set by %s=%s, "
+				 "the elf privilege attribute is %s"),
+			       option, value,
+			       riscv_get_priv_spec_name (default_priv_spec));
     }
   else
     {
@@ -582,6 +590,29 @@ print_insn_riscv (bfd_vma memaddr, struct disassemble_info *info)
   return riscv_disassemble_insn (memaddr, insn, info);
 }
 
+disassembler_ftype
+riscv_get_disassembler (bfd *abfd)
+{
+  /* If -Mpriv-spec= isn't set, then try to set it by checking the elf
+     privileged attributes.  */
+  if (abfd)
+    {
+      const char *sec_name = get_elf_backend_data (abfd)->obj_attrs_section;
+      if (bfd_get_section_by_name (abfd, sec_name) != NULL)
+        {
+	  obj_attribute *attr = elf_known_obj_attributes_proc (abfd);
+	  unsigned int Tag_a = Tag_RISCV_priv_spec;
+	  unsigned int Tag_b = Tag_RISCV_priv_spec_minor;
+	  unsigned int Tag_c = Tag_RISCV_priv_spec_revision;
+	  riscv_get_priv_spec_class_from_numbers (attr[Tag_a].i,
+						  attr[Tag_b].i,
+						  attr[Tag_c].i,
+						  &default_priv_spec);
+        }
+    }
+   return print_insn_riscv;
+}
+
 /* Prevent use of the fake labels that are generated as part of the DWARF
    and for relaxable relocations in the assembler.  */
 
-- 
2.7.4



More information about the Binutils mailing list