Fix Linux to respect ASLR settings when launching processes to debug locally and remotely.

See the following links for details:
http://llvm.org/bugs/show_bug.cgi?id=20658
See http://reviews.llvm.org/D4941

llvm-svn: 215822
diff --git a/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp b/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
index cbafc4c..63439b1 100644
--- a/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
+++ b/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
@@ -807,6 +807,7 @@
                                const char *stdout_path,
                                const char *stderr_path,
                                const char *working_dir,
+                               const lldb_private::ProcessLaunchInfo & /* launch_info */,
                                lldb_private::Error &error)
     : m_process(static_cast<ProcessFreeBSD *>(process)),
       m_operation_thread(LLDB_INVALID_HOST_THREAD),
diff --git a/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h b/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h
index ad88809..314743b 100644
--- a/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h
+++ b/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h
@@ -55,6 +55,7 @@
                    const char *stdout_path,
                    const char *stderr_path,
                    const char *working_dir,
+                   const lldb_private::ProcessLaunchInfo &launch_info,
                    lldb_private::Error &error);
 
     ProcessMonitor(ProcessPOSIX *process,
diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
index 6a7e6b8..9d88bb2 100644
--- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -18,6 +18,7 @@
 #include <stdint.h>
 #include <unistd.h>
 #include <linux/unistd.h>
+#include <sys/personality.h>
 #include <sys/ptrace.h>
 #include <sys/socket.h>
 #include <sys/syscall.h>
@@ -92,6 +93,7 @@
   #define ARCH_GET_GS 0x1004
 #endif
 
+#define LLDB_PERSONALITY_GET_CURRENT_SETTINGS  0xffffffff
 
 // Support hardware breakpoints in case it has not been defined
 #ifndef TRAP_HWBKPT
@@ -993,7 +995,8 @@
                                        const char *stdin_path,
                                        const char *stdout_path,
                                        const char *stderr_path,
-                                       const char *working_dir)
+                                       const char *working_dir,
+                                       const lldb_private::ProcessLaunchInfo &launch_info)
     : OperationArgs(monitor),
       m_module(module),
       m_argv(argv),
@@ -1001,7 +1004,10 @@
       m_stdin_path(stdin_path),
       m_stdout_path(stdout_path),
       m_stderr_path(stderr_path),
-      m_working_dir(working_dir) { }
+      m_working_dir(working_dir),
+      m_launch_info(launch_info)
+{
+}
 
 NativeProcessLinux::LaunchArgs::~LaunchArgs()
 { }
@@ -1084,6 +1090,7 @@
             stdout_path,
             stderr_path,
             working_dir,
+            launch_info,
             error);
 
     if (error.Fail ())
@@ -1182,6 +1189,7 @@
     const char *stdout_path,
     const char *stderr_path,
     const char *working_dir,
+    const lldb_private::ProcessLaunchInfo &launch_info,
     lldb_private::Error &error)
 {
     if (module)
@@ -1193,7 +1201,7 @@
         new LaunchArgs(
             this, module, argv, envp,
             stdin_path, stdout_path, stderr_path,
-            working_dir));
+            working_dir, launch_info));
 
     sem_init(&m_operation_pending, 0, 0);
     sem_init(&m_operation_done, 0, 0);
@@ -1351,6 +1359,10 @@
 bool
 NativeProcessLinux::Launch(LaunchArgs *args)
 {
+    assert (args && "null args");
+    if (!args)
+        return false;
+
     NativeProcessLinux *monitor = args->m_monitor;
     assert (monitor && "monitor is NULL");
     if (!monitor)
@@ -1462,6 +1474,33 @@
           if (0 != ::chdir(working_dir))
               exit(eChdirFailed);
 
+        // Disable ASLR if requested.
+        if (args->m_launch_info.GetFlags ().Test (lldb::eLaunchFlagDisableASLR))
+        {
+            const int old_personality = personality (LLDB_PERSONALITY_GET_CURRENT_SETTINGS);
+            if (old_personality == -1)
+            {
+                if (log)
+                    log->Printf ("NativeProcessLinux::%s retrieval of Linux personality () failed: %s. Cannot disable ASLR.", __FUNCTION__, strerror (errno));
+            }
+            else
+            {
+                const int new_personality = personality (ADDR_NO_RANDOMIZE | old_personality);
+                if (new_personality == -1)
+                {
+                    if (log)
+                        log->Printf ("NativeProcessLinux::%s setting of Linux personality () to disable ASLR failed, ignoring: %s", __FUNCTION__, strerror (errno));
+
+                }
+                else
+                {
+                    if (log)
+                        log->Printf ("NativeProcessLinux::%s disbling ASLR: SUCCESS", __FUNCTION__);
+
+                }
+            }
+        }
+
         // Execute.  We should never return.
         execve(argv[0],
                const_cast<char *const *>(argv),
diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
index f72b01b..ee71376 100644
--- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
+++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
@@ -217,7 +217,8 @@
                     const char *stdin_path,
                     const char *stdout_path,
                     const char *stderr_path,
-                    const char *working_dir);
+                    const char *working_dir,
+                    const lldb_private::ProcessLaunchInfo &launch_info);
 
             ~LaunchArgs();
 
@@ -228,6 +229,7 @@
             const char *m_stdout_path;      // Redirect stdout or NULL.
             const char *m_stderr_path;      // Redirect stderr or NULL.
             const char *m_working_dir;      // Working directory or NULL.
+            const lldb_private::ProcessLaunchInfo &m_launch_info;
         };
 
         struct AttachArgs : OperationArgs
