This commit was generated by cvs2svn to compensate for changes in r157571,
which included commits to RCS files with non-trunk default branches.
This commit is contained in:
commit
0bf49b8fa9
176
gnu/usr.bin/gdb/gdbserver/fbsd-i386-low.c
Normal file
176
gnu/usr.bin/gdb/gdbserver/fbsd-i386-low.c
Normal file
@ -0,0 +1,176 @@
|
||||
/* GNU/Linux/i386 specific low level interface, for the remote server for GDB.
|
||||
Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "server.h"
|
||||
#include "linux-low.h"
|
||||
#include "i387-fp.h"
|
||||
|
||||
#ifdef HAVE_SYS_REG_H
|
||||
#include <sys/reg.h>
|
||||
#endif
|
||||
|
||||
/* This module only supports access to the general purpose registers. */
|
||||
|
||||
#define i386_num_regs 16
|
||||
|
||||
/* This stuff comes from i386-linux-nat.c. */
|
||||
|
||||
/* Mapping between the general-purpose registers in `struct user'
|
||||
format and GDB's register array layout. */
|
||||
static int i386_regmap[] =
|
||||
{
|
||||
EAX * 4, ECX * 4, EDX * 4, EBX * 4,
|
||||
UESP * 4, EBP * 4, ESI * 4, EDI * 4,
|
||||
EIP * 4, EFL * 4, CS * 4, SS * 4,
|
||||
DS * 4, ES * 4, FS * 4, GS * 4
|
||||
};
|
||||
|
||||
static int
|
||||
i386_cannot_store_register (int regno)
|
||||
{
|
||||
return (regno >= i386_num_regs);
|
||||
}
|
||||
|
||||
static int
|
||||
i386_cannot_fetch_register (int regno)
|
||||
{
|
||||
return (regno >= i386_num_regs);
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_LINUX_REGSETS
|
||||
#include <sys/procfs.h>
|
||||
#include <sys/ptrace.h>
|
||||
|
||||
static void
|
||||
i386_fill_gregset (void *buf)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < i386_num_regs; i++)
|
||||
collect_register (i, ((char *) buf) + i386_regmap[i]);
|
||||
|
||||
collect_register_by_name ("orig_eax", ((char *) buf) + ORIG_EAX * 4);
|
||||
}
|
||||
|
||||
static void
|
||||
i386_store_gregset (const void *buf)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < i386_num_regs; i++)
|
||||
supply_register (i, ((char *) buf) + i386_regmap[i]);
|
||||
|
||||
supply_register_by_name ("orig_eax", ((char *) buf) + ORIG_EAX * 4);
|
||||
}
|
||||
|
||||
static void
|
||||
i386_fill_fpregset (void *buf)
|
||||
{
|
||||
i387_cache_to_fsave (buf);
|
||||
}
|
||||
|
||||
static void
|
||||
i386_store_fpregset (const void *buf)
|
||||
{
|
||||
i387_fsave_to_cache (buf);
|
||||
}
|
||||
|
||||
static void
|
||||
i386_fill_fpxregset (void *buf)
|
||||
{
|
||||
i387_cache_to_fxsave (buf);
|
||||
}
|
||||
|
||||
static void
|
||||
i386_store_fpxregset (const void *buf)
|
||||
{
|
||||
i387_fxsave_to_cache (buf);
|
||||
}
|
||||
|
||||
|
||||
struct regset_info target_regsets[] = {
|
||||
{ PTRACE_GETREGS, PTRACE_SETREGS, sizeof (elf_gregset_t),
|
||||
GENERAL_REGS,
|
||||
i386_fill_gregset, i386_store_gregset },
|
||||
#ifdef HAVE_PTRACE_GETFPXREGS
|
||||
{ PTRACE_GETFPXREGS, PTRACE_SETFPXREGS, sizeof (elf_fpxregset_t),
|
||||
EXTENDED_REGS,
|
||||
i386_fill_fpxregset, i386_store_fpxregset },
|
||||
#endif
|
||||
{ PTRACE_GETFPREGS, PTRACE_SETFPREGS, sizeof (elf_fpregset_t),
|
||||
FP_REGS,
|
||||
i386_fill_fpregset, i386_store_fpregset },
|
||||
{ 0, 0, -1, -1, NULL, NULL }
|
||||
};
|
||||
|
||||
#endif /* HAVE_LINUX_REGSETS */
|
||||
|
||||
static const char i386_breakpoint[] = { 0xCC };
|
||||
#define i386_breakpoint_len 1
|
||||
|
||||
extern int debug_threads;
|
||||
|
||||
static CORE_ADDR
|
||||
i386_get_pc ()
|
||||
{
|
||||
unsigned long pc;
|
||||
|
||||
collect_register_by_name ("eip", &pc);
|
||||
|
||||
if (debug_threads)
|
||||
fprintf (stderr, "stop pc (before any decrement) is %08lx\n", pc);
|
||||
return pc;
|
||||
}
|
||||
|
||||
static void
|
||||
i386_set_pc (CORE_ADDR newpc)
|
||||
{
|
||||
if (debug_threads)
|
||||
fprintf (stderr, "set pc to %08lx\n", (long) newpc);
|
||||
supply_register_by_name ("eip", &newpc);
|
||||
}
|
||||
|
||||
static int
|
||||
i386_breakpoint_at (CORE_ADDR pc)
|
||||
{
|
||||
unsigned char c;
|
||||
|
||||
read_inferior_memory (pc, &c, 1);
|
||||
if (c == 0xCC)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct linux_target_ops the_low_target = {
|
||||
i386_num_regs,
|
||||
i386_regmap,
|
||||
i386_cannot_fetch_register,
|
||||
i386_cannot_store_register,
|
||||
i386_get_pc,
|
||||
i386_set_pc,
|
||||
i386_breakpoint,
|
||||
i386_breakpoint_len,
|
||||
NULL,
|
||||
1,
|
||||
i386_breakpoint_at,
|
||||
};
|
1458
gnu/usr.bin/gdb/gdbserver/fbsd-low.c
Normal file
1458
gnu/usr.bin/gdb/gdbserver/fbsd-low.c
Normal file
File diff suppressed because it is too large
Load Diff
120
gnu/usr.bin/gdb/gdbserver/fbsd-low.h
Normal file
120
gnu/usr.bin/gdb/gdbserver/fbsd-low.h
Normal file
@ -0,0 +1,120 @@
|
||||
/* Internal interfaces for the GNU/Linux specific target code for gdbserver.
|
||||
Copyright 2002, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifdef HAVE_LINUX_REGSETS
|
||||
typedef void (*regset_fill_func) (void *);
|
||||
typedef void (*regset_store_func) (const void *);
|
||||
enum regset_type {
|
||||
GENERAL_REGS,
|
||||
FP_REGS,
|
||||
EXTENDED_REGS,
|
||||
};
|
||||
|
||||
struct regset_info
|
||||
{
|
||||
int get_request, set_request;
|
||||
int size;
|
||||
enum regset_type type;
|
||||
regset_fill_func fill_function;
|
||||
regset_store_func store_function;
|
||||
};
|
||||
extern struct regset_info target_regsets[];
|
||||
#endif
|
||||
|
||||
struct linux_target_ops
|
||||
{
|
||||
int num_regs;
|
||||
int *regmap;
|
||||
int (*cannot_fetch_register) (int);
|
||||
|
||||
/* Returns 0 if we can store the register, 1 if we can not
|
||||
store the register, and 2 if failure to store the register
|
||||
is acceptable. */
|
||||
int (*cannot_store_register) (int);
|
||||
CORE_ADDR (*get_pc) (void);
|
||||
void (*set_pc) (CORE_ADDR newpc);
|
||||
const char *breakpoint;
|
||||
int breakpoint_len;
|
||||
CORE_ADDR (*breakpoint_reinsert_addr) (void);
|
||||
|
||||
|
||||
int decr_pc_after_break;
|
||||
int (*breakpoint_at) (CORE_ADDR pc);
|
||||
};
|
||||
|
||||
extern struct linux_target_ops the_low_target;
|
||||
|
||||
#define get_process(inf) ((struct process_info *)(inf))
|
||||
#define get_thread_process(thr) (get_process (inferior_target_data (thr)))
|
||||
#define get_process_thread(proc) ((struct thread_info *) \
|
||||
find_inferior_id (&all_threads, \
|
||||
get_process (proc)->tid))
|
||||
|
||||
struct process_info
|
||||
{
|
||||
struct inferior_list_entry head;
|
||||
int thread_known;
|
||||
int lwpid;
|
||||
int tid;
|
||||
|
||||
/* If this flag is set, the next SIGSTOP will be ignored (the process will
|
||||
be immediately resumed). */
|
||||
int stop_expected;
|
||||
|
||||
/* If this flag is set, the process is known to be stopped right now (stop
|
||||
event already received in a wait()). */
|
||||
int stopped;
|
||||
|
||||
/* If this flag is set, we have sent a SIGSTOP to this process and are
|
||||
waiting for it to stop. */
|
||||
int sigstop_sent;
|
||||
|
||||
/* If this flag is set, STATUS_PENDING is a waitstatus that has not yet
|
||||
been reported. */
|
||||
int status_pending_p;
|
||||
int status_pending;
|
||||
|
||||
/* If this flag is set, the pending status is a (GDB-placed) breakpoint. */
|
||||
int pending_is_breakpoint;
|
||||
CORE_ADDR pending_stop_pc;
|
||||
|
||||
/* If this is non-zero, it is a breakpoint to be reinserted at our next
|
||||
stop (SIGTRAP stops only). */
|
||||
CORE_ADDR bp_reinsert;
|
||||
|
||||
/* If this flag is set, the last continue operation on this process
|
||||
was a single-step. */
|
||||
int stepping;
|
||||
|
||||
/* If this is non-zero, it points to a chain of signals which need to
|
||||
be delivered to this process. */
|
||||
struct pending_signals *pending_signals;
|
||||
|
||||
/* A link used when resuming. It is initialized from the resume request,
|
||||
and then processed and cleared in linux_resume_one_process. */
|
||||
|
||||
struct thread_resume *resume;
|
||||
};
|
||||
|
||||
extern struct inferior_list all_processes;
|
||||
|
||||
void linux_attach_lwp (int pid, int tid);
|
||||
|
||||
int thread_db_init (void);
|
Loading…
Reference in New Issue
Block a user