RISC-V: Dump CSR according to the elf privileged spec attributes.
authorNelson Chu <nelson.chu@sifive.com>
Tue, 8 Dec 2020 06:39:01 +0000 (14:39 +0800)
committerNelson Chu <nelson.chu@sifive.com>
Thu, 10 Dec 2020 02:43:18 +0000 (10:43 +0800)
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/ChangeLog
opcodes/disassemble.c
opcodes/disassemble.h
opcodes/riscv-dis.c

index b0cc885e8e4e96ee03956c1a0d9d33fd98e82e6e..b3801196591a40876107635195bf586d823c9098 100644 (file)
@@ -1,3 +1,14 @@
+2020-12-10  Nelson Chu  <nelson.chu@sifive.com>
+
+       * 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.
+
 2020-12-10  Nelson Chu  <nelson.chu@sifive.com>
 
        * riscv-opc.c (riscv_opcodes): Control fence.i and csr instructions by
index 290dcdd100d19437e7f52423d629711e3c2a007e..48bc558fe0212ba7fb4f0536431e5df9c84eb0eb 100644 (file)
@@ -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
index 89db88640572c20e48d89a450d546973f3623f8b..a47071fc587152061604b7034a42c5b42171f3e1 100644 (file)
@@ -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);
 
index 655ce4ad0b205434c4206fbc5c285c5df31afd53..ca3b110a027cd78ac96d3b6f659c877777d146a1 100644 (file)
@@ -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.  */