This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFA] Disable ASLR on Darwin


Hi,

this patch disable ASLR on Darwin for spawned programs, so that you can reuse breakpoint/watchpoints with addresses.
Also this adds support for PIE for free (as already noted by Pedro, this doesn't handle attached processes).

Contrary to other OS, this is done at exec (i.e. posix_spawn) time.  In order to use posix_spawn instead of exec, I added a parameter to fork_inferior, adjusted all the calls of fork_inferior (I preferred to pass NULL instead of execvp, because the prototype of the later is somewhat not universal), and added the real work for darwin.

No regressions on i386/GNU linux
Manually tested on Lion.

Ok for trunk ?

Tristan.

2011-09-07  Tristan Gingold  <gingold@adacore.com>

	* fork-child.c (fork_inferior): Add exec_fun parameter.
	Call exec_fun or execvp.
	* inferior.h: Adjust prototype.
	* gnu-nat.c (gnu_create_inferior): Adjust fork_inferior call.
	* inf-ttrace.c (inf_ttrace_create_inferior): Ditto.
	* inf-ptrace.c (inf_ptrace_create_inferior): Ditto.
	* procfs.c (procfs_create_inferior): Ditto.
	* darwin-nat.c (darwin_execvp): New function.
	(darwin_create_inferior): Use it.

diff --git a/gdb/darwin-nat.c b/gdb/darwin-nat.c
index 06a1558..7c0ff5b 100644
--- a/gdb/darwin-nat.c
+++ b/gdb/darwin-nat.c
@@ -53,6 +53,7 @@
 #include <sys/proc.h>
 #include <libproc.h>
 #include <sys/syscall.h>
+#include <spawn.h>
 
 #include <mach/mach_error.h>
 #include <mach/mach_vm.h>
@@ -1507,12 +1508,47 @@ darwin_ptrace_him (int pid)
 }
 
 static void
+darwin_execvp (const char *file, char * const argv[], char * const env[])
+{
+  posix_spawnattr_t attr;
+  short ps_flags = 0;
+  int retval;
+
+  retval = posix_spawnattr_init (&attr);
+  if (retval != 0)
+    {
+      fprintf_unfiltered
+        (gdb_stderr, "Cannot initialize attribute for posix_spawn\n");
+      return;
+    }
+
+  /* Do like execve: replace the image.  */
+  ps_flags = POSIX_SPAWN_SETEXEC;
+
+  /* Disable ASLR.  The constant doesn't look to be available outside the
+     kernel include files.  */
+#ifndef _POSIX_SPAWN_DISABLE_ASLR
+#define _POSIX_SPAWN_DISABLE_ASLR 0x0100
+#endif
+  ps_flags |= _POSIX_SPAWN_DISABLE_ASLR;
+  retval = posix_spawnattr_setflags (&attr, ps_flags);
+  if (retval != 0)
+    {
+      fprintf_unfiltered
+        (gdb_stderr, "Cannot set posix_spawn flags\n");
+      return;
+    }
+
+  posix_spawnp (NULL, argv[0], NULL, &attr, argv, env);
+}
+
+static void
 darwin_create_inferior (struct target_ops *ops, char *exec_file,
 			char *allargs, char **env, int from_tty)
 {
   /* Do the hard work.  */
   fork_inferior (exec_file, allargs, env, darwin_ptrace_me, darwin_ptrace_him,
-		 darwin_pre_ptrace, NULL);
+		 darwin_pre_ptrace, NULL, darwin_execvp);
 
   /* Return now in case of error.  */
   if (ptid_equal (inferior_ptid, null_ptid))
diff --git a/gdb/fork-child.c b/gdb/fork-child.c
index 5dbf1f7..e6408f4 100644
--- a/gdb/fork-child.c
+++ b/gdb/fork-child.c
@@ -115,6 +115,7 @@ escape_bang_in_quoted_argument (const char *shell_file)
    pid.  EXEC_FILE is the file to run.  ALLARGS is a string containing
    the arguments to the program.  ENV is the environment vector to
    pass.  SHELL_FILE is the shell file, or NULL if we should pick
