Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Tristan Gingold <gingold@adacore.com>
To: "gdb-patches@sourceware.org ml" <gdb-patches@sourceware.org>
Subject: [RFA] Disable ASLR on Darwin
Date: Wed, 21 Sep 2011 13:57:00 -0000	[thread overview]
Message-ID: <EDAE3865-56A4-4962-9E29-FF1353DBC11A@adacore.com> (raw)

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);
 }


             reply	other threads:[~2011-09-21 13:46 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-09-21 13:57 Tristan Gingold [this message]
2011-09-21 14:36 ` Pedro Alves
2011-09-21 15:07   ` Pedro Alves
2011-09-22 11:47   ` Tristan Gingold

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=EDAE3865-56A4-4962-9E29-FF1353DBC11A@adacore.com \
    --to=gingold@adacore.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox