Added the ability to disable ASLR (Address Space Layout Randomization). ASLR
is disabled by default, and can be enabled using:
(lldb) set disable-aslr 0
llvm-svn: 112616
diff --git a/lldb/tools/debugserver/source/DNB.cpp b/lldb/tools/debugserver/source/DNB.cpp
index 72a111b..ce7670c 100644
--- a/lldb/tools/debugserver/source/DNB.cpp
+++ b/lldb/tools/debugserver/source/DNB.cpp
@@ -177,10 +177,11 @@
const char *envp[],
const char *stdio_path,
nub_launch_flavor_t launch_flavor,
+ int disable_aslr,
char *err_str,
size_t err_len)
{
- DNBLogThreadedIf(LOG_PROCESS, "%s ( path='%s', argv = %p, envp = %p, launch_flavor = %u, err = %p, err_len = %zu) called...", __FUNCTION__, path, argv, envp, launch_flavor, err_str, err_len);
+ DNBLogThreadedIf(LOG_PROCESS, "%s ( path='%s', argv = %p, envp = %p, launch_flavor = %u, disable_aslr = %d, err = %p, err_len = %zu) called...", __FUNCTION__, path, argv, envp, launch_flavor, disable_aslr, err_str, err_len);
if (err_str && err_len > 0)
err_str[0] = '\0';
@@ -197,7 +198,7 @@
if (processSP.get())
{
DNBError launch_err;
- pid_t pid = processSP->LaunchForDebug(path, argv, envp, stdio_path, launch_flavor, launch_err);
+ pid_t pid = processSP->LaunchForDebug(path, argv, envp, stdio_path, launch_flavor, disable_aslr, launch_err);
if (err_str)
{
*err_str = '\0';
diff --git a/lldb/tools/debugserver/source/DNB.h b/lldb/tools/debugserver/source/DNB.h
index 55a039e..4dadff2 100644
--- a/lldb/tools/debugserver/source/DNB.h
+++ b/lldb/tools/debugserver/source/DNB.h
@@ -28,7 +28,7 @@
//----------------------------------------------------------------------
// Process control
//----------------------------------------------------------------------
-nub_process_t DNBProcessLaunch (const char *path, char const *argv[], const char *envp[], const char *stdio_path, nub_launch_flavor_t launch_flavor, char *err_str, size_t err_len) DNB_EXPORT;
+nub_process_t DNBProcessLaunch (const char *path, char const *argv[], const char *envp[], const char *stdio_path, nub_launch_flavor_t launch_flavor, int disable_aslr, char *err_str, size_t err_len) DNB_EXPORT;
nub_process_t DNBProcessAttach (nub_process_t pid, struct timespec *timeout, char *err_str, size_t err_len) DNB_EXPORT;
nub_process_t DNBProcessAttachByName (const char *name, struct timespec *timeout, char *err_str, size_t err_len) DNB_EXPORT;
nub_process_t DNBProcessAttachWait (const char *wait_name, nub_launch_flavor_t launch_flavor, struct timespec *timeout, useconds_t interval, char *err_str, size_t err_len, DNBShouldCancelCallback should_cancel = NULL, void *callback_data = NULL) DNB_EXPORT;
diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp b/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp
index a0d7d35..2eb371f 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp
@@ -85,6 +85,9 @@
#define MACH_PROCESS_USE_POSIX_SPAWN 1
#endif
+#ifndef _POSIX_SPAWN_DISABLE_ASLR
+#define _POSIX_SPAWN_DISABLE_ASLR 0x0100
+#endif
MachProcess::MachProcess() :
m_pid (0),
@@ -1457,13 +1460,14 @@
char const *envp[],
const char *stdio_path,
nub_launch_flavor_t launch_flavor,
+ int disable_aslr,
DNBError &launch_err
)
{
// Clear out and clean up from any current state
Clear();
- DNBLogThreadedIf(LOG_PROCESS, "%s( path = '%s', argv = %p, envp = %p, launch_flavor = %u )", __FUNCTION__, path, argv, envp, launch_flavor);
+ DNBLogThreadedIf(LOG_PROCESS, "%s( path = '%s', argv = %p, envp = %p, launch_flavor = %u, disable_aslr = %d )", __FUNCTION__, path, argv, envp, launch_flavor, disable_aslr);
// Fork a child process for debugging
SetState(eStateLaunching);
@@ -1475,7 +1479,7 @@
break;
case eLaunchFlavorPosixSpawn:
- m_pid = MachProcess::PosixSpawnChildForPTraceDebugging (path, argv, envp, stdio_path, this, launch_err);
+ m_pid = MachProcess::PosixSpawnChildForPTraceDebugging (path, argv, envp, stdio_path, this, disable_aslr, launch_err);
break;
#if defined (__arm__)
@@ -1562,10 +1566,12 @@
char const *envp[],
const char *stdio_path,
MachProcess* process,
+ int disable_aslr,
DNBError& err
)
{
posix_spawnattr_t attr;
+ short flags;
DNBLogThreadedIf(LOG_PROCESS, "%s ( path='%s', argv=%p, envp=%p, process )", __FUNCTION__, path, argv, envp);
err.SetError( ::posix_spawnattr_init (&attr), DNBError::POSIX);
@@ -1574,9 +1580,13 @@
if (err.Fail())
return INVALID_NUB_PROCESS;
- err.SetError( ::posix_spawnattr_setflags (&attr, POSIX_SPAWN_START_SUSPENDED), DNBError::POSIX);
+ flags = POSIX_SPAWN_START_SUSPENDED;
+ if (disable_aslr)
+ flags |= _POSIX_SPAWN_DISABLE_ASLR;
+
+ err.SetError( ::posix_spawnattr_setflags (&attr, flags), DNBError::POSIX);
if (err.Fail() || DNBLogCheckLogBit(LOG_PROCESS))
- err.LogThreaded("::posix_spawnattr_setflags ( &attr, POSIX_SPAWN_START_SUSPENDED )");
+ err.LogThreaded("::posix_spawnattr_setflags ( &attr, POSIX_SPAWN_START_SUSPENDED%s )", flags & _POSIX_SPAWN_DISABLE_ASLR ? " | _POSIX_SPAWN_DISABLE_ASLR" : "");
if (err.Fail())
return INVALID_NUB_PROCESS;
@@ -1585,13 +1595,6 @@
// On SnowLeopard we should set "DYLD_NO_PIE" in the inferior environment....
-//#ifndef _POSIX_SPAWN_DISABLE_ASLR
-//#define _POSIX_SPAWN_DISABLE_ASLR 0x0100
-//#endif
-// err.SetError( ::posix_spawnattr_setflags (&attr, _POSIX_SPAWN_DISABLE_ASLR), DNBError::POSIX);
-// if (err.Fail() || DNBLogCheckLogBit(LOG_PROCESS))
-// err.LogThreaded("::posix_spawnattr_setflags ( &attr, _POSIX_SPAWN_DISABLE_ASLR )");
-
#if !defined(__arm__)
// We don't need to do this for ARM, and we really shouldn't now that we
diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.h b/lldb/tools/debugserver/source/MacOSX/MachProcess.h
index ddab00e..533cb2eb 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachProcess.h
+++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.h
@@ -46,9 +46,9 @@
// Child process control
//----------------------------------------------------------------------
pid_t AttachForDebug (pid_t pid, char *err_str, size_t err_len);
- pid_t LaunchForDebug (const char *path, char const *argv[], char const *envp[], const char *stdio_path, nub_launch_flavor_t launch_flavor, DNBError &err);
+ pid_t LaunchForDebug (const char *path, char const *argv[], char const *envp[], const char *stdio_path, nub_launch_flavor_t launch_flavor, int disable_aslr, DNBError &err);
static pid_t ForkChildForPTraceDebugging (const char *path, char const *argv[], char const *envp[], MachProcess* process, DNBError &err);
- static pid_t PosixSpawnChildForPTraceDebugging (const char *path, char const *argv[], char const *envp[], const char *stdio_path, MachProcess* process, DNBError& err);
+ static pid_t PosixSpawnChildForPTraceDebugging (const char *path, char const *argv[], char const *envp[], const char *stdio_path, MachProcess* process, int disable_aslr, DNBError& err);
nub_addr_t GetDYLDAllImageInfosAddress ();
static const void * PrepareForAttach (const char *path, nub_launch_flavor_t launch_flavor, bool waitfor, DNBError &err_str);
static void CleanupAfterAttach (const void *attach_token, bool success, DNBError &err_str);
diff --git a/lldb/tools/debugserver/source/debugserver.cpp b/lldb/tools/debugserver/source/debugserver.cpp
index 680a988..17918da 100644
--- a/lldb/tools/debugserver/source/debugserver.cpp
+++ b/lldb/tools/debugserver/source/debugserver.cpp
@@ -53,6 +53,7 @@
static int g_lockdown_opt = 0;
static int g_applist_opt = 0;
static nub_launch_flavor_t g_launch_flavor = eLaunchFlavorDefault;
+static int g_disable_aslr = 0;
int g_isatty = 0;
@@ -209,6 +210,7 @@
&inferior_envp[0],
stdio_path,
launch_flavor,
+ g_disable_aslr,
launch_err_str,
sizeof(launch_err_str));
@@ -655,6 +657,7 @@
{ "native-regs", no_argument, NULL, 'r' }, // Specify to use the native registers instead of the gdb defaults for the architecture.
{ "stdio-path", required_argument, NULL, 's' }, // Set the STDIO path to be used when launching applications
{ "setsid", no_argument, NULL, 'S' }, // call setsid() to make debugserver run in its own sessions
+ { "disable-aslr", no_argument, NULL, 'D' }, // Use _POSIX_SPAWN_DISABLE_ASLR to avoid shared library randomization
{ NULL, 0, NULL, 0 }
};
@@ -861,6 +864,9 @@
// signals sent to the session (i.e. dying when anyone hits ^C).
setsid();
break;
+ case 'D':
+ g_disable_aslr = 1;
+ break;
}
}