Add support for debugging KASLR kernels via kdp (the kernel being
loaded at a random offset).

To get the kernel's UUID and load address I need to send a kdp
packet so I had to implement the kernel relocation (and attempt to
find the kernel if none was provided to lldb already) in ProcessKDP
-- but this code really properly belongs in DynamicLoaderDarwinKernel.

I also had to add an optional Stream to ConnectRemote so
ProcessKDP::DoConnectRemote can print feedback about the remote kernel's
UUID, load address, and notify the user if we auto-loaded the kernel via
the UUID.

<rdar://problem/7714201>


git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@164881 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
index c0e6288..7600ab6 100644
--- a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
@@ -11,6 +11,7 @@
 #include "CommunicationKDP.h"
 
 // C Includes
+#include <errno.h>
 #include <limits.h>
 #include <string.h>
 
@@ -22,6 +23,7 @@
 #include "lldb/Core/DataExtractor.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/State.h"
+#include "lldb/Core/UUID.h"
 #include "lldb/Host/FileSpec.h"
 #include "lldb/Host/Host.h"
 #include "lldb/Host/TimeValue.h"
@@ -499,6 +501,51 @@
     return m_kdp_hostinfo_cpu_subtype;
 }
 
+lldb_private::UUID
+CommunicationKDP::GetUUID ()
+{
+    UUID uuid;
+    if (GetKernelVersion() == NULL)
+        return uuid;
+
+    if (m_kernel_version.find("UUID=") == std::string::npos)
+        return uuid;
+
+    size_t p = m_kernel_version.find("UUID=") + strlen ("UUID=");
+    std::string uuid_str = m_kernel_version.substr(p, 36);
+    if (uuid_str.size() < 32)
+        return uuid;
+
+    if (uuid.SetFromCString (uuid_str.c_str()) == 0)
+    {
+        UUID invalid_uuid;
+        return invalid_uuid;
+    }
+
+    return uuid;
+}
+
+lldb::addr_t
+CommunicationKDP::GetLoadAddress ()
+{
+    if (GetKernelVersion() == NULL)
+        return LLDB_INVALID_ADDRESS;
+
+    if (m_kernel_version.find("stext=") == std::string::npos)
+        return LLDB_INVALID_ADDRESS;
+    size_t p = m_kernel_version.find("stext=") + strlen ("stext=");
+    if (m_kernel_version[p] != '0' || m_kernel_version[p + 1] != 'x')
+        return LLDB_INVALID_ADDRESS;
+
+    addr_t kernel_load_address;
+    errno = 0;
+    kernel_load_address = ::strtoul (m_kernel_version.c_str() + p, NULL, 16);
+    if (errno != 0 || kernel_load_address == 0)
+        return LLDB_INVALID_ADDRESS;
+
+    return kernel_load_address;
+}
+
 bool
 CommunicationKDP::SendRequestHostInfo ()
 {