+2021-03-17 Luis Machado <luis.machado@arm.com>
+
+ * aarch64-tdep.c (aarch64_find_mapping_symbol, aarch64_pc_is_c64): New
+ functions.
+ (aarch64_gdb_print_insn): Pass map type to disassembler.
+
2021-01-15 Luis Machado <luis.machado@arm.com>
* aarch64-linux-nat.c (store_cregs_to_thread): Implement.
return -1;
}
+/* Search for the mapping symbol covering MEMADDR. If one is found,
+ return its type. Otherwise, return 0. If START is non-NULL,
+ set *START to the location of the mapping symbol. */
+
+static char
+aarch64_find_mapping_symbol (CORE_ADDR memaddr, CORE_ADDR *start)
+{
+ struct obj_section *sec;
+
+ /* If there are mapping symbols, consult them. */
+ sec = find_pc_section (memaddr);
+ if (sec != NULL)
+ {
+ aarch64_per_bfd *data = aarch64_bfd_data_key.get (sec->objfile->obfd);
+ if (data != NULL)
+ {
+ unsigned int section_idx = sec->the_bfd_section->index;
+ aarch64_mapping_symbol_vec &map
+ = data->section_maps[section_idx];
+
+ /* Sort the vector on first use. */
+ if (!data->section_maps_sorted[section_idx])
+ {
+ std::sort (map.begin (), map.end ());
+ data->section_maps_sorted[section_idx] = true;
+ }
+
+ struct aarch64_mapping_symbol map_key
+ = { memaddr - obj_section_addr (sec), 0 };
+ aarch64_mapping_symbol_vec::const_iterator it
+ = std::lower_bound (map.begin (), map.end (), map_key);
+
+ /* std::lower_bound finds the earliest ordered insertion
+ point. If the symbol at this position starts at this exact
+ address, we use that; otherwise, the preceding
+ mapping symbol covers this address. */
+ if (it < map.end ())
+ {
+ if (it->value == map_key.value)
+ {
+ if (start)
+ *start = it->value + obj_section_addr (sec);
+ return it->type;
+ }
+ }
+
+ if (it > map.begin ())
+ {
+ aarch64_mapping_symbol_vec::const_iterator prev_it
+ = it - 1;
+
+ if (start)
+ *start = prev_it->value + obj_section_addr (sec);
+ return prev_it->type;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/* Determine if the program counter specified in MEMADDR is in a C64
+ function. This function should be called for addresses unrelated to
+ any executing frame. */
+
+static bool
+aarch64_pc_is_c64 (struct gdbarch *gdbarch, CORE_ADDR memaddr)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ /* If we're using the AAPCS64-CAP ABI, then this is pure-cap and it is
+ always C64. */
+ if (tdep->abi == AARCH64_ABI_AAPCS64_CAP)
+ return true;
+
+ /* If there are mapping symbols, consult them. */
+ char type = aarch64_find_mapping_symbol (memaddr, NULL);
+ if (type)
+ return type == 'c';
+
+ /* C64 functions have a "special" bit set in minimal symbols. */
+ struct bound_minimal_symbol sym;
+ sym = lookup_minimal_symbol_by_pc (memaddr);
+ if (sym.minsym)
+ return (MSYMBOL_IS_SPECIAL (sym.minsym));
+
+ /* Otherwise we're out of luck; we assume A64. */
+ return false;
+}
+
/* Implement the "print_insn" gdbarch method. */
static int
aarch64_gdb_print_insn (bfd_vma memaddr, disassemble_info *info)
{
+ gdb_disassembler *di
+ = static_cast<gdb_disassembler *>(info->application_data);
+ struct gdbarch *gdbarch = di->arch ();
+ struct aarch64_private_data data;
+
+ info->private_data = static_cast<void *> (&data);
+
+ if (aarch64_pc_is_c64 (gdbarch, memaddr))
+ data.instruction_type = MAP_TYPE_C64;
+
info->symbols = NULL;
+
return default_print_insn (memaddr, info);
}
+2021-03-17 Luis Machado <luis.machado@arm.com>
+
+ * opcode/aarch64.h (enum map_type): Moved from opcodes/aarch64-dis.c.
+ Renamed fields.
+ (struct aarch64_private_data): New struct.
+
2020-10-20 Luis Machado <luis.machado@arm.com>
* elf/common.h (NT_ARM_MORELLO): Define.
int next_insn;
};
+/* Cached mapping symbol state. */
+enum map_type
+{
+ MAP_TYPE_INSN,
+ MAP_TYPE_DATA,
+ MAP_TYPE_C64
+};
+
+/* AArch64-specific data to help proper disassembling of instructions. */
+struct aarch64_private_data
+{
+ enum map_type instruction_type;
+};
+
/* Encoding entrypoint. */
extern int
+2021-03-17 Luis Machado <luis.machado@arm.com>
+
+ * aarch64-dis.c (enum map_type): Moved to include/opcode/aarch64.h.
+ (MAYBE_C64): Adjust.
+ (get_sym_code_type): Adjust.
+ (print_insn_aarch64): Use private data when available.
+
2020-10-20 Luis Machado <luis.machado@arm.com>
* aarch64-tbl.h (aarch64_opcode_table): Update iclass field
#define INSNLEN 4
-/* Cached mapping symbol state. */
-enum map_type
-{
- MAP_INSN,
- MAP_DATA,
- MAP_C64
-};
-
static aarch64_feature_set arch_variant; /* See select_aarch64_variant. */
static enum map_type last_type;
static int last_mapping_sym = -1;
static bfd_vma last_stop_offset = 0;
static bfd_vma last_mapping_addr = 0;
-#define MAYBE_C64 (last_type == MAP_C64 ? AARCH64_FEATURE_C64 : 0)
+#define MAYBE_C64 (last_type == MAP_TYPE_C64 ? AARCH64_FEATURE_C64 : 0)
/* Other options */
static int no_aliases = 0; /* If set disassemble as most general inst. */
if (type == STT_FUNC && !(es->symbol.flags & BSF_SYNTHETIC))
{
*map_type = (es->internal_elf_sym.st_target_internal & ST_BRANCH_TO_C64
- ? MAP_C64 : MAP_INSN);
+ ? MAP_TYPE_C64 : MAP_TYPE_INSN);
return TRUE;
}
switch (name[1])
{
case 'd':
- *map_type = MAP_DATA;
+ *map_type = MAP_TYPE_DATA;
break;
case 'x':
- *map_type = MAP_INSN;
+ *map_type = MAP_TYPE_INSN;
break;
case 'c':
- *map_type = MAP_C64;
+ *map_type = MAP_TYPE_C64;
break;
default:
abort ();
/* Aarch64 instructions are always little-endian */
info->endian_code = BFD_ENDIAN_LITTLE;
- /* Default to DATA. A text section is required by the ABI to contain an
- INSN mapping symbol at the start. A data section has no such
- requirement, hence if no mapping symbol is found the section must
- contain only data. This however isn't very useful if the user has
- fully stripped the binaries. If this is the case use the section
- attributes to determine the default. If we have no section default to
- INSN as well, as we may be disassembling some raw bytes on a baremetal
- HEX file or similar. */
- enum map_type type = MAP_DATA;
- if ((info->section && info->section->flags & SEC_CODE) || !info->section)
- type = last_type == MAP_C64 ? MAP_C64 : MAP_INSN;
+ enum map_type type;
+
+ if (info->private_data != NULL)
+ {
+ struct aarch64_private_data *aarch64_data
+ = (struct aarch64_private_data *) info->private_data;
+ type = aarch64_data->instruction_type;
+ }
+ else
+ {
+ /* Default to DATA. A text section is required by the ABI to contain an
+ INSN mapping symbol at the start. A data section has no such
+ requirement, hence if no mapping symbol is found the section must
+ contain only data. This however isn't very useful if the user has
+ fully stripped the binaries. If this is the case use the section
+ attributes to determine the default. If we have no section default to
+ INSN as well, as we may be disassembling some raw bytes on a baremetal
+ HEX file or similar. */
+ type = MAP_TYPE_DATA;
+ if ((info->section && info->section->flags & SEC_CODE) || !info->section)
+ type = last_type == MAP_TYPE_C64 ? MAP_TYPE_C64 : MAP_TYPE_INSN;
+ }
/* First check the full symtab for a mapping symbol, even if there
are no usable non-mapping symbols for this address. */
less than four bytes of data. If there's a symbol,
mapping or otherwise, after two bytes then don't
print more. */
- if (last_type == MAP_DATA)
+ if (last_type == MAP_TYPE_DATA)
{
size = 4 - (pc & 3);
for (n = last_sym + 1; n < info->symtab_size; n++)
last_type = type;
/* PR 10263: Disassemble data if requested to do so by the user. */
- if (last_type == MAP_DATA && ((info->flags & DISASSEMBLE_DATA) == 0))
+ if (last_type == MAP_TYPE_DATA && ((info->flags & DISASSEMBLE_DATA) == 0))
{
/* size was set above. */
info->bytes_per_chunk = size;