* inferior.h (disable_randomization): Declare.
authorUlrich Weigand <uweigand@de.ibm.com>
Fri, 7 Oct 2011 12:06:48 +0000 (12:06 +0000)
committerUlrich Weigand <uweigand@de.ibm.com>
Fri, 7 Oct 2011 12:06:48 +0000 (12:06 +0000)
* infrun.c (disable_randomization): New global variable.
(show_disable_randomization): New function.
(set_disable_randomization): Likewise.
(_initialize_infrun): Install set/show disable-randomization
commands.
* linux-nat.c (disable_randomization): Remove.
(show_disable_randomization): Likewise.
(set_disable_randomization): Likewise.
(_initialize_linux_nat): No longer install set/show
disable-randomization commands here.
(linux_nat_supports_disable_randomization): New function.
(linux_nat_add_target): Install it.
* remote.c (PACKET_QDisableRandomization): New enum value.
(remote_protocol_packets): Support QDisableRandomization.
(_initialize_remote): Likewise.
(remote_supports_disable_randomization): New function.
(init_remote_ops): Install it.
(extended_remote_supports_disable_randomization): New function.
(init_extended_remote_ops): Install it.
(extended_remote_disable_randomization): New function.
(extended_remote_create_inferior_1): Call it.
* target.h (struct target_ops): Add to_supports_disable_randomization.
(target_supports_disable_randomization): Add prototype.
* target.c (target_supports_disable_randomization): New function.
(find_default_supports_disable_randomization): Likewise.
(init_dummy_target): Install it.

doc/
* gdb.texinfo (Starting your Program): "set disable-randomization"
is no longer Linux-specific.
(Remote Configuration): Document "set remote
disable-randomization-packet".
(General Query Packets): Document "QDisableRandomization" packet
and add it to "qSupported" list.

gdbserver/
* 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.

17 files changed:
gdb/ChangeLog
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/gdbserver/ChangeLog
gdb/gdbserver/config.in
gdb/gdbserver/configure
gdb/gdbserver/configure.ac
gdb/gdbserver/linux-low.c
gdb/gdbserver/server.c
gdb/gdbserver/server.h
gdb/gdbserver/target.h
gdb/inferior.h
gdb/infrun.c
gdb/linux-nat.c
gdb/remote.c
gdb/target.c
gdb/target.h

index 0d06fdd..13bb992 100644 (file)
@@ -1,3 +1,33 @@
+2011-10-07  Ulrich Weigand  <ulrich.weigand@linaro.org>
+
+       * inferior.h (disable_randomization): Declare.
+       * infrun.c (disable_randomization): New global variable.
+       (show_disable_randomization): New function.
+       (set_disable_randomization): Likewise.
+       (_initialize_infrun): Install set/show disable-randomization
+       commands.
+       * linux-nat.c (disable_randomization): Remove.
+       (show_disable_randomization): Likewise.
+       (set_disable_randomization): Likewise.
+       (_initialize_linux_nat): No longer install set/show
+       disable-randomization commands here.
+       (linux_nat_supports_disable_randomization): New function.
+       (linux_nat_add_target): Install it.
+       * remote.c (PACKET_QDisableRandomization): New enum value.
+       (remote_protocol_packets): Support QDisableRandomization.
+       (_initialize_remote): Likewise.
+       (remote_supports_disable_randomization): New function.
+       (init_remote_ops): Install it.
+       (extended_remote_supports_disable_randomization): New function.
+       (init_extended_remote_ops): Install it.
+       (extended_remote_disable_randomization): New function.
+       (extended_remote_create_inferior_1): Call it.
+       * target.h (struct target_ops): Add to_supports_disable_randomization.
+       (target_supports_disable_randomization): Add prototype.
+       * target.c (target_supports_disable_randomization): New function.
+       (find_default_supports_disable_randomization): Likewise.
+       (init_dummy_target): Install it.
+
 2011-10-07  Kevin Pouget  <kevin.pouget@st.com>
 
        Allow Python notification of new object-file loadings.
