1*5796c8dcSSimon Schubert /* Native-dependent code for modern i386 BSD's. 2*5796c8dcSSimon Schubert 3*5796c8dcSSimon Schubert Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009 4*5796c8dcSSimon Schubert Free Software Foundation, Inc. 5*5796c8dcSSimon Schubert 6*5796c8dcSSimon Schubert This file is part of GDB. 7*5796c8dcSSimon Schubert 8*5796c8dcSSimon Schubert This program is free software; you can redistribute it and/or modify 9*5796c8dcSSimon Schubert it under the terms of the GNU General Public License as published by 10*5796c8dcSSimon Schubert the Free Software Foundation; either version 3 of the License, or 11*5796c8dcSSimon Schubert (at your option) any later version. 12*5796c8dcSSimon Schubert 13*5796c8dcSSimon Schubert This program is distributed in the hope that it will be useful, 14*5796c8dcSSimon Schubert but WITHOUT ANY WARRANTY; without even the implied warranty of 15*5796c8dcSSimon Schubert MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16*5796c8dcSSimon Schubert GNU General Public License for more details. 17*5796c8dcSSimon Schubert 18*5796c8dcSSimon Schubert You should have received a copy of the GNU General Public License 19*5796c8dcSSimon Schubert along with this program. If not, see <http://www.gnu.org/licenses/>. */ 20*5796c8dcSSimon Schubert 21*5796c8dcSSimon Schubert #include "defs.h" 22*5796c8dcSSimon Schubert #include "inferior.h" 23*5796c8dcSSimon Schubert #include "regcache.h" 24*5796c8dcSSimon Schubert 25*5796c8dcSSimon Schubert #include "gdb_assert.h" 26*5796c8dcSSimon Schubert #include <signal.h> 27*5796c8dcSSimon Schubert #include <stddef.h> 28*5796c8dcSSimon Schubert #include <sys/types.h> 29*5796c8dcSSimon Schubert #include <sys/ptrace.h> 30*5796c8dcSSimon Schubert #include <machine/reg.h> 31*5796c8dcSSimon Schubert #include <machine/frame.h> 32*5796c8dcSSimon Schubert 33*5796c8dcSSimon Schubert #include "i386-tdep.h" 34*5796c8dcSSimon Schubert #include "i387-tdep.h" 35*5796c8dcSSimon Schubert #include "i386bsd-nat.h" 36*5796c8dcSSimon Schubert #include "inf-ptrace.h" 37*5796c8dcSSimon Schubert 38*5796c8dcSSimon Schubert 39*5796c8dcSSimon Schubert /* In older BSD versions we cannot get at some of the segment 40*5796c8dcSSimon Schubert registers. FreeBSD for example didn't support the %fs and %gs 41*5796c8dcSSimon Schubert registers until the 3.0 release. We have autoconf checks for their 42*5796c8dcSSimon Schubert presence, and deal gracefully with their absence. */ 43*5796c8dcSSimon Schubert 44*5796c8dcSSimon Schubert /* Offset in `struct reg' where MEMBER is stored. */ 45*5796c8dcSSimon Schubert #define REG_OFFSET(member) offsetof (struct reg, member) 46*5796c8dcSSimon Schubert 47*5796c8dcSSimon Schubert /* At i386bsd_reg_offset[REGNUM] you'll find the offset in `struct 48*5796c8dcSSimon Schubert reg' where the GDB register REGNUM is stored. Unsupported 49*5796c8dcSSimon Schubert registers are marked with `-1'. */ 50*5796c8dcSSimon Schubert static int i386bsd_r_reg_offset[] = 51*5796c8dcSSimon Schubert { 52*5796c8dcSSimon Schubert REG_OFFSET (r_eax), 53*5796c8dcSSimon Schubert REG_OFFSET (r_ecx), 54*5796c8dcSSimon Schubert REG_OFFSET (r_edx), 55*5796c8dcSSimon Schubert REG_OFFSET (r_ebx), 56*5796c8dcSSimon Schubert REG_OFFSET (r_esp), 57*5796c8dcSSimon Schubert REG_OFFSET (r_ebp), 58*5796c8dcSSimon Schubert REG_OFFSET (r_esi), 59*5796c8dcSSimon Schubert REG_OFFSET (r_edi), 60*5796c8dcSSimon Schubert REG_OFFSET (r_eip), 61*5796c8dcSSimon Schubert REG_OFFSET (r_eflags), 62*5796c8dcSSimon Schubert REG_OFFSET (r_cs), 63*5796c8dcSSimon Schubert REG_OFFSET (r_ss), 64*5796c8dcSSimon Schubert REG_OFFSET (r_ds), 65*5796c8dcSSimon Schubert REG_OFFSET (r_es), 66*5796c8dcSSimon Schubert #ifdef HAVE_STRUCT_REG_R_FS 67*5796c8dcSSimon Schubert REG_OFFSET (r_fs), 68*5796c8dcSSimon Schubert #else 69*5796c8dcSSimon Schubert -1, 70*5796c8dcSSimon Schubert #endif 71*5796c8dcSSimon Schubert #ifdef HAVE_STRUCT_REG_R_GS 72*5796c8dcSSimon Schubert REG_OFFSET (r_gs) 73*5796c8dcSSimon Schubert #else 74*5796c8dcSSimon Schubert -1 75*5796c8dcSSimon Schubert #endif 76*5796c8dcSSimon Schubert }; 77*5796c8dcSSimon Schubert 78*5796c8dcSSimon Schubert /* Macro to determine if a register is fetched with PT_GETREGS. */ 79*5796c8dcSSimon Schubert #define GETREGS_SUPPLIES(regnum) \ 80*5796c8dcSSimon Schubert ((0 <= (regnum) && (regnum) <= 15)) 81*5796c8dcSSimon Schubert 82*5796c8dcSSimon Schubert #ifdef HAVE_PT_GETXMMREGS 83*5796c8dcSSimon Schubert /* Set to 1 if the kernel supports PT_GETXMMREGS. Initialized to -1 84*5796c8dcSSimon Schubert so that we try PT_GETXMMREGS the first time around. */ 85*5796c8dcSSimon Schubert static int have_ptrace_xmmregs = -1; 86*5796c8dcSSimon Schubert #endif 87*5796c8dcSSimon Schubert 88*5796c8dcSSimon Schubert 89*5796c8dcSSimon Schubert /* Supply the general-purpose registers in GREGS, to REGCACHE. */ 90*5796c8dcSSimon Schubert 91*5796c8dcSSimon Schubert static void 92*5796c8dcSSimon Schubert i386bsd_supply_gregset (struct regcache *regcache, const void *gregs) 93*5796c8dcSSimon Schubert { 94*5796c8dcSSimon Schubert const char *regs = gregs; 95*5796c8dcSSimon Schubert int regnum; 96*5796c8dcSSimon Schubert 97*5796c8dcSSimon Schubert for (regnum = 0; regnum < ARRAY_SIZE (i386bsd_r_reg_offset); regnum++) 98*5796c8dcSSimon Schubert { 99*5796c8dcSSimon Schubert int offset = i386bsd_r_reg_offset[regnum]; 100*5796c8dcSSimon Schubert 101*5796c8dcSSimon Schubert if (offset != -1) 102*5796c8dcSSimon Schubert regcache_raw_supply (regcache, regnum, regs + offset); 103*5796c8dcSSimon Schubert } 104*5796c8dcSSimon Schubert } 105*5796c8dcSSimon Schubert 106*5796c8dcSSimon Schubert /* Collect register REGNUM from REGCACHE and store its contents in 107*5796c8dcSSimon Schubert GREGS. If REGNUM is -1, collect and store all appropriate 108*5796c8dcSSimon Schubert registers. */ 109*5796c8dcSSimon Schubert 110*5796c8dcSSimon Schubert static void 111*5796c8dcSSimon Schubert i386bsd_collect_gregset (const struct regcache *regcache, 112*5796c8dcSSimon Schubert void *gregs, int regnum) 113*5796c8dcSSimon Schubert { 114*5796c8dcSSimon Schubert char *regs = gregs; 115*5796c8dcSSimon Schubert int i; 116*5796c8dcSSimon Schubert 117*5796c8dcSSimon Schubert for (i = 0; i < ARRAY_SIZE (i386bsd_r_reg_offset); i++) 118*5796c8dcSSimon Schubert { 119*5796c8dcSSimon Schubert if (regnum == -1 || regnum == i) 120*5796c8dcSSimon Schubert { 121*5796c8dcSSimon Schubert int offset = i386bsd_r_reg_offset[i]; 122*5796c8dcSSimon Schubert 123*5796c8dcSSimon Schubert if (offset != -1) 124*5796c8dcSSimon Schubert regcache_raw_collect (regcache, i, regs + offset); 125*5796c8dcSSimon Schubert } 126*5796c8dcSSimon Schubert } 127*5796c8dcSSimon Schubert } 128*5796c8dcSSimon Schubert 129*5796c8dcSSimon Schubert /* Fetch register REGNUM from the inferior. If REGNUM is -1, do this 130*5796c8dcSSimon Schubert for all registers (including the floating point registers). */ 131*5796c8dcSSimon Schubert 132*5796c8dcSSimon Schubert static void 133*5796c8dcSSimon Schubert i386bsd_fetch_inferior_registers (struct target_ops *ops, 134*5796c8dcSSimon Schubert struct regcache *regcache, int regnum) 135*5796c8dcSSimon Schubert { 136*5796c8dcSSimon Schubert if (regnum == -1 || GETREGS_SUPPLIES (regnum)) 137*5796c8dcSSimon Schubert { 138*5796c8dcSSimon Schubert struct reg regs; 139*5796c8dcSSimon Schubert 140*5796c8dcSSimon Schubert if (ptrace (PT_GETREGS, PIDGET (inferior_ptid), 141*5796c8dcSSimon Schubert (PTRACE_TYPE_ARG3) ®s, 0) == -1) 142*5796c8dcSSimon Schubert perror_with_name (_("Couldn't get registers")); 143*5796c8dcSSimon Schubert 144*5796c8dcSSimon Schubert i386bsd_supply_gregset (regcache, ®s); 145*5796c8dcSSimon Schubert if (regnum != -1) 146*5796c8dcSSimon Schubert return; 147*5796c8dcSSimon Schubert } 148*5796c8dcSSimon Schubert 149*5796c8dcSSimon Schubert if (regnum == -1 || regnum >= I386_ST0_REGNUM) 150*5796c8dcSSimon Schubert { 151*5796c8dcSSimon Schubert struct fpreg fpregs; 152*5796c8dcSSimon Schubert #ifdef HAVE_PT_GETXMMREGS 153*5796c8dcSSimon Schubert char xmmregs[512]; 154*5796c8dcSSimon Schubert 155*5796c8dcSSimon Schubert if (have_ptrace_xmmregs != 0 156*5796c8dcSSimon Schubert && ptrace(PT_GETXMMREGS, PIDGET (inferior_ptid), 157*5796c8dcSSimon Schubert (PTRACE_TYPE_ARG3) xmmregs, 0) == 0) 158*5796c8dcSSimon Schubert { 159*5796c8dcSSimon Schubert have_ptrace_xmmregs = 1; 160*5796c8dcSSimon Schubert i387_supply_fxsave (regcache, -1, xmmregs); 161*5796c8dcSSimon Schubert } 162*5796c8dcSSimon Schubert else 163*5796c8dcSSimon Schubert { 164*5796c8dcSSimon Schubert if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), 165*5796c8dcSSimon Schubert (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) 166*5796c8dcSSimon Schubert perror_with_name (_("Couldn't get floating point status")); 167*5796c8dcSSimon Schubert 168*5796c8dcSSimon Schubert i387_supply_fsave (regcache, -1, &fpregs); 169*5796c8dcSSimon Schubert } 170*5796c8dcSSimon Schubert #else 171*5796c8dcSSimon Schubert if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), 172*5796c8dcSSimon Schubert (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) 173*5796c8dcSSimon Schubert perror_with_name (_("Couldn't get floating point status")); 174*5796c8dcSSimon Schubert 175*5796c8dcSSimon Schubert i387_supply_fsave (regcache, -1, &fpregs); 176*5796c8dcSSimon Schubert #endif 177*5796c8dcSSimon Schubert } 178*5796c8dcSSimon Schubert } 179*5796c8dcSSimon Schubert 180*5796c8dcSSimon Schubert /* Store register REGNUM back into the inferior. If REGNUM is -1, do 181*5796c8dcSSimon Schubert this for all registers (including the floating point registers). */ 182*5796c8dcSSimon Schubert 183*5796c8dcSSimon Schubert static void 184*5796c8dcSSimon Schubert i386bsd_store_inferior_registers (struct target_ops *ops, 185*5796c8dcSSimon Schubert struct regcache *regcache, int regnum) 186*5796c8dcSSimon Schubert { 187*5796c8dcSSimon Schubert if (regnum == -1 || GETREGS_SUPPLIES (regnum)) 188*5796c8dcSSimon Schubert { 189*5796c8dcSSimon Schubert struct reg regs; 190*5796c8dcSSimon Schubert 191*5796c8dcSSimon Schubert if (ptrace (PT_GETREGS, PIDGET (inferior_ptid), 192*5796c8dcSSimon Schubert (PTRACE_TYPE_ARG3) ®s, 0) == -1) 193*5796c8dcSSimon Schubert perror_with_name (_("Couldn't get registers")); 194*5796c8dcSSimon Schubert 195*5796c8dcSSimon Schubert i386bsd_collect_gregset (regcache, ®s, regnum); 196*5796c8dcSSimon Schubert 197*5796c8dcSSimon Schubert if (ptrace (PT_SETREGS, PIDGET (inferior_ptid), 198*5796c8dcSSimon Schubert (PTRACE_TYPE_ARG3) ®s, 0) == -1) 199*5796c8dcSSimon Schubert perror_with_name (_("Couldn't write registers")); 200*5796c8dcSSimon Schubert 201*5796c8dcSSimon Schubert if (regnum != -1) 202*5796c8dcSSimon Schubert return; 203*5796c8dcSSimon Schubert } 204*5796c8dcSSimon Schubert 205*5796c8dcSSimon Schubert if (regnum == -1 || regnum >= I386_ST0_REGNUM) 206*5796c8dcSSimon Schubert { 207*5796c8dcSSimon Schubert struct fpreg fpregs; 208*5796c8dcSSimon Schubert #ifdef HAVE_PT_GETXMMREGS 209*5796c8dcSSimon Schubert char xmmregs[512]; 210*5796c8dcSSimon Schubert 211*5796c8dcSSimon Schubert if (have_ptrace_xmmregs != 0 212*5796c8dcSSimon Schubert && ptrace(PT_GETXMMREGS, PIDGET (inferior_ptid), 213*5796c8dcSSimon Schubert (PTRACE_TYPE_ARG3) xmmregs, 0) == 0) 214*5796c8dcSSimon Schubert { 215*5796c8dcSSimon Schubert have_ptrace_xmmregs = 1; 216*5796c8dcSSimon Schubert 217*5796c8dcSSimon Schubert i387_collect_fxsave (regcache, regnum, xmmregs); 218*5796c8dcSSimon Schubert 219*5796c8dcSSimon Schubert if (ptrace (PT_SETXMMREGS, PIDGET (inferior_ptid), 220*5796c8dcSSimon Schubert (PTRACE_TYPE_ARG3) xmmregs, 0) == -1) 221*5796c8dcSSimon Schubert perror_with_name (_("Couldn't write XMM registers")); 222*5796c8dcSSimon Schubert } 223*5796c8dcSSimon Schubert else 224*5796c8dcSSimon Schubert { 225*5796c8dcSSimon Schubert have_ptrace_xmmregs = 0; 226*5796c8dcSSimon Schubert #endif 227*5796c8dcSSimon Schubert if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), 228*5796c8dcSSimon Schubert (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) 229*5796c8dcSSimon Schubert perror_with_name (_("Couldn't get floating point status")); 230*5796c8dcSSimon Schubert 231*5796c8dcSSimon Schubert i387_collect_fsave (regcache, regnum, &fpregs); 232*5796c8dcSSimon Schubert 233*5796c8dcSSimon Schubert if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid), 234*5796c8dcSSimon Schubert (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) 235*5796c8dcSSimon Schubert perror_with_name (_("Couldn't write floating point status")); 236*5796c8dcSSimon Schubert #ifdef HAVE_PT_GETXMMREGS 237*5796c8dcSSimon Schubert } 238*5796c8dcSSimon Schubert #endif 239*5796c8dcSSimon Schubert } 240*5796c8dcSSimon Schubert } 241*5796c8dcSSimon Schubert 242*5796c8dcSSimon Schubert /* Create a prototype *BSD/i386 target. The client can override it 243*5796c8dcSSimon Schubert with local methods. */ 244*5796c8dcSSimon Schubert 245*5796c8dcSSimon Schubert struct target_ops * 246*5796c8dcSSimon Schubert i386bsd_target (void) 247*5796c8dcSSimon Schubert { 248*5796c8dcSSimon Schubert struct target_ops *t; 249*5796c8dcSSimon Schubert 250*5796c8dcSSimon Schubert t = inf_ptrace_target (); 251*5796c8dcSSimon Schubert t->to_fetch_registers = i386bsd_fetch_inferior_registers; 252*5796c8dcSSimon Schubert t->to_store_registers = i386bsd_store_inferior_registers; 253*5796c8dcSSimon Schubert return t; 254*5796c8dcSSimon Schubert } 255*5796c8dcSSimon Schubert 256*5796c8dcSSimon Schubert 257*5796c8dcSSimon Schubert /* Support for debug registers. */ 258*5796c8dcSSimon Schubert 259*5796c8dcSSimon Schubert #ifdef HAVE_PT_GETDBREGS 260*5796c8dcSSimon Schubert 261*5796c8dcSSimon Schubert /* Not all versions of FreeBSD/i386 that support the debug registers 262*5796c8dcSSimon Schubert have this macro. */ 263*5796c8dcSSimon Schubert #ifndef DBREG_DRX 264*5796c8dcSSimon Schubert #define DBREG_DRX(d, x) ((&d->dr0)[x]) 265*5796c8dcSSimon Schubert #endif 266*5796c8dcSSimon Schubert 267*5796c8dcSSimon Schubert static void 268*5796c8dcSSimon Schubert i386bsd_dr_set (int regnum, unsigned int value) 269*5796c8dcSSimon Schubert { 270*5796c8dcSSimon Schubert struct dbreg dbregs; 271*5796c8dcSSimon Schubert 272*5796c8dcSSimon Schubert if (ptrace (PT_GETDBREGS, PIDGET (inferior_ptid), 273*5796c8dcSSimon Schubert (PTRACE_TYPE_ARG3) &dbregs, 0) == -1) 274*5796c8dcSSimon Schubert perror_with_name (_("Couldn't get debug registers")); 275*5796c8dcSSimon Schubert 276*5796c8dcSSimon Schubert /* For some mysterious reason, some of the reserved bits in the 277*5796c8dcSSimon Schubert debug control register get set. Mask these off, otherwise the 278*5796c8dcSSimon Schubert ptrace call below will fail. */ 279*5796c8dcSSimon Schubert DBREG_DRX ((&dbregs), 7) &= ~(0x0000fc00); 280*5796c8dcSSimon Schubert 281*5796c8dcSSimon Schubert DBREG_DRX ((&dbregs), regnum) = value; 282*5796c8dcSSimon Schubert 283*5796c8dcSSimon Schubert if (ptrace (PT_SETDBREGS, PIDGET (inferior_ptid), 284*5796c8dcSSimon Schubert (PTRACE_TYPE_ARG3) &dbregs, 0) == -1) 285*5796c8dcSSimon Schubert perror_with_name (_("Couldn't write debug registers")); 286*5796c8dcSSimon Schubert } 287*5796c8dcSSimon Schubert 288*5796c8dcSSimon Schubert void 289*5796c8dcSSimon Schubert i386bsd_dr_set_control (unsigned long control) 290*5796c8dcSSimon Schubert { 291*5796c8dcSSimon Schubert i386bsd_dr_set (7, control); 292*5796c8dcSSimon Schubert } 293*5796c8dcSSimon Schubert 294*5796c8dcSSimon Schubert void 295*5796c8dcSSimon Schubert i386bsd_dr_set_addr (int regnum, CORE_ADDR addr) 296*5796c8dcSSimon Schubert { 297*5796c8dcSSimon Schubert gdb_assert (regnum >= 0 && regnum <= 4); 298*5796c8dcSSimon Schubert 299*5796c8dcSSimon Schubert i386bsd_dr_set (regnum, addr); 300*5796c8dcSSimon Schubert } 301*5796c8dcSSimon Schubert 302*5796c8dcSSimon Schubert void 303*5796c8dcSSimon Schubert i386bsd_dr_reset_addr (int regnum) 304*5796c8dcSSimon Schubert { 305*5796c8dcSSimon Schubert gdb_assert (regnum >= 0 && regnum <= 4); 306*5796c8dcSSimon Schubert 307*5796c8dcSSimon Schubert i386bsd_dr_set (regnum, 0); 308*5796c8dcSSimon Schubert } 309*5796c8dcSSimon Schubert 310*5796c8dcSSimon Schubert unsigned long 311*5796c8dcSSimon Schubert i386bsd_dr_get_status (void) 312*5796c8dcSSimon Schubert { 313*5796c8dcSSimon Schubert struct dbreg dbregs; 314*5796c8dcSSimon Schubert 315*5796c8dcSSimon Schubert /* FIXME: kettenis/2001-03-31: Calling perror_with_name if the 316*5796c8dcSSimon Schubert ptrace call fails breaks debugging remote targets. The correct 317*5796c8dcSSimon Schubert way to fix this is to add the hardware breakpoint and watchpoint 318*5796c8dcSSimon Schubert stuff to the target vector. For now, just return zero if the 319*5796c8dcSSimon Schubert ptrace call fails. */ 320*5796c8dcSSimon Schubert if (ptrace (PT_GETDBREGS, PIDGET (inferior_ptid), 321*5796c8dcSSimon Schubert (PTRACE_TYPE_ARG3) &dbregs, 0) == -1) 322*5796c8dcSSimon Schubert #if 0 323*5796c8dcSSimon Schubert perror_with_name (_("Couldn't read debug registers")); 324*5796c8dcSSimon Schubert #else 325*5796c8dcSSimon Schubert return 0; 326*5796c8dcSSimon Schubert #endif 327*5796c8dcSSimon Schubert 328*5796c8dcSSimon Schubert return DBREG_DRX ((&dbregs), 6); 329*5796c8dcSSimon Schubert } 330*5796c8dcSSimon Schubert 331*5796c8dcSSimon Schubert #endif /* PT_GETDBREGS */ 332*5796c8dcSSimon Schubert 333*5796c8dcSSimon Schubert 334*5796c8dcSSimon Schubert void 335*5796c8dcSSimon Schubert _initialize_i386bsd_nat (void) 336*5796c8dcSSimon Schubert { 337*5796c8dcSSimon Schubert int offset; 338*5796c8dcSSimon Schubert 339*5796c8dcSSimon Schubert /* To support the recognition of signal handlers, i386bsd-tdep.c 340*5796c8dcSSimon Schubert hardcodes some constants. Inclusion of this file means that we 341*5796c8dcSSimon Schubert are compiling a native debugger, which means that we can use the 342*5796c8dcSSimon Schubert system header files and sysctl(3) to get at the relevant 343*5796c8dcSSimon Schubert information. */ 344*5796c8dcSSimon Schubert 345*5796c8dcSSimon Schubert #if defined (__FreeBSD_version) && __FreeBSD_version >= 400011 346*5796c8dcSSimon Schubert #define SC_REG_OFFSET i386fbsd4_sc_reg_offset 347*5796c8dcSSimon Schubert #elif defined (__FreeBSD_version) && __FreeBSD_version >= 300005 348*5796c8dcSSimon Schubert #define SC_REG_OFFSET i386fbsd_sc_reg_offset 349*5796c8dcSSimon Schubert #elif defined (NetBSD) || defined (__NetBSD_Version__) 350*5796c8dcSSimon Schubert #define SC_REG_OFFSET i386nbsd_sc_reg_offset 351*5796c8dcSSimon Schubert #elif defined (OpenBSD) 352*5796c8dcSSimon Schubert #define SC_REG_OFFSET i386obsd_sc_reg_offset 353*5796c8dcSSimon Schubert #endif 354*5796c8dcSSimon Schubert 355*5796c8dcSSimon Schubert #ifdef SC_REG_OFFSET 356*5796c8dcSSimon Schubert 357*5796c8dcSSimon Schubert /* We only check the program counter, stack pointer and frame 358*5796c8dcSSimon Schubert pointer since these members of `struct sigcontext' are essential 359*5796c8dcSSimon Schubert for providing backtraces. More checks could be added, but would 360*5796c8dcSSimon Schubert involve adding configure checks for the appropriate structure 361*5796c8dcSSimon Schubert members, since older BSD's don't provide all of them. */ 362*5796c8dcSSimon Schubert 363*5796c8dcSSimon Schubert #define SC_PC_OFFSET SC_REG_OFFSET[I386_EIP_REGNUM] 364*5796c8dcSSimon Schubert #define SC_SP_OFFSET SC_REG_OFFSET[I386_ESP_REGNUM] 365*5796c8dcSSimon Schubert #define SC_FP_OFFSET SC_REG_OFFSET[I386_EBP_REGNUM] 366*5796c8dcSSimon Schubert 367*5796c8dcSSimon Schubert /* Override the default value for the offset of the program counter 368*5796c8dcSSimon Schubert in the sigcontext structure. */ 369*5796c8dcSSimon Schubert offset = offsetof (struct sigcontext, sc_pc); 370*5796c8dcSSimon Schubert 371*5796c8dcSSimon Schubert if (SC_PC_OFFSET != offset) 372*5796c8dcSSimon Schubert { 373*5796c8dcSSimon Schubert warning (_("\ 374*5796c8dcSSimon Schubert offsetof (struct sigcontext, sc_pc) yields %d instead of %d.\n\ 375*5796c8dcSSimon Schubert Please report this to <bug-gdb@gnu.org>."), 376*5796c8dcSSimon Schubert offset, SC_PC_OFFSET); 377*5796c8dcSSimon Schubert } 378*5796c8dcSSimon Schubert 379*5796c8dcSSimon Schubert SC_PC_OFFSET = offset; 380*5796c8dcSSimon Schubert 381*5796c8dcSSimon Schubert /* Likewise for the stack pointer. */ 382*5796c8dcSSimon Schubert offset = offsetof (struct sigcontext, sc_sp); 383*5796c8dcSSimon Schubert 384*5796c8dcSSimon Schubert if (SC_SP_OFFSET != offset) 385*5796c8dcSSimon Schubert { 386*5796c8dcSSimon Schubert warning (_("\ 387*5796c8dcSSimon Schubert offsetof (struct sigcontext, sc_sp) yields %d instead of %d.\n\ 388*5796c8dcSSimon Schubert Please report this to <bug-gdb@gnu.org>."), 389*5796c8dcSSimon Schubert offset, SC_SP_OFFSET); 390*5796c8dcSSimon Schubert } 391*5796c8dcSSimon Schubert 392*5796c8dcSSimon Schubert SC_SP_OFFSET = offset; 393*5796c8dcSSimon Schubert 394*5796c8dcSSimon Schubert /* And the frame pointer. */ 395*5796c8dcSSimon Schubert offset = offsetof (struct sigcontext, sc_fp); 396*5796c8dcSSimon Schubert 397*5796c8dcSSimon Schubert if (SC_FP_OFFSET != offset) 398*5796c8dcSSimon Schubert { 399*5796c8dcSSimon Schubert warning (_("\ 400*5796c8dcSSimon Schubert offsetof (struct sigcontext, sc_fp) yields %d instead of %d.\n\ 401*5796c8dcSSimon Schubert Please report this to <bug-gdb@gnu.org>."), 402*5796c8dcSSimon Schubert offset, SC_FP_OFFSET); 403*5796c8dcSSimon Schubert } 404*5796c8dcSSimon Schubert 405*5796c8dcSSimon Schubert SC_FP_OFFSET = offset; 406*5796c8dcSSimon Schubert 407*5796c8dcSSimon Schubert #endif /* SC_REG_OFFSET */ 408*5796c8dcSSimon Schubert } 409