From: Nelson Chu Date: Thu, 4 May 2023 07:22:13 +0000 (+0800) Subject: RISC-V: Minor improvements for dis-assembler. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=26e91972538544a237897baa5c806a008d36a88c;p=binutils-gdb.git 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. --- diff --git a/opcodes/disassemble.c b/opcodes/disassemble.c index 93052e75088..03cfccc562e 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 d9ea70ac949..b7474a85e5d 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 f25993d1e45..108baeb32ef 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); +}