index a6f8c81..398f347 100644 (file)
@@ -1,3 +1,12 @@
+2011-10-07  Ulrich Weigand  <ulrich.weigand@linaro.org>
+
+       * gdb.texinfo (Starting your Program): "set disable-randomization"
+       is no longer Linux-specific.
+       (Remote Configuration): Document "set remote
+       disable-randomization-packet".
+       (General Query Packets): Document "QDisableRandomization" packet
+       and add it to "qSupported" list.
+
 2011-10-07  Kevin Pouget  <kevin.pouget@st.com>
 
        Allow Python notification of new object-file loadings.
index aad877a..26f6216 100644 (file)
@@ -2044,8 +2044,8 @@ randomization of the virtual address space of the started program.  This option
 is useful for multiple debugging sessions to make the execution better
 reproducible and memory addresses reusable across debugging sessions.
 
-This feature is implemented only on @sc{gnu}/Linux.  You can get the same
-behavior using
+This feature is implemented only on certain targets, including @sc{gnu}/Linux.
+On @sc{gnu}/Linux you can get the same behavior using
 
 @smallexample
 (@value{GDBP}) set exec-wrapper setarch `uname -m` -R
@@ -2059,8 +2059,8 @@ disappears when you run the program under @value{GDBN}, that might be because
 as @sc{gnu}/Linux, which do that for stand-alone programs.  Use @kbd{set
 disable-randomization off} to try to reproduce such elusive bugs.
 
-The virtual address space randomization is implemented only on @sc{gnu}/Linux.
-It protects the programs against some kinds of security attacks.  In these
+On targets where it is available, virtual address space randomization
+protects the programs against certain kinds of security attacks.  In these
 cases the attacker needs to know the exact location of a concrete executable
 code.  Randomizing its location makes it impossible to inject jumps misusing
 a code at its expected addresses.
@@ -16906,6 +16906,10 @@ are:
 @item @code{traceframe-info}
 @tab @code{qXfer:traceframe-info:read}
 @tab Traceframe info
+
+@item @code{disable-randomization}
+@tab @code{QDisableRandomization}
+@tab @code{set disable-randomization}
 @end multitable
 
 @node Remote Stub
@@ -33534,6 +33538,38 @@ An error (such as memory fault)
 The specified memory region's checksum is @var{crc32}.
 @end table
 
+@item QDisableRandomization:@var{value}
+@cindex disable address space randomization, remote request
+@cindex @samp{QDisableRandomization} packet
+Some target operating systems will randomize the virtual address space
+of the inferior process as a security feature, but provide a feature
+to disable such randomization, e.g.@: to allow for a more deterministic
+debugging experience.  On such systems, this packet with a @var{value}
+of 1 directs the target to disable address space randomization for
+processes subsequently started via @samp{vRun} packets, while a packet
+with a @var{value} of 0 tells the target to enable address space
+randomization.
+
+This packet is only available in extended mode (@pxref{extended mode}).
+
+Reply:
+@table @samp
+@item OK
+The request succeeded.
+
+@item E @var{nn}
+An error occurred.  @var{nn} are hex digits.
+
+@item
+An empty reply indicates that @samp{QDisableRandomization} is not supported
+by the stub.
+@end table
+
+This packet is not probed by default; the remote stub must request it,
+by supplying an appropriate @samp{qSupported} response (@pxref{qSupported}).
+This should only be done on targets that actually support disabling
+address space randomization.
+
 @item qfThreadInfo
 @itemx qsThreadInfo
 @cindex list active threads, remote request
@@ -34037,6 +34073,11 @@ These are the currently defined stub features and their properties:
 @tab @samp{-}
 @tab No
 
+@item @samp{QDisableRandomization}
+@tab No
+@tab @samp{-}
+@tab No
+
 @item @samp{EnableDisableTracepoints}
 @tab No
 @tab @samp{-}
@@ -34154,6 +34195,9 @@ the source form of tracepoint definitions.
 @item QAllow
 The remote stub understands the @samp{QAllow} packet.
 
+@item QDisableRandomization
+The remote stub understands the @samp{QDisableRandomization} packet.
+
 @item StaticTracepoint
 @cindex static tracepoints, in remote protocol
 The remote stub supports static tracepoints.
