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