aboutsummaryrefslogtreecommitdiff
path: root/gdb/gdbserver
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/gdbserver')
-rw-r--r--gdb/gdbserver/ChangeLog20
-rw-r--r--gdb/gdbserver/config.in7
-rwxr-xr-xgdb/gdbserver/configure74
-rw-r--r--gdb/gdbserver/configure.ac23
-rw-r--r--gdb/gdbserver/linux-low.c50
-rw-r--r--gdb/gdbserver/server.c32
-rw-r--r--gdb/gdbserver/server.h2
-rw-r--r--gdb/gdbserver/target.h7
8 files changed, 214 insertions, 1 deletions
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index abd8fbe..eab3ac8 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,3 +1,23 @@
+2011-10-07 Ulrich Weigand <ulrich.weigand@linaro.org>
+
+ * configure.ac: Check support for personality routine.
+ * configure: Regenerate.
+ * config.in: Likewise.
+ * linux-low.c: Include <sys/personality.h>.
+ Define ADDR_NO_RANDOMIZE if necessary.
+ (linux_create_inferior): Disable address space randomization when
+ forking inferior, if requested.
+ (linux_supports_disable_randomization): New function.
+ (linux_target_ops): Install it.
+ * server.h (disable_randomization): Declare.
+ * server.c (disable_randomization): New global variable.
+ (handle_general_set): Handle QDisableRandomization.
+ (handle_query): Likewise for qSupported.
+ (main): Support --disable-randomization and --no-disable-randomization
+ command line arguments.
+ * target.h (struct target_ops): Add supports_disable_randomization.
+ (target_supports_disable_randomization): New macro.
+
2011-09-29 Mike Frysinger <vapier@gentoo.org>
* linux-low.c (target_loadseg): Add defined PTRACE_GETFDPIC to the
diff --git a/gdb/gdbserver/config.in b/gdb/gdbserver/config.in
index 65aa1ab..a9472ea 100644
--- a/gdb/gdbserver/config.in
+++ b/gdb/gdbserver/config.in
@@ -18,6 +18,10 @@
/* Define to 1 if you have the <arpa/inet.h> header file. */
#undef HAVE_ARPA_INET_H
+/* Define to 1 if you have the declaration of `ADDR_NO_RANDOMIZE', and to 0 if
+ you don't. */
+#undef HAVE_DECL_ADDR_NO_RANDOMIZE
+
/* Define to 1 if you have the declaration of `memmem', and to 0 if you don't.
*/
#undef HAVE_DECL_MEMMEM
@@ -96,6 +100,9 @@
/* Define to 1 if you have the <netinet/tcp.h> header file. */
#undef HAVE_NETINET_TCP_H
+/* Define if you support the personality syscall. */
+#undef HAVE_PERSONALITY
+
/* Define to 1 if you have the `pread' function. */
#undef HAVE_PREAD
diff --git a/gdb/gdbserver/configure b/gdb/gdbserver/configure
index c350159..d92a00f 100755
--- a/gdb/gdbserver/configure
+++ b/gdb/gdbserver/configure
@@ -5066,6 +5066,80 @@ fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
CFLAGS="$saved_cflags"
+ac_fn_c_check_decl "$LINENO" "ADDR_NO_RANDOMIZE" "ac_cv_have_decl_ADDR_NO_RANDOMIZE" "#include <sys/personality.h>
+"
+if test "x$ac_cv_have_decl_ADDR_NO_RANDOMIZE" = x""yes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_ADDR_NO_RANDOMIZE $ac_have_decl
+_ACEOF
+
+
+if test "$cross_compiling" = yes; then :
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/personality.h>
+int
+main ()
+{
+
+# if !HAVE_DECL_ADDR_NO_RANDOMIZE
+# define ADDR_NO_RANDOMIZE 0x0040000
+# endif
+ /* Test the flag could be set and stays set. */
+ personality (personality (0xffffffff) | ADDR_NO_RANDOMIZE);
+ if (!(personality (personality (0xffffffff)) & ADDR_NO_RANDOMIZE))
+ return 1
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gdbsrv_cv_have_personality=true
+else
+ gdbsrv_cv_have_personality=false
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/personality.h>
+int
+main ()
+{
+
+# if !HAVE_DECL_ADDR_NO_RANDOMIZE
+# define ADDR_NO_RANDOMIZE 0x0040000
+# endif
+ /* Test the flag could be set and stays set. */
+ personality (personality (0xffffffff) | ADDR_NO_RANDOMIZE);
+ if (!(personality (personality (0xffffffff)) & ADDR_NO_RANDOMIZE))
+ return 1
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ gdbsrv_cv_have_personality=true
+else
+ gdbsrv_cv_have_personality=false
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+if $gdbsrv_cv_have_personality
+then
+
+$as_echo "#define HAVE_PERSONALITY 1" >>confdefs.h
+
+fi
+
IPA_DEPFILES=""
extra_libraries=""
diff --git a/gdb/gdbserver/configure.ac b/gdb/gdbserver/configure.ac
index 567d3ea..3a36c05 100644
--- a/gdb/gdbserver/configure.ac
+++ b/gdb/gdbserver/configure.ac
@@ -358,6 +358,29 @@ AC_COMPILE_IFELSE(AC_LANG_PROGRAM([]),
[gdbsrv_cv_have_visibility_hidden=no])
CFLAGS="$saved_cflags"
+dnl Check if we can disable the virtual address space randomization.
+dnl The functionality of setarch -R.
+AC_CHECK_DECLS([ADDR_NO_RANDOMIZE],,, [#include <sys/personality.h>])
+define([PERSONALITY_TEST], [AC_LANG_PROGRAM([#include <sys/personality.h>], [
+# if !HAVE_DECL_ADDR_NO_RANDOMIZE
+# define ADDR_NO_RANDOMIZE 0x0040000
+# endif
+ /* Test the flag could be set and stays set. */
+ personality (personality (0xffffffff) | ADDR_NO_RANDOMIZE);
+ if (!(personality (personality (0xffffffff)) & ADDR_NO_RANDOMIZE))
+ return 1])])
+AC_RUN_IFELSE([PERSONALITY_TEST],
+ [gdbsrv_cv_have_personality=true],
+ [gdbsrv_cv_have_personality=false],
+ [AC_LINK_IFELSE([PERSONALITY_TEST],
+ [gdbsrv_cv_have_personality=true],
+ [gdbsrv_cv_have_personality=false])])
+if $gdbsrv_cv_have_personality
+then
+ AC_DEFINE([HAVE_PERSONALITY], 1,
+ [Define if you support the personality syscall.])
+fi
+
IPA_DEPFILES=""
extra_libraries=""
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 5dfa59a..e8cf374 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -55,6 +55,13 @@
#define SPUFS_MAGIC 0x23c9b64e
#endif
+#ifdef HAVE_PERSONALITY
+# include <sys/personality.h>
+# if !HAVE_DECL_ADDR_NO_RANDOMIZE
+# define ADDR_NO_RANDOMIZE 0x0040000
+# endif
+#endif
+
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
#endif
@@ -520,10 +527,30 @@ add_lwp (ptid_t ptid)
static int
linux_create_inferior (char *program, char **allargs)
{
+#ifdef HAVE_PERSONALITY
+ int personality_orig = 0, personality_set = 0;
+#endif
struct lwp_info *new_lwp;
int pid;
ptid_t ptid;
+#ifdef HAVE_PERSONALITY
+ if (disable_randomization)
+ {
+ errno = 0;
+ personality_orig = personality (0xffffffff);
+ if (errno == 0 && !(personality_orig & ADDR_NO_RANDOMIZE))
+ {
+ personality_set = 1;
+ personality (personality_orig | ADDR_NO_RANDOMIZE);
+ }
+ if (errno != 0 || (personality_set
+ && !(personality (0xffffffff) & ADDR_NO_RANDOMIZE)))
+ warning ("Error disabling address space randomization: %s",
+ strerror (errno));
+ }
+#endif
+
#if defined(__UCLIBC__) && defined(HAS_NOMMU)
pid = vfork ();
#else
@@ -552,6 +579,17 @@ linux_create_inferior (char *program, char **allargs)
_exit (0177);
}
+#ifdef HAVE_PERSONALITY
+ if (personality_set)
+ {
+ errno = 0;
+ personality (personality_orig);
+ if (errno != 0)
+ warning ("Error restoring address space randomization: %s",
+ strerror (errno));
+ }
+#endif
+
linux_add_process (pid, 0);
ptid = ptid_build (pid, pid, 0);
@@ -4633,6 +4671,15 @@ linux_supports_multi_process (void)
return 1;
}
+static int
+linux_supports_disable_randomization (void)
+{
+#ifdef HAVE_PERSONALITY
+ return 1;
+#else
+ return 0;
+#endif
+}
/* Enumerate spufs IDs for process PID. */
static int
@@ -4965,7 +5012,8 @@ static struct target_ops linux_target_ops = {
linux_cancel_breakpoints,
linux_stabilize_threads,
linux_install_fast_tracepoint_jump_pad,
- linux_emit_ops
+ linux_emit_ops,
+ linux_supports_disable_randomization,
};
static void
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index 79eeba5..5ba08ea 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -45,6 +45,10 @@ int run_once;
int multi_process;
int non_stop;
+/* Whether we should attempt to disable the operating system's address
+ space randomization feature before starting an inferior. */
+int disable_randomization = 1;
+
static char **program_argv, **wrapper_argv;
/* Enable miscellaneous debugging output. The name is historical - it
@@ -497,6 +501,27 @@ handle_general_set (char *own_buf)
return;
}
+ if (strncmp ("QDisableRandomization:", own_buf,
+ strlen ("QDisableRandomization:")) == 0)
+ {
+ char *packet = own_buf + strlen ("QDisableRandomization:");
+ ULONGEST setting;
+
+ unpack_varlen_hex (packet, &setting);
+ disable_randomization = setting;
+
+ if (remote_debug)
+ {
+ if (disable_randomization)
+ fprintf (stderr, "[address space randomization disabled]\n");
+ else
+ fprintf (stderr, "[address space randomization enabled]\n");
+ }
+
+ write_ok (own_buf);
+ return;
+ }
+
if (target_supports_tracepoints ()
&& handle_tracepoint_general_set (own_buf))
return;
@@ -1545,6 +1570,9 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
if (target_supports_non_stop ())
strcat (own_buf, ";QNonStop+");
+ if (target_supports_disable_randomization ())
+ strcat (own_buf, ";QDisableRandomization+");
+
strcat (own_buf, ";qXfer:threads:read+");
if (target_supports_tracepoints ())
@@ -2549,6 +2577,10 @@ main (int argc, char *argv[])
}
}
}
+ else if (strcmp (*next_arg, "--disable-randomization") == 0)
+ disable_randomization = 1;
+ else if (strcmp (*next_arg, "--no-disable-randomization") == 0)
+ disable_randomization = 0;
else if (strcmp (*next_arg, "--once") == 0)
run_once = 1;
else
diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h
index 7c682dc..e53c852 100644
--- a/gdb/gdbserver/server.h
+++ b/gdb/gdbserver/server.h
@@ -299,6 +299,8 @@ extern int run_once;
extern int multi_process;
extern int non_stop;
+extern int disable_randomization;
+
#if USE_WIN32API
#include <winsock2.h>
typedef SOCKET gdb_fildes_t;
diff --git a/gdb/gdbserver/target.h b/gdb/gdbserver/target.h
index 442dc91..8b241ff 100644
--- a/gdb/gdbserver/target.h
+++ b/gdb/gdbserver/target.h
@@ -377,6 +377,9 @@ struct target_ops
/* Return the bytecode operations vector for the current inferior.
Returns NULL if bytecode compilation is not supported. */
struct emit_ops *(*emit_ops) (void);
+
+ /* Returns true if the target supports disabling randomization. */
+ int (*supports_disable_randomization) (void);
};
extern struct target_ops *the_target;
@@ -483,6 +486,10 @@ void set_target_ops (struct target_ops *);
#define target_emit_ops() \
(the_target->emit_ops ? (*the_target->emit_ops) () : NULL)
+#define target_supports_disable_randomization() \
+ (the_target->supports_disable_randomization ? \
+ (*the_target->supports_disable_randomization) () : 0)
+
/* Start non-stop mode, returns 0 on success, -1 on failure. */
int start_non_stop (int nonstop);