diff options
Diffstat (limited to 'gdb/gdbserver')
-rw-r--r-- | gdb/gdbserver/ChangeLog | 20 | ||||
-rw-r--r-- | gdb/gdbserver/config.in | 7 | ||||
-rwxr-xr-x | gdb/gdbserver/configure | 74 | ||||
-rw-r--r-- | gdb/gdbserver/configure.ac | 23 | ||||
-rw-r--r-- | gdb/gdbserver/linux-low.c | 50 | ||||
-rw-r--r-- | gdb/gdbserver/server.c | 32 | ||||
-rw-r--r-- | gdb/gdbserver/server.h | 2 | ||||
-rw-r--r-- | gdb/gdbserver/target.h | 7 |
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); |