From: Alan Hayward Date: Thu, 13 Sep 2018 15:48:27 +0000 (+0100) Subject: Add target_description_changed_p and target_get_tdep_info methods X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c749ff472db05b55b183eac3de5a0edd75798a56;p=thirdparty%2Fbinutils-gdb.git Add target_description_changed_p and target_get_tdep_info methods target_description_changed_p () is added as a new gdbarch function. Given a list of register values received from the inferior, it will check if the current target descriptor is no longer valid for the inferior. This is required because on SVE the register sizes can change whilst the inferior is running. target_get_tdep_info () is added as a new gdbarch function. Given a list of registers, it will return a tdep info which then can be used when creating/finding a valid target descriptor for that inferior. Include stubbed aarch64 versions. 2018-09-13 Alan Hayward gdb/ * aarch64-tdep.c (aarch64_target_description_changed_p): New function. (aarch64_target_get_tdep_info): New function. (aarch64_gdbarch_init): Add in the new functions * arch-utils.c (default_target_description_changed_p): New function. (default_target_get_tdep_info): New function. * arch-utils.h: (default_target_description_changed_p): New declaration. (default_target_get_tdep_info): New declaration. * gdbarch.c: Regenerate. * gdbarch.h: Regenerate. * gdbarch.sh: (target_description_changed_p): New function. (target_get_tdep_info): New function. --- diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index 9859ba15692..209bc256f35 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -2964,6 +2964,24 @@ aarch64_get_tdesc_vq (const struct target_desc *tdesc) } +/* Implement the "target_description_changed_p" gdbarch method. */ + +static bool +aarch64_target_description_changed_p (struct gdbarch *gdbarch, + ptid_t ptid, + VEC (cached_reg_t) *registers) +{ + return false; +} + +/* Implement the "target_get_tdep_info" gdbarch method. */ + +static union gdbarch_target_info +aarch64_target_get_tdep_info (VEC (cached_reg_t) *registers) +{ + return {0}; +} + /* Initialize the current architecture based on INFO. If possible, re-use an architecture from ARCHES, which is a list of architectures already created during this debugging session. @@ -3129,6 +3147,9 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_tdesc_pseudo_register_type (gdbarch, aarch64_pseudo_register_type); set_tdesc_pseudo_register_reggroup_p (gdbarch, aarch64_pseudo_register_reggroup_p); + set_gdbarch_target_description_changed_p + (gdbarch, aarch64_target_description_changed_p); + set_gdbarch_target_get_tdep_info (gdbarch, aarch64_target_get_tdep_info); /* ABI */ set_gdbarch_short_bit (gdbarch, 16); diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c index 6b40cb91607..baedeb4c73b 100644 --- a/gdb/arch-utils.c +++ b/gdb/arch-utils.c @@ -996,6 +996,24 @@ default_type_align (struct gdbarch *gdbarch, struct type *type) return type_length_units (check_typedef (type)); } +/* See arch-utils.h. */ + +bool +default_target_description_changed_p (struct gdbarch *gdbarch, + ptid_t ptid, + VEC (cached_reg_t) *registers) +{ + return false; +} + +/* See arch-utils.h. */ + +union gdbarch_target_info +default_target_get_tdep_info (VEC (cached_reg_t) *registers) +{ + return {0}; +} + void _initialize_gdbarch_utils (void) { diff --git a/gdb/arch-utils.h b/gdb/arch-utils.h index 77ee9af2bfc..508adf5a546 100644 --- a/gdb/arch-utils.h +++ b/gdb/arch-utils.h @@ -271,4 +271,13 @@ extern bool default_in_indirect_branch_thunk (gdbarch *gdbarch, extern ULONGEST default_type_align (struct gdbarch *gdbarch, struct type *type); +/* Default implementation of target_description_changed_p. Returns False. */ +extern bool default_target_description_changed_p + (struct gdbarch *gdbarch, ptid_t ptid, VEC (cached_reg_t) *registers); + +/* Default implementation of default_target_get_tdep_info. Returns null + info. */ +extern union gdbarch_target_info default_target_get_tdep_info + (VEC (cached_reg_t) *registers); + #endif diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index 19dacea34fe..9d4745b08f1 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -354,6 +354,8 @@ struct gdbarch char ** disassembler_options; const disasm_options_and_args_t * valid_disassembler_options; gdbarch_type_align_ftype *type_align; + gdbarch_target_description_changed_p_ftype *target_description_changed_p; + gdbarch_target_get_tdep_info_ftype *target_get_tdep_info; }; /* Create a new ``struct gdbarch'' based on information provided by @@ -466,6 +468,8 @@ gdbarch_alloc (const struct gdbarch_info *info, gdbarch->gnu_triplet_regexp = default_gnu_triplet_regexp; gdbarch->addressable_memory_unit_size = default_addressable_memory_unit_size; gdbarch->type_align = default_type_align; + gdbarch->target_description_changed_p = default_target_description_changed_p; + gdbarch->target_get_tdep_info = default_target_get_tdep_info; /* gdbarch_alloc() */ return gdbarch; @@ -712,6 +716,8 @@ verify_gdbarch (struct gdbarch *gdbarch) /* Skip verify of disassembler_options, invalid_p == 0 */ /* Skip verify of valid_disassembler_options, invalid_p == 0 */ /* Skip verify of type_align, invalid_p == 0 */ + /* Skip verify of target_description_changed_p, invalid_p == 0 */ + /* Skip verify of target_get_tdep_info, invalid_p == 0 */ if (!log.empty ()) internal_error (__FILE__, __LINE__, _("verify_gdbarch: the following are invalid ...%s"), @@ -1437,6 +1443,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) fprintf_unfiltered (file, "gdbarch_dump: target_desc = %s\n", host_address_to_string (gdbarch->target_desc)); + fprintf_unfiltered (file, + "gdbarch_dump: target_description_changed_p = <%s>\n", + host_address_to_string (gdbarch->target_description_changed_p)); + fprintf_unfiltered (file, + "gdbarch_dump: target_get_tdep_info = <%s>\n", + host_address_to_string (gdbarch->target_get_tdep_info)); fprintf_unfiltered (file, "gdbarch_dump: type_align = <%s>\n", host_address_to_string (gdbarch->type_align)); @@ -5117,6 +5129,40 @@ set_gdbarch_type_align (struct gdbarch *gdbarch, gdbarch->type_align = type_align; } +bool +gdbarch_target_description_changed_p (struct gdbarch *gdbarch, ptid_t ptid, VEC (cached_reg_t) *registers) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->target_description_changed_p != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_target_description_changed_p called\n"); + return gdbarch->target_description_changed_p (gdbarch, ptid, registers); +} + +void +set_gdbarch_target_description_changed_p (struct gdbarch *gdbarch, + gdbarch_target_description_changed_p_ftype target_description_changed_p) +{ + gdbarch->target_description_changed_p = target_description_changed_p; +} + +union gdbarch_target_info +gdbarch_target_get_tdep_info (struct gdbarch *gdbarch, VEC (cached_reg_t) *registers) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->target_get_tdep_info != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_target_get_tdep_info called\n"); + return gdbarch->target_get_tdep_info (registers); +} + +void +set_gdbarch_target_get_tdep_info (struct gdbarch *gdbarch, + gdbarch_target_get_tdep_info_ftype target_get_tdep_info) +{ + gdbarch->target_get_tdep_info = target_get_tdep_info; +} + /* Keep a registry of per-architecture data-pointers required by GDB modules. */ diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index 72edc791779..157e8928a27 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -1587,6 +1587,23 @@ typedef ULONGEST (gdbarch_type_align_ftype) (struct gdbarch *gdbarch, struct typ extern ULONGEST gdbarch_type_align (struct gdbarch *gdbarch, struct type *type); extern void set_gdbarch_type_align (struct gdbarch *gdbarch, gdbarch_type_align_ftype *type_align); +/* Given a list of register values (in a VEC of reg_info_t structures) received + from the inferior, check if the current target descriptor is no longer valid + for the inferior (for example, register sizes have changed), and if so return + true. The default implementation will always return false. */ + +typedef bool (gdbarch_target_description_changed_p_ftype) (struct gdbarch *gdbarch, ptid_t ptid, VEC (cached_reg_t) *registers); +extern bool gdbarch_target_description_changed_p (struct gdbarch *gdbarch, ptid_t ptid, VEC (cached_reg_t) *registers); +extern void set_gdbarch_target_description_changed_p (struct gdbarch *gdbarch, gdbarch_target_description_changed_p_ftype *target_description_changed_p); + +/* Given a list of registers, return a tdep info which then can be used when + creating/finding a valid target descriptor for that inferior. The default + implementation will always return null. */ + +typedef union gdbarch_target_info (gdbarch_target_get_tdep_info_ftype) (VEC (cached_reg_t) *registers); +extern union gdbarch_target_info gdbarch_target_get_tdep_info (struct gdbarch *gdbarch, VEC (cached_reg_t) *registers); +extern void set_gdbarch_target_get_tdep_info (struct gdbarch *gdbarch, gdbarch_target_get_tdep_info_ftype *target_get_tdep_info); + /* Definition for an unknown syscall, used basically in error-cases. */ #define UNKNOWN_SYSCALL (-1) diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh index 9e770c41089..b19ab976c55 100755 --- a/gdb/gdbarch.sh +++ b/gdb/gdbarch.sh @@ -1166,6 +1166,17 @@ v;const disasm_options_and_args_t *;valid_disassembler_options;;;0;0;;0;host_add # Type alignment. m;ULONGEST;type_align;struct type *type;type;;default_type_align;;0 +# Given a list of register values (in a VEC of reg_info_t structures) received +# from the inferior, check if the current target descriptor is no longer valid +# for the inferior (for example, register sizes have changed), and if so return +# true. The default implementation will always return false. +m;bool;target_description_changed_p;ptid_t ptid, VEC (cached_reg_t) *registers;ptid, registers;;default_target_description_changed_p;;0 + +# Given a list of registers, return a tdep info which then can be used when +# creating/finding a valid target descriptor for that inferior. The default +# implementation will always return null. +f;union gdbarch_target_info;target_get_tdep_info;VEC (cached_reg_t) *registers;registers;;default_target_get_tdep_info;;0 + EOF } diff --git a/gdb/regcache.h b/gdb/regcache.h index 4a45f338718..12022a1fece 100644 --- a/gdb/regcache.h +++ b/gdb/regcache.h @@ -152,6 +152,8 @@ typedef struct cached_reg gdb_byte *data; } cached_reg_t; +DEF_VEC_O(cached_reg_t); + /* Buffer of registers. */ class reg_buffer : public reg_buffer_common diff --git a/gdb/remote.c b/gdb/remote.c index 3b19da75eaf..69e7d93c87e 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -6842,8 +6842,6 @@ remote_console_output (char *msg) gdb_flush (gdb_stdtarg); } -DEF_VEC_O(cached_reg_t); - typedef struct stop_reply { struct notif_event base;