@@ -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
@@ -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 *);
@@ -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->private_data == NULL && !riscv_init_disasm_info (info))
+ return -1;
+
if (info->disassembler_options != NULL)
{
- parse_riscv_dis_options (info->disassembler_options);
+ parse_riscv_dis_options (info->disassembler_options, info);
/* 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;
+ 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);
}