* Makefile.in (linux-nat.o): Add rule.
authorDaniel Jacobowitz <drow@false.org>
Sun, 15 Jun 2003 20:56:48 +0000 (20:56 +0000)
committerDaniel Jacobowitz <drow@false.org>
Sun, 15 Jun 2003 20:56:48 +0000 (20:56 +0000)
* linux-nat.c: New file.
* config/nm-linux.h (CHILD_INSERT_FORK_CATCHPOINT): Define.
(CHILD_INSERT_VFORK_CATCHPOINT): Define.
(CHILD_INSERT_EXEC_CATCHPOINT): Define.
* config/alpha/alpha-linux.mh (NATDEPFILES): Add linux-nat.o.
* config/arm/linux.mh (NATDEPFILES): Likewise.
* config/i386/linux.mh (NATDEPFILES): Likewise.
* config/i386/x86-64linux.mh (NATDEPFILES): Likewise.
* config/ia64/linux.mh (NATDEPFILES): Likewise.
* config/m68k/linux.mh (NATDEPFILES): Likewise.
* config/mips/linux.mh (NATDEPFILES): Likewise.
* config/powerpc/linux.mh (NATDEPFILES): Likewise.
* config/s390/s390.mh (NATDEPFILES): Likewise.
* config/sparc/linux.mh (NATDEPFILES): Likewise.

14 files changed:
gdb/ChangeLog
gdb/Makefile.in
gdb/config/alpha/alpha-linux.mh
gdb/config/arm/linux.mh
gdb/config/i386/linux.mh
gdb/config/i386/x86-64linux.mh
gdb/config/ia64/linux.mh
gdb/config/m68k/linux.mh
gdb/config/mips/linux.mh
gdb/config/nm-linux.h
gdb/config/powerpc/linux.mh
gdb/config/s390/s390.mh
gdb/config/sparc/linux.mh
gdb/linux-nat.c [new file with mode: 0644]

index 9ca17ceccedb37dbf95e5852fa3f370f151e9463..a9b8d6a8f293304ea36e227f61f78a13c2f8a525 100644 (file)
@@ -1,3 +1,21 @@
+2003-06-15  Daniel Jacobowitz  <drow@mvista.com>
+
+       * Makefile.in (linux-nat.o): Add rule.
+       * linux-nat.c: New file.
+       * config/nm-linux.h (CHILD_INSERT_FORK_CATCHPOINT): Define.
+       (CHILD_INSERT_VFORK_CATCHPOINT): Define.
+       (CHILD_INSERT_EXEC_CATCHPOINT): Define.
+       * config/alpha/alpha-linux.mh (NATDEPFILES): Add linux-nat.o.
+       * config/arm/linux.mh (NATDEPFILES): Likewise.
+       * config/i386/linux.mh (NATDEPFILES): Likewise.
+       * config/i386/x86-64linux.mh (NATDEPFILES): Likewise.
+       * config/ia64/linux.mh (NATDEPFILES): Likewise.
+       * config/m68k/linux.mh (NATDEPFILES): Likewise.
+       * config/mips/linux.mh (NATDEPFILES): Likewise.
+       * config/powerpc/linux.mh (NATDEPFILES): Likewise.
+       * config/s390/s390.mh (NATDEPFILES): Likewise.
+       * config/sparc/linux.mh (NATDEPFILES): Likewise.
+
 2003-06-15  Mark Kettenis  <kettenis@gnu.org>
 
        * i387-tdep.c: Reorder includes, fix some whitespace issues and
index a0342e3690b7d2547070bdc35fea6b49d9e96896..6dcd7b7fb04589beb26604e94ae855e4e27d498a 100644 (file)
@@ -1916,6 +1916,7 @@ lin-lwp.o: lin-lwp.c $(defs_h) $(gdb_assert_h) $(gdb_string_h) $(gdb_wait_h) \
 linespec.o: linespec.c $(defs_h) $(symtab_h) $(frame_h) $(command_h) \
        $(symfile_h) $(objfiles_h) $(source_h) $(demangle_h) $(value_h) \
        $(completer_h) $(cp_abi_h) $(parser_defs_h) $(block_h) $(objc_lang_h)
