diff options
Diffstat (limited to 'lldb/source')
11 files changed, 197 insertions, 12 deletions
diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp index e6e1e744870..9cdf73d9944 100644 --- a/lldb/source/API/SBTarget.cpp +++ b/lldb/source/API/SBTarget.cpp @@ -1087,7 +1087,7 @@ SBTarget::ConnectRemote if (process_sp) { sb_process.SetSP (process_sp); - error.SetError (process_sp->ConnectRemote (url)); + error.SetError (process_sp->ConnectRemote (NULL, url)); } else { diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp index 1e01898b0b9..5653e7a724e 100644 --- a/lldb/source/Commands/CommandObjectProcess.cpp +++ b/lldb/source/Commands/CommandObjectProcess.cpp @@ -1041,7 +1041,7 @@ protected: if (process) { - error = process->ConnectRemote (remote_url); + error = process->ConnectRemote (&process->GetTarget().GetDebugger().GetOutputStream(), remote_url); if (error.Fail()) { diff --git a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp index 5edd3684108..abaf1b4e862 100644 --- a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp +++ b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp @@ -342,7 +342,16 @@ DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() { m_kernel.Clear(false); m_kernel.module_sp = m_process->GetTarget().GetExecutableModule(); - strncpy(m_kernel.name, "mach_kernel", sizeof(m_kernel.name)); + + ConstString kernel_name("mach_kernel"); + if (m_kernel.module_sp.get() + && m_kernel.module_sp->GetObjectFile() + && !m_kernel.module_sp->GetObjectFile()->GetFileSpec().GetFilename().IsEmpty()) + { + kernel_name = m_kernel.module_sp->GetObjectFile()->GetFileSpec().GetFilename(); + } + strlcpy (m_kernel.name, kernel_name.AsCString(), sizeof(m_kernel.name)); + if (m_kernel.address == LLDB_INVALID_ADDRESS) { m_kernel.address = m_process->GetImageInfoAddress (); @@ -353,7 +362,25 @@ DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() // the file if we have one ObjectFile *kernel_object_file = m_kernel.module_sp->GetObjectFile(); if (kernel_object_file) - m_kernel.address = kernel_object_file->GetHeaderAddress().GetFileAddress(); + { + addr_t load_address = kernel_object_file->GetHeaderAddress().GetLoadAddress(&m_process->GetTarget()); + addr_t file_address = kernel_object_file->GetHeaderAddress().GetFileAddress(); + if (load_address != LLDB_INVALID_ADDRESS && load_address != 0) + { + m_kernel.address = load_address; + if (load_address != file_address) + { + // Don't accidentally relocate the kernel to the File address -- + // the Load address has already been set to its actual in-memory address. + // Mark it as IsLoaded. + m_kernel.load_process_stop_id = m_process->GetStopID(); + } + } + else + { + m_kernel.address = file_address; + } + } } } @@ -725,7 +752,6 @@ DynamicLoaderDarwinKernel::PrivateInitialize(Process *process) DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState())); Clear(true); m_process = process; - m_process->GetTarget().GetSectionLoadList().Clear(); } void diff --git a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp index a596618ab51..2f3b77e9cd7 100644 --- a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp +++ b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp @@ -398,7 +398,7 @@ PlatformRemoteGDBServer::Attach (lldb_private::ProcessAttachInfo &attach_info, GetHostname (), port); assert (connect_url_len < sizeof(connect_url)); - error = process_sp->ConnectRemote (connect_url); + error = process_sp->ConnectRemote (NULL, connect_url); if (error.Success()) error = process_sp->Attach(attach_info); } diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp index c0e62888cf8..7600ab61625 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp +++ b/lldb/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 @@ CommunicationKDP::GetCPUSubtype () 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 () { diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h b/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h index 03e1856bf50..c46d409be47 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h @@ -213,6 +213,12 @@ public: uint32_t GetCPUSubtype (); + lldb_private::UUID + GetUUID (); + + lldb::addr_t + GetLoadAddress (); + bool SendRequestResume (); diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp index c5be91435d7..4e856897b90 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp @@ -17,8 +17,11 @@ #include "lldb/Core/Debugger.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Module.h" +#include "lldb/Core/ModuleSpec.h" #include "lldb/Core/State.h" +#include "lldb/Core/UUID.h" #include "lldb/Host/Host.h" +#include "lldb/Host/Symbols.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Target.h" @@ -167,7 +170,7 @@ ProcessKDP::WillAttachToProcessWithName (const char *process_name, bool wait_for } Error -ProcessKDP::DoConnectRemote (const char *remote_url) +ProcessKDP::DoConnectRemote (Stream *strm, const char *remote_url) { Error error; @@ -214,6 +217,90 @@ ProcessKDP::DoConnectRemote (const char *remote_url) ArchSpec kernel_arch; kernel_arch.SetArchitecture(eArchTypeMachO, cpu, sub); m_target.SetArchitecture(kernel_arch); + + /* Get the kernel's UUID and load address via kdp-kernelversion packet. */ + + UUID kernel_uuid = m_comm.GetUUID (); + addr_t kernel_load_addr = m_comm.GetLoadAddress (); + if (strm) + { + char uuidbuf[64]; + strm->Printf ("Kernel UUID: %s\n", kernel_uuid.GetAsCString (uuidbuf, sizeof (uuidbuf))); + strm->Printf ("Load Address: 0x%llx\n", kernel_load_addr); + strm->Flush (); + } + + /* Set the kernel's LoadAddress based on the information from kdp. + This would normally be handled by the DynamicLoaderDarwinKernel plugin but there's no easy + way to communicate the UUID / load addr from kdp back up to that plugin so we'll set it here. */ + ModuleSP exe_module_sp = m_target.GetExecutableModule (); + bool find_and_load_kernel = true; + if (exe_module_sp.get ()) + { + ObjectFile *exe_objfile = exe_module_sp->GetObjectFile(); + if (exe_objfile->GetType() == ObjectFile::eTypeExecutable && + exe_objfile->GetStrata() == ObjectFile::eStrataKernel) + { + UUID exe_objfile_uuid; + if (exe_objfile->GetUUID (&exe_objfile_uuid) && kernel_uuid == exe_objfile_uuid + && exe_objfile->GetHeaderAddress().IsValid()) + { + find_and_load_kernel = false; + addr_t slide = kernel_load_addr - exe_objfile->GetHeaderAddress().GetFileAddress(); + if (slide != 0) + { + bool changed = false; + exe_module_sp->SetLoadAddress (m_target, slide, changed); + if (changed) + { + ModuleList modlist; + modlist.Append (exe_module_sp); + m_target.ModulesDidLoad (modlist); + } + } + } + } + } + + // If the executable binary is not the same as the kernel being run on the remote host, + // see if Symbols::DownloadObjectAndSymbolFile can find us a symbol file based on the UUID + // and if so, load it at the correct address. + if (find_and_load_kernel && kernel_load_addr != LLDB_INVALID_ADDRESS && kernel_uuid.IsValid()) + { + ModuleSpec sym_spec; + sym_spec.GetUUID() = kernel_uuid; + if (Symbols::DownloadObjectAndSymbolFile (sym_spec) + && sym_spec.GetArchitecture().IsValid() + && sym_spec.GetSymbolFileSpec().Exists()) + { + ModuleSP kernel_sp = m_target.GetSharedModule (sym_spec); + if (kernel_sp.get()) + { + m_target.SetExecutableModule(kernel_sp, false); + if (kernel_sp->GetObjectFile() && kernel_sp->GetObjectFile()->GetHeaderAddress().IsValid()) + { + addr_t slide = kernel_load_addr - kernel_sp->GetObjectFile()->GetHeaderAddress().GetFileAddress(); + bool changed = false; + kernel_sp->SetLoadAddress (m_target, slide, changed); + if (changed) + { + ModuleList modlist; + modlist.Append (kernel_sp); + m_target.ModulesDidLoad (modlist); + } + if (strm) + { + strm->Printf ("Loaded kernel file %s/%s\n", + kernel_sp->GetFileSpec().GetDirectory().AsCString(), + kernel_sp->GetFileSpec().GetFilename().AsCString()); + strm->Flush (); + } + } + } + } + } + + // Set the thread ID UpdateThreadListIfNeeded (); SetID (1); diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h index 825e6b66d15..4aebcddb34c 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h @@ -90,7 +90,7 @@ public: WillAttachToProcessWithName (const char *process_name, bool wait_for_launch); virtual lldb_private::Error - DoConnectRemote (const char *remote_url); + DoConnectRemote (lldb_private::Stream *strm, const char *remote_url); virtual lldb_private::Error DoAttachToProcessWithID (lldb::pid_t pid); diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index d25f134de8a..f29a1677874 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -414,7 +414,7 @@ ProcessGDBRemote::WillAttachToProcessWithName (const char *process_name, bool wa } Error -ProcessGDBRemote::DoConnectRemote (const char *remote_url) +ProcessGDBRemote::DoConnectRemote (Stream *strm, const char *remote_url) { Error error (WillLaunchOrAttach ()); @@ -427,6 +427,25 @@ ProcessGDBRemote::DoConnectRemote (const char *remote_url) return error; StartAsyncThread (); + const ArchSpec &gdb_remote_arch = m_gdb_comm.GetHostArchitecture(); + if (gdb_remote_arch.IsValid() && gdb_remote_arch.GetTriple().getVendor() == llvm::Triple::Apple) + { + Module *exe_module = GetTarget().GetExecutableModulePointer(); + + ObjectFile *exe_objfile = exe_module->GetObjectFile(); + + // If the remote system is an Apple device and we don't have an exec file + // OR we have an exec file and it is a kernel, look for the kernel's load address + // in memory and load/relocate the kernel symbols as appropriate. + if (exe_objfile == NULL + || (exe_objfile->GetType() == ObjectFile::eTypeExecutable && + exe_objfile->GetStrata() == ObjectFile::eStrataKernel)) + { + + + } + } + lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID (); if (pid == LLDB_INVALID_PROCESS_ID) { diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index 563b89963fa..4a716157943 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -94,7 +94,7 @@ public: WillAttachToProcessWithName (const char *process_name, bool wait_for_launch); virtual lldb_private::Error - DoConnectRemote (const char *remote_url); + DoConnectRemote (lldb_private::Stream *strm, const char *remote_url); lldb_private::Error WillLaunchOrAttach (); diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 4ad52a29677..5858f9972f2 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -2906,7 +2906,7 @@ Process::CompleteAttach () } Error -Process::ConnectRemote (const char *remote_url) +Process::ConnectRemote (Stream *strm, const char *remote_url) { m_abi_sp.reset(); m_process_input_reader.reset(); @@ -2914,7 +2914,7 @@ Process::ConnectRemote (const char *remote_url) // Find the process and its architecture. Make sure it matches the architecture // of the current Target, and if not adjust it. - Error error (DoConnectRemote (remote_url)); + Error error (DoConnectRemote (strm, remote_url)); if (error.Success()) { if (GetID() != LLDB_INVALID_PROCESS_ID) |