@@ -256,6 +258,7 @@
             const char *stdout_path,
             const char *stderr_path,
             const char *working_dir,
+            const lldb_private::ProcessLaunchInfo &launch_info,
             Error &error);
 
         /// Attaches to an existing process.  Forms the
diff --git a/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp b/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp
index 9e5f844..42a0aa5 100644
--- a/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp
+++ b/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp
@@ -15,6 +15,7 @@
 #include <string.h>
 #include <stdint.h>
 #include <unistd.h>
+#include <sys/personality.h>
 #include <sys/ptrace.h>
 #include <sys/socket.h>
 #include <sys/syscall.h>
@@ -60,6 +61,7 @@
   #define ARCH_GET_GS 0x1004
 #endif
 
+#define LLDB_PERSONALITY_GET_CURRENT_SETTINGS  0xffffffff
 
 // Support hardware breakpoints in case it has not been defined
 #ifndef TRAP_HWBKPT
@@ -967,7 +969,8 @@
                                        const char *stdin_path,
                                        const char *stdout_path,
                                        const char *stderr_path,
-                                       const char *working_dir)
+                                       const char *working_dir,
+                                       const lldb_private::ProcessLaunchInfo &launch_info)
     : OperationArgs(monitor),
       m_module(module),
       m_argv(argv),
@@ -975,7 +978,10 @@
       m_stdin_path(stdin_path),
       m_stdout_path(stdout_path),
       m_stderr_path(stderr_path),
-      m_working_dir(working_dir) { }
+      m_working_dir(working_dir),
+      m_launch_info(launch_info)
+{
+}
 
 ProcessMonitor::LaunchArgs::~LaunchArgs()
 { }
@@ -1007,6 +1013,7 @@
                                const char *stdout_path,
                                const char *stderr_path,
                                const char *working_dir,
+                               const lldb_private::ProcessLaunchInfo &launch_info,
                                lldb_private::Error &error)
     : m_process(static_cast<ProcessLinux *>(process)),
       m_operation_thread(LLDB_INVALID_HOST_THREAD),
@@ -1017,7 +1024,7 @@
 {
     std::unique_ptr<LaunchArgs> args(new LaunchArgs(this, module, argv, envp,
                                      stdin_path, stdout_path, stderr_path,
-                                     working_dir));
+                                     working_dir, launch_info));
 
     sem_init(&m_operation_pending, 0, 0);
     sem_init(&m_operation_done, 0, 0);
@@ -1145,6 +1152,10 @@
 bool
 ProcessMonitor::Launch(LaunchArgs *args)
 {
+    assert (args && "null args");
+    if (!args)
+        return false;
+
     ProcessMonitor *monitor = args->m_monitor;
     ProcessLinux &process = monitor->GetProcess();
     const char **argv = args->m_argv;
@@ -1219,6 +1230,33 @@
           if (0 != ::chdir(working_dir))
               exit(eChdirFailed);
 
+        // Disable ASLR if requested.
+        if (args->m_launch_info.GetFlags ().Test (lldb::eLaunchFlagDisableASLR))
+        {
+            const int old_personality = personality (LLDB_PERSONALITY_GET_CURRENT_SETTINGS);
+            if (old_personality == -1)
+            {
+                if (log)
+                    log->Printf ("ProcessMonitor::%s retrieval of Linux personality () failed: %s. Cannot disable ASLR.", __FUNCTION__, strerror (errno));
+            }
+            else
+            {
+                const int new_personality = personality (ADDR_NO_RANDOMIZE | old_personality);
+                if (new_personality == -1)
+                {
+                    if (log)
+                        log->Printf ("ProcessMonitor::%s setting of Linux personality () to disable ASLR failed, ignoring: %s", __FUNCTION__, strerror (errno));
+
+                }
+                else
+                {
+                    if (log)
+                        log->Printf ("ProcessMonitor::%s disbling ASLR: SUCCESS", __FUNCTION__);
+
+                }
+            }
+        }
+
         // Execute.  We should never return.
         execve(argv[0],
                const_cast<char *const *>(argv),
diff --git a/lldb/source/Plugins/Process/Linux/ProcessMonitor.h b/lldb/source/Plugins/Process/Linux/ProcessMonitor.h
index 3e289ff..bd32534 100644
--- a/lldb/source/Plugins/Process/Linux/ProcessMonitor.h
+++ b/lldb/source/Plugins/Process/Linux/ProcessMonitor.h
@@ -55,6 +55,7 @@
                    const char *stdout_path,
                    const char *stderr_path,
                    const char *working_dir,
+                   const lldb_private::ProcessLaunchInfo &launch_info,
                    lldb_private::Error &error);
 
     ProcessMonitor(ProcessPOSIX *process,
@@ -233,7 +234,8 @@
                    const char *stdin_path,
                    const char *stdout_path,
                    const char *stderr_path,
-                   const char *working_dir);
+                   const char *working_dir,
+                   const lldb_private::ProcessLaunchInfo &launch_info);
 
         ~LaunchArgs();
 
@@ -244,6 +246,7 @@
         const char *m_stdout_path;      // Redirect stdout or NULL.
         const char *m_stderr_path;      // Redirect stderr or NULL.
         const char *m_working_dir;      // Working directory or NULL.
+        const lldb_private::ProcessLaunchInfo &m_launch_info;
     };
 
     void
diff --git a/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp b/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp
index 2ce61e9..e96e0b6 100644
--- a/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp
+++ b/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp
@@ -241,6 +241,7 @@
                                     stdout_path, 
                                     stderr_path,
                                     working_dir,
+                                    launch_info,
                                     error);
 
     m_module = module;