From: Ulrich Weigand Date: Fri, 7 Oct 2011 12:06:48 +0000 (+0000) Subject: * inferior.h (disable_randomization): Declare. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=03583c206f350870e077f4e112f83b3c4bdd0b27;p=binutils-gdb.git * 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. 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 . 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. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 0d06fdd0174..13bb992e7aa 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,33 @@ +2011-10-07 Ulrich Weigand + + * 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 Allow Python notification of new object-file loadings. diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index a6f8c8187a6..398f3472148 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,12 @@ +2011-10-07 Ulrich Weigand + + * 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 Allow Python notification of new object-file loadings. diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index aad877a582c..26f6216eb86 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -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. diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index abd8fbe1bdc..eab3ac8b7d9 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,3 +1,23 @@ +2011-10-07 Ulrich Weigand + + * configure.ac: Check support for personality routine. + * configure: Regenerate. + * config.in: Likewise. + * linux-low.c: Include . + 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 * linux-low.c (target_loadseg): Add defined PTRACE_GETFDPIC to the diff --git a/gdb/gdbserver/config.in b/gdb/gdbserver/config.in index 65aa1ab098e..a9472eaa4fc 100644 --- a/gdb/gdbserver/config.in +++ b/gdb/gdbserver/config.in @@ -18,6 +18,10 @@ /* Define to 1 if you have the 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 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 c350159e23e..d92a00f3c0e 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 +" +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 +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 +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 567d3ea7e81..3a36c05fc20 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 ]) +define([PERSONALITY_TEST], [AC_LANG_PROGRAM([#include ], [ +# 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 5dfa59aeebb..e8cf3746352 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 +# 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 79eeba55e44..5ba08eada6e 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 7c682dcca77..e53c852f77e 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 typedef SOCKET gdb_fildes_t; diff --git a/gdb/gdbserver/target.h b/gdb/gdbserver/target.h index 442dc913a8a..8b241ff9c71 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); diff --git a/gdb/inferior.h b/gdb/inferior.h index 8aca8dc6522..cfaea7f0d00 100644 --- a/gdb/inferior.h +++ b/gdb/inferior.h @@ -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); diff --git a/gdb/infrun.c b/gdb/infrun.c index 225034c8978..cc2e29b8bd1 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -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; diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index 9fcff9e5605..ef0837bd338 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -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); } diff --git a/gdb/remote.c b/gdb/remote.c index 1c9e96508f7..32e68f3d16d 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -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 diff --git a/gdb/target.c b/gdb/target.c index 7fa891a083a..e6328a12258 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -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 = ¤t_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; diff --git a/gdb/target.h b/gdb/target.h index 173e60bd549..1adcf4643e8 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -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. */