+linux-nat.o: linux-nat.c $(defs_h) $(inferior_h) $(target_h) $(gdb_wait_h)
 linux-proc.o: linux-proc.c $(defs_h) $(inferior_h) $(regcache_h) \
        $(gregset_h) $(gdbcore_h) $(gdbthread_h) $(elf_bfd_h) \
        $(cli_decode_h) $(gdb_string_h)
index 7691d0729eb4c198f4452551eaf95224c90b3b80..d3731795020d3ad62915aacd7c819e96a8d1d322 100644 (file)
@@ -2,7 +2,8 @@
 XM_FILE= xm-alphalinux.h
 NAT_FILE= nm-linux.h
 NATDEPFILES= infptrace.o inftarg.o corelow.o alpha-nat.o linux-proc.o \
-       fork-child.o proc-service.o thread-db.o lin-lwp.o gcore.o
+       fork-child.o proc-service.o thread-db.o lin-lwp.o gcore.o \
+       linux-nat.o
 
 LOADLIBES = -ldl -rdynamic
 
index fa1eb63d67fea01c61804929a5cd43a8ef1dcc27..1b0a3ba46d49baf97ad04fc4ed3798a609c7b3d2 100644 (file)
@@ -5,7 +5,7 @@ XM_FILE= xm-linux.h
 NAT_FILE= nm-linux.h
 NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o      \
        core-regset.o arm-linux-nat.o linux-proc.o gcore.o      \
-       proc-service.o thread-db.o lin-lwp.o
+       proc-service.o thread-db.o lin-lwp.o linux-nat.o
 
 LOADLIBES= -ldl -rdynamic
 
index 494ccf1a4a4337717b4fe7e95132faf7558bf679..2a20cdd97496e5a0e4b7618e243b3dcc55be9ffa 100644 (file)
@@ -5,7 +5,8 @@ XM_FILE= xm-i386.h
 NAT_FILE= nm-linux.h
 NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o linux-proc.o \
        core-aout.o i386-nat.o i386-linux-nat.o \
-       proc-service.o thread-db.o lin-lwp.o linux-proc.o gcore.o
+       proc-service.o thread-db.o lin-lwp.o linux-proc.o gcore.o \
+       linux-nat.o
 
 # The dynamically loaded libthread_db needs access to symbols in the
 # gdb executable.
index 895d1fb9f3ac254f312e3f0df13d274eaab888ac..0c3c855e0183ed0a6a4cae55a6961a469c3b1d90 100644 (file)
@@ -5,6 +5,7 @@ XM_FILE= xm-i386.h
 NAT_FILE= nm-x86-64linux.h
 NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o \
        core-regset.o i386-nat.o x86-64-linux-nat.o \
+       linux-nat.o \
        proc-service.o thread-db.o lin-lwp.o linux-proc.o gcore.o 
 
 # The dynamically loaded libthread_db needs access to symbols in the
index 65f30284e1cfa4be3df47b18d0375be20f612451..2013af35505e6e6760d30e853f49618fcafadea9 100644 (file)
@@ -5,6 +5,6 @@ XM_FILE= xm-linux.h
 NAT_FILE= nm-linux.h
 NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o gcore.o \
        core-aout.o core-regset.o ia64-linux-nat.o linux-proc.o \
-       proc-service.o thread-db.o lin-lwp.o
+       proc-service.o thread-db.o lin-lwp.o linux-nat.o
 
 LOADLIBES = -ldl -rdynamic
index f94df64c104e2ddd3a8ae40942a16730dfca594b..d814b73a9e958dbc7900fb45a9fe9922a214a29d 100644 (file)
@@ -5,7 +5,7 @@ XM_FILE= xm-linux.h
 NAT_FILE= nm-linux.h
 NATDEPFILES= infptrace.o inftarg.o fork-child.o \
        corelow.o core-aout.o m68klinux-nat.o linux-proc.o gcore.o \
-       proc-service.o thread-db.o lin-lwp.o 
+       proc-service.o thread-db.o lin-lwp.o linux-nat.o
 
 # The dynamically loaded libthread_db needs access to symbols in the
 # gdb executable.
