fbsd-i386-low.c revision 157571
1139749Simp/* GNU/Linux/i386 specific low level interface, for the remote server for GDB. 226003Smsmith Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002 326003Smsmith Free Software Foundation, Inc. 426003Smsmith 526003Smsmith This file is part of GDB. 626003Smsmith 726003Smsmith This program is free software; you can redistribute it and/or modify 897748Sschweikh it under the terms of the GNU General Public License as published by 926003Smsmith the Free Software Foundation; either version 2 of the License, or 1026003Smsmith (at your option) any later version. 1126003Smsmith 1226003Smsmith This program is distributed in the hope that it will be useful, 1326003Smsmith but WITHOUT ANY WARRANTY; without even the implied warranty of 1426003Smsmith MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1526003Smsmith GNU General Public License for more details. 1626003Smsmith 1726003Smsmith You should have received a copy of the GNU General Public License 1826003Smsmith along with this program; if not, write to the Free Software 1926003Smsmith Foundation, Inc., 59 Temple Place - Suite 330, 2026003Smsmith Boston, MA 02111-1307, USA. */ 2126003Smsmith 2226003Smsmith#include "server.h" 2326003Smsmith#include "linux-low.h" 2426003Smsmith#include "i387-fp.h" 2526003Smsmith 2626003Smsmith#ifdef HAVE_SYS_REG_H 2726003Smsmith#include <sys/reg.h> 2826003Smsmith#endif 2926003Smsmith 3026003Smsmith/* This module only supports access to the general purpose registers. */ 3126003Smsmith 3226003Smsmith#define i386_num_regs 16 3326003Smsmith 3426003Smsmith/* This stuff comes from i386-linux-nat.c. */ 3526003Smsmith 3627817Smsmith/* Mapping between the general-purpose registers in `struct user' 3727817Smsmith format and GDB's register array layout. */ 3827817Smsmithstatic int i386_regmap[] = 3927817Smsmith{ 4027817Smsmith EAX * 4, ECX * 4, EDX * 4, EBX * 4, 4127817Smsmith UESP * 4, EBP * 4, ESI * 4, EDI * 4, 4226003Smsmith EIP * 4, EFL * 4, CS * 4, SS * 4, 4326003Smsmith DS * 4, ES * 4, FS * 4, GS * 4 4426003Smsmith}; 4526003Smsmith 4626003Smsmithstatic int 4726003Smsmithi386_cannot_store_register (int regno) 4826003Smsmith{ 4926003Smsmith return (regno >= i386_num_regs); 5026003Smsmith} 5126003Smsmith 5226003Smsmithstatic int 5326003Smsmithi386_cannot_fetch_register (int regno) 54108533Sschweikh{ 5526003Smsmith return (regno >= i386_num_regs); 5626003Smsmith} 5726003Smsmith 5826003Smsmith 5926003Smsmith#ifdef HAVE_LINUX_REGSETS 6026003Smsmith#include <sys/procfs.h> 6126003Smsmith#include <sys/ptrace.h> 6226003Smsmith 6326003Smsmithstatic void 6426003Smsmithi386_fill_gregset (void *buf) 6526003Smsmith{ 6626003Smsmith int i; 6726003Smsmith 6826003Smsmith for (i = 0; i < i386_num_regs; i++) 6926003Smsmith collect_register (i, ((char *) buf) + i386_regmap[i]); 7026003Smsmith 7126003Smsmith collect_register_by_name ("orig_eax", ((char *) buf) + ORIG_EAX * 4); 7226003Smsmith} 7326003Smsmith 7426003Smsmithstatic void 7526003Smsmithi386_store_gregset (const void *buf) 7626003Smsmith{ 7726003Smsmith int i; 7826003Smsmith 7926003Smsmith for (i = 0; i < i386_num_regs; i++) 8026003Smsmith supply_register (i, ((char *) buf) + i386_regmap[i]); 8126003Smsmith 8226003Smsmith supply_register_by_name ("orig_eax", ((char *) buf) + ORIG_EAX * 4); 8340565Sbde} 8426003Smsmith 8526003Smsmithstatic void 8627817Smsmithi386_fill_fpregset (void *buf) 8727817Smsmith{ 8827817Smsmith i387_cache_to_fsave (buf); 8927817Smsmith} 9027817Smsmith 9127817Smsmithstatic void 9227817Smsmithi386_store_fpregset (const void *buf) 9327817Smsmith{ 9426003Smsmith i387_fsave_to_cache (buf); 9526003Smsmith} 9627817Smsmith 9726003Smsmithstatic void 9826003Smsmithi386_fill_fpxregset (void *buf) 9927817Smsmith{ 10027817Smsmith i387_cache_to_fxsave (buf); 10127817Smsmith} 10227817Smsmith 10327817Smsmithstatic void 10427817Smsmithi386_store_fpxregset (const void *buf) 10527817Smsmith{ 10627817Smsmith i387_fxsave_to_cache (buf); 10727817Smsmith} 10827817Smsmith 10927817Smsmith 11027817Smsmithstruct regset_info target_regsets[] = { 11127817Smsmith { PTRACE_GETREGS, PTRACE_SETREGS, sizeof (elf_gregset_t), 11227817Smsmith GENERAL_REGS, 11327817Smsmith i386_fill_gregset, i386_store_gregset }, 11427817Smsmith#ifdef HAVE_PTRACE_GETFPXREGS 11527817Smsmith { PTRACE_GETFPXREGS, PTRACE_SETFPXREGS, sizeof (elf_fpxregset_t), 11627817Smsmith EXTENDED_REGS, 11727817Smsmith i386_fill_fpxregset, i386_store_fpxregset }, 11827817Smsmith#endif 11927817Smsmith { PTRACE_GETFPREGS, PTRACE_SETFPREGS, sizeof (elf_fpregset_t), 12027817Smsmith FP_REGS, 12126003Smsmith i386_fill_fpregset, i386_store_fpregset }, 12226003Smsmith { 0, 0, -1, -1, NULL, NULL } 12326003Smsmith}; 12426003Smsmith 12526003Smsmith#endif /* HAVE_LINUX_REGSETS */ 12626003Smsmith 12726003Smsmithstatic const char i386_breakpoint[] = { 0xCC }; 12826003Smsmith#define i386_breakpoint_len 1 12926003Smsmith 13026003Smsmithextern int debug_threads; 13126003Smsmith 13226003Smsmithstatic CORE_ADDR 13326003Smsmithi386_get_pc () 13426003Smsmith{ 13526003Smsmith unsigned long pc; 13626003Smsmith 13726003Smsmith collect_register_by_name ("eip", &pc); 13826003Smsmith 13926003Smsmith if (debug_threads) 14026003Smsmith fprintf (stderr, "stop pc (before any decrement) is %08lx\n", pc); 14126003Smsmith return pc; 14226003Smsmith} 14326003Smsmith 14426003Smsmithstatic void 14526003Smsmithi386_set_pc (CORE_ADDR newpc) 14626003Smsmith{ 14726003Smsmith if (debug_threads) 14826003Smsmith fprintf (stderr, "set pc to %08lx\n", (long) newpc); 14926003Smsmith supply_register_by_name ("eip", &newpc); 15026003Smsmith} 15126003Smsmith 15226003Smsmithstatic int 15326003Smsmithi386_breakpoint_at (CORE_ADDR pc) 15426003Smsmith{ 15526003Smsmith unsigned char c; 15626003Smsmith 15726003Smsmith read_inferior_memory (pc, &c, 1); 15826003Smsmith if (c == 0xCC) 15926003Smsmith return 1; 16026003Smsmith 16126003Smsmith return 0; 16226003Smsmith} 16326003Smsmith 16426003Smsmithstruct linux_target_ops the_low_target = { 16526003Smsmith i386_num_regs, 16626003Smsmith i386_regmap, 16726003Smsmith i386_cannot_fetch_register, 16826003Smsmith i386_cannot_store_register, 16926003Smsmith i386_get_pc, 17026003Smsmith i386_set_pc, 17126003Smsmith i386_breakpoint, 17226003Smsmith i386_breakpoint_len, 17326003Smsmith NULL, 17426003Smsmith 1, 175122625Sobrien i386_breakpoint_at, 176122625Sobrien}; 177122625Sobrien