aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2022-11-15 17:35:09 -0800
committerJohn Baldwin <jhb@FreeBSD.org>2022-11-15 17:40:27 -0800
commit4695a547e1f2f7b25598a43544707a3f7651ec9d (patch)
tree7a2451613e6a0e438fa18ccb6586a8ff1f955a31
parentddd1b56a1dcec42f549b140dfeee394c93599072 (diff)
downloadfsf-binutils-gdb-4695a547e1f2f7b25598a43544707a3f7651ec9d.zip
fsf-binutils-gdb-4695a547e1f2f7b25598a43544707a3f7651ec9d.tar.gz
fsf-binutils-gdb-4695a547e1f2f7b25598a43544707a3f7651ec9d.tar.bz2
gdb tdesc: Handle mismatched pointer register types.
In the XML target descriptions, registers can be given a type of "code_ptr" or "data_ptr". GDB always uses the builtin type for "void *" for these registers. However, this is wrong if the register's size does not match (e.g. the legacy "sp" and "pc" ARM64 registers when using a purecap binary for which "void *" is a capability). If the sizes don't match, try to find a matching type such as "long" or "intcap_t" to use instead.
-rw-r--r--gdb/target-descriptions.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/gdb/target-descriptions.c b/gdb/target-descriptions.c
index 5b886f4..a003009 100644
--- a/gdb/target-descriptions.c
+++ b/gdb/target-descriptions.c
@@ -945,7 +945,24 @@ tdesc_register_type (struct gdbarch *gdbarch, int regno)
{
/* First check for a predefined or target defined type. */
if (reg->tdesc_type)
- arch_reg->type = make_gdb_type (gdbarch, reg->tdesc_type);
+ {
+ if ((reg->type == "code_ptr" || reg->type == "data_ptr")
+ && reg->bitsize != gdbarch_ptr_bit (gdbarch))
+ {
+ if (reg->bitsize == gdbarch_long_bit (gdbarch))
+ arch_reg->type = builtin_type (gdbarch)->builtin_long;
+ else if (reg->bitsize == gdbarch_capability_bit (gdbarch))
+ arch_reg->type = builtin_type (gdbarch)->builtin_data_capability;
+ else
+ {
+ warning (_("Register \"%s\" has an unsupported size (%d bits)"),
+ reg->name.c_str (), reg->bitsize);
+ arch_reg->type = builtin_type (gdbarch)->builtin_data_ptr;
+ }
+ }
+ else
+ arch_reg->type = make_gdb_type (gdbarch, reg->tdesc_type);
+ }
/* Next try size-sensitive type shortcuts. */
else if (reg->type == "float")