index abd8fbe..eab3ac8 100644 (file)
@@ -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
index 65aa1ab..a9472ea 100644 (file)
 /* 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
 /* 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
 
index c350159..d92a00f 100755 (executable)
@@ -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=""
index 567d3ea..3a36c05 100644 (file)
@@ -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=""
index 5dfa59a..e8cf374 100644 (file)
 #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
index 79eeba5..5ba08ea 100644 (file)
@@ -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
index 7c682dc..e53c852 100644 (file)
@@ -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;
index 442dc91..8b241ff 100644 (file)
@@ -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);
index 8aca8dc..cfaea7f 100644 (file)
@@ -124,6 +124,10 @@ extern int non_stop;
    detached depends on 'set follow-fork-mode' setting.  */
 extern int detach_fork;
 
+/* When set (default), the target should attempt to disable the operating
+   system's address space randomization feature when starting an inferior.  */
+extern int disable_randomization;
+
 extern void generic_mourn_inferior (void);
 
 extern void terminal_save_ours (void);
index 225034c..cc2e29b 100644 (file)
@@ -147,6 +147,37 @@ show_debug_infrun (struct ui_file *file, int from_tty,
   fprintf_filtered (file, _("Inferior debugging is %s.\n"), value);
 }
 
+
+/* Support for disabling address space randomization.  */
+
+int disable_randomization = 1;
+
+static void
+show_disable_randomization (struct ui_file *file, int from_tty,
+                           struct cmd_list_element *c, const char *value)
+{
+  if (target_supports_disable_randomization ())
+    fprintf_filtered (file,
+                     _("Disabling randomization of debuggee's "
+                       "virtual address space is %s.\n"),
+                     value);
+  else
+    fputs_filtered (_("Disabling randomization of debuggee's "
+                     "virtual address space is unsupported on\n"
+                     "this platform.\n"), file);
+}
+
+static void
+set_disable_randomization (char *args, int from_tty,
+                          struct cmd_list_element *c)
+{
+  if (!target_supports_disable_randomization ())
+    error (_("Disabling randomization of debuggee's "
+            "virtual address space is unsupported on\n"
+            "this platform."));
+}
+
+
 /* If the program uses ELF-style shared libraries, then calls to
    functions in shared libraries go through stubs, which live in a
    table called the PLT (Procedure Linkage Table).  The first time the
@@ -7232,6 +7263,19 @@ Show whether gdb will detach the child of a fork."), _("\
 Tells gdb whether to detach the child of a fork."),
                           NULL, NULL, &setlist, &showlist);
 
+  /* Set/show disable address space randomization mode.  */
+
+  add_setshow_boolean_cmd ("disable-randomization", class_support,
+                          &disable_randomization, _("\
+Set disabling of debuggee's virtual address space randomization."), _("\
+Show disabling of debuggee's virtual address space randomization."), _("\
+When this mode is on (which is the default), randomization of the virtual\n\
+address space is disabled.  Standalone programs run with the randomization\n\
+enabled by default on some platforms."),
+                          &set_disable_randomization,
+                          &show_disable_randomization,
+                          &setlist, &showlist);
+
   /* ptid initializations */
   inferior_ptid = null_ptid;
   target_last_wait_ptid = minus_one_ptid;
index 9fcff9e..ef0837b 100644 (file)
@@ -200,35 +200,6 @@ show_debug_linux_nat (struct ui_file *file, int from_tty,
                    value);
 }
 
