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/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp
index c863bc7..6c55c68 100644
--- a/lldb/source/API/SBTarget.cpp
+++ b/lldb/source/API/SBTarget.cpp
@@ -121,6 +121,7 @@
     char const **argv,
     char const **envp,
     const char *tty,
+    uint32_t launch_flags,
     bool stop_at_entry
 )
 {
@@ -129,7 +130,7 @@
         process = CreateProcess();
     if (process.IsValid())
     {
-        Error error (process->Launch (argv, envp, tty, tty, tty));
+        Error error (process->Launch (argv, envp, launch_flags, tty, tty, tty));
         if (error.Success())
         {
             if (!stop_at_entry)
diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp
index dd2d545..73386b4 100644
--- a/lldb/source/Commands/CommandObjectProcess.cpp
+++ b/lldb/source/Commands/CommandObjectProcess.cpp
@@ -163,6 +163,9 @@
 
         const Args *environment = interpreter.GetEnvironmentVariables();
         const Args *run_args = interpreter.GetProgramArguments();
+		uint32_t launch_flags = eLaunchFlagNone;
+        if (interpreter.GetDisableASLR())
+			launch_flags |= eLaunchFlagDisableASLR;
 
         // There are two possible sources of args to be passed to the process upon launching:  Those the user
         // typed at the run command (launch_args); or those the user pre-set in the run-args variable (run_args).
@@ -204,6 +207,7 @@
 
             Error error (process->Launch (launch_args.GetConstArgumentVector(),
                                           environment ? environment->GetConstArgumentVector() : NULL,
+                                          launch_flags,
                                           stdin_path,
                                           stdout_path,
                                           stderr_path));
diff --git a/lldb/source/Host/macosx/Host.mm b/lldb/source/Host/macosx/Host.mm
index 70f2886..00450ac 100644
--- a/lldb/source/Host/macosx/Host.mm
+++ b/lldb/source/Host/macosx/Host.mm
@@ -834,17 +834,17 @@
     
     file_and_line_desc.descKey = keyAEPosition;
     
+    static FSRef g_app_fsref;
+
     LSApplicationParameters app_params;
-    static FSRef app_to_use;
-    static std::string app_name;
-    bzero (&app_params, sizeof (app_params));
+    ::bzero (&app_params, sizeof (app_params));
     app_params.flags = kLSLaunchDefaults | 
                        kLSLaunchDontAddToRecents | 
                        kLSLaunchDontSwitch;
-                       
+    
     char *external_editor = ::getenv ("LLDB_EXTERNAL_EDITOR");
     
-    if (external_editor != NULL)
+    if (external_editor)
     {
         bool calculate_fsref = true;
         if (log)
@@ -852,20 +852,15 @@
 
         if (app_name.empty() || strcmp (app_name.c_str(), external_editor) != 0)
         {
-            calculate_fsref = true;
-        }
-        else
-            calculate_fsref = false;
-            
-        if (calculate_fsref)
-        {
             CFCString editor_name (external_editor, kCFStringEncodingUTF8);
-            error = ::LSFindApplicationForInfo(kLSUnknownCreator, NULL, editor_name.get(), &app_to_use, NULL);
+            error = ::LSFindApplicationForInfo (kLSUnknownCreator, 
+                                                NULL, 
+                                                editor_name.get(), 
+                                                &g_app_fsref, 
+                                                NULL);
             
             // If we found the app, then store away the name so we don't have to re-look it up.
-            if (error == noErr)
-                app_name.assign (external_editor);
-            else
+            if (error != noErr)
             {
                 if (log)
                     log->Printf("Could not find External Editor application, error: %d.\n", error);
@@ -873,12 +868,9 @@
             }
                 
         }
-        
-        app_params.application = &app_to_use;
+        app_params.application = &g_app_fsref;
     }
 
-
-
     ProcessSerialNumber psn;
     CFCReleaser<CFArrayRef> file_array(CFArrayCreate (NULL, (const void **) file_URL.ptr_address(false), 1, NULL));
     error = ::LSOpenURLsWithRole (file_array.get(), 
diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp
index eaf886f..f127fde 100644
--- a/lldb/source/Interpreter/CommandInterpreter.cpp
+++ b/lldb/source/Interpreter/CommandInterpreter.cpp
@@ -161,6 +161,11 @@
                                          80,
                                         "The maximum number of columns to use for displaying text."));
     
+    m_variables["disable-aslr"] =
+    StateVariableSP (new StateVariable ("disable-aslr",
+                                        1,
+                                        "Disable Address Space Layout Randomization (ASLR)."));
+    
 }
 
 const char *
@@ -898,6 +903,14 @@
     return NULL;
 }
 
