diff options
author | Daniel Jacobowitz <drow@false.org> | 2005-09-10 18:11:14 +0000 |
---|---|---|
committer | Daniel Jacobowitz <drow@false.org> | 2005-09-10 18:11:14 +0000 |
commit | 10d6c8cd3f92fadf295eb3c91d550626f6080f79 (patch) | |
tree | cff10005f06bf60c545372f3066342f1a412e3c7 /gdb/linux-nat.c | |
parent | a6cd0eb35dcc43b0c491397ae1b7ec16b143b79e (diff) | |
download | gdb-10d6c8cd3f92fadf295eb3c91d550626f6080f79.zip gdb-10d6c8cd3f92fadf295eb3c91d550626f6080f79.tar.gz gdb-10d6c8cd3f92fadf295eb3c91d550626f6080f79.tar.bz2 |
* 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.
Diffstat (limited to 'gdb/linux-nat.c')
-rw-r--r-- | gdb/linux-nat.c | 190 |
1 files changed, 142 insertions, 48 deletions
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index 582bcfb..61c0eff 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -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; @@ -2380,6 +2382,26 @@ linux_nat_pid_to_str (ptid_t 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) { #if 0 @@ -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\ |