From 883f5c1d08ba7e4229554f63f849bffb92a114f8 Mon Sep 17 00:00:00 2001 From: Luis Machado Date: Fri, 17 Jul 2020 17:40:44 -0300 Subject: [PATCH] [Morello] Add set/show ABI command for AArch64 Add a new command for developers to set and show the AArch64 ABI GDB is using at the moment. We define 2 ABI's: AAPCS64 and AAPCS64-cap. Each of these ABI's should impact the architecture setup in different ways. gdb/ChangeLog: 2020-10-20 Luis Machado * aarch64-tdep.c (set_aarch64_cmdlist, show_aarch64_cmdlist, aarch64_abi_strings, aarch64_current_abi_global) (aarch64_current_abi_string): New static globals. (aarch64_update_current_architecture, aarch64_set_abi) (aarch64_show_abi): New functions. (aarch64_gdbarch_init): Handle ABI identification. (_initialize_aarch64_tdep): Add new ABI commands. * aarch64-tdep.h (aarch64_abi_kind): New enum. (struct gdbarch_tdep) : New field. --- gdb/aarch64-tdep.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++ gdb/aarch64-tdep.h | 15 ++++++++ 2 files changed, 110 insertions(+) diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index f9cce1db8b0..ca2cf5c104c 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -63,6 +63,78 @@ /* All possible aarch64 target descriptors. */ static std::unordered_map tdesc_aarch64_map; +/* The list of available aarch64 set/show commands. */ +static struct cmd_list_element *set_aarch64_cmdlist = NULL; +static struct cmd_list_element *show_aarch64_cmdlist = NULL; + +/* The ABI to use. Keep this in sync with aarch64_abi_kind. */ +static const char *const aarch64_abi_strings[] = +{ + "auto", + "AAPCS64", + "AAPCS64-cap", + nullptr +}; + +/* Variables for the ABI user setting. */ +static enum aarch64_abi_kind aarch64_current_abi_global = AARCH64_ABI_AUTO; +static const char *aarch64_current_abi_string = "auto"; + +static void +aarch64_update_current_architecture (void) +{ + struct gdbarch_info info; + + /* If the current architecture is not AArch64, we have nothing to do. */ + if (gdbarch_bfd_arch_info (target_gdbarch ())->arch != bfd_arch_aarch64) + return; + + /* Update the architecture. */ + if (!gdbarch_update_p (info)) + internal_error (__FILE__, __LINE__, _("could not update architecture")); +} + +/* Sets the current ABI for AArch64. */ + +static void +aarch64_set_abi (const char *args, int from_tty, + struct cmd_list_element *c) +{ + int abi; + + for (abi = AARCH64_ABI_AUTO; abi != AARCH64_ABI_LAST; abi++) + if (strcmp (aarch64_current_abi_string, aarch64_abi_strings[abi]) == 0) + { + aarch64_current_abi_global = (enum aarch64_abi_kind) abi; + break; + } + + if (abi == AARCH64_ABI_LAST) + internal_error (__FILE__, __LINE__, _("Invalid ABI accepted: %s."), + aarch64_current_abi_string); + + aarch64_update_current_architecture (); +} + +/* Shows the current ABI for AArch64. */ + +static void +aarch64_show_abi (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + aarch64_gdbarch_tdep *tdep + = (aarch64_gdbarch_tdep *) gdbarch_tdep (target_gdbarch ()); + + if (aarch64_current_abi_global == AARCH64_ABI_AUTO + && gdbarch_bfd_arch_info (target_gdbarch ())->arch == bfd_arch_aarch64) + fprintf_filtered (file, _("\ +The current AArch64 ABI is \"auto\" (currently \"%s\").\n"), + aarch64_abi_strings[tdep->abi]); + else + fprintf_filtered (file, _("The current AArch64 ABI is \"%s\".\n"), + aarch64_current_abi_string); +} + /* The standard register names, and all the valid aliases for them. */ static const struct { @@ -3505,6 +3577,8 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) int i, num_regs = 0, num_pseudo_regs = 0; int first_pauth_regnum = -1, pauth_ra_state_offset = -1; int first_mte_regnum = -1, tls_regnum = -1; + aarch64_abi_kind abi = (aarch64_current_abi_global == AARCH64_ABI_AUTO)? + AARCH64_ABI_AAPCS64 : aarch64_current_abi_global; /* Use the vector length passed via the target info. Here -1 is used for no SVE, and 0 is unset. If unset then use the vector length from the existing @@ -3681,6 +3755,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) aarch64_gdbarch_tdep *tdep = new aarch64_gdbarch_tdep; struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep); + tdep->abi = abi; /* This should be low enough for everything. */ tdep->lowest_pc = 0x20; tdep->jb_pc = -1; /* Longjump support not enabled by default. */ @@ -3825,6 +3900,9 @@ aarch64_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file) fprintf_filtered (file, _("aarch64_dump_tdep: Lowest pc = 0x%s"), paddress (gdbarch, tdep->lowest_pc)); + + fprintf_filtered (file, _("%s: ABI is %s"), + __func__, aarch64_abi_strings[tdep->abi]); } #if GDB_SELF_TEST @@ -3865,6 +3943,23 @@ _initialize_aarch64_tdep () gdbarch_register (bfd_arch_aarch64, aarch64_gdbarch_init, aarch64_dump_tdep); + /* Add root prefix command for all set/show aarch64 commands. */ + add_basic_prefix_cmd ("aarch64", no_class, + _("Various AArch64-specific commands."), + &set_aarch64_cmdlist, 0, &setlist); + + add_show_prefix_cmd ("aarch64", no_class, + _("Various AArch64-specific commands."), + &show_aarch64_cmdlist, 0, &showlist); + + /* Add a command to allow the user to force the ABI. */ + add_setshow_enum_cmd ("abi", class_support, aarch64_abi_strings, + &aarch64_current_abi_string, + _("Set the ABI."), + _("Show the ABI."), + NULL, aarch64_set_abi, aarch64_show_abi, + &set_aarch64_cmdlist, &show_aarch64_cmdlist); + /* Debug this file's internals. */ add_setshow_boolean_cmd ("aarch64", class_maintenance, &aarch64_debug, _("\ Set AArch64 debugging."), _("\ diff --git a/gdb/aarch64-tdep.h b/gdb/aarch64-tdep.h index e847a42cbe6..7598df1471e 100644 --- a/gdb/aarch64-tdep.h +++ b/gdb/aarch64-tdep.h @@ -67,9 +67,24 @@ struct regset; single-stepped instruction. */ #define AARCH64_DISPLACED_MODIFIED_INSNS 1 +/* AArch64 ABI used by the inferior. */ +enum aarch64_abi_kind +{ + AARCH64_ABI_AUTO, + /* Procedure Call Standard for the Arm 64-bit Architecture. */ + AARCH64_ABI_AAPCS64, + /* The pure capability Procedure Call Standard for the Arm 64-bit + Architecture (AArch64). */ + AARCH64_ABI_AAPCS64_CAP, + AARCH64_ABI_LAST +}; + /* Target-dependent structure in gdbarch. */ struct aarch64_gdbarch_tdep : gdbarch_tdep { + /* The current ABI. */ + aarch64_abi_kind abi; + /* Lowest address at which instructions will appear. */ CORE_ADDR lowest_pc = 0; -- 2.47.2