diff options
author | Nelson Chu <nelson.chu@sifive.com> | 2020-12-08 14:39:01 +0800 |
---|---|---|
committer | Nelson Chu <nelson.chu@sifive.com> | 2020-12-10 10:43:18 +0800 |
commit | 8152e0407c25612c6a8079cc8e1a5c1fe14afdbf (patch) | |
tree | daa8aa52a6cb7ed7f284c8ea31019af9d502badf | |
parent | 729a53530e86972d1143553a415db34e6e01d5d2 (diff) | |
download | binutils-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/ChangeLog | 11 | ||||
-rw-r--r-- | opcodes/disassemble.c | 2 | ||||
-rw-r--r-- | opcodes/disassemble.h | 1 | ||||
-rw-r--r-- | opcodes/riscv-dis.c | 37 |
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. */ |