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