index 991fd6c0dee8e730771b60ff019bc7f5dd5e7d06..38f87256689425559e4be5d650068973dd7e49a1 100644 (file)
@@ -2,6 +2,7 @@
 XM_FILE= xm-linux.h
 NAT_FILE= nm-linux.h
 NATDEPFILES= infptrace.o inftarg.o fork-child.o mips-linux-nat.o \
-       thread-db.o lin-lwp.o proc-service.o linux-proc.o gcore.o
+       thread-db.o lin-lwp.o proc-service.o linux-proc.o gcore.o \
+       linux-nat.o
 
 LOADLIBES = -ldl -rdynamic
index 0fb562714735a3e801a5b37f4f7026f7174388b8..7e0a076210a185264c2c94d75de9fe9472815662 100644 (file)
@@ -77,3 +77,7 @@ struct mem_attrib;
 extern int linux_proc_xfer_memory (CORE_ADDR addr, char *myaddr, int len,
                                   int write, struct mem_attrib *attrib,
                                   struct target_ops *target);
+
+#define CHILD_INSERT_FORK_CATCHPOINT
+#define CHILD_INSERT_VFORK_CATCHPOINT
+#define CHILD_INSERT_EXEC_CATCHPOINT
index d0a2104bd899355801baa4b88ad660378f1c31de..240c4e0bc2177a605e89c5bf7f28da265275d5bf 100644 (file)
@@ -6,7 +6,7 @@ XM_CLIBS=
 NAT_FILE= nm-linux.h
 NATDEPFILES= infptrace.o inftarg.o fork-child.o linux-proc.o \
        ppc-linux-nat.o proc-service.o thread-db.o lin-lwp.o \
-       gcore.o
+       gcore.o linux-nat.o
 
 LOADLIBES = -ldl -rdynamic
 
index 300a5e3c1ce9c827a97ddebac5ad78e52bdb15fb..ab3350fdb4722f07f667ddd7ce91cef02f94baa5 100644 (file)
@@ -6,7 +6,7 @@ XM_CLIBS=
 NAT_FILE= nm-linux.h
 NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o s390-nat.o \
        core-aout.o core-regset.o linux-proc.o gcore.o thread-db.o lin-lwp.o \
-       proc-service.o
+       proc-service.o linux-nat.o
 LOADLIBES = -ldl -rdynamic
 
 
index 4a2c41f38c48463f4fed62c205b75ea048c8cab0..f36dbb1ae347806d487f1a532309e443d20ca961 100644 (file)
@@ -5,7 +5,7 @@ XM_FILE= xm-linux.h
 NAT_FILE= nm-linux.h
 NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o sparc-nat.o \
        proc-service.o thread-db.o lin-lwp.o sparc-linux-nat.o \
