From feae0585b51a6524500d60036f58a945e4c19c6f 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/ChangeLog | 12 ++++++ gdb/aarch64-tdep.c | 100 ++++++++++++++++++++++++++++++++++++++++++++- gdb/aarch64-tdep.h | 15 +++++++ 3 files changed, 125 insertions(+), 2 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index e477c46fac3..1a40953f3ac 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,15 @@ +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. + 2020-10-20 Luis Machado * c-typeprint.c (c_type_print_varspec_prefix) diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index d9b55fdbdd0..f882a0a4652 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -66,6 +66,79 @@ /* All possible aarch64 target descriptors. */ struct target_desc *tdesc_aarch64_list[AARCH64_MAX_SVE_VQ + 1][2/*pauth*/][2 /* capability */]; +/* 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. */ + gdbarch_info_init (&info); + + 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) +{ + struct gdbarch_tdep *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 { @@ -3433,6 +3506,8 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) bool valid_p = true; int i, num_regs = 0, num_pseudo_regs = 0; int first_pauth_regnum = -1, pauth_ra_state_offset = -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 @@ -3573,6 +3648,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) struct gdbarch_tdep *tdep = XCNEW (struct 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. */ @@ -3710,8 +3786,11 @@ aarch64_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file) if (tdep == NULL) return; - fprintf_unfiltered (file, _("aarch64_dump_tdep: Lowest pc = 0x%s"), - paddress (gdbarch, tdep->lowest_pc)); + fprintf_unfiltered (file, _("%s: Lowest pc = 0x%s"), + __func__, paddress (gdbarch, tdep->lowest_pc)); + + fprintf_unfiltered (file, _("%s: ABI is %s"), + __func__, aarch64_abi_strings[tdep->abi]); } #if GDB_SELF_TEST @@ -3752,6 +3831,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, "set aarch64 ", 0, &setlist); + + add_show_prefix_cmd ("aarch64", no_class, + _("Various AArch64-specific commands."), + &show_aarch64_cmdlist, "show aarch64 ", 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 3a2c30c47f3..c7238207c0e 100644 --- a/gdb/aarch64-tdep.h +++ b/gdb/aarch64-tdep.h @@ -66,9 +66,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 gdbarch_tdep { + /* The current ABI. */ + aarch64_abi_kind abi; + /* Lowest address at which instructions will appear. */ CORE_ADDR lowest_pc; -- 2.39.5