RISC-V: Minor improvements for dis-assembler.
authorNelson Chu <nelson@rivosinc.com>
Thu, 4 May 2023 07:22:13 +0000 (15:22 +0800)
committerNelson Chu <nelson@rivosinc.com>
Fri, 19 May 2023 08:24:05 +0000 (16:24 +0800)
* 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.

opcodes/disassemble.c
opcodes/disassemble.h
opcodes/riscv-dis.c

index 93052e75088b14729ab76fd74cecf38a66dcbf1c..03cfccc562e2d2ddfc3d7943cde26e41fb903767 100644 (file)
@@ -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
index d9ea70ac94963b0fcf9cf6d0cbe576a9225a43da..b7474a85e5dbf2f637b0397edaea21a7f38335b4 100644 (file)
@@ -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) \
index f25993d1e45e9d9b7e15f5e3d4197a0ed399cad9..108baeb32ef71c500242bf3c832fbdd5306d1860 100644 (file)
@@ -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);
+}