forked from Imagelibrary/binutils-gdb
RISC-V: Move all global static target stuff into private data for disassembler.
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.
This commit is contained in:
@@ -382,7 +382,7 @@ disassembler (enum bfd_architecture a,
|
|||||||
#endif
|
#endif
|
||||||
#ifdef ARCH_riscv
|
#ifdef ARCH_riscv
|
||||||
case bfd_arch_riscv:
|
case bfd_arch_riscv:
|
||||||
disassemble = riscv_get_disassembler (abfd);
|
disassemble = print_insn_riscv;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef ARCH_rl78
|
#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 csky_get_disassembler (bfd *);
|
||||||
extern disassembler_ftype rl78_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_riscv (disassemble_info *);
|
||||||
extern void disassemble_free_powerpc (disassemble_info *);
|
extern void disassemble_free_powerpc (disassemble_info *);
|
||||||
|
|||||||
@@ -37,26 +37,6 @@
|
|||||||
disassemble_info::fprintf_func which is for unstyled output. */
|
disassemble_info::fprintf_func which is for unstyled output. */
|
||||||
#define fprintf_func please_use_fprintf_styled_func_instead
|
#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
|
struct riscv_private_data
|
||||||
{
|
{
|
||||||
bfd_vma gp;
|
bfd_vma gp;
|
||||||
@@ -64,50 +44,57 @@ struct riscv_private_data
|
|||||||
bfd_vma hi_addr[OP_MASK_RD + 1];
|
bfd_vma hi_addr[OP_MASK_RD + 1];
|
||||||
bool to_print_addr;
|
bool to_print_addr;
|
||||||
bool has_gp;
|
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. */
|
/* Set default RISC-V disassembler options. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_default_riscv_dis_options (void)
|
set_default_riscv_dis_options (struct disassemble_info *info)
|
||||||
{
|
{
|
||||||
riscv_gpr_names = riscv_gpr_names_abi;
|
struct riscv_private_data *pd = info->private_data;
|
||||||
riscv_fpr_names = riscv_fpr_names_abi;
|
pd->riscv_gpr_names = riscv_gpr_names_abi;
|
||||||
no_aliases = false;
|
pd->riscv_fpr_names = riscv_fpr_names_abi;
|
||||||
|
pd->no_aliases = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse RISC-V disassembler option (without arguments). */
|
/* Parse RISC-V disassembler option (without arguments). */
|
||||||
|
|
||||||
static bool
|
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)
|
if (strcmp (option, "no-aliases") == 0)
|
||||||
no_aliases = true;
|
pd->no_aliases = true;
|
||||||
else if (strcmp (option, "numeric") == 0)
|
else if (strcmp (option, "numeric") == 0)
|
||||||
{
|
{
|
||||||
riscv_gpr_names = riscv_gpr_names_numeric;
|
pd->riscv_gpr_names = riscv_gpr_names_numeric;
|
||||||
riscv_fpr_names = riscv_fpr_names_numeric;
|
pd->riscv_fpr_names = riscv_fpr_names_numeric;
|
||||||
}
|
}
|
||||||
else if (strcmp (option, "max") == 0)
|
else if (strcmp (option, "max") == 0)
|
||||||
all_ext = true;
|
pd->all_ext = true;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
@@ -116,11 +103,11 @@ parse_riscv_dis_option_without_args (const char *option)
|
|||||||
/* Parse RISC-V disassembler option (possibly with arguments). */
|
/* Parse RISC-V disassembler option (possibly with arguments). */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parse_riscv_dis_option (const char *option)
|
parse_riscv_dis_option (const char *option, struct disassemble_info *info)
|
||||||
{
|
{
|
||||||
char *equal, *value;
|
char *equal, *value;
|
||||||
|
|
||||||
if (parse_riscv_dis_option_without_args (option))
|
if (parse_riscv_dis_option_without_args (option, info))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
equal = strchr (option, '=');
|
equal = strchr (option, '=');
|
||||||
@@ -144,6 +131,7 @@ parse_riscv_dis_option (const char *option)
|
|||||||
value = equal + 1;
|
value = equal + 1;
|
||||||
if (strcmp (option, "priv-spec") == 0)
|
if (strcmp (option, "priv-spec") == 0)
|
||||||
{
|
{
|
||||||
|
struct riscv_private_data *pd = info->private_data;
|
||||||
enum riscv_spec_class priv_spec = PRIV_SPEC_CLASS_NONE;
|
enum riscv_spec_class priv_spec = PRIV_SPEC_CLASS_NONE;
|
||||||
const char *name = NULL;
|
const char *name = NULL;
|
||||||
|
|
||||||
@@ -151,11 +139,11 @@ parse_riscv_dis_option (const char *option)
|
|||||||
if (priv_spec == PRIV_SPEC_CLASS_NONE)
|
if (priv_spec == PRIV_SPEC_CLASS_NONE)
|
||||||
opcodes_error_handler (_("unknown privileged spec set by %s=%s"),
|
opcodes_error_handler (_("unknown privileged spec set by %s=%s"),
|
||||||
option, value);
|
option, value);
|
||||||
else if (default_priv_spec == PRIV_SPEC_CLASS_NONE)
|
else if (pd->default_priv_spec == PRIV_SPEC_CLASS_NONE)
|
||||||
default_priv_spec = priv_spec;
|
pd->default_priv_spec = priv_spec;
|
||||||
else if (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, "
|
opcodes_error_handler (_("mis-matched privilege spec set by %s=%s, "
|
||||||
"the elf privilege attribute is %s"),
|
"the elf privilege attribute is %s"),
|
||||||
option, value, name);
|
option, value, name);
|
||||||
@@ -171,17 +159,17 @@ parse_riscv_dis_option (const char *option)
|
|||||||
/* Parse RISC-V disassembler options. */
|
/* Parse RISC-V disassembler options. */
|
||||||
|
|
||||||
static void
|
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;
|
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)
|
for ( ; opt_end != NULL; opt = opt_end + 1)
|
||||||
{
|
{
|
||||||
if ((opt_end = strchr (opt, ',')) != NULL)
|
if ((opt_end = strchr (opt, ',')) != NULL)
|
||||||
*opt_end = 0;
|
*opt_end = 0;
|
||||||
parse_riscv_dis_option (opt);
|
parse_riscv_dis_option (opt, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
free (opts);
|
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;
|
pd->print_addr = (bfd_vma)(int32_t) pd->print_addr;
|
||||||
|
|
||||||
/* Fit into a 32-bit value on RV32. */
|
/* 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;
|
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
|
static void
|
||||||
print_reg_list (disassemble_info *info, insn_t l)
|
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 reg_list = (int)EXTRACT_OPERAND (REG_LIST, l);
|
||||||
unsigned r_start = numeric ? X_S2 : X_S0;
|
unsigned r_start = numeric ? X_S2 : X_S0;
|
||||||
info->fprintf_styled_func (info->stream, dis_style_register,
|
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)
|
if (reg_list == 5)
|
||||||
{
|
{
|
||||||
info->fprintf_styled_func (info->stream, dis_style_text, ",");
|
info->fprintf_styled_func (info->stream, dis_style_text, ",");
|
||||||
info->fprintf_styled_func (info->stream, dis_style_register,
|
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))
|
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_text, ",");
|
||||||
info->fprintf_styled_func (info->stream, dis_style_register,
|
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_text, "-");
|
||||||
info->fprintf_styled_func (info->stream, dis_style_register,
|
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)
|
if (reg_list == 15)
|
||||||
{
|
{
|
||||||
info->fprintf_styled_func (info->stream, dis_style_text, ",");
|
info->fprintf_styled_func (info->stream, dis_style_text, ",");
|
||||||
info->fprintf_styled_func (info->stream, dis_style_register,
|
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_text, "-");
|
||||||
info->fprintf_styled_func (info->stream, dis_style_register,
|
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)
|
else if (reg_list == 7 && numeric)
|
||||||
{
|
{
|
||||||
info->fprintf_styled_func (info->stream, dis_style_text, ",");
|
info->fprintf_styled_func (info->stream, dis_style_text, ",");
|
||||||
info->fprintf_styled_func (info->stream, dis_style_register,
|
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)
|
else if (reg_list > 6)
|
||||||
{
|
{
|
||||||
info->fprintf_styled_func (info->stream, dis_style_text, ",");
|
info->fprintf_styled_func (info->stream, dis_style_text, ",");
|
||||||
info->fprintf_styled_func (info->stream, dis_style_register,
|
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_text, "-");
|
||||||
info->fprintf_styled_func (info->stream, dis_style_register,
|
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. */
|
/* Get Zcmp sp adjustment immediate. */
|
||||||
|
|
||||||
static int
|
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);
|
spimm += EXTRACT_ZCMP_SPIMM (l);
|
||||||
if (((l ^ MATCH_CM_PUSH) & MASK_CM_PUSH) == 0)
|
if (((l ^ MATCH_CM_PUSH) & MASK_CM_PUSH) == 0)
|
||||||
spimm *= -1;
|
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 's': /* RS1 x8-x15. */
|
||||||
case 'w': /* RS1 x8-x15. */
|
case 'w': /* RS1 x8-x15. */
|
||||||
print (info->stream, dis_style_register, "%s",
|
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;
|
break;
|
||||||
case 't': /* RS2 x8-x15. */
|
case 't': /* RS2 x8-x15. */
|
||||||
case 'x': /* RS2 x8-x15. */
|
case 'x': /* RS2 x8-x15. */
|
||||||
print (info->stream, dis_style_register, "%s",
|
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;
|
break;
|
||||||
case 'U': /* RS1, constrained to equal RD. */
|
case 'U': /* RS1, constrained to equal RD. */
|
||||||
print (info->stream, dis_style_register,
|
print (info->stream, dis_style_register,
|
||||||
"%s", riscv_gpr_names[rd]);
|
"%s", pd->riscv_gpr_names[rd]);
|
||||||
break;
|
break;
|
||||||
case 'c': /* RS1, constrained to equal sp. */
|
case 'c': /* RS1, constrained to equal sp. */
|
||||||
print (info->stream, dis_style_register, "%s",
|
print (info->stream, dis_style_register, "%s",
|
||||||
riscv_gpr_names[X_SP]);
|
pd->riscv_gpr_names[X_SP]);
|
||||||
break;
|
break;
|
||||||
case 'V': /* RS2 */
|
case 'V': /* RS2 */
|
||||||
print (info->stream, dis_style_register, "%s",
|
print (info->stream, dis_style_register, "%s",
|
||||||
riscv_gpr_names[EXTRACT_OPERAND (CRS2, l)]);
|
pd->riscv_gpr_names[EXTRACT_OPERAND (CRS2, l)]);
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
case 'j':
|
case 'j':
|
||||||
@@ -409,11 +398,11 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
|
|||||||
break;
|
break;
|
||||||
case 'T': /* Floating-point RS2. */
|
case 'T': /* Floating-point RS2. */
|
||||||
print (info->stream, dis_style_register, "%s",
|
print (info->stream, dis_style_register, "%s",
|
||||||
riscv_fpr_names[EXTRACT_OPERAND (CRS2, l)]);
|
pd->riscv_fpr_names[EXTRACT_OPERAND (CRS2, l)]);
|
||||||
break;
|
break;
|
||||||
case 'D': /* Floating-point RS2 x8-x15. */
|
case 'D': /* Floating-point RS2 x8-x15. */
|
||||||
print (info->stream, dis_style_register, "%s",
|
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;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -429,7 +418,7 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
|
|||||||
case 'e':
|
case 'e':
|
||||||
if (!EXTRACT_OPERAND (VWD, l))
|
if (!EXTRACT_OPERAND (VWD, l))
|
||||||
print (info->stream, dis_style_register, "%s",
|
print (info->stream, dis_style_register, "%s",
|
||||||
riscv_gpr_names[0]);
|
pd->riscv_gpr_names[0]);
|
||||||
else
|
else
|
||||||
print (info->stream, dis_style_register, "%s",
|
print (info->stream, dis_style_register, "%s",
|
||||||
riscv_vecr_names_numeric[EXTRACT_OPERAND (VD, l)]);
|
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':
|
case 's':
|
||||||
if ((l & MASK_JALR) == MATCH_JALR)
|
if ((l & MASK_JALR) == MATCH_JALR)
|
||||||
maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 0);
|
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;
|
break;
|
||||||
|
|
||||||
case 't':
|
case 't':
|
||||||
print (info->stream, dis_style_register, "%s",
|
print (info->stream, dis_style_register, "%s",
|
||||||
riscv_gpr_names[EXTRACT_OPERAND (RS2, l)]);
|
pd->riscv_gpr_names[EXTRACT_OPERAND (RS2, l)]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'u':
|
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);
|
pd->hi_addr[rd] = EXTRACT_UTYPE_IMM (l);
|
||||||
else if ((l & MASK_C_LUI) == MATCH_C_LUI)
|
else if ((l & MASK_C_LUI) == MATCH_C_LUI)
|
||||||
pd->hi_addr[rd] = EXTRACT_CITYPE_LUI_IMM (l);
|
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;
|
break;
|
||||||
|
|
||||||
case 'y':
|
case 'y':
|
||||||
@@ -594,7 +585,8 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'z':
|
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;
|
break;
|
||||||
|
|
||||||
case '>':
|
case '>':
|
||||||
@@ -609,21 +601,23 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
|
|||||||
|
|
||||||
case 'S':
|
case 'S':
|
||||||
case 'U':
|
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;
|
break;
|
||||||
|
|
||||||
case 'T':
|
case 'T':
|
||||||
print (info->stream, dis_style_register, "%s",
|
print (info->stream, dis_style_register, "%s",
|
||||||
riscv_fpr_names[EXTRACT_OPERAND (RS2, l)]);
|
pd->riscv_fpr_names[EXTRACT_OPERAND (RS2, l)]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'D':
|
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;
|
break;
|
||||||
|
|
||||||
case 'R':
|
case 'R':
|
||||||
print (info->stream, dis_style_register, "%s",
|
print (info->stream, dis_style_register, "%s",
|
||||||
riscv_fpr_names[EXTRACT_OPERAND (RS3, l)]);
|
pd->riscv_fpr_names[EXTRACT_OPERAND (RS3, l)]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'E':
|
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;
|
riscv_csr_hash[i] = NULL;
|
||||||
|
|
||||||
/* Set to the newest privileged version. */
|
/* Set to the newest privileged version. */
|
||||||
if (default_priv_spec == PRIV_SPEC_CLASS_NONE)
|
if (pd->default_priv_spec == PRIV_SPEC_CLASS_NONE)
|
||||||
default_priv_spec = PRIV_SPEC_CLASS_DRAFT - 1;
|
pd->default_priv_spec = PRIV_SPEC_CLASS_DRAFT - 1;
|
||||||
|
|
||||||
#define DECLARE_CSR(name, num, class, define_version, abort_version) \
|
#define DECLARE_CSR(name, num, class, define_version, abort_version) \
|
||||||
if (riscv_csr_hash[num] == NULL \
|
if (riscv_csr_hash[num] == NULL \
|
||||||
&& ((define_version == PRIV_SPEC_CLASS_NONE \
|
&& ((define_version == PRIV_SPEC_CLASS_NONE \
|
||||||
&& abort_version == PRIV_SPEC_CLASS_NONE) \
|
&& abort_version == PRIV_SPEC_CLASS_NONE) \
|
||||||
|| (default_priv_spec >= define_version \
|
|| (pd->default_priv_spec >= define_version \
|
||||||
&& default_priv_spec < abort_version))) \
|
&& pd->default_priv_spec < abort_version))) \
|
||||||
riscv_csr_hash[num] = #name;
|
riscv_csr_hash[num] = #name;
|
||||||
#define DECLARE_CSR_ALIAS(name, num, class, define_version, abort_version) \
|
#define DECLARE_CSR_ALIAS(name, num, class, define_version, abort_version) \
|
||||||
DECLARE_CSR (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_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_VSTART
|
||||||
|| csr == CSR_VXSAT
|
|| csr == CSR_VXSAT
|
||||||
|| csr == CSR_VXRM
|
|| csr == CSR_VXRM
|
||||||
@@ -716,11 +710,11 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
|
|||||||
{
|
{
|
||||||
case '1':
|
case '1':
|
||||||
print (info->stream, dis_style_register, "%s",
|
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;
|
break;
|
||||||
case '2':
|
case '2':
|
||||||
print (info->stream, dis_style_register, "%s",
|
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;
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
print (info->stream, dis_style_immediate, "%d",
|
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;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
print (info->stream, dis_style_immediate, "%d",
|
print (info->stream, dis_style_immediate, "%d",
|
||||||
riscv_get_spimm (l));
|
riscv_get_spimm (l, pd->xlen));
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
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 XLEN is not known, get its value from the ELF class. */
|
||||||
if (info->mach == bfd_mach_riscv64)
|
if (info->mach == bfd_mach_riscv64)
|
||||||
xlen = 64;
|
pd->xlen = 64;
|
||||||
else if (info->mach == bfd_mach_riscv32)
|
else if (info->mach == bfd_mach_riscv32)
|
||||||
xlen = 32;
|
pd->xlen = 32;
|
||||||
else if (info->section != NULL)
|
else if (info->section != NULL)
|
||||||
{
|
{
|
||||||
Elf_Internal_Ehdr *ehdr = elf_elfheader (info->section->owner);
|
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 arch has the Zfinx extension, replace FPR with GPR. */
|
||||||
if (riscv_subset_supports (&riscv_rps_dis, "zfinx"))
|
if (riscv_subset_supports (&pd->riscv_rps_dis, "zfinx"))
|
||||||
riscv_fpr_names = riscv_gpr_names;
|
pd->riscv_fpr_names = pd->riscv_gpr_names;
|
||||||
else
|
else
|
||||||
riscv_fpr_names = riscv_gpr_names == riscv_gpr_names_abi ?
|
pd->riscv_fpr_names = pd->riscv_gpr_names == riscv_gpr_names_abi ?
|
||||||
riscv_fpr_names_abi : riscv_fpr_names_numeric;
|
riscv_fpr_names_abi : riscv_fpr_names_numeric;
|
||||||
|
|
||||||
for (; op->name; op++)
|
for (; op->name; op++)
|
||||||
{
|
{
|
||||||
@@ -972,14 +966,16 @@ riscv_disassemble_insn (bfd_vma memaddr,
|
|||||||
if (! (op->match_func) (op, word))
|
if (! (op->match_func) (op, word))
|
||||||
continue;
|
continue;
|
||||||
/* Is this a pseudo-instruction and may we print it as such? */
|
/* 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;
|
continue;
|
||||||
/* Is this instruction restricted to a certain value of XLEN? */
|
/* 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;
|
continue;
|
||||||
/* Is this instruction supported by the current architecture? */
|
/* Is this instruction supported by the current architecture? */
|
||||||
if (!all_ext
|
if (!pd->all_ext
|
||||||
&& !riscv_multi_subset_supports (&riscv_rps_dis, op->insn_class))
|
&& !riscv_multi_subset_supports (&pd->riscv_rps_dis,
|
||||||
|
op->insn_class))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* It's a match. */
|
/* It's a match. */
|
||||||
@@ -1060,6 +1056,7 @@ riscv_update_map_state (int n,
|
|||||||
enum riscv_seg_mstate *state,
|
enum riscv_seg_mstate *state,
|
||||||
struct disassemble_info *info)
|
struct disassemble_info *info)
|
||||||
{
|
{
|
||||||
|
struct riscv_private_data *pd = info->private_data;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
/* If the symbol is in a different section, ignore it. */
|
/* 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)
|
else if (strncmp (name, "$xrv", 4) == 0)
|
||||||
{
|
{
|
||||||
*state = MAP_INSN;
|
*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
|
/* ISA mapping string may be numbered, suffixed with '.n'. Do not
|
||||||
consider this as part of the ISA string. */
|
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);
|
char *name_substr = xmalloc (suffix_index + 1);
|
||||||
strncpy (name_substr, name, suffix_index);
|
strncpy (name_substr, name, suffix_index);
|
||||||
name_substr[suffix_index] = '\0';
|
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);
|
free (name_substr);
|
||||||
}
|
}
|
||||||
else
|
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,
|
riscv_search_mapping_symbol (bfd_vma memaddr,
|
||||||
struct disassemble_info *info)
|
struct disassemble_info *info)
|
||||||
{
|
{
|
||||||
|
struct riscv_private_data *pd = info->private_data;
|
||||||
enum riscv_seg_mstate mstate;
|
enum riscv_seg_mstate mstate;
|
||||||
bool from_last_map_symbol;
|
bool from_last_map_symbol;
|
||||||
bool found = false;
|
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
|
/* Return the last map state if the address is still within the range of the
|
||||||
last mapping symbol. */
|
last mapping symbol. */
|
||||||
if (last_map_section == info->section
|
if (pd->last_map_section == info->section
|
||||||
&& (memaddr < last_map_symbol_boundary))
|
&& (memaddr < pd->last_map_symbol_boundary))
|
||||||
return last_map_state;
|
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
|
/* Decide whether to print the data or instruction by default, in case
|
||||||
we can not find the corresponding mapping symbols. */
|
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. */
|
/* Reset the last_map_symbol if we start to dump a new section. */
|
||||||
if (memaddr <= 0)
|
if (memaddr <= 0)
|
||||||
last_map_symbol = -1;
|
pd->last_map_symbol = -1;
|
||||||
|
|
||||||
/* If the last stop offset is different from the current one, then
|
/* 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
|
don't use the last_map_symbol to search. We usually reset the
|
||||||
info->stop_offset when handling a new section. */
|
info->stop_offset when handling a new section. */
|
||||||
from_last_map_symbol = (last_map_symbol >= 0
|
from_last_map_symbol = (pd->last_map_symbol >= 0
|
||||||
&& info->stop_offset == last_stop_offset);
|
&& info->stop_offset == pd->last_stop_offset);
|
||||||
|
|
||||||
/* Start scanning from wherever we finished last time, or the start
|
/* Start scanning from wherever we finished last time, or the start
|
||||||
of the function. */
|
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. */
|
/* Find the suitable mapping symbol to dump. */
|
||||||
for (; n < info->symtab_size; n++)
|
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. */
|
can pick up a text mapping symbol of a preceeding section. */
|
||||||
if (!found)
|
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--)
|
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
|
/* The next mapping symbol has been found, and it represents the
|
||||||
boundary of this mapping symbol. */
|
boundary of this mapping symbol. */
|
||||||
found_next = true;
|
found_next = true;
|
||||||
last_map_symbol_boundary = addr;
|
pd->last_map_symbol_boundary = addr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1229,12 +1227,13 @@ riscv_search_mapping_symbol (bfd_vma memaddr,
|
|||||||
/* No further mapping symbol has been found, indicating that the boundary
|
/* No further mapping symbol has been found, indicating that the boundary
|
||||||
of the current mapping symbol is the end of this section. */
|
of the current mapping symbol is the end of this section. */
|
||||||
if (!found_next)
|
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. */
|
/* Save the information for next use. */
|
||||||
last_map_symbol = symbol;
|
pd->last_map_symbol = symbol;
|
||||||
last_stop_offset = info->stop_offset;
|
pd->last_stop_offset = info->stop_offset;
|
||||||
|
|
||||||
return mstate;
|
return mstate;
|
||||||
}
|
}
|
||||||
@@ -1245,17 +1244,18 @@ static bfd_vma
|
|||||||
riscv_data_length (bfd_vma memaddr,
|
riscv_data_length (bfd_vma memaddr,
|
||||||
disassemble_info *info)
|
disassemble_info *info)
|
||||||
{
|
{
|
||||||
|
struct riscv_private_data *pd = info->private_data;
|
||||||
bfd_vma length;
|
bfd_vma length;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
length = 4;
|
length = 4;
|
||||||
if (info->symtab_size != 0
|
if (info->symtab_size != 0
|
||||||
&& bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour
|
&& bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour
|
||||||
&& last_map_symbol >= 0)
|
&& pd->last_map_symbol >= 0)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
enum riscv_seg_mstate m = MAP_NONE;
|
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]);
|
bfd_vma addr = bfd_asymbol_value (info->symtab[n]);
|
||||||
if (addr > memaddr
|
if (addr > memaddr
|
||||||
@@ -1344,7 +1344,6 @@ static bool
|
|||||||
riscv_init_disasm_info (struct disassemble_info *info)
|
riscv_init_disasm_info (struct disassemble_info *info)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
struct riscv_private_data *pd =
|
struct riscv_private_data *pd =
|
||||||
xcalloc (1, sizeof (struct riscv_private_data));
|
xcalloc (1, sizeof (struct riscv_private_data));
|
||||||
pd->gp = 0;
|
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++)
|
for (i = 0; i < (int) ARRAY_SIZE (pd->hi_addr); i++)
|
||||||
pd->hi_addr[i] = -1;
|
pd->hi_addr[i] = -1;
|
||||||
pd->to_print_addr = false;
|
pd->to_print_addr = false;
|
||||||
pd->has_gp = false;
|
|
||||||
|
|
||||||
|
pd->has_gp = false;
|
||||||
for (i = 0; i < info->symtab_size; i++)
|
for (i = 0; i < info->symtab_size; i++)
|
||||||
{
|
{
|
||||||
asymbol *sym = info->symtab[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;
|
info->private_data = pd;
|
||||||
return true;
|
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 *,
|
int (*riscv_disassembler) (bfd_vma, insn_t, const bfd_byte *,
|
||||||
struct disassemble_info *);
|
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))
|
if (info->private_data == NULL && !riscv_init_disasm_info (info))
|
||||||
return -1;
|
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);
|
mstate = riscv_search_mapping_symbol (memaddr, info);
|
||||||
/* Save the last mapping state. */
|
/* 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. */
|
/* Set the size to dump. */
|
||||||
if (mstate == MAP_DATA
|
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);
|
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
|
/* Prevent use of the fake labels that are generated as part of the DWARF
|
||||||
and for relaxable relocations in the assembler. */
|
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)
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user