aboutsummaryrefslogtreecommitdiff
path: root/opcodes
diff options
context:
space:
mode:
authorNelson Chu <nelson@rivosinc.com>2023-05-04 15:22:13 +0800
committerNelson Chu <nelson@rivosinc.com>2023-05-19 16:24:05 +0800
commit26e91972538544a237897baa5c806a008d36a88c (patch)
tree4baad01123ed0b2277dc27461678e03f75a46d9d /opcodes
parent1e66f4c55f83ba4d27330312aefdd4fbdf56cb43 (diff)
downloadgdb-26e91972538544a237897baa5c806a008d36a88c.zip
gdb-26e91972538544a237897baa5c806a008d36a88c.tar.gz
gdb-26e91972538544a237897baa5c806a008d36a88c.tar.bz2
RISC-V: Minor improvements for dis-assembler.
* Extract all private_data initializations into riscv_init_disasm_info, which called from print_insn_riscv rather than riscv_disassemble_insn. * The disassemble_free_target seems like the right place to release all target private_data, also including the internal data structures, like riscv_subsets. Therefore, add a new function, disassemble_free_riscv, to release them for safe. opcodes/ * disassemble.c (disassemble_free_target): Called disassemble_free_riscv for riscv to release private_data and internal data structures. * disassemble.h: Added extern disassemble_free_riscv. * riscv-dis.c (riscv_init_disasm_info): New function, used to init riscv_private_data. (riscv_disassemble_insn): Moved riscv_private_data initializations into riscv_init_disasm_info. (print_insn_riscv): Called riscv_init_disasm_info to init riscv_private_data once time. (disassemble_free_riscv): New function, used to free the internal data structures, like riscv_subsets.
Diffstat (limited to 'opcodes')
-rw-r--r--opcodes/disassemble.c1
-rw-r--r--opcodes/disassemble.h2
-rw-r--r--opcodes/riscv-dis.c58
3 files changed, 40 insertions, 21 deletions
diff --git a/opcodes/disassemble.c b/opcodes/disassemble.c
index 93052e7..03cfccc 100644
--- a/opcodes/disassemble.c
+++ b/opcodes/disassemble.c
@@ -800,6 +800,7 @@ disassemble_free_target (struct disassemble_info *info)
#endif
#ifdef ARCH_riscv
case bfd_arch_riscv:
+ disassemble_free_riscv (info);
break;
#endif
#ifdef ARCH_rs6000
diff --git a/opcodes/disassemble.h b/opcodes/disassemble.h
index d9ea70a..b7474a8 100644
--- a/opcodes/disassemble.h
+++ b/opcodes/disassemble.h
@@ -105,6 +105,8 @@ 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 ATTRIBUTE_NORETURN opcodes_assert (const char *, int);
#define OPCODES_ASSERT(x) \
diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index f25993d..108baeb 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -668,7 +668,7 @@ riscv_disassemble_insn (bfd_vma memaddr,
const struct riscv_opcode *op;
static bool init = false;
static const struct riscv_opcode *riscv_hash[OP_MASK_OP + 1];
- struct riscv_private_data *pd;
+ struct riscv_private_data *pd = info->private_data;
int insnlen, i;
bool printed;
@@ -684,26 +684,6 @@ riscv_disassemble_insn (bfd_vma memaddr,
init = true;
}
- if (info->private_data == NULL)
- {
- pd = info->private_data = xcalloc (1, sizeof (struct riscv_private_data));
- pd->gp = 0;
- pd->print_addr = 0;
- 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;
-
- for (i = 0; i < info->symtab_size; i++)
- if (strcmp (bfd_asymbol_name (info->symtab[i]), RISCV_GP_SYMBOL) == 0)
- {
- pd->gp = bfd_asymbol_value (info->symtab[i]);
- pd->has_gp = true;
- }
- }
- else
- pd = info->private_data;
-
insnlen = riscv_insn_length (word);
/* RISC-V instructions are always little-endian. */
@@ -1079,6 +1059,34 @@ riscv_disassemble_data (bfd_vma memaddr ATTRIBUTE_UNUSED,
return info->bytes_per_chunk;
}
+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;
+ pd->print_addr = 0;
+ 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;
+
+ for (i = 0; i < info->symtab_size; i++)
+ {
+ asymbol *sym = info->symtab[i];
+ if (strcmp (bfd_asymbol_name (sym), RISCV_GP_SYMBOL) == 0)
+ {
+ pd->gp = bfd_asymbol_value (sym);
+ pd->has_gp = true;
+ }
+ }
+
+ info->private_data = pd;
+ return true;
+}
+
int
print_insn_riscv (bfd_vma memaddr, struct disassemble_info *info)
{
@@ -1099,6 +1107,9 @@ print_insn_riscv (bfd_vma memaddr, struct disassemble_info *info)
else if (riscv_gpr_names == NULL)
set_default_riscv_dis_options ();
+ if (info->private_data == NULL && !riscv_init_disasm_info (info))
+ return -1;
+
mstate = riscv_search_mapping_symbol (memaddr, info);
/* Save the last mapping state. */
last_map_state = mstate;
@@ -1333,3 +1344,8 @@ with the -M switch (multiple options should be separated by commas):\n"));
fprintf (stream, _("\n"));
}
+
+void disassemble_free_riscv (struct disassemble_info *info ATTRIBUTE_UNUSED)
+{
+ riscv_release_subset_list (&riscv_subsets);
+}