From 4695a547e1f2f7b25598a43544707a3f7651ec9d Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Tue, 15 Nov 2022 17:35:09 -0800 Subject: [PATCH] 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. --- gdb/target-descriptions.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/gdb/target-descriptions.c b/gdb/target-descriptions.c index 5b886f49872..a00300995b7 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") -- 2.47.2