-static int disable_randomization = 1;
-
-static void
-show_disable_randomization (struct ui_file *file, int from_tty,
-                           struct cmd_list_element *c, const char *value)
-{
-#ifdef HAVE_PERSONALITY
-  fprintf_filtered (file,
-                   _("Disabling randomization of debuggee's "
-                     "virtual address space is %s.\n"),
-                   value);
-#else /* !HAVE_PERSONALITY */
-  fputs_filtered (_("Disabling randomization of debuggee's "
-                   "virtual address space is unsupported on\n"
-                   "this platform.\n"), file);
-#endif /* !HAVE_PERSONALITY */
-}
-
-static void
-set_disable_randomization (char *args, int from_tty,
-                          struct cmd_list_element *c)
-{
-#ifndef HAVE_PERSONALITY
-  error (_("Disabling randomization of debuggee's "
-          "virtual address space is unsupported on\n"
-          "this platform."));
-#endif /* !HAVE_PERSONALITY */
-}
-
 struct simple_pid_list
 {
   int pid;
@@ -5308,6 +5279,16 @@ linux_nat_supports_multi_process (void)
   return linux_multi_process;
 }
 
+static int
+linux_nat_supports_disable_randomization (void)
+{
+#ifdef HAVE_PERSONALITY
+  return 1;
+#else
+  return 0;
+#endif
+}
+
 static int async_terminal_is_ours = 1;
 
 /* target_terminal_inferior implementation.  */
@@ -5677,6 +5658,9 @@ linux_nat_add_target (struct target_ops *t)
 
   t->to_supports_multi_process = linux_nat_supports_multi_process;
 
+  t->to_supports_disable_randomization
+    = linux_nat_supports_disable_randomization;
+
   t->to_core_of_thread = linux_nat_core_of_thread;
 
   /* We don't change the stratum; this target will sit at
@@ -5762,17 +5746,6 @@ Enables printf debugging output."),
   sigdelset (&suspend_mask, SIGCHLD);
 
   sigemptyset (&blocked_mask);
-
-  add_setshow_boolean_cmd ("disable-randomization", class_support,
-                          &disable_randomization, _("\
-Set disabling of debuggee's virtual address space randomization."), _("\
-Show disabling of debuggee's virtual address space randomization."), _("\
-When this mode is on (which is the default), randomization of the virtual\n\
-address space is disabled.  Standalone programs run with the randomization\n\
-enabled by default on some platforms."),
-                          &set_disable_randomization,
-                          &show_disable_randomization,
-                          &setlist, &showlist);
 }
 \f
 
index 1c9e965..32e68f3 100644 (file)
@@ -1263,6 +1263,7 @@ enum {
   PACKET_TracepointSource,
   PACKET_QAllow,
   PACKET_qXfer_fdpic,
+  PACKET_QDisableRandomization,
   PACKET_MAX
 };
 
@@ -3761,6 +3762,8 @@ static struct protocol_feature remote_protocol_features[] = {
     remote_enable_disable_tracepoint_feature, -1 },
   { "qXfer:fdpic:read", PACKET_DISABLE, remote_supported_packet,
     PACKET_qXfer_fdpic },
+  { "QDisableRandomization", PACKET_DISABLE, remote_supported_packet,
+    PACKET_QDisableRandomization },
 };
 
 static char *remote_support_xml;
@@ -7484,6 +7487,28 @@ extended_remote_mourn (struct target_ops *ops)
 }
 
 static int
+extended_remote_supports_disable_randomization (void)
+{
+  return (remote_protocol_packets[PACKET_QDisableRandomization].support
+         == PACKET_ENABLE);
+}
+
+static void
+extended_remote_disable_randomization (int val)
+{
+  struct remote_state *rs = get_remote_state ();
+  char *reply;
+
+  sprintf (rs->buf, "QDisableRandomization:%x", val);
+  putpkt (rs->buf);
+  reply = remote_get_noisy_reply (&target_buf, &target_buf_size);
+  if (*reply == '\0')
+    error (_("Target does not support QDisableRandomization."));
+  if (strcmp (reply, "OK") != 0)
+    error (_("Bogus QDisableRandomization reply from target: %s"), reply);
+}
+
+static int
 extended_remote_run (char *args)
 {
   struct remote_state *rs = get_remote_state ();
@@ -7559,6 +7584,10 @@ extended_remote_create_inferior_1 (char *exec_file, char *args,
   if (target_can_async_p ())
     target_async (inferior_event_handler, 0);
 
+  /* Disable address space randomization if requested (and supported).  */
+  if (extended_remote_supports_disable_randomization ())
+    extended_remote_disable_randomization (disable_randomization);
+
   /* Now restart the remote server.  */
   if (extended_remote_run (args) == -1)
     {
@@ -9665,6 +9694,13 @@ remote_supports_non_stop (void)
 }
 
 static int