+int
+CommandInterpreter::GetDisableASLR ()
+{
+    StateVariable *var = GetStateVariable ("disable-aslr");
+    int disable_aslr = var->GetIntValue();
+
+    return disable_aslr;
+}
 
 CommandInterpreter::~CommandInterpreter ()
 {
diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp b/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp
index fc33c75..80ee9ef 100644
--- a/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp
+++ b/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp
@@ -64,6 +64,9 @@
 #define MACH_PROCESS_USE_POSIX_SPAWN 1
 #endif
 
+#ifndef _POSIX_SPAWN_DISABLE_ASLR
+#define _POSIX_SPAWN_DISABLE_ASLR       0x0100
+#endif
 
 #if defined (__arm__)
 
@@ -312,6 +315,7 @@
     Module* module,
     char const *argv[],
     char const *envp[],
+    uint32_t flags,
     const char *stdin_path,
     const char *stdout_path,
     const char *stderr_path
@@ -328,7 +332,7 @@
         ArchSpec arch_spec(module->GetArchitecture());
 
         // Set our user ID to our process ID.
-        SetID (LaunchForDebug(argv[0], argv, envp, arch_spec, stdin_path, stdout_path, stderr_path, eLaunchDefault, error));
+        SetID (LaunchForDebug(argv[0], argv, envp, arch_spec, stdin_path, stdout_path, stderr_path, eLaunchDefault, flags, error));
     }
     else
     {
@@ -1557,6 +1561,7 @@
     const char *stdout_path,
     const char *stderr_path,
     PDLaunchType launch_type,
+    uint32_t flags,
     Error &launch_err)
 {
     // Clear out and clean up from any current state
@@ -1569,7 +1574,7 @@
 
     Log *log = ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_PROCESS);
     if (log)
-        log->Printf ("%s( path = '%s', argv = %p, envp = %p, launch_type = %u )", __FUNCTION__, path, argv, envp, launch_type);
+        log->Printf ("%s( path = '%s', argv = %p, envp = %p, launch_type = %u, flags = %x )", __FUNCTION__, path, argv, envp, launch_type, flags);
 
     // Fork a child process for debugging
     SetPrivateState (eStateLaunching);
@@ -1580,7 +1585,7 @@
         break;
 
     case eLaunchPosixSpawn:
-        SetID(ProcessMacOSX::PosixSpawnChildForPTraceDebugging(path, argv, envp, arch_spec, stdin_path, stdout_path, stderr_path, this, launch_err));
+        SetID(ProcessMacOSX::PosixSpawnChildForPTraceDebugging(path, argv, envp, arch_spec, stdin_path, stdout_path, stderr_path, this, flags & eLaunchFlagDisableASLR ? 1 : 0, launch_err));
         break;
 
 #if defined (__arm__)
@@ -1683,11 +1688,12 @@
     const char *stdout_path,
     const char *stderr_path,
     ProcessMacOSX* process,
+    int disable_aslr,
     Error &err
 )
 {
     posix_spawnattr_t attr;
-
+    short flags;
     Log *log = ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_PROCESS);
 
     Error local_err;    // Errors that don't affect the spawning.
@@ -1699,9 +1705,13 @@
     if (err.Fail())
         return LLDB_INVALID_PROCESS_ID;
 
-    err.SetError( ::posix_spawnattr_setflags (&attr, POSIX_SPAWN_START_SUSPENDED), eErrorTypePOSIX);
+    flags = POSIX_SPAWN_START_SUSPENDED;
+    if (disable_aslr)
+        flags |= _POSIX_SPAWN_DISABLE_ASLR;
+    
+    err.SetError( ::posix_spawnattr_setflags (&attr, flags), eErrorTypePOSIX);
     if (err.Fail() || log)
-        err.PutToLog(log, "::posix_spawnattr_setflags ( &attr, POSIX_SPAWN_START_SUSPENDED )");
+        err.PutToLog(log, "::posix_spawnattr_setflags ( &attr, POSIX_SPAWN_START_SUSPENDED%s )", disable_aslr ? " | _POSIX_SPAWN_DISABLE_ASLR" : "");
     if (err.Fail())
         return LLDB_INVALID_PROCESS_ID;
 
diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h b/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h
index a3585db..9a6e149 100644
--- a/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h
+++ b/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h
@@ -93,6 +93,7 @@
     DoLaunch (lldb_private::Module* module,
               char const *argv[],           // Can be NULL
               char const *envp[],           // Can be NULL
+              uint32_t launch_flags,
               const char *stdin_path,       // Can be NULL
               const char *stdout_path,  // Can be NULL
               const char *stderr_path); // Can be NULL
@@ -261,6 +262,7 @@
                     const char *stdout_path,
                     const char *stderr_path,
                     PDLaunchType launch_type,
+                    uint32_t flags,
                     lldb_private::Error &launch_err);
 
     static lldb::pid_t
@@ -283,6 +285,7 @@
                                        const char *stdout_path,
                                        const char *stderr_path,
                                        ProcessMacOSX* process,