+   one.  EXEC_FUN is the exec(2) function to use, or NULL for the default
    one.  */
 
 /* This function is NOT reentrant.  Some of the variables have been
@@ -123,7 +124,9 @@ escape_bang_in_quoted_argument (const char *shell_file)
 int
 fork_inferior (char *exec_file_arg, char *allargs, char **env,
 	       void (*traceme_fun) (void), void (*init_trace_fun) (int),
-	       void (*pre_trace_fun) (void), char *shell_file_arg)
+	       void (*pre_trace_fun) (void), char *shell_file_arg,
+               void (*exec_fun)(const char *file, char * const *argv,
+                                char * const *env))
 {
   int pid;
   static char default_shell_file[] = SHELL_FILE;
@@ -359,7 +362,10 @@ fork_inferior (char *exec_file_arg, char *allargs, char **env,
          path to find $SHELL.  Rich Pixley says so, and I agree.  */
       environ = env;
 
-      execvp (argv[0], argv);
+      if (exec_fun != NULL)
+        (*exec_fun) (argv[0], argv, env);
+      else
+        execvp (argv[0], argv);
 
       /* If we get here, it's an error.  */
       save_errno = errno;
diff --git a/gdb/gnu-nat.c b/gdb/gnu-nat.c
index 7269694..32f78be 100644
--- a/gdb/gnu-nat.c
+++ b/gdb/gnu-nat.c
@@ -2114,7 +2114,8 @@ gnu_create_inferior (struct target_ops *ops,
 
   inf_debug (inf, "creating inferior");
 
-  pid = fork_inferior (exec_file, allargs, env, trace_me, NULL, NULL, NULL);
+  pid = fork_inferior (exec_file, allargs, env, trace_me,
+                       NULL, NULL, NULL, NULL);
 
   /* Attach to the now stopped child, which is actually a shell...  */
   inf_debug (inf, "attaching to child: %d", pid);
diff --git a/gdb/inf-ptrace.c b/gdb/inf-ptrace.c
index b5e1744..110e825 100644
--- a/gdb/inf-ptrace.c
+++ b/gdb/inf-ptrace.c
@@ -134,7 +134,7 @@ inf_ptrace_create_inferior (struct target_ops *ops,
     }
 
   pid = fork_inferior (exec_file, allargs, env, inf_ptrace_me, NULL,
-		       NULL, NULL);
+		       NULL, NULL, NULL);
 
   if (! ops_already_pushed)
     discard_cleanups (back_to);
diff --git a/gdb/inf-ttrace.c b/gdb/inf-ttrace.c
index ab075db..0ab6580 100644
--- a/gdb/inf-ttrace.c
+++ b/gdb/inf-ttrace.c
@@ -650,7 +650,7 @@ inf_ttrace_create_inferior (struct target_ops *ops, char *exec_file,
   gdb_assert (inf_ttrace_vfork_ppid == -1);
 
   pid = fork_inferior (exec_file, allargs, env, inf_ttrace_me, NULL,
-		       inf_ttrace_prepare, NULL);
+		       inf_ttrace_prepare, NULL, NULL);
 
   inf_ttrace_him (ops, pid);
 }
diff --git a/gdb/inferior.h b/gdb/inferior.h
index 0815b65..8aca8dc 100644
--- a/gdb/inferior.h
+++ b/gdb/inferior.h
@@ -189,7 +189,9 @@ extern void terminal_init_inferior_with_pgrp (int pgrp);
 
 extern int fork_inferior (char *, char *, char **,
 			  void (*)(void),
-			  void (*)(int), void (*)(void), char *);
+			  void (*)(int), void (*)(void), char *,
+                          void (*)(const char *,
+                                   char * const *, char * const *));
 
 
 extern void startup_inferior (int);
diff --git a/gdb/procfs.c b/gdb/procfs.c
index 917e122..871dd47 100644
--- a/gdb/procfs.c
+++ b/gdb/procfs.c
@@ -4915,7 +4915,7 @@ procfs_create_inferior (struct target_ops *ops, char *exec_file,
     }
 
   pid = fork_inferior (exec_file, allargs, env, procfs_set_exec_trap,
-		       NULL, NULL, shell_file);
+		       NULL, NULL, shell_file, NULL);
 
   procfs_init_inferior (ops, pid);
 }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]