aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Hayward <alan.hayward@arm.com>2018-09-13 16:48:27 +0100
committerAlan Hayward <alan.hayward@arm.com>2018-09-13 16:48:27 +0100
commitc749ff472db05b55b183eac3de5a0edd75798a56 (patch)
tree913108efdfdd0586796edc6ca88fa6af6adce122
parent94db4093aa62bad3fc8abea6ba6b353b1699e6bb (diff)
downloadfsf-binutils-gdb-c749ff472db05b55b183eac3de5a0edd75798a56.zip
fsf-binutils-gdb-c749ff472db05b55b183eac3de5a0edd75798a56.tar.gz
fsf-binutils-gdb-c749ff472db05b55b183eac3de5a0edd75798a56.tar.bz2
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 <alan.hayward@arm.com> 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.
-rw-r--r--gdb/aarch64-tdep.c21
-rw-r--r--gdb/arch-utils.c18
-rw-r--r--gdb/arch-utils.h9
-rw-r--r--gdb/gdbarch.c46
-rw-r--r--gdb/gdbarch.h17
-rwxr-xr-xgdb/gdbarch.sh11
-rw-r--r--gdb/regcache.h2
-rw-r--r--gdb/remote.c2
8 files changed, 124 insertions, 2 deletions
diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index 9859ba1..209bc25 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 6b40cb91..baedeb4 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 77ee9af..508adf5 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 19dacea..9d4745b 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"),
@@ -1438,6 +1444,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *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));
fprintf_unfiltered (file,
@@ -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 72edc79..157e892 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 9e770c4..b19ab97 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 4a45f33..12022a1 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 3b19da7..69e7d93 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;