* Makefile.in (ALLDEPFILES): Update.

(alpha-linux-nat.o, sparc-linux-nat.o): New rules.
	(amd64-linux-nat.o, arm-linux-nat.o, hppa-linux-nat.o)
	(i386-linux-nat.o, ia64-linux-nat.o, linux-nat.o, m32r-linux-nat.o)
	(m68klinux-nat.o, mips-linux-nat.o, ppc-linux-nat.o, s390-nat.o)
	(sparc64-linux-nat.o): Update dependencies.
	* alpha-linux-nat.c, sparc-linux-nat.c: New files.
	* amd64-linux-nat.c (amd64_linux_fetch_inferior_registers): Renamed
	from fetch_inferior_registers and made static.
	(amd64_linux_store_inferior_registers): Renamed from
	store_inferior_registers and made static.
	(amd64_linux_child_post_start_inferior): Renamed from
	child_post_startup_inferior and made static.  Call
	super_post_startup_inferior.
	(super_post_startup_inferior): New.
	(_initialize_amd64_linux_nat): Set it.  Call linux_target and
	add_target.
	* arm-linux-nat.c (arm_linux_fetch_inferior_registers): Renamed
	from fetch_inferior_registers and made static.
	(arm_linux_store_inferior_registers): Renamed from
	store_inferior_registers and made static.
	(_initialize_arm_linux_nat): Add a prototype.  Use linux_target and
	add_target.
	* hppa-linux-nat.c (hppa_linux_fetch_inferior_registers): Renamed
	from fetch_inferior_registers and made static.
	(hppa_linux_store_inferior_registers): Renamed from
	store_inferior_registers and made static.
	(_initialize_hppa_linux_nat): New function.
	* i386-linux-nat.c (i386_linux_fetch_inferior_registers): Renamed
	from fetch_inferior_registers and made static.
	(i386_linux_store_inferior_registers): Renamed from
	store_inferior_registers and made static.
	(i386_linux_resume): Renamed from child_resume and made static.
	(i386_linux_child_post_start_inferior): Renamed from
	child_post_startup_inferior and made static.  Call
	super_post_startup_inferior.
	(super_post_startup_inferior): New.
	(_initialize_i386_linux_nat): New function.
	* i386-nat.c: Remove LINUX_CHILD_POST_STARTUP_INFERIOR #ifndef.
	* ia64-linux-nat.c (ia64_linux_xfer_unwind_table): Remove.
	(super_xfer_partial): New.
	(ia64_linux_xfer_partial): New function.  Use it.
	(_initialize_ia64_linux_nat): New function.
	* ia64-tdep.c (getunwind_table): Revert 2005-06-08 change; use
	target_read_partial and document the problem.
	* inf-ptrace.c (inf_ptrace_fetch_register): Use
	CANNOT_FETCH_REGISTER.  Fix some comments.
	(inf_ptrace_store_register): Use CANNOT_STORE_REGISTER.  Fix some
	comments.
	* linux-nat.c: Include "inf-ptrace.h" and "auxv.h".
	(linux_ops, super_xfer_partial): New variables.
	(linux_child_post_startup_inferior): Make static.
	(child_post_startup_inferior): Delete.
	(linux_nat_attach, linux_nat_detach, resume_callback)
	(linux_nat_resume, linux_nat_wait, linux_nat_create_inferior)
	(linux_nat_mourn_inferior): Use linux_ops instead of
	deprecated_child_ops.
	(child_wait): Do not depend on CHILD_WAIT.
	(linux_nat_xfer_memory): Remove, replace by ...
	(linux_nat_xfer_partial): ... this.  Use linux_ops->to_xfer_partial
	instead of linux_proc_xfer_memory and child_xfer_memory.
	(linux_nat_fetch_registers, linux_nat_store_registers)
	(linux_nat_child_post_startup_inferior): New functions.
	(init_linux_nat_ops): Use the new functions.
	(linux_proc_xfer_memory): Remove, replace by ...
	(linux_proc_xfer_partial): ... this.  Make static.
	(linux_xfer_partial, linux_register_u_offset, linux_target): New
	functions.
	(_initialize_linux_nat): Do not modify deprecated_child_ops.
	* linux-nat.h (linux_proc_xfer_memory): Remove prototype.
	(struct mem_attrib, struct target_ops): Remove forward declarations.
	(linux_child_post_startup_inferior): Remove prototype.
	(linux_target): Add prototype.
	* linux-thread-db.c (thread_db_xfer_memory): Remove, replace by ...
	(thread_db_xfer_partial): ... this.
	(init_thread_db_ops): Set to_xfer_partial instead of
	deprecated_xfer_memory.
	* m32r-linux-nat.c (m32r_linux_fetch_inferior_registers): Renamed
	from fetch_inferior_registers and made static.
	(m32r_linux_store_inferior_registers): Renamed from
	store_inferior_registers and made static.
	(_initialize_m32r_linux_nat): New function.
	* m68klinux-nat.c (m68k_linux_fetch_inferior_registers): Renamed
	from fetch_inferior_registers and made static.
	(m68k_linux_store_inferior_registers): Renamed from
	store_inferior_registers and made static.
	(old_fetch_inferior_registers, old_store_inferior_registers): Made
	static.
	(_initialize_m68k_linux_nat): Use linux_target and add_target.
	* mips-linux-nat.c (_initialize_mips_linux_nat): New function.
	* ppc-linux-nat.c (ppc_linux_fetch_inferior_registers): Renamed
	from fetch_inferior_registers and made static.
	(ppc_linux_store_inferior_registers): Renamed from
	store_inferior_registers and made static.
	(_initialize_ppc_linux_nat): New function.
	* s390-nat.c (s390_linux_fetch_inferior_registers): Renamed
	from fetch_inferior_registers and made static.
	(s390_linux_store_inferior_registers): Renamed from
	store_inferior_registers and made static.
	(_initialize_s390_nat): New function.
	* sparc64-linux-nat.c (_initialize_sparc64_linux_nat): Use
	linux_target and add_target.
	* config/nm-linux.h: Don't include "auxv.h".
	(struct target_waitstatus, child_wait, CHILD_WAIT)
	(CHILD_PID_TO_EXEC_FILE, CHILD_INSERT_FORK_CATCHPOINT)
	(CHILD_INSERT_VFORK_CATCHPOINT, CHILD_INSERT_EXEC_CATCHPOINT)
	(CHILD_POST_STARTUP_INFERIOR, CHILD_POST_ATTACH, CHILD_FOLLOW_FORK)
	(DEPRECATED_KILL_INFERIOR, NATIVE_XFER_AUXV): Delete.
	* config/alpha/alpha-linux.mh (NATDEPFILES): Replace infptrace.o
	and inftarg.o with inf-ptrace.o and alpha-linux-nat.o.
	* config/sparc/linux.mh (NATDEPFILES): Replace infptrace.o and
	inftarg.o with sparc-linux-nat.o.
	* config/sparc/linux64.mh (NATDEPFILES): Remove infptrace.o and
	inftarg.o.
	* config/arm/linux.mh (NATDEPFILES): Replace infptrace.o and
	inftarg.o with inf-ptrace.o.
	* config/i386/linux.mh (NATDEPFILES): Likewise.
	* config/i386/linux64.mh (NATDEPFILES): Likewise.
	* config/ia64/linux.mh (NATDEPFILES): Likewise.
	* config/m32r/linux.mh (NATDEPFILES): Likewise.
	* config/m68k/linux.mh (NATDEPFILES): Likewise.
	* config/mips/linux.mh (NATDEPFILES): Likewise.
	* config/pa/linux.mh (NATDEPFILES): Likewise.
	* config/powerpc/linux.mh (NATDEPFILES): Likewise.
	* config/powerpc/ppc64-linux.mh (NATDEPFILES): Likewise.
	* config/s390/s390.mh (NATDEPFILES): Likewise.
	* config/i386/nm-linux.h (DEPRECATED_CHILD_RESUME): Don't define.
	(LINUX_CHILD_POST_STARTUP_INFERIOR): Don't define.
	* config/i386/nm-linux64.h (LINUX_CHILD_POST_STARTUP_INFERIOR):
	Don't define.
	* config/ia64/nm-linux.h: Don't include "target.h".
	(NATIVE_XFER_UNWIND_TABLE, ia64_linux_xfer_unwind_table): Remove.
	* config/djgpp/fnchange.lst: Add alpha-linux-tdep.c,
	alpha-linux-nat.c, sparc-linux-tdep.c, and sparc-linux-nat.c.
