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