From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6641 invoked by alias); 21 Sep 2011 13:46:29 -0000 Received: (qmail 6625 invoked by uid 22791); 21 Sep 2011 13:46:26 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL,BAYES_00 X-Spam-Check-By: sourceware.org Received: from mel.act-europe.fr (HELO mel.act-europe.fr) (194.98.77.210) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 21 Sep 2011 13:46:11 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 29FFBCB0361 for ; Wed, 21 Sep 2011 15:46:11 +0200 (CEST) Received: from mel.act-europe.fr ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id aRbtlcwDNvdW for ; Wed, 21 Sep 2011 15:46:00 +0200 (CEST) Received: from ulanbator.act-europe.fr (ulanbator.act-europe.fr [10.10.1.67]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (No client certificate requested) by mel.act-europe.fr (Postfix) with ESMTP id EAF84CB0350 for ; Wed, 21 Sep 2011 15:45:38 +0200 (CEST) From: Tristan Gingold Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable Subject: [RFA] Disable ASLR on Darwin Date: Wed, 21 Sep 2011 13:57:00 -0000 Message-Id: To: "gdb-patches@sourceware.org ml" Mime-Version: 1.0 (Apple Message framework v1244.3) X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2011-09/txt/msg00382.txt.bz2 Hi, this patch disable ASLR on Darwin for spawned programs, so that you can reu= se breakpoint/watchpoints with addresses. Also this adds support for PIE for free (as already noted by Pedro, this do= esn't handle attached processes). Contrary to other OS, this is done at exec (i.e. posix_spawn) time. In ord= er 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 * 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 #include #include +#include =20 #include #include @@ -1507,12 +1508,47 @@ darwin_ptrace_him (int pid) } =20 static void +darwin_execvp (const char *file, char * const argv[], char * const env[]) +{ + posix_spawnattr_t attr; + short ps_flags =3D 0; + int retval; + + retval =3D posix_spawnattr_init (&attr); + if (retval !=3D 0) + { + fprintf_unfiltered + (gdb_stderr, "Cannot initialize attribute for posix_spawn\n"); + return; + } + + /* Do like execve: replace the image. */ + ps_flags =3D 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 |=3D _POSIX_SPAWN_DISABLE_ASLR; + retval =3D posix_spawnattr_setflags (&attr, ps_flags); + if (retval !=3D 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); =20 /* 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. */ =20 /* 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[] =3D SHELL_FILE; @@ -359,7 +362,10 @@ fork_inferior (char *exec_file_arg, char *allargs, cha= r **env, path to find $SHELL. Rich Pixley says so, and I agree. */ environ =3D env; =20 - execvp (argv[0], argv); + if (exec_fun !=3D NULL) + (*exec_fun) (argv[0], argv, env); + else + execvp (argv[0], argv); =20 /* If we get here, it's an error. */ save_errno =3D 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, =20 inf_debug (inf, "creating inferior"); =20 - pid =3D fork_inferior (exec_file, allargs, env, trace_me, NULL, NULL, NU= LL); + pid =3D fork_inferior (exec_file, allargs, env, trace_me, + NULL, NULL, NULL, NULL); =20 /* 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, } =20 pid =3D fork_inferior (exec_file, allargs, env, inf_ptrace_me, NULL, - NULL, NULL); + NULL, NULL, NULL); =20 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, cha= r *exec_file, gdb_assert (inf_ttrace_vfork_ppid =3D=3D -1); =20 pid =3D fork_inferior (exec_file, allargs, env, inf_ttrace_me, NULL, - inf_ttrace_prepare, NULL); + inf_ttrace_prepare, NULL, NULL); =20 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); =20 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 *)); =20 =20 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, } =20 pid =3D fork_inferior (exec_file, allargs, env, procfs_set_exec_trap, - NULL, NULL, shell_file); + NULL, NULL, shell_file, NULL); =20 procfs_init_inferior (ops, pid); }