diff options
author | John Baldwin <jhb@FreeBSD.org> | 2022-11-15 17:35:09 -0800 |
---|---|---|
committer | John Baldwin <jhb@FreeBSD.org> | 2022-11-15 17:40:27 -0800 |
commit | 4695a547e1f2f7b25598a43544707a3f7651ec9d (patch) | |
tree | 7a2451613e6a0e438fa18ccb6586a8ff1f955a31 | |
parent | ddd1b56a1dcec42f549b140dfeee394c93599072 (diff) | |
download | fsf-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.c | 19 |
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") |