diff --git a/opcodes/disassemble.c b/opcodes/disassemble.c index 98de1a772f9..53ee1ecf38b 100644 --- a/opcodes/disassemble.c +++ b/opcodes/disassemble.c @@ -382,7 +382,7 @@ disassembler (enum bfd_architecture a, #endif #ifdef ARCH_riscv case bfd_arch_riscv: - disassemble = riscv_get_disassembler (abfd); + disassemble = print_insn_riscv; break; #endif #ifdef ARCH_rl78 diff --git a/opcodes/disassemble.h b/opcodes/disassemble.h index 5fcd45ea5ae..a6c7d8fb756 100644 --- a/opcodes/disassemble.h +++ b/opcodes/disassemble.h @@ -102,7 +102,6 @@ extern int print_insn_loongarch (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 disassemble_free_riscv (disassemble_info *); extern void disassemble_free_powerpc (disassemble_info *); diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c index 367004d3341..d67b2c2aaf0 100644 --- a/opcodes/riscv-dis.c +++ b/opcodes/riscv-dis.c @@ -37,26 +37,6 @@ disassemble_info::fprintf_func which is for unstyled output. */ #define fprintf_func please_use_fprintf_styled_func_instead -/* Current XLEN for the disassembler. */ -static unsigned xlen = 0; - -/* Default ISA specification version (constant as of now). */ -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 riscv_subset_list_t riscv_subsets; -static riscv_parse_subset_t riscv_rps_dis = -{ - &riscv_subsets, /* subset_list. */ - opcodes_error_handler,/* error_handler. */ - &xlen, /* xlen. */ - &default_isa_spec, /* isa_spec. */ - false, /* check_unknown_prefixed_ext. */ -}; - struct riscv_private_data { bfd_vma gp; @@ -64,50 +44,57 @@ struct riscv_private_data bfd_vma hi_addr[OP_MASK_RD + 1]; bool to_print_addr; bool has_gp; + /* Current XLEN for the disassembler. */ + unsigned xlen; + /* Default ISA specification version. */ + enum riscv_spec_class default_isa_spec; + /* Default privileged specification. */ + enum riscv_spec_class default_priv_spec; + /* Used for architecture parser. */ + riscv_parse_subset_t riscv_rps_dis; + /* Used for mapping symbols. */ + int last_map_symbol; + bfd_vma last_stop_offset; + bfd_vma last_map_symbol_boundary; + enum riscv_seg_mstate last_map_state; + asection *last_map_section; + /* Register names as used by the disassembler. */ + const char (*riscv_gpr_names)[NRC]; + const char (*riscv_fpr_names)[NRC]; + /* If set, disassemble as most general instruction. */ + bool no_aliases; + /* If set, disassemble without checking architectire string, just like what + we did at the beginning. */ + bool all_ext; }; -/* Used for mapping symbols. */ -static int last_map_symbol = -1; -static bfd_vma last_stop_offset = 0; -static bfd_vma last_map_symbol_boundary = 0; -static enum riscv_seg_mstate last_map_state = MAP_NONE; -static asection *last_map_section = NULL; - -/* Register names as used by the disassembler. */ -static const char (*riscv_gpr_names)[NRC]; -static const char (*riscv_fpr_names)[NRC]; - -/* If set, disassemble as most general instruction. */ -static bool no_aliases = false; - -/* If set, disassemble without checking architectire string, just like what - we did at the beginning. */ -static bool all_ext = false; - /* Set default RISC-V disassembler options. */ static void -set_default_riscv_dis_options (void) +set_default_riscv_dis_options (struct disassemble_info *info) { - riscv_gpr_names = riscv_gpr_names_abi; - riscv_fpr_names = riscv_fpr_names_abi; - no_aliases = false; + struct riscv_private_data *pd = info->private_data; + pd->riscv_gpr_names = riscv_gpr_names_abi; + pd->riscv_fpr_names = riscv_fpr_names_abi; + pd->no_aliases = false; } /* Parse RISC-V disassembler option (without arguments). */ static bool -parse_riscv_dis_option_without_args (const char *option) +parse_riscv_dis_option_without_args (const char *option, + struct disassemble_info *info) { + struct riscv_private_data *pd = info->private_data; if (strcmp (option, "no-aliases") == 0) - no_aliases = true; + pd->no_aliases = true; else if (strcmp (option, "numeric") == 0) { - riscv_gpr_names = riscv_gpr_names_numeric; - riscv_fpr_names = riscv_fpr_names_numeric; + pd->riscv_gpr_names = riscv_gpr_names_numeric; + pd->riscv_fpr_names = riscv_fpr_names_numeric; } else if (strcmp (option, "max") == 0) - all_ext = true; + pd->all_ext = true; else return false; return true; @@ -116,11 +103,11 @@ parse_riscv_dis_option_without_args (const char *option) /* Parse RISC-V disassembler option (possibly with arguments). */ static void -parse_riscv_dis_option (const char *option) +parse_riscv_dis_option (const char *option, struct disassemble_info *info) { char *equal, *value; - if (parse_riscv_dis_option_without_args (option)) + if (parse_riscv_dis_option_without_args (option, info)) return; equal = strchr (option, '='); @@ -144,6 +131,7 @@ parse_riscv_dis_option (const char *option) value = equal + 1; if (strcmp (option, "priv-spec") == 0) { + struct riscv_private_data *pd = info->private_data; enum riscv_spec_class priv_spec = PRIV_SPEC_CLASS_NONE; const char *name = NULL; @@ -151,11 +139,11 @@ parse_riscv_dis_option (const char *option) 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) + else if (pd->default_priv_spec == PRIV_SPEC_CLASS_NONE) + pd->default_priv_spec = priv_spec; + else if (pd->default_priv_spec != priv_spec) { - RISCV_GET_PRIV_SPEC_NAME (name, default_priv_spec); + RISCV_GET_PRIV_SPEC_NAME (name, pd->default_priv_spec); opcodes_error_handler (_("mis-matched privilege spec set by %s=%s, " "the elf privilege attribute is %s"), option, value, name); @@ -171,17 +159,17 @@ parse_riscv_dis_option (const char *option) /* Parse RISC-V disassembler options. */ static void -parse_riscv_dis_options (const char *opts_in) +parse_riscv_dis_options (const char *opts_in, struct disassemble_info *info) { char *opts = xstrdup (opts_in), *opt = opts, *opt_end = opts; - set_default_riscv_dis_options (); + set_default_riscv_dis_options (info); for ( ; opt_end != NULL; opt = opt_end + 1) { if ((opt_end = strchr (opt, ',')) != NULL) *opt_end = 0; - parse_riscv_dis_option (opt); + parse_riscv_dis_option (opt, info); } free (opts); @@ -221,7 +209,7 @@ maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset, pd->print_addr = (bfd_vma)(int32_t) pd->print_addr; /* Fit into a 32-bit value on RV32. */ - if (xlen == 32) + if (pd->xlen == 32) pd->print_addr = (bfd_vma)(uint32_t)pd->print_addr; } @@ -230,60 +218,61 @@ maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset, static void print_reg_list (disassemble_info *info, insn_t l) { - bool numeric = riscv_gpr_names == riscv_gpr_names_numeric; + struct riscv_private_data *pd = info->private_data; + bool numeric = pd->riscv_gpr_names == riscv_gpr_names_numeric; unsigned reg_list = (int)EXTRACT_OPERAND (REG_LIST, l); unsigned r_start = numeric ? X_S2 : X_S0; info->fprintf_styled_func (info->stream, dis_style_register, - "%s", riscv_gpr_names[X_RA]); + "%s", pd->riscv_gpr_names[X_RA]); if (reg_list == 5) { info->fprintf_styled_func (info->stream, dis_style_text, ","); info->fprintf_styled_func (info->stream, dis_style_register, - "%s", riscv_gpr_names[X_S0]); + "%s", pd->riscv_gpr_names[X_S0]); } else if (reg_list == 6 || (numeric && reg_list > 6)) { info->fprintf_styled_func (info->stream, dis_style_text, ","); info->fprintf_styled_func (info->stream, dis_style_register, - "%s", riscv_gpr_names[X_S0]); + "%s", pd->riscv_gpr_names[X_S0]); info->fprintf_styled_func (info->stream, dis_style_text, "-"); info->fprintf_styled_func (info->stream, dis_style_register, - "%s", riscv_gpr_names[X_S1]); + "%s", pd->riscv_gpr_names[X_S1]); } if (reg_list == 15) { info->fprintf_styled_func (info->stream, dis_style_text, ","); info->fprintf_styled_func (info->stream, dis_style_register, - "%s", riscv_gpr_names[r_start]); + "%s", pd->riscv_gpr_names[r_start]); info->fprintf_styled_func (info->stream, dis_style_text, "-"); info->fprintf_styled_func (info->stream, dis_style_register, - "%s", riscv_gpr_names[X_S11]); + "%s", pd->riscv_gpr_names[X_S11]); } else if (reg_list == 7 && numeric) { info->fprintf_styled_func (info->stream, dis_style_text, ","); info->fprintf_styled_func (info->stream, dis_style_register, - "%s", riscv_gpr_names[X_S2]); + "%s", pd->riscv_gpr_names[X_S2]); } else if (reg_list > 6) { info->fprintf_styled_func (info->stream, dis_style_text, ","); info->fprintf_styled_func (info->stream, dis_style_register, - "%s", riscv_gpr_names[r_start]); + "%s", pd->riscv_gpr_names[r_start]); info->fprintf_styled_func (info->stream, dis_style_text, "-"); info->fprintf_styled_func (info->stream, dis_style_register, - "%s", riscv_gpr_names[reg_list + 11]); + "%s", pd->riscv_gpr_names[reg_list + 11]); } } /* Get Zcmp sp adjustment immediate. */ static int -riscv_get_spimm (insn_t l) +riscv_get_spimm (insn_t l, int xlen) { - int spimm = riscv_get_sp_base(l, *riscv_rps_dis.xlen); + int spimm = riscv_get_sp_base(l, xlen); spimm += EXTRACT_ZCMP_SPIMM (l); if (((l ^ MATCH_CM_PUSH) & MASK_CM_PUSH) == 0) spimm *= -1; @@ -326,24 +315,24 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info case 's': /* RS1 x8-x15. */ case 'w': /* RS1 x8-x15. */ print (info->stream, dis_style_register, "%s", - riscv_gpr_names[EXTRACT_OPERAND (CRS1S, l) + 8]); + pd->riscv_gpr_names[EXTRACT_OPERAND (CRS1S, l) + 8]); break; case 't': /* RS2 x8-x15. */ case 'x': /* RS2 x8-x15. */ print (info->stream, dis_style_register, "%s", - riscv_gpr_names[EXTRACT_OPERAND (CRS2S, l) + 8]); + pd->riscv_gpr_names[EXTRACT_OPERAND (CRS2S, l) + 8]); break; case 'U': /* RS1, constrained to equal RD. */ print (info->stream, dis_style_register, - "%s", riscv_gpr_names[rd]); + "%s", pd->riscv_gpr_names[rd]); break; case 'c': /* RS1, constrained to equal sp. */ print (info->stream, dis_style_register, "%s", - riscv_gpr_names[X_SP]); + pd->riscv_gpr_names[X_SP]); break; case 'V': /* RS2 */ print (info->stream, dis_style_register, "%s", - riscv_gpr_names[EXTRACT_OPERAND (CRS2, l)]); + pd->riscv_gpr_names[EXTRACT_OPERAND (CRS2, l)]); break; case 'o': case 'j': @@ -409,11 +398,11 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info break; case 'T': /* Floating-point RS2. */ print (info->stream, dis_style_register, "%s", - riscv_fpr_names[EXTRACT_OPERAND (CRS2, l)]); + pd->riscv_fpr_names[EXTRACT_OPERAND (CRS2, l)]); break; case 'D': /* Floating-point RS2 x8-x15. */ print (info->stream, dis_style_register, "%s", - riscv_fpr_names[EXTRACT_OPERAND (CRS2S, l) + 8]); + pd->riscv_fpr_names[EXTRACT_OPERAND (CRS2S, l) + 8]); break; } break; @@ -429,7 +418,7 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info case 'e': if (!EXTRACT_OPERAND (VWD, l)) print (info->stream, dis_style_register, "%s", - riscv_gpr_names[0]); + pd->riscv_gpr_names[0]); else print (info->stream, dis_style_register, "%s", riscv_vecr_names_numeric[EXTRACT_OPERAND (VD, l)]); @@ -520,12 +509,13 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info case 's': if ((l & MASK_JALR) == MATCH_JALR) maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 0); - print (info->stream, dis_style_register, "%s", riscv_gpr_names[rs1]); + print (info->stream, dis_style_register, "%s", + pd->riscv_gpr_names[rs1]); break; case 't': print (info->stream, dis_style_register, "%s", - riscv_gpr_names[EXTRACT_OPERAND (RS2, l)]); + pd->riscv_gpr_names[EXTRACT_OPERAND (RS2, l)]); break; case 'u': @@ -585,7 +575,8 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info pd->hi_addr[rd] = EXTRACT_UTYPE_IMM (l); else if ((l & MASK_C_LUI) == MATCH_C_LUI) pd->hi_addr[rd] = EXTRACT_CITYPE_LUI_IMM (l); - print (info->stream, dis_style_register, "%s", riscv_gpr_names[rd]); + print (info->stream, dis_style_register, "%s", + pd->riscv_gpr_names[rd]); break; case 'y': @@ -594,7 +585,8 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info break; case 'z': - print (info->stream, dis_style_register, "%s", riscv_gpr_names[0]); + print (info->stream, dis_style_register, "%s", + pd->riscv_gpr_names[0]); break; case '>': @@ -609,21 +601,23 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info case 'S': case 'U': - print (info->stream, dis_style_register, "%s", riscv_fpr_names[rs1]); + print (info->stream, dis_style_register, "%s", + pd->riscv_fpr_names[rs1]); break; case 'T': print (info->stream, dis_style_register, "%s", - riscv_fpr_names[EXTRACT_OPERAND (RS2, l)]); + pd->riscv_fpr_names[EXTRACT_OPERAND (RS2, l)]); break; case 'D': - print (info->stream, dis_style_register, "%s", riscv_fpr_names[rd]); + print (info->stream, dis_style_register, "%s", + pd->riscv_fpr_names[rd]); break; case 'R': print (info->stream, dis_style_register, "%s", - riscv_fpr_names[EXTRACT_OPERAND (RS3, l)]); + pd->riscv_fpr_names[EXTRACT_OPERAND (RS3, l)]); break; case 'E': @@ -639,15 +633,15 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info 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; + if (pd->default_priv_spec == PRIV_SPEC_CLASS_NONE) + pd->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))) \ + || (pd->default_priv_spec >= define_version \ + && pd->default_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) @@ -656,7 +650,7 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info } if (riscv_csr_hash[csr] != NULL) - if (riscv_subset_supports (&riscv_rps_dis, "xtheadvector") + if (riscv_subset_supports (&pd->riscv_rps_dis, "xtheadvector") && (csr == CSR_VSTART || csr == CSR_VXSAT || csr == CSR_VXRM @@ -716,11 +710,11 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info { case '1': print (info->stream, dis_style_register, "%s", - riscv_gpr_names[riscv_zcmp_get_sregno (EXTRACT_OPERAND (SREG1, l))]); + pd->riscv_gpr_names[riscv_zcmp_get_sregno (EXTRACT_OPERAND (SREG1, l))]); break; case '2': print (info->stream, dis_style_register, "%s", - riscv_gpr_names[riscv_zcmp_get_sregno (EXTRACT_OPERAND (SREG2, l))]); + pd->riscv_gpr_names[riscv_zcmp_get_sregno (EXTRACT_OPERAND (SREG2, l))]); break; case 'b': print (info->stream, dis_style_immediate, "%d", @@ -735,7 +729,7 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info break; case 'p': print (info->stream, dis_style_immediate, "%d", - riscv_get_spimm (l)); + riscv_get_spimm (l, pd->xlen)); break; case 'i': case 'I': @@ -947,21 +941,21 @@ riscv_disassemble_insn (bfd_vma memaddr, { /* If XLEN is not known, get its value from the ELF class. */ if (info->mach == bfd_mach_riscv64) - xlen = 64; + pd->xlen = 64; else if (info->mach == bfd_mach_riscv32) - xlen = 32; + pd->xlen = 32; else if (info->section != NULL) { Elf_Internal_Ehdr *ehdr = elf_elfheader (info->section->owner); - xlen = ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? 64 : 32; + pd->xlen = ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? 64 : 32; } /* If arch has the Zfinx extension, replace FPR with GPR. */ - if (riscv_subset_supports (&riscv_rps_dis, "zfinx")) - riscv_fpr_names = riscv_gpr_names; + if (riscv_subset_supports (&pd->riscv_rps_dis, "zfinx")) + pd->riscv_fpr_names = pd->riscv_gpr_names; else - riscv_fpr_names = riscv_gpr_names == riscv_gpr_names_abi ? - riscv_fpr_names_abi : riscv_fpr_names_numeric; + pd->riscv_fpr_names = pd->riscv_gpr_names == riscv_gpr_names_abi ? + riscv_fpr_names_abi : riscv_fpr_names_numeric; for (; op->name; op++) { @@ -972,14 +966,16 @@ riscv_disassemble_insn (bfd_vma memaddr, if (! (op->match_func) (op, word)) continue; /* Is this a pseudo-instruction and may we print it as such? */ - if (no_aliases && (op->pinfo & INSN_ALIAS)) + if (pd->no_aliases && (op->pinfo & INSN_ALIAS)) continue; /* Is this instruction restricted to a certain value of XLEN? */ - if ((op->xlen_requirement != 0) && (op->xlen_requirement != xlen)) + if ((op->xlen_requirement != 0) + && (op->xlen_requirement != pd->xlen)) continue; /* Is this instruction supported by the current architecture? */ - if (!all_ext - && !riscv_multi_subset_supports (&riscv_rps_dis, op->insn_class)) + if (!pd->all_ext + && !riscv_multi_subset_supports (&pd->riscv_rps_dis, + op->insn_class)) continue; /* It's a match. */ @@ -1060,6 +1056,7 @@ riscv_update_map_state (int n, enum riscv_seg_mstate *state, struct disassemble_info *info) { + struct riscv_private_data *pd = info->private_data; const char *name; /* If the symbol is in a different section, ignore it. */ @@ -1075,7 +1072,7 @@ riscv_update_map_state (int n, else if (strncmp (name, "$xrv", 4) == 0) { *state = MAP_INSN; - riscv_release_subset_list (&riscv_subsets); + riscv_release_subset_list (pd->riscv_rps_dis.subset_list); /* ISA mapping string may be numbered, suffixed with '.n'. Do not consider this as part of the ISA string. */ @@ -1086,11 +1083,11 @@ riscv_update_map_state (int n, char *name_substr = xmalloc (suffix_index + 1); strncpy (name_substr, name, suffix_index); name_substr[suffix_index] = '\0'; - riscv_parse_subset (&riscv_rps_dis, name_substr + 2); + riscv_parse_subset (&pd->riscv_rps_dis, name_substr + 2); free (name_substr); } else - riscv_parse_subset (&riscv_rps_dis, name + 2); + riscv_parse_subset (&pd->riscv_rps_dis, name + 2); } } @@ -1119,6 +1116,7 @@ static enum riscv_seg_mstate riscv_search_mapping_symbol (bfd_vma memaddr, struct disassemble_info *info) { + struct riscv_private_data *pd = info->private_data; enum riscv_seg_mstate mstate; bool from_last_map_symbol; bool found = false; @@ -1127,11 +1125,11 @@ riscv_search_mapping_symbol (bfd_vma memaddr, /* Return the last map state if the address is still within the range of the last mapping symbol. */ - if (last_map_section == info->section - && (memaddr < last_map_symbol_boundary)) - return last_map_state; + if (pd->last_map_section == info->section + && (memaddr < pd->last_map_symbol_boundary)) + return pd->last_map_state; - last_map_section = info->section; + pd->last_map_section = info->section; /* Decide whether to print the data or instruction by default, in case we can not find the corresponding mapping symbols. */ @@ -1147,17 +1145,17 @@ riscv_search_mapping_symbol (bfd_vma memaddr, /* Reset the last_map_symbol if we start to dump a new section. */ if (memaddr <= 0) - last_map_symbol = -1; + pd->last_map_symbol = -1; /* If the last stop offset is different from the current one, then don't use the last_map_symbol to search. We usually reset the info->stop_offset when handling a new section. */ - from_last_map_symbol = (last_map_symbol >= 0 - && info->stop_offset == last_stop_offset); + from_last_map_symbol = (pd->last_map_symbol >= 0 + && info->stop_offset == pd->last_stop_offset); /* Start scanning from wherever we finished last time, or the start of the function. */ - n = from_last_map_symbol ? last_map_symbol : info->symtab_pos + 1; + n = from_last_map_symbol ? pd->last_map_symbol : info->symtab_pos + 1; /* Find the suitable mapping symbol to dump. */ for (; n < info->symtab_size; n++) @@ -1182,7 +1180,7 @@ riscv_search_mapping_symbol (bfd_vma memaddr, can pick up a text mapping symbol of a preceeding section. */ if (!found) { - n = from_last_map_symbol ? last_map_symbol : info->symtab_pos; + n = from_last_map_symbol ? pd->last_map_symbol : info->symtab_pos; for (; n >= 0; n--) { @@ -1221,7 +1219,7 @@ riscv_search_mapping_symbol (bfd_vma memaddr, /* The next mapping symbol has been found, and it represents the boundary of this mapping symbol. */ found_next = true; - last_map_symbol_boundary = addr; + pd->last_map_symbol_boundary = addr; break; } } @@ -1229,12 +1227,13 @@ riscv_search_mapping_symbol (bfd_vma memaddr, /* No further mapping symbol has been found, indicating that the boundary of the current mapping symbol is the end of this section. */ if (!found_next) - last_map_symbol_boundary = info->section->vma + info->section->size; + pd->last_map_symbol_boundary = info->section->vma + + info->section->size; } /* Save the information for next use. */ - last_map_symbol = symbol; - last_stop_offset = info->stop_offset; + pd->last_map_symbol = symbol; + pd->last_stop_offset = info->stop_offset; return mstate; } @@ -1245,17 +1244,18 @@ static bfd_vma riscv_data_length (bfd_vma memaddr, disassemble_info *info) { + struct riscv_private_data *pd = info->private_data; bfd_vma length; bool found = false; length = 4; if (info->symtab_size != 0 && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour - && last_map_symbol >= 0) + && pd->last_map_symbol >= 0) { int n; enum riscv_seg_mstate m = MAP_NONE; - for (n = last_map_symbol + 1; n < info->symtab_size; n++) + for (n = pd->last_map_symbol + 1; n < info->symtab_size; n++) { bfd_vma addr = bfd_asymbol_value (info->symtab[n]); if (addr > memaddr @@ -1344,7 +1344,6 @@ static bool riscv_init_disasm_info (struct disassemble_info *info) { int i; - struct riscv_private_data *pd = xcalloc (1, sizeof (struct riscv_private_data)); pd->gp = 0; @@ -1352,8 +1351,8 @@ riscv_init_disasm_info (struct disassemble_info *info) for (i = 0; i < (int) ARRAY_SIZE (pd->hi_addr); i++) pd->hi_addr[i] = -1; pd->to_print_addr = false; - pd->has_gp = false; + pd->has_gp = false; for (i = 0; i < info->symtab_size; i++) { asymbol *sym = info->symtab[i]; @@ -1364,6 +1363,50 @@ riscv_init_disasm_info (struct disassemble_info *info) } } + pd->xlen = 0; + pd->default_isa_spec = ISA_SPEC_CLASS_DRAFT - 1; + pd->default_priv_spec = PRIV_SPEC_CLASS_NONE; + + pd->riscv_rps_dis.subset_list = xcalloc (1, sizeof (riscv_parse_subset_t)); + pd->riscv_rps_dis.error_handler = opcodes_error_handler; + pd->riscv_rps_dis.xlen = &pd->xlen; + pd->riscv_rps_dis.isa_spec = &pd->default_isa_spec; + pd->riscv_rps_dis.check_unknown_prefixed_ext = false; + const char *default_arch = "rv64gc"; + if (info->section != NULL) + { + bfd *abfd = info->section->owner; + if (abfd && bfd_get_flavour (abfd) == bfd_target_elf_flavour) + { + 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, + &pd->default_priv_spec); + default_arch = attr[Tag_RISCV_arch].s; + } + } + } + riscv_release_subset_list (pd->riscv_rps_dis.subset_list); + riscv_parse_subset (&pd->riscv_rps_dis, default_arch); + + pd->last_map_symbol = -1; + pd->last_stop_offset = 0; + pd->last_map_symbol_boundary = 0; + pd->last_map_state = MAP_NONE; + pd->last_map_section = NULL; + pd->riscv_gpr_names = NULL; + pd->riscv_fpr_names = NULL; + pd->no_aliases = false; + pd->all_ext = false; + info->private_data = pd; return true; } @@ -1398,21 +1441,21 @@ print_insn_riscv (bfd_vma memaddr, struct disassemble_info *info) int (*riscv_disassembler) (bfd_vma, insn_t, const bfd_byte *, struct disassemble_info *); - if (info->disassembler_options != NULL) - { - parse_riscv_dis_options (info->disassembler_options); - /* Avoid repeatedly parsing the options. */ - info->disassembler_options = NULL; - } - else if (riscv_gpr_names == NULL) - set_default_riscv_dis_options (); - if (info->private_data == NULL && !riscv_init_disasm_info (info)) return -1; + if (info->disassembler_options != NULL) + { + parse_riscv_dis_options (info->disassembler_options, info); + /* Avoid repeatedly parsing the options. */ + info->disassembler_options = NULL; + } + else if (((struct riscv_private_data *) info->private_data)->riscv_gpr_names == NULL) + set_default_riscv_dis_options (info); + mstate = riscv_search_mapping_symbol (memaddr, info); /* Save the last mapping state. */ - last_map_state = mstate; + ((struct riscv_private_data *) info->private_data)->last_map_state = mstate; /* Set the size to dump. */ if (mstate == MAP_DATA @@ -1466,33 +1509,6 @@ print_insn_riscv (bfd_vma memaddr, struct disassemble_info *info) return (*riscv_disassembler) (memaddr, insn, packet, info); } -disassembler_ftype -riscv_get_disassembler (bfd *abfd) -{ - const char *default_arch = "rv64gc"; - - if (abfd && bfd_get_flavour (abfd) == bfd_target_elf_flavour) - { - 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); - default_arch = attr[Tag_RISCV_arch].s; - } - } - - riscv_release_subset_list (&riscv_subsets); - riscv_parse_subset (&riscv_rps_dis, default_arch); - 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. */ @@ -1665,5 +1681,7 @@ with the -M switch (multiple options should be separated by commas):\n")); void disassemble_free_riscv (struct disassemble_info *info ATTRIBUTE_UNUSED) { - riscv_release_subset_list (&riscv_subsets); + struct riscv_private_data *pd = info->private_data; + if (pd) + riscv_release_subset_list (pd->riscv_rps_dis.subset_list); }