diff options
-rw-r--r-- | lldb/include/lldb/Target/Platform.h | 15 | ||||
-rw-r--r-- | lldb/include/lldb/Target/Process.h | 35 | ||||
-rw-r--r-- | lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp | 61 | ||||
-rw-r--r-- | lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h | 6 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp | 12 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h | 5 | ||||
-rw-r--r-- | lldb/source/Target/Platform.cpp | 9 |
7 files changed, 140 insertions, 3 deletions
diff --git a/lldb/include/lldb/Target/Platform.h b/lldb/include/lldb/Target/Platform.h index d2b86e813f7..db71e3abde9 100644 --- a/lldb/include/lldb/Target/Platform.h +++ b/lldb/include/lldb/Target/Platform.h @@ -244,10 +244,21 @@ class ModuleCache; ResolveRemotePath (const FileSpec &platform_path, FileSpec &resolved_platform_path); - bool + //------------------------------------------------------------------ + /// Get the OS version from a connected platform. + /// + /// Some platforms might not be connected to a remote platform, but + /// can figure out the OS version for a process. This is common for + /// simulator platforms that will run native programs on the current + /// host, but the simulator might be simulating a different OS. The + /// \a process parameter might be specified to help to determine + /// the OS version. + //------------------------------------------------------------------ + virtual bool GetOSVersion (uint32_t &major, uint32_t &minor, - uint32_t &update); + uint32_t &update, + Process *process = nullptr); bool SetOSVersion (uint32_t major, diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index f04c0019c3f..b78017d0993 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -1820,6 +1820,41 @@ public: RefreshStateAfterStop () = 0; //------------------------------------------------------------------ + /// Sometimes the connection to a process can detect the host OS + /// version that the process is running on. The current platform + /// should be checked first in case the platform is connected, but + /// clients can fall back onto this function if the platform fails + /// to identify the host OS version. The platform should be checked + /// first in case you are running a simulator platform that might + /// itself be running natively, but have different heuristics for + /// figuring out which OS is is emulating. + /// + /// @param[out] major + /// The major OS version, or UINT32_MAX if it can't be determined + /// + /// @param[out] minor + /// The minor OS version, or UINT32_MAX if it can't be determined + /// + /// @param[out] update + /// The update OS version, or UINT32_MAX if it can't be determined + /// + /// @return + /// Returns \b true if the host OS version info was filled in + /// and \b false otherwise. + //------------------------------------------------------------------ + virtual bool + GetHostOSVersion(uint32_t &major, + uint32_t &minor, + uint32_t &update) + { + major = UINT32_MAX; + minor = UINT32_MAX; + update = UINT32_MAX; + return false; + } + + + //------------------------------------------------------------------ /// Get the target object pointer for this module. /// /// @return diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp index 0c31ff7247e..f9a588c9709 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp @@ -31,10 +31,13 @@ #include "lldb/Host/HostInfo.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Symbols.h" +#include "lldb/Host/StringConvert.h" +#include "lldb/Host/XML.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/SymbolVendor.h" +#include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "llvm/ADT/STLExtras.h" @@ -1586,6 +1589,64 @@ PlatformDarwin::GetFullNameForDylib (ConstString basename) return ConstString(stream.GetData()); } +bool +PlatformDarwin::GetOSVersion (uint32_t &major, + uint32_t &minor, + uint32_t &update, + Process *process) +{ + if (process && strstr(GetPluginName().GetCString(), "-simulator")) + { + lldb_private::ProcessInstanceInfo proc_info; + if (Host::GetProcessInfo(process->GetID(), proc_info)) + { + Args &env = proc_info.GetEnvironmentEntries(); + const size_t n = env.GetArgumentCount(); + const llvm::StringRef k_runtime_version("SIMULATOR_RUNTIME_VERSION="); + const llvm::StringRef k_dyld_root_path("DYLD_ROOT_PATH="); + std::string dyld_root_path; + + for (size_t i=0; i<n; ++i) + { + const char *env_cstr = env.GetArgumentAtIndex(i); + if (env_cstr) + { + llvm::StringRef env_str(env_cstr); + if (env_str.startswith(k_runtime_version)) + { + llvm::StringRef version_str(env_str.substr(k_runtime_version.size())); + Args::StringToVersion (version_str.data(), major, minor, update); + if (major != UINT32_MAX) + return true; + } + else if (env_str.startswith(k_dyld_root_path)) + { + dyld_root_path = std::move(env_str.substr(k_dyld_root_path.size()).str()); + } + } + } + + if (!dyld_root_path.empty()) + { + dyld_root_path += "/System/Library/CoreServices/SystemVersion.plist"; + ApplePropertyList system_version_plist(dyld_root_path.c_str()); + std::string product_version; + if (system_version_plist.GetValueAsString("ProductVersion", product_version)) + { + Args::StringToVersion (product_version.c_str(), major, minor, update); + return major != UINT32_MAX; + } + } + + } + // For simulator platforms, do NOT call back through Platform::GetOSVersion() + // as it might call Process::GetHostOSVersion() which we don't want as it will be + // incorrect + return false; + } + + return Platform::GetOSVersion(major, minor, update, process); +} lldb_private::FileSpec PlatformDarwin::LocateExecutable (const char *basename) diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h index 54ea1a18513..b280b35da65 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h @@ -84,6 +84,12 @@ public: CalculateTrapHandlerSymbolNames () override; bool + GetOSVersion (uint32_t &major, + uint32_t &minor, + uint32_t &update, + lldb_private::Process *process = nullptr) override; + + bool SupportsModules () override { return true; } lldb_private::ConstString diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index a6e15d21063..4a321879e5b 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -4296,6 +4296,18 @@ ProcessGDBRemote::GetModuleSpec(const FileSpec& module_file_spec, return true; } +bool +ProcessGDBRemote::GetHostOSVersion(uint32_t &major, + uint32_t &minor, + uint32_t &update) +{ + if (m_gdb_comm.GetOSVersion(major, minor, update)) + return true; + // We failed to get the host OS version, defer to the base + // implementation to correctly invalidate the arguments. + return Process::GetHostOSVersion(major, minor, update); +} + namespace { typedef std::vector<std::string> stringVec; diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index 0a0f32e69be..39d44212ab1 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -239,6 +239,11 @@ public: const ArchSpec& arch, ModuleSpec &module_spec) override; + bool + GetHostOSVersion(uint32_t &major, + uint32_t &minor, + uint32_t &update) override; + size_t LoadModules() override; diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp index 33446a9fb3a..aebe9192fbe 100644 --- a/lldb/source/Target/Platform.cpp +++ b/lldb/source/Target/Platform.cpp @@ -528,7 +528,8 @@ Platform::GetStatus (Stream &strm) bool Platform::GetOSVersion (uint32_t &major, uint32_t &minor, - uint32_t &update) + uint32_t &update, + Process *process) { Mutex::Locker locker (m_mutex); @@ -579,6 +580,12 @@ Platform::GetOSVersion (uint32_t &major, minor = m_minor_os_version; update = m_update_os_version; } + else if (process) + { + // Check with the process in case it can answer the question if + // a process was provided + return process->GetHostOSVersion(major, minor, update); + } return success; } |