diff options
11 files changed, 3373 insertions, 12 deletions
diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj index 35be00f45f1..a7267e9804f 100644 --- a/lldb/lldb.xcodeproj/project.pbxproj +++ b/lldb/lldb.xcodeproj/project.pbxproj @@ -844,9 +844,9 @@ AE44FB301BB07EB20033EB62 /* GoUserExpression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE44FB2C1BB07DD80033EB62 /* GoUserExpression.cpp */; }; AE44FB311BB07EB80033EB62 /* GoLexer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE44FB2A1BB07DD80033EB62 /* GoLexer.cpp */; }; AE44FB321BB07EBC0033EB62 /* GoParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE44FB2B1BB07DD80033EB62 /* GoParser.cpp */; }; + AE44FB3E1BB485960033EB62 /* GoLanguageRuntime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE44FB3D1BB485960033EB62 /* GoLanguageRuntime.cpp */; }; AE44FB471BB4BB090033EB62 /* GoLanguage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE44FB451BB4BB090033EB62 /* GoLanguage.cpp */; }; AE44FB4C1BB4BB540033EB62 /* GoFormatterFunctions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE44FB4A1BB4BB540033EB62 /* GoFormatterFunctions.cpp */; }; - AE44FB3E1BB485960033EB62 /* GoLanguageRuntime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE44FB3D1BB485960033EB62 /* GoLanguageRuntime.cpp */; }; AE6897281B94F6DE0018845D /* DWARFASTParserGo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE6897261B94F6DE0018845D /* DWARFASTParserGo.cpp */; }; AE7F56291B8FE418001377A8 /* GoASTContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AEFFBA7C1AC4835D0087B932 /* GoASTContext.cpp */; }; AE8F624919EF3E1E00326B21 /* OperatingSystemGo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE8F624719EF3E1E00326B21 /* OperatingSystemGo.cpp */; }; @@ -885,6 +885,14 @@ AF77E0A41A033D360096C0EA /* RegisterContextPOSIX_powerpc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF77E09D1A033D360096C0EA /* RegisterContextPOSIX_powerpc.cpp */; }; AF77E0A91A033D740096C0EA /* RegisterContextPOSIXCore_powerpc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF77E0A71A033D740096C0EA /* RegisterContextPOSIXCore_powerpc.cpp */; }; AF81DEFA1828A23F0042CF19 /* SystemRuntime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF81DEF91828A23F0042CF19 /* SystemRuntime.cpp */; }; + AF8AD62E1BEC28A400150209 /* PlatformAppleTVSimulator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF8AD62A1BEC28A400150209 /* PlatformAppleTVSimulator.cpp */; }; + AF8AD62F1BEC28A400150209 /* PlatformAppleTVSimulator.h in Headers */ = {isa = PBXBuildFile; fileRef = AF8AD62B1BEC28A400150209 /* PlatformAppleTVSimulator.h */; }; + AF8AD6301BEC28A400150209 /* PlatformAppleWatchSimulator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF8AD62C1BEC28A400150209 /* PlatformAppleWatchSimulator.cpp */; }; + AF8AD6311BEC28A400150209 /* PlatformAppleWatchSimulator.h in Headers */ = {isa = PBXBuildFile; fileRef = AF8AD62D1BEC28A400150209 /* PlatformAppleWatchSimulator.h */; }; + AF8AD6371BEC28C400150209 /* PlatformRemoteAppleTV.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF8AD6331BEC28C400150209 /* PlatformRemoteAppleTV.cpp */; }; + AF8AD6381BEC28C400150209 /* PlatformRemoteAppleTV.h in Headers */ = {isa = PBXBuildFile; fileRef = AF8AD6341BEC28C400150209 /* PlatformRemoteAppleTV.h */; }; + AF8AD6391BEC28C400150209 /* PlatformRemoteAppleWatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF8AD6351BEC28C400150209 /* PlatformRemoteAppleWatch.cpp */; }; + AF8AD63A1BEC28C400150209 /* PlatformRemoteAppleWatch.h in Headers */ = {isa = PBXBuildFile; fileRef = AF8AD6361BEC28C400150209 /* PlatformRemoteAppleWatch.h */; }; AF90106515AB7D3600FF120D /* lldb.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = AF90106315AB7C5700FF120D /* lldb.1 */; }; AF9107EE168570D200DBCD3C /* RegisterContextDarwin_arm64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF9107EC168570D200DBCD3C /* RegisterContextDarwin_arm64.cpp */; }; AF9107EF168570D200DBCD3C /* RegisterContextDarwin_arm64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF9107EC168570D200DBCD3C /* RegisterContextDarwin_arm64.cpp */; }; @@ -2703,12 +2711,12 @@ AE44FB2A1BB07DD80033EB62 /* GoLexer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GoLexer.cpp; path = ExpressionParser/Go/GoLexer.cpp; sourceTree = "<group>"; }; AE44FB2B1BB07DD80033EB62 /* GoParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GoParser.cpp; path = ExpressionParser/Go/GoParser.cpp; sourceTree = "<group>"; }; AE44FB2C1BB07DD80033EB62 /* GoUserExpression.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GoUserExpression.cpp; path = ExpressionParser/Go/GoUserExpression.cpp; sourceTree = "<group>"; }; + AE44FB3C1BB4858A0033EB62 /* GoLanguageRuntime.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = GoLanguageRuntime.h; path = Go/GoLanguageRuntime.h; sourceTree = "<group>"; }; + AE44FB3D1BB485960033EB62 /* GoLanguageRuntime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GoLanguageRuntime.cpp; path = Go/GoLanguageRuntime.cpp; sourceTree = "<group>"; }; AE44FB451BB4BB090033EB62 /* GoLanguage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GoLanguage.cpp; path = Language/Go/GoLanguage.cpp; sourceTree = "<group>"; }; AE44FB461BB4BB090033EB62 /* GoLanguage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GoLanguage.h; path = Language/Go/GoLanguage.h; sourceTree = "<group>"; }; AE44FB4A1BB4BB540033EB62 /* GoFormatterFunctions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GoFormatterFunctions.cpp; path = Language/Go/GoFormatterFunctions.cpp; sourceTree = "<group>"; }; AE44FB4B1BB4BB540033EB62 /* GoFormatterFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GoFormatterFunctions.h; path = Language/Go/GoFormatterFunctions.h; sourceTree = "<group>"; }; - AE44FB3C1BB4858A0033EB62 /* GoLanguageRuntime.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = GoLanguageRuntime.h; path = Go/GoLanguageRuntime.h; sourceTree = "<group>"; }; - AE44FB3D1BB485960033EB62 /* GoLanguageRuntime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GoLanguageRuntime.cpp; path = Go/GoLanguageRuntime.cpp; sourceTree = "<group>"; }; AE6897261B94F6DE0018845D /* DWARFASTParserGo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DWARFASTParserGo.cpp; sourceTree = "<group>"; }; AE6897271B94F6DE0018845D /* DWARFASTParserGo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DWARFASTParserGo.h; sourceTree = "<group>"; }; AE8F624719EF3E1E00326B21 /* OperatingSystemGo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OperatingSystemGo.cpp; path = Go/OperatingSystemGo.cpp; sourceTree = "<group>"; }; @@ -2792,6 +2800,14 @@ AF77E0A71A033D740096C0EA /* RegisterContextPOSIXCore_powerpc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterContextPOSIXCore_powerpc.cpp; sourceTree = "<group>"; }; AF77E0A81A033D740096C0EA /* RegisterContextPOSIXCore_powerpc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterContextPOSIXCore_powerpc.h; sourceTree = "<group>"; }; AF81DEF91828A23F0042CF19 /* SystemRuntime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SystemRuntime.cpp; path = source/Target/SystemRuntime.cpp; sourceTree = "<group>"; }; + AF8AD62A1BEC28A400150209 /* PlatformAppleTVSimulator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlatformAppleTVSimulator.cpp; sourceTree = "<group>"; }; + AF8AD62B1BEC28A400150209 /* PlatformAppleTVSimulator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformAppleTVSimulator.h; sourceTree = "<group>"; }; + AF8AD62C1BEC28A400150209 /* PlatformAppleWatchSimulator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlatformAppleWatchSimulator.cpp; sourceTree = "<group>"; }; + AF8AD62D1BEC28A400150209 /* PlatformAppleWatchSimulator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformAppleWatchSimulator.h; sourceTree = "<group>"; }; + AF8AD6331BEC28C400150209 /* PlatformRemoteAppleTV.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlatformRemoteAppleTV.cpp; sourceTree = "<group>"; }; + AF8AD6341BEC28C400150209 /* PlatformRemoteAppleTV.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformRemoteAppleTV.h; sourceTree = "<group>"; }; + AF8AD6351BEC28C400150209 /* PlatformRemoteAppleWatch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlatformRemoteAppleWatch.cpp; sourceTree = "<group>"; }; + AF8AD6361BEC28C400150209 /* PlatformRemoteAppleWatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformRemoteAppleWatch.h; sourceTree = "<group>"; }; AF90106315AB7C5700FF120D /* lldb.1 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.man; name = lldb.1; path = docs/lldb.1; sourceTree = "<group>"; }; AF9107E91685709A00DBCD3C /* ARM64_Stabs_Registers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ARM64_Stabs_Registers.h; path = source/Utility/ARM64_Stabs_Registers.h; sourceTree = "<group>"; }; AF9107EC168570D200DBCD3C /* RegisterContextDarwin_arm64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RegisterContextDarwin_arm64.cpp; path = Utility/RegisterContextDarwin_arm64.cpp; sourceTree = "<group>"; }; @@ -4937,6 +4953,10 @@ children = ( 9455630A1BEAD0570073F75F /* PlatformAppleSimulator.cpp */, 9455630B1BEAD0570073F75F /* PlatformAppleSimulator.h */, + AF8AD62A1BEC28A400150209 /* PlatformAppleTVSimulator.cpp */, + AF8AD62B1BEC28A400150209 /* PlatformAppleTVSimulator.h */, + AF8AD62C1BEC28A400150209 /* PlatformAppleWatchSimulator.cpp */, + AF8AD62D1BEC28A400150209 /* PlatformAppleWatchSimulator.h */, AF254E2F170CCC33007AE5C9 /* PlatformDarwinKernel.cpp */, AF254E30170CCC33007AE5C9 /* PlatformDarwinKernel.h */, 2697A54B133A6305004E4240 /* PlatformDarwin.cpp */, @@ -4947,6 +4967,10 @@ 9455630D1BEAD0570073F75F /* PlatformiOSSimulatorCoreSimulatorSupport.mm */, 26C5577B132575AD008FD8FE /* PlatformMacOSX.cpp */, 26C5577C132575AD008FD8FE /* PlatformMacOSX.h */, + AF8AD6331BEC28C400150209 /* PlatformRemoteAppleTV.cpp */, + AF8AD6341BEC28C400150209 /* PlatformRemoteAppleTV.h */, + AF8AD6351BEC28C400150209 /* PlatformRemoteAppleWatch.cpp */, + AF8AD6361BEC28C400150209 /* PlatformRemoteAppleWatch.h */, 2675F6FE1332BE690067997B /* PlatformRemoteiOS.cpp */, 2675F6FF1332BE690067997B /* PlatformRemoteiOS.h */, ); @@ -5630,6 +5654,15 @@ name = Go; sourceTree = "<group>"; }; + AE44FB3B1BB485730033EB62 /* Go */ = { + isa = PBXGroup; + children = ( + AE44FB3C1BB4858A0033EB62 /* GoLanguageRuntime.h */, + AE44FB3D1BB485960033EB62 /* GoLanguageRuntime.cpp */, + ); + name = Go; + sourceTree = "<group>"; + }; AE44FB431BB4BAC20033EB62 /* Go */ = { isa = PBXGroup; children = ( @@ -5649,15 +5682,6 @@ name = Formatters; sourceTree = "<group>"; }; - AE44FB3B1BB485730033EB62 /* Go */ = { - isa = PBXGroup; - children = ( - AE44FB3C1BB4858A0033EB62 /* GoLanguageRuntime.h */, - AE44FB3D1BB485960033EB62 /* GoLanguageRuntime.cpp */, - ); - name = Go; - sourceTree = "<group>"; - }; AE8F624519EF3DFC00326B21 /* Go */ = { isa = PBXGroup; children = ( @@ -5857,9 +5881,13 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + AF8AD6381BEC28C400150209 /* PlatformRemoteAppleTV.h in Headers */, 4984BA181B979C08008658D4 /* ExpressionVariable.h in Headers */, + AF8AD62F1BEC28A400150209 /* PlatformAppleTVSimulator.h in Headers */, + AF8AD63A1BEC28C400150209 /* PlatformRemoteAppleWatch.h in Headers */, 257906651BD5AFD000178368 /* Acceptor.h in Headers */, 260A63171861008E00FECF8E /* IOHandler.h in Headers */, + AF8AD6311BEC28A400150209 /* PlatformAppleWatchSimulator.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6425,6 +6453,7 @@ 2689002513353DDE00698AC0 /* CommandObjectSource.cpp in Sources */, 2689002613353DDE00698AC0 /* CommandObjectSyntax.cpp in Sources */, 267A48011B1411E40021A5BC /* XML.cpp in Sources */, + AF8AD6371BEC28C400150209 /* PlatformRemoteAppleTV.cpp in Sources */, 2666ADC61B3CB675001FAFD3 /* DynamicLoaderHexagonDYLD.cpp in Sources */, 3F8169331ABB7A6D001DA9DF /* SystemLifetimeManager.cpp in Sources */, 4959511F1A1BC4BC00F6F8FC /* ClangModulesDeclVendor.cpp in Sources */, @@ -6470,6 +6499,7 @@ 2689004313353E0400698AC0 /* Mangled.cpp in Sources */, 2689004413353E0400698AC0 /* Module.cpp in Sources */, 2689004513353E0400698AC0 /* ModuleChild.cpp in Sources */, + AF8AD6301BEC28A400150209 /* PlatformAppleWatchSimulator.cpp in Sources */, 266E829D1B8E542C008FCA06 /* DWARFAttribute.cpp in Sources */, 2689004613353E0400698AC0 /* ModuleList.cpp in Sources */, 2689004713353E0400698AC0 /* PluginManager.cpp in Sources */, @@ -6480,6 +6510,7 @@ 2689004913353E0400698AC0 /* Scalar.cpp in Sources */, AF20F7701AF1902900751A6E /* RegisterContextLinux_arm64.cpp in Sources */, 263FDE601A79A01500E68013 /* FormatEntity.cpp in Sources */, + AF8AD62E1BEC28A400150209 /* PlatformAppleTVSimulator.cpp in Sources */, 2689004A13353E0400698AC0 /* SearchFilter.cpp in Sources */, 2689004B13353E0400698AC0 /* Section.cpp in Sources */, 4984BA161B979973008658D4 /* ExpressionVariable.cpp in Sources */, @@ -6844,6 +6875,7 @@ 26F4A21C13FBA31A0064B613 /* ThreadMemory.cpp in Sources */, 3FBA69E11B6067120008F44A /* ScriptInterpreterNone.cpp in Sources */, 266DFE9713FD656E00D0C574 /* OperatingSystem.cpp in Sources */, + AF8AD6391BEC28C400150209 /* PlatformRemoteAppleWatch.cpp in Sources */, 26954EBE1401EE8B00294D09 /* DynamicRegisterInfo.cpp in Sources */, 6D9AB3DD1BB2B74E003F2289 /* TypeMap.cpp in Sources */, 255EFF761AFABA950069F277 /* LockFilePosix.cpp in Sources */, diff --git a/lldb/source/API/SystemInitializerFull.cpp b/lldb/source/API/SystemInitializerFull.cpp index 43e0f046ac3..d458cb5daf4 100644 --- a/lldb/source/API/SystemInitializerFull.cpp +++ b/lldb/source/API/SystemInitializerFull.cpp @@ -69,6 +69,10 @@ #include "Plugins/Process/mach-core/ProcessMachCore.h" #include "Plugins/Process/MacOSX-Kernel/ProcessKDP.h" #include "Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h" +#include "Plugins/Platform/MacOSX/PlatformAppleTVSimulator.h" +#include "Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.h" +#include "Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h" +#include "Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h" #endif #if defined(__FreeBSD__) @@ -318,6 +322,10 @@ SystemInitializerFull::Initialize() SymbolVendorMacOSX::Initialize(); ProcessKDP::Initialize(); ProcessMachCore::Initialize(); + PlatformAppleTVSimulator::Initialize(); + PlatformAppleWatchSimulator::Initialize(); + PlatformRemoteAppleTV::Initialize(); + PlatformRemoteAppleWatch::Initialize(); #endif //---------------------------------------------------------------------- // Platform agnostic plugins @@ -424,6 +432,10 @@ SystemInitializerFull::Terminate() ProcessMachCore::Terminate(); ProcessKDP::Terminate(); SymbolVendorMacOSX::Terminate(); + PlatformAppleTVSimulator::Terminate(); + PlatformAppleWatchSimulator::Terminate(); + PlatformRemoteAppleTV::Terminate(); + PlatformRemoteAppleWatch::Terminate(); #endif #if defined(__FreeBSD__) diff --git a/lldb/source/Plugins/Platform/MacOSX/CMakeLists.txt b/lldb/source/Plugins/Platform/MacOSX/CMakeLists.txt index bb91db4df31..02566ab3db0 100644 --- a/lldb/source/Plugins/Platform/MacOSX/CMakeLists.txt +++ b/lldb/source/Plugins/Platform/MacOSX/CMakeLists.txt @@ -3,12 +3,16 @@ list(APPEND PLUGIN_PLATFORM_MACOSX_SOURCES PlatformDarwinKernel.cpp PlatformMacOSX.cpp PlatformRemoteiOS.cpp + PlatformRemoteAppleTV.cpp + PlatformRemoteAppleWatch.cpp ) list(APPEND PLUGIN_PLATFORM_MACOSX_DARWIN_ONLY_SOURCES PlatformAppleSimulator.cpp PlatformiOSSimulator.cpp PlatformiOSSimulatorCoreSimulatorSupport.mm + PlatformAppleTVSimulator.cpp + PlatformAppleWatchSimulator.cpp ) if(CMAKE_SYSTEM_NAME MATCHES "Darwin") diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp new file mode 100644 index 00000000000..fda46375560 --- /dev/null +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp @@ -0,0 +1,442 @@ +//===-- PlatformAppleTVSimulator.cpp ----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "PlatformAppleTVSimulator.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Breakpoint/BreakpointLocation.h" +#include "lldb/Core/ArchSpec.h" +#include "lldb/Core/Error.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleList.h" +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/StreamString.h" +#include "lldb/Host/FileSpec.h" +#include "lldb/Host/Host.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" + +using namespace lldb; +using namespace lldb_private; + +//------------------------------------------------------------------ +// Static Variables +//------------------------------------------------------------------ +static uint32_t g_initialize_count = 0; + +//------------------------------------------------------------------ +// Static Functions +//------------------------------------------------------------------ +void +PlatformAppleTVSimulator::Initialize () +{ + PlatformDarwin::Initialize (); + + if (g_initialize_count++ == 0) + { + PluginManager::RegisterPlugin (PlatformAppleTVSimulator::GetPluginNameStatic(), + PlatformAppleTVSimulator::GetDescriptionStatic(), + PlatformAppleTVSimulator::CreateInstance); + } +} + +void +PlatformAppleTVSimulator::Terminate () +{ + if (g_initialize_count > 0) + { + if (--g_initialize_count == 0) + { + PluginManager::UnregisterPlugin (PlatformAppleTVSimulator::CreateInstance); + } + } + + PlatformDarwin::Terminate (); +} + +PlatformSP +PlatformAppleTVSimulator::CreateInstance (bool force, const ArchSpec *arch) +{ + bool create = force; + if (create == false && arch && arch->IsValid()) + { + switch (arch->GetMachine()) + { + case llvm::Triple::x86_64: + { + const llvm::Triple &triple = arch->GetTriple(); + switch (triple.getVendor()) + { + case llvm::Triple::Apple: + create = true; + break; + +#if defined(__APPLE__) + // Only accept "unknown" for the vendor if the host is Apple and + // it "unknown" wasn't specified (it was just returned because it + // was NOT specified) + case llvm::Triple::UnknownArch: + create = !arch->TripleVendorWasSpecified(); + break; +#endif + default: + break; + } + + if (create) + { + switch (triple.getOS()) + { + case llvm::Triple::TvOS: + break; + +#if defined(__APPLE__) + // Only accept "unknown" for the OS if the host is Apple and + // it "unknown" wasn't specified (it was just returned because it + // was NOT specified) + case llvm::Triple::UnknownOS: + create = !arch->TripleOSWasSpecified(); + break; +#endif + default: + create = false; + break; + } + } + } + break; + default: + break; + } + } + if (create) + return PlatformSP(new PlatformAppleTVSimulator ()); + return PlatformSP(); +} + + +lldb_private::ConstString +PlatformAppleTVSimulator::GetPluginNameStatic () +{ + static ConstString g_name("tvos-simulator"); + return g_name; +} + +const char * +PlatformAppleTVSimulator::GetDescriptionStatic() +{ + return "Apple TV simulator platform plug-in."; +} + + +//------------------------------------------------------------------ +/// Default Constructor +//------------------------------------------------------------------ +PlatformAppleTVSimulator::PlatformAppleTVSimulator () : + PlatformDarwin (true), + m_sdk_directory () +{ +} + +//------------------------------------------------------------------ +/// Destructor. +/// +/// The destructor is virtual since this class is designed to be +/// inherited from by the plug-in instance. +//------------------------------------------------------------------ +PlatformAppleTVSimulator::~PlatformAppleTVSimulator() +{ +} + + +void +PlatformAppleTVSimulator::GetStatus (Stream &strm) +{ + Platform::GetStatus (strm); + const char *sdk_directory = GetSDKDirectoryAsCString(); + if (sdk_directory) + strm.Printf (" SDK Path: \"%s\"\n", sdk_directory); + else + strm.PutCString (" SDK Path: error: unable to locate SDK\n"); +} + + +Error +PlatformAppleTVSimulator::ResolveExecutable (const ModuleSpec &module_spec, + lldb::ModuleSP &exe_module_sp, + const FileSpecList *module_search_paths_ptr) +{ + Error error; + // Nothing special to do here, just use the actual file and architecture + + ModuleSpec resolved_module_spec(module_spec); + + // If we have "ls" as the exe_file, resolve the executable loation based on + // the current path variables + // TODO: resolve bare executables in the Platform SDK +// if (!resolved_exe_file.Exists()) +// resolved_exe_file.ResolveExecutableLocation (); + + // Resolve any executable within a bundle on MacOSX + // TODO: verify that this handles shallow bundles, if not then implement one ourselves + Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec()); + + if (resolved_module_spec.GetFileSpec().Exists()) + { + if (resolved_module_spec.GetArchitecture().IsValid()) + { + error = ModuleList::GetSharedModule (resolved_module_spec, + exe_module_sp, + NULL, + NULL, + NULL); + + if (exe_module_sp && exe_module_sp->GetObjectFile()) + return error; + exe_module_sp.reset(); + } + // No valid architecture was specified or the exact ARM slice wasn't + // found so ask the platform for the architectures that we should be + // using (in the correct order) and see if we can find a match that way + StreamString arch_names; + ArchSpec platform_arch; + for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx) + { + // Only match x86 with x86 and x86_64 with x86_64... + if (!module_spec.GetArchitecture().IsValid() || module_spec.GetArchitecture().GetCore() == resolved_module_spec.GetArchitecture().GetCore()) + { + error = ModuleList::GetSharedModule (resolved_module_spec, + exe_module_sp, + NULL, + NULL, + NULL); + // Did we find an executable using one of the + if (error.Success()) + { + if (exe_module_sp && exe_module_sp->GetObjectFile()) + break; + else + error.SetErrorToGenericError(); + } + + if (idx > 0) + arch_names.PutCString (", "); + arch_names.PutCString (platform_arch.GetArchitectureName()); + } + } + + if (error.Fail() || !exe_module_sp) + { + if (resolved_module_spec.GetFileSpec().Readable()) + { + error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s", + resolved_module_spec.GetFileSpec().GetPath().c_str(), + GetPluginName().GetCString(), + arch_names.GetString().c_str()); + } + else + { + error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str()); + } + } + } + else + { + error.SetErrorStringWithFormat ("'%s' does not exist", + module_spec.GetFileSpec().GetPath().c_str()); + } + + return error; +} + +static FileSpec::EnumerateDirectoryResult +EnumerateDirectoryCallback (void *baton, FileSpec::FileType file_type, const FileSpec &file_spec) +{ + if (file_type == FileSpec::eFileTypeDirectory) + { + const char *filename = file_spec.GetFilename().GetCString(); + if (filename && strncmp(filename, "AppleTVSimulator", strlen ("AppleTVSimulator")) == 0) + { + ::snprintf ((char *)baton, PATH_MAX, "%s", filename); + return FileSpec::eEnumerateDirectoryResultQuit; + } + } + return FileSpec::eEnumerateDirectoryResultNext; +} + + + +const char * +PlatformAppleTVSimulator::GetSDKDirectoryAsCString() +{ + Mutex::Locker locker (m_mutex); + if (m_sdk_directory.empty()) + { + const char *developer_dir = GetDeveloperDirectory(); + if (developer_dir) + { + char sdks_directory[PATH_MAX]; + char sdk_dirname[PATH_MAX]; + sdk_dirname[0] = '\0'; + snprintf (sdks_directory, + sizeof(sdks_directory), + "%s/Platforms/AppleTVSimulator.platform/Developer/SDKs", + developer_dir); + FileSpec simulator_sdk_spec; + bool find_directories = true; + bool find_files = false; + bool find_other = false; + FileSpec::EnumerateDirectory (sdks_directory, + find_directories, + find_files, + find_other, + EnumerateDirectoryCallback, + sdk_dirname); + + if (sdk_dirname[0]) + { + m_sdk_directory = sdks_directory; + m_sdk_directory.append (1, '/'); + m_sdk_directory.append (sdk_dirname); + return m_sdk_directory.c_str(); + } + } + // Assign a single NULL character so we know we tried to find the device + // support directory and we don't keep trying to find it over and over. + m_sdk_directory.assign (1, '\0'); + } + + // We should have put a single NULL character into m_sdk_directory + // or it should have a valid path if the code gets here + assert (m_sdk_directory.empty() == false); + if (m_sdk_directory[0]) + return m_sdk_directory.c_str(); + return NULL; +} + +Error +PlatformAppleTVSimulator::GetSymbolFile (const FileSpec &platform_file, + const UUID *uuid_ptr, + FileSpec &local_file) +{ + Error error; + char platform_file_path[PATH_MAX]; + if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) + { + char resolved_path[PATH_MAX]; + + const char * sdk_dir = GetSDKDirectoryAsCString(); + if (sdk_dir) + { + ::snprintf (resolved_path, + sizeof(resolved_path), + "%s/%s", + sdk_dir, + platform_file_path); + + // First try in the SDK and see if the file is in there + local_file.SetFile(resolved_path, true); + if (local_file.Exists()) + return error; + + // Else fall back to the actual path itself + local_file.SetFile(platform_file_path, true); + if (local_file.Exists()) + return error; + + } + error.SetErrorStringWithFormat ("unable to locate a platform file for '%s' in platform '%s'", + platform_file_path, + GetPluginName().GetCString()); + } + else + { + error.SetErrorString ("invalid platform file argument"); + } + return error; +} + +Error +PlatformAppleTVSimulator::GetSharedModule (const ModuleSpec &module_spec, + lldb_private::Process* process, + ModuleSP &module_sp, + const FileSpecList *module_search_paths_ptr, + ModuleSP *old_module_sp_ptr, + bool *did_create_ptr) +{ + // For AppleTV, the SDK files are all cached locally on the host + // system. So first we ask for the file in the cached SDK, + // then we attempt to get a shared module for the right architecture + // with the right UUID. + Error error; + ModuleSpec platform_module_spec (module_spec); + const FileSpec &platform_file = module_spec.GetFileSpec(); + error = GetSymbolFile (platform_file, module_spec.GetUUIDPtr(), platform_module_spec.GetFileSpec()); + if (error.Success()) + { + error = ResolveExecutable (platform_module_spec, module_sp, module_search_paths_ptr); + } + else + { + const bool always_create = false; + error = ModuleList::GetSharedModule (module_spec, + module_sp, + module_search_paths_ptr, + old_module_sp_ptr, + did_create_ptr, + always_create); + + } + if (module_sp) + module_sp->SetPlatformFileSpec(platform_file); + + return error; +} + + +uint32_t +PlatformAppleTVSimulator::FindProcesses (const ProcessInstanceInfoMatch &match_info, + ProcessInstanceInfoList &process_infos) +{ + ProcessInstanceInfoList all_osx_process_infos; + // First we get all OSX processes + const uint32_t n = Host::FindProcesses (match_info, all_osx_process_infos); + + // Now we filter them down to only the TvOS triples + for (uint32_t i=0; i<n; ++i) + { + const ProcessInstanceInfo &proc_info = all_osx_process_infos.GetProcessInfoAtIndex(i); + if (proc_info.GetArchitecture().GetTriple().getOS() == llvm::Triple::TvOS) { + process_infos.Append(proc_info); + } + } + return process_infos.GetSize(); +} + +bool +PlatformAppleTVSimulator::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) +{ + static const ArchSpec platform_arch(HostInfo::GetArchitecture(HostInfo::eArchKind64)); + + if (idx == 0) + { + arch = platform_arch; + if (arch.IsValid()) + { + arch.GetTriple().setOS (llvm::Triple::TvOS); + return true; + } + } + return false; +} diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.h b/lldb/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.h new file mode 100644 index 00000000000..0990f072920 --- /dev/null +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.h @@ -0,0 +1,121 @@ +//===-- PlatformAppleTVSimulator.h ------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_PlatformAppleTVSimulator_h_ +#define liblldb_PlatformAppleTVSimulator_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "PlatformDarwin.h" + +class PlatformAppleTVSimulator : public PlatformDarwin +{ +public: + + //------------------------------------------------------------ + // Class Functions + //------------------------------------------------------------ + static lldb::PlatformSP + CreateInstance (bool force, const lldb_private::ArchSpec *arch); + + static void + Initialize (); + + static void + Terminate (); + + static lldb_private::ConstString + GetPluginNameStatic (); + + static const char * + GetDescriptionStatic(); + + //------------------------------------------------------------ + // Class Methods + //------------------------------------------------------------ + PlatformAppleTVSimulator (); + + virtual + ~PlatformAppleTVSimulator(); + + //------------------------------------------------------------ + // lldb_private::PluginInterface functions + //------------------------------------------------------------ + lldb_private::ConstString + GetPluginName() override + { + return GetPluginNameStatic(); + } + + uint32_t + GetPluginVersion() override + { + return 1; + } + + //------------------------------------------------------------ + // lldb_private::Platform functions + //------------------------------------------------------------ + lldb_private::Error + ResolveExecutable (const lldb_private::ModuleSpec &module_spec, + lldb::ModuleSP &module_sp, + const lldb_private::FileSpecList *module_search_paths_ptr) override; + + const char * + GetDescription () override + { + return GetDescriptionStatic(); + } + + void + GetStatus (lldb_private::Stream &strm) override; + + virtual lldb_private::Error + GetSymbolFile (const lldb_private::FileSpec &platform_file, + const lldb_private::UUID *uuid_ptr, + lldb_private::FileSpec &local_file); + + lldb_private::Error + GetSharedModule (const lldb_private::ModuleSpec &module_spec, + lldb_private::Process* process, + lldb::ModuleSP &module_sp, + const lldb_private::FileSpecList *module_search_paths_ptr, + lldb::ModuleSP *old_module_sp_ptr, + bool *did_create_ptr) override; + + uint32_t + FindProcesses (const lldb_private::ProcessInstanceInfoMatch &match_info, + lldb_private::ProcessInstanceInfoList &process_infos) override; + + bool + GetSupportedArchitectureAtIndex (uint32_t idx, + lldb_private::ArchSpec &arch) override; + + void + AddClangModuleCompilationOptions (lldb_private::Target *target, std::vector<std::string> &options) override + { + return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(target, options, PlatformDarwin::SDKType::iPhoneSimulator); + } + +protected: + std::string m_sdk_directory; + std::string m_build_update; + + const char * + GetSDKDirectoryAsCString(); + +private: + DISALLOW_COPY_AND_ASSIGN (PlatformAppleTVSimulator); + +}; + + +#endif // liblldb_PlatformAppleTVSimulator_h_ diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp new file mode 100644 index 00000000000..03bfb5fbbe2 --- /dev/null +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp @@ -0,0 +1,442 @@ +//===-- PlatformAppleWatchSimulator.cpp -------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "PlatformAppleWatchSimulator.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Breakpoint/BreakpointLocation.h" +#include "lldb/Core/ArchSpec.h" +#include "lldb/Core/Error.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleList.h" +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/StreamString.h" +#include "lldb/Host/FileSpec.h" +#include "lldb/Host/Host.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" + +using namespace lldb; +using namespace lldb_private; + +//------------------------------------------------------------------ +// Static Variables +//------------------------------------------------------------------ +static uint32_t g_initialize_count = 0; + +//------------------------------------------------------------------ +// Static Functions +//------------------------------------------------------------------ +void +PlatformAppleWatchSimulator::Initialize () +{ + PlatformDarwin::Initialize (); + + if (g_initialize_count++ == 0) + { + PluginManager::RegisterPlugin (PlatformAppleWatchSimulator::GetPluginNameStatic(), + PlatformAppleWatchSimulator::GetDescriptionStatic(), + PlatformAppleWatchSimulator::CreateInstance); + } +} + +void +PlatformAppleWatchSimulator::Terminate () +{ + if (g_initialize_count > 0) + { + if (--g_initialize_count == 0) + { + PluginManager::UnregisterPlugin (PlatformAppleWatchSimulator::CreateInstance); + } + } + + PlatformDarwin::Terminate (); +} + +PlatformSP +PlatformAppleWatchSimulator::CreateInstance (bool force, const ArchSpec *arch) +{ + bool create = force; + if (create == false && arch && arch->IsValid()) + { + switch (arch->GetMachine()) + { + case llvm::Triple::x86_64: + { + const llvm::Triple &triple = arch->GetTriple(); + switch (triple.getVendor()) + { + case llvm::Triple::Apple: + create = true; + break; + +#if defined(__APPLE__) + // Only accept "unknown" for the vendor if the host is Apple and + // it "unknown" wasn't specified (it was just returned because it + // was NOT specified) + case llvm::Triple::UnknownArch: + create = !arch->TripleVendorWasSpecified(); + break; +#endif + default: + break; + } + + if (create) + { + switch (triple.getOS()) + { + case llvm::Triple::WatchOS: + break; + +#if defined(__APPLE__) + // Only accept "unknown" for the OS if the host is Apple and + // it "unknown" wasn't specified (it was just returned because it + // was NOT specified) + case llvm::Triple::UnknownOS: + create = !arch->TripleOSWasSpecified(); + break; +#endif + default: + create = false; + break; + } + } + } + break; + default: + break; + } + } + if (create) + return PlatformSP(new PlatformAppleWatchSimulator ()); + return PlatformSP(); +} + + +lldb_private::ConstString +PlatformAppleWatchSimulator::GetPluginNameStatic () +{ + static ConstString g_name("watchos-simulator"); + return g_name; +} + +const char * +PlatformAppleWatchSimulator::GetDescriptionStatic() +{ + return "Apple Watch simulator platform plug-in."; +} + + +//------------------------------------------------------------------ +/// Default Constructor +//------------------------------------------------------------------ +PlatformAppleWatchSimulator::PlatformAppleWatchSimulator () : + PlatformDarwin (true), + m_sdk_directory () +{ +} + +//------------------------------------------------------------------ +/// Destructor. +/// +/// The destructor is virtual since this class is designed to be +/// inherited from by the plug-in instance. +//------------------------------------------------------------------ +PlatformAppleWatchSimulator::~PlatformAppleWatchSimulator() +{ +} + + +void +PlatformAppleWatchSimulator::GetStatus (Stream &strm) +{ + Platform::GetStatus (strm); + const char *sdk_directory = GetSDKDirectoryAsCString(); + if (sdk_directory) + strm.Printf (" SDK Path: \"%s\"\n", sdk_directory); + else + strm.PutCString (" SDK Path: error: unable to locate SDK\n"); +} + + +Error +PlatformAppleWatchSimulator::ResolveExecutable (const ModuleSpec &module_spec, + lldb::ModuleSP &exe_module_sp, + const FileSpecList *module_search_paths_ptr) +{ + Error error; + // Nothing special to do here, just use the actual file and architecture + + ModuleSpec resolved_module_spec(module_spec); + + // If we have "ls" as the exe_file, resolve the executable loation based on + // the current path variables + // TODO: resolve bare executables in the Platform SDK +// if (!resolved_exe_file.Exists()) +// resolved_exe_file.ResolveExecutableLocation (); + + // Resolve any executable within a bundle on MacOSX + // TODO: verify that this handles shallow bundles, if not then implement one ourselves + Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec()); + + if (resolved_module_spec.GetFileSpec().Exists()) + { + if (resolved_module_spec.GetArchitecture().IsValid()) + { + error = ModuleList::GetSharedModule (resolved_module_spec, + exe_module_sp, + NULL, + NULL, + NULL); + + if (exe_module_sp && exe_module_sp->GetObjectFile()) + return error; + exe_module_sp.reset(); + } + // No valid architecture was specified or the exact ARM slice wasn't + // found so ask the platform for the architectures that we should be + // using (in the correct order) and see if we can find a match that way + StreamString arch_names; + ArchSpec platform_arch; + for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx) + { + // Only match x86 with x86 and x86_64 with x86_64... + if (!module_spec.GetArchitecture().IsValid() || module_spec.GetArchitecture().GetCore() == resolved_module_spec.GetArchitecture().GetCore()) + { + error = ModuleList::GetSharedModule (resolved_module_spec, + exe_module_sp, + NULL, + NULL, + NULL); + // Did we find an executable using one of the + if (error.Success()) + { + if (exe_module_sp && exe_module_sp->GetObjectFile()) + break; + else + error.SetErrorToGenericError(); + } + + if (idx > 0) + arch_names.PutCString (", "); + arch_names.PutCString (platform_arch.GetArchitectureName()); + } + } + + if (error.Fail() || !exe_module_sp) + { + if (resolved_module_spec.GetFileSpec().Readable()) + { + error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s", + resolved_module_spec.GetFileSpec().GetPath().c_str(), + GetPluginName().GetCString(), + arch_names.GetString().c_str()); + } + else + { + error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str()); + } + } + } + else + { + error.SetErrorStringWithFormat ("'%s' does not exist", + module_spec.GetFileSpec().GetPath().c_str()); + } + + return error; +} + +static FileSpec::EnumerateDirectoryResult +EnumerateDirectoryCallback (void *baton, FileSpec::FileType file_type, const FileSpec &file_spec) +{ + if (file_type == FileSpec::eFileTypeDirectory) + { + const char *filename = file_spec.GetFilename().GetCString(); + if (filename && strncmp(filename, "AppleWatchSimulator", strlen ("AppleWatchSimulator")) == 0) + { + ::snprintf ((char *)baton, PATH_MAX, "%s", filename); + return FileSpec::eEnumerateDirectoryResultQuit; + } + } + return FileSpec::eEnumerateDirectoryResultNext; +} + + + +const char * +PlatformAppleWatchSimulator::GetSDKDirectoryAsCString() +{ + Mutex::Locker locker (m_mutex); + if (m_sdk_directory.empty()) + { + const char *developer_dir = GetDeveloperDirectory(); + if (developer_dir) + { + char sdks_directory[PATH_MAX]; + char sdk_dirname[PATH_MAX]; + sdk_dirname[0] = '\0'; + snprintf (sdks_directory, + sizeof(sdks_directory), + "%s/Platforms/AppleWatchSimulator.platform/Developer/SDKs", + developer_dir); + FileSpec simulator_sdk_spec; + bool find_directories = true; + bool find_files = false; + bool find_other = false; + FileSpec::EnumerateDirectory (sdks_directory, + find_directories, + find_files, + find_other, + EnumerateDirectoryCallback, + sdk_dirname); + + if (sdk_dirname[0]) + { + m_sdk_directory = sdks_directory; + m_sdk_directory.append (1, '/'); + m_sdk_directory.append (sdk_dirname); + return m_sdk_directory.c_str(); + } + } + // Assign a single NULL character so we know we tried to find the device + // support directory and we don't keep trying to find it over and over. + m_sdk_directory.assign (1, '\0'); + } + + // We should have put a single NULL character into m_sdk_directory + // or it should have a valid path if the code gets here + assert (m_sdk_directory.empty() == false); + if (m_sdk_directory[0]) + return m_sdk_directory.c_str(); + return NULL; +} + +Error +PlatformAppleWatchSimulator::GetSymbolFile (const FileSpec &platform_file, + const UUID *uuid_ptr, + FileSpec &local_file) +{ + Error error; + char platform_file_path[PATH_MAX]; + if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) + { + char resolved_path[PATH_MAX]; + + const char * sdk_dir = GetSDKDirectoryAsCString(); + if (sdk_dir) + { + ::snprintf (resolved_path, + sizeof(resolved_path), + "%s/%s", + sdk_dir, + platform_file_path); + + // First try in the SDK and see if the file is in there + local_file.SetFile(resolved_path, true); + if (local_file.Exists()) + return error; + + // Else fall back to the actual path itself + local_file.SetFile(platform_file_path, true); + if (local_file.Exists()) + return error; + + } + error.SetErrorStringWithFormat ("unable to locate a platform file for '%s' in platform '%s'", + platform_file_path, + GetPluginName().GetCString()); + } + else + { + error.SetErrorString ("invalid platform file argument"); + } + return error; +} + +Error +PlatformAppleWatchSimulator::GetSharedModule (const ModuleSpec &module_spec, + lldb_private::Process* process, + ModuleSP &module_sp, + const FileSpecList *module_search_paths_ptr, + ModuleSP *old_module_sp_ptr, + bool *did_create_ptr) +{ + // For AppleWatch, the SDK files are all cached locally on the host + // system. So first we ask for the file in the cached SDK, + // then we attempt to get a shared module for the right architecture + // with the right UUID. + Error error; + ModuleSpec platform_module_spec (module_spec); + const FileSpec &platform_file = module_spec.GetFileSpec(); + error = GetSymbolFile (platform_file, module_spec.GetUUIDPtr(), platform_module_spec.GetFileSpec()); + if (error.Success()) + { + error = ResolveExecutable (platform_module_spec, module_sp, module_search_paths_ptr); + } + else + { + const bool always_create = false; + error = ModuleList::GetSharedModule (module_spec, + module_sp, + module_search_paths_ptr, + old_module_sp_ptr, + did_create_ptr, + always_create); + + } + if (module_sp) + module_sp->SetPlatformFileSpec(platform_file); + + return error; +} + + +uint32_t +PlatformAppleWatchSimulator::FindProcesses (const ProcessInstanceInfoMatch &match_info, + ProcessInstanceInfoList &process_infos) +{ + ProcessInstanceInfoList all_osx_process_infos; + // First we get all OSX processes + const uint32_t n = Host::FindProcesses (match_info, all_osx_process_infos); + + // Now we filter them down to only the WatchOS triples + for (uint32_t i=0; i<n; ++i) + { + const ProcessInstanceInfo &proc_info = all_osx_process_infos.GetProcessInfoAtIndex(i); + if (proc_info.GetArchitecture().GetTriple().getOS() == llvm::Triple::WatchOS) { + process_infos.Append(proc_info); + } + } + return process_infos.GetSize(); +} + +bool +PlatformAppleWatchSimulator::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) +{ + static const ArchSpec platform_arch(HostInfo::GetArchitecture(HostInfo::eArchKind64)); + + if (idx == 0) + { + arch = platform_arch; + if (arch.IsValid()) + { + arch.GetTriple().setOS (llvm::Triple::WatchOS); + return true; + } + } + return false; +} diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.h b/lldb/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.h new file mode 100644 index 00000000000..8bcc0d4784f --- /dev/null +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.h @@ -0,0 +1,120 @@ +//===-- PlatformAppleWatchSimulator.h ---------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_PlatformAppleWatchSimulator_h_ +#define liblldb_PlatformAppleWatchSimulator_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "PlatformDarwin.h" + +class PlatformAppleWatchSimulator : public PlatformDarwin +{ +public: + + //------------------------------------------------------------ + // Class Functions + //------------------------------------------------------------ + static lldb::PlatformSP + CreateInstance (bool force, const lldb_private::ArchSpec *arch); + + static void + Initialize (); + + static void + Terminate (); + + static lldb_private::ConstString + GetPluginNameStatic (); + + static const char * + GetDescriptionStatic(); + + //------------------------------------------------------------ + // Class Methods + //------------------------------------------------------------ + PlatformAppleWatchSimulator (); + + virtual + ~PlatformAppleWatchSimulator(); + + //------------------------------------------------------------ + // lldb_private::PluginInterface functions + //------------------------------------------------------------ + lldb_private::ConstString + GetPluginName() override + { + return GetPluginNameStatic(); + } + + uint32_t + GetPluginVersion() override + { + return 1; + } + + //------------------------------------------------------------ + // lldb_private::Platform functions + //------------------------------------------------------------ + lldb_private::Error + ResolveExecutable (const lldb_private::ModuleSpec &module_spec, + lldb::ModuleSP &module_sp, + const lldb_private::FileSpecList *module_search_paths_ptr) override; + + const char * + GetDescription () override + { + return GetDescriptionStatic(); + } + + void + GetStatus (lldb_private::Stream &strm) override; + + virtual lldb_private::Error + GetSymbolFile (const lldb_private::FileSpec &platform_file, + const lldb_private::UUID *uuid_ptr, + lldb_private::FileSpec &local_file); + + lldb_private::Error + GetSharedModule (const lldb_private::ModuleSpec &module_spec, + lldb_private::Process* process, + lldb::ModuleSP &module_sp, + const lldb_private::FileSpecList *module_search_paths_ptr, + lldb::ModuleSP *old_module_sp_ptr, + bool *did_create_ptr) override; + + uint32_t + FindProcesses (const lldb_private::ProcessInstanceInfoMatch &match_info, + lldb_private::ProcessInstanceInfoList &process_infos) override; + + bool + GetSupportedArchitectureAtIndex (uint32_t idx, + lldb_private::ArchSpec &arch) override; + + void + AddClangModuleCompilationOptions (lldb_private::Target *target, std::vector<std::string> &options) override + { + return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(target, options, PlatformDarwin::SDKType::iPhoneSimulator); + } + +protected: + std::string m_sdk_directory; + std::string m_build_update; + + const char * + GetSDKDirectoryAsCString(); + +private: + DISALLOW_COPY_AND_ASSIGN (PlatformAppleWatchSimulator); + +}; + +#endif // liblldb_PlatformAppleWatchSimulator_h_ diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp new file mode 100644 index 00000000000..3eed85f4e0a --- /dev/null +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp @@ -0,0 +1,905 @@ +//===-- PlatformRemoteAppleTV.cpp -------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "PlatformRemoteAppleTV.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Breakpoint/BreakpointLocation.h" +#include "lldb/Core/ArchSpec.h" +#include "lldb/Core/Error.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleList.h" +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/StreamString.h" +#include "lldb/Host/FileSpec.h" +#include "lldb/Host/Host.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" + +using namespace lldb; +using namespace lldb_private; + +PlatformRemoteAppleTV::SDKDirectoryInfo::SDKDirectoryInfo (const lldb_private::FileSpec &sdk_dir) : + directory(sdk_dir), + build(), + version_major(0), + version_minor(0), + version_update(0), + user_cached(false) +{ + const char *dirname_cstr = sdk_dir.GetFilename().GetCString(); + const char *pos = Args::StringToVersion (dirname_cstr, + version_major, + version_minor, + version_update); + + if (pos && pos[0] == ' ' && pos[1] == '(') + { + const char *build_start = pos + 2; + const char *end_paren = strchr (build_start, ')'); + if (end_paren && build_start < end_paren) + build.SetCStringWithLength(build_start, end_paren - build_start); + } +} + +//------------------------------------------------------------------ +// Static Variables +//------------------------------------------------------------------ +static uint32_t g_initialize_count = 0; + +//------------------------------------------------------------------ +// Static Functions +//------------------------------------------------------------------ +void +PlatformRemoteAppleTV::Initialize () +{ + PlatformDarwin::Initialize (); + + if (g_initialize_count++ == 0) + { + PluginManager::RegisterPlugin (PlatformRemoteAppleTV::GetPluginNameStatic(), + PlatformRemoteAppleTV::GetDescriptionStatic(), + PlatformRemoteAppleTV::CreateInstance); + } +} + +void +PlatformRemoteAppleTV::Terminate () +{ + if (g_initialize_count > 0) + { + if (--g_initialize_count == 0) + { + PluginManager::UnregisterPlugin (PlatformRemoteAppleTV::CreateInstance); + } + } + + PlatformDarwin::Terminate (); +} + +PlatformSP +PlatformRemoteAppleTV::CreateInstance (bool force, const ArchSpec *arch) +{ + bool create = force; + if (create == false && arch && arch->IsValid()) + { + switch (arch->GetMachine()) + { + case llvm::Triple::arm: + case llvm::Triple::aarch64: + case llvm::Triple::thumb: + { + const llvm::Triple &triple = arch->GetTriple(); + llvm::Triple::VendorType vendor = triple.getVendor(); + switch (vendor) + { + case llvm::Triple::Apple: + create = true; + break; + +#if defined(__APPLE__) + // Only accept "unknown" for the vendor if the host is Apple and + // it "unknown" wasn't specified (it was just returned because it + // was NOT specified) + case llvm::Triple::UnknownArch: + create = !arch->TripleVendorWasSpecified(); + break; + +#endif + default: + break; + } + if (create) + { + switch (triple.getOS()) + { + case llvm::Triple::TvOS: // This is the right triple value for Apple TV debugging + break; + +#if defined(__APPLE__) + // Only accept "unknown" for the OS if the host is Apple and + // it "unknown" wasn't specified (it was just returned because it + // was NOT specified) + case llvm::Triple::UnknownOS: + create = !arch->TripleOSWasSpecified(); + break; +#endif + default: + create = false; + break; + } + } + } + break; + default: + break; + } + } + + if (create) + return lldb::PlatformSP(new PlatformRemoteAppleTV ()); + return lldb::PlatformSP(); +} + + +lldb_private::ConstString +PlatformRemoteAppleTV::GetPluginNameStatic () +{ + static ConstString g_name("remote-tvos"); + return g_name; +} + +const char * +PlatformRemoteAppleTV::GetDescriptionStatic() +{ + return "Remote Apple TV platform plug-in."; +} + + +//------------------------------------------------------------------ +/// Default Constructor +//------------------------------------------------------------------ +PlatformRemoteAppleTV::PlatformRemoteAppleTV () : + PlatformDarwin (false), // This is a remote platform + m_sdk_directory_infos(), + m_device_support_directory(), + m_device_support_directory_for_os_version (), + m_build_update(), + m_last_module_sdk_idx (UINT32_MAX), + m_connected_module_sdk_idx (UINT32_MAX) +{ +} + +//------------------------------------------------------------------ +/// Destructor. +/// +/// The destructor is virtual since this class is designed to be +/// inherited from by the plug-in instance. +//------------------------------------------------------------------ +PlatformRemoteAppleTV::~PlatformRemoteAppleTV() +{ +} + + +void +PlatformRemoteAppleTV::GetStatus (Stream &strm) +{ + Platform::GetStatus (strm); + const char *sdk_directory = GetDeviceSupportDirectoryForOSVersion(); + if (sdk_directory) + strm.Printf (" SDK Path: \"%s\"\n", sdk_directory); + else + strm.PutCString (" SDK Path: error: unable to locate SDK\n"); + + const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); + for (uint32_t i=0; i<num_sdk_infos; ++i) + { + const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i]; + strm.Printf (" SDK Roots: [%2u] \"%s\"\n", + i, + sdk_dir_info.directory.GetPath().c_str()); + } +} + + +Error +PlatformRemoteAppleTV::ResolveExecutable (const ModuleSpec &ms, + lldb::ModuleSP &exe_module_sp, + const FileSpecList *module_search_paths_ptr) +{ + Error error; + // Nothing special to do here, just use the actual file and architecture + + ModuleSpec resolved_module_spec(ms); + + // Resolve any executable within a bundle on MacOSX + // TODO: verify that this handles shallow bundles, if not then implement one ourselves + Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec()); + + if (resolved_module_spec.GetFileSpec().Exists()) + { + if (resolved_module_spec.GetArchitecture().IsValid() || resolved_module_spec.GetUUID().IsValid()) + { + error = ModuleList::GetSharedModule (resolved_module_spec, + exe_module_sp, + NULL, + NULL, + NULL); + + if (exe_module_sp && exe_module_sp->GetObjectFile()) + return error; + exe_module_sp.reset(); + } + // No valid architecture was specified or the exact ARM slice wasn't + // found so ask the platform for the architectures that we should be + // using (in the correct order) and see if we can find a match that way + StreamString arch_names; + for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx) + { + error = ModuleList::GetSharedModule (resolved_module_spec, + exe_module_sp, + NULL, + NULL, + NULL); + // Did we find an executable using one of the + if (error.Success()) + { + if (exe_module_sp && exe_module_sp->GetObjectFile()) + break; + else + error.SetErrorToGenericError(); + } + + if (idx > 0) + arch_names.PutCString (", "); + arch_names.PutCString (resolved_module_spec.GetArchitecture().GetArchitectureName()); + } + + if (error.Fail() || !exe_module_sp) + { + if (resolved_module_spec.GetFileSpec().Readable()) + { + error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s", + resolved_module_spec.GetFileSpec().GetPath().c_str(), + GetPluginName().GetCString(), + arch_names.GetString().c_str()); + } + else + { + error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str()); + } + } + } + else + { + error.SetErrorStringWithFormat ("'%s' does not exist", + resolved_module_spec.GetFileSpec().GetPath().c_str()); + } + + return error; +} + +FileSpec::EnumerateDirectoryResult +PlatformRemoteAppleTV::GetContainedFilesIntoVectorOfStringsCallback (void *baton, + FileSpec::FileType file_type, + const FileSpec &file_spec) +{ + ((PlatformRemoteAppleTV::SDKDirectoryInfoCollection *)baton)->push_back(PlatformRemoteAppleTV::SDKDirectoryInfo(file_spec)); + return FileSpec::eEnumerateDirectoryResultNext; +} + +bool +PlatformRemoteAppleTV::UpdateSDKDirectoryInfosIfNeeded() +{ + if (m_sdk_directory_infos.empty()) + { + const char *device_support_dir = GetDeviceSupportDirectory(); + if (device_support_dir) + { + const bool find_directories = true; + const bool find_files = false; + const bool find_other = false; + + SDKDirectoryInfoCollection builtin_sdk_directory_infos; + FileSpec::EnumerateDirectory (m_device_support_directory.c_str(), + find_directories, + find_files, + find_other, + GetContainedFilesIntoVectorOfStringsCallback, + &builtin_sdk_directory_infos); + + // Only add SDK directories that have symbols in them, some SDKs only contain + // developer disk images and no symbols, so they aren't useful to us. + FileSpec sdk_symbols_symlink_fspec; + for (const auto &sdk_directory_info : builtin_sdk_directory_infos) + { + sdk_symbols_symlink_fspec = sdk_directory_info.directory; + sdk_symbols_symlink_fspec.AppendPathComponent("Symbols.Internal"); + if (sdk_symbols_symlink_fspec.Exists()) + { + m_sdk_directory_infos.push_back(sdk_directory_info); + } + else + { + sdk_symbols_symlink_fspec.GetFilename().SetCString("Symbols"); + if (sdk_symbols_symlink_fspec.Exists()) + m_sdk_directory_infos.push_back(sdk_directory_info); + } + } + + const uint32_t num_installed = m_sdk_directory_infos.size(); + FileSpec local_sdk_cache("~/Library/Developer/Xcode/tvOS DeviceSupport", true); + if (!local_sdk_cache.Exists()) + { + // Try looking for another possible name + local_sdk_cache = FileSpec("~/Library/Developer/Xcode/Apple TVOS DeviceSupport", true); + } + if (!local_sdk_cache.Exists()) + { + // Try looking for another possible name + local_sdk_cache = FileSpec("~/Library/Developer/Xcode/AppleTVOS DeviceSupport", true); + } + if (!local_sdk_cache.Exists()) + { + // Try looking for another possible name + local_sdk_cache = FileSpec("~/Library/Developer/Xcode/AppleTV OS DeviceSupport", true); + } + if (!local_sdk_cache.Exists()) + { + // Try looking for another possible name + local_sdk_cache = FileSpec("~/Library/Developer/Xcode/Apple TV OS DeviceSupport", true); + } + if (local_sdk_cache.Exists()) + { + char path[PATH_MAX]; + if (local_sdk_cache.GetPath(path, sizeof(path))) + { + FileSpec::EnumerateDirectory (path, + find_directories, + find_files, + find_other, + GetContainedFilesIntoVectorOfStringsCallback, + &m_sdk_directory_infos); + const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); + // First try for an exact match of major, minor and update + for (uint32_t i=num_installed; i<num_sdk_infos; ++i) + { + m_sdk_directory_infos[i].user_cached = true; + } + } + } + } + } + return !m_sdk_directory_infos.empty(); +} + +const PlatformRemoteAppleTV::SDKDirectoryInfo * +PlatformRemoteAppleTV::GetSDKDirectoryForCurrentOSVersion () +{ + uint32_t i; + if (UpdateSDKDirectoryInfosIfNeeded()) + { + const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); + + // Check to see if the user specified a build string. If they did, then + // be sure to match it. + std::vector<bool> check_sdk_info(num_sdk_infos, true); + ConstString build(m_sdk_build); + if (build) + { + for (i=0; i<num_sdk_infos; ++i) + check_sdk_info[i] = m_sdk_directory_infos[i].build == build; + } + + // If we are connected we can find the version of the OS the platform + // us running on and select the right SDK + uint32_t major, minor, update; + if (GetOSVersion(major, minor, update)) + { + if (UpdateSDKDirectoryInfosIfNeeded()) + { + // First try for an exact match of major, minor and update + for (i=0; i<num_sdk_infos; ++i) + { + if (check_sdk_info[i]) + { + if (m_sdk_directory_infos[i].version_major == major && + m_sdk_directory_infos[i].version_minor == minor && + m_sdk_directory_infos[i].version_update == update) + { + return &m_sdk_directory_infos[i]; + } + } + } + // First try for an exact match of major and minor + for (i=0; i<num_sdk_infos; ++i) + { + if (check_sdk_info[i]) + { + if (m_sdk_directory_infos[i].version_major == major && + m_sdk_directory_infos[i].version_minor == minor) + { + return &m_sdk_directory_infos[i]; + } + } + } + // Lastly try to match of major version only.. + for (i=0; i<num_sdk_infos; ++i) + { + if (check_sdk_info[i]) + { + if (m_sdk_directory_infos[i].version_major == major) + { + return &m_sdk_directory_infos[i]; + } + } + } + } + } + else if (build) + { + // No version, just a build number, search for the first one that matches + for (i=0; i<num_sdk_infos; ++i) + if (check_sdk_info[i]) + return &m_sdk_directory_infos[i]; + } + } + return NULL; +} + +const PlatformRemoteAppleTV::SDKDirectoryInfo * +PlatformRemoteAppleTV::GetSDKDirectoryForLatestOSVersion () +{ + const PlatformRemoteAppleTV::SDKDirectoryInfo *result = NULL; + if (UpdateSDKDirectoryInfosIfNeeded()) + { + const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); + // First try for an exact match of major, minor and update + for (uint32_t i=0; i<num_sdk_infos; ++i) + { + const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i]; + if (sdk_dir_info.version_major != UINT32_MAX) + { + if (result == NULL || sdk_dir_info.version_major > result->version_major) + { + result = &sdk_dir_info; + } + else if (sdk_dir_info.version_major == result->version_major) + { + if (sdk_dir_info.version_minor > result->version_minor) + { + result = &sdk_dir_info; + } + else if (sdk_dir_info.version_minor == result->version_minor) + { + if (sdk_dir_info.version_update > result->version_update) + { + result = &sdk_dir_info; + } + } + } + } + } + } + return result; +} + + + +const char * +PlatformRemoteAppleTV::GetDeviceSupportDirectory() +{ + if (m_device_support_directory.empty()) + { + const char *device_support_dir = GetDeveloperDirectory(); + if (device_support_dir) + { + m_device_support_directory.assign (device_support_dir); + m_device_support_directory.append ("/Platforms/AppleTVOS.platform/DeviceSupport"); + } + else + { + // Assign a single NULL character so we know we tried to find the device + // support directory and we don't keep trying to find it over and over. + m_device_support_directory.assign (1, '\0'); + } + } + // We should have put a single NULL character into m_device_support_directory + // or it should have a valid path if the code gets here + assert (m_device_support_directory.empty() == false); + if (m_device_support_directory[0]) + return m_device_support_directory.c_str(); + return NULL; +} + + +const char * +PlatformRemoteAppleTV::GetDeviceSupportDirectoryForOSVersion() +{ + if (m_sdk_sysroot) + return m_sdk_sysroot.GetCString(); + + if (m_device_support_directory_for_os_version.empty()) + { + const PlatformRemoteAppleTV::SDKDirectoryInfo *sdk_dir_info = GetSDKDirectoryForCurrentOSVersion (); + if (sdk_dir_info == NULL) + sdk_dir_info = GetSDKDirectoryForLatestOSVersion (); + if (sdk_dir_info) + { + char path[PATH_MAX]; + if (sdk_dir_info->directory.GetPath(path, sizeof(path))) + { + m_device_support_directory_for_os_version = path; + return m_device_support_directory_for_os_version.c_str(); + } + } + else + { + // Assign a single NULL character so we know we tried to find the device + // support directory and we don't keep trying to find it over and over. + m_device_support_directory_for_os_version.assign (1, '\0'); + } + } + // We should have put a single NULL character into m_device_support_directory_for_os_version + // or it should have a valid path if the code gets here + assert (m_device_support_directory_for_os_version.empty() == false); + if (m_device_support_directory_for_os_version[0]) + return m_device_support_directory_for_os_version.c_str(); + return NULL; +} + +uint32_t +PlatformRemoteAppleTV::FindFileInAllSDKs (const char *platform_file_path, + FileSpecList &file_list) +{ + if (platform_file_path && platform_file_path[0] && UpdateSDKDirectoryInfosIfNeeded()) + { + const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); + lldb_private::FileSpec local_file; + // First try for an exact match of major, minor and update + for (uint32_t sdk_idx=0; sdk_idx<num_sdk_infos; ++sdk_idx) + { + if (GetFileInSDK (platform_file_path, + sdk_idx, + local_file)) + { + file_list.Append(local_file); + } + } + } + return file_list.GetSize(); +} + +bool +PlatformRemoteAppleTV::GetFileInSDK (const char *platform_file_path, + uint32_t sdk_idx, + lldb_private::FileSpec &local_file) +{ + if (sdk_idx < m_sdk_directory_infos.size()) + { + char sdkroot_path[PATH_MAX]; + const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[sdk_idx]; + if (sdk_dir_info.directory.GetPath(sdkroot_path, sizeof(sdkroot_path))) + { + const bool symbols_dirs_only = true; + + return GetFileInSDKRoot (platform_file_path, + sdkroot_path, + symbols_dirs_only, + local_file); + } + } + return false; +} + + +bool +PlatformRemoteAppleTV::GetFileInSDKRoot (const char *platform_file_path, + const char *sdkroot_path, + bool symbols_dirs_only, + lldb_private::FileSpec &local_file) +{ + if (sdkroot_path && sdkroot_path[0] && platform_file_path && platform_file_path[0]) + { + char resolved_path[PATH_MAX]; + + if (!symbols_dirs_only) + { + ::snprintf (resolved_path, + sizeof(resolved_path), + "%s%s", + sdkroot_path, + platform_file_path); + + local_file.SetFile(resolved_path, true); + if (local_file.Exists()) + return true; + } + + ::snprintf (resolved_path, + sizeof(resolved_path), + "%s/Symbols.Internal%s", + sdkroot_path, + platform_file_path); + + local_file.SetFile(resolved_path, true); + if (local_file.Exists()) + return true; + ::snprintf (resolved_path, + sizeof(resolved_path), + "%s/Symbols%s", + sdkroot_path, + platform_file_path); + + local_file.SetFile(resolved_path, true); + if (local_file.Exists()) + return true; + } + return false; +} + + +Error +PlatformRemoteAppleTV::GetSymbolFile (const FileSpec &platform_file, + const UUID *uuid_ptr, + FileSpec &local_file) +{ + Error error; + char platform_file_path[PATH_MAX]; + if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) + { + char resolved_path[PATH_MAX]; + + const char * os_version_dir = GetDeviceSupportDirectoryForOSVersion(); + if (os_version_dir) + { + ::snprintf (resolved_path, + sizeof(resolved_path), + "%s/%s", + os_version_dir, + platform_file_path); + + local_file.SetFile(resolved_path, true); + if (local_file.Exists()) + return error; + + ::snprintf (resolved_path, + sizeof(resolved_path), + "%s/Symbols.Internal/%s", + os_version_dir, + platform_file_path); + + local_file.SetFile(resolved_path, true); + if (local_file.Exists()) + return error; + ::snprintf (resolved_path, + sizeof(resolved_path), + "%s/Symbols/%s", + os_version_dir, + platform_file_path); + + local_file.SetFile(resolved_path, true); + if (local_file.Exists()) + return error; + + } + local_file = platform_file; + if (local_file.Exists()) + return error; + + error.SetErrorStringWithFormat ("unable to locate a platform file for '%s' in platform '%s'", + platform_file_path, + GetPluginName().GetCString()); + } + else + { + error.SetErrorString ("invalid platform file argument"); + } + return error; +} + +Error +PlatformRemoteAppleTV::GetSharedModule (const ModuleSpec &module_spec, + lldb_private::Process* process, + ModuleSP &module_sp, + const FileSpecList *module_search_paths_ptr, + ModuleSP *old_module_sp_ptr, + bool *did_create_ptr) +{ + // For Apple TV, the SDK files are all cached locally on the host + // system. So first we ask for the file in the cached SDK, + // then we attempt to get a shared module for the right architecture + // with the right UUID. + const FileSpec &platform_file = module_spec.GetFileSpec(); + + Error error; + char platform_file_path[PATH_MAX]; + + if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) + { + ModuleSpec platform_module_spec(module_spec); + + UpdateSDKDirectoryInfosIfNeeded(); + + const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); + + // If we are connected we migth be able to correctly deduce the SDK directory + // using the OS build. + const uint32_t connected_sdk_idx = GetConnectedSDKIndex (); + if (connected_sdk_idx < num_sdk_infos) + { + if (GetFileInSDK (platform_file_path, connected_sdk_idx, platform_module_spec.GetFileSpec())) + { + module_sp.reset(); + error = ResolveExecutable (platform_module_spec, + module_sp, + NULL); + if (module_sp) + { + m_last_module_sdk_idx = connected_sdk_idx; + error.Clear(); + return error; + } + } + } + + // Try the last SDK index if it is set as most files from an SDK + // will tend to be valid in that same SDK. + if (m_last_module_sdk_idx < num_sdk_infos) + { + if (GetFileInSDK (platform_file_path, m_last_module_sdk_idx, platform_module_spec.GetFileSpec())) + { + module_sp.reset(); + error = ResolveExecutable (platform_module_spec, + module_sp, + NULL); + if (module_sp) + { + error.Clear(); + return error; + } + } + } + + // First try for an exact match of major, minor and update + for (uint32_t sdk_idx=0; sdk_idx<num_sdk_infos; ++sdk_idx) + { + if (m_last_module_sdk_idx == sdk_idx) + { + // Skip the last module SDK index if we already searched + // it above + continue; + } + if (GetFileInSDK (platform_file_path, sdk_idx, platform_module_spec.GetFileSpec())) + { + //printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str()); + + error = ResolveExecutable (platform_module_spec, module_sp, NULL); + if (module_sp) + { + // Remember the index of the last SDK that we found a file + // in in case the wrong SDK was selected. + m_last_module_sdk_idx = sdk_idx; + error.Clear(); + return error; + } + } + } + } + // Not the module we are looking for... Nothing to see here... + module_sp.reset(); + + // This may not be an SDK-related module. Try whether we can bring in the thing to our local cache. + error = GetSharedModuleWithLocalCache(module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, did_create_ptr); + if (error.Success()) + return error; + + const bool always_create = false; + error = ModuleList::GetSharedModule (module_spec, + module_sp, + module_search_paths_ptr, + old_module_sp_ptr, + did_create_ptr, + always_create); + + if (module_sp) + module_sp->SetPlatformFileSpec(platform_file); + + return error; +} + +bool +PlatformRemoteAppleTV::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) +{ + ArchSpec system_arch (GetSystemArchitecture()); + + const ArchSpec::Core system_core = system_arch.GetCore(); + switch (system_core) + { + default: + switch (idx) + { + case 0: arch.SetTriple ("arm64-apple-tvos"); return true; + case 1: arch.SetTriple ("armv7s-apple-tvos"); return true; + case 2: arch.SetTriple ("armv7-apple-tvos"); return true; + case 3: arch.SetTriple ("thumbv7s-apple-tvos"); return true; + case 4: arch.SetTriple ("thumbv7-apple-tvos"); return true; + default: break; + } + break; + + case ArchSpec::eCore_arm_arm64: + switch (idx) + { + case 0: arch.SetTriple ("arm64-apple-tvos"); return true; + case 1: arch.SetTriple ("armv7s-apple-tvos"); return true; + case 2: arch.SetTriple ("armv7-apple-tvos"); return true; + case 3: arch.SetTriple ("thumbv7s-apple-tvos"); return true; + case 4: arch.SetTriple ("thumbv7-apple-tvos"); return true; + default: break; + } + break; + + case ArchSpec::eCore_arm_armv7s: + switch (idx) + { + case 0: arch.SetTriple ("armv7s-apple-tvos"); return true; + case 1: arch.SetTriple ("armv7-apple-tvos"); return true; + case 2: arch.SetTriple ("thumbv7s-apple-tvos"); return true; + case 3: arch.SetTriple ("thumbv7-apple-tvos"); return true; + default: break; + } + break; + + case ArchSpec::eCore_arm_armv7: + switch (idx) + { + case 0: arch.SetTriple ("armv7-apple-tvos"); return true; + case 1: arch.SetTriple ("thumbv7-apple-tvos"); return true; + default: break; + } + break; + + } + arch.Clear(); + return false; +} + +uint32_t +PlatformRemoteAppleTV::GetConnectedSDKIndex () +{ + if (IsConnected()) + { + if (m_connected_module_sdk_idx == UINT32_MAX) + { + std::string build; + if (GetRemoteOSBuildString(build)) + { + const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); + for (uint32_t i=0; i<num_sdk_infos; ++i) + { + const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i]; + if (strstr(sdk_dir_info.directory.GetFilename().AsCString(""), build.c_str())) + { + m_connected_module_sdk_idx = i; + } + } + } + } + } + else + { + m_connected_module_sdk_idx = UINT32_MAX; + } + return m_connected_module_sdk_idx; +} diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h new file mode 100644 index 00000000000..b989275ceb5 --- /dev/null +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h @@ -0,0 +1,172 @@ +//===-- PlatformRemoteAppleTV.h ---------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_PlatformRemoteAppleTV_h_ +#define liblldb_PlatformRemoteAppleTV_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +#include "lldb/Host/FileSpec.h" + +// Project includes +#include "PlatformDarwin.h" + +class PlatformRemoteAppleTV : public PlatformDarwin +{ +public: + + //------------------------------------------------------------ + // Class Functions + //------------------------------------------------------------ + static lldb::PlatformSP + CreateInstance (bool force, const lldb_private::ArchSpec *arch); + + static void + Initialize (); + + static void + Terminate (); + + static lldb_private::ConstString + GetPluginNameStatic (); + + static const char * + GetDescriptionStatic(); + + //------------------------------------------------------------ + // Class Methods + //------------------------------------------------------------ + PlatformRemoteAppleTV (); + + virtual + ~PlatformRemoteAppleTV(); + + //------------------------------------------------------------ + // lldb_private::PluginInterface functions + //------------------------------------------------------------ + lldb_private::ConstString + GetPluginName() override + { + return GetPluginNameStatic(); + } + + uint32_t + GetPluginVersion() override + { + return 1; + } + + //------------------------------------------------------------ + // lldb_private::Platform functions + //------------------------------------------------------------ + lldb_private::Error + ResolveExecutable (const lldb_private::ModuleSpec &module_spec, + lldb::ModuleSP &module_sp, + const lldb_private::FileSpecList *module_search_paths_ptr) override; + + const char * + GetDescription () override + { + return GetDescriptionStatic(); + } + + void + GetStatus (lldb_private::Stream &strm) override; + + virtual lldb_private::Error + GetSymbolFile (const lldb_private::FileSpec &platform_file, + const lldb_private::UUID *uuid_ptr, + lldb_private::FileSpec &local_file); + + lldb_private::Error + GetSharedModule (const lldb_private::ModuleSpec &module_spec, + lldb_private::Process* process, + lldb::ModuleSP &module_sp, + const lldb_private::FileSpecList *module_search_paths_ptr, + lldb::ModuleSP *old_module_sp_ptr, + bool *did_create_ptr) override; + + bool + GetSupportedArchitectureAtIndex (uint32_t idx, + lldb_private::ArchSpec &arch) override; + + void + AddClangModuleCompilationOptions (lldb_private::Target *target, std::vector<std::string> &options) override + { + return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(target, options, PlatformDarwin::SDKType::iPhoneOS); + } + +protected: + struct SDKDirectoryInfo + { + SDKDirectoryInfo (const lldb_private::FileSpec &sdk_dir_spec); + lldb_private::FileSpec directory; + lldb_private::ConstString build; + uint32_t version_major; + uint32_t version_minor; + uint32_t version_update; + bool user_cached; + }; + typedef std::vector<SDKDirectoryInfo> SDKDirectoryInfoCollection; + SDKDirectoryInfoCollection m_sdk_directory_infos; + std::string m_device_support_directory; + std::string m_device_support_directory_for_os_version; + std::string m_build_update; + uint32_t m_last_module_sdk_idx; + uint32_t m_connected_module_sdk_idx; + + bool + UpdateSDKDirectoryInfosIfNeeded(); + + const char * + GetDeviceSupportDirectory(); + + const char * + GetDeviceSupportDirectoryForOSVersion(); + + const SDKDirectoryInfo * + GetSDKDirectoryForLatestOSVersion (); + + const SDKDirectoryInfo * + GetSDKDirectoryForCurrentOSVersion (); + + static lldb_private::FileSpec::EnumerateDirectoryResult + GetContainedFilesIntoVectorOfStringsCallback (void *baton, + lldb_private::FileSpec::FileType file_type, + const lldb_private::FileSpec &file_spec); + + uint32_t + FindFileInAllSDKs (const char *platform_file_path, + lldb_private::FileSpecList &file_list); + + bool + GetFileInSDK (const char *platform_file_path, + uint32_t sdk_idx, + lldb_private::FileSpec &local_file); + + bool + GetFileInSDKRoot (const char *platform_file_path, + const char *sdkroot_path, + bool symbols_dirs_only, + lldb_private::FileSpec &local_file); + + uint32_t + FindFileInAllSDKs (const lldb_private::FileSpec &platform_file, + lldb_private::FileSpecList &file_list); + + uint32_t + GetConnectedSDKIndex (); + +private: + DISALLOW_COPY_AND_ASSIGN (PlatformRemoteAppleTV); + +}; + +#endif // liblldb_PlatformRemoteAppleTV_h_ diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp new file mode 100644 index 00000000000..13350921d97 --- /dev/null +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp @@ -0,0 +1,939 @@ +//===-- PlatformRemoteAppleWatch.cpp ----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "PlatformRemoteAppleWatch.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Breakpoint/BreakpointLocation.h" +#include "lldb/Core/ArchSpec.h" +#include "lldb/Core/Error.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleList.h" +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/StreamString.h" +#include "lldb/Host/FileSpec.h" +#include "lldb/Host/Host.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" + +using namespace lldb; +using namespace lldb_private; + +PlatformRemoteAppleWatch::SDKDirectoryInfo::SDKDirectoryInfo (const lldb_private::FileSpec &sdk_dir) : + directory(sdk_dir), + build(), + version_major(0), + version_minor(0), + version_update(0), + user_cached(false) +{ + const char *dirname_cstr = sdk_dir.GetFilename().GetCString(); + const char *pos = Args::StringToVersion (dirname_cstr, + version_major, + version_minor, + version_update); + + if (pos && pos[0] == ' ' && pos[1] == '(') + { + const char *build_start = pos + 2; + const char *end_paren = strchr (build_start, ')'); + if (end_paren && build_start < end_paren) + build.SetCStringWithLength(build_start, end_paren - build_start); + } +} + +//------------------------------------------------------------------ +// Static Variables +//------------------------------------------------------------------ +static uint32_t g_initialize_count = 0; + +//------------------------------------------------------------------ +// Static Functions +//------------------------------------------------------------------ +void +PlatformRemoteAppleWatch::Initialize () +{ + PlatformDarwin::Initialize (); + + if (g_initialize_count++ == 0) + { + PluginManager::RegisterPlugin (PlatformRemoteAppleWatch::GetPluginNameStatic(), + PlatformRemoteAppleWatch::GetDescriptionStatic(), + PlatformRemoteAppleWatch::CreateInstance); + } +} + +void +PlatformRemoteAppleWatch::Terminate () +{ + if (g_initialize_count > 0) + { + if (--g_initialize_count == 0) + { + PluginManager::UnregisterPlugin (PlatformRemoteAppleWatch::CreateInstance); + } + } + + PlatformDarwin::Terminate (); +} + +PlatformSP +PlatformRemoteAppleWatch::CreateInstance (bool force, const ArchSpec *arch) +{ + bool create = force; + if (create == false && arch && arch->IsValid()) + { + switch (arch->GetMachine()) + { + case llvm::Triple::arm: + case llvm::Triple::aarch64: + case llvm::Triple::thumb: + { + const llvm::Triple &triple = arch->GetTriple(); + llvm::Triple::VendorType vendor = triple.getVendor(); + switch (vendor) + { + case llvm::Triple::Apple: + create = true; + break; + +#if defined(__APPLE__) + // Only accept "unknown" for the vendor if the host is Apple and + // it "unknown" wasn't specified (it was just returned because it + // was NOT specified) + case llvm::Triple::UnknownArch: + create = !arch->TripleVendorWasSpecified(); + break; + +#endif + default: + break; + } + if (create) + { + switch (triple.getOS()) + { + case llvm::Triple::WatchOS: // This is the right triple value for Apple Watch debugging + break; + +#if defined(__APPLE__) + // Only accept "unknown" for the OS if the host is Apple and + // it "unknown" wasn't specified (it was just returned because it + // was NOT specified) + case llvm::Triple::UnknownOS: + create = !arch->TripleOSWasSpecified(); + break; +#endif + default: + create = false; + break; + } + } + } + break; + default: + break; + } + } + +#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__) || defined(__aarch64__)) + // If lldb is running on a watch, this isn't a RemoteWatch environment; it's a local system environment. + if (force == false) + { + create = false; + } +#endif + + + if (create) + return lldb::PlatformSP(new PlatformRemoteAppleWatch ()); + return lldb::PlatformSP(); +} + + +lldb_private::ConstString +PlatformRemoteAppleWatch::GetPluginNameStatic () +{ + static ConstString g_name("remote-watchos"); + return g_name; +} + +const char * +PlatformRemoteAppleWatch::GetDescriptionStatic() +{ + return "Remote Apple Watch platform plug-in."; +} + + +//------------------------------------------------------------------ +/// Default Constructor +//------------------------------------------------------------------ +PlatformRemoteAppleWatch::PlatformRemoteAppleWatch () : + PlatformDarwin (false), // This is a remote platform + m_sdk_directory_infos(), + m_device_support_directory(), + m_device_support_directory_for_os_version (), + m_build_update(), + m_last_module_sdk_idx (UINT32_MAX), + m_connected_module_sdk_idx (UINT32_MAX) +{ +} + +//------------------------------------------------------------------ +/// Destructor. +/// +/// The destructor is virtual since this class is designed to be +/// inherited from by the plug-in instance. +//------------------------------------------------------------------ +PlatformRemoteAppleWatch::~PlatformRemoteAppleWatch() +{ +} + + +void +PlatformRemoteAppleWatch::GetStatus (Stream &strm) +{ + Platform::GetStatus (strm); + const char *sdk_directory = GetDeviceSupportDirectoryForOSVersion(); + if (sdk_directory) + strm.Printf (" SDK Path: \"%s\"\n", sdk_directory); + else + strm.PutCString (" SDK Path: error: unable to locate SDK\n"); + + const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); + for (uint32_t i=0; i<num_sdk_infos; ++i) + { + const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i]; + strm.Printf (" SDK Roots: [%2u] \"%s\"\n", + i, + sdk_dir_info.directory.GetPath().c_str()); + } +} + + +Error +PlatformRemoteAppleWatch::ResolveExecutable (const ModuleSpec &ms, + lldb::ModuleSP &exe_module_sp, + const FileSpecList *module_search_paths_ptr) +{ + Error error; + // Nothing special to do here, just use the actual file and architecture + + ModuleSpec resolved_module_spec(ms); + + // Resolve any executable within a bundle on MacOSX + // TODO: verify that this handles shallow bundles, if not then implement one ourselves + Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec()); + + if (resolved_module_spec.GetFileSpec().Exists()) + { + if (resolved_module_spec.GetArchitecture().IsValid() || resolved_module_spec.GetUUID().IsValid()) + { + error = ModuleList::GetSharedModule (resolved_module_spec, + exe_module_sp, + NULL, + NULL, + NULL); + + if (exe_module_sp && exe_module_sp->GetObjectFile()) + return error; + exe_module_sp.reset(); + } + // No valid architecture was specified or the exact ARM slice wasn't + // found so ask the platform for the architectures that we should be + // using (in the correct order) and see if we can find a match that way + StreamString arch_names; + for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx) + { + error = ModuleList::GetSharedModule (resolved_module_spec, + exe_module_sp, + NULL, + NULL, + NULL); + // Did we find an executable using one of the + if (error.Success()) + { + if (exe_module_sp && exe_module_sp->GetObjectFile()) + break; + else + error.SetErrorToGenericError(); + } + + if (idx > 0) + arch_names.PutCString (", "); + arch_names.PutCString (resolved_module_spec.GetArchitecture().GetArchitectureName()); + } + + if (error.Fail() || !exe_module_sp) + { + if (resolved_module_spec.GetFileSpec().Readable()) + { + error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s", + resolved_module_spec.GetFileSpec().GetPath().c_str(), + GetPluginName().GetCString(), + arch_names.GetString().c_str()); + } + else + { + error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str()); + } + } + } + else + { + error.SetErrorStringWithFormat ("'%s' does not exist", + resolved_module_spec.GetFileSpec().GetPath().c_str()); + } + + return error; +} + +FileSpec::EnumerateDirectoryResult +PlatformRemoteAppleWatch::GetContainedFilesIntoVectorOfStringsCallback (void *baton, + FileSpec::FileType file_type, + const FileSpec &file_spec) +{ + ((PlatformRemoteAppleWatch::SDKDirectoryInfoCollection *)baton)->push_back(PlatformRemoteAppleWatch::SDKDirectoryInfo(file_spec)); + return FileSpec::eEnumerateDirectoryResultNext; +} + +bool +PlatformRemoteAppleWatch::UpdateSDKDirectoryInfosIfNeeded() +{ + if (m_sdk_directory_infos.empty()) + { + const char *device_support_dir = GetDeviceSupportDirectory(); + if (device_support_dir) + { + const bool find_directories = true; + const bool find_files = false; + const bool find_other = false; + + SDKDirectoryInfoCollection builtin_sdk_directory_infos; + FileSpec::EnumerateDirectory (m_device_support_directory.c_str(), + find_directories, + find_files, + find_other, + GetContainedFilesIntoVectorOfStringsCallback, + &builtin_sdk_directory_infos); + + // Only add SDK directories that have symbols in them, some SDKs only contain + // developer disk images and no symbols, so they aren't useful to us. + FileSpec sdk_symbols_symlink_fspec; + for (const auto &sdk_directory_info : builtin_sdk_directory_infos) + { + sdk_symbols_symlink_fspec = sdk_directory_info.directory; + sdk_symbols_symlink_fspec.AppendPathComponent("Symbols.Internal"); + if (sdk_symbols_symlink_fspec.Exists()) + { + m_sdk_directory_infos.push_back(sdk_directory_info); + } + else + { + sdk_symbols_symlink_fspec.GetFilename().SetCString("Symbols"); + if (sdk_symbols_symlink_fspec.Exists()) + m_sdk_directory_infos.push_back(sdk_directory_info); + } + } + + const uint32_t num_installed = m_sdk_directory_infos.size(); + FileSpec local_sdk_cache("~/Library/Developer/Xcode/watchOS DeviceSupport", true); + if (!local_sdk_cache.Exists()) + { + local_sdk_cache = FileSpec("~/Library/Developer/Xcode/watch OS DeviceSupport", true); + } + if (!local_sdk_cache.Exists()) + { + local_sdk_cache = FileSpec("~/Library/Developer/Xcode/WatchOS DeviceSupport", true); + } + if (!local_sdk_cache.Exists()) + { + local_sdk_cache = FileSpec("~/Library/Developer/Xcode/Watch OS DeviceSupport", true); + } + if (local_sdk_cache.Exists()) + { + char path[PATH_MAX]; + if (local_sdk_cache.GetPath(path, sizeof(path))) + { + FileSpec::EnumerateDirectory (path, + find_directories, + find_files, + find_other, + GetContainedFilesIntoVectorOfStringsCallback, + &m_sdk_directory_infos); + const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); + // First try for an exact match of major, minor and update + for (uint32_t i=num_installed; i<num_sdk_infos; ++i) + { + m_sdk_directory_infos[i].user_cached = true; + } + } + } + } + } + return !m_sdk_directory_infos.empty(); +} + +const PlatformRemoteAppleWatch::SDKDirectoryInfo * +PlatformRemoteAppleWatch::GetSDKDirectoryForCurrentOSVersion () +{ + uint32_t i; + if (UpdateSDKDirectoryInfosIfNeeded()) + { + const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); + + // Check to see if the user specified a build string. If they did, then + // be sure to match it. + std::vector<bool> check_sdk_info(num_sdk_infos, true); + ConstString build(m_sdk_build); + if (build) + { + for (i=0; i<num_sdk_infos; ++i) + check_sdk_info[i] = m_sdk_directory_infos[i].build == build; + } + + // If we are connected we can find the version of the OS the platform + // us running on and select the right SDK + uint32_t major, minor, update; + if (GetOSVersion(major, minor, update)) + { + if (UpdateSDKDirectoryInfosIfNeeded()) + { + // First try for an exact match of major, minor and update + for (i=0; i<num_sdk_infos; ++i) + { + if (check_sdk_info[i]) + { + if (m_sdk_directory_infos[i].version_major == major && + m_sdk_directory_infos[i].version_minor == minor && + m_sdk_directory_infos[i].version_update == update) + { + return &m_sdk_directory_infos[i]; + } + } + } + // First try for an exact match of major and minor + for (i=0; i<num_sdk_infos; ++i) + { + if (check_sdk_info[i]) + { + if (m_sdk_directory_infos[i].version_major == major && + m_sdk_directory_infos[i].version_minor == minor) + { + return &m_sdk_directory_infos[i]; + } + } + } + // Lastly try to match of major version only.. + for (i=0; i<num_sdk_infos; ++i) + { + if (check_sdk_info[i]) + { + if (m_sdk_directory_infos[i].version_major == major) + { + return &m_sdk_directory_infos[i]; + } + } + } + } + } + else if (build) + { + // No version, just a build number, search for the first one that matches + for (i=0; i<num_sdk_infos; ++i) + if (check_sdk_info[i]) + return &m_sdk_directory_infos[i]; + } + } + return NULL; +} + +const PlatformRemoteAppleWatch::SDKDirectoryInfo * +PlatformRemoteAppleWatch::GetSDKDirectoryForLatestOSVersion () +{ + const PlatformRemoteAppleWatch::SDKDirectoryInfo *result = NULL; + if (UpdateSDKDirectoryInfosIfNeeded()) + { + const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); + // First try for an exact match of major, minor and update + for (uint32_t i=0; i<num_sdk_infos; ++i) + { + const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i]; + if (sdk_dir_info.version_major != UINT32_MAX) + { + if (result == NULL || sdk_dir_info.version_major > result->version_major) + { + result = &sdk_dir_info; + } + else if (sdk_dir_info.version_major == result->version_major) + { + if (sdk_dir_info.version_minor > result->version_minor) + { + result = &sdk_dir_info; + } + else if (sdk_dir_info.version_minor == result->version_minor) + { + if (sdk_dir_info.version_update > result->version_update) + { + result = &sdk_dir_info; + } + } + } + } + } + } + return result; +} + + + +const char * +PlatformRemoteAppleWatch::GetDeviceSupportDirectory() +{ + if (m_device_support_directory.empty()) + { + const char *device_support_dir = GetDeveloperDirectory(); + if (device_support_dir) + { + m_device_support_directory.assign (device_support_dir); + m_device_support_directory.append ("/Platforms/watchOS.platform/DeviceSupport"); + FileSpec platform_device_support_dir (m_device_support_directory.c_str(), true); + if (!platform_device_support_dir.Exists()) + { + std::string alt_platform_dirname = device_support_dir; + alt_platform_dirname.append ("/Platforms/WatchOS.platform/DeviceSupport"); + FileSpec alt_platform_device_support_dir (m_device_support_directory.c_str(), true); + if (alt_platform_device_support_dir.Exists()) + { + m_device_support_directory = alt_platform_dirname; + } + } + } + else + { + // Assign a single NULL character so we know we tried to find the device + // support directory and we don't keep trying to find it over and over. + m_device_support_directory.assign (1, '\0'); + } + } + // We should have put a single NULL character into m_device_support_directory + // or it should have a valid path if the code gets here + assert (m_device_support_directory.empty() == false); + if (m_device_support_directory[0]) + return m_device_support_directory.c_str(); + return NULL; +} + + +const char * +PlatformRemoteAppleWatch::GetDeviceSupportDirectoryForOSVersion() +{ + if (m_sdk_sysroot) + return m_sdk_sysroot.GetCString(); + + if (m_device_support_directory_for_os_version.empty()) + { + const PlatformRemoteAppleWatch::SDKDirectoryInfo *sdk_dir_info = GetSDKDirectoryForCurrentOSVersion (); + if (sdk_dir_info == NULL) + sdk_dir_info = GetSDKDirectoryForLatestOSVersion (); + if (sdk_dir_info) + { + char path[PATH_MAX]; + if (sdk_dir_info->directory.GetPath(path, sizeof(path))) + { + m_device_support_directory_for_os_version = path; + return m_device_support_directory_for_os_version.c_str(); + } + } + else + { + // Assign a single NULL character so we know we tried to find the device + // support directory and we don't keep trying to find it over and over. + m_device_support_directory_for_os_version.assign (1, '\0'); + } + } + // We should have put a single NULL character into m_device_support_directory_for_os_version + // or it should have a valid path if the code gets here + assert (m_device_support_directory_for_os_version.empty() == false); + if (m_device_support_directory_for_os_version[0]) + return m_device_support_directory_for_os_version.c_str(); + return NULL; +} + +uint32_t +PlatformRemoteAppleWatch::FindFileInAllSDKs (const char *platform_file_path, + FileSpecList &file_list) +{ + if (platform_file_path && platform_file_path[0] && UpdateSDKDirectoryInfosIfNeeded()) + { + const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); + lldb_private::FileSpec local_file; + // First try for an exact match of major, minor and update + for (uint32_t sdk_idx=0; sdk_idx<num_sdk_infos; ++sdk_idx) + { + if (GetFileInSDK (platform_file_path, + sdk_idx, + local_file)) + { + file_list.Append(local_file); + } + } + } + return file_list.GetSize(); +} + +bool +PlatformRemoteAppleWatch::GetFileInSDK (const char *platform_file_path, + uint32_t sdk_idx, + lldb_private::FileSpec &local_file) +{ + if (sdk_idx < m_sdk_directory_infos.size()) + { + char sdkroot_path[PATH_MAX]; + const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[sdk_idx]; + if (sdk_dir_info.directory.GetPath(sdkroot_path, sizeof(sdkroot_path))) + { + const bool symbols_dirs_only = true; + + return GetFileInSDKRoot (platform_file_path, + sdkroot_path, + symbols_dirs_only, + local_file); + } + } + return false; +} + + +bool +PlatformRemoteAppleWatch::GetFileInSDKRoot (const char *platform_file_path, + const char *sdkroot_path, + bool symbols_dirs_only, + lldb_private::FileSpec &local_file) +{ + if (sdkroot_path && sdkroot_path[0] && platform_file_path && platform_file_path[0]) + { + char resolved_path[PATH_MAX]; + + if (!symbols_dirs_only) + { + ::snprintf (resolved_path, + sizeof(resolved_path), + "%s%s", + sdkroot_path, + platform_file_path); + + local_file.SetFile(resolved_path, true); + if (local_file.Exists()) + return true; + } + + ::snprintf (resolved_path, + sizeof(resolved_path), + "%s/Symbols.Internal%s", + sdkroot_path, + platform_file_path); + + local_file.SetFile(resolved_path, true); + if (local_file.Exists()) + return true; + ::snprintf (resolved_path, + sizeof(resolved_path), + "%s/Symbols%s", + sdkroot_path, + platform_file_path); + + local_file.SetFile(resolved_path, true); + if (local_file.Exists()) + return true; + } + return false; +} + + +Error +PlatformRemoteAppleWatch::GetSymbolFile (const FileSpec &platform_file, + const UUID *uuid_ptr, + FileSpec &local_file) +{ + Error error; + char platform_file_path[PATH_MAX]; + if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) + { + char resolved_path[PATH_MAX]; + + const char * os_version_dir = GetDeviceSupportDirectoryForOSVersion(); + if (os_version_dir) + { + ::snprintf (resolved_path, + sizeof(resolved_path), + "%s/%s", + os_version_dir, + platform_file_path); + + local_file.SetFile(resolved_path, true); + if (local_file.Exists()) + return error; + + ::snprintf (resolved_path, + sizeof(resolved_path), + "%s/Symbols.Internal/%s", + os_version_dir, + platform_file_path); + + local_file.SetFile(resolved_path, true); + if (local_file.Exists()) + return error; + ::snprintf (resolved_path, + sizeof(resolved_path), + "%s/Symbols/%s", + os_version_dir, + platform_file_path); + + local_file.SetFile(resolved_path, true); + if (local_file.Exists()) + return error; + + } + local_file = platform_file; + if (local_file.Exists()) + return error; + + error.SetErrorStringWithFormat ("unable to locate a platform file for '%s' in platform '%s'", + platform_file_path, + GetPluginName().GetCString()); + } + else + { + error.SetErrorString ("invalid platform file argument"); + } + return error; +} + +Error +PlatformRemoteAppleWatch::GetSharedModule (const ModuleSpec &module_spec, + lldb_private::Process* process, + ModuleSP &module_sp, + const FileSpecList *module_search_paths_ptr, + ModuleSP *old_module_sp_ptr, + bool *did_create_ptr) +{ + // For Apple Watch, the SDK files are all cached locally on the host + // system. So first we ask for the file in the cached SDK, + // then we attempt to get a shared module for the right architecture + // with the right UUID. + const FileSpec &platform_file = module_spec.GetFileSpec(); + + Error error; + char platform_file_path[PATH_MAX]; + + if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) + { + ModuleSpec platform_module_spec(module_spec); + + UpdateSDKDirectoryInfosIfNeeded(); + + const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); + + // If we are connected we migth be able to correctly deduce the SDK directory + // using the OS build. + const uint32_t connected_sdk_idx = GetConnectedSDKIndex (); + if (connected_sdk_idx < num_sdk_infos) + { + if (GetFileInSDK (platform_file_path, connected_sdk_idx, platform_module_spec.GetFileSpec())) + { + module_sp.reset(); + error = ResolveExecutable (platform_module_spec, + module_sp, + NULL); + if (module_sp) + { + m_last_module_sdk_idx = connected_sdk_idx; + error.Clear(); + return error; + } + } + } + + // Try the last SDK index if it is set as most files from an SDK + // will tend to be valid in that same SDK. + if (m_last_module_sdk_idx < num_sdk_infos) + { + if (GetFileInSDK (platform_file_path, m_last_module_sdk_idx, platform_module_spec.GetFileSpec())) + { + module_sp.reset(); + error = ResolveExecutable (platform_module_spec, + module_sp, + NULL); + if (module_sp) + { + error.Clear(); + return error; + } + } + } + + // First try for an exact match of major, minor and update + for (uint32_t sdk_idx=0; sdk_idx<num_sdk_infos; ++sdk_idx) + { + if (m_last_module_sdk_idx == sdk_idx) + { + // Skip the last module SDK index if we already searched + // it above + continue; + } + if (GetFileInSDK (platform_file_path, sdk_idx, platform_module_spec.GetFileSpec())) + { + //printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str()); + + error = ResolveExecutable (platform_module_spec, module_sp, NULL); + if (module_sp) + { + // Remember the index of the last SDK that we found a file + // in in case the wrong SDK was selected. + m_last_module_sdk_idx = sdk_idx; + error.Clear(); + return error; + } + } + } + } + // Not the module we are looking for... Nothing to see here... + module_sp.reset(); + + // This may not be an SDK-related module. Try whether we can bring in the thing to our local cache. + error = GetSharedModuleWithLocalCache(module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, did_create_ptr); + if (error.Success()) + return error; + + const bool always_create = false; + error = ModuleList::GetSharedModule (module_spec, + module_sp, + module_search_paths_ptr, + old_module_sp_ptr, + did_create_ptr, + always_create); + + if (module_sp) + module_sp->SetPlatformFileSpec(platform_file); + + return error; +} + +bool +PlatformRemoteAppleWatch::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) +{ + ArchSpec system_arch (GetSystemArchitecture()); + + const ArchSpec::Core system_core = system_arch.GetCore(); + switch (system_core) + { + default: + switch (idx) + { + case 0: arch.SetTriple ("arm64-apple-watchos"); return true; + case 1: arch.SetTriple ("armv7k-apple-watchos"); return true; + case 2: arch.SetTriple ("armv7s-apple-watchos"); return true; + case 3: arch.SetTriple ("armv7-apple-watchos"); return true; + case 4: arch.SetTriple ("thumbv7k-apple-watchos"); return true; + case 5: arch.SetTriple ("thumbv7-apple-watchos"); return true; + case 6: arch.SetTriple ("thumbv7s-apple-watchos"); return true; + default: break; + } + break; + + case ArchSpec::eCore_arm_arm64: + switch (idx) + { + case 0: arch.SetTriple ("arm64-apple-watchos"); return true; + case 1: arch.SetTriple ("armv7k-apple-watchos"); return true; + case 2: arch.SetTriple ("armv7s-apple-watchos"); return true; + case 3: arch.SetTriple ("armv7-apple-watchos"); return true; + case 4: arch.SetTriple ("thumbv7k-apple-watchos"); return true; + case 5: arch.SetTriple ("thumbv7-apple-watchos"); return true; + case 6: arch.SetTriple ("thumbv7s-apple-watchos"); return true; + default: break; + } + break; + + case ArchSpec::eCore_arm_armv7k: + switch (idx) + { + case 0: arch.SetTriple ("armv7k-apple-watchos"); return true; + case 1: arch.SetTriple ("armv7s-apple-watchos"); return true; + case 2: arch.SetTriple ("armv7-apple-watchos"); return true; + case 3: arch.SetTriple ("thumbv7k-apple-watchos"); return true; + case 4: arch.SetTriple ("thumbv7-apple-watchos"); return true; + case 5: arch.SetTriple ("thumbv7s-apple-watchos"); return true; + default: break; + } + break; + + case ArchSpec::eCore_arm_armv7s: + switch (idx) + { + case 0: arch.SetTriple ("armv7s-apple-watchos"); return true; + case 1: arch.SetTriple ("armv7k-apple-watchos"); return true; + case 2: arch.SetTriple ("armv7-apple-watchos"); return true; + case 3: arch.SetTriple ("thumbv7k-apple-watchos"); return true; + case 4: arch.SetTriple ("thumbv7-apple-watchos"); return true; + case 5: arch.SetTriple ("thumbv7s-apple-watchos"); return true; + default: break; + } + break; + + case ArchSpec::eCore_arm_armv7: + switch (idx) + { + case 0: arch.SetTriple ("armv7-apple-watchos"); return true; + case 1: arch.SetTriple ("armv7k-apple-watchos"); return true; + case 2: arch.SetTriple ("thumbv7k-apple-watchos"); return true; + case 3: arch.SetTriple ("thumbv7-apple-watchos"); return true; + default: break; + } + break; + + } + arch.Clear(); + return false; +} + +uint32_t +PlatformRemoteAppleWatch::GetConnectedSDKIndex () +{ + if (IsConnected()) + { + if (m_connected_module_sdk_idx == UINT32_MAX) + { + std::string build; + if (GetRemoteOSBuildString(build)) + { + const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); + for (uint32_t i=0; i<num_sdk_infos; ++i) + { + const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i]; + if (strstr(sdk_dir_info.directory.GetFilename().AsCString(""), build.c_str())) + { + m_connected_module_sdk_idx = i; + } + } + } + } + } + else + { + m_connected_module_sdk_idx = UINT32_MAX; + } + return m_connected_module_sdk_idx; +} + diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h new file mode 100644 index 00000000000..a075cc6fea7 --- /dev/null +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h @@ -0,0 +1,172 @@ +//===-- PlatformRemoteAppleWatch.h ------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_PlatformRemoteAppleWatch_h_ +#define liblldb_PlatformRemoteAppleWatch_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +#include "lldb/Host/FileSpec.h" + +// Project includes +#include "PlatformDarwin.h" + +class PlatformRemoteAppleWatch : public PlatformDarwin +{ +public: + + //------------------------------------------------------------ + // Class Functions + //------------------------------------------------------------ + static lldb::PlatformSP + CreateInstance (bool force, const lldb_private::ArchSpec *arch); + + static void + Initialize (); + + static void + Terminate (); + + static lldb_private::ConstString + GetPluginNameStatic (); + + static const char * + GetDescriptionStatic(); + + //------------------------------------------------------------ + // Class Methods + //------------------------------------------------------------ + PlatformRemoteAppleWatch (); + + virtual + ~PlatformRemoteAppleWatch(); + + //------------------------------------------------------------ + // lldb_private::PluginInterface functions + //------------------------------------------------------------ + lldb_private::ConstString + GetPluginName() override + { + return GetPluginNameStatic(); + } + + uint32_t + GetPluginVersion() override + { + return 1; + } + + //------------------------------------------------------------ + // lldb_private::Platform functions + //------------------------------------------------------------ + lldb_private::Error + ResolveExecutable (const lldb_private::ModuleSpec &module_spec, + lldb::ModuleSP &module_sp, + const lldb_private::FileSpecList *module_search_paths_ptr) override; + + const char * + GetDescription () override + { + return GetDescriptionStatic(); + } + + void + GetStatus (lldb_private::Stream &strm) override; + + virtual lldb_private::Error + GetSymbolFile (const lldb_private::FileSpec &platform_file, + const lldb_private::UUID *uuid_ptr, + lldb_private::FileSpec &local_file); + + lldb_private::Error + GetSharedModule (const lldb_private::ModuleSpec &module_spec, + lldb_private::Process* process, + lldb::ModuleSP &module_sp, + const lldb_private::FileSpecList *module_search_paths_ptr, + lldb::ModuleSP *old_module_sp_ptr, + bool *did_create_ptr) override; + + bool + GetSupportedArchitectureAtIndex (uint32_t idx, + lldb_private::ArchSpec &arch) override; + + void + AddClangModuleCompilationOptions (lldb_private::Target *target, std::vector<std::string> &options) override + { + return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(target, options, PlatformDarwin::SDKType::iPhoneOS); + } + +protected: + struct SDKDirectoryInfo + { + SDKDirectoryInfo (const lldb_private::FileSpec &sdk_dir_spec); + lldb_private::FileSpec directory; + lldb_private::ConstString build; + uint32_t version_major; + uint32_t version_minor; + uint32_t version_update; + bool user_cached; + }; + typedef std::vector<SDKDirectoryInfo> SDKDirectoryInfoCollection; + SDKDirectoryInfoCollection m_sdk_directory_infos; + std::string m_device_support_directory; + std::string m_device_support_directory_for_os_version; + std::string m_build_update; + uint32_t m_last_module_sdk_idx; + uint32_t m_connected_module_sdk_idx; + + bool + UpdateSDKDirectoryInfosIfNeeded(); + + const char * + GetDeviceSupportDirectory(); + + const char * + GetDeviceSupportDirectoryForOSVersion(); + + const SDKDirectoryInfo * + GetSDKDirectoryForLatestOSVersion (); + + const SDKDirectoryInfo * + GetSDKDirectoryForCurrentOSVersion (); + + static lldb_private::FileSpec::EnumerateDirectoryResult + GetContainedFilesIntoVectorOfStringsCallback (void *baton, + lldb_private::FileSpec::FileType file_type, + const lldb_private::FileSpec &file_spec); + + uint32_t + FindFileInAllSDKs (const char *platform_file_path, + lldb_private::FileSpecList &file_list); + + bool + GetFileInSDK (const char *platform_file_path, + uint32_t sdk_idx, + lldb_private::FileSpec &local_file); + + bool + GetFileInSDKRoot (const char *platform_file_path, + const char *sdkroot_path, + bool symbols_dirs_only, + lldb_private::FileSpec &local_file); + + uint32_t + FindFileInAllSDKs (const lldb_private::FileSpec &platform_file, + lldb_private::FileSpecList &file_list); + + uint32_t + GetConnectedSDKIndex (); + +private: + DISALLOW_COPY_AND_ASSIGN (PlatformRemoteAppleWatch); + +}; + +#endif // liblldb_PlatformRemoteAppleWatch_h_ |