This commit is contained in:
Daniel Jacobowitz 2005-09-10 18:11:14 +00:00
parent a6cd0eb35d
commit 10d6c8cd3f
40 changed files with 710 additions and 224 deletions

View file

@ -34,6 +34,8 @@
#include "gdbthread.h"
#include "gdbcmd.h"
#include "regcache.h"
#include "inf-ptrace.h"
#include "auxv.h"
#include <sys/param.h> /* for MAXPATHLEN */
#include <sys/procfs.h> /* for elf_gregset etc. */
#include "elf-bfd.h" /* for elfcore_write_* */
@ -81,6 +83,16 @@
#define __WALL 0x40000000 /* Wait for any child. */
#endif
/* The single-threaded native GNU/Linux target_ops. We save a pointer for
the use of the multi-threaded target. */
static struct target_ops *linux_ops;
/* The saved to_xfer_partial method, inherited from inf-ptrace.c. Called
by our to_xfer_partial. */
static LONGEST (*super_xfer_partial) (struct target_ops *, enum target_object,
const char *, gdb_byte *, const gdb_byte *,
ULONGEST, LONGEST);
static int debug_linux_nat;
static void
show_debug_linux_nat (struct ui_file *file, int from_tty,
@ -319,20 +331,12 @@ child_post_attach (int pid)
linux_enable_event_reporting (pid_to_ptid (pid));
}
void
static void
linux_child_post_startup_inferior (ptid_t ptid)
{
linux_enable_event_reporting (ptid);
}
#ifndef LINUX_CHILD_POST_STARTUP_INFERIOR
void
child_post_startup_inferior (ptid_t ptid)
{
linux_child_post_startup_inferior (ptid);
}
#endif
int
child_follow_fork (struct target_ops *ops, int follow_child)
{
@ -913,7 +917,7 @@ linux_nat_attach (char *args, int from_tty)
/* FIXME: We should probably accept a list of process id's, and
attach all of them. */
deprecated_child_ops.to_attach (args, from_tty);
linux_ops->to_attach (args, from_tty);
/* Add the initial process as the first LWP to the list. */
lp = add_lwp (BUILD_LWP (GET_PID (inferior_ptid), GET_PID (inferior_ptid)));
@ -1023,7 +1027,7 @@ linux_nat_detach (char *args, int from_tty)
sigemptyset (&blocked_mask);
inferior_ptid = pid_to_ptid (GET_PID (inferior_ptid));
deprecated_child_ops.to_detach (args, from_tty);
linux_ops->to_detach (args, from_tty);
}
/* Resume LP. */
@ -1035,7 +1039,8 @@ resume_callback (struct lwp_info *lp, void *data)
{
struct thread_info *tp;
child_resume (pid_to_ptid (GET_LWP (lp->ptid)), 0, TARGET_SIGNAL_0);
linux_ops->to_resume (pid_to_ptid (GET_LWP (lp->ptid)),
0, TARGET_SIGNAL_0);
if (debug_linux_nat)
fprintf_unfiltered (gdb_stdlog,
"RC: PTRACE_CONT %s, 0, 0 (resume sibling)\n",
@ -1109,7 +1114,7 @@ linux_nat_resume (ptid_t ptid, int step, enum target_signal signo)
if (resume_all)
iterate_over_lwps (resume_callback, NULL);
child_resume (ptid, step, signo);
linux_ops->to_resume (ptid, step, signo);
if (debug_linux_nat)
fprintf_unfiltered (gdb_stdlog,
"LLR: %s %s, %s (resume event thread)\n",
@ -1683,8 +1688,6 @@ resumed_callback (struct lwp_info *lp, void *data)
return lp->resumed;
}
#ifdef CHILD_WAIT
/* We need to override child_wait to support attaching to cloned
processes, since a normal wait (as done by the default version)
ignores those processes. */
@ -1789,8 +1792,6 @@ child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
return pid_to_ptid (pid);
}
#endif
/* Stop an active thread, verify it still exists, then resume it. */
static int
@ -1899,8 +1900,8 @@ retry:
/* Resume the thread. It should halt immediately returning the
pending SIGSTOP. */
registers_changed ();
child_resume (pid_to_ptid (GET_LWP (lp->ptid)), lp->step,
TARGET_SIGNAL_0);
linux_ops->to_resume (pid_to_ptid (GET_LWP (lp->ptid)),
lp->step, TARGET_SIGNAL_0);
if (debug_linux_nat)
fprintf_unfiltered (gdb_stdlog,
"LLW: %s %s, 0, 0 (expect SIGSTOP)\n",
@ -2101,8 +2102,8 @@ retry:
lp->signalled = 0;
registers_changed ();
child_resume (pid_to_ptid (GET_LWP (lp->ptid)), lp->step,
TARGET_SIGNAL_0);
linux_ops->to_resume (pid_to_ptid (GET_LWP (lp->ptid)),
lp->step, TARGET_SIGNAL_0);
if (debug_linux_nat)
fprintf_unfiltered (gdb_stdlog,
"LLW: %s %s, 0, 0 (discard SIGSTOP)\n",
@ -2161,7 +2162,8 @@ retry:
newly attached threads may cause an unwanted delay in
getting them running. */
registers_changed ();
child_resume (pid_to_ptid (GET_LWP (lp->ptid)), lp->step, signo);
linux_ops->to_resume (pid_to_ptid (GET_LWP (lp->ptid)),
lp->step, signo);
if (debug_linux_nat)
fprintf_unfiltered (gdb_stdlog,
"LLW: %s %s, %s (preempt 'handle')\n",
@ -2310,7 +2312,7 @@ static void
linux_nat_create_inferior (char *exec_file, char *allargs, char **env,
int from_tty)
{
deprecated_child_ops.to_create_inferior (exec_file, allargs, env, from_tty);
linux_ops->to_create_inferior (exec_file, allargs, env, from_tty);
}
static void
@ -2325,23 +2327,23 @@ linux_nat_mourn_inferior (void)
sigprocmask (SIG_SETMASK, &normal_mask, NULL);
sigemptyset (&blocked_mask);
deprecated_child_ops.to_mourn_inferior ();
linux_ops->to_mourn_inferior ();
}
static int
linux_nat_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len,
int write, struct mem_attrib *attrib,
struct target_ops *target)
static LONGEST
linux_nat_xfer_partial (struct target_ops *ops, enum target_object object,
const char *annex, gdb_byte *readbuf,
const gdb_byte *writebuf,
ULONGEST offset, LONGEST len)
{
struct cleanup *old_chain = save_inferior_ptid ();
int xfer;
LONGEST xfer;
if (is_lwp (inferior_ptid))
inferior_ptid = pid_to_ptid (GET_LWP (inferior_ptid));
xfer = linux_proc_xfer_memory (memaddr, myaddr, len, write, attrib, target);
if (xfer == 0)
xfer = child_xfer_memory (memaddr, myaddr, len, write, attrib, target);
xfer = linux_ops->to_xfer_partial (ops, object, annex, readbuf, writebuf,
offset, len);
do_cleanups (old_chain);
return xfer;
@ -2379,6 +2381,26 @@ linux_nat_pid_to_str (ptid_t ptid)
return normal_pid_to_str (ptid);
}
static void
linux_nat_fetch_registers (int regnum)
{
/* to_fetch_registers will honor the LWP ID, so we can use it directly. */
linux_ops->to_fetch_registers (regnum);
}
static void
linux_nat_store_registers (int regnum)
{
/* to_store_registers will honor the LWP ID, so we can use it directly. */
linux_ops->to_store_registers (regnum);
}
static void
linux_nat_child_post_startup_inferior (ptid_t ptid)
{
linux_ops->to_post_startup_inferior (ptid);
}
static void
init_linux_nat_ops (void)
{
@ -2392,17 +2414,16 @@ init_linux_nat_ops (void)
linux_nat_ops.to_detach = linux_nat_detach;
linux_nat_ops.to_resume = linux_nat_resume;
linux_nat_ops.to_wait = linux_nat_wait;
/* fetch_inferior_registers and store_inferior_registers will
honor the LWP id, so we can use them directly. */
linux_nat_ops.to_fetch_registers = fetch_inferior_registers;
linux_nat_ops.to_store_registers = store_inferior_registers;
linux_nat_ops.deprecated_xfer_memory = linux_nat_xfer_memory;
linux_nat_ops.to_fetch_registers = linux_nat_fetch_registers;
linux_nat_ops.to_store_registers = linux_nat_store_registers;
linux_nat_ops.to_xfer_partial = linux_nat_xfer_partial;
linux_nat_ops.to_kill = linux_nat_kill;
linux_nat_ops.to_create_inferior = linux_nat_create_inferior;
linux_nat_ops.to_mourn_inferior = linux_nat_mourn_inferior;
linux_nat_ops.to_thread_alive = linux_nat_thread_alive;
linux_nat_ops.to_pid_to_str = linux_nat_pid_to_str;
linux_nat_ops.to_post_startup_inferior = child_post_startup_inferior;
linux_nat_ops.to_post_startup_inferior
= linux_nat_child_post_startup_inferior;
linux_nat_ops.to_post_attach = child_post_attach;
linux_nat_ops.to_insert_fork_catchpoint = child_insert_fork_catchpoint;
linux_nat_ops.to_insert_vfork_catchpoint = child_insert_vfork_catchpoint;
@ -2948,14 +2969,22 @@ linux_nat_info_proc_cmd (char *args, int from_tty)
}
}
int
linux_proc_xfer_memory (CORE_ADDR addr, gdb_byte *myaddr, int len, int write,
struct mem_attrib *attrib, struct target_ops *target)
/* Implement the to_xfer_partial interface for memory reads using the /proc
filesystem. Because we can use a single read() call for /proc, this
can be much more efficient than banging away at PTRACE_PEEKTEXT,
but it doesn't support writes. */
static LONGEST
linux_proc_xfer_partial (struct target_ops *ops, enum target_object object,
const char *annex, gdb_byte *readbuf,
const gdb_byte *writebuf,
ULONGEST offset, LONGEST len)
{
int fd, ret;
LONGEST ret;
int fd;
char filename[64];
if (write)
if (object != TARGET_OBJECT_MEMORY || !readbuf)
return 0;
/* Don't bother for one word. */
@ -2974,9 +3003,9 @@ linux_proc_xfer_memory (CORE_ADDR addr, gdb_byte *myaddr, int len, int write,
32-bit platforms (for instance, SPARC debugging a SPARC64
application). */
#ifdef HAVE_PREAD64
if (pread64 (fd, myaddr, len, addr) != len)
if (pread64 (fd, readbuf, len, offset) != len)
#else
if (lseek (fd, addr, SEEK_SET) == -1 || read (fd, myaddr, len) != len)
if (lseek (fd, offset, SEEK_SET) == -1 || read (fd, readbuf, len) != len)
#endif
ret = 0;
else
@ -3067,15 +3096,80 @@ linux_proc_pending_signals (int pid, sigset_t *pending, sigset_t *blocked, sigse
fclose (procfile);
}
static LONGEST
linux_xfer_partial (struct target_ops *ops, enum target_object object,
const char *annex, gdb_byte *readbuf,
const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
{
LONGEST xfer;
if (object == TARGET_OBJECT_AUXV)
return procfs_xfer_auxv (ops, object, annex, readbuf, writebuf,
offset, len);
xfer = linux_proc_xfer_partial (ops, object, annex, readbuf, writebuf,
offset, len);
if (xfer != 0)
return xfer;
return super_xfer_partial (ops, object, annex, readbuf, writebuf,
offset, len);
}
#ifndef FETCH_INFERIOR_REGISTERS
/* Return the address in the core dump or inferior of register
REGNO. */
static CORE_ADDR
linux_register_u_offset (int regno)
{
/* FIXME drow/2005-09-04: The hardcoded use of register_addr should go
away. This requires disentangling the various definitions of it
(particularly alpha-nat.c's). */
return register_addr (regno, 0);
}
#endif
/* Create a prototype generic Linux target. The client can override
it with local methods. */
struct target_ops *
linux_target (void)
{
struct target_ops *t;
#ifdef FETCH_INFERIOR_REGISTERS
t = inf_ptrace_target ();
#else
t = inf_ptrace_trad_target (linux_register_u_offset);
#endif
t->to_wait = child_wait;
t->to_kill = kill_inferior;
t->to_insert_fork_catchpoint = child_insert_fork_catchpoint;
t->to_insert_vfork_catchpoint = child_insert_vfork_catchpoint;
t->to_insert_exec_catchpoint = child_insert_exec_catchpoint;
t->to_pid_to_exec_file = child_pid_to_exec_file;
t->to_post_startup_inferior = linux_child_post_startup_inferior;
t->to_post_attach = child_post_attach;
t->to_follow_fork = child_follow_fork;
t->to_find_memory_regions = linux_nat_find_memory_regions;
t->to_make_corefile_notes = linux_nat_make_corefile_notes;
super_xfer_partial = t->to_xfer_partial;
t->to_xfer_partial = linux_xfer_partial;
linux_ops = t;
return t;
}
void
_initialize_linux_nat (void)
{
struct sigaction action;
extern void thread_db_init (struct target_ops *);
deprecated_child_ops.to_find_memory_regions = linux_nat_find_memory_regions;
deprecated_child_ops.to_make_corefile_notes = linux_nat_make_corefile_notes;
add_info ("proc", linux_nat_info_proc_cmd, _("\
Show /proc process information about any running process.\n\
Specify any process id, or use the program being debugged by default.\n\