From: Sébastien Michelland Date: Mon, 1 Apr 2024 09:55:53 +0000 (+0200) Subject: gdb: specify sh pointer register types X-Git-Tag: gdb-15-branchpoint~244 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=afdd600c0982f0ce95439f2936c6d6d6d0201f77;p=thirdparty%2Fbinutils-gdb.git gdb: specify sh pointer register types This patch fixes a pretty funny issue on sh targets that occurred because $pc (and similar registers) were typed as int. When $pc is in the upper half of the address space (i.e. kernel code on sh), `x/i $pc' would resolve to a negative value. At least in the case of a remote target with an Xfer memory map, this leads to a spurious "cannot access memory" error as negative addresses are out of bounds. (gdb) x/i $pc 0x8c202c04: Cannot access memory at address 0x8c202c04 (gdb) x/i 0x8c202c04 => 0x8c202c04 : mov.l @r1,r10 The issue is fixed by specifying pointer types for pc and other pointer registers. Code pointer registers on sh include pc, pr (return address of a call), vbr (interrupt handler) and spc (return address after interrupt). Data pointers include r15 (stack pointer) and gbr (base register for a few specific addressing modes). Change-Id: I043a058f7cbc6494f380dc0461616a9f3e0d87e0 Approved-By: Simon Marchi --- diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c index 0a3b50702d9..0dbb905f1db 100644 --- a/gdb/sh-tdep.c +++ b/gdb/sh-tdep.c @@ -1401,6 +1401,11 @@ sh_sh2a_register_type (struct gdbarch *gdbarch, int reg_nr) return builtin_type (gdbarch)->builtin_float; else if (reg_nr >= DR0_REGNUM && reg_nr <= DR_LAST_REGNUM) return builtin_type (gdbarch)->builtin_double; + else if (reg_nr == PC_REGNUM || reg_nr == PR_REGNUM || reg_nr == VBR_REGNUM + || reg_nr == SPC_REGNUM) + return builtin_type (gdbarch)->builtin_func_ptr; + else if (reg_nr == R0_REGNUM + 15 || reg_nr == GBR_REGNUM) + return builtin_type (gdbarch)->builtin_data_ptr; else return builtin_type (gdbarch)->builtin_int; } @@ -1413,6 +1418,11 @@ sh_sh3e_register_type (struct gdbarch *gdbarch, int reg_nr) if ((reg_nr >= gdbarch_fp0_regnum (gdbarch) && (reg_nr <= FP_LAST_REGNUM)) || (reg_nr == FPUL_REGNUM)) return builtin_type (gdbarch)->builtin_float; + else if (reg_nr == PC_REGNUM || reg_nr == PR_REGNUM || reg_nr == VBR_REGNUM + || reg_nr == SPC_REGNUM) + return builtin_type (gdbarch)->builtin_func_ptr; + else if (reg_nr == R0_REGNUM + 15 || reg_nr == GBR_REGNUM) + return builtin_type (gdbarch)->builtin_data_ptr; else return builtin_type (gdbarch)->builtin_int; } @@ -1434,6 +1444,11 @@ sh_sh4_register_type (struct gdbarch *gdbarch, int reg_nr) return builtin_type (gdbarch)->builtin_double; else if (reg_nr >= FV0_REGNUM && reg_nr <= FV_LAST_REGNUM) return sh_sh4_build_float_register_type (gdbarch, 3); + else if (reg_nr == PC_REGNUM || reg_nr == PR_REGNUM || reg_nr == VBR_REGNUM + || reg_nr == SPC_REGNUM) + return builtin_type (gdbarch)->builtin_func_ptr; + else if (reg_nr == R0_REGNUM + 15 || reg_nr == GBR_REGNUM) + return builtin_type (gdbarch)->builtin_data_ptr; else return builtin_type (gdbarch)->builtin_int; } @@ -1441,7 +1456,13 @@ sh_sh4_register_type (struct gdbarch *gdbarch, int reg_nr) static struct type * sh_default_register_type (struct gdbarch *gdbarch, int reg_nr) { - return builtin_type (gdbarch)->builtin_int; + if (reg_nr == PC_REGNUM || reg_nr == PR_REGNUM || reg_nr == VBR_REGNUM + || reg_nr == SPC_REGNUM) + return builtin_type (gdbarch)->builtin_func_ptr; + else if (reg_nr == R0_REGNUM + 15 || reg_nr == GBR_REGNUM) + return builtin_type (gdbarch)->builtin_data_ptr; + else + return builtin_type (gdbarch)->builtin_int; } /* Is a register in a reggroup?