+                                       int disable_aslr,
                                        lldb_private::Error &launch_err);
 
 #if defined (__arm__)
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 2a07ee9..e8d596a 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -375,6 +375,7 @@
     Module* module,
     char const *argv[],
     char const *envp[],
+    uint32_t launch_flags,
     const char *stdin_path,
     const char *stdout_path,
     const char *stderr_path
@@ -404,6 +405,7 @@
                                              NULL, //stdin_path,
                                              LLDB_INVALID_PROCESS_ID,
                                              NULL, false,
+                                             launch_flags & eLaunchFlagDisableASLR != 0,
                                              inferior_arch);
             if (error.Fail())
                 return error;
@@ -422,6 +424,7 @@
                                              NULL, //stdin_path,
                                              LLDB_INVALID_PROCESS_ID,
                                              NULL, false,
+                                             launch_flags & eLaunchFlagDisableASLR != 0,
                                              inferior_arch);
             if (error.Fail())
                 return error;
@@ -639,12 +642,14 @@
         SetPrivateState (eStateAttaching);
         char host_port[128];
         snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ());
-        error = StartDebugserverProcess (host_port,
-                                         NULL,
-                                         NULL,
-                                         NULL,
-                                         LLDB_INVALID_PROCESS_ID,
-                                         NULL, false,
+        error = StartDebugserverProcess (host_port,                 // debugserver_url
+                                         NULL,                      // inferior_argv
+                                         NULL,                      // inferior_envp
+                                         NULL,                      // stdin_path
+                                         LLDB_INVALID_PROCESS_ID,   // attach_pid
+                                         NULL,                      // attach_pid_name
+                                         false,                     // wait_for_launch
+                                         false,                     // disable_aslr
                                          arch_spec);
         
         if (error.Fail())
@@ -740,12 +745,14 @@
         char host_port[128];
         ArchSpec arch_spec = GetTarget().GetArchitecture();
         snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ());
-        error = StartDebugserverProcess (host_port,
-                                         NULL,
-                                         NULL,
-                                         NULL,
-                                         LLDB_INVALID_PROCESS_ID,
-                                         NULL, false,
+        error = StartDebugserverProcess (host_port,                 // debugserver_url
+                                         NULL,                      // inferior_argv
+                                         NULL,                      // inferior_envp
+                                         NULL,                      // stdin_path
+                                         LLDB_INVALID_PROCESS_ID,   // attach_pid
+                                         NULL,                      // attach_pid_name
+                                         false,                     // wait_for_launch
+                                         false,                     // disable_aslr
                                          arch_spec);
         if (error.Fail())
         {
@@ -1644,6 +1651,7 @@
     lldb::pid_t attach_pid,         // If inferior inferior_argv == NULL, and attach_pid != LLDB_INVALID_PROCESS_ID then attach to this attach_pid
     const char *attach_name,        // Wait for the next process to launch whose basename matches "attach_name"
     bool wait_for_launch,           // Wait for the process named "attach_name" to launch
+    bool disable_aslr,               // Disable ASLR
     ArchSpec& inferior_arch         // The arch of the inferior that we will launch
 )
 {
@@ -1771,6 +1779,9 @@
                                                         // signals generated by special terminal key
                                                         // sequences (^C) don't affect debugserver
 
+            if (disable_aslr)
+                debugserver_args.AppendArguments("--disable-aslr");
+            
             // Only set the inferior
             if (launch_process)
             {
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 88c495a..62473f9 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -81,6 +81,7 @@
     DoLaunch (lldb_private::Module* module,
               char const *argv[],           // Can be NULL
               char const *envp[],           // Can be NULL
+              uint32_t flags,
               const char *stdin_path,       // Can be NULL
               const char *stdout_path,  // Can be NULL
               const char *stderr_path); // Can be NULL
@@ -292,6 +293,7 @@
                              lldb::pid_t attach_pid,         // If inferior inferior_argv == NULL, then attach to this pid
                              const char *attach_pid_name,    // Wait for the next process to launch whose basename matches "attach_wait_name"
                              bool wait_for_launch,           // Wait for the process named "attach_wait_name" to launch
+                             bool disable_aslr,               // Disable ASLR
                              lldb_private::ArchSpec& arch_spec);
 
     void
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 20bd1cc..986e44d 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -946,6 +946,7 @@
 (
     char const *argv[],
     char const *envp[],
+    uint32_t launch_flags,
     const char *stdin_path,
     const char *stdout_path,
     const char *stderr_path
@@ -994,6 +995,7 @@
                 error = DoLaunch (exe_module, 
                                   exec_path_plus_argv.empty() ? NULL : &exec_path_plus_argv.front(), 
                                   envp, 
+                                  launch_flags,
                                   stdin_path, 
                                   stdout_path, 
                                   stderr_path);