]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
* 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 0d06fdd0174f23136f4878063a8d6e02d9155e0b..13bb992e7aacdecdf221fb0bb55c7e2c48640ee6 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 a6f8c8187a65daa21fc487b11346c7d35fa398a0..398f3472148fb84da6f20e336f944ead3efaabb0 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 aad877a582cf1c327e40746635396bcc2cf769a0..26f6216eb86b9ab4968585de302e7d3a32d98c02 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 abd8fbe1bdcd9c7da6ce9a006fbbfaea4b5aa37c..eab3ac8b7d99b1a462e84210831a2e88e7f7167f 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 65aa1ab098ef0aa1fa71dd8b5bee2faff8cec021..a9472eaa4fc3c52c1c16d202924af5ff398f39ad 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 c350159e23e4a2bcc7789f60b07f4aca180c7b6b..d92a00f3c0edb4cd0de678ded8d19b648fc729e2 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 567d3ea7e81e54897aad8d9c13639f085bb1c78a..3a36c05fc205e71f6acff740c246ab2f68fb450f 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 5dfa59aeebbd4ba89b1fef78360f82c3b9aee036..e8cf3746352eba0d03d966397b4d8f3fc14f563d 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 79eeba55e44426f0e1de08165182e42f4c5624de..5ba08eada6ee8c54f44bc5d1c2911fe8cebb726d 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 7c682dcca778c72b418f7dba0c8f18813a4f1388..e53c852f77ea65b995a947ef87816eea58ad8ce6 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 442dc913a8a082abf36a49d70adb9a2e5e0a0b53..8b241ff9c71f52ef6096626706092206a4747809 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 8aca8dc65227c67181bc9740ee232e6cdb045e07..cfaea7f0d003c1eaaba5e1045f0edeb977dbee0e 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 225034c89782bfd6bdb1cb2646207487e6094056..cc2e29b8bd13b20217fab71627283938fd0ecc9b 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 9fcff9e5605b81d8910cc9c0e1ab2976a9720f93..ef0837bd3381a248bcae2c9d9afd5e6ba76dbc45 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 1c9e96508f73be01786aa6e7130ca6f4e914875c..32e68f3d16dc2b71af9c86e04e70b34850497287 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;
@@ -7483,6 +7486,28 @@ extended_remote_mourn (struct target_ops *ops)
   extended_remote_mourn_1 (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)
 {
@@ -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)
     {
@@ -9664,6 +9693,13 @@ remote_supports_non_stop (void)
   return 1;
 }
 
+static int
+remote_supports_disable_randomization (void)
+{
+  /* Only supported in extended mode.  */
+  return 0;
+}
+
 static int
 remote_supports_multi_process (void)
 {
@@ -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 7fa891a083a91653989469cce858308250ce64da..e6328a1225887d399a330b13d9f11aeccd37c643 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 173e60bd549949321d10e135d5727d86c3f3bcca..1adcf4643e893f4d7ce39c4648b54cb41744e87d 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.  */