aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNelson Chu <nelson.chu@sifive.com>2020-12-08 14:39:01 +0800
committerNelson Chu <nelson.chu@sifive.com>2020-12-10 10:43:18 +0800
commit8152e0407c25612c6a8079cc8e1a5c1fe14afdbf (patch)
treedaa8aa52a6cb7ed7f284c8ea31019af9d502badf
parent729a53530e86972d1143553a415db34e6e01d5d2 (diff)
downloadbinutils-8152e0407c25612c6a8079cc8e1a5c1fe14afdbf.zip
binutils-8152e0407c25612c6a8079cc8e1a5c1fe14afdbf.tar.gz
binutils-8152e0407c25612c6a8079cc8e1a5c1fe14afdbf.tar.bz2
RISC-V: Dump CSR according to the elf privileged spec attributes.
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.
-rw-r--r--opcodes/ChangeLog11
-rw-r--r--opcodes/disassemble.c2
-rw-r--r--opcodes/disassemble.h1
-rw-r--r--opcodes/riscv-dis.c37
4 files changed, 47 insertions, 4 deletions
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index b0cc885..b380119 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,5 +1,16 @@
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
zifencei and zicsr.
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. */