1157571Sjmg/* GNU/Linux/i386 specific low level interface, for the remote server for GDB. 2157571Sjmg Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002 3157571Sjmg Free Software Foundation, Inc. 4157571Sjmg 5157571Sjmg This file is part of GDB. 6157571Sjmg 7157571Sjmg This program is free software; you can redistribute it and/or modify 8157571Sjmg it under the terms of the GNU General Public License as published by 9157571Sjmg the Free Software Foundation; either version 2 of the License, or 10157571Sjmg (at your option) any later version. 11157571Sjmg 12157571Sjmg This program is distributed in the hope that it will be useful, 13157571Sjmg but WITHOUT ANY WARRANTY; without even the implied warranty of 14157571Sjmg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15157571Sjmg GNU General Public License for more details. 16157571Sjmg 17157571Sjmg You should have received a copy of the GNU General Public License 18157571Sjmg along with this program; if not, write to the Free Software 19157571Sjmg Foundation, Inc., 59 Temple Place - Suite 330, 20157571Sjmg Boston, MA 02111-1307, USA. */ 21157571Sjmg 22157574Sjmg#include <sys/cdefs.h> 23157574Sjmg__FBSDID("$FreeBSD: releng/10.2/gnu/usr.bin/gdb/gdbserver/fbsd-i386-low.c 157574 2006-04-06 22:24:01Z jmg $"); 24157574Sjmg 25157571Sjmg#include "server.h" 26157574Sjmg#include "fbsd-low.h" 27157571Sjmg#include "i387-fp.h" 28157571Sjmg 29157571Sjmg#ifdef HAVE_SYS_REG_H 30157571Sjmg#include <sys/reg.h> 31157574Sjmg#else 32157574Sjmg#include <machine/reg.h> 33157571Sjmg#endif 34157571Sjmg 35157571Sjmg/* This module only supports access to the general purpose registers. */ 36157571Sjmg 37157571Sjmg#define i386_num_regs 16 38157571Sjmg 39157574Sjmg/* This stuff comes from i386-fbsd-nat.c. */ 40157571Sjmg 41157571Sjmg/* Mapping between the general-purpose registers in `struct user' 42157571Sjmg format and GDB's register array layout. */ 43157571Sjmgstatic int i386_regmap[] = 44157571Sjmg{ 45157574Sjmg tEAX * 4, tECX * 4, tEDX * 4, tEBX * 4, 46157574Sjmg tESP * 4, tEBP * 4, tESI * 4, tEDI * 4, 47157574Sjmg tEIP * 4, tEFLAGS * 4, tCS * 4, tSS * 4, 48157574Sjmg tDS * 4, tES * 4, tFS * 4, tGS * 4 49157571Sjmg}; 50157571Sjmg 51157571Sjmgstatic int 52157571Sjmgi386_cannot_store_register (int regno) 53157571Sjmg{ 54157571Sjmg return (regno >= i386_num_regs); 55157571Sjmg} 56157571Sjmg 57157571Sjmgstatic int 58157571Sjmgi386_cannot_fetch_register (int regno) 59157571Sjmg{ 60157571Sjmg return (regno >= i386_num_regs); 61157571Sjmg} 62157571Sjmg 63157571Sjmg 64157571Sjmg#include <sys/procfs.h> 65157571Sjmg#include <sys/ptrace.h> 66157571Sjmg 67157571Sjmgstatic void 68157571Sjmgi386_fill_gregset (void *buf) 69157571Sjmg{ 70157571Sjmg int i; 71157571Sjmg 72157571Sjmg for (i = 0; i < i386_num_regs; i++) 73157571Sjmg collect_register (i, ((char *) buf) + i386_regmap[i]); 74157571Sjmg 75157571Sjmg} 76157571Sjmg 77157571Sjmgstatic void 78157571Sjmgi386_store_gregset (const void *buf) 79157571Sjmg{ 80157571Sjmg int i; 81157571Sjmg 82157571Sjmg for (i = 0; i < i386_num_regs; i++) 83157571Sjmg supply_register (i, ((char *) buf) + i386_regmap[i]); 84157571Sjmg 85157571Sjmg} 86157571Sjmg 87157571Sjmgstatic void 88157571Sjmgi386_fill_fpregset (void *buf) 89157571Sjmg{ 90157571Sjmg i387_cache_to_fsave (buf); 91157571Sjmg} 92157571Sjmg 93157571Sjmgstatic void 94157571Sjmgi386_store_fpregset (const void *buf) 95157571Sjmg{ 96157571Sjmg i387_fsave_to_cache (buf); 97157571Sjmg} 98157571Sjmg 99157571Sjmgstatic void 100157571Sjmgi386_fill_fpxregset (void *buf) 101157571Sjmg{ 102157571Sjmg i387_cache_to_fxsave (buf); 103157571Sjmg} 104157571Sjmg 105157571Sjmgstatic void 106157571Sjmgi386_store_fpxregset (const void *buf) 107157571Sjmg{ 108157571Sjmg i387_fxsave_to_cache (buf); 109157571Sjmg} 110157571Sjmg 111157571Sjmg 112157571Sjmgstruct regset_info target_regsets[] = { 113157574Sjmg { PT_GETREGS, PT_SETREGS, sizeof (struct reg), 114157571Sjmg GENERAL_REGS, 115157571Sjmg i386_fill_gregset, i386_store_gregset }, 116157571Sjmg#ifdef HAVE_PTRACE_GETFPXREGS 117157571Sjmg { PTRACE_GETFPXREGS, PTRACE_SETFPXREGS, sizeof (elf_fpxregset_t), 118157571Sjmg EXTENDED_REGS, 119157571Sjmg i386_fill_fpxregset, i386_store_fpxregset }, 120157571Sjmg#endif 121157574Sjmg { PT_GETFPREGS, PT_SETFPREGS, sizeof (struct fpreg), 122157571Sjmg FP_REGS, 123157571Sjmg i386_fill_fpregset, i386_store_fpregset }, 124157571Sjmg { 0, 0, -1, -1, NULL, NULL } 125157571Sjmg}; 126157571Sjmg 127157571Sjmgstatic const char i386_breakpoint[] = { 0xCC }; 128157571Sjmg#define i386_breakpoint_len 1 129157571Sjmg 130157571Sjmgextern int debug_threads; 131157571Sjmg 132157571Sjmgstatic CORE_ADDR 133157571Sjmgi386_get_pc () 134157571Sjmg{ 135157571Sjmg unsigned long pc; 136157571Sjmg 137157571Sjmg collect_register_by_name ("eip", &pc); 138157571Sjmg 139157571Sjmg if (debug_threads) 140157571Sjmg fprintf (stderr, "stop pc (before any decrement) is %08lx\n", pc); 141157571Sjmg return pc; 142157571Sjmg} 143157571Sjmg 144157571Sjmgstatic void 145157571Sjmgi386_set_pc (CORE_ADDR newpc) 146157571Sjmg{ 147157571Sjmg if (debug_threads) 148157571Sjmg fprintf (stderr, "set pc to %08lx\n", (long) newpc); 149157571Sjmg supply_register_by_name ("eip", &newpc); 150157571Sjmg} 151157571Sjmg 152157571Sjmgstatic int 153157571Sjmgi386_breakpoint_at (CORE_ADDR pc) 154157571Sjmg{ 155157571Sjmg unsigned char c; 156157571Sjmg 157157571Sjmg read_inferior_memory (pc, &c, 1); 158157571Sjmg if (c == 0xCC) 159157571Sjmg return 1; 160157571Sjmg 161157571Sjmg return 0; 162157571Sjmg} 163157571Sjmg 164157574Sjmgstruct fbsd_target_ops the_low_target = { 165157571Sjmg i386_num_regs, 166157571Sjmg i386_regmap, 167157571Sjmg i386_cannot_fetch_register, 168157571Sjmg i386_cannot_store_register, 169157571Sjmg i386_get_pc, 170157571Sjmg i386_set_pc, 171157571Sjmg i386_breakpoint, 172157571Sjmg i386_breakpoint_len, 173157571Sjmg NULL, 174157571Sjmg 1, 175157571Sjmg i386_breakpoint_at, 176157571Sjmg}; 177