aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--opcodes/riscv-dis.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index 3aaa45f..f25993d 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -64,6 +64,9 @@ struct riscv_private_data
/* 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 * const *riscv_gpr_names;
@@ -868,6 +871,14 @@ riscv_search_mapping_symbol (bfd_vma memaddr,
int symbol = -1;
int n;
+ /* 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;
+
+ 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. */
mstate = MAP_DATA;
@@ -939,6 +950,36 @@ riscv_search_mapping_symbol (bfd_vma memaddr,
}
}
+ if (found)
+ {
+ /* Find the next mapping symbol to determine the boundary of this mapping
+ symbol. */
+
+ bool found_next = false;
+ /* Try to found next mapping symbol. */
+ for (n = symbol + 1; n < info->symtab_size; n++)
+ {
+ if (info->symtab[symbol]->section != info->symtab[n]->section)
+ continue;
+
+ bfd_vma addr = bfd_asymbol_value (info->symtab[n]);
+ const char *sym_name = bfd_asymbol_name(info->symtab[n]);
+ if (sym_name[0] == '$' && (sym_name[1] == 'x' || sym_name[1] == 'd'))
+ {
+ /* The next mapping symbol has been found, and it represents the
+ boundary of this mapping symbol. */
+ found_next = true;
+ last_map_symbol_boundary = addr;
+ break;
+ }
+ }
+
+ /* 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;
+ }
+
/* Save the information for next use. */
last_map_symbol = symbol;
last_stop_offset = info->stop_offset;
@@ -1059,6 +1100,8 @@ print_insn_riscv (bfd_vma memaddr, struct disassemble_info *info)
set_default_riscv_dis_options ();
mstate = riscv_search_mapping_symbol (memaddr, info);
+ /* Save the last mapping state. */
+ last_map_state = mstate;
/* Set the size to dump. */
if (mstate == MAP_DATA