+remote_supports_disable_randomization (void)
+{
+  /* Only supported in extended mode.  */
+  return 0;
+}
+
+static int
 remote_supports_multi_process (void)
 {
   struct remote_state *rs = get_remote_state ();
@@ -10420,6 +10456,8 @@ Specify the serial device it is connected to\n\
   remote_ops.to_terminal_ours = remote_terminal_ours;
   remote_ops.to_supports_non_stop = remote_supports_non_stop;
   remote_ops.to_supports_multi_process = remote_supports_multi_process;
+  remote_ops.to_supports_disable_randomization
+    = remote_supports_disable_randomization;
   remote_ops.to_supports_enable_disable_tracepoint = remote_supports_enable_disable_tracepoint;
   remote_ops.to_trace_init = remote_trace_init;
   remote_ops.to_download_tracepoint = remote_download_tracepoint;
@@ -10472,6 +10510,8 @@ Specify the serial device it is connected to (e.g. /dev/ttya).";
   extended_remote_ops.to_detach = extended_remote_detach;
   extended_remote_ops.to_attach = extended_remote_attach;
   extended_remote_ops.to_kill = extended_remote_kill;
+  extended_remote_ops.to_supports_disable_randomization
+    = extended_remote_supports_disable_randomization;
 }
 
 static int
@@ -10944,6 +10984,9 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
   add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_fdpic],
                         "qXfer:fdpic:read", "read-fdpic-loadmap", 0);
 
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_QDisableRandomization],
+                        "QDisableRandomization", "disable-randomization", 0);
+
   /* Keep the old ``set remote Z-packet ...'' working.  Each individual
      Z sub-packet has its own set and show commands, but users may
      have sets to this variable in their .gdbinit files (or in their
index 7fa891a..e6328a1 100644 (file)
@@ -3013,6 +3013,28 @@ target_supports_non_stop (void)
   return 0;
 }
 
+static int
+find_default_supports_disable_randomization (void)
+{
+  struct target_ops *t;
+
+  t = find_default_run_target (NULL);
+  if (t && t->to_supports_disable_randomization)
+    return (t->to_supports_disable_randomization) ();
+  return 0;
+}
+
+int
+target_supports_disable_randomization (void)
+{
+  struct target_ops *t;
+
+  for (t = &current_target; t != NULL; t = t->beneath)
+    if (t->to_supports_disable_randomization)
+      return t->to_supports_disable_randomization ();
+
+  return 0;
+}
 
 char *
 target_get_osdata (const char *type)
@@ -3257,6 +3279,8 @@ init_dummy_target (void)
   dummy_target.to_can_async_p = find_default_can_async_p;
   dummy_target.to_is_async_p = find_default_is_async_p;
   dummy_target.to_supports_non_stop = find_default_supports_non_stop;
+  dummy_target.to_supports_disable_randomization
+    = find_default_supports_disable_randomization;
   dummy_target.to_pid_to_str = dummy_pid_to_str;
   dummy_target.to_stratum = dummy_stratum;
   dummy_target.to_find_memory_regions = dummy_find_memory_regions;
index 173e60b..1adcf46 100644 (file)
@@ -653,6 +653,9 @@ struct target_ops
        experiment is running?  */
     int (*to_supports_enable_disable_tracepoint) (void);
 
+    /* Does this target support disabling address space randomization?  */
+    int (*to_supports_disable_randomization) (void);
+
     /* Determine current architecture of thread PTID.
 
        The target is supposed to determine the architecture of the code where
@@ -888,6 +891,10 @@ struct address_space *target_thread_address_space (ptid_t);
 #define        target_supports_multi_process() \
      (*current_target.to_supports_multi_process) ()
 
+/* Returns true if this target can disable address space randomization.  */
+
+int target_supports_disable_randomization (void);
+
 /* Returns true if this target can enable and disable tracepoints
    while a trace experiment is running.  */