-       linux-proc.o gcore.o 
+       linux-proc.o gcore.o linux-nat.o
 
 # The dynamically loaded libthread_db needs access to symbols in the
 # gdb executable.
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
new file mode 100644 (file)
index 0000000..046544d
--- /dev/null
@@ -0,0 +1,176 @@
+/* GNU/Linux native-dependent code common to multiple platforms.
+   Copyright (C) 2003 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 "defs.h"
+#include "inferior.h"
+#include "target.h"
+
+#include "gdb_wait.h"
+#include <sys/ptrace.h>
+
+/* If the system headers did not provide the constants, hard-code the normal
+   values.  */
+#ifndef PTRACE_EVENT_FORK
+
+#define PTRACE_SETOPTIONS      0x4200
+#define PTRACE_GETEVENTMSG     0x4201
+
+/* options set using PTRACE_SETOPTIONS */
+#define PTRACE_O_TRACESYSGOOD  0x00000001
+#define PTRACE_O_TRACEFORK     0x00000002
+#define PTRACE_O_TRACEVFORK    0x00000004
+#define PTRACE_O_TRACECLONE    0x00000008
+#define PTRACE_O_TRACEEXEC     0x00000010
+
+/* Wait extended result codes for the above trace options.  */
+#define PTRACE_EVENT_FORK      1
+#define PTRACE_EVENT_VFORK     2
+#define PTRACE_EVENT_CLONE     3
+#define PTRACE_EVENT_EXEC      4
+
+#endif /* PTRACE_EVENT_FORK */
+
+/* We can't always assume that this flag is available, but all systems
+   with the ptrace event handlers also have __WALL, so it's safe to use
+   here.  */
+#ifndef __WALL
+#define __WALL          0x40000000 /* Wait for any child.  */
+#endif
+
+/* This variable is a tri-state flag: -1 for unknown, 0 if PTRACE_O_TRACEFORK
+   can not be used, 1 if it can.  */
+
+static int linux_supports_tracefork_flag = -1;
+
+\f
+/* A helper function for linux_test_for_tracefork, called after fork ().  */
+
+static void
+linux_tracefork_child (void)
+{
+  int ret;
+
+  ptrace (PTRACE_TRACEME, 0, 0, 0);
+  kill (getpid (), SIGSTOP);
+  fork ();
+  exit (0);
+}
+
+/* Determine if PTRACE_O_TRACEFORK can be used to follow fork events.  We
+   create a child process, attach to it, use PTRACE_SETOPTIONS to enable
+   fork tracing, and let it fork.  If the process exits, we assume that
+   we can't use TRACEFORK; if we get the fork notification, and we can
+   extract the new child's PID, then we assume that we can.  */
+
+static void
+linux_test_for_tracefork (void)
+{
+  int child_pid, ret, status;
+  long second_pid;
+
+  child_pid = fork ();
+  if (child_pid == -1)
+    perror_with_name ("linux_test_for_tracefork: fork");
+
+  if (child_pid == 0)
+    linux_tracefork_child ();
+
+  ret = waitpid (child_pid, &status, 0);
+  if (ret == -1)
+    perror_with_name ("linux_test_for_tracefork: waitpid");
+  else if (ret != child_pid)
+    error ("linux_test_for_tracefork: waitpid: unexpected result %d.", ret);
+  if (! WIFSTOPPED (status))
+    error ("linux_test_for_tracefork: waitpid: unexpected status %d.", status);
+
+  linux_supports_tracefork_flag = 0;
+
+  ret = ptrace (PTRACE_SETOPTIONS, child_pid, 0, PTRACE_O_TRACEFORK);
+  if (ret != 0)
+    {
+      ptrace (PTRACE_KILL, child_pid, 0, 0);
+      waitpid (child_pid, &status, 0);
+      return;
+    }
+
+  ptrace (PTRACE_CONT, child_pid, 0, 0);
+  ret = waitpid (child_pid, &status, 0);
+  if (ret == child_pid && WIFSTOPPED (status)
+      && status >> 16 == PTRACE_EVENT_FORK)
+    {
+      second_pid = 0;
+      ret = ptrace (PTRACE_GETEVENTMSG, child_pid, 0, &second_pid);
+      if (ret == 0 && second_pid != 0)
+       {
+         int second_status;
+
+         linux_supports_tracefork_flag = 1;
+         waitpid (second_pid, &second_status, 0);
+         ptrace (PTRACE_DETACH, second_pid, 0, 0);
+       }
+    }
+
+  if (WIFSTOPPED (status))
+    {
+      ptrace (PTRACE_DETACH, child_pid, 0, 0);
+      waitpid (child_pid, &status, 0);
+    }
+}
+
+/* Return non-zero iff we have tracefork functionality available.
+   This function also sets linux_supports_tracefork_flag.  */
+
+static int
+linux_supports_tracefork (void)
+{
+  if (linux_supports_tracefork_flag == -1)
+    linux_test_for_tracefork ();
+  return linux_supports_tracefork_flag;
+}
+
+\f
+int
+child_insert_fork_catchpoint (int pid)
+{
+  if (linux_supports_tracefork ())
+    error ("Fork catchpoints have not been implemented yet.");
+  else
+    error ("Your system does not support fork catchpoints.");
+}
+
+int
+child_insert_vfork_catchpoint (int pid)
+{
+  if (linux_supports_tracefork ())
+    error ("Vfork catchpoints have not been implemented yet.");
+  else
+    error ("Your system does not support vfork catchpoints.");
+}
+
+int
+child_insert_exec_catchpoint (int pid)
+{
+  if (linux_supports_tracefork ())
+    error ("Exec catchpoints have not been implemented yet.");
+  else
+    error ("Your system does not support exec catchpoints.");
+}
+
+