fbsd-i386-low.c revision 157574
155714Skris/* GNU/Linux/i386 specific low level interface, for the remote server for GDB. 255714Skris Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002 355714Skris Free Software Foundation, Inc. 455714Skris 555714Skris This file is part of GDB. 655714Skris 755714Skris This program is free software; you can redistribute it and/or modify 855714Skris it under the terms of the GNU General Public License as published by 955714Skris the Free Software Foundation; either version 2 of the License, or 1055714Skris (at your option) any later version. 1155714Skris 1255714Skris This program is distributed in the hope that it will be useful, 1368651Skris but WITHOUT ANY WARRANTY; without even the implied warranty of 1455714Skris MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1555714Skris GNU General Public License for more details. 1655714Skris 1755714Skris You should have received a copy of the GNU General Public License 18238405Sjkim along with this program; if not, write to the Free Software 1955714Skris Foundation, Inc., 59 Temple Place - Suite 330, 2055714Skris Boston, MA 02111-1307, USA. */ 2155714Skris 2255714Skris#include <sys/cdefs.h> 2355714Skris__FBSDID("$FreeBSD: head/gnu/usr.bin/gdb/gdbserver/fbsd-i386-low.c 157574 2006-04-06 22:24:01Z jmg $"); 2455714Skris 2555714Skris#include "server.h" 2655714Skris#include "fbsd-low.h" 27109998Smarkm#include "i387-fp.h" 28162911Ssimon 29194206Ssimon#ifdef HAVE_SYS_REG_H 30238405Sjkim#include <sys/reg.h> 3155714Skris#else 3255714Skris#include <machine/reg.h> 3355714Skris#endif 3468651Skris 3555714Skris/* This module only supports access to the general purpose registers. */ 36109998Smarkm 37160814Ssimon#define i386_num_regs 16 38160814Ssimon 3955714Skris/* This stuff comes from i386-fbsd-nat.c. */ 4055714Skris 4155714Skris/* Mapping between the general-purpose registers in `struct user' 4255714Skris format and GDB's register array layout. */ 4355714Skrisstatic int i386_regmap[] = 4455714Skris{ 4555714Skris tEAX * 4, tECX * 4, tEDX * 4, tEBX * 4, 4655714Skris tESP * 4, tEBP * 4, tESI * 4, tEDI * 4, 4755714Skris tEIP * 4, tEFLAGS * 4, tCS * 4, tSS * 4, 4855714Skris tDS * 4, tES * 4, tFS * 4, tGS * 4 4955714Skris}; 5055714Skris 51238405Sjkimstatic int 5255714Skrisi386_cannot_store_register (int regno) 53194206Ssimon{ 5455714Skris return (regno >= i386_num_regs); 5555714Skris} 5655714Skris 5755714Skrisstatic int 58109998Smarkmi386_cannot_fetch_register (int regno) 59109998Smarkm{ 60109998Smarkm return (regno >= i386_num_regs); 61109998Smarkm} 62238405Sjkim 63160814Ssimon 64238405Sjkim#include <sys/procfs.h> 65238405Sjkim#include <sys/ptrace.h> 66238405Sjkim 6755714Skrisstatic void 6855714Skrisi386_fill_gregset (void *buf) 69160814Ssimon{ 70238405Sjkim int i; 7155714Skris 7255714Skris for (i = 0; i < i386_num_regs; i++) 7355714Skris collect_register (i, ((char *) buf) + i386_regmap[i]); 7455714Skris 75238405Sjkim} 76238405Sjkim 7755714Skrisstatic void 78142425Snectari386_store_gregset (const void *buf) 7955714Skris{ 8055714Skris int i; 8155714Skris 8255714Skris for (i = 0; i < i386_num_regs; i++) 8355714Skris supply_register (i, ((char *) buf) + i386_regmap[i]); 8455714Skris 8555714Skris} 8655714Skris 8755714Skrisstatic void 8855714Skrisi386_fill_fpregset (void *buf) 8955714Skris{ 9055714Skris i387_cache_to_fsave (buf); 9155714Skris} 9255714Skris 9355714Skrisstatic void 9455714Skrisi386_store_fpregset (const void *buf) 9555714Skris{ 9655714Skris i387_fsave_to_cache (buf); 9755714Skris} 9855714Skris 9955714Skrisstatic void 10055714Skrisi386_fill_fpxregset (void *buf) 10155714Skris{ 10255714Skris i387_cache_to_fxsave (buf); 10355714Skris} 10455714Skris 10555714Skrisstatic void 10655714Skrisi386_store_fpxregset (const void *buf) 10755714Skris{ 10855714Skris i387_fxsave_to_cache (buf); 10955714Skris} 11055714Skris 11155714Skris 11255714Skrisstruct regset_info target_regsets[] = { 11355714Skris { PT_GETREGS, PT_SETREGS, sizeof (struct reg), 11455714Skris GENERAL_REGS, 11555714Skris i386_fill_gregset, i386_store_gregset }, 11655714Skris#ifdef HAVE_PTRACE_GETFPXREGS 11755714Skris { PTRACE_GETFPXREGS, PTRACE_SETFPXREGS, sizeof (elf_fpxregset_t), 11855714Skris EXTENDED_REGS, 11955714Skris i386_fill_fpxregset, i386_store_fpxregset }, 120238405Sjkim#endif 121238405Sjkim { PT_GETFPREGS, PT_SETFPREGS, sizeof (struct fpreg), 12255714Skris FP_REGS, 12355714Skris i386_fill_fpregset, i386_store_fpregset }, 12455714Skris { 0, 0, -1, -1, NULL, NULL } 12555714Skris}; 12655714Skris 12755714Skrisstatic const char i386_breakpoint[] = { 0xCC }; 12855714Skris#define i386_breakpoint_len 1 12955714Skris 13055714Skrisextern int debug_threads; 131238405Sjkim 132238405Sjkimstatic CORE_ADDR 133238405Sjkimi386_get_pc () 134238405Sjkim{ 135238405Sjkim unsigned long pc; 136238405Sjkim 137238405Sjkim collect_register_by_name ("eip", &pc); 138238405Sjkim 139238405Sjkim if (debug_threads) 14055714Skris fprintf (stderr, "stop pc (before any decrement) is %08lx\n", pc); 14155714Skris return pc; 14255714Skris} 14355714Skris 144static void 145i386_set_pc (CORE_ADDR newpc) 146{ 147 if (debug_threads) 148 fprintf (stderr, "set pc to %08lx\n", (long) newpc); 149 supply_register_by_name ("eip", &newpc); 150} 151 152static int 153i386_breakpoint_at (CORE_ADDR pc) 154{ 155 unsigned char c; 156 157 read_inferior_memory (pc, &c, 1); 158 if (c == 0xCC) 159 return 1; 160 161 return 0; 162} 163 164struct fbsd_target_ops the_low_target = { 165 i386_num_regs, 166 i386_regmap, 167 i386_cannot_fetch_register, 168 i386_cannot_store_register, 169 i386_get_pc, 170 i386_set_pc, 171 i386_breakpoint, 172 i386_breakpoint_len, 173 NULL, 174 1, 175 i386_breakpoint_at, 176}; 177