[PATCH] RISC-V: Move all global static target stuff into private data for disassembler.
Nelson Chu
nelson@rivosinc.com
Thu Feb 6 13:47:37 GMT 2025
I got a request said that the JDK multi-thread compiler may be broken
if two or more threads are trying to print/disassemble stuff, and filling
the disassemble_info, setting callbacks, and grabbing the function pointer
to disasm at the same time. Since such as the target global static stuff,
including subset of extensions and mapping symbol stuff, seems to only be
one globally. Ideally, for dis-assembler, all global static target stuff
should/can be better to be defined into the target private data, since they
are target-dependency.
opcodes/
* riscv-dis.c: Moved all global static target-dependency stuff into
riscv_private_data, including architecture and mapping symbol stuff.
(set_default_riscv_dis_options): Updated since global static target-
dependency stuff are moved into riscv_private_data.
(parse_riscv_dis_option_without_args): Likewise.
(parse_riscv_dis_option): Likewise.
(parse_riscv_dis_options): Likewise.
(maybe_print_address): Likewise.
(print_reg_list): Likewise.
(riscv_get_spimm): Likewise.
(print_insn_args): Likewise.
(riscv_disassemble_insn): Likewise.
(riscv_update_map_state): Likewise.
(riscv_search_mapping_symbol): Likewise.
(riscv_data_length): Likewise.
(print_insn_riscv): Likewise. Call the riscv_init_disasm_info before
parsing any disassembler options, since the related stuff are moved
into riscv_private_data.
(riscv_init_disasm_info): Likewise. Parse and set the architecture
string and privileged spec version since riscv_get_disassembler is
no longer needed.
(riscv_get_disassembler): Removed.
(disassemble_free_riscv): Only free the subset_list if
riscv_private_data exsits.
* disassemble.c (disassembler): Since riscv_get_disassembler is
removed, call to print_insn_riscv.
* disassemble.h: Removed extern riscv_get_disassembler.
---
opcodes/disassemble.c | 2 +-
opcodes/disassemble.h | 1 -
opcodes/riscv-dis.c | 336 ++++++++++++++++++++++--------------------
3 files changed, 178 insertions(+), 161 deletions(-)
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->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);
}
--
2.39.3 (Apple Git-146)
More information about the Binutils
mailing list