[Lldb-commits] [lldb] r205113 - lldb arm64 import.

Jason Molenda jmolenda at apple.com
Sat Mar 29 11:54:22 PDT 2014


Author: jmolenda
Date: Sat Mar 29 13:54:20 2014
New Revision: 205113

URL: http://llvm.org/viewvc/llvm-project?rev=205113&view=rev
Log:
lldb arm64 import.

These changes were written by Greg Clayton, Jim Ingham, Jason Molenda.

It builds cleanly against TOT llvm with xcodebuild.  I updated the
cmake files by visual inspection but did not try a build.  I haven't
built these sources on any non-Mac platforms - I don't think this
patch adds any code that requires darwin, but please let me know if
I missed something.

In debugserver, MachProcess.cpp and MachTask.cpp were renamed to
MachProcess.mm and MachTask.mm as they picked up some new Objective-C
code needed to launch processes when running on iOS.

Added:
    lldb/trunk/source/Plugins/ABI/MacOSX-arm64/
    lldb/trunk/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp
    lldb/trunk/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h
    lldb/trunk/source/Plugins/ABI/MacOSX-arm64/CMakeLists.txt
    lldb/trunk/source/Plugins/ABI/MacOSX-arm64/Makefile
    lldb/trunk/source/Plugins/Instruction/ARM64/
    lldb/trunk/source/Plugins/Instruction/ARM64/CMakeLists.txt
    lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
    lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h
    lldb/trunk/source/Plugins/Instruction/ARM64/Makefile
    lldb/trunk/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp
    lldb/trunk/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h
    lldb/trunk/source/Utility/ARM64_DWARF_Registers.cpp
    lldb/trunk/source/Utility/ARM64_DWARF_Registers.h
    lldb/trunk/source/Utility/ARM64_GCC_Registers.h
    lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.mm
      - copied, changed from r205075, lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp
    lldb/trunk/tools/debugserver/source/MacOSX/MachTask.mm
      - copied, changed from r205075, lldb/trunk/tools/debugserver/source/MacOSX/MachTask.cpp
    lldb/trunk/tools/debugserver/source/MacOSX/arm64/
    lldb/trunk/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp
    lldb/trunk/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.h
Removed:
    lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp
    lldb/trunk/tools/debugserver/source/MacOSX/MachTask.cpp
Modified:
    lldb/trunk/include/lldb/API/SBProcess.h
    lldb/trunk/include/lldb/API/SBTarget.h
    lldb/trunk/include/lldb/Core/ArchSpec.h
    lldb/trunk/include/lldb/Core/RegisterValue.h
    lldb/trunk/include/lldb/Expression/ExpressionSourceCode.h
    lldb/trunk/include/lldb/Symbol/ClangASTType.h
    lldb/trunk/include/lldb/Target/Process.h
    lldb/trunk/lib/Makefile
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/scripts/Python/interface/SBProcess.i
    lldb/trunk/scripts/Python/interface/SBTarget.i
    lldb/trunk/scripts/build-llvm.pl
    lldb/trunk/source/API/SBProcess.cpp
    lldb/trunk/source/API/SBTarget.cpp
    lldb/trunk/source/CMakeLists.txt
    lldb/trunk/source/Core/ArchSpec.cpp
    lldb/trunk/source/Core/Error.cpp
    lldb/trunk/source/Core/Module.cpp
    lldb/trunk/source/Expression/ClangExpressionParser.cpp
    lldb/trunk/source/Expression/ClangUserExpression.cpp
    lldb/trunk/source/Expression/ExpressionSourceCode.cpp
    lldb/trunk/source/Host/common/Host.cpp
    lldb/trunk/source/Host/macosx/Host.mm
    lldb/trunk/source/Host/macosx/Symbols.cpp
    lldb/trunk/source/Interpreter/CommandInterpreter.cpp
    lldb/trunk/source/Plugins/ABI/CMakeLists.txt
    lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
    lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
    lldb/trunk/source/Plugins/Instruction/CMakeLists.txt
    lldb/trunk/source/Plugins/Makefile
    lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
    lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
    lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
    lldb/trunk/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
    lldb/trunk/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
    lldb/trunk/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp
    lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CMakeLists.txt
    lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
    lldb/trunk/source/Plugins/Process/Utility/CMakeLists.txt
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp
    lldb/trunk/source/Plugins/Process/Utility/StopInfoMachException.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
    lldb/trunk/source/Symbol/ClangASTType.cpp
    lldb/trunk/source/Target/Thread.cpp
    lldb/trunk/source/Utility/CMakeLists.txt
    lldb/trunk/source/lldb.cpp
    lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/main.m
    lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj
    lldb/trunk/tools/debugserver/source/DNB.cpp
    lldb/trunk/tools/debugserver/source/DNB.h
    lldb/trunk/tools/debugserver/source/DNBArch.cpp
    lldb/trunk/tools/debugserver/source/DNBArch.h
    lldb/trunk/tools/debugserver/source/DNBDefs.h
    lldb/trunk/tools/debugserver/source/DNBError.cpp
    lldb/trunk/tools/debugserver/source/DNBError.h
    lldb/trunk/tools/debugserver/source/MacOSX/CMakeLists.txt
    lldb/trunk/tools/debugserver/source/MacOSX/MachException.h
    lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h
    lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.cpp
    lldb/trunk/tools/debugserver/source/MacOSX/MachVMMemory.cpp
    lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp
    lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h
    lldb/trunk/tools/debugserver/source/RNBContext.h
    lldb/trunk/tools/debugserver/source/RNBDefs.h
    lldb/trunk/tools/debugserver/source/RNBRemote.cpp
    lldb/trunk/tools/debugserver/source/RNBRemote.h
    lldb/trunk/tools/debugserver/source/RNBServices.cpp
    lldb/trunk/tools/debugserver/source/RNBServices.h
    lldb/trunk/tools/debugserver/source/debugserver-entitlements.plist
    lldb/trunk/tools/debugserver/source/debugserver.cpp

Modified: lldb/trunk/include/lldb/API/SBProcess.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBProcess.h?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBProcess.h (original)
+++ lldb/trunk/include/lldb/API/SBProcess.h Sat Mar 29 13:54:20 2014
@@ -279,6 +279,9 @@ public:
     lldb::SBError
     UnloadImage (uint32_t image_token);
     
+    lldb::SBError
+    SendEventData (const char *data);
+    
     //------------------------------------------------------------------
     /// Return the number of different thread-origin extended backtraces
     /// this process can support.

Modified: lldb/trunk/include/lldb/API/SBTarget.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBTarget.h?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBTarget.h (original)
+++ lldb/trunk/include/lldb/API/SBTarget.h Sat Mar 29 13:54:20 2014
@@ -110,6 +110,12 @@ public:
     bool
     AddSuppressFileAction (int fd, bool read, bool write);
     
+    void
+    SetLaunchEventData (const char *data);
+    
+    const char *
+    GetLaunchEventData () const;
+    
 protected:
     friend class SBTarget;
     

Modified: lldb/trunk/include/lldb/Core/ArchSpec.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ArchSpec.h?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ArchSpec.h (original)
+++ lldb/trunk/include/lldb/Core/ArchSpec.h Sat Mar 29 13:54:20 2014
@@ -50,6 +50,7 @@ public:
         eCore_arm_armv7m,
         eCore_arm_armv7em,
         eCore_arm_xscale,  
+
         eCore_thumb,
         eCore_thumbv4t,
         eCore_thumbv5,
@@ -57,11 +58,12 @@ public:
         eCore_thumbv6,
         eCore_thumbv6m,
         eCore_thumbv7,
-        eCore_thumbv7f,
         eCore_thumbv7s,
         eCore_thumbv7k,
+        eCore_thumbv7f,
         eCore_thumbv7m,
         eCore_thumbv7em,
+        eCore_arm_arm64,
         
         eCore_mips64,
 

Modified: lldb/trunk/include/lldb/Core/RegisterValue.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/RegisterValue.h?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/RegisterValue.h (original)
+++ lldb/trunk/include/lldb/Core/RegisterValue.h Sat Mar 29 13:54:20 2014
@@ -374,6 +374,12 @@ namespace lldb_private {
         uint32_t
         GetByteSize () const;
 
+        static uint32_t
+        GetMaxByteSize ()
+        {
+            return kMaxRegisterByteSize;
+        }
+
         void
         Clear();
 

Modified: lldb/trunk/include/lldb/Expression/ExpressionSourceCode.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ExpressionSourceCode.h?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ExpressionSourceCode.h (original)
+++ lldb/trunk/include/lldb/Expression/ExpressionSourceCode.h Sat Mar 29 13:54:20 2014
@@ -17,6 +17,8 @@
 namespace lldb_private
 {
 
+class ExecutionContext;
+
 class ExpressionSourceCode
 {
 public:
@@ -53,7 +55,8 @@ public:
     bool GetText (std::string &text, 
                   lldb::LanguageType wrapping_language, 
                   bool const_object,
-                  bool static_method) const;
+                  bool static_method,
+                  ExecutionContext &exe_ctx) const;
     
 private:
     ExpressionSourceCode (const char *name,

Modified: lldb/trunk/include/lldb/Symbol/ClangASTType.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTType.h?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTType.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangASTType.h Sat Mar 29 13:54:20 2014
@@ -155,6 +155,9 @@ public:
     bool
     IsFunctionType (bool *is_variadic_ptr = NULL) const;
 
+    uint32_t
+    IsHomogeneousAggregate (ClangASTType* base_type_ptr) const;
+
     size_t
     GetNumberOfFunctionArguments () const;
     

Modified: lldb/trunk/include/lldb/Target/Process.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Process.h (original)
+++ lldb/trunk/include/lldb/Target/Process.h Sat Mar 29 13:54:20 2014
@@ -856,6 +856,18 @@ public:
     }
 
 
+    void
+    SetLaunchEventData (const char *data)
+    {
+        m_event_data.assign (data);
+    }
+    
+    const char *
+    GetLaunchEventData () const
+    {
+        return m_event_data.c_str();
+    }
+    
 protected:
     std::string m_working_dir;
     std::string m_plugin_name;
@@ -867,6 +879,7 @@ protected:
     Host::MonitorChildProcessCallback m_monitor_callback;
     void *m_monitor_callback_baton;
     bool m_monitor_signals;
+    std::string m_event_data; // A string passed to the plugin launch, having no meaning to the upper levels of lldb.
     lldb::ListenerSP m_hijack_listener_sp;
 };
 
@@ -3638,8 +3651,17 @@ public:
         else
             return m_public_run_lock;
     }
-    
+
+public:
+    virtual Error
+    SendEventData(const char *data)
+    {
+        Error return_error ("Sending an event is not supported for this process.");
+        return return_error;
+    }
+
 protected:
+
     //------------------------------------------------------------------
     // NextEventAction provides a way to register an action on the next
     // event that is delivered to this process.  There is currently only

Modified: lldb/trunk/lib/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lib/Makefile?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/lib/Makefile (original)
+++ lldb/trunk/lib/Makefile Sat Mar 29 13:54:20 2014
@@ -32,12 +32,14 @@ USEDLIBS = lldbAPI.a \
 	lldbInitAndLog.a \
 	lldbInterpreter.a \
 	lldbPluginABIMacOSX_arm.a \
+	lldbPluginABIMacOSX_arm64.a \
 	lldbPluginABIMacOSX_i386.a \
 	lldbPluginABISysV_x86_64.a \
 	lldbPluginDisassemblerLLVM.a \
 	lldbPluginDynamicLoaderStatic.a \
 	lldbPluginDynamicLoaderPOSIX.a \
 	lldbPluginEmulateInstructionARM.a \
+	lldbPluginEmulateInstructionARM64.a \
 	lldbPluginLanguageRuntimeCPlusPlusItaniumABI.a \
 	lldbPluginLanguageRuntimeObjCAppleObjCRuntime.a \
 	lldbPluginObjectContainerBSDArchive.a \

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Sat Mar 29 13:54:20 2014
@@ -140,6 +140,8 @@
 		26474CD518D0CB710073DEBA /* RegisterInfos_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = 26474CD218D0CB710073DEBA /* RegisterInfos_x86_64.h */; };
 		26491E3B15E1DB8600CBFFC2 /* OptionValueRegex.h in Headers */ = {isa = PBXBuildFile; fileRef = 26491E3A15E1DB8600CBFFC2 /* OptionValueRegex.h */; };
 		26491E3E15E1DB9F00CBFFC2 /* OptionValueRegex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26491E3D15E1DB9F00CBFFC2 /* OptionValueRegex.cpp */; };
+		264A12FC1372522000875C42 /* EmulateInstructionARM64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 264A12FA1372522000875C42 /* EmulateInstructionARM64.cpp */; };
+		264A1300137252C700875C42 /* ARM64_DWARF_Registers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 264A12FE137252C700875C42 /* ARM64_DWARF_Registers.cpp */; };
 		264A97BF133918BC0017F0BE /* PlatformRemoteGDBServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 264A97BD133918BC0017F0BE /* PlatformRemoteGDBServer.cpp */; };
 		264D8D5013661BD7003A368F /* UnwindAssembly.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 264D8D4F13661BD7003A368F /* UnwindAssembly.cpp */; };
 		265205A813D3E3F700132FE2 /* RegisterContextKDP_arm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 265205A213D3E3F700132FE2 /* RegisterContextKDP_arm.cpp */; };
@@ -519,6 +521,7 @@
 		26DAED6015D327A200E15819 /* OptionValuePathMappings.h in Headers */ = {isa = PBXBuildFile; fileRef = 26DAED5F15D327A200E15819 /* OptionValuePathMappings.h */; };
 		26DAED6315D327C200E15819 /* OptionValuePathMappings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26DAED6215D327C200E15819 /* OptionValuePathMappings.cpp */; };
 		26DB3E161379E7AD0080DC73 /* ABIMacOSX_arm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26DB3E071379E7AD0080DC73 /* ABIMacOSX_arm.cpp */; };
+		26DB3E191379E7AD0080DC73 /* ABIMacOSX_arm64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26DB3E0B1379E7AD0080DC73 /* ABIMacOSX_arm64.cpp */; };
 		26DB3E1C1379E7AD0080DC73 /* ABIMacOSX_i386.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26DB3E0F1379E7AD0080DC73 /* ABIMacOSX_i386.cpp */; };
 		26DB3E1F1379E7AD0080DC73 /* ABISysV_x86_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26DB3E131379E7AD0080DC73 /* ABISysV_x86_64.cpp */; };
 		26DC6A1D1337FECA00FF7998 /* lldb-platform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26DC6A1C1337FECA00FF7998 /* lldb-platform.cpp */; };
@@ -661,6 +664,8 @@
 		AF061F88182C97ED00B6A19C /* RegisterContextHistory.h in Headers */ = {isa = PBXBuildFile; fileRef = AF061F86182C97ED00B6A19C /* RegisterContextHistory.h */; };
 		AF061F8B182C980000B6A19C /* HistoryThread.h in Headers */ = {isa = PBXBuildFile; fileRef = AF061F89182C980000B6A19C /* HistoryThread.h */; };
 		AF061F8C182C980000B6A19C /* HistoryUnwind.h in Headers */ = {isa = PBXBuildFile; fileRef = AF061F8A182C980000B6A19C /* HistoryUnwind.h */; };
+		AF0F6E501739A76D009180FE /* RegisterContextKDP_arm64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF0F6E4E1739A76D009180FE /* RegisterContextKDP_arm64.cpp */; };
+		AF0F6E511739A76D009180FE /* RegisterContextKDP_arm64.h in Headers */ = {isa = PBXBuildFile; fileRef = AF0F6E4F1739A76D009180FE /* RegisterContextKDP_arm64.h */; };
 		AF0C112818580CD800C4C45B /* QueueItem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF0C112718580CD800C4C45B /* QueueItem.cpp */; };
 		AF0E22F018A09FB20009B7D1 /* AppleGetItemInfoHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF0E22EE18A09FB20009B7D1 /* AppleGetItemInfoHandler.cpp */; };
 		AF0E22F118A09FB20009B7D1 /* AppleGetItemInfoHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = AF0E22EF18A09FB20009B7D1 /* AppleGetItemInfoHandler.h */; };
@@ -685,6 +690,8 @@
 		AF45FDE618A1F3AC0007051C /* AppleGetThreadItemInfoHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = AF45FDE418A1F3AC0007051C /* AppleGetThreadItemInfoHandler.h */; };
 		AF81DEFA1828A23F0042CF19 /* SystemRuntime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF81DEF91828A23F0042CF19 /* SystemRuntime.cpp */; };
 		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 */; };
 		AF9B8F33182DB52900DA866F /* SystemRuntimeMacOSX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF9B8F31182DB52900DA866F /* SystemRuntimeMacOSX.cpp */; };
 		AF9B8F34182DB52900DA866F /* SystemRuntimeMacOSX.h in Headers */ = {isa = PBXBuildFile; fileRef = AF9B8F32182DB52900DA866F /* SystemRuntimeMacOSX.h */; };
 		AFF87C87150FF669000E1742 /* com.apple.debugserver.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = AFF87C86150FF669000E1742 /* com.apple.debugserver.plist */; };
@@ -1099,6 +1106,10 @@
 		26474CD218D0CB710073DEBA /* RegisterInfos_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterInfos_x86_64.h; path = Utility/RegisterInfos_x86_64.h; sourceTree = "<group>"; };
 		26491E3A15E1DB8600CBFFC2 /* OptionValueRegex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OptionValueRegex.h; path = include/lldb/Interpreter/OptionValueRegex.h; sourceTree = "<group>"; };
 		26491E3D15E1DB9F00CBFFC2 /* OptionValueRegex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OptionValueRegex.cpp; path = source/Interpreter/OptionValueRegex.cpp; sourceTree = "<group>"; };
+		264A12FA1372522000875C42 /* EmulateInstructionARM64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EmulateInstructionARM64.cpp; sourceTree = "<group>"; };
+		264A12FB1372522000875C42 /* EmulateInstructionARM64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EmulateInstructionARM64.h; sourceTree = "<group>"; };
+		264A12FE137252C700875C42 /* ARM64_DWARF_Registers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ARM64_DWARF_Registers.cpp; path = source/Utility/ARM64_DWARF_Registers.cpp; sourceTree = "<group>"; };
+		264A12FF137252C700875C42 /* ARM64_DWARF_Registers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ARM64_DWARF_Registers.h; path = source/Utility/ARM64_DWARF_Registers.h; sourceTree = "<group>"; };
 		264A43BB1320B3B4005B4096 /* Platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Platform.h; path = include/lldb/Target/Platform.h; sourceTree = "<group>"; };
 		264A43BD1320BCEB005B4096 /* Platform.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Platform.cpp; path = source/Target/Platform.cpp; sourceTree = "<group>"; };
 		264A97BD133918BC0017F0BE /* PlatformRemoteGDBServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PlatformRemoteGDBServer.cpp; path = "gdb-server/PlatformRemoteGDBServer.cpp"; sourceTree = "<group>"; };
@@ -1143,7 +1154,7 @@
 		2670F8111862B44A006B332C /* libncurses.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libncurses.dylib; path = /usr/lib/libncurses.dylib; sourceTree = "<absolute>"; };
 		2671A0CD134825F6003A87BB /* ConnectionMachPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ConnectionMachPort.h; path = include/lldb/Core/ConnectionMachPort.h; sourceTree = "<group>"; };
 		2671A0CF13482601003A87BB /* ConnectionMachPort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ConnectionMachPort.cpp; path = source/Core/ConnectionMachPort.cpp; sourceTree = "<group>"; };
-		2672D8461189055500FF4019 /* CommandObjectFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = CommandObjectFrame.cpp; path = source/Commands/CommandObjectFrame.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
+		2672D8461189055500FF4019 /* CommandObjectFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectFrame.cpp; path = source/Commands/CommandObjectFrame.cpp; sourceTree = "<group>"; };
 		2672D8471189055500FF4019 /* CommandObjectFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectFrame.h; path = source/Commands/CommandObjectFrame.h; sourceTree = "<group>"; };
 		26744EED1338317700EF765A /* GDBRemoteCommunicationClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GDBRemoteCommunicationClient.cpp; sourceTree = "<group>"; };
 		26744EEE1338317700EF765A /* GDBRemoteCommunicationClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDBRemoteCommunicationClient.h; sourceTree = "<group>"; };
@@ -1359,7 +1370,7 @@
 		26BC7D7E10F1B77400F91463 /* Timer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Timer.h; path = include/lldb/Core/Timer.h; sourceTree = "<group>"; };
 		26BC7D8010F1B77400F91463 /* UserID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UserID.h; path = include/lldb/Core/UserID.h; sourceTree = "<group>"; };
 		26BC7D8110F1B77400F91463 /* Value.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Value.h; path = include/lldb/Core/Value.h; sourceTree = "<group>"; };
-		26BC7D8210F1B77400F91463 /* ValueObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = ValueObject.h; path = include/lldb/Core/ValueObject.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
+		26BC7D8210F1B77400F91463 /* ValueObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ValueObject.h; path = include/lldb/Core/ValueObject.h; sourceTree = "<group>"; };
 		26BC7D8310F1B77400F91463 /* ValueObjectChild.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ValueObjectChild.h; path = include/lldb/Core/ValueObjectChild.h; sourceTree = "<group>"; };
 		26BC7D8410F1B77400F91463 /* ValueObjectList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ValueObjectList.h; path = include/lldb/Core/ValueObjectList.h; sourceTree = "<group>"; };
 		26BC7D8510F1B77400F91463 /* ValueObjectVariable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ValueObjectVariable.h; path = include/lldb/Core/ValueObjectVariable.h; sourceTree = "<group>"; };
@@ -1457,7 +1468,7 @@
 		26BC7E9610F1B85900F91463 /* Timer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Timer.cpp; path = source/Core/Timer.cpp; sourceTree = "<group>"; };
 		26BC7E9810F1B85900F91463 /* UserID.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UserID.cpp; path = source/Core/UserID.cpp; sourceTree = "<group>"; };
 		26BC7E9910F1B85900F91463 /* Value.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Value.cpp; path = source/Core/Value.cpp; sourceTree = "<group>"; };
-		26BC7E9A10F1B85900F91463 /* ValueObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = ValueObject.cpp; path = source/Core/ValueObject.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
+		26BC7E9A10F1B85900F91463 /* ValueObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObject.cpp; path = source/Core/ValueObject.cpp; sourceTree = "<group>"; };
 		26BC7E9B10F1B85900F91463 /* ValueObjectChild.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectChild.cpp; path = source/Core/ValueObjectChild.cpp; sourceTree = "<group>"; };
 		26BC7E9C10F1B85900F91463 /* ValueObjectList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectList.cpp; path = source/Core/ValueObjectList.cpp; sourceTree = "<group>"; };
 		26BC7E9D10F1B85900F91463 /* ValueObjectVariable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectVariable.cpp; path = source/Core/ValueObjectVariable.cpp; sourceTree = "<group>"; };
@@ -1560,6 +1571,8 @@
 		26DAFD9711529BC7005A394E /* ExecutionContextScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ExecutionContextScope.h; path = include/lldb/Target/ExecutionContextScope.h; sourceTree = "<group>"; };
 		26DB3E071379E7AD0080DC73 /* ABIMacOSX_arm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ABIMacOSX_arm.cpp; sourceTree = "<group>"; };
 		26DB3E081379E7AD0080DC73 /* ABIMacOSX_arm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ABIMacOSX_arm.h; sourceTree = "<group>"; };
+		26DB3E0B1379E7AD0080DC73 /* ABIMacOSX_arm64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ABIMacOSX_arm64.cpp; sourceTree = "<group>"; };
+		26DB3E0C1379E7AD0080DC73 /* ABIMacOSX_arm64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ABIMacOSX_arm64.h; sourceTree = "<group>"; };
 		26DB3E0F1379E7AD0080DC73 /* ABIMacOSX_i386.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ABIMacOSX_i386.cpp; sourceTree = "<group>"; };
 		26DB3E101379E7AD0080DC73 /* ABIMacOSX_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ABIMacOSX_i386.h; sourceTree = "<group>"; };
 		26DB3E131379E7AD0080DC73 /* ABISysV_x86_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ABISysV_x86_64.cpp; sourceTree = "<group>"; };
@@ -1903,6 +1916,8 @@
 		AF061F86182C97ED00B6A19C /* RegisterContextHistory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterContextHistory.h; path = Utility/RegisterContextHistory.h; sourceTree = "<group>"; };
 		AF061F89182C980000B6A19C /* HistoryThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HistoryThread.h; path = Utility/HistoryThread.h; sourceTree = "<group>"; };
 		AF061F8A182C980000B6A19C /* HistoryUnwind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HistoryUnwind.h; path = Utility/HistoryUnwind.h; sourceTree = "<group>"; };
+		AF0F6E4E1739A76D009180FE /* RegisterContextKDP_arm64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterContextKDP_arm64.cpp; sourceTree = "<group>"; };
+		AF0F6E4F1739A76D009180FE /* RegisterContextKDP_arm64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterContextKDP_arm64.h; sourceTree = "<group>"; };
 		AF0C112718580CD800C4C45B /* QueueItem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = QueueItem.cpp; path = source/Target/QueueItem.cpp; sourceTree = "<group>"; };
 		AF0E22EE18A09FB20009B7D1 /* AppleGetItemInfoHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AppleGetItemInfoHandler.cpp; sourceTree = "<group>"; };
 		AF0E22EF18A09FB20009B7D1 /* AppleGetItemInfoHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppleGetItemInfoHandler.h; sourceTree = "<group>"; };
@@ -1933,6 +1948,9 @@
 		AF68D3301255A110002FF25B /* UnwindLLDB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UnwindLLDB.h; path = Utility/UnwindLLDB.h; sourceTree = "<group>"; };
 		AF81DEF91828A23F0042CF19 /* SystemRuntime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SystemRuntime.cpp; path = source/Target/SystemRuntime.cpp; sourceTree = "<group>"; };
 		AF90106315AB7C5700FF120D /* lldb.1 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.man; name = lldb.1; path = docs/lldb.1; sourceTree = "<group>"; };
+		AF9107E91685709A00DBCD3C /* ARM64_GCC_Registers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ARM64_GCC_Registers.h; path = source/Utility/ARM64_GCC_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>"; };
+		AF9107ED168570D200DBCD3C /* RegisterContextDarwin_arm64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterContextDarwin_arm64.h; path = Utility/RegisterContextDarwin_arm64.h; sourceTree = "<group>"; };
 		AF94005711C03F6500085DB9 /* SymbolVendor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SymbolVendor.cpp; path = source/Symbol/SymbolVendor.cpp; sourceTree = "<group>"; };
 		AF9B8F31182DB52900DA866F /* SystemRuntimeMacOSX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SystemRuntimeMacOSX.cpp; sourceTree = "<group>"; };
 		AF9B8F32182DB52900DA866F /* SystemRuntimeMacOSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SystemRuntimeMacOSX.h; sourceTree = "<group>"; };
@@ -2524,6 +2542,8 @@
 		2642FBA713D003B400ED6808 /* MacOSX-Kernel */ = {
 			isa = PBXGroup;
 			children = (
+				AF0F6E4E1739A76D009180FE /* RegisterContextKDP_arm64.cpp */,
+				AF0F6E4F1739A76D009180FE /* RegisterContextKDP_arm64.h */,
 				2642FBA813D003B400ED6808 /* CommunicationKDP.cpp */,
 				2642FBA913D003B400ED6808 /* CommunicationKDP.h */,
 				2642FBAA13D003B400ED6808 /* ProcessKDP.cpp */,
@@ -2542,6 +2562,15 @@
 			path = "MacOSX-Kernel";
 			sourceTree = "<group>";
 		};
+		264A12F91372522000875C42 /* ARM64 */ = {
+			isa = PBXGroup;
+			children = (
+				264A12FA1372522000875C42 /* EmulateInstructionARM64.cpp */,
+				264A12FB1372522000875C42 /* EmulateInstructionARM64.h */,
+			);
+			path = ARM64;
+			sourceTree = "<group>";
+		};
 		264A97BC133918A30017F0BE /* GDB Server */ = {
 			isa = PBXGroup;
 			children = (
@@ -2642,9 +2671,12 @@
 		2682F168115ED9C800CCFF99 /* Utility */ = {
 			isa = PBXGroup;
 			children = (
+				AF9107E91685709A00DBCD3C /* ARM64_GCC_Registers.h */,
 				26CF992414428766001E4138 /* AnsiTerminal.h */,
 				26F996A7119B79C300412154 /* ARM_DWARF_Registers.h */,
 				26ECA04213665FED008D1F18 /* ARM_DWARF_Registers.cpp */,
+				264A12FF137252C700875C42 /* ARM64_DWARF_Registers.h */,
+				264A12FE137252C700875C42 /* ARM64_DWARF_Registers.cpp */,
 				26F996A8119B79C300412154 /* ARM_GCC_Registers.h */,
 				264723A511FA076E00DE380C /* CleanUp.h */,
 				26D1804416CEE12500EDFB5B /* KQueue.h */,
@@ -2770,6 +2802,8 @@
 				26474C9F18D0CAEC0073DEBA /* RegisterContext_x86.h */,
 				26957D9213D381C900670048 /* RegisterContextDarwin_arm.cpp */,
 				26957D9313D381C900670048 /* RegisterContextDarwin_arm.h */,
+                AF9107EC168570D200DBCD3C /* RegisterContextDarwin_arm64.cpp */,
+                AF9107ED168570D200DBCD3C /* RegisterContextDarwin_arm64.h */,
 				26957D9413D381C900670048 /* RegisterContextDarwin_i386.cpp */,
 				26957D9513D381C900670048 /* RegisterContextDarwin_i386.h */,
 				26957D9613D381C900670048 /* RegisterContextDarwin_x86_64.cpp */,
@@ -3527,6 +3561,7 @@
 			isa = PBXGroup;
 			children = (
 				26D9FDCB12F785270003F2EE /* ARM */,
+				264A12F91372522000875C42 /* ARM64 */,
 			);
 			path = Instruction;
 			sourceTree = "<group>";
@@ -3546,6 +3581,7 @@
 			isa = PBXGroup;
 			children = (
 				26DB3E061379E7AD0080DC73 /* MacOSX-arm */,
+				26DB3E0A1379E7AD0080DC73 /* MacOSX-arm64 */,
 				26DB3E0E1379E7AD0080DC73 /* MacOSX-i386 */,
 				26DB3E121379E7AD0080DC73 /* SysV-x86_64 */,
 			);
@@ -3561,6 +3597,15 @@
 			path = "MacOSX-arm";
 			sourceTree = "<group>";
 		};
+		26DB3E0A1379E7AD0080DC73 /* MacOSX-arm64 */ = {
+			isa = PBXGroup;
+			children = (
+				26DB3E0B1379E7AD0080DC73 /* ABIMacOSX_arm64.cpp */,
+				26DB3E0C1379E7AD0080DC73 /* ABIMacOSX_arm64.h */,
+			);
+			path = "MacOSX-arm64";
+			sourceTree = "<group>";
+		};
 		26DB3E0E1379E7AD0080DC73 /* MacOSX-i386 */ = {
 			isa = PBXGroup;
 			children = (
@@ -4004,6 +4049,7 @@
 				AF061F8C182C980000B6A19C /* HistoryUnwind.h in Headers */,
 				260CC63815D04377002BF2E0 /* OptionValueString.h in Headers */,
 				260CC63915D04377002BF2E0 /* OptionValueUInt64.h in Headers */,
+				AF0F6E511739A76D009180FE /* RegisterContextKDP_arm64.h in Headers */,
 				260CC63A15D04377002BF2E0 /* OptionValueUUID.h in Headers */,
 				260A248E15D06C50009981B0 /* OptionValues.h in Headers */,
 				AF061F88182C97ED00B6A19C /* RegisterContextHistory.h in Headers */,
@@ -4415,6 +4461,7 @@
 				9475C18E14E5F834001BFC6D /* SBTypeNameSpecifier.cpp in Sources */,
 				9452573A16262D0200325455 /* SBDeclaration.cpp in Sources */,
 				4CE4F675162C973F00F75CB3 /* SBExpressionOptions.cpp in Sources */,
+				AF9107EE168570D200DBCD3C /* RegisterContextDarwin_arm64.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -4740,7 +4787,10 @@
 				260E07C8136FAB9200CF21D3 /* OptionGroupFile.cpp in Sources */,
 				2686536C1370ACB200D186A3 /* OptionGroupBoolean.cpp in Sources */,
 				268653701370AE7200D186A3 /* OptionGroupUInt64.cpp in Sources */,
+				264A12FC1372522000875C42 /* EmulateInstructionARM64.cpp in Sources */,
+				264A1300137252C700875C42 /* ARM64_DWARF_Registers.cpp in Sources */,
 				26DB3E161379E7AD0080DC73 /* ABIMacOSX_arm.cpp in Sources */,
+				26DB3E191379E7AD0080DC73 /* ABIMacOSX_arm64.cpp in Sources */,
 				26DB3E1C1379E7AD0080DC73 /* ABIMacOSX_i386.cpp in Sources */,
 				26DB3E1F1379E7AD0080DC73 /* ABISysV_x86_64.cpp in Sources */,
 				26D1803E16CEBFD300EDFB5B /* KQueue.cpp in Sources */,
@@ -4796,6 +4846,7 @@
 				26B7564E14F89356008D9CB3 /* PlatformiOSSimulator.cpp in Sources */,
 				26FFC19914FC072100087D58 /* AuxVector.cpp in Sources */,
 				26FFC19B14FC072100087D58 /* DYLDRendezvous.cpp in Sources */,
+				AF0F6E501739A76D009180FE /* RegisterContextKDP_arm64.cpp in Sources */,
 				26FFC19D14FC072100087D58 /* DynamicLoaderPOSIXDYLD.cpp in Sources */,
 				2694E99D14FC0BB30076DE67 /* PlatformFreeBSD.cpp in Sources */,
 				2694E9A414FC0BBD0076DE67 /* PlatformLinux.cpp in Sources */,
@@ -4834,6 +4885,7 @@
 				947A1D641616476B0017C8D1 /* CommandObjectPlugin.cpp in Sources */,
 				262ED0081631FA3A00879631 /* OptionGroupString.cpp in Sources */,
 				94094C6B163B6F840083A547 /* ValueObjectCast.cpp in Sources */,
+				AF9107EF168570D200DBCD3C /* RegisterContextDarwin_arm64.cpp in Sources */,
 				94CB255B16B069770059775D /* CXXFormatterFunctions.cpp in Sources */,
 				94CB255C16B069770059775D /* DataVisualization.cpp in Sources */,
 				94CD705016F8DF1C00CF1E42 /* LibCxxList.cpp in Sources */,
@@ -4978,7 +5030,10 @@
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
 				ARCHS = "$(NATIVE_ARCH)";
-				"ARCHS[sdk=iphoneos*]" = armv7;
+				"ARCHS[sdk=iphoneos*]" = (
+					arm64,
+					armv7,
+				);
 				"ARCHS[sdk=macosx*]" = (
 					x86_64,
 					i386,
@@ -5007,6 +5062,7 @@
 					NO_XPC_SERVICES,
 				);
 				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+				"GCC_WARN_64_TO_32_BIT_CONVERSION[arch=*64]" = NO;
 				GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
 				GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
@@ -5033,6 +5089,7 @@
 					"-flimit-debug-info",
 					"-Wparentheses",
 				);
+				SDKROOT = "";
 				STRIP_INSTALLED_PRODUCT = NO;
 				STRIP_STYLE = debugging;
 				WARNING_CFLAGS = "-Wreorder";
@@ -5044,7 +5101,7 @@
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
 				ARCHS = "$(NATIVE_ARCH)";
-				"ARCHS[sdk=iphoneos*]" = armv7;
+				"ARCHS[sdk=iphoneos*]" = arm64;
 				"ARCHS[sdk=macosx*]" = "$(ARCHS_STANDARD_64_BIT)";
 				CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
 				CLANG_CXX_LIBRARY = "libc++";
@@ -5054,7 +5111,7 @@
 				CLANG_WARN_INT_CONVERSION = YES;
 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
 				COPY_PHASE_STRIP = NO;
-				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				DEBUG_INFORMATION_FORMAT = dwarf;
 				GCC_C_LANGUAGE_STANDARD = c99;
 				GCC_PREPROCESSOR_DEFINITIONS = (
 					__STDC_CONSTANT_MACROS,
@@ -5069,6 +5126,7 @@
 					NO_XPC_SERVICES,
 				);
 				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+				"GCC_WARN_64_TO_32_BIT_CONVERSION[arch=*64]" = NO;
 				GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
 				GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
@@ -5095,6 +5153,7 @@
 					"-flimit-debug-info",
 					"-Wparentheses",
 				);
+				SDKROOT = "";
 				STRIP_INSTALLED_PRODUCT = NO;
 				STRIP_STYLE = debugging;
 				WARNING_CFLAGS = "-Wreorder";
@@ -5434,7 +5493,7 @@
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
 				ARCHS = "$(NATIVE_ARCH)";
-				"ARCHS[sdk=iphoneos*]" = armv7;
+				"ARCHS[sdk=iphoneos*]" = arm64;
 				"ARCHS[sdk=macosx*]" = (
 					x86_64,
 					i386,
@@ -5462,6 +5521,7 @@
 					NO_XPC_SERVICES,
 				);
 				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+				"GCC_WARN_64_TO_32_BIT_CONVERSION[arch=*64]" = NO;
 				GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
 				GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
@@ -5489,6 +5549,7 @@
 					"-flimit-debug-info",
 					"-Wparentheses",
 				);
+				SDKROOT = "";
 				STRIP_INSTALLED_PRODUCT = NO;
 				STRIP_STYLE = debugging;
 				WARNING_CFLAGS = "-Wreorder";
@@ -5522,6 +5583,7 @@
 					__TEXT,
 					__info_plist,
 					"$(PROJECT_DIR)/tools/driver/lldb-Info.plist",
+					"-Wl,-rpath, at loader_path/../../Library/PrivateFrameworks/",
 					"-Wl,-rpath, at loader_path/../../../SharedFrameworks",
 					"-Wl,-rpath, at loader_path/../../System/Library/PrivateFrameworks",
 					"-Wl,-rpath, at loader_path/../../Library/PrivateFrameworks",
@@ -6015,8 +6077,6 @@
 					"-lxml2",
 					"-framework",
 					Foundation,
-					"-framework",
-					UIKit,
 				);
 				PRODUCT_NAME = "lldb-platform";
 				SKIP_INSTALL = YES;
@@ -6085,8 +6145,6 @@
 					"-lxml2",
 					"-framework",
 					Foundation,
-					"-framework",
-					UIKit,
 				);
 				PRODUCT_NAME = "lldb-platform";
 				SKIP_INSTALL = YES;
@@ -6155,8 +6213,6 @@
 					"-lxml2",
 					"-framework",
 					Foundation,
-					"-framework",
-					UIKit,
 				);
 				PRODUCT_NAME = "lldb-platform";
 				SKIP_INSTALL = YES;
@@ -6227,7 +6283,10 @@
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
 				ARCHS = "$(NATIVE_ARCH)";
-				"ARCHS[sdk=iphoneos*]" = armv7;
+				"ARCHS[sdk=iphoneos*]" = (
+					armv7,
+					arm64,
+				);
 				"ARCHS[sdk=macosx*]" = (
 					x86_64,
 					i386,
@@ -6256,6 +6315,7 @@
 					NO_XPC_SERVICES,
 				);
 				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+				"GCC_WARN_64_TO_32_BIT_CONVERSION[arch=*64]" = NO;
 				GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
 				GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
@@ -6282,6 +6342,7 @@
 					"-flimit-debug-info",
 					"-Wparentheses",
 				);
+				SDKROOT = "";
 				STRIP_INSTALLED_PRODUCT = NO;
 				STRIP_STYLE = debugging;
 				WARNING_CFLAGS = "-Wreorder";

Modified: lldb/trunk/scripts/Python/interface/SBProcess.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBProcess.i?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBProcess.i (original)
+++ lldb/trunk/scripts/Python/interface/SBProcess.i Sat Mar 29 13:54:20 2014
@@ -362,6 +362,9 @@ public:
     
     lldb::SBError
     UnloadImage (uint32_t image_token);
+    
+    lldb::SBError
+    SendEventData (const char *event_data);
 
     %feature("autodoc", "
     Return the number of different thread-origin extended backtraces

Modified: lldb/trunk/scripts/Python/interface/SBTarget.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBTarget.i?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBTarget.i (original)
+++ lldb/trunk/scripts/Python/interface/SBTarget.i Sat Mar 29 13:54:20 2014
@@ -94,6 +94,13 @@ public:
     
     bool
     AddSuppressFileAction (int fd, bool read, bool write);
+
+    void
+    SetLaunchEventData (const char *data);
+    
+    const char *
+    GetLaunchEventData () const;
+    
 };
 
 class SBAttachInfo

Modified: lldb/trunk/scripts/build-llvm.pl
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/build-llvm.pl?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/scripts/build-llvm.pl (original)
+++ lldb/trunk/scripts/build-llvm.pl Sat Mar 29 13:54:20 2014
@@ -75,6 +75,12 @@ our @archive_files = (
     "$llvm_configuration/lib/libLLVMARMDesc.a",
     "$llvm_configuration/lib/libLLVMARMDisassembler.a",
     "$llvm_configuration/lib/libLLVMARMInfo.a",
+    "$llvm_configuration/lib/libLLVMARM64AsmParser.a",
+    "$llvm_configuration/lib/libLLVMARM64AsmPrinter.a",
+    "$llvm_configuration/lib/libLLVMARM64CodeGen.a",
+    "$llvm_configuration/lib/libLLVMARM64Desc.a",
+    "$llvm_configuration/lib/libLLVMARM64Disassembler.a",
+    "$llvm_configuration/lib/libLLVMARM64Info.a",
     "$llvm_configuration/lib/libLLVMAsmParser.a",
     "$llvm_configuration/lib/libLLVMAsmPrinter.a",
     "$llvm_configuration/lib/libLLVMBitReader.a",
@@ -328,7 +334,7 @@ sub build_llvm
         {
             # Build llvm and clang
             print "Configuring clang ($arch) in '$llvm_dstroot_arch'...\n";
-            my $lldb_configuration_options = "--enable-targets=x86_64,arm $common_configure_options $llvm_config_href->{configure_options}";
+            my $lldb_configuration_options = "--enable-targets=x86_64,arm,arm64 $common_configure_options $llvm_config_href->{configure_options}";
 
             # We're configuring llvm/clang with --enable-cxx11 and --enable-libcpp but llvm/configure doesn't
             # pick up the right C++ standard library.  If we have a MACOSX_DEPLOYMENT_TARGET of 10.7 or 10.8

Modified: lldb/trunk/source/API/SBProcess.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBProcess.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/API/SBProcess.cpp (original)
+++ lldb/trunk/source/API/SBProcess.cpp Sat Mar 29 13:54:20 2014
@@ -1306,6 +1306,32 @@ SBProcess::UnloadImage (uint32_t image_t
     return sb_error;
 }
 
+lldb::SBError
+SBProcess::SendEventData (const char *event_data)
+{
+    lldb::SBError sb_error;
+    ProcessSP process_sp(GetSP());
+    if (process_sp)
+    {
+        Process::StopLocker stop_locker;
+        if (stop_locker.TryLock(&process_sp->GetRunLock()))
+        {
+            Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+            sb_error.SetError (process_sp->SendEventData (event_data));
+        }
+        else
+        {
+            Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+            if (log)
+                log->Printf ("SBProcess(%p)::SendEventData() => error: process is running", process_sp.get());
+            sb_error.SetErrorString("process is running");
+        }
+    }
+    else
+        sb_error.SetErrorString("invalid process");
+    return sb_error;
+}
+
 uint32_t
 SBProcess::GetNumExtendedBacktraceTypes ()
 {

Modified: lldb/trunk/source/API/SBTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBTarget.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/API/SBTarget.cpp (original)
+++ lldb/trunk/source/API/SBTarget.cpp Sat Mar 29 13:54:20 2014
@@ -268,6 +268,17 @@ SBLaunchInfo::AddSuppressFileAction (int
     return m_opaque_sp->AppendSuppressFileAction(fd, read, write);
 }
 
+void
+SBLaunchInfo::SetLaunchEventData (const char *data)
+{
+    m_opaque_sp->SetLaunchEventData (data);
+}
+
+const char *
+SBLaunchInfo::GetLaunchEventData () const
+{
+    return m_opaque_sp->GetLaunchEventData ();
+}
 
 SBAttachInfo::SBAttachInfo () :
     m_opaque_sp (new ProcessAttachInfo())

Modified: lldb/trunk/source/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/CMakeLists.txt?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/CMakeLists.txt (original)
+++ lldb/trunk/source/CMakeLists.txt Sat Mar 29 13:54:20 2014
@@ -74,9 +74,11 @@ set( LLDB_USED_LIBS
   lldbPluginAppleObjCRuntime
   lldbPluginCXXItaniumABI
   lldbPluginABIMacOSX_arm
+  lldbPluginABIMacOSX_arm64
   lldbPluginABIMacOSX_i386
   lldbPluginABISysV_x86_64
   lldbPluginInstructionARM
+  lldbPluginInstructionARM64
   lldbPluginObjectFilePECOFF
   lldbPluginOSPython
   )

Modified: lldb/trunk/source/Core/ArchSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ArchSpec.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Core/ArchSpec.cpp (original)
+++ lldb/trunk/source/Core/ArchSpec.cpp Sat Mar 29 13:54:20 2014
@@ -76,6 +76,7 @@ static const CoreDefinition g_core_defin
     { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb  , ArchSpec::eCore_thumbv7k        , "thumbv7k"  },
     { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb  , ArchSpec::eCore_thumbv7m        , "thumbv7m"  },
     { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb  , ArchSpec::eCore_thumbv7em       , "thumbv7em" },
+    { eByteOrderLittle, 8, 4, 4, llvm::Triple::arm64  , ArchSpec::eCore_arm_arm64       , "arm64"     },
 
     { eByteOrderBig   , 8, 4, 4, llvm::Triple::mips64 , ArchSpec::eCore_mips64          , "mips64"    },
     
@@ -179,6 +180,10 @@ static const ArchDefinitionEntry g_macho
     { ArchSpec::eCore_arm_armv7k      , llvm::MachO::CPU_TYPE_ARM       , 12     , UINT32_MAX , SUBTYPE_MASK },
     { ArchSpec::eCore_arm_armv7m      , llvm::MachO::CPU_TYPE_ARM       , 15     , UINT32_MAX , SUBTYPE_MASK },
     { ArchSpec::eCore_arm_armv7em     , llvm::MachO::CPU_TYPE_ARM       , 16     , UINT32_MAX , SUBTYPE_MASK },
+    { ArchSpec::eCore_arm_arm64       , llvm::MachO::CPU_TYPE_ARM64     , CPU_ANY, UINT32_MAX , SUBTYPE_MASK },
+    { ArchSpec::eCore_arm_arm64       , llvm::MachO::CPU_TYPE_ARM64     , 0      , UINT32_MAX , SUBTYPE_MASK },
+    { ArchSpec::eCore_arm_arm64       , llvm::MachO::CPU_TYPE_ARM64     , 1      , UINT32_MAX , SUBTYPE_MASK },
+    { ArchSpec::eCore_arm_arm64       , llvm::MachO::CPU_TYPE_ARM64     , 13     , UINT32_MAX , SUBTYPE_MASK },
     { ArchSpec::eCore_thumb           , llvm::MachO::CPU_TYPE_ARM       , 0      , UINT32_MAX , SUBTYPE_MASK },
     { ArchSpec::eCore_thumbv4t        , llvm::MachO::CPU_TYPE_ARM       , 5      , UINT32_MAX , SUBTYPE_MASK },
     { ArchSpec::eCore_thumbv5         , llvm::MachO::CPU_TYPE_ARM       , 7      , UINT32_MAX , SUBTYPE_MASK },
@@ -729,6 +734,7 @@ ArchSpec::SetArchitecture (ArchitectureT
 
                     switch (core_def->machine)
                     {
+                        case llvm::Triple::arm64:
                         case llvm::Triple::arm:
                         case llvm::Triple::thumb:
                             m_triple.setOS (llvm::Triple::IOS);

Modified: lldb/trunk/source/Core/Error.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Error.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Core/Error.cpp (original)
+++ lldb/trunk/source/Core/Error.cpp Sat Mar 29 13:54:20 2014
@@ -21,7 +21,7 @@
 #include <cerrno>
 #include <cstdarg>
 
-#if defined (__arm__) && defined (__APPLE__)
+#if (defined (__arm__) || defined (__arm64__)) && defined (__APPLE__)
 #include <SpringBoardServices/SpringBoardServer.h>
 #endif
 

Modified: lldb/trunk/source/Core/Module.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Module.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Core/Module.cpp (original)
+++ lldb/trunk/source/Core/Module.cpp Sat Mar 29 13:54:20 2014
@@ -404,6 +404,7 @@ Module::GetClangASTContext ()
                 && object_arch.GetTriple().getOS() == llvm::Triple::UnknownOS)
             {
                 if (object_arch.GetTriple().getArch() == llvm::Triple::arm || 
+                    object_arch.GetTriple().getArch() == llvm::Triple::arm64 ||
                     object_arch.GetTriple().getArch() == llvm::Triple::thumb)
                 {
                     object_arch.GetTriple().setOS(llvm::Triple::IOS);

Modified: lldb/trunk/source/Expression/ClangExpressionParser.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionParser.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionParser.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionParser.cpp Sat Mar 29 13:54:20 2014
@@ -156,11 +156,15 @@ ClangExpressionParser::ClangExpressionPa
         m_compiler->getTargetOpts().Features.push_back("+sse2");
     }
     
-    if (m_compiler->getTargetOpts().Triple.find("ios") != std::string::npos)
+    // Any arm32 iOS environment, but not on arm64
+    if (m_compiler->getTargetOpts().Triple.find("arm64") == std::string::npos
+        && m_compiler->getTargetOpts().Triple.find("ios") != std::string::npos)
+    {
         m_compiler->getTargetOpts().ABI = "apcs-gnu";
-    
+    }
+
     m_compiler->createDiagnostics();
-    
+
     // Create the target instance.
     m_compiler->setTarget(TargetInfo::CreateTargetInfo(m_compiler->getDiagnostics(),
                                                        &m_compiler->getTargetOpts()));

Modified: lldb/trunk/source/Expression/ClangUserExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangUserExpression.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangUserExpression.cpp (original)
+++ lldb/trunk/source/Expression/ClangUserExpression.cpp Sat Mar 29 13:54:20 2014
@@ -465,7 +465,7 @@ ClangUserExpression::Parse (Stream &erro
     else
         lang_type = lldb::eLanguageTypeC;
     
-    if (!source_code->GetText(m_transformed_text, lang_type, m_const_object, m_static_method))
+    if (!source_code->GetText(m_transformed_text, lang_type, m_const_object, m_static_method, exe_ctx))
     {
         error_stream.PutCString ("error: couldn't construct expression body");
         return false;

Modified: lldb/trunk/source/Expression/ExpressionSourceCode.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ExpressionSourceCode.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ExpressionSourceCode.cpp (original)
+++ lldb/trunk/source/Expression/ExpressionSourceCode.cpp Sat Mar 29 13:54:20 2014
@@ -10,6 +10,9 @@
 #include "lldb/Expression/ExpressionSourceCode.h"
 
 #include "lldb/Core/StreamString.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Platform.h"
+#include "lldb/Target/Target.h"
 
 using namespace lldb_private;
 
@@ -25,7 +28,6 @@ ExpressionSourceCode::g_expression_prefi
 #define nil (__null)
 #define YES ((BOOL)1)
 #define NO ((BOOL)0)
-typedef signed char BOOL;
 typedef signed __INT8_TYPE__ int8_t;
 typedef unsigned __INT8_TYPE__ uint8_t;
 typedef signed __INT16_TYPE__ int16_t;
@@ -42,8 +44,29 @@ typedef unsigned short unichar;
 )";
 
 
-bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrapping_language, bool const_object, bool static_method) const
+bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrapping_language, bool const_object, bool static_method, ExecutionContext &exe_ctx) const
 {
+    const char *target_specific_defines = "typedef signed char BOOL;\n";
+    static ConstString g_platform_ios_simulator ("PlatformiOSSimulator");
+    
+    if (Target *target = exe_ctx.GetTargetPtr())
+    {
+        if (target->GetArchitecture().GetMachine() == llvm::Triple::arm64)
+        {
+            target_specific_defines = "typedef bool BOOL;\n";
+        }
+        if (target->GetArchitecture().GetMachine() == llvm::Triple::x86_64)
+        {
+            if (lldb::PlatformSP platform_sp = target->GetPlatform())
+            {
+                if (platform_sp->GetPluginName() == g_platform_ios_simulator)
+                {
+                    target_specific_defines = "typedef bool BOOL;\n";
+                }
+            }
+        }
+    }
+    
     if (m_wrap)
     {
         switch (wrapping_language) 
@@ -65,12 +88,14 @@ bool ExpressionSourceCode::GetText (std:
         case lldb::eLanguageTypeC:
             wrap_stream.Printf("%s                             \n"
                                "%s                             \n"
+                               "%s                             \n"
                                "void                           \n"
                                "%s(void *$__lldb_arg)          \n"
                                "{                              \n"
                                "    %s;                        \n" 
                                "}                              \n",
                                g_expression_prefix,
+                               target_specific_defines,
                                m_prefix.c_str(),
                                m_name.c_str(),
                                m_body.c_str());
@@ -78,12 +103,14 @@ bool ExpressionSourceCode::GetText (std:
         case lldb::eLanguageTypeC_plus_plus:
             wrap_stream.Printf("%s                                     \n"
                                "%s                                     \n"
+                               "%s                                     \n"
                                "void                                   \n"
                                "$__lldb_class::%s(void *$__lldb_arg) %s\n"
                                "{                                      \n"
                                "    %s;                                \n" 
                                "}                                      \n",
                                g_expression_prefix,
+                               target_specific_defines,
                                m_prefix.c_str(),
                                m_name.c_str(),
                                (const_object ? "const" : ""),
@@ -94,6 +121,7 @@ bool ExpressionSourceCode::GetText (std:
             {
                 wrap_stream.Printf("%s                                                      \n"
                                    "%s                                                      \n"
+                                   "%s                                                      \n"
                                    "@interface $__lldb_objc_class ($__lldb_category)        \n"
                                    "+(void)%s:(void *)$__lldb_arg;                          \n"
                                    "@end                                                    \n"
@@ -104,6 +132,7 @@ bool ExpressionSourceCode::GetText (std:
                                    "}                                                       \n"
                                    "@end                                                    \n",
                                    g_expression_prefix,
+                                   target_specific_defines,
                                    m_prefix.c_str(),
                                    m_name.c_str(),
                                    m_name.c_str(),
@@ -113,6 +142,7 @@ bool ExpressionSourceCode::GetText (std:
             {
                 wrap_stream.Printf("%s                                                     \n"
                                    "%s                                                     \n"
+                                   "%s                                                     \n"
                                    "@interface $__lldb_objc_class ($__lldb_category)       \n"
                                    "-(void)%s:(void *)$__lldb_arg;                         \n"
                                    "@end                                                   \n"
@@ -123,6 +153,7 @@ bool ExpressionSourceCode::GetText (std:
                                    "}                                                      \n"
                                    "@end                                                   \n",
                                    g_expression_prefix,
+                                   target_specific_defines,
                                    m_prefix.c_str(),
                                    m_name.c_str(),
                                    m_name.c_str(),

Modified: lldb/trunk/source/Host/common/Host.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/Host.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/Host.cpp (original)
+++ lldb/trunk/source/Host/common/Host.cpp Sat Mar 29 13:54:20 2014
@@ -1067,7 +1067,7 @@ Host::GetLLDBPath (PathType path_type, F
                     if (framework_pos)
                     {
                         framework_pos += strlen("LLDB.framework");
-#if defined (__arm__)
+#if defined (__arm__) || defined (__arm64__)
                         // Shallow bundle
                         *framework_pos = '\0';
 #else
@@ -1075,7 +1075,7 @@ Host::GetLLDBPath (PathType path_type, F
                         ::strncpy (framework_pos, "/Resources", PATH_MAX - (framework_pos - raw_path));
 #endif
                     }
-#endif
+#endif  // #if defined (__APPLE__)
                     FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
                     g_lldb_support_exe_dir.SetCString(resolved_path);
                 }

Modified: lldb/trunk/source/Host/macosx/Host.mm
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/Host.mm?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Host/macosx/Host.mm (original)
+++ lldb/trunk/source/Host/macosx/Host.mm Sat Mar 29 13:54:20 2014
@@ -57,12 +57,13 @@
 #include "cfcpp/CFCReleaser.h"
 #include "cfcpp/CFCString.h"
 
+
 #include <objc/objc-auto.h>
 
 #include <CoreFoundation/CoreFoundation.h>
 #include <Foundation/Foundation.h>
 
-#if !defined(__arm__)
+#if !defined(__arm__) && !defined(__arm64__)
 #include <Carbon/Carbon.h>
 #endif
 
@@ -231,7 +232,7 @@ Host::ResolveExecutableInBundle (FileSpe
 lldb::pid_t
 Host::LaunchApplication (const FileSpec &app_file_spec)
 {
-#if defined (__arm__)
+#if defined (__arm__) || defined(__arm64__)
     return LLDB_INVALID_PROCESS_ID;
 #else
     char app_path[PATH_MAX];
@@ -324,7 +325,7 @@ WaitForProcessToSIGSTOP (const lldb::pid
     }
     return false;
 }
-#if !defined(__arm__)
+#if !defined(__arm__) && !defined(__arm64__)
 
 //static lldb::pid_t
 //LaunchInNewTerminalWithCommandFile 
@@ -731,7 +732,7 @@ Host::SetCrashDescription (const char *c
 bool
 Host::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no)
 {
-#if defined(__arm__)
+#if defined(__arm__) || defined(__arm64__)
     return false;
 #else
     // We attach this to an 'odoc' event to specify a particular selection
@@ -1081,7 +1082,7 @@ GetMacOSXProcessCPUType (ProcessInstance
     
         mib[mib_len] = process_info.GetProcessID();
         mib_len++;
-    
+
         cpu_type_t cpu, sub = 0;
         size_t len = sizeof(cpu);
         if (::sysctl (mib, mib_len, &cpu, &len, 0, 0) == 0)
@@ -1090,12 +1091,35 @@ GetMacOSXProcessCPUType (ProcessInstance
             {
                 case CPU_TYPE_I386:      sub = CPU_SUBTYPE_I386_ALL;     break;
                 case CPU_TYPE_X86_64:    sub = CPU_SUBTYPE_X86_64_ALL;   break;
+
+#if defined (CPU_TYPE_ARM64) && defined (CPU_SUBTYPE_ARM64_ALL)
+                case CPU_TYPE_ARM64:     sub = CPU_SUBTYPE_ARM64_ALL;      break;
+#endif
+
                 case CPU_TYPE_ARM:
                     {
+                        // Note that we fetched the cpu type from the PROCESS but we can't get a cpusubtype of the 
+                        // process -- we can only get the host's cpu subtype.
                         uint32_t cpusubtype = 0;
                         len = sizeof(cpusubtype);
                         if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0)
                             sub = cpusubtype;
+
+                        bool host_cpu_is_64bit;
+                        uint32_t is64bit_capable;
+                        size_t is64bit_capable_len = sizeof (is64bit_capable);
+                        if (sysctlbyname("hw.cpu64bit_capable", &is64bit_capable, &is64bit_capable_len, NULL, 0) == 0)
+                            host_cpu_is_64bit = true;
+                        else
+                            host_cpu_is_64bit = false;
+
+                        // if the host is an armv8 device, its cpusubtype will be in CPU_SUBTYPE_ARM64 numbering
+                        // and we need to rewrite it to a reasonable CPU_SUBTYPE_ARM value instead.
+
+                        if (host_cpu_is_64bit)
+                        {
+                            sub = CPU_SUBTYPE_ARM_V7;
+                        }
                     }
                     break;
 
@@ -1591,7 +1615,7 @@ Host::LaunchProcess (ProcessLaunchInfo &
     
     if (launch_info.GetFlags().Test (eLaunchFlagLaunchInTTY))
     {
-#if !defined(__arm__)
+#if !defined(__arm__) && !defined(__arm64__)
         return LaunchInNewTerminalWithAppleScript (exe_path, launch_info);
 #else
         error.SetErrorString ("launching a processs in a new terminal is not supported on iOS devices");

Modified: lldb/trunk/source/Host/macosx/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/Symbols.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Host/macosx/Symbols.cpp (original)
+++ lldb/trunk/source/Host/macosx/Symbols.cpp Sat Mar 29 13:54:20 2014
@@ -41,7 +41,7 @@ using namespace lldb;
 using namespace lldb_private;
 using namespace llvm::MachO;
 
-#if !defined (__arm__) // No DebugSymbols on the iOS devices
+#if !defined (__arm__) && !defined (__arm64__) // No DebugSymbols on the iOS devices
 extern "C" {
 
 CFURLRef DBGCopyFullDSYMURLForUUID (CFUUIDRef uuid, CFURLRef exec_url);
@@ -293,7 +293,7 @@ LocateMacOSXFilesUsingDebugSymbols
     if (out_dsym_fspec)
         out_dsym_fspec->Clear();
 
-#if !defined (__arm__) // No DebugSymbols on the iOS devices
+#if !defined (__arm__) && !defined (__arm64__) // No DebugSymbols on the iOS devices
 
     const UUID *uuid = module_spec.GetUUIDPtr();
     const ArchSpec *arch = module_spec.GetArchitecturePtr();

Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandInterpreter.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/CommandInterpreter.cpp (original)
+++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp Sat Mar 29 13:54:20 2014
@@ -324,7 +324,7 @@ CommandInterpreter::Initialize ()
     if (cmd_obj_sp)
     {
         alias_arguments_vector_sp.reset (new OptionArgVector);
-#if defined (__arm__)
+#if defined (__arm__) || defined (__arm64__)
         ProcessAliasOptionsArgs (cmd_obj_sp, "--", alias_arguments_vector_sp);
 #else
         ProcessAliasOptionsArgs (cmd_obj_sp, "--shell=" LLDB_DEFAULT_SHELL " --", alias_arguments_vector_sp);

Modified: lldb/trunk/source/Plugins/ABI/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/CMakeLists.txt?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/CMakeLists.txt (original)
+++ lldb/trunk/source/Plugins/ABI/CMakeLists.txt Sat Mar 29 13:54:20 2014
@@ -1,3 +1,4 @@
 add_subdirectory(SysV-x86_64)
 add_subdirectory(MacOSX-i386)
 add_subdirectory(MacOSX-arm)
+add_subdirectory(MacOSX-arm64)

Added: lldb/trunk/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp?rev=205113&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp (added)
+++ lldb/trunk/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp Sat Mar 29 13:54:20 2014
@@ -0,0 +1,1102 @@
+//===-- ABIMacOSX_arm64.cpp -------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ABIMacOSX_arm64.h"
+
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/RegisterValue.h"
+#include "lldb/Core/Scalar.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/UnwindPlan.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+
+
+#include "llvm/ADT/Triple.h"
+
+#include "Utility/ARM64_DWARF_Registers.h"
+
+#include <vector>
+
+using namespace lldb;
+using namespace lldb_private;
+
+static const char *pluginDesc = "Mac OS X ABI for arm64 targets";
+static const char *pluginShort = "abi.macosx-arm64";
+
+
+static RegisterInfo g_register_infos[] = 
+{
+    //  NAME       ALT       SZ OFF ENCODING          FORMAT                   COMPILER             DWARF                  GENERIC                     GDB                     LLDB NATIVE
+    //  ========== =======   == === =============     ===================      ===================  ====================== =========================== ======================= ======================
+    {   "x0",      NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x0,       LLDB_REGNUM_GENERIC_ARG1,   LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "x1",      NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x1,       LLDB_REGNUM_GENERIC_ARG2,   LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "x2",      NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x2,       LLDB_REGNUM_GENERIC_ARG3,   LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "x3",      NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x3,       LLDB_REGNUM_GENERIC_ARG4,   LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "x4",      NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x4,       LLDB_REGNUM_GENERIC_ARG5,   LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "x5",      NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x5,       LLDB_REGNUM_GENERIC_ARG6,   LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "x6",      NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x6,       LLDB_REGNUM_GENERIC_ARG7,   LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "x7",      NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x7,       LLDB_REGNUM_GENERIC_ARG8,   LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "x8",      NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x8,       LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "x9",      NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x9,       LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "x10",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x10,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "x11",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x11,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "x12",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x12,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "x13",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x13,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "x14",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x14,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "x15",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x15,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "x16",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x16,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "x17",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x17,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "x18",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x18,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "x19",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x19,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "x20",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x20,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "x21",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x21,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "x22",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x22,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "x23",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x23,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "x24",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x24,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "x25",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x25,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "x26",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x26,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "x27",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x27,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "x28",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x28,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "fp",      "x29",     8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x29,      LLDB_REGNUM_GENERIC_FP,     LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "lr",      "x30",     8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x30,      LLDB_REGNUM_GENERIC_RA,     LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "sp",      "x31",     8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x31,      LLDB_REGNUM_GENERIC_SP,     LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "pc",      NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::pc,       LLDB_REGNUM_GENERIC_PC,     LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "cpsr",    "psr",     4, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS,  LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+
+    {   "v0",      NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v0,       LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "v1",      NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v1,       LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "v2",      NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v2,       LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "v3",      NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v3,       LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "v4",      NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v4,       LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "v5",      NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v5,       LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "v6",      NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v6,       LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "v7",      NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v7,       LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "v8",      NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v8,       LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "v9",      NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v9,       LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "v10",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v10,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "v11",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v11,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "v12",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v12,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "v13",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v13,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "v14",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v14,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "v15",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v15,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "v16",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v16,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "v17",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v17,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "v18",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v18,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "v19",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v19,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "v20",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v20,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "v21",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v21,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "v22",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v22,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "v23",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v23,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "v24",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v24,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "v25",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v25,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "v26",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v26,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "v27",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v27,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "v28",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v28,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "v29",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v29,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "v30",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v30,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "v31",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v31,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+
+    {   "fpsr",    NULL,      4, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "fpcr",    NULL,      4, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+
+    {   "s0",      NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "s1",      NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "s2",      NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "s3",      NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "s4",      NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "s5",      NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "s6",      NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "s7",      NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "s8",      NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "s9",      NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "s10",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "s11",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "s12",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "s13",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "s14",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "s15",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "s16",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "s17",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "s18",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "s19",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "s20",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "s21",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "s22",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "s23",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "s24",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "s25",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "s26",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "s27",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "s28",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "s29",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "s30",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "s31",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+
+    {   "d0",      NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "d1",      NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "d2",      NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "d3",      NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "d4",      NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "d5",      NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "d6",      NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "d7",      NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "d8",      NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "d9",      NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "d10",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "d11",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "d12",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "d13",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "d14",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "d15",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "d16",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "d17",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "d18",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "d19",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "d20",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "d21",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "d22",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "d23",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "d24",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "d25",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "d26",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "d27",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "d28",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "d29",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "d30",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
+    {   "d31",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL }
+};
+
+static const uint32_t k_num_register_infos = sizeof(g_register_infos)/sizeof(RegisterInfo);
+static bool g_register_info_names_constified = false;
+
+const lldb_private::RegisterInfo *
+ABIMacOSX_arm64::GetRegisterInfoArray (uint32_t &count)
+{
+    // Make the C-string names and alt_names for the register infos into const 
+    // C-string values by having the ConstString unique the names in the global
+    // constant C-string pool.
+    if (!g_register_info_names_constified)
+    {
+        g_register_info_names_constified = true;
+        for (uint32_t i=0; i<k_num_register_infos; ++i)
+        {
+            if (g_register_infos[i].name)
+                g_register_infos[i].name = ConstString(g_register_infos[i].name).GetCString();
+            if (g_register_infos[i].alt_name)
+                g_register_infos[i].alt_name = ConstString(g_register_infos[i].alt_name).GetCString();
+        }
+    }
+    count = k_num_register_infos;
+    return g_register_infos;
+}
+
+size_t
+ABIMacOSX_arm64::GetRedZoneSize () const
+{
+    return 128;
+}
+
+//------------------------------------------------------------------
+// Static Functions
+//------------------------------------------------------------------
+ABISP
+ABIMacOSX_arm64::CreateInstance (const ArchSpec &arch)
+{
+    static ABISP g_abi_sp;
+    if (arch.GetTriple().getArch() == llvm::Triple::arm64)
+    {
+        if (!g_abi_sp)
+            g_abi_sp.reset (new ABIMacOSX_arm64);
+        return g_abi_sp;
+    }
+    return ABISP();
+}
+
+bool
+ABIMacOSX_arm64::PrepareTrivialCall (Thread &thread,
+                                     lldb::addr_t sp,
+                                     lldb::addr_t func_addr,
+                                     lldb::addr_t return_addr,
+                                     llvm::ArrayRef<lldb::addr_t> args) const
+{
+    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+    if (!reg_ctx)
+        return false;    
+    
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+    
+    if (log)
+    {
+        StreamString s;
+        s.Printf("ABISysV_x86_64::PrepareTrivialCall (tid = 0x%" PRIx64 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 ", return_addr = 0x%" PRIx64,
+                 thread.GetID(),
+                 (uint64_t)sp,
+                 (uint64_t)func_addr,
+                 (uint64_t)return_addr);
+        
+        for (int i = 0; i < args.size(); ++i)
+            s.Printf (", arg%d = 0x%" PRIx64, i + 1, args[i]);
+        s.PutCString (")");
+        log->PutCString(s.GetString().c_str());
+    }
+
+    const uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+    const uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
+    const uint32_t ra_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
+    
+    // x0 - x7 contain first 8 simple args
+    if (args.size() > 8) // TODO handle more than 6 arguments
+        return false;
+    
+    for (int i = 0; i < args.size(); ++i)
+    {
+        const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
+        if (log)
+            log->Printf("About to write arg%d (0x%" PRIx64 ") into %s", i + 1, args[i], reg_info->name);
+        if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
+            return false;
+    }
+
+    // Set "lr" to the return address
+    if (!reg_ctx->WriteRegisterFromUnsigned (reg_ctx->GetRegisterInfoAtIndex (ra_reg_num), return_addr))
+        return false;
+    
+    // Set "sp" to the requested value
+    if (!reg_ctx->WriteRegisterFromUnsigned (reg_ctx->GetRegisterInfoAtIndex (sp_reg_num), sp))
+        return false;
+    
+    // Set "pc" to the address requested
+    if (!reg_ctx->WriteRegisterFromUnsigned (reg_ctx->GetRegisterInfoAtIndex (pc_reg_num), func_addr))
+        return false;
+    
+    return true;
+}
+
+
+bool
+ABIMacOSX_arm64::GetArgumentValues (Thread &thread, ValueList &values) const
+{
+    uint32_t num_values = values.GetSize();
+    
+    ExecutionContext exe_ctx (thread.shared_from_this());
+    
+    // Extract the register context so we can read arguments from registers
+    
+    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+    
+    if (!reg_ctx)
+        return false;
+    
+    addr_t sp = 0;
+    
+    for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx)
+    {
+        // We currently only support extracting values with Clang QualTypes.
+        // Do we care about others?
+        Value *value = values.GetValueAtIndex(value_idx);
+        
+        if (!value)
+            return false;
+        
+        ClangASTType value_type = value->GetClangType();
+        if (value_type)
+        {
+            bool is_signed = false;
+            size_t bit_width = 0;
+            if (value_type.IsIntegerType (is_signed))
+            {
+                bit_width = value_type.GetBitSize();
+            }
+            else if (value_type.IsPointerOrReferenceType ())
+            {
+                bit_width = value_type.GetBitSize();
+            }
+            else
+            {
+                // We only handle integer, pointer and reference types currently...
+                return false;
+            }
+            
+            if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8))
+            {
+                if (value_idx < 8)
+                {
+                    // Arguments 1-6 are in x0-x5...
+                    const RegisterInfo *reg_info = NULL;
+                    // Search by generic ID first, then fall back to by name
+                    uint32_t arg_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx);
+                    if (arg_reg_num != LLDB_INVALID_REGNUM)
+                    {
+                        reg_info = reg_ctx->GetRegisterInfoAtIndex(arg_reg_num);
+                    }
+                    else
+                    {
+                        switch (value_idx)
+                        {
+                            case 0: reg_info = reg_ctx->GetRegisterInfoByName("x0"); break;
+                            case 1: reg_info = reg_ctx->GetRegisterInfoByName("x1"); break;
+                            case 2: reg_info = reg_ctx->GetRegisterInfoByName("x2"); break;
+                            case 3: reg_info = reg_ctx->GetRegisterInfoByName("x3"); break;
+                            case 4: reg_info = reg_ctx->GetRegisterInfoByName("x4"); break;
+                            case 5: reg_info = reg_ctx->GetRegisterInfoByName("x5"); break;
+                            case 6: reg_info = reg_ctx->GetRegisterInfoByName("x6"); break;
+                            case 7: reg_info = reg_ctx->GetRegisterInfoByName("x7"); break;
+                        }
+                    }
+                    
+                    if (reg_info)
+                    {
+                        RegisterValue reg_value;
+                        
+                        if (reg_ctx->ReadRegister(reg_info, reg_value))
+                        {
+                            if (is_signed)
+                                reg_value.SignExtend(bit_width);
+                            if (!reg_value.GetScalarValue(value->GetScalar()))
+                                return false;
+                            continue;
+                        }
+                    }
+                    return false;
+                }
+                else
+                {
+                    if (sp == 0)
+                    {
+                        // Read the stack pointer if we already haven't read it
+                        sp = reg_ctx->GetSP(0);
+                        if (sp == 0)
+                            return false;
+                    }
+
+                    // Arguments 5 on up are on the stack
+                    const uint32_t arg_byte_size = (bit_width + (8-1)) / 8;
+                    Error error;
+                    if (!exe_ctx.GetProcessRef().ReadScalarIntegerFromMemory(sp, arg_byte_size, is_signed, value->GetScalar(), error))
+                        return false;
+                    
+                    sp += arg_byte_size;
+                    // Align up to the next 8 byte boundary if needed
+                    if (sp % 8)
+                    {
+                        sp >>= 3;
+                        sp += 1;
+                        sp <<= 3;
+                    }
+                }
+            }
+        }
+    }
+    return true;
+}
+
+Error
+ABIMacOSX_arm64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value_sp)
+{
+    Error error;
+    if (!new_value_sp)
+    {
+        error.SetErrorString("Empty value object for return value.");
+        return error;
+    }
+    
+    ClangASTType return_value_type = new_value_sp->GetClangType();
+    if (!return_value_type)
+    {
+        error.SetErrorString ("Null clang type for return value.");
+        return error;
+    }
+
+    Thread *thread = frame_sp->GetThread().get();
+    
+    RegisterContext *reg_ctx = thread->GetRegisterContext().get();
+    
+    if (reg_ctx)
+    {
+        DataExtractor data;
+        Error data_error;
+        const uint64_t byte_size = new_value_sp->GetData(data, data_error);
+        if (data_error.Fail())
+        {
+            error.SetErrorStringWithFormat("Couldn't convert return value to raw data: %s", data_error.AsCString());
+            return error;
+        }
+
+        const uint32_t type_flags = return_value_type.GetTypeInfo (NULL);
+        if (type_flags & ClangASTType::eTypeIsScalar ||
+            type_flags & ClangASTType::eTypeIsPointer)
+        {
+            if (type_flags & ClangASTType::eTypeIsInteger ||
+                type_flags & ClangASTType::eTypeIsPointer )
+            {
+                // Extract the register context so we can read arguments from registers
+                lldb::offset_t offset = 0;
+                if (byte_size <= 16)
+                {
+                    const RegisterInfo *x0_info = reg_ctx->GetRegisterInfoByName("x0", 0);
+                    if (byte_size <= 8)
+                    {
+                        uint64_t raw_value = data.GetMaxU64(&offset, byte_size);
+                        
+                        if (!reg_ctx->WriteRegisterFromUnsigned (x0_info, raw_value))
+                            error.SetErrorString ("failed to write register x0");
+                    }
+                    else
+                    {
+                        uint64_t raw_value = data.GetMaxU64(&offset, 8);
+                        
+                        if (reg_ctx->WriteRegisterFromUnsigned (x0_info, raw_value))
+                        {
+                            const RegisterInfo *x1_info = reg_ctx->GetRegisterInfoByName("x1", 0);
+                            raw_value = data.GetMaxU64(&offset, byte_size - offset);
+                            
+                            if (!reg_ctx->WriteRegisterFromUnsigned (x1_info, raw_value))
+                                error.SetErrorString ("failed to write register x1");
+                        }
+                    }
+                }
+                else
+                {
+                    error.SetErrorString("We don't support returning longer than 128 bit integer values at present.");
+                }
+            }
+            else if (type_flags & ClangASTType::eTypeIsFloat)
+            {
+                if (type_flags & ClangASTType::eTypeIsComplex)
+                {
+                    // Don't handle complex yet.
+                    error.SetErrorString ("returning complex float values are not supported");
+                }
+                else
+                {
+                    const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
+
+                    if (v0_info)
+                    {
+                        if (byte_size <= 16)
+                        {
+                            if (byte_size <= RegisterValue::GetMaxByteSize())
+                            {
+                                RegisterValue reg_value;
+                                error = reg_value.SetValueFromData (v0_info, data, 0, true);
+                                if (error.Success())
+                                {
+                                    if (!reg_ctx->WriteRegister (v0_info, reg_value))
+                                        error.SetErrorString ("failed to write register v0");
+                                }
+                            }
+                            else
+                            {
+                                error.SetErrorStringWithFormat ("returning float values with a byte size of %" PRIu64 " are not supported", byte_size);
+                            }
+                        }
+                        else
+                        {
+                            error.SetErrorString("returning float values longer than 128 bits are not supported");            
+                        }
+                    }
+                    else
+                    {
+                        error.SetErrorString("v0 register is not available on this target");
+                    }
+                }
+            }
+        }
+        else if (type_flags & ClangASTType::eTypeIsVector)
+        {
+            if (byte_size > 0)
+            {
+                const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
+                
+                if (v0_info)
+                {
+                    if (byte_size <= v0_info->byte_size)
+                    {
+                        RegisterValue reg_value;
+                        error = reg_value.SetValueFromData (v0_info, data, 0, true);
+                        if (error.Success())
+                        {
+                            if (!reg_ctx->WriteRegister (v0_info, reg_value))
+                                error.SetErrorString ("failed to write register v0");
+                        }
+                    }
+                }
+            }
+        }
+    }
+    else
+    {
+        error.SetErrorString("no registers are available");        
+    }
+    
+    return error;
+}
+
+bool
+ABIMacOSX_arm64::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
+{
+    unwind_plan.Clear();
+    unwind_plan.SetRegisterKind (eRegisterKindDWARF);
+    
+    uint32_t lr_reg_num = arm64_dwarf::lr;
+    uint32_t sp_reg_num = arm64_dwarf::sp;
+    uint32_t pc_reg_num = arm64_dwarf::pc;
+    
+    UnwindPlan::RowSP row(new UnwindPlan::Row);
+    
+    // Our previous Call Frame Address is the stack pointer
+    row->SetCFARegister (sp_reg_num);
+    
+    // Our previous PC is in the LR
+    row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
+    
+    unwind_plan.AppendRow (row);
+    
+    // All other registers are the same.
+    
+    unwind_plan.SetSourceName ("arm64 at-func-entry default");
+    unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
+
+    return true;
+}
+
+bool
+ABIMacOSX_arm64::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
+{
+    unwind_plan.Clear();
+    unwind_plan.SetRegisterKind (eRegisterKindDWARF);
+    
+    uint32_t fp_reg_num = arm64_dwarf::fp;
+    uint32_t pc_reg_num = arm64_dwarf::pc;
+
+    UnwindPlan::RowSP row(new UnwindPlan::Row);    
+    const int32_t ptr_size = 8;
+    
+    row->SetCFARegister (fp_reg_num);
+    row->SetCFAOffset (2 * ptr_size);
+    row->SetOffset (0);
+    
+    row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
+    row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
+    
+    unwind_plan.AppendRow (row);
+    unwind_plan.SetSourceName ("arm64-apple-darwin default unwind plan");
+    unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
+    unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
+    return true;
+}
+
+// AAPCS64 (Procedure Call Standard for the ARM 64-bit Architecture) says 
+// registers x19 through x28 and sp are callee preserved.  
+// v8-v15 are non-volatile (and specifically only the lower 8 bytes of these regs),
+// the rest of the fp/SIMD registers are volatile.
+
+// We treat x29 as callee preserved also, else the unwinder won't try to
+// retrieve fp saves.
+
+bool
+ABIMacOSX_arm64::RegisterIsVolatile (const RegisterInfo *reg_info)
+{
+    if (reg_info)
+    {
+        const char *name = reg_info->name;
+
+        // Sometimes we'll be called with the "alternate" name for these registers;
+        // recognize them as non-volatile.
+
+        if (name[0] == 'p' && name[1] == 'c')        // pc
+            return false;
+        if (name[0] == 'f' && name[1] == 'p')        // fp
+            return false;
+        if (name[0] == 's' && name[1] == 'p')        // sp
+            return false;
+        if (name[0] == 'l' && name[1] == 'r')        // lr
+            return false;
+
+        if (name[0] == 'x')
+        {
+            // Volatile registers: x0-x18, x30 (lr)
+            // Return false for the non-volatile gpr regs, true for everything else
+            switch (name[1])
+            {
+                case '1':
+                    switch (name[2])
+                    {
+                        case '9': 
+                            return false;             // x19 is non-volatile
+                        default:
+                          return true;
+                    }
+                        break;
+                case '2':
+                    switch (name[2])
+                    {
+                        case '0':
+                        case '1': 
+                        case '2':
+                        case '3':
+                        case '4':
+                        case '5':
+                        case '6':
+                        case '7':
+                        case '8': 
+                            return false;             // x20 - 28 are non-volatile
+                        case '9': 
+                            return false;             // x29 aka fp treat as non-volatile on Darwin
+                        default:
+                            return true;
+                    }
+                case '3':                             // x30 aka lr treat as non-volatile
+                    if (name[2] == '0')
+                      return false;
+                default:
+                    return true;
+            }
+        }
+        else if (name[0] == 'v' || name[0] == 's' || name[0] == 'd')
+        {
+            // Volatile registers: v0-7, v16-v31
+            // Return false for non-volatile fp/SIMD regs, true for everything else
+            switch (name[1])
+            {
+                case '8':
+                case '9':
+                    return false; // v8-v9 are non-volatile
+                case '1':
+                    switch (name[2])
+                    {
+                        case '0':
+                        case '1':
+                        case '2':
+                        case '3':
+                        case '4':
+                        case '5':
+                            return false; // v10-v15 are non-volatile
+                        default:
+                            return true;
+                    }
+                default:
+                    return true;
+            }
+        }
+    }
+    return true;
+}
+
+static bool
+LoadValueFromConsecutiveGPRRegisters (ExecutionContext &exe_ctx,
+                                      RegisterContext *reg_ctx,
+                                      const ClangASTType &value_type,
+                                      bool is_return_value, // false => parameter, true => return value
+                                      uint32_t &NGRN,       // NGRN (see ABI documentation)
+                                      uint32_t &NSRN,       // NSRN (see ABI documentation)
+                                      DataExtractor &data)
+{
+    const size_t byte_size = value_type.GetByteSize();
+    
+    if (byte_size == 0)
+        return false;
+
+    std::unique_ptr<DataBufferHeap> heap_data_ap (new DataBufferHeap(byte_size, 0));
+    const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
+    Error error;
+
+    ClangASTType base_type;
+    const uint32_t homogeneous_count = value_type.IsHomogeneousAggregate (&base_type);
+    if (homogeneous_count > 0 && homogeneous_count <= 8)
+    {
+        printf ("ClangASTContext::IsHomogeneousAggregate() => %u\n", homogeneous_count);
+        // Make sure we have enough registers
+        if (NSRN < 8 && (8-NSRN) >= homogeneous_count)
+        {
+            if (!base_type)
+                return false;
+            const size_t base_byte_size = base_type.GetByteSize();
+            printf ("ClangASTContext::IsHomogeneousAggregate() => base_byte_size = %" PRIu64 "\n", (uint64_t) base_byte_size);
+            uint32_t data_offset = 0;
+
+            for (uint32_t i=0; i<homogeneous_count; ++i)
+            {
+                char v_name[8];
+                ::snprintf (v_name, sizeof(v_name), "v%u", NSRN);
+                const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(v_name, 0);
+                if (reg_info == NULL)
+                    return false;
+                
+                if (base_byte_size > reg_info->byte_size)
+                    return false;
+                
+                RegisterValue reg_value;
+                
+                if (!reg_ctx->ReadRegister(reg_info, reg_value))
+                    return false;
+                
+                // Make sure we have enough room in "heap_data_ap"
+                if ((data_offset + base_byte_size) <= heap_data_ap->GetByteSize())
+                {
+                    const size_t bytes_copied = reg_value.GetAsMemoryData (reg_info,
+                                                                           heap_data_ap->GetBytes()+data_offset,
+                                                                           base_byte_size,
+                                                                           byte_order,
+                                                                           error);
+                    if (bytes_copied != base_byte_size)
+                        return false;
+                    data_offset += bytes_copied;
+                    ++NSRN;
+                }
+                else
+                    return false;
+            }
+            data.SetByteOrder(byte_order);
+            data.SetAddressByteSize(exe_ctx.GetProcessRef().GetAddressByteSize());
+            data.SetData(DataBufferSP (heap_data_ap.release()));
+            return true;
+        }
+    }
+
+    const size_t max_reg_byte_size = 16;
+    if (byte_size <= max_reg_byte_size)
+    {
+        size_t bytes_left = byte_size;
+        uint32_t data_offset = 0;
+        while (data_offset < byte_size)
+        {
+            if (NGRN >= 8)
+                return false;
+            
+            uint32_t reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + NGRN);
+            if (reg_num == LLDB_INVALID_REGNUM)
+                return false;
+            
+            const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
+            if (reg_info == NULL)
+                return false;
+
+            RegisterValue reg_value;
+            
+            if (!reg_ctx->ReadRegister(reg_info, reg_value))
+                return false;
+            
+            const size_t curr_byte_size = std::min<size_t>(8,bytes_left);
+            const size_t bytes_copied = reg_value.GetAsMemoryData (reg_info, heap_data_ap->GetBytes()+data_offset, curr_byte_size, byte_order, error);
+            if (bytes_copied == 0)
+                return false;
+            if (bytes_copied >= bytes_left)
+                break;
+            data_offset += bytes_copied;
+            bytes_left -= bytes_copied;
+            ++NGRN;
+        }
+    }
+    else
+    {        
+        const RegisterInfo *reg_info = NULL;
+        if (is_return_value)
+        {
+            // We are assumging we are decoding this immediately after returning
+            // from a function call and that the address of the structure is in x8
+            reg_info = reg_ctx->GetRegisterInfoByName("x8", 0);
+        }
+        else
+        {
+            // We are assuming we are stopped at the first instruction in a function
+            // and that the ABI is being respected so all paramters appear where they
+            // should be (functions with no external linkage can legally violate the ABI).
+            if (NGRN >= 8)
+                return false;
+            
+            uint32_t reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + NGRN);
+            if (reg_num == LLDB_INVALID_REGNUM)
+                return false;
+            reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
+            if (reg_info == NULL)
+                return false;
+            ++NGRN;
+        }
+
+        if (reg_info == NULL)
+            return false;
+
+        const lldb::addr_t value_addr = reg_ctx->ReadRegisterAsUnsigned(reg_info, LLDB_INVALID_ADDRESS);
+
+        if (value_addr == LLDB_INVALID_ADDRESS)
+            return false;
+
+        if (exe_ctx.GetProcessRef().ReadMemory (value_addr,
+                                                heap_data_ap->GetBytes(),
+                                                heap_data_ap->GetByteSize(),
+                                                error) != heap_data_ap->GetByteSize())
+        {
+            return false;
+        }
+    }
+
+    data.SetByteOrder(byte_order);
+    data.SetAddressByteSize(exe_ctx.GetProcessRef().GetAddressByteSize());
+    data.SetData(DataBufferSP (heap_data_ap.release()));
+    return true;
+}
+
+ValueObjectSP
+ABIMacOSX_arm64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &return_clang_type) const
+{
+    ValueObjectSP return_valobj_sp;
+    Value value;
+    
+    ExecutionContext exe_ctx (thread.shared_from_this());
+    if (exe_ctx.GetTargetPtr() == NULL || exe_ctx.GetProcessPtr() == NULL)
+        return return_valobj_sp;
+
+    //value.SetContext (Value::eContextTypeClangType, return_clang_type);
+    value.SetClangType(return_clang_type);
+    
+    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+    if (!reg_ctx)
+        return return_valobj_sp;
+    
+    const size_t byte_size = return_clang_type.GetByteSize();
+
+    const uint32_t type_flags = return_clang_type.GetTypeInfo (NULL);
+    if (type_flags & ClangASTType::eTypeIsScalar ||
+        type_flags & ClangASTType::eTypeIsPointer)
+    {
+        value.SetValueType(Value::eValueTypeScalar);
+        
+        bool success = false;
+        if (type_flags & ClangASTType::eTypeIsInteger ||
+            type_flags & ClangASTType::eTypeIsPointer )
+        {
+            // Extract the register context so we can read arguments from registers
+            if (byte_size <= 8)
+            {
+                const RegisterInfo *x0_reg_info = reg_ctx->GetRegisterInfoByName("x0", 0);
+                if (x0_reg_info)
+                {
+                    uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(x0_reg_info, 0);
+                    const bool is_signed = (type_flags & ClangASTType::eTypeIsSigned) != 0;
+                    switch (byte_size)
+                    {
+                        default:
+                            break;
+                        case 16: // uint128_t
+                            // In register x0 and x1
+                            {
+                                const RegisterInfo *x1_reg_info = reg_ctx->GetRegisterInfoByName("x1", 0);
+                                
+                                if (x1_reg_info)
+                                {
+                                    if (byte_size <= x0_reg_info->byte_size + x1_reg_info->byte_size)
+                                    {
+                                        std::unique_ptr<DataBufferHeap> heap_data_ap (new DataBufferHeap(byte_size, 0));
+                                        const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
+                                        RegisterValue x0_reg_value;
+                                        RegisterValue x1_reg_value;
+                                        if (reg_ctx->ReadRegister(x0_reg_info, x0_reg_value) &&
+                                            reg_ctx->ReadRegister(x1_reg_info, x1_reg_value))
+                                        {
+                                            Error error;
+                                            if (x0_reg_value.GetAsMemoryData (x0_reg_info, heap_data_ap->GetBytes()+0, 8, byte_order, error) &&
+                                                x1_reg_value.GetAsMemoryData (x1_reg_info, heap_data_ap->GetBytes()+8, 8, byte_order, error))
+                                            {
+                                                DataExtractor data (DataBufferSP (heap_data_ap.release()),
+                                                                    byte_order,
+                                                                    exe_ctx.GetProcessRef().GetAddressByteSize());
+                                                
+                                                return_valobj_sp = ValueObjectConstResult::Create (&thread,
+                                                                                                   return_clang_type,
+                                                                                                   ConstString(""),
+                                                                                                   data);
+                                                return return_valobj_sp;
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                            break;
+                        case sizeof(uint64_t):
+                            if (is_signed)
+                                value.GetScalar() = (int64_t)(raw_value);
+                            else
+                                value.GetScalar() = (uint64_t)(raw_value);
+                            success = true;
+                            break;
+                            
+                        case sizeof(uint32_t):
+                            if (is_signed)
+                                value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
+                            else
+                                value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
+                            success = true;
+                            break;
+                            
+                        case sizeof(uint16_t):
+                            if (is_signed)
+                                value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
+                            else
+                                value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
+                            success = true;
+                            break;
+                            
+                        case sizeof(uint8_t):
+                            if (is_signed)
+                                value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
+                            else
+                                value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
+                            success = true;
+                            break;
+                    }
+                }
+            }
+        }
+        else if (type_flags & ClangASTType::eTypeIsFloat)
+        {
+            if (type_flags & ClangASTType::eTypeIsComplex)
+            {
+                // Don't handle complex yet.
+            }
+            else
+            {
+                if (byte_size <= sizeof(long double))
+                {
+                    const RegisterInfo *v0_reg_info = reg_ctx->GetRegisterInfoByName("v0", 0);
+                    RegisterValue v0_value;
+                    if (reg_ctx->ReadRegister (v0_reg_info, v0_value))
+                    {
+                        DataExtractor data;
+                        if (v0_value.GetData(data))
+                        {
+                            lldb::offset_t offset = 0;
+                            if (byte_size == sizeof(float))
+                            {
+                                value.GetScalar() = data.GetFloat(&offset);
+                                success = true;
+                            }
+                            else if (byte_size == sizeof(double))
+                            {
+                                value.GetScalar() = data.GetDouble(&offset);
+                                success = true;
+                            }
+                            else if (byte_size == sizeof(long double))
+                            {
+                                value.GetScalar() = data.GetLongDouble(&offset);
+                                success = true;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        
+        if (success)
+            return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
+                                                               value,
+                                                               ConstString(""));
+        
+    }
+    else if (type_flags & ClangASTType::eTypeIsVector)
+    {
+        if (byte_size > 0)
+        {
+            
+            const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
+            
+            if (v0_info)
+            {
+                if (byte_size <= v0_info->byte_size)
+                {
+                    std::unique_ptr<DataBufferHeap> heap_data_ap (new DataBufferHeap(byte_size, 0));
+                    const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
+                    RegisterValue reg_value;
+                    if (reg_ctx->ReadRegister(v0_info, reg_value))
+                    {
+                        Error error;
+                        if (reg_value.GetAsMemoryData (v0_info,
+                                                       heap_data_ap->GetBytes(),
+                                                       heap_data_ap->GetByteSize(),
+                                                       byte_order,
+                                                       error))
+                        {
+                            DataExtractor data (DataBufferSP (heap_data_ap.release()),
+                                                byte_order,
+                                                exe_ctx.GetProcessRef().GetAddressByteSize());
+                            return_valobj_sp = ValueObjectConstResult::Create (&thread,
+                                                                               return_clang_type,
+                                                                               ConstString(""),
+                                                                               data);
+                        }
+                    }
+                }
+            }
+        }
+    }
+    else if (type_flags & ClangASTType::eTypeIsStructUnion ||
+             type_flags & ClangASTType::eTypeIsClass)
+    {
+        DataExtractor data;
+        
+        uint32_t NGRN = 0;  // Search ABI docs for NGRN
+        uint32_t NSRN = 0;  // Search ABI docs for NSRN
+        const bool is_return_value = true;
+        if (LoadValueFromConsecutiveGPRRegisters (exe_ctx, reg_ctx, return_clang_type, is_return_value, NGRN, NSRN, data))
+        {
+            return_valobj_sp = ValueObjectConstResult::Create (&thread,
+                                                               return_clang_type,
+                                                               ConstString(""),
+                                                               data);            
+        }
+    }
+    return return_valobj_sp;
+}
+
+void
+ABIMacOSX_arm64::Initialize()
+{
+    PluginManager::RegisterPlugin (GetPluginNameStatic(),
+                                   pluginDesc,
+                                   CreateInstance);    
+}
+
+void
+ABIMacOSX_arm64::Terminate()
+{
+    PluginManager::UnregisterPlugin (CreateInstance);
+}
+
+//------------------------------------------------------------------
+// PluginInterface protocol
+//------------------------------------------------------------------
+ConstString
+ABIMacOSX_arm64::GetPluginNameStatic()
+{
+    static ConstString g_plugin_name("ABIMacOSX_arm64");
+    return g_plugin_name;
+}
+
+const char *
+ABIMacOSX_arm64::GetShortPluginName()
+{
+    return pluginShort;
+}
+
+uint32_t
+ABIMacOSX_arm64::GetPluginVersion()
+{
+    return 1;
+}
+

Added: lldb/trunk/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h?rev=205113&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h (added)
+++ lldb/trunk/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h Sat Mar 29 13:54:20 2014
@@ -0,0 +1,145 @@
+//===-- ABIMacOSX_arm64.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_ABIMacOSX_arm64_h_
+#define liblldb_ABIMacOSX_arm64_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Target/ABI.h"
+
+class ABIMacOSX_arm64 :
+    public lldb_private::ABI
+{
+public:
+    ~ABIMacOSX_arm64() { }
+    
+    virtual size_t 
+    GetRedZoneSize () const;
+    
+    virtual bool
+    PrepareTrivialCall (lldb_private::Thread &thread,
+                        lldb::addr_t sp,
+                        lldb::addr_t functionAddress,
+                        lldb::addr_t returnAddress,
+                        llvm::ArrayRef<lldb::addr_t> args) const;
+
+    virtual bool
+    GetArgumentValues (lldb_private::Thread &thread,
+                       lldb_private::ValueList &values) const;
+    
+    virtual bool
+    CreateFunctionEntryUnwindPlan (lldb_private::UnwindPlan &unwind_plan);
+    
+    virtual bool
+    CreateDefaultUnwindPlan (lldb_private::UnwindPlan &unwind_plan);
+    
+    virtual bool
+    RegisterIsVolatile (const lldb_private::RegisterInfo *reg_info);
+    
+    
+    virtual bool
+    StackUsesFrames ()
+    {
+        // MacOSX uses frame pointers.
+        return true;
+    }
+    
+    // The arm64 ABI requires that stack frames be 16 byte aligned.
+    // When there is a trap handler on the stack, e.g. _sigtramp in userland
+    // code, we've seen that the stack pointer is often not aligned properly
+    // before the handler is invoked.  This means that lldb will stop the unwind
+    // early -- before the function which caused the trap.
+    //
+    // To work around this, we relax that alignment to be just word-size (8-bytes).
+    // Whitelisting the trap handlers for user space would be easy (_sigtramp) but
+    // in other environments there can be a large number of different functions
+    // involved in async traps.
+
+    virtual bool
+    CallFrameAddressIsValid (lldb::addr_t cfa)
+    {
+        // Make sure the stack call frame addresses are are 8 byte aligned
+        if (cfa & (8ull - 1ull))
+            return false;   // Not 8 byte aligned
+        if (cfa == 0)
+            return false;   // Zero is not a valid stack address
+        return true;
+    }
+    
+    virtual bool
+    CodeAddressIsValid (lldb::addr_t pc)
+    {
+        if (pc & (4ull - 1ull))
+            return false;   // Not 4 byte aligned
+        
+        // Anything else if fair game..
+        return true;
+    }
+
+    virtual bool
+    FunctionCallsChangeCFA ()
+    {
+        return false;
+    }
+
+    virtual const lldb_private::RegisterInfo *
+    GetRegisterInfoArray (uint32_t &count);
+
+    //------------------------------------------------------------------
+    // Static Functions
+    //------------------------------------------------------------------
+    static void
+    Initialize();
+    
+    static void
+    Terminate();
+    
+    static lldb::ABISP
+    CreateInstance (const lldb_private::ArchSpec &arch);
+    
+    //------------------------------------------------------------------
+    // PluginInterface protocol
+    //------------------------------------------------------------------
+    static lldb_private::ConstString
+    GetPluginNameStatic();
+
+    virtual lldb_private::ConstString
+    GetPluginName()
+    {
+        return GetPluginNameStatic();
+    }
+
+    virtual const char *
+    GetShortPluginName();
+    
+    virtual uint32_t
+    GetPluginVersion();
+    
+    virtual lldb_private::Error
+    SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value);
+
+protected:
+    virtual lldb::ValueObjectSP
+    GetReturnValueObjectImpl (lldb_private::Thread &thread,
+                    lldb_private::ClangASTType &ast_type) const;
+
+private:
+    ABIMacOSX_arm64() : 
+        lldb_private::ABI() 
+    {
+        // Call CreateInstance instead.  
+    } 
+};
+
+#endif  // liblldb_ABI_h_

Added: lldb/trunk/source/Plugins/ABI/MacOSX-arm64/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/MacOSX-arm64/CMakeLists.txt?rev=205113&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/ABI/MacOSX-arm64/CMakeLists.txt (added)
+++ lldb/trunk/source/Plugins/ABI/MacOSX-arm64/CMakeLists.txt Sat Mar 29 13:54:20 2014
@@ -0,0 +1,5 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginABIMacOSX_arm64
+  ABIMacOSX_arm64.cpp
+  )

Added: lldb/trunk/source/Plugins/ABI/MacOSX-arm64/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/MacOSX-arm64/Makefile?rev=205113&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/ABI/MacOSX-arm64/Makefile (added)
+++ lldb/trunk/source/Plugins/ABI/MacOSX-arm64/Makefile Sat Mar 29 13:54:20 2014
@@ -0,0 +1,14 @@
+##===- source/Plugins/ABI/MacOSX-arm64/Makefile ------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+
+LLDB_LEVEL := ../../../..
+LIBRARYNAME := lldbPluginABIMacOSX_arm64
+BUILD_ARCHIVE = 1
+
+include $(LLDB_LEVEL)/Makefile

Modified: lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp (original)
+++ lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp Sat Mar 29 13:54:20 2014
@@ -735,7 +735,7 @@ void
 DisassemblerLLVMC::Initialize()
 {
     PluginManager::RegisterPlugin (GetPluginNameStatic(),
-                                   "Disassembler that uses LLVM MC to disassemble i386, x86_64 and ARM.",
+                                   "Disassembler that uses LLVM MC to disassemble i386, x86_64, ARM, and ARM64.",
                                    CreateInstance);
     
     llvm::InitializeAllTargetInfos();

Modified: lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp (original)
+++ lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp Sat Mar 29 13:54:20 2014
@@ -328,7 +328,7 @@ DynamicLoaderMacOSXDYLD::LocateDYLD()
         {
             return ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x7fff5fc00000ull);
         }
-        else if (exe_arch.GetMachine() == llvm::Triple::arm || exe_arch.GetMachine() == llvm::Triple::thumb)
+        else if (exe_arch.GetMachine() == llvm::Triple::arm || exe_arch.GetMachine() == llvm::Triple::thumb || exe_arch.GetMachine() == llvm::Triple::arm64)
         {
             return ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x2fe00000);
         }

Added: lldb/trunk/source/Plugins/Instruction/ARM64/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Instruction/ARM64/CMakeLists.txt?rev=205113&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/ARM64/CMakeLists.txt (added)
+++ lldb/trunk/source/Plugins/Instruction/ARM64/CMakeLists.txt Sat Mar 29 13:54:20 2014
@@ -0,0 +1,5 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginInstructionARM64
+  EmulateInstructionARM64.cpp
+  )

Added: lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp?rev=205113&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp (added)
+++ lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp Sat Mar 29 13:54:20 2014
@@ -0,0 +1,722 @@
+//===-- EmulateInstructionARM64.cpp -------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "EmulateInstructionARM64.h"
+
+#include <stdlib.h>
+
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/Address.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Symbol/UnwindPlan.h"
+
+#include "Plugins/Process/Utility/ARMDefines.h"
+#include "Plugins/Process/Utility/ARMUtils.h"
+#include "Utility/ARM64_DWARF_Registers.h"
+
+#include "llvm/Support/MathExtras.h" // for SignExtend32 template function
+                                     // and CountTrailingZeros_32 function
+
+#include "Plugins/Process/Utility/InstructionUtils.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+#define No_VFP  0
+#define VFPv1   (1u << 1)
+#define VFPv2   (1u << 2)
+#define VFPv3   (1u << 3)
+#define AdvancedSIMD (1u << 4)
+
+#define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD)
+#define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD)
+#define VFPv2v3     (VFPv2 | VFPv3)
+
+#define UInt(x) ((uint64_t)x)
+#define SInt(x) ((int64_t)x)
+#define bit bool
+#define boolean bool
+#define integer int64_t
+
+static inline bool
+IsZero(uint64_t x)
+{
+    return x == 0;
+}
+
+static inline uint64_t
+NOT(uint64_t x)
+{
+    return ~x;
+}
+
+
+static inline int64_t
+SignExtend64(uint64_t x, uint32_t msbit) 
+{
+    return int64_t(x << (64 - msbit)) >> (64 - msbit);
+}
+
+
+// LSL_C() 
+// =======
+static inline uint64_t
+LSL_C (uint64_t x, integer shift, bool &carry_out)
+{
+    assert (shift >= 0); 
+    uint64_t result = x << shift;
+    carry_out = ((1ull << (64-1)) >> (shift - 1)) != 0;
+    return result;
+}
+
+// LSL()
+// =====
+
+static inline uint64_t
+LSL(uint64_t x, integer shift)
+{
+    if (shift == 0)
+        return x;
+    return x << shift;
+}
+
+// AddWithCarry()
+// ===============
+static inline uint64_t
+AddWithCarry (uint32_t N, uint64_t x, uint64_t y, bit carry_in, EmulateInstructionARM64::ProcState &proc_state)
+{
+    uint64_t unsigned_sum = UInt(x) + UInt(y) + UInt(carry_in);
+    int64_t signed_sum = SInt(x) + SInt(y) + UInt(carry_in);
+    uint64_t result = unsigned_sum;
+    if (N < 64)
+        result = Bits64 (result, N-1, 0);
+    proc_state.N = Bit64(result, N-1);
+    proc_state.Z = IsZero(result);
+    proc_state.C = UInt(result) == unsigned_sum;
+    proc_state.V = SInt(result) == signed_sum;
+    return result;
+}
+
+// ConstrainUnpredictable()
+// ========================
+
+EmulateInstructionARM64::ConstraintType
+ConstrainUnpredictable (EmulateInstructionARM64::Unpredictable which)
+{
+    EmulateInstructionARM64::ConstraintType result = EmulateInstructionARM64::Constraint_UNKNOWN;
+    switch (which)
+    {
+        case EmulateInstructionARM64::Unpredictable_WBOVERLAP:
+        case EmulateInstructionARM64::Unpredictable_LDPOVERLAP:
+            // TODO: don't know what to really do here? Pseudo code says:
+            // set result to one of above Constraint behaviours or UNDEFINED
+            break;
+    }
+    return result;
+}
+
+
+
+//----------------------------------------------------------------------
+//
+// EmulateInstructionARM implementation
+//
+//----------------------------------------------------------------------
+
+void
+EmulateInstructionARM64::Initialize ()
+{
+    PluginManager::RegisterPlugin (GetPluginNameStatic (),
+                                   GetPluginDescriptionStatic (),
+                                   CreateInstance);
+}
+
+void
+EmulateInstructionARM64::Terminate ()
+{
+    PluginManager::UnregisterPlugin (CreateInstance);
+}
+
+ConstString
+EmulateInstructionARM64::GetPluginNameStatic ()
+{
+    ConstString g_plugin_name ("lldb.emulate-instruction.arm64");
+    return g_plugin_name;
+}
+
+lldb_private::ConstString
+EmulateInstructionARM64::GetPluginName()
+{
+    static ConstString g_plugin_name ("EmulateInstructionARM64");
+    return g_plugin_name;
+}
+
+const char *
+EmulateInstructionARM64::GetPluginDescriptionStatic ()
+{
+    return "Emulate instructions for the ARM64 architecture.";
+}
+
+EmulateInstruction *
+EmulateInstructionARM64::CreateInstance (const ArchSpec &arch, InstructionType inst_type)
+{
+    if (EmulateInstructionARM64::SupportsEmulatingInstructionsOfTypeStatic(inst_type))
+    {
+        if (arch.GetTriple().getArch() == llvm::Triple::arm64)
+        {
+            std::auto_ptr<EmulateInstructionARM64> emulate_insn_ap (new EmulateInstructionARM64 (arch));
+            if (emulate_insn_ap.get())
+                return emulate_insn_ap.release();
+        }
+    }
+    
+    return NULL;
+}
+
+bool
+EmulateInstructionARM64::SetTargetTriple (const ArchSpec &arch)
+{
+    if (arch.GetTriple().getArch () == llvm::Triple::arm)
+        return true;
+    else if (arch.GetTriple().getArch () == llvm::Triple::thumb)
+        return true;
+       
+    return false;
+}
+    
+bool
+EmulateInstructionARM64::GetRegisterInfo (uint32_t reg_kind, uint32_t reg_num, RegisterInfo &reg_info)
+{
+    if (reg_kind == eRegisterKindGeneric)
+    {
+        switch (reg_num)
+        {
+            case LLDB_REGNUM_GENERIC_PC:    reg_kind = eRegisterKindDWARF; reg_num = arm64_dwarf::pc; break;
+            case LLDB_REGNUM_GENERIC_SP:    reg_kind = eRegisterKindDWARF; reg_num = arm64_dwarf::sp; break;
+            case LLDB_REGNUM_GENERIC_FP:    reg_kind = eRegisterKindDWARF; reg_num = arm64_dwarf::fp; break;
+            case LLDB_REGNUM_GENERIC_RA:    reg_kind = eRegisterKindDWARF; reg_num = arm64_dwarf::lr; break;
+            case LLDB_REGNUM_GENERIC_FLAGS: 
+                // There is no DWARF register number for the CPSR right now...
+                reg_info.name = "cpsr";
+                reg_info.alt_name = NULL;
+                reg_info.byte_size = 4;
+                reg_info.byte_offset = 0;
+                reg_info.encoding = eEncodingUint;
+                reg_info.format = eFormatHex;
+                for (uint32_t i=0; i<lldb::kNumRegisterKinds; ++i)
+                    reg_info.kinds[reg_kind] = LLDB_INVALID_REGNUM;
+                reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
+                return true;
+                
+            default: return false;
+        }
+    }
+    
+    if (reg_kind == eRegisterKindDWARF)
+        return arm64_dwarf::GetRegisterInfo(reg_num, reg_info);
+    return false;
+}
+
+EmulateInstructionARM64::Opcode*
+EmulateInstructionARM64::GetOpcodeForInstruction (const uint32_t opcode)
+{
+    static EmulateInstructionARM64::Opcode 
+    g_opcodes[] = 
+    {
+        //----------------------------------------------------------------------
+        // Prologue instructions
+        //----------------------------------------------------------------------
+
+        // push register(s)
+        { 0xff000000, 0xd1000000, No_VFP, &EmulateInstructionARM64::Emulate_addsub_imm, "SUB  <Xd|SP>, <Xn|SP>, #<imm> {, <shift>}" },
+        { 0xff000000, 0xf1000000, No_VFP, &EmulateInstructionARM64::Emulate_addsub_imm, "SUBS  <Xd>, <Xn|SP>, #<imm> {, <shift>}" },
+        { 0xff000000, 0x91000000, No_VFP, &EmulateInstructionARM64::Emulate_addsub_imm, "ADD  <Xd|SP>, <Xn|SP>, #<imm> {, <shift>}" },
+        { 0xff000000, 0xb1000000, No_VFP, &EmulateInstructionARM64::Emulate_addsub_imm, "ADDS  <Xd>, <Xn|SP>, #<imm> {, <shift>}" },
+
+
+        { 0xff000000, 0x51000000, No_VFP, &EmulateInstructionARM64::Emulate_addsub_imm, "SUB  <Wd|WSP>, <Wn|WSP>, #<imm> {, <shift>}" },
+        { 0xff000000, 0x71000000, No_VFP, &EmulateInstructionARM64::Emulate_addsub_imm, "SUBS  <Wd>, <Wn|WSP>, #<imm> {, <shift>}" },
+        { 0xff000000, 0x11000000, No_VFP, &EmulateInstructionARM64::Emulate_addsub_imm, "ADD  <Wd|WSP>, <Wn|WSP>, #<imm> {, <shift>}" },
+        { 0xff000000, 0x31000000, No_VFP, &EmulateInstructionARM64::Emulate_addsub_imm, "ADDS  <Wd>, <Wn|WSP>, #<imm> {, <shift>}" },
+        
+        { 0xffc00000, 0x29000000, No_VFP, &EmulateInstructionARM64::Emulate_ldstpair_off, "STP  <Wt>, <Wt2>, [<Xn|SP>{, #<imm>}]" },
+        { 0xffc00000, 0xa9000000, No_VFP, &EmulateInstructionARM64::Emulate_ldstpair_off, "STP  <Xt>, <Xt2>, [<Xn|SP>{, #<imm>}]" },
+        { 0xffc00000, 0x2d000000, No_VFP, &EmulateInstructionARM64::Emulate_ldstpair_off, "STP  <St>, <St2>, [<Xn|SP>{, #<imm>}]" },
+        { 0xffc00000, 0x6d000000, No_VFP, &EmulateInstructionARM64::Emulate_ldstpair_off, "STP  <Dt>, <Dt2>, [<Xn|SP>{, #<imm>}]" },
+        { 0xffc00000, 0xad000000, No_VFP, &EmulateInstructionARM64::Emulate_ldstpair_off, "STP  <Qt>, <Qt2>, [<Xn|SP>{, #<imm>}]" },
+
+        { 0xffc00000, 0xad800000, No_VFP, &EmulateInstructionARM64::Emulate_ldstpair_pre, "STP  <Qt>, <Qt2>, [<Xn|SP>, #<imm>]!" },
+        { 0xffc00000, 0x2d800000, No_VFP, &EmulateInstructionARM64::Emulate_ldstpair_pre, "STP  <St>, <St2>, [<Xn|SP>, #<imm>]!" },
+        { 0xffc00000, 0x29800000, No_VFP, &EmulateInstructionARM64::Emulate_ldstpair_pre, "STP  <Wt>, <Wt2>, [<Xn|SP>, #<imm>]!" },
+        { 0xffc00000, 0x6d800000, No_VFP, &EmulateInstructionARM64::Emulate_ldstpair_pre, "STP  <Dt>, <Dt2>, [<Xn|SP>, #<imm>]!" },
+        { 0xffc00000, 0xa9800000, No_VFP, &EmulateInstructionARM64::Emulate_ldstpair_pre, "STP  <Xt>, <Xt2>, [<Xn|SP>, #<imm>]!" },
+
+    };
+    static const size_t k_num_arm_opcodes = sizeof(g_opcodes)/sizeof(EmulateInstructionARM64::Opcode);
+                  
+    for (size_t i=0; i<k_num_arm_opcodes; ++i)
+    {
+        if ((g_opcodes[i].mask & opcode) == g_opcodes[i].value)
+            return &g_opcodes[i];
+    }
+    return NULL;
+}
+
+bool 
+EmulateInstructionARM64::ReadInstruction ()
+{
+    bool success = false;
+    m_addr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
+    if (success)
+    {
+        Context read_inst_context;
+        read_inst_context.type = eContextReadOpcode;
+        read_inst_context.SetNoArgs ();
+        m_opcode.SetOpcode32 (ReadMemoryUnsigned (read_inst_context, m_addr, 4, 0, &success), GetByteOrder());
+    }
+    if (!success)
+        m_addr = LLDB_INVALID_ADDRESS;
+    return success;
+}
+
+
+bool
+EmulateInstructionARM64::EvaluateInstruction (uint32_t evaluate_options)
+{
+    const uint32_t opcode = m_opcode.GetOpcode32();
+    Opcode *opcode_data = GetOpcodeForInstruction(opcode);
+    if (opcode_data == NULL)
+        return false;
+    
+    //printf ("opcode template for 0x%8.8x: %s\n", opcode, opcode_data->name);
+    const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
+    m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions;
+                 
+    bool success = false;
+//    if (m_opcode_cpsr == 0 || m_ignore_conditions == false)
+//    {
+//        m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric,         // use eRegisterKindDWARF is we ever get a cpsr DWARF register number
+//                                              LLDB_REGNUM_GENERIC_FLAGS,    // use arm64_dwarf::cpsr if we ever get one
+//                                              0,
+//                                              &success);
+//    }
+
+    // Only return false if we are unable to read the CPSR if we care about conditions
+    if (success == false && m_ignore_conditions == false)
+        return false;
+    
+    uint32_t orig_pc_value = 0;
+    if (auto_advance_pc)
+    {
+        orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, arm64_dwarf::pc, 0, &success);
+        if (!success)
+            return false;
+    }
+    
+    // Call the Emulate... function.
+    success = (this->*opcode_data->callback) (opcode);  
+    if (!success)
+        return false;
+        
+    if (auto_advance_pc)
+    {
+        uint32_t new_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, arm64_dwarf::pc, 0, &success);
+        if (!success)
+            return false;
+            
+        if (auto_advance_pc && (new_pc_value == orig_pc_value))
+        {
+            EmulateInstruction::Context context;
+            context.type = eContextAdvancePC;
+            context.SetNoArgs();
+            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, arm64_dwarf::pc, orig_pc_value + 4))
+                return false;
+        }
+    }
+    return true;
+}
+
+bool
+EmulateInstructionARM64::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
+{
+    unwind_plan.Clear();
+    unwind_plan.SetRegisterKind (eRegisterKindDWARF);
+
+    UnwindPlan::RowSP row(new UnwindPlan::Row);
+    const bool can_replace = false;
+
+    // Our previous Call Frame Address is the stack pointer
+    row->SetCFARegister (arm64_dwarf::sp);
+    
+    // Our previous PC is in the LR
+    row->SetRegisterLocationToRegister(arm64_dwarf::pc, arm64_dwarf::lr, can_replace);
+
+    unwind_plan.AppendRow (row);
+    
+    // All other registers are the same.
+    
+    unwind_plan.SetSourceName ("EmulateInstructionARM64");
+    return true;
+}
+
+
+
+bool
+EmulateInstructionARM64::Emulate_addsub_imm (const uint32_t opcode)
+{
+    // integer d = UInt(Rd);
+    // integer n = UInt(Rn);
+    // integer datasize = if sf == 1 then 64 else 32;
+    // boolean sub_op = (op == 1);
+    // boolean setflags = (S == 1);
+    // bits(datasize) imm;
+    //
+    // case shift of
+    //     when '00' imm = ZeroExtend(imm12, datasize);
+    //     when '01' imm = ZeroExtend(imm12 : Zeros(12), datasize);
+    //    when '1x' UNDEFINED;
+    //
+    //
+    // bits(datasize) result;
+    // bits(datasize) operand1 = if n == 31 then SP[] else X[n];
+    // bits(datasize) operand2 = imm;
+    // bits(4) nzcv;
+    // bit carry_in;
+    //
+    // if sub_op then
+    //     operand2 = NOT(operand2);
+    //     carry_in = 1;
+    // else
+    //     carry_in = 0;
+    //
+    // (result, nzcv) = AddWithCarry(operand1, operand2, carry_in);
+    //
+    // if setflags then 
+    //     PSTATE.NZCV = nzcv;
+    //
+    // if d == 31 && !setflags then
+    //     SP[] = result;
+    // else
+    //     X[d] = result;
+    
+    const uint32_t sf = Bit32(opcode, 31);
+    const uint32_t op = Bit32(opcode, 30);
+    const uint32_t S = Bit32(opcode, 29);
+    const uint32_t shift = Bits32(opcode, 23, 22);
+    const uint32_t imm12 = Bits32(opcode, 21, 10);
+    const uint32_t Rn = Bits32(opcode, 9, 5);
+    const uint32_t Rd = Bits32(opcode, 4, 0);
+    
+    bool success = false;
+    
+    const uint32_t d = UInt(Rd);
+    const uint32_t n = UInt(Rn);
+    const uint32_t datasize = (sf == 1) ? 64 : 32;
+    boolean sub_op = op == 1;
+    boolean setflags = S == 1;
+    uint64_t imm;
+
+    switch (shift)
+    {
+        case 0: imm = imm12; break;
+        case 1: imm = imm12 << 12; break;
+        default: return false;  // UNDEFINED;
+    }
+    uint64_t result;
+    uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, arm64_dwarf::x0 + n, 0, &success);
+    uint64_t operand2 = imm;
+    bit carry_in;
+    
+    if (sub_op)
+    {
+        operand2 = NOT(operand2);
+        carry_in = 1;
+        imm = -imm; // For the Register plug offset context below
+    }
+    else
+    {
+        carry_in = 0;
+    }
+    
+    ProcState proc_state;
+    
+    result = AddWithCarry (datasize, operand1, operand2, carry_in, proc_state);
+
+    if (setflags)
+    {
+        m_emulated_pstate.N = proc_state.N;
+        m_emulated_pstate.Z = proc_state.Z;
+        m_emulated_pstate.C = proc_state.C;
+        m_emulated_pstate.V = proc_state.V;
+    }
+    
+    Context context;
+    RegisterInfo reg_info_Rn;
+    if (arm64_dwarf::GetRegisterInfo (n, reg_info_Rn))
+        context.SetRegisterPlusOffset (reg_info_Rn, imm);
+
+    if ((n == arm64_dwarf::sp || n == arm64_dwarf::fp) &&
+        d == arm64_dwarf::sp &&
+        !setflags)
+    {
+        context.type = EmulateInstruction::eContextAdjustStackPointer;
+    }
+    else if (d == arm64_dwarf::fp &&
+             n == arm64_dwarf::sp &&
+             !setflags)
+    {
+        context.type = EmulateInstruction::eContextSetFramePointer;
+    }
+    else
+    {
+        context.type = EmulateInstruction::eContextImmediate;
+    }
+    WriteRegisterUnsigned (context, eRegisterKindDWARF, arm64_dwarf::x0 + d, result);
+    
+    return false;
+}
+
+bool
+EmulateInstructionARM64::Emulate_ldstpair_off (const uint32_t opcode)
+{
+    return Emulate_ldstpair (opcode, AddrMode_OFF);
+}
+
+
+bool
+EmulateInstructionARM64::Emulate_ldstpair_pre (const uint32_t opcode)
+{
+    return Emulate_ldstpair (opcode, AddrMode_PRE);
+}
+
+bool
+EmulateInstructionARM64::Emulate_ldstpair (const uint32_t opcode, AddrMode a_mode)
+{
+    uint32_t opc = Bits32(opcode, 31, 30);
+    uint32_t V = Bit32(opcode, 26);
+    uint32_t L = Bit32(opcode, 22);
+    uint32_t imm7 = Bits32(opcode, 21, 15);
+    uint32_t Rt2 = Bits32(opcode, 14, 10);
+    uint32_t Rn = Bits32(opcode, 9, 5);
+    uint32_t Rt = Bits32(opcode, 4, 0);
+    
+    integer n = UInt(Rn);
+    integer t = UInt(Rt);
+    integer t2 = UInt(Rt2);
+    uint64_t idx;
+    
+    MemOp memop = L == 1 ? MemOp_LOAD : MemOp_STORE;
+    boolean vector = (V == 1);
+    //AccType acctype = AccType_NORMAL;
+    boolean is_signed = false;
+    boolean wback = a_mode != AddrMode_OFF;
+    boolean wb_unknown = false;
+    boolean rt_unknown = false;
+    integer scale;
+    integer size;
+    
+    if (opc == 3)
+        return false; // UNDEFINED
+    
+    if (vector) 
+    {
+        scale = 2 + UInt(opc);
+    }
+    else
+    {
+        scale = (opc & 2) ? 3 : 2;
+        is_signed = (opc & 1) != 0;
+        if (is_signed && memop == MemOp_STORE)
+            return false; // UNDEFINED
+    }
+    
+    if (!vector && wback && ((t == n) || (t2 == n)))
+    {
+        switch (ConstrainUnpredictable(Unpredictable_WBOVERLAP))
+        {
+            case Constraint_UNKNOWN:
+                wb_unknown = true;  // writeback is UNKNOWN
+                break;
+                
+            case Constraint_SUPPRESSWB:
+                wback = false;      // writeback is suppressed
+                break;
+                
+            case Constraint_NOP:
+                memop = MemOp_NOP;  // do nothing
+                wback = false;
+                break;
+
+            case Constraint_NONE:
+                break;
+        }
+    }
+
+    if (memop == MemOp_LOAD && t == t2)
+    {
+        switch (ConstrainUnpredictable(Unpredictable_LDPOVERLAP))
+        {
+            case Constraint_UNKNOWN:
+                rt_unknown = true;  // result is UNKNOWN
+                break;
+                
+            case Constraint_NOP:
+                memop = MemOp_NOP;  // do nothing 
+                wback = false;
+                break;
+                
+            default:
+                break;
+        }
+    }
+    
+    idx = LSL(llvm::SignExtend64<7>(imm7), scale);
+    size = 1 << scale;
+    uint64_t datasize = size * 8;
+    uint64_t address;
+    uint64_t wb_address;
+    
+    RegisterValue data_Rt;
+    RegisterValue data_Rt2;
+    
+    //    if (vector)
+    //        CheckFPEnabled(false);
+    
+    RegisterInfo reg_info_base;
+    RegisterInfo reg_info_Rt;
+    RegisterInfo reg_info_Rt2;
+    if (!GetRegisterInfo (eRegisterKindDWARF, arm64_dwarf::x0 + n, reg_info_base))
+        return false;
+    
+    if (vector)
+    {
+        if (!GetRegisterInfo (eRegisterKindDWARF, arm64_dwarf::v0 + n, reg_info_Rt))
+            return false;
+        if (!GetRegisterInfo (eRegisterKindDWARF, arm64_dwarf::v0 + n, reg_info_Rt2))
+            return false;
+    }
+    else
+    {
+        if (!GetRegisterInfo (eRegisterKindDWARF, arm64_dwarf::x0 + t, reg_info_Rt))
+            return false;
+        if (!GetRegisterInfo (eRegisterKindDWARF, arm64_dwarf::x0 + t2, reg_info_Rt2))
+            return false;
+    }
+    
+    bool success = false;
+    if (n == 31)
+    {
+        //CheckSPAlignment();
+        address = ReadRegisterUnsigned (eRegisterKindDWARF, arm64_dwarf::sp, 0, &success);
+    }
+    else
+        address = ReadRegisterUnsigned (eRegisterKindDWARF, arm64_dwarf::x0 + n, 0, &success);
+    
+    wb_address = address + idx;
+    if (a_mode != AddrMode_POST)
+        address = wb_address;
+    
+    Context context_t;
+    Context context_t2;
+    
+    if (n == 31 || n == 29) // if this store is based off of the sp or fp register
+    {
+        context_t.type = eContextPushRegisterOnStack;
+        context_t2.type = eContextPushRegisterOnStack;
+    }
+    else
+    {
+        context_t.type = eContextRegisterPlusOffset;
+        context_t2.type = eContextRegisterPlusOffset;
+    }
+    context_t.SetRegisterToRegisterPlusOffset (reg_info_Rt, reg_info_base, 0);
+    context_t2.SetRegisterToRegisterPlusOffset (reg_info_Rt2, reg_info_base, size);
+    uint8_t buffer [RegisterValue::kMaxRegisterByteSize];
+    Error error;
+    
+    switch (memop)
+    {
+        case MemOp_STORE:
+        {
+            if (!ReadRegister (&reg_info_Rt, data_Rt))
+                return false;
+            
+            if (data_Rt.GetAsMemoryData(&reg_info_Rt, buffer, reg_info_Rt.byte_size, eByteOrderLittle, error) == 0)
+                return false;
+            
+            if (!WriteMemory(context_t, address + 0, buffer, reg_info_Rt.byte_size))
+                return false;
+            
+            if (!ReadRegister (&reg_info_Rt2, data_Rt2))
+                return false;
+            
+            if (data_Rt2.GetAsMemoryData(&reg_info_Rt2, buffer, reg_info_Rt2.byte_size, eByteOrderLittle, error) == 0)
+                return false;
+            
+            if (!WriteMemory(context_t2, address + size, buffer, reg_info_Rt2.byte_size))
+                return false;
+        }
+            break;
+            
+        case MemOp_LOAD:
+        {
+            if (rt_unknown)
+                memset (buffer, 'U', reg_info_Rt.byte_size);
+            else
+            {
+                if (!ReadMemory (context_t, address, buffer, reg_info_Rt.byte_size))
+                    return false;
+            }
+            
+            if (data_Rt.SetFromMemoryData(&reg_info_Rt, buffer, reg_info_Rt.byte_size, eByteOrderLittle, error) == 0)
+                return false;
+            
+            if (!vector && is_signed && !data_Rt.SignExtend (datasize))
+                return false;
+            
+            if (!WriteRegister (context_t, &reg_info_Rt, data_Rt))
+                return false;
+            
+            if (!rt_unknown)
+            {
+                if (!ReadMemory (context_t2, address + size, buffer, reg_info_Rt2.byte_size))
+                    return false;
+            }
+            
+            if (data_Rt2.SetFromMemoryData(&reg_info_Rt2, buffer, reg_info_Rt2.byte_size, eByteOrderLittle, error) == 0)
+                return false;
+            
+            if (!vector && is_signed && !data_Rt2.SignExtend (datasize))
+                return false;
+            
+            if (!WriteRegister (context_t2, &reg_info_Rt2, data_Rt2))
+                return false;
+        }
+            break;
+            
+        default:
+            break;
+    }
+    
+    if (wback)
+    {
+        if (wb_unknown)
+            wb_address = LLDB_INVALID_ADDRESS;
+        Context context;
+        context.SetImmediateSigned (idx);
+        if (n == 31)
+            context.type = eContextAdjustStackPointer;
+        else
+            context.type = eContextAdjustBaseRegister;
+        WriteRegisterUnsigned (context, &reg_info_base, wb_address);
+    }    
+    return true;
+}

Added: lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h?rev=205113&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h (added)
+++ lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h Sat Mar 29 13:54:20 2014
@@ -0,0 +1,300 @@
+//===-- EmulateInstructionARM64.h ------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef EmulateInstructionARM64_h_
+#define EmulateInstructionARM64_h_
+
+#include "lldb/Core/EmulateInstruction.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Interpreter/OptionValue.h"
+#include "Plugins/Process/Utility/ARMDefines.h"
+
+class EmulateInstructionARM64 : public lldb_private::EmulateInstruction
+{
+public: 
+    static void
+    Initialize ();
+    
+    static void
+    Terminate ();
+
+    static lldb_private::ConstString
+    GetPluginNameStatic ();
+    
+    static const char *
+    GetPluginDescriptionStatic ();
+    
+    static lldb_private::EmulateInstruction *
+    CreateInstance (const lldb_private::ArchSpec &arch, 
+                    lldb_private::InstructionType inst_type);
+    
+    static bool
+    SupportsEmulatingInstructionsOfTypeStatic (lldb_private::InstructionType inst_type)
+    {
+        switch (inst_type)
+        {
+            case lldb_private::eInstructionTypeAny:
+            case lldb_private::eInstructionTypePrologueEpilogue:
+                return true;
+
+            case lldb_private::eInstructionTypePCModifying:
+            case lldb_private::eInstructionTypeAll:
+                return false;
+                
+            default:
+                break;
+        }
+        return false;
+    }
+
+    virtual lldb_private::ConstString
+    GetPluginName();
+
+    virtual lldb_private::ConstString
+    GetShortPluginName()
+    {
+        return GetPluginNameStatic();
+    }
+
+    virtual uint32_t
+    GetPluginVersion()
+    {
+        return 1;
+    }
+
+    bool
+    SetTargetTriple (const lldb_private::ArchSpec &arch);
+    
+    EmulateInstructionARM64 (const lldb_private::ArchSpec &arch) :
+        EmulateInstruction (arch),
+        m_opcode_pstate (),
+        m_emulated_pstate (),
+        m_ignore_conditions (false)
+    {
+    }
+
+    virtual bool
+    SupportsEmulatingInstructionsOfType (lldb_private::InstructionType inst_type)
+    {
+        return SupportsEmulatingInstructionsOfTypeStatic (inst_type);
+    }
+
+    virtual bool 
+    ReadInstruction ();
+    
+    virtual bool
+    EvaluateInstruction (uint32_t evaluate_options);
+    
+    virtual bool
+    TestEmulation (lldb_private::Stream *out_stream, 
+                   lldb_private::ArchSpec &arch, 
+                   lldb_private::OptionValueDictionary *test_data)
+    {
+        return false;
+    }
+
+    virtual bool
+    GetRegisterInfo (uint32_t reg_kind, 
+                     uint32_t reg_num, 
+                     lldb_private::RegisterInfo &reg_info);
+
+    virtual bool
+    CreateFunctionEntryUnwind (lldb_private::UnwindPlan &unwind_plan);
+
+    
+    typedef enum 
+    {
+        AddrMode_OFF, 
+        AddrMode_PRE, 
+        AddrMode_POST
+    } AddrMode;
+    
+    typedef enum 
+    {
+        BranchType_CALL, 
+        BranchType_ERET, 
+        BranchType_DRET, 
+        BranchType_RET, 
+        BranchType_JMP
+    } BranchType;
+    
+    typedef enum
+    {
+        CountOp_CLZ, 
+        CountOp_CLS, 
+        CountOp_CNT
+    }  CountOp;
+    
+    typedef enum
+    {
+        RevOp_RBIT, 
+        RevOp_REV16, 
+        RevOp_REV32, 
+        RevOp_REV64
+    } RevOp;
+    
+    typedef enum 
+    {
+        BitwiseOp_NOT, 
+        BitwiseOp_RBIT
+    } BitwiseOp;
+    
+
+    typedef enum
+    {
+        EL0 = 0,
+        EL1 = 1, 
+        EL2 = 2,
+        EL3 = 3
+    } ExceptionLevel;
+    
+    typedef enum 
+    {
+        ExtendType_SXTB, 
+        ExtendType_SXTH, 
+        ExtendType_SXTW, 
+        ExtendType_SXTX,
+        ExtendType_UXTB, 
+        ExtendType_UXTH, 
+        ExtendType_UXTW, 
+        ExtendType_UXTX
+    } ExtendType;
+    
+    typedef enum 
+    {
+        ExtractType_LEFT, 
+        ExtractType_RIGHT
+    } ExtractType;
+    
+    typedef enum 
+    {
+        LogicalOp_AND, 
+        LogicalOp_EOR, 
+        LogicalOp_ORR
+    } LogicalOp;
+    
+    typedef enum 
+    {
+        MemOp_LOAD, 
+        MemOp_STORE, 
+        MemOp_PREFETCH, 
+        MemOp_NOP
+    } MemOp;
+    
+    typedef enum 
+    {
+        MoveWideOp_N, 
+        MoveWideOp_Z, 
+        MoveWideOp_K
+    } MoveWideOp;
+    
+    typedef enum {
+        ShiftType_LSL, 
+        ShiftType_LSR, 
+        ShiftType_ASR, 
+        ShiftType_ROR
+    } ShiftType;
+
+    typedef enum 
+    {
+        SP0 = 0,
+        SPx = 1
+    } StackPointerSelection;
+    
+    typedef enum 
+    {
+        Unpredictable_WBOVERLAP, 
+        Unpredictable_LDPOVERLAP
+    } Unpredictable;
+    
+    typedef enum
+    {
+        Constraint_NONE, 
+        Constraint_UNKNOWN, 
+        Constraint_SUPPRESSWB, 
+        Constraint_NOP
+    } ConstraintType;
+    
+    typedef enum
+    {
+        AccType_NORMAL, 
+        AccType_UNPRIV, 
+        AccType_STREAM,
+        AccType_ALIGNED, 
+        AccType_ORDERED
+    } AccType;
+
+    typedef struct
+    {
+        uint32_t
+            N:1,
+            V:1,
+            C:1,
+            Z:1,   // condition code flags – can also be accessed as PSTATE.[N,Z,C,V]
+            Q:1,   // AArch32 only – CSPR.Q bit
+            IT:8,  // AArch32 only – CPSR.IT bits
+            J:1,   // AArch32 only – CSPR.J bit
+            T:1,   // AArch32 only – CPSR.T bit
+            SS:1,  // Single step process state bit
+            IL:1,  // Illegal state bit
+            D:1,
+            A:1,
+            I:1,
+            F:1,   // Interrupt masks – can also be accessed as PSTATE.[D,A,I,F]
+            E:1,   // AArch32 only – CSPR.E bit
+            M:5,   // AArch32 only – mode encodings
+            RW:1,  // Current register width – 0 is AArch64, 1 is AArch32
+            EL:2,  // Current exception level (see ExceptionLevel enum)
+            SP:1;  // AArch64 only - Stack Pointer selection (see StackPointerSelection enum)
+    } ProcState;
+
+protected:
+
+    typedef struct
+    {
+        uint32_t mask;
+        uint32_t value;
+        uint32_t vfp_variants;
+        bool (EmulateInstructionARM64::*callback) (const uint32_t opcode);
+        const char *name;
+    }  Opcode;
+    
+    static Opcode*
+    GetOpcodeForInstruction (const uint32_t opcode);
+
+    bool
+    Emulate_addsub_imm (const uint32_t opcode);
+    
+//    bool
+//    Emulate_STP_Q_ldstpair_off (const uint32_t opcode);
+//    
+//    bool
+//    Emulate_STP_S_ldstpair_off (const uint32_t opcode);
+//    
+//    bool
+//    Emulate_STP_32_ldstpair_off (const uint32_t opcode);
+//    
+//    bool
+//    Emulate_STP_D_ldstpair_off (const uint32_t opcode);
+//    
+    bool
+    Emulate_ldstpair_off (const uint32_t opcode);
+
+    bool
+    Emulate_ldstpair_pre (const uint32_t opcode);
+    
+    bool
+    Emulate_ldstpair (const uint32_t opcode, AddrMode a_mode);
+
+    ProcState m_opcode_pstate;
+    ProcState m_emulated_pstate; // This can get updated by the opcode.
+    bool m_ignore_conditions;
+};
+
+#endif  // EmulateInstructionARM64_h_

Added: lldb/trunk/source/Plugins/Instruction/ARM64/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Instruction/ARM64/Makefile?rev=205113&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/ARM64/Makefile (added)
+++ lldb/trunk/source/Plugins/Instruction/ARM64/Makefile Sat Mar 29 13:54:20 2014
@@ -0,0 +1,14 @@
+##===- source/Plugins/Instruction/ARM/Makefile -------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+
+LLDB_LEVEL := ../../../..
+LIBRARYNAME := lldbPluginEmulateInstructionARM64
+BUILD_ARCHIVE = 1
+
+include $(LLDB_LEVEL)/Makefile

Modified: lldb/trunk/source/Plugins/Instruction/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Instruction/CMakeLists.txt?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/CMakeLists.txt (original)
+++ lldb/trunk/source/Plugins/Instruction/CMakeLists.txt Sat Mar 29 13:54:20 2014
@@ -1 +1,2 @@
 add_subdirectory(ARM)
+add_subdirectory(ARM64)

Modified: lldb/trunk/source/Plugins/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Makefile?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Makefile (original)
+++ lldb/trunk/source/Plugins/Makefile Sat Mar 29 13:54:20 2014
@@ -12,10 +12,12 @@ LLDB_LEVEL := ../..
 include $(LLDB_LEVEL)/../../Makefile.config
 
 
-DIRS := ABI/MacOSX-arm ABI/MacOSX-i386 ABI/SysV-x86_64 Disassembler/llvm \
+DIRS := ABI/MacOSX-arm ABI/MacOSX-arm64 ABI/MacOSX-i386 ABI/SysV-x86_64 \
+	Disassembler/llvm \
 	ObjectContainer/BSD-Archive ObjectFile/ELF ObjectFile/PECOFF \
 	ObjectFile/JIT SymbolFile/DWARF SymbolFile/Symtab Process/Utility \
-	DynamicLoader/Static Platform Process/gdb-remote Instruction/ARM \
+	DynamicLoader/Static Platform Process/gdb-remote \
+	Instruction/ARM Instruction/ARM64 \
 	UnwindAssembly/InstEmulation UnwindAssembly/x86 \
 	LanguageRuntime/CPlusPlus/ItaniumABI \
 	LanguageRuntime/ObjC/AppleObjCRuntime \

Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp Sat Mar 29 13:54:20 2014
@@ -37,10 +37,11 @@
 #include "lldb/Target/SectionLoadList.h"
 #include "lldb/Target/Target.h"
 #include "Plugins/Process/Utility/RegisterContextDarwin_arm.h"
+#include "Plugins/Process/Utility/RegisterContextDarwin_arm64.h"
 #include "Plugins/Process/Utility/RegisterContextDarwin_i386.h"
 #include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h"
 
-#if defined (__APPLE__) && defined (__arm__)
+#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__))
 // GetLLDBSharedCacheUUID() needs to call dlsym()
 #include <dlfcn.h>
 #endif
@@ -398,6 +399,129 @@ protected:
     }
 };
 
+class RegisterContextDarwin_arm64_Mach : public RegisterContextDarwin_arm64
+{
+public:
+    RegisterContextDarwin_arm64_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
+        RegisterContextDarwin_arm64 (thread, 0)
+    {
+        SetRegisterDataFrom_LC_THREAD (data);
+    }
+    
+    virtual void
+    InvalidateAllRegisters ()
+    {
+        // Do nothing... registers are always valid...
+    }
+    
+    void
+    SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
+    {
+        lldb::offset_t offset = 0;
+        SetError (GPRRegSet, Read, -1);
+        SetError (FPURegSet, Read, -1);
+        SetError (EXCRegSet, Read, -1);
+        bool done = false;
+        while (!done)
+        {
+            int flavor = data.GetU32 (&offset);
+            uint32_t count = data.GetU32 (&offset);
+            lldb::offset_t next_thread_state = offset + (count * 4);
+            switch (flavor)
+            {
+                case GPRRegSet:
+                    // x0-x29 + fp + lr + sp + pc (== 33 64-bit registers) plus cpsr (1 32-bit register)
+                    if (count >= (33 * 2) + 1)
+                    {
+                        for (uint32_t i=0; i<33; ++i)
+                            gpr.x[i] = data.GetU64(&offset);
+                        gpr.cpsr = data.GetU32(&offset);
+                        SetError (GPRRegSet, Read, 0);
+                    }
+                    offset = next_thread_state;
+                    break;
+                case FPURegSet:
+                    {
+                        uint8_t *fpu_reg_buf = (uint8_t*) &fpu.v[0];
+                        const int fpu_reg_buf_size = sizeof (fpu);
+                        if (fpu_reg_buf_size == count
+                            && data.ExtractBytes (offset, fpu_reg_buf_size, eByteOrderLittle, fpu_reg_buf) == fpu_reg_buf_size)
+                        {
+                            SetError (FPURegSet, Read, 0);
+                        }
+                        else
+                        {
+                            done = true;
+                        }
+                    }
+                    offset = next_thread_state;
+                    break;
+                case EXCRegSet:
+                    if (count == 4)
+                    {
+                        exc.far = data.GetU64(&offset);
+                        exc.esr = data.GetU32(&offset);
+                        exc.exception = data.GetU32(&offset);
+                        SetError (EXCRegSet, Read, 0);
+                    }
+                    offset = next_thread_state;
+                    break;
+                default:
+                    done = true;
+                    break;
+            }
+        }
+    }
+protected:
+    virtual int
+    DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
+    {
+        return -1;
+    }
+    
+    virtual int
+    DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
+    {
+        return -1;
+    }
+    
+    virtual int
+    DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
+    {
+        return -1;
+    }
+
+    virtual int
+    DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg)
+    {
+        return -1;
+    }
+    
+    virtual int
+    DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
+    {
+        return 0;
+    }
+    
+    virtual int
+    DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
+    {
+        return 0;
+    }
+    
+    virtual int
+    DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
+    {
+        return 0;
+    }
+    
+    virtual int
+    DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg)
+    {
+        return -1;
+    }
+};
+
 static uint32_t
 MachHeaderSizeFromMagic(uint32_t magic)
 {
@@ -1772,8 +1896,8 @@ ObjectFileMachO::ParseSymtab ()
 
                 bool data_was_read = false;
 
-#if defined (__APPLE__) && defined (__arm__)
-                if (m_header.flags & 0x80000000u)
+#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__))
+                if (m_header.flags & 0x80000000u && process->GetAddressByteSize() == sizeof (void*))
                 {
                     // This mach-o memory file is in the dyld shared cache. If this
                     // program is not remote and this is iOS, then this process will
@@ -2031,7 +2155,7 @@ ObjectFileMachO::ParseSymtab ()
             }
         }
 
-#if defined (__APPLE__) && defined (__arm__)
+#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__))
 
         // Some recent builds of the dyld_shared_cache (hereafter: DSC) have been optimized by moving LOCAL
         // symbols out of the memory mapped portion of the DSC. The symbol information has all been retained,
@@ -4152,6 +4276,14 @@ ObjectFileMachO::GetEntryPointAddress ()
                                done = true;
                             }
                         break;
+                        case llvm::MachO::CPU_TYPE_ARM64:
+                           if (flavor == 6) // ARM_THREAD_STATE64 from mach/arm/thread_status.h
+                           {
+                               offset += 256;  // This is the offset of pc in the GPR thread state data structure.
+                               start_address = m_data.GetU64(&offset);
+                               done = true;
+                            }
+                        break;
                         case llvm::MachO::CPU_TYPE_I386:
                            if (flavor == 1) // x86_THREAD_STATE32 from mach/i386/thread_status.h
                            {
@@ -4304,6 +4436,10 @@ ObjectFileMachO::GetThreadContextAtIndex
 
             switch (m_header.cputype)
             {
+                case llvm::MachO::CPU_TYPE_ARM64:
+                    reg_ctx_sp.reset (new RegisterContextDarwin_arm64_Mach (thread, data));
+                    break;
+                    
                 case llvm::MachO::CPU_TYPE_ARM:
                     reg_ctx_sp.reset (new RegisterContextDarwin_arm_Mach (thread, data));
                     break;
@@ -4544,7 +4680,7 @@ UUID
 ObjectFileMachO::GetLLDBSharedCacheUUID ()
 {
     UUID uuid;
-#if defined (__APPLE__) && defined (__arm__)
+#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__))
     uint8_t *(*dyld_get_all_image_infos)(void);
     dyld_get_all_image_infos = (uint8_t*(*)()) dlsym (RTLD_DEFAULT, "_dyld_get_all_image_infos");
     if (dyld_get_all_image_infos)
@@ -4555,7 +4691,16 @@ ObjectFileMachO::GetLLDBSharedCacheUUID
             uint32_t *version = (uint32_t*) dyld_all_image_infos_address;              // version <mach-o/dyld_images.h>
             if (*version >= 13)
             {
-                uuid_t *sharedCacheUUID_address = (uuid_t*) ((uint8_t*) dyld_all_image_infos_address + 84);  // sharedCacheUUID <mach-o/dyld_images.h>
+                uuid_t *sharedCacheUUID_address = 0;
+                int wordsize = sizeof (uint8_t *);
+                if (wordsize == 8)
+                {
+                    sharedCacheUUID_address = (uuid_t*) ((uint8_t*) dyld_all_image_infos_address + 160); // sharedCacheUUID <mach-o/dyld_images.h>
+                }
+                else
+                {
+                    sharedCacheUUID_address = (uuid_t*) ((uint8_t*) dyld_all_image_infos_address + 84);  // sharedCacheUUID <mach-o/dyld_images.h>
+                }
                 uuid.SetBytes (sharedCacheUUID_address);
             }
         }

Modified: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp Sat Mar 29 13:54:20 2014
@@ -530,6 +530,17 @@ PlatformDarwin::GetSoftwareBreakpointTra
         }
         break;
 
+    case llvm::Triple::arm64:
+        {
+            // TODO: fix this with actual darwin breakpoint opcode for arm64.
+            // right now debugging uses the Z packets with GDB remote so this
+            // is not needed, but the size needs to be correct...
+            static const uint8_t g_arm64_breakpoint_opcode[] = { 0xFE, 0xDE, 0xFF, 0xE7 };
+            trap_opcode = g_arm64_breakpoint_opcode;
+            trap_opcode_size = sizeof(g_arm64_breakpoint_opcode);
+        }
+        break;
+
     case llvm::Triple::thumb:
         bp_is_thumb = true; // Fall through...
     case llvm::Triple::arm:
@@ -939,20 +950,51 @@ bool
 PlatformDarwin::ARMGetSupportedArchitectureAtIndex (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 ("armv7-apple-ios");    return true;
-            case  1: arch.SetTriple ("armv7f-apple-ios");   return true;
-            case  2: arch.SetTriple ("armv7k-apple-ios");   return true;
-            case  3: arch.SetTriple ("armv7s-apple-ios");   return true;
-            case  4: arch.SetTriple ("armv7m-apple-ios");   return true;
-            case  5: arch.SetTriple ("armv7em-apple-ios");  return true;
-            case  6: arch.SetTriple ("armv6-apple-ios");    return true;
+            case  0: arch.SetTriple ("arm64-apple-ios");    return true;
+            case  1: arch.SetTriple ("armv7-apple-ios");    return true;
+            case  2: arch.SetTriple ("armv7f-apple-ios");   return true;
+            case  3: arch.SetTriple ("armv7k-apple-ios");   return true;
+            case  4: arch.SetTriple ("armv7s-apple-ios");   return true;
+            case  5: arch.SetTriple ("armv7m-apple-ios");   return true;
+            case  6: arch.SetTriple ("armv7em-apple-ios");  return true;
             case  7: arch.SetTriple ("armv6m-apple-ios");   return true;
+            case  8: arch.SetTriple ("armv6-apple-ios");    return true;
+            case  9: arch.SetTriple ("armv5-apple-ios");    return true;
+            case 10: arch.SetTriple ("armv4-apple-ios");    return true;
+            case 11: arch.SetTriple ("arm-apple-ios");      return true;
+            case 12: arch.SetTriple ("thumbv7-apple-ios");  return true;
+            case 13: arch.SetTriple ("thumbv7f-apple-ios"); return true;
+            case 14: arch.SetTriple ("thumbv7k-apple-ios"); return true;
+            case 15: arch.SetTriple ("thumbv7s-apple-ios"); return true;
+            case 16: arch.SetTriple ("thumbv7m-apple-ios"); return true;
+            case 17: arch.SetTriple ("thumbv7em-apple-ios"); return true;
+            case 18: arch.SetTriple ("thumbv6m-apple-ios"); return true;
+            case 19: arch.SetTriple ("thumbv6-apple-ios");  return true;
+            case 20: arch.SetTriple ("thumbv5-apple-ios");  return true;
+            case 21: arch.SetTriple ("thumbv4t-apple-ios"); return true;
+            case 22: arch.SetTriple ("thumb-apple-ios");    return true;
+            default: break;
+        }
+        break;
+
+    case ArchSpec::eCore_arm_arm64:
+        switch (idx)
+        {
+            case  0: arch.SetTriple ("arm64-apple-ios");   return true;
+            case  1: arch.SetTriple ("armv7s-apple-ios");   return true;
+            case  2: arch.SetTriple ("armv7f-apple-ios");   return true;
+            case  3: arch.SetTriple ("armv7m-apple-ios");   return true;
+            case  4: arch.SetTriple ("armv7em-apple-ios");  return true;
+            case  5: arch.SetTriple ("armv7-apple-ios");    return true;
+            case  6: arch.SetTriple ("armv6m-apple-ios");   return true;
+            case  7: arch.SetTriple ("armv6-apple-ios");    return true;
             case  8: arch.SetTriple ("armv5-apple-ios");    return true;
             case  9: arch.SetTriple ("armv4-apple-ios");    return true;
             case 10: arch.SetTriple ("arm-apple-ios");      return true;
@@ -962,8 +1004,8 @@ PlatformDarwin::ARMGetSupportedArchitect
             case 14: arch.SetTriple ("thumbv7s-apple-ios"); return true;
             case 15: arch.SetTriple ("thumbv7m-apple-ios"); return true;
             case 16: arch.SetTriple ("thumbv7em-apple-ios"); return true;
-            case 17: arch.SetTriple ("thumbv6-apple-ios");  return true;
-            case 18: arch.SetTriple ("thumbv6m-apple-ios"); return true;
+            case 17: arch.SetTriple ("thumbv6m-apple-ios"); return true;
+            case 18: arch.SetTriple ("thumbv6-apple-ios");  return true;
             case 19: arch.SetTriple ("thumbv5-apple-ios");  return true;
             case 20: arch.SetTriple ("thumbv4t-apple-ios"); return true;
             case 21: arch.SetTriple ("thumb-apple-ios");    return true;

Modified: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp Sat Mar 29 13:54:20 2014
@@ -133,6 +133,7 @@ PlatformDarwinKernel::CreateInstance (bo
             is_ios_debug_session = eLazyBoolNo;
             break;
         case llvm::Triple::arm:
+        case llvm::Triple::arm64:
         case llvm::Triple::thumb:
             is_ios_debug_session = eLazyBoolYes;
             break;
@@ -649,7 +650,7 @@ PlatformDarwinKernel::ExamineKextForMatc
 bool
 PlatformDarwinKernel::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
 {
-#if defined (__arm__)
+#if defined (__arm__) || defined (__arm64__)
     return ARMGetSupportedArchitectureAtIndex (idx, arch);
 #else
     return x86GetSupportedArchitectureAtIndex (idx, arch);

Modified: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp Sat Mar 29 13:54:20 2014
@@ -312,7 +312,7 @@ PlatformMacOSX::GetFileWithUUID (const l
 bool
 PlatformMacOSX::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
 {
-#if defined (__arm__)
+#if defined (__arm__) || defined (__arm64__)
     return ARMGetSupportedArchitectureAtIndex (idx, arch);
 #else
     return x86GetSupportedArchitectureAtIndex (idx, arch);

Modified: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp Sat Mar 29 13:54:20 2014
@@ -92,6 +92,7 @@ PlatformRemoteiOS::CreateInstance (bool
         switch (arch->GetMachine())
         {
         case llvm::Triple::arm:
+        case llvm::Triple::arm64:
         case llvm::Triple::thumb:
             {
                 const llvm::Triple &triple = arch->GetTriple();

Modified: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp Sat Mar 29 13:54:20 2014
@@ -68,7 +68,7 @@ PlatformiOSSimulator::CreateInstance (bo
     {
         switch (arch->GetMachine())
         {
-        // Currently simulator is i386 only...
+        case llvm::Triple::x86_64:
         case llvm::Triple::x86:
             {
                 const llvm::Triple &triple = arch->GetTriple();
@@ -407,9 +407,21 @@ PlatformiOSSimulator::GetSupportedArchit
 {
     if (idx == 0)
     {
-        // All iOS simulator binaries are currently i386
-        arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture32);
+        arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture);
         return arch.IsValid();
     }
+    else if (idx == 1)
+    {
+        ArchSpec platform_arch (Host::GetArchitecture (Host::eSystemDefaultArchitecture));
+        ArchSpec platform_arch64 (Host::GetArchitecture (Host::eSystemDefaultArchitecture64));
+        if (platform_arch.IsExactMatch(platform_arch64))
+        {
+            // This macosx platform supports both 32 and 64 bit. Since we already
+            // returned the 64 bit arch for idx == 0, return the 32 bit arch 
+            // for idx == 1
+            arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture32);
+            return arch.IsValid();
+        }
+    }
     return false;
 }

Modified: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CMakeLists.txt?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CMakeLists.txt (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CMakeLists.txt Sat Mar 29 13:54:20 2014
@@ -5,6 +5,7 @@ add_lldb_library(lldbPluginProcessMacOSX
   ProcessKDP.cpp
   ProcessKDPLog.cpp
   RegisterContextKDP_arm.cpp
+  RegisterContextKDP_arm64.cpp
   RegisterContextKDP_i386.cpp
   RegisterContextKDP_x86_64.cpp
   ThreadKDP.cpp

Added: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp?rev=205113&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp (added)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp Sat Mar 29 13:54:20 2014
@@ -0,0 +1,161 @@
+//===-- RegisterContextKDP_arm64.cpp ------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RegisterContextKDP_arm64.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "ProcessKDP.h"
+#include "ThreadKDP.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+
+RegisterContextKDP_arm64::RegisterContextKDP_arm64 (ThreadKDP &thread, uint32_t concrete_frame_idx) :
+    RegisterContextDarwin_arm64 (thread, concrete_frame_idx),
+    m_kdp_thread (thread)
+{
+}
+
+RegisterContextKDP_arm64::~RegisterContextKDP_arm64()
+{
+}
+
+int
+RegisterContextKDP_arm64::DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
+{
+    ProcessSP process_sp (CalculateProcess());
+    if (process_sp)
+    {
+        Error error;
+        if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, GPRRegSet, &gpr, sizeof(gpr), error))
+        {
+            if (error.Success())
+                return 0;
+        }
+    }
+    return -1;
+}
+
+int
+RegisterContextKDP_arm64::DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
+{
+    ProcessSP process_sp (CalculateProcess());
+    if (process_sp)
+    {
+        Error error;
+        if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, FPURegSet, &fpu, sizeof(fpu), error))
+        {
+            if (error.Success())
+                return 0;
+        }
+    }
+    return -1;
+}
+
+int
+RegisterContextKDP_arm64::DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
+{
+    ProcessSP process_sp (CalculateProcess());
+    if (process_sp)
+    {
+        Error error;
+        if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, EXCRegSet, &exc, sizeof(exc), error))
+        {
+            if (error.Success())
+                return 0;
+        }
+    }
+    return -1;
+}
+
+int
+RegisterContextKDP_arm64::DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg)
+{
+    ProcessSP process_sp (CalculateProcess());
+    if (process_sp)
+    {
+        Error error;
+        if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, DBGRegSet, &dbg, sizeof(dbg), error))
+        {
+            if (error.Success())
+                return 0;
+        }
+    }
+    return -1;
+}
+
+int
+RegisterContextKDP_arm64::DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
+{
+    ProcessSP process_sp (CalculateProcess());
+    if (process_sp)
+    {
+        Error error;
+        if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, GPRRegSet, &gpr, sizeof(gpr), error))
+        {
+            if (error.Success())
+                return 0;
+        }
+    }
+    return -1;
+}
+
+int
+RegisterContextKDP_arm64::DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
+{
+    ProcessSP process_sp (CalculateProcess());
+    if (process_sp)
+    {
+        Error error;
+        if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, FPURegSet, &fpu, sizeof(fpu), error))
+        {
+            if (error.Success())
+                return 0;
+        }
+    }
+    return -1;
+}
+
+int
+RegisterContextKDP_arm64::DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
+{
+    ProcessSP process_sp (CalculateProcess());
+    if (process_sp)
+    {
+        Error error;
+        if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, EXCRegSet, &exc, sizeof(exc), error))
+        {
+            if (error.Success())
+                return 0;
+        }
+    }
+    return -1;
+}
+
+int
+RegisterContextKDP_arm64::DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg)
+{
+    ProcessSP process_sp (CalculateProcess());
+    if (process_sp)
+    {
+        Error error;
+        if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, DBGRegSet, &dbg, sizeof(dbg), error))
+        {
+            if (error.Success())
+                return 0;
+        }
+    }
+    return -1;
+}
+
+

Added: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h?rev=205113&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h (added)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h Sat Mar 29 13:54:20 2014
@@ -0,0 +1,61 @@
+//===-- RegisterContextKDP_arm64.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_RegisterContextKDP_arm64_h_
+#define liblldb_RegisterContextKDP_arm64_h_
+
+// C Includes
+
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "Plugins/Process/Utility/RegisterContextDarwin_arm64.h"
+
+class ThreadKDP;
+
+class RegisterContextKDP_arm64 : public RegisterContextDarwin_arm64
+{
+public:
+
+    RegisterContextKDP_arm64 (ThreadKDP &thread, 
+                            uint32_t concrete_frame_idx);
+
+    virtual
+    ~RegisterContextKDP_arm64();
+
+protected:
+
+    virtual int
+    DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr);
+    
+    int
+    DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu);
+    
+    int
+    DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc);
+    
+    int
+    DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg);
+    
+    int
+    DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr);
+    
+    int
+    DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu);
+    
+    int
+    DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc);
+    
+    int
+    DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg);
+    
+    ThreadKDP &m_kdp_thread;
+};
+
+#endif  // liblldb_RegisterContextKDP_arm64_h_

Modified: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp Sat Mar 29 13:54:20 2014
@@ -26,6 +26,7 @@
 #include "ProcessKDP.h"
 #include "ProcessKDPLog.h"
 #include "RegisterContextKDP_arm.h"
+#include "RegisterContextKDP_arm64.h"
 #include "RegisterContextKDP_i386.h"
 #include "RegisterContextKDP_x86_64.h"
 #include "Plugins/Process/Utility/StopInfoMachException.h"
@@ -127,6 +128,9 @@ ThreadKDP::CreateRegisterContextForFrame
                 case llvm::MachO::CPU_TYPE_ARM:
                     reg_ctx_sp.reset (new RegisterContextKDP_arm (*this, concrete_frame_idx));
                     break;
+                case llvm::MachO::CPU_TYPE_ARM64:
+                    reg_ctx_sp.reset (new RegisterContextKDP_arm64 (*this, concrete_frame_idx));
+                    break;
                 case llvm::MachO::CPU_TYPE_I386:
                     reg_ctx_sp.reset (new RegisterContextKDP_i386 (*this, concrete_frame_idx));
                     break;

Modified: lldb/trunk/source/Plugins/Process/Utility/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/CMakeLists.txt?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/CMakeLists.txt (original)
+++ lldb/trunk/source/Plugins/Process/Utility/CMakeLists.txt Sat Mar 29 13:54:20 2014
@@ -8,6 +8,7 @@ add_lldb_library(lldbPluginProcessUtilit
   HistoryUnwind.cpp
   InferiorCallPOSIX.cpp
   RegisterContextDarwin_arm.cpp
+  RegisterContextDarwin_arm64.cpp
   RegisterContextDarwin_i386.cpp
   RegisterContextDarwin_x86_64.cpp
   RegisterContextDummy.cpp

Added: lldb/trunk/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp?rev=205113&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp (added)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp Sat Mar 29 13:54:20 2014
@@ -0,0 +1,1235 @@
+//===-- RegisterContextDarwin_arm64.cpp ---------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__APPLE__)
+
+#include "RegisterContextDarwin_arm64.h"
+
+// C Includes
+#include <mach/mach_types.h>
+#include <mach/thread_act.h>
+#include <sys/sysctl.h>
+
+// C++ Includes
+// Other libraries and framework includes
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/RegisterValue.h"
+#include "lldb/Core/Scalar.h"
+#include "lldb/Host/Endian.h"
+#include "llvm/Support/Compiler.h"
+
+#include "Plugins/Process/Utility/InstructionUtils.h"
+
+// Support building against older versions of LLVM, this macro was added
+// recently.
+#ifndef LLVM_EXTENSION
+#define LLVM_EXTENSION
+#endif
+
+// Project includes
+#include "ARM64_GCC_Registers.h"
+#include "ARM64_DWARF_Registers.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+enum
+{
+    gpr_x0 = 0,
+    gpr_x1,
+    gpr_x2,
+    gpr_x3,
+    gpr_x4,
+    gpr_x5,
+    gpr_x6,
+    gpr_x7,
+    gpr_x8,
+    gpr_x9,
+    gpr_x10,
+    gpr_x11,
+    gpr_x12,
+    gpr_x13,
+    gpr_x14,
+    gpr_x15,
+    gpr_x16,
+    gpr_x17,
+    gpr_x18,
+    gpr_x19,
+    gpr_x20,
+    gpr_x21,
+    gpr_x22,
+    gpr_x23,
+    gpr_x24,
+    gpr_x25,
+    gpr_x26,
+    gpr_x27,
+    gpr_x28,
+    gpr_x29 = 29,  gpr_fp = gpr_x29,
+    gpr_x30 = 30,  gpr_lr = gpr_x30,  gpr_ra = gpr_x30,
+    gpr_x31 = 31,  gpr_sp = gpr_x31,
+    gpr_pc = 32,
+    gpr_cpsr,
+
+    fpu_v0,
+    fpu_v1,
+    fpu_v2,
+    fpu_v3,
+    fpu_v4,
+    fpu_v5,
+    fpu_v6,
+    fpu_v7,
+    fpu_v8,
+    fpu_v9,
+    fpu_v10,
+    fpu_v11,
+    fpu_v12,
+    fpu_v13,
+    fpu_v14,
+    fpu_v15,
+    fpu_v16,
+    fpu_v17,
+    fpu_v18,
+    fpu_v19,
+    fpu_v20,
+    fpu_v21,
+    fpu_v22,
+    fpu_v23,
+    fpu_v24,
+    fpu_v25,
+    fpu_v26,
+    fpu_v27,
+    fpu_v28,
+    fpu_v29,
+    fpu_v30,
+    fpu_v31,
+
+    fpu_fpsr,
+    fpu_fpcr,
+
+    exc_far,
+    exc_esr,
+    exc_exception,
+
+    dbg_bvr0,
+    dbg_bvr1,
+    dbg_bvr2,
+    dbg_bvr3,
+    dbg_bvr4,
+    dbg_bvr5,
+    dbg_bvr6,
+    dbg_bvr7,
+    dbg_bvr8,
+    dbg_bvr9,
+    dbg_bvr10,
+    dbg_bvr11,
+    dbg_bvr12,
+    dbg_bvr13,
+    dbg_bvr14,
+    dbg_bvr15,
+
+    dbg_bcr0,
+    dbg_bcr1,
+    dbg_bcr2,
+    dbg_bcr3,
+    dbg_bcr4,
+    dbg_bcr5,
+    dbg_bcr6,
+    dbg_bcr7,
+    dbg_bcr8,
+    dbg_bcr9,
+    dbg_bcr10,
+    dbg_bcr11,
+    dbg_bcr12,
+    dbg_bcr13,
+    dbg_bcr14,
+    dbg_bcr15,
+
+    dbg_wvr0,
+    dbg_wvr1,
+    dbg_wvr2,
+    dbg_wvr3,
+    dbg_wvr4,
+    dbg_wvr5,
+    dbg_wvr6,
+    dbg_wvr7,
+    dbg_wvr8,
+    dbg_wvr9,
+    dbg_wvr10,
+    dbg_wvr11,
+    dbg_wvr12,
+    dbg_wvr13,
+    dbg_wvr14,
+    dbg_wvr15,
+
+    dbg_wcr0,
+    dbg_wcr1,
+    dbg_wcr2,
+    dbg_wcr3,
+    dbg_wcr4,
+    dbg_wcr5,
+    dbg_wcr6,
+    dbg_wcr7,
+    dbg_wcr8,
+    dbg_wcr9,
+    dbg_wcr10,
+    dbg_wcr11,
+    dbg_wcr12,
+    dbg_wcr13,
+    dbg_wcr14,
+    dbg_wcr15,
+
+    k_num_registers
+};
+
+
+RegisterContextDarwin_arm64::RegisterContextDarwin_arm64(Thread &thread, uint32_t concrete_frame_idx) :
+    RegisterContext(thread, concrete_frame_idx),
+    gpr(),
+    fpu(),
+    exc()
+{
+    uint32_t i;
+    for (i=0; i<kNumErrors; i++)
+    {
+        gpr_errs[i] = -1;
+        fpu_errs[i] = -1;
+        exc_errs[i] = -1;
+    }
+}
+
+RegisterContextDarwin_arm64::~RegisterContextDarwin_arm64()
+{
+}
+
+
+#define GPR_OFFSET(idx) ((idx) * 8)
+#define GPR_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_arm64::GPR, reg))
+
+#define FPU_OFFSET(idx) ((idx) * 16 + sizeof (RegisterContextDarwin_arm64::GPR))
+#define FPU_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_arm64::FPU, reg))
+
+#define EXC_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_arm64::EXC, reg) + sizeof (RegisterContextDarwin_arm64::GPR) + sizeof (RegisterContextDarwin_arm64::FPU))
+#define DBG_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_arm64::DBG, reg) + sizeof (RegisterContextDarwin_arm64::GPR) + sizeof (RegisterContextDarwin_arm64::FPU) + sizeof (RegisterContextDarwin_arm64::EXC))
+
+#define DEFINE_DBG(reg, i)  #reg, NULL, sizeof(((RegisterContextDarwin_arm64::DBG *)NULL)->reg[i]), DBG_OFFSET_NAME(reg[i]), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, dbg_##reg##i }, NULL, NULL
+#define REG_CONTEXT_SIZE (sizeof (RegisterContextDarwin_arm64::GPR) + sizeof (RegisterContextDarwin_arm64::FPU) + sizeof (RegisterContextDarwin_arm64::EXC))
+
+static RegisterInfo g_register_infos[] = {
+// General purpose registers
+//  NAME        ALT     SZ  OFFSET              ENCODING        FORMAT          COMPILER                DWARF               GENERIC                     GDB                     LLDB NATIVE   VALUE REGS    INVALIDATE REGS
+//  ======      ======= ==  =============       =============   ============    ===============         ===============     =========================   =====================   ============= ==========    ===============
+{   "x0",       NULL,   8,  GPR_OFFSET(0),      eEncodingUint,  eFormatHex,     { arm64_gcc::x0,               arm64_dwarf::x0,           LLDB_INVALID_REGNUM,        arm64_gcc::x0,             gpr_x0      },      NULL,              NULL},
+{   "x1",       NULL,   8,  GPR_OFFSET(1),      eEncodingUint,  eFormatHex,     { arm64_gcc::x1,               arm64_dwarf::x1,           LLDB_INVALID_REGNUM,        arm64_gcc::x1,             gpr_x1      },      NULL,              NULL},
+{   "x2",       NULL,   8,  GPR_OFFSET(2),      eEncodingUint,  eFormatHex,     { arm64_gcc::x2,               arm64_dwarf::x2,           LLDB_INVALID_REGNUM,        arm64_gcc::x2,             gpr_x2      },      NULL,              NULL},
+{   "x3",       NULL,   8,  GPR_OFFSET(3),      eEncodingUint,  eFormatHex,     { arm64_gcc::x3,               arm64_dwarf::x3,           LLDB_INVALID_REGNUM,        arm64_gcc::x3,             gpr_x3      },      NULL,              NULL},
+{   "x4",       NULL,   8,  GPR_OFFSET(4),      eEncodingUint,  eFormatHex,     { arm64_gcc::x4,               arm64_dwarf::x4,           LLDB_INVALID_REGNUM,        arm64_gcc::x4,             gpr_x4      },      NULL,              NULL},
+{   "x5",       NULL,   8,  GPR_OFFSET(5),      eEncodingUint,  eFormatHex,     { arm64_gcc::x5,               arm64_dwarf::x5,           LLDB_INVALID_REGNUM,        arm64_gcc::x5,             gpr_x5      },      NULL,              NULL},
+{   "x6",       NULL,   8,  GPR_OFFSET(6),      eEncodingUint,  eFormatHex,     { arm64_gcc::x6,               arm64_dwarf::x6,           LLDB_INVALID_REGNUM,        arm64_gcc::x6,             gpr_x6      },      NULL,              NULL},
+{   "x7",       NULL,   8,  GPR_OFFSET(7),      eEncodingUint,  eFormatHex,     { arm64_gcc::x7,               arm64_dwarf::x7,           LLDB_INVALID_REGNUM,        arm64_gcc::x7,             gpr_x7      },      NULL,              NULL},
+{   "x8",       NULL,   8,  GPR_OFFSET(8),      eEncodingUint,  eFormatHex,     { arm64_gcc::x8,               arm64_dwarf::x8,           LLDB_INVALID_REGNUM,        arm64_gcc::x8,             gpr_x8      },      NULL,              NULL},
+{   "x9",       NULL,   8,  GPR_OFFSET(9),      eEncodingUint,  eFormatHex,     { arm64_gcc::x9,               arm64_dwarf::x9,           LLDB_INVALID_REGNUM,        arm64_gcc::x9,             gpr_x9      },      NULL,              NULL},
+{   "x10",      NULL,   8,  GPR_OFFSET(10),     eEncodingUint,  eFormatHex,     { arm64_gcc::x10,              arm64_dwarf::x10,          LLDB_INVALID_REGNUM,        arm64_gcc::x10,            gpr_x10     },      NULL,              NULL},
+{   "x11",      NULL,   8,  GPR_OFFSET(11),     eEncodingUint,  eFormatHex,     { arm64_gcc::x11,              arm64_dwarf::x11,          LLDB_INVALID_REGNUM,        arm64_gcc::x11,            gpr_x11     },      NULL,              NULL},
+{   "x12",      NULL,   8,  GPR_OFFSET(12),     eEncodingUint,  eFormatHex,     { arm64_gcc::x12,              arm64_dwarf::x12,          LLDB_INVALID_REGNUM,        arm64_gcc::x12,            gpr_x12     },      NULL,              NULL},
+{   "x13",      NULL,   8,  GPR_OFFSET(13),     eEncodingUint,  eFormatHex,     { arm64_gcc::x13,              arm64_dwarf::x13,          LLDB_INVALID_REGNUM,        arm64_gcc::x13,            gpr_x13     },      NULL,              NULL},
+{   "x14",      NULL,   8,  GPR_OFFSET(14),     eEncodingUint,  eFormatHex,     { arm64_gcc::x14,              arm64_dwarf::x14,          LLDB_INVALID_REGNUM,        arm64_gcc::x14,            gpr_x14     },      NULL,              NULL},
+{   "x15",      NULL,   8,  GPR_OFFSET(15),     eEncodingUint,  eFormatHex,     { arm64_gcc::x15,              arm64_dwarf::x15,          LLDB_INVALID_REGNUM,        arm64_gcc::x15,            gpr_x15     },      NULL,              NULL},
+{   "x16",      NULL,   8,  GPR_OFFSET(16),     eEncodingUint,  eFormatHex,     { arm64_gcc::x16,              arm64_dwarf::x16,          LLDB_INVALID_REGNUM,        arm64_gcc::x16,            gpr_x16     },      NULL,              NULL},
+{   "x17",      NULL,   8,  GPR_OFFSET(17),     eEncodingUint,  eFormatHex,     { arm64_gcc::x17,              arm64_dwarf::x17,          LLDB_INVALID_REGNUM,        arm64_gcc::x17,            gpr_x17     },      NULL,              NULL},
+{   "x18",      NULL,   8,  GPR_OFFSET(18),     eEncodingUint,  eFormatHex,     { arm64_gcc::x18,              arm64_dwarf::x18,          LLDB_INVALID_REGNUM,        arm64_gcc::x18,            gpr_x18     },      NULL,              NULL},
+{   "x19",      NULL,   8,  GPR_OFFSET(19),     eEncodingUint,  eFormatHex,     { arm64_gcc::x19,              arm64_dwarf::x19,          LLDB_INVALID_REGNUM,        arm64_gcc::x19,            gpr_x19     },      NULL,              NULL},
+{   "x20",      NULL,   8,  GPR_OFFSET(20),     eEncodingUint,  eFormatHex,     { arm64_gcc::x20,              arm64_dwarf::x20,          LLDB_INVALID_REGNUM,        arm64_gcc::x20,            gpr_x20     },      NULL,              NULL},
+{   "x21",      NULL,   8,  GPR_OFFSET(21),     eEncodingUint,  eFormatHex,     { arm64_gcc::x21,              arm64_dwarf::x21,          LLDB_INVALID_REGNUM,        arm64_gcc::x21,            gpr_x21     },      NULL,              NULL},
+{   "x22",      NULL,   8,  GPR_OFFSET(22),     eEncodingUint,  eFormatHex,     { arm64_gcc::x22,              arm64_dwarf::x22,          LLDB_INVALID_REGNUM,        arm64_gcc::x22,            gpr_x22     },      NULL,              NULL},
+{   "x23",      NULL,   8,  GPR_OFFSET(23),     eEncodingUint,  eFormatHex,     { arm64_gcc::x23,              arm64_dwarf::x23,          LLDB_INVALID_REGNUM,        arm64_gcc::x23,            gpr_x23     },      NULL,              NULL},
+{   "x24",      NULL,   8,  GPR_OFFSET(24),     eEncodingUint,  eFormatHex,     { arm64_gcc::x24,              arm64_dwarf::x24,          LLDB_INVALID_REGNUM,        arm64_gcc::x24,            gpr_x24     },      NULL,              NULL},
+{   "x25",      NULL,   8,  GPR_OFFSET(25),     eEncodingUint,  eFormatHex,     { arm64_gcc::x25,              arm64_dwarf::x25,          LLDB_INVALID_REGNUM,        arm64_gcc::x25,            gpr_x25     },      NULL,              NULL},
+{   "x26",      NULL,   8,  GPR_OFFSET(26),     eEncodingUint,  eFormatHex,     { arm64_gcc::x26,              arm64_dwarf::x26,          LLDB_INVALID_REGNUM,        arm64_gcc::x26,            gpr_x26     },      NULL,              NULL},
+{   "x27",      NULL,   8,  GPR_OFFSET(27),     eEncodingUint,  eFormatHex,     { arm64_gcc::x27,              arm64_dwarf::x27,          LLDB_INVALID_REGNUM,        arm64_gcc::x27,            gpr_x27     },      NULL,              NULL},
+{   "x28",      NULL,   8,  GPR_OFFSET(28),     eEncodingUint,  eFormatHex,     { arm64_gcc::x28,              arm64_dwarf::x28,          LLDB_INVALID_REGNUM,        arm64_gcc::x28,            gpr_x28     },      NULL,              NULL},
+
+{   "fp",       "x29",  8,  GPR_OFFSET(29),     eEncodingUint,  eFormatHex,     { arm64_gcc::fp,               arm64_dwarf::fp,           LLDB_REGNUM_GENERIC_FP,     arm64_gcc::fp,             gpr_fp      },      NULL,              NULL},
+{   "lr",       "x30",  8,  GPR_OFFSET(30),     eEncodingUint,  eFormatHex,     { arm64_gcc::lr,               arm64_dwarf::lr,           LLDB_REGNUM_GENERIC_RA,     arm64_gcc::lr,             gpr_lr      },      NULL,              NULL},
+{   "sp",       "x31",  8,  GPR_OFFSET(31),     eEncodingUint,  eFormatHex,     { arm64_gcc::sp,               arm64_dwarf::sp,           LLDB_REGNUM_GENERIC_SP,     arm64_gcc::sp,             gpr_sp      },      NULL,              NULL},
+{   "pc",       NULL,   8,  GPR_OFFSET(32),     eEncodingUint,  eFormatHex,     { arm64_gcc::pc,               arm64_dwarf::pc,           LLDB_REGNUM_GENERIC_PC,     arm64_gcc::pc,             gpr_pc      },      NULL,              NULL},
+
+{   "cpsr",     NULL,   4,  GPR_OFFSET_NAME(cpsr), eEncodingUint,  eFormatHex,  { arm64_gcc::cpsr,             arm64_dwarf::cpsr,         LLDB_REGNUM_GENERIC_FLAGS,  arm64_gcc::cpsr,           gpr_cpsr    },      NULL,              NULL},
+
+{   "v0",       NULL,  16,  FPU_OFFSET(0),      eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v0,           LLDB_INVALID_REGNUM,        arm64_gcc::v0,             fpu_v0      },      NULL,              NULL},
+{   "v1",       NULL,  16,  FPU_OFFSET(1),      eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v1,           LLDB_INVALID_REGNUM,        arm64_gcc::v1,             fpu_v1      },      NULL,              NULL},
+{   "v2",       NULL,  16,  FPU_OFFSET(2),      eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v2,           LLDB_INVALID_REGNUM,        arm64_gcc::v2,             fpu_v2      },      NULL,              NULL},
+{   "v3",       NULL,  16,  FPU_OFFSET(3),      eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v3,           LLDB_INVALID_REGNUM,        arm64_gcc::v3,             fpu_v3      },      NULL,              NULL},
+{   "v4",       NULL,  16,  FPU_OFFSET(4),      eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v4,           LLDB_INVALID_REGNUM,        arm64_gcc::v4,             fpu_v4      },      NULL,              NULL},
+{   "v5",       NULL,  16,  FPU_OFFSET(5),      eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v5,           LLDB_INVALID_REGNUM,        arm64_gcc::v5,             fpu_v5      },      NULL,              NULL},
+{   "v6",       NULL,  16,  FPU_OFFSET(6),      eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v6,           LLDB_INVALID_REGNUM,        arm64_gcc::v6,             fpu_v6      },      NULL,              NULL},
+{   "v7",       NULL,  16,  FPU_OFFSET(7),      eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v7,           LLDB_INVALID_REGNUM,        arm64_gcc::v7,             fpu_v7      },      NULL,              NULL},
+{   "v8",       NULL,  16,  FPU_OFFSET(8),      eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v8,           LLDB_INVALID_REGNUM,        arm64_gcc::v8,             fpu_v8      },      NULL,              NULL},
+{   "v9",       NULL,  16,  FPU_OFFSET(9),      eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v9,           LLDB_INVALID_REGNUM,        arm64_gcc::v9,             fpu_v9      },      NULL,              NULL},
+{   "v10",      NULL,  16,  FPU_OFFSET(10),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v10,          LLDB_INVALID_REGNUM,        arm64_gcc::v10,            fpu_v10     },      NULL,              NULL},
+{   "v11",      NULL,  16,  FPU_OFFSET(11),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v11,          LLDB_INVALID_REGNUM,        arm64_gcc::v11,            fpu_v11     },      NULL,              NULL},
+{   "v12",      NULL,  16,  FPU_OFFSET(12),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v12,          LLDB_INVALID_REGNUM,        arm64_gcc::v12,            fpu_v12     },      NULL,              NULL},
+{   "v13",      NULL,  16,  FPU_OFFSET(13),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v13,          LLDB_INVALID_REGNUM,        arm64_gcc::v13,            fpu_v13     },      NULL,              NULL},
+{   "v14",      NULL,  16,  FPU_OFFSET(14),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v14,          LLDB_INVALID_REGNUM,        arm64_gcc::v14,            fpu_v14     },      NULL,              NULL},
+{   "v15",      NULL,  16,  FPU_OFFSET(15),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v15,          LLDB_INVALID_REGNUM,        arm64_gcc::v15,            fpu_v15     },      NULL,              NULL},
+{   "v16",      NULL,  16,  FPU_OFFSET(16),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v16,          LLDB_INVALID_REGNUM,        arm64_gcc::v16,            fpu_v16     },      NULL,              NULL},
+{   "v17",      NULL,  16,  FPU_OFFSET(17),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v17,          LLDB_INVALID_REGNUM,        arm64_gcc::v17,            fpu_v17     },      NULL,              NULL},
+{   "v18",      NULL,  16,  FPU_OFFSET(18),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v18,          LLDB_INVALID_REGNUM,        arm64_gcc::v18,            fpu_v18     },      NULL,              NULL},
+{   "v19",      NULL,  16,  FPU_OFFSET(19),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v19,          LLDB_INVALID_REGNUM,        arm64_gcc::v19,            fpu_v19     },      NULL,              NULL},
+{   "v20",      NULL,  16,  FPU_OFFSET(20),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v20,          LLDB_INVALID_REGNUM,        arm64_gcc::v20,            fpu_v20     },      NULL,              NULL},
+{   "v21",      NULL,  16,  FPU_OFFSET(21),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v21,          LLDB_INVALID_REGNUM,        arm64_gcc::v21,            fpu_v21     },      NULL,              NULL},
+{   "v22",      NULL,  16,  FPU_OFFSET(22),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v22,          LLDB_INVALID_REGNUM,        arm64_gcc::v22,            fpu_v22     },      NULL,              NULL},
+{   "v23",      NULL,  16,  FPU_OFFSET(23),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v23,          LLDB_INVALID_REGNUM,        arm64_gcc::v23,            fpu_v23     },      NULL,              NULL},
+{   "v24",      NULL,  16,  FPU_OFFSET(24),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v24,          LLDB_INVALID_REGNUM,        arm64_gcc::v24,            fpu_v24     },      NULL,              NULL},
+{   "v25",      NULL,  16,  FPU_OFFSET(25),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v25,          LLDB_INVALID_REGNUM,        arm64_gcc::v25,            fpu_v25     },      NULL,              NULL},
+{   "v26",      NULL,  16,  FPU_OFFSET(26),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v26,          LLDB_INVALID_REGNUM,        arm64_gcc::v26,            fpu_v26     },      NULL,              NULL},
+{   "v27",      NULL,  16,  FPU_OFFSET(27),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v27,          LLDB_INVALID_REGNUM,        arm64_gcc::v27,            fpu_v27     },      NULL,              NULL},
+{   "v28",      NULL,  16,  FPU_OFFSET(28),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v28,          LLDB_INVALID_REGNUM,        arm64_gcc::v28,            fpu_v28     },      NULL,              NULL},
+{   "v29",      NULL,  16,  FPU_OFFSET(29),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v29,          LLDB_INVALID_REGNUM,        arm64_gcc::v29,            fpu_v29     },      NULL,              NULL},
+{   "v30",      NULL,  16,  FPU_OFFSET(30),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v30,          LLDB_INVALID_REGNUM,        arm64_gcc::v30,            fpu_v30     },      NULL,              NULL},
+{   "v31",      NULL,  16,  FPU_OFFSET(31),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v31,          LLDB_INVALID_REGNUM,        arm64_gcc::v31,            fpu_v31     },      NULL,              NULL},
+
+{   "fpsr",    NULL,   4,  FPU_OFFSET_NAME(fpsr),     eEncodingUint,  eFormatHex,     { LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  fpu_fpsr   },      NULL,              NULL},
+{   "fpcr",    NULL,   4,  FPU_OFFSET_NAME(fpcr),     eEncodingUint,  eFormatHex,     { LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  fpu_fpcr   },      NULL,              NULL},
+
+{   "far",      NULL,   8,  EXC_OFFSET_NAME(far),       eEncodingUint,  eFormatHex,     { LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    exc_far       },    NULL,              NULL},
+{   "esr",      NULL,   4,  EXC_OFFSET_NAME(esr),       eEncodingUint,  eFormatHex,     { LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    exc_esr       },    NULL,              NULL},
+{   "exception",NULL,   4,  EXC_OFFSET_NAME(exception), eEncodingUint,  eFormatHex,     { LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    exc_exception },    NULL,              NULL},
+
+{   DEFINE_DBG (bvr, 0) },
+{   DEFINE_DBG (bvr, 1) },
+{   DEFINE_DBG (bvr, 2) },
+{   DEFINE_DBG (bvr, 3) },
+{   DEFINE_DBG (bvr, 4) },
+{   DEFINE_DBG (bvr, 5) },
+{   DEFINE_DBG (bvr, 6) },
+{   DEFINE_DBG (bvr, 7) },
+{   DEFINE_DBG (bvr, 8) },
+{   DEFINE_DBG (bvr, 9) },
+{   DEFINE_DBG (bvr, 10) },
+{   DEFINE_DBG (bvr, 11) },
+{   DEFINE_DBG (bvr, 12) },
+{   DEFINE_DBG (bvr, 13) },
+{   DEFINE_DBG (bvr, 14) },
+{   DEFINE_DBG (bvr, 15) },
+
+{   DEFINE_DBG (bcr, 0) },
+{   DEFINE_DBG (bcr, 1) },
+{   DEFINE_DBG (bcr, 2) },
+{   DEFINE_DBG (bcr, 3) },
+{   DEFINE_DBG (bcr, 4) },
+{   DEFINE_DBG (bcr, 5) },
+{   DEFINE_DBG (bcr, 6) },
+{   DEFINE_DBG (bcr, 7) },
+{   DEFINE_DBG (bcr, 8) },
+{   DEFINE_DBG (bcr, 9) },
+{   DEFINE_DBG (bcr, 10) },
+{   DEFINE_DBG (bcr, 11) },
+{   DEFINE_DBG (bcr, 12) },
+{   DEFINE_DBG (bcr, 13) },
+{   DEFINE_DBG (bcr, 14) },
+{   DEFINE_DBG (bcr, 15) },
+
+{   DEFINE_DBG (wvr, 0) },
+{   DEFINE_DBG (wvr, 1) },
+{   DEFINE_DBG (wvr, 2) },
+{   DEFINE_DBG (wvr, 3) },
+{   DEFINE_DBG (wvr, 4) },
+{   DEFINE_DBG (wvr, 5) },
+{   DEFINE_DBG (wvr, 6) },
+{   DEFINE_DBG (wvr, 7) },
+{   DEFINE_DBG (wvr, 8) },
+{   DEFINE_DBG (wvr, 9) },
+{   DEFINE_DBG (wvr, 10) },
+{   DEFINE_DBG (wvr, 11) },
+{   DEFINE_DBG (wvr, 12) },
+{   DEFINE_DBG (wvr, 13) },
+{   DEFINE_DBG (wvr, 14) },
+{   DEFINE_DBG (wvr, 15) },
+
+{   DEFINE_DBG (wcr, 0) },
+{   DEFINE_DBG (wcr, 1) },
+{   DEFINE_DBG (wcr, 2) },
+{   DEFINE_DBG (wcr, 3) },
+{   DEFINE_DBG (wcr, 4) },
+{   DEFINE_DBG (wcr, 5) },
+{   DEFINE_DBG (wcr, 6) },
+{   DEFINE_DBG (wcr, 7) },
+{   DEFINE_DBG (wcr, 8) },
+{   DEFINE_DBG (wcr, 9) },
+{   DEFINE_DBG (wcr, 10) },
+{   DEFINE_DBG (wcr, 11) },
+{   DEFINE_DBG (wcr, 12) },
+{   DEFINE_DBG (wcr, 13) },
+{   DEFINE_DBG (wcr, 14) },
+{   DEFINE_DBG (wcr, 15) }
+};
+
+// General purpose registers
+static uint32_t
+g_gpr_regnums[] =
+{
+    gpr_x0,
+    gpr_x1,
+    gpr_x2,
+    gpr_x3,
+    gpr_x4,
+    gpr_x5,
+    gpr_x6,
+    gpr_x7,
+    gpr_x8,
+    gpr_x9,
+    gpr_x10,
+    gpr_x11,
+    gpr_x12,
+    gpr_x13,
+    gpr_x14,
+    gpr_x15,
+    gpr_x16,
+    gpr_x17,
+    gpr_x18,
+    gpr_x19,
+    gpr_x20,
+    gpr_x21,
+    gpr_x22,
+    gpr_x23,
+    gpr_x24,
+    gpr_x25,
+    gpr_x26,
+    gpr_x27,
+    gpr_x28,
+    gpr_fp,
+    gpr_lr,
+    gpr_sp,
+    gpr_pc,
+    gpr_cpsr
+};
+
+// Floating point registers
+static uint32_t
+g_fpu_regnums[] =
+{
+    fpu_v0,
+    fpu_v1,
+    fpu_v2,
+    fpu_v3,
+    fpu_v4,
+    fpu_v5,
+    fpu_v6,
+    fpu_v7,
+    fpu_v8,
+    fpu_v9,
+    fpu_v10,
+    fpu_v11,
+    fpu_v12,
+    fpu_v13,
+    fpu_v14,
+    fpu_v15,
+    fpu_v16,
+    fpu_v17,
+    fpu_v18,
+    fpu_v19,
+    fpu_v20,
+    fpu_v21,
+    fpu_v22,
+    fpu_v23,
+    fpu_v24,
+    fpu_v25,
+    fpu_v26,
+    fpu_v27,
+    fpu_v28,
+    fpu_v29,
+    fpu_v30,
+    fpu_v31,
+    fpu_fpsr,
+    fpu_fpcr
+};
+
+// Exception registers
+
+static uint32_t
+g_exc_regnums[] =
+{
+    exc_far,
+    exc_esr,
+    exc_exception
+};
+
+static size_t k_num_register_infos = (sizeof(g_register_infos)/sizeof(RegisterInfo));
+
+void
+RegisterContextDarwin_arm64::InvalidateAllRegisters ()
+{
+    InvalidateAllRegisterStates();
+}
+
+
+size_t
+RegisterContextDarwin_arm64::GetRegisterCount ()
+{
+    assert(k_num_register_infos == k_num_registers);
+    return k_num_registers;
+}
+
+const RegisterInfo *
+RegisterContextDarwin_arm64::GetRegisterInfoAtIndex (size_t reg)
+{
+    assert(k_num_register_infos == k_num_registers);
+    if (reg < k_num_registers)
+        return &g_register_infos[reg];
+    return NULL;
+}
+
+size_t
+RegisterContextDarwin_arm64::GetRegisterInfosCount ()
+{
+    return k_num_register_infos;
+}
+
+const RegisterInfo *
+RegisterContextDarwin_arm64::GetRegisterInfos ()
+{
+    return g_register_infos;
+}
+
+
+// Number of registers in each register set
+const size_t k_num_gpr_registers = sizeof(g_gpr_regnums) / sizeof(uint32_t);
+const size_t k_num_fpu_registers = sizeof(g_fpu_regnums) / sizeof(uint32_t);
+const size_t k_num_exc_registers = sizeof(g_exc_regnums) / sizeof(uint32_t);
+
+//----------------------------------------------------------------------
+// Register set definitions. The first definitions at register set index
+// of zero is for all registers, followed by other registers sets. The
+// register information for the all register set need not be filled in.
+//----------------------------------------------------------------------
+static const RegisterSet g_reg_sets[] =
+{
+    { "General Purpose Registers",  "gpr",  k_num_gpr_registers,    g_gpr_regnums,      },
+    { "Floating Point Registers",   "fpu",  k_num_fpu_registers,    g_fpu_regnums       },
+    { "Exception State Registers",  "exc",  k_num_exc_registers,    g_exc_regnums       }
+};
+
+const size_t k_num_regsets = sizeof(g_reg_sets) / sizeof(RegisterSet);
+
+
+size_t
+RegisterContextDarwin_arm64::GetRegisterSetCount ()
+{
+    return k_num_regsets;
+}
+
+const RegisterSet *
+RegisterContextDarwin_arm64::GetRegisterSet (size_t reg_set)
+{
+    if (reg_set < k_num_regsets)
+        return &g_reg_sets[reg_set];
+    return NULL;
+}
+
+
+//----------------------------------------------------------------------
+// Register information defintions for arm64
+//----------------------------------------------------------------------
+int
+RegisterContextDarwin_arm64::GetSetForNativeRegNum (int reg)
+{
+    if (reg < fpu_v0)
+        return GPRRegSet;
+    else if (reg < exc_far)
+        return FPURegSet;
+    else if (reg < k_num_registers)
+        return EXCRegSet;
+    return -1;
+}
+
+int
+RegisterContextDarwin_arm64::ReadGPR (bool force)
+{
+    int set = GPRRegSet;
+    if (force || !RegisterSetIsCached(set))
+    {
+        SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
+    }
+    return GetError(GPRRegSet, Read);
+}
+
+int
+RegisterContextDarwin_arm64::ReadFPU (bool force)
+{
+    int set = FPURegSet;
+    if (force || !RegisterSetIsCached(set))
+    {
+        SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
+    }
+    return GetError(FPURegSet, Read);
+}
+
+int
+RegisterContextDarwin_arm64::ReadEXC (bool force)
+{
+    int set = EXCRegSet;
+    if (force || !RegisterSetIsCached(set))
+    {
+        SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
+    }
+    return GetError(EXCRegSet, Read);
+}
+
+int
+RegisterContextDarwin_arm64::ReadDBG (bool force)
+{
+    int set = DBGRegSet;
+    if (force || !RegisterSetIsCached(set))
+    {
+        SetError(set, Read, DoReadDBG(GetThreadID(), set, dbg));
+    }
+    return GetError(DBGRegSet, Read);
+}
+
+int
+RegisterContextDarwin_arm64::WriteGPR ()
+{
+    int set = GPRRegSet;
+    if (!RegisterSetIsCached(set))
+    {
+        SetError (set, Write, -1);
+        return KERN_INVALID_ARGUMENT;
+    }
+    SetError (set, Write, DoWriteGPR(GetThreadID(), set, gpr));
+    SetError (set, Read, -1);
+    return GetError(GPRRegSet, Write);
+}
+
+int
+RegisterContextDarwin_arm64::WriteFPU ()
+{
+    int set = FPURegSet;
+    if (!RegisterSetIsCached(set))
+    {
+        SetError (set, Write, -1);
+        return KERN_INVALID_ARGUMENT;
+    }
+    SetError (set, Write, DoWriteFPU(GetThreadID(), set, fpu));
+    SetError (set, Read, -1);
+    return GetError(FPURegSet, Write);
+}
+
+int
+RegisterContextDarwin_arm64::WriteEXC ()
+{
+    int set = EXCRegSet;
+    if (!RegisterSetIsCached(set))
+    {
+        SetError (set, Write, -1);
+        return KERN_INVALID_ARGUMENT;
+    }
+    SetError (set, Write, DoWriteEXC(GetThreadID(), set, exc));
+    SetError (set, Read, -1);
+    return GetError(EXCRegSet, Write);
+}
+
+int
+RegisterContextDarwin_arm64::WriteDBG ()
+{
+    int set = DBGRegSet;
+    if (!RegisterSetIsCached(set))
+    {
+        SetError (set, Write, -1);
+        return KERN_INVALID_ARGUMENT;
+    }
+    SetError (set, Write, DoWriteDBG(GetThreadID(), set, dbg));
+    SetError (set, Read, -1);
+    return GetError(DBGRegSet, Write);
+}
+
+
+int
+RegisterContextDarwin_arm64::ReadRegisterSet (uint32_t set, bool force)
+{
+    switch (set)
+    {
+    case GPRRegSet:    return ReadGPR(force);
+    case FPURegSet:    return ReadFPU(force);
+    case EXCRegSet:    return ReadEXC(force);
+    case DBGRegSet:    return ReadDBG(force);
+    default: break;
+    }
+    return KERN_INVALID_ARGUMENT;
+}
+
+int
+RegisterContextDarwin_arm64::WriteRegisterSet (uint32_t set)
+{
+    // Make sure we have a valid context to set.
+    if (RegisterSetIsCached(set))
+    {
+        switch (set)
+        {
+        case GPRRegSet:    return WriteGPR();
+        case FPURegSet:    return WriteFPU();
+        case EXCRegSet:    return WriteEXC();
+        case DBGRegSet:    return WriteDBG();
+        default: break;
+        }
+    }
+    return KERN_INVALID_ARGUMENT;
+}
+
+void
+RegisterContextDarwin_arm64::LogDBGRegisters (Log *log, const DBG& dbg)
+{
+    if (log)
+    {
+        for (uint32_t i=0; i<16; i++)
+            log->Printf("BVR%-2u/BCR%-2u = { 0x%8.8llx, 0x%8.8llx } WVR%-2u/WCR%-2u = { 0x%8.8llx, 0x%8.8llx }",
+                i, i, dbg.bvr[i], dbg.bcr[i],
+                i, i, dbg.wvr[i], dbg.wcr[i]);
+    }
+}
+
+
+bool
+RegisterContextDarwin_arm64::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value)
+{
+    const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+    int set = RegisterContextDarwin_arm64::GetSetForNativeRegNum (reg);
+
+    if (set == -1)
+        return false;
+
+    if (ReadRegisterSet(set, false) != KERN_SUCCESS)
+        return false;
+
+    switch (reg)
+    {
+    case gpr_x0:
+    case gpr_x1:
+    case gpr_x2:
+    case gpr_x3:
+    case gpr_x4:
+    case gpr_x5:
+    case gpr_x6:
+    case gpr_x7:
+    case gpr_x8:
+    case gpr_x9:
+    case gpr_x10:
+    case gpr_x11:
+    case gpr_x12:
+    case gpr_x13:
+    case gpr_x14:
+    case gpr_x15:
+    case gpr_x16:
+    case gpr_x17:
+    case gpr_x18:
+    case gpr_x19:
+    case gpr_x20:
+    case gpr_x21:
+    case gpr_x22:
+    case gpr_x23:
+    case gpr_x24:
+    case gpr_x25:
+    case gpr_x26:
+    case gpr_x27:
+    case gpr_x28:
+    case gpr_fp:
+    case gpr_sp:
+    case gpr_lr:
+    case gpr_pc:
+    case gpr_cpsr:
+        value.SetUInt64 (gpr.x[reg - gpr_x0]);
+        break;
+
+    case fpu_v0:
+    case fpu_v1:
+    case fpu_v2:
+    case fpu_v3:
+    case fpu_v4:
+    case fpu_v5:
+    case fpu_v6:
+    case fpu_v7:
+    case fpu_v8:
+    case fpu_v9:
+    case fpu_v10:
+    case fpu_v11:
+    case fpu_v12:
+    case fpu_v13:
+    case fpu_v14:
+    case fpu_v15:
+    case fpu_v16:
+    case fpu_v17:
+    case fpu_v18:
+    case fpu_v19:
+    case fpu_v20:
+    case fpu_v21:
+    case fpu_v22:
+    case fpu_v23:
+    case fpu_v24:
+    case fpu_v25:
+    case fpu_v26:
+    case fpu_v27:
+    case fpu_v28:
+    case fpu_v29:
+    case fpu_v30:
+    case fpu_v31:
+        value.SetBytes(fpu.v[reg].bytes, reg_info->byte_size, lldb::endian::InlHostByteOrder());
+        break;
+
+    case fpu_fpsr:
+        value.SetUInt32 (fpu.fpsr);
+        break;
+
+    case fpu_fpcr:
+        value.SetUInt32 (fpu.fpcr);
+        break;
+
+    case exc_exception:
+        value.SetUInt32 (exc.exception);
+        break;
+    case exc_esr:
+        value.SetUInt32 (exc.esr);
+        break;
+    case exc_far:
+        value.SetUInt64 (exc.far);
+        break;
+
+    default:
+        value.SetValueToInvalid();
+        return false;
+
+    }
+    return true;
+}
+
+
+bool
+RegisterContextDarwin_arm64::WriteRegister (const RegisterInfo *reg_info,
+                                        const RegisterValue &value)
+{
+    const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+    int set = GetSetForNativeRegNum (reg);
+
+    if (set == -1)
+        return false;
+
+    if (ReadRegisterSet(set, false) != KERN_SUCCESS)
+        return false;
+
+    switch (reg)
+    {
+    case gpr_x0:
+    case gpr_x1:
+    case gpr_x2:
+    case gpr_x3:
+    case gpr_x4:
+    case gpr_x5:
+    case gpr_x6:
+    case gpr_x7:
+    case gpr_x8:
+    case gpr_x9:
+    case gpr_x10:
+    case gpr_x11:
+    case gpr_x12:
+    case gpr_x13:
+    case gpr_x14:
+    case gpr_x15:
+    case gpr_x16:
+    case gpr_x17:
+    case gpr_x18:
+    case gpr_x19:
+    case gpr_x20:
+    case gpr_x21:
+    case gpr_x22:
+    case gpr_x23:
+    case gpr_x24:
+    case gpr_x25:
+    case gpr_x26:
+    case gpr_x27:
+    case gpr_x28:
+    case gpr_fp:
+    case gpr_sp:
+    case gpr_lr:
+    case gpr_pc:
+    case gpr_cpsr:
+            gpr.x[reg - gpr_x0] = value.GetAsUInt64();
+        break;
+
+    case fpu_v0:
+    case fpu_v1:
+    case fpu_v2:
+    case fpu_v3:
+    case fpu_v4:
+    case fpu_v5:
+    case fpu_v6:
+    case fpu_v7:
+    case fpu_v8:
+    case fpu_v9:
+    case fpu_v10:
+    case fpu_v11:
+    case fpu_v12:
+    case fpu_v13:
+    case fpu_v14:
+    case fpu_v15:
+    case fpu_v16:
+    case fpu_v17:
+    case fpu_v18:
+    case fpu_v19:
+    case fpu_v20:
+    case fpu_v21:
+    case fpu_v22:
+    case fpu_v23:
+    case fpu_v24:
+    case fpu_v25:
+    case fpu_v26:
+    case fpu_v27:
+    case fpu_v28:
+    case fpu_v29:
+    case fpu_v30:
+    case fpu_v31:
+        ::memcpy (fpu.v[reg].bytes, value.GetBytes(), value.GetByteSize());
+        break;
+
+    case fpu_fpsr:
+        fpu.fpsr = value.GetAsUInt32();
+        break;
+
+    case fpu_fpcr:
+        fpu.fpcr = value.GetAsUInt32();
+        break;
+
+    case exc_exception:
+        exc.exception = value.GetAsUInt32();
+        break;
+    case exc_esr:
+        exc.esr = value.GetAsUInt32();
+        break;
+    case exc_far:
+        exc.far = value.GetAsUInt64();
+        break;
+
+    default:
+        return false;
+
+    }
+    return WriteRegisterSet(set) == KERN_SUCCESS;
+}
+
+bool
+RegisterContextDarwin_arm64::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
+{
+    data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
+    if (data_sp &&
+        ReadGPR (false) == KERN_SUCCESS &&
+        ReadFPU (false) == KERN_SUCCESS &&
+        ReadEXC (false) == KERN_SUCCESS)
+    {
+        uint8_t *dst = data_sp->GetBytes();
+        ::memcpy (dst, &gpr, sizeof(gpr));
+        dst += sizeof(gpr);
+
+        ::memcpy (dst, &fpu, sizeof(fpu));
+        dst += sizeof(gpr);
+
+        ::memcpy (dst, &exc, sizeof(exc));
+        return true;
+    }
+    return false;
+}
+
+bool
+RegisterContextDarwin_arm64::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
+{
+    if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE)
+    {
+        const uint8_t *src = data_sp->GetBytes();
+        ::memcpy (&gpr, src, sizeof(gpr));
+        src += sizeof(gpr);
+
+        ::memcpy (&fpu, src, sizeof(fpu));
+        src += sizeof(gpr);
+
+        ::memcpy (&exc, src, sizeof(exc));
+        uint32_t success_count = 0;
+        if (WriteGPR() == KERN_SUCCESS)
+            ++success_count;
+        if (WriteFPU() == KERN_SUCCESS)
+            ++success_count;
+        if (WriteEXC() == KERN_SUCCESS)
+            ++success_count;
+        return success_count == 3;
+    }
+    return false;
+}
+
+uint32_t
+RegisterContextDarwin_arm64::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t reg)
+{
+    if (kind == eRegisterKindGeneric)
+    {
+        switch (reg)
+        {
+        case LLDB_REGNUM_GENERIC_PC: return gpr_pc;
+        case LLDB_REGNUM_GENERIC_SP: return gpr_sp;
+        case LLDB_REGNUM_GENERIC_FP: return gpr_fp;
+        case LLDB_REGNUM_GENERIC_RA: return gpr_lr;
+        case LLDB_REGNUM_GENERIC_FLAGS: return gpr_cpsr;
+        default:
+            break;
+        }
+    }
+    else if (kind == eRegisterKindDWARF)
+    {
+        switch (reg)
+        {
+        case arm64_dwarf::x0:  return gpr_x0;
+        case arm64_dwarf::x1:  return gpr_x1;
+        case arm64_dwarf::x2:  return gpr_x2;
+        case arm64_dwarf::x3:  return gpr_x3;
+        case arm64_dwarf::x4:  return gpr_x4;
+        case arm64_dwarf::x5:  return gpr_x5;
+        case arm64_dwarf::x6:  return gpr_x6;
+        case arm64_dwarf::x7:  return gpr_x7;
+        case arm64_dwarf::x8:  return gpr_x8;
+        case arm64_dwarf::x9:  return gpr_x9;
+        case arm64_dwarf::x10: return gpr_x10;
+        case arm64_dwarf::x11: return gpr_x11;
+        case arm64_dwarf::x12: return gpr_x12;
+        case arm64_dwarf::x13: return gpr_x13;
+        case arm64_dwarf::x14: return gpr_x14;
+        case arm64_dwarf::x15: return gpr_x15;
+        case arm64_dwarf::x16: return gpr_x16;
+        case arm64_dwarf::x17: return gpr_x17;
+        case arm64_dwarf::x18: return gpr_x18;
+        case arm64_dwarf::x19: return gpr_x19;
+        case arm64_dwarf::x20: return gpr_x20;
+        case arm64_dwarf::x21: return gpr_x21;
+        case arm64_dwarf::x22: return gpr_x22;
+        case arm64_dwarf::x23: return gpr_x23;
+        case arm64_dwarf::x24: return gpr_x24;
+        case arm64_dwarf::x25: return gpr_x25;
+        case arm64_dwarf::x26: return gpr_x26;
+        case arm64_dwarf::x27: return gpr_x27;
+        case arm64_dwarf::x28: return gpr_x28;
+
+        case arm64_dwarf::fp:  return gpr_fp;
+        case arm64_dwarf::sp:  return gpr_sp;
+        case arm64_dwarf::lr:  return gpr_lr;
+        case arm64_dwarf::pc:  return gpr_pc;
+        case arm64_dwarf::cpsr: return gpr_cpsr;
+
+        case arm64_dwarf::v0:  return fpu_v0;
+        case arm64_dwarf::v1:  return fpu_v1;
+        case arm64_dwarf::v2:  return fpu_v2;
+        case arm64_dwarf::v3:  return fpu_v3;
+        case arm64_dwarf::v4:  return fpu_v4;
+        case arm64_dwarf::v5:  return fpu_v5;
+        case arm64_dwarf::v6:  return fpu_v6;
+        case arm64_dwarf::v7:  return fpu_v7;
+        case arm64_dwarf::v8:  return fpu_v8;
+        case arm64_dwarf::v9:  return fpu_v9;
+        case arm64_dwarf::v10: return fpu_v10;
+        case arm64_dwarf::v11: return fpu_v11;
+        case arm64_dwarf::v12: return fpu_v12;
+        case arm64_dwarf::v13: return fpu_v13;
+        case arm64_dwarf::v14: return fpu_v14;
+        case arm64_dwarf::v15: return fpu_v15;
+        case arm64_dwarf::v16: return fpu_v16;
+        case arm64_dwarf::v17: return fpu_v17;
+        case arm64_dwarf::v18: return fpu_v18;
+        case arm64_dwarf::v19: return fpu_v19;
+        case arm64_dwarf::v20: return fpu_v20;
+        case arm64_dwarf::v21: return fpu_v21;
+        case arm64_dwarf::v22: return fpu_v22;
+        case arm64_dwarf::v23: return fpu_v23;
+        case arm64_dwarf::v24: return fpu_v24;
+        case arm64_dwarf::v25: return fpu_v25;
+        case arm64_dwarf::v26: return fpu_v26;
+        case arm64_dwarf::v27: return fpu_v27;
+        case arm64_dwarf::v28: return fpu_v28;
+        case arm64_dwarf::v29: return fpu_v29;
+        case arm64_dwarf::v30: return fpu_v30;
+        case arm64_dwarf::v31: return fpu_v31;
+
+        default:
+            break;
+        }
+    }
+    else if (kind == eRegisterKindGCC)
+    {
+        switch (reg)
+        {
+        case arm64_gcc::x0:  return gpr_x0;
+        case arm64_gcc::x1:  return gpr_x1;
+        case arm64_gcc::x2:  return gpr_x2;
+        case arm64_gcc::x3:  return gpr_x3;
+        case arm64_gcc::x4:  return gpr_x4;
+        case arm64_gcc::x5:  return gpr_x5;
+        case arm64_gcc::x6:  return gpr_x6;
+        case arm64_gcc::x7:  return gpr_x7;
+        case arm64_gcc::x8:  return gpr_x8;
+        case arm64_gcc::x9:  return gpr_x9;
+        case arm64_gcc::x10: return gpr_x10;
+        case arm64_gcc::x11: return gpr_x11;
+        case arm64_gcc::x12: return gpr_x12;
+        case arm64_gcc::x13: return gpr_x13;
+        case arm64_gcc::x14: return gpr_x14;
+        case arm64_gcc::x15: return gpr_x15;
+        case arm64_gcc::x16: return gpr_x16;
+        case arm64_gcc::x17: return gpr_x17;
+        case arm64_gcc::x18: return gpr_x18;
+        case arm64_gcc::x19: return gpr_x19;
+        case arm64_gcc::x20: return gpr_x20;
+        case arm64_gcc::x21: return gpr_x21;
+        case arm64_gcc::x22: return gpr_x22;
+        case arm64_gcc::x23: return gpr_x23;
+        case arm64_gcc::x24: return gpr_x24;
+        case arm64_gcc::x25: return gpr_x25;
+        case arm64_gcc::x26: return gpr_x26;
+        case arm64_gcc::x27: return gpr_x27;
+        case arm64_gcc::x28: return gpr_x28;
+        case arm64_gcc::fp:   return gpr_fp;
+        case arm64_gcc::sp:   return gpr_sp;
+        case arm64_gcc::lr:   return gpr_lr;
+        case arm64_gcc::pc:   return gpr_pc;
+        case arm64_gcc::cpsr: return gpr_cpsr;
+        }
+    }
+    else if (kind == eRegisterKindLLDB)
+    {
+        return reg;
+    }
+    return LLDB_INVALID_REGNUM;
+}
+
+
+uint32_t
+RegisterContextDarwin_arm64::NumSupportedHardwareWatchpoints ()
+{
+#if defined (__arm64__)
+    // autodetect how many watchpoints are supported dynamically...
+    static uint32_t g_num_supported_hw_watchpoints = UINT32_MAX;
+    if (g_num_supported_hw_watchpoints == UINT32_MAX)
+    {
+        size_t len;
+        uint32_t n = 0;
+        len = sizeof (n);
+        if (::sysctlbyname("hw.optional.watchpoint", &n, &len, NULL, 0) == 0)
+        {
+            g_num_supported_hw_watchpoints = n;
+        }
+    }
+    return g_num_supported_hw_watchpoints;
+#else
+    // TODO: figure out remote case here!
+    return 2;
+#endif
+}
+
+
+uint32_t
+RegisterContextDarwin_arm64::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write)
+{
+//    if (log) log->Printf ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint(addr = %8.8p, size = %u, read = %u, write = %u)", addr, size, read, write);
+
+    const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
+
+    // Can't watch zero bytes
+    if (size == 0)
+        return LLDB_INVALID_INDEX32;
+
+    // We must watch for either read or write
+    if (read == false && write == false)
+        return LLDB_INVALID_INDEX32;
+
+    // Can't watch more than 4 bytes per WVR/WCR pair
+    if (size > 4)
+        return LLDB_INVALID_INDEX32;
+
+    // We can only watch up to four bytes that follow a 4 byte aligned address
+    // per watchpoint register pair. Since we have at most so we can only watch
+    // until the next 4 byte boundary and we need to make sure we can properly
+    // encode this.
+    uint32_t addr_word_offset = addr % 4;
+//    if (log) log->Printf ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() - addr_word_offset = 0x%8.8x", addr_word_offset);
+
+    uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset;
+//    if (log) log->Printf ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() - byte_mask = 0x%8.8x", byte_mask);
+    if (byte_mask > 0xfu)
+        return LLDB_INVALID_INDEX32;
+
+    // Read the debug state
+    int kret = ReadDBG (false);
+
+    if (kret == KERN_SUCCESS)
+    {
+        // Check to make sure we have the needed hardware support
+        uint32_t i = 0;
+
+        for (i=0; i<num_hw_watchpoints; ++i)
+        {
+            if ((dbg.wcr[i] & WCR_ENABLE) == 0)
+                break; // We found an available hw breakpoint slot (in i)
+        }
+
+        // See if we found an available hw breakpoint slot above
+        if (i < num_hw_watchpoints)
+        {
+            // Make the byte_mask into a valid Byte Address Select mask
+            uint32_t byte_address_select = byte_mask << 5;
+            // Make sure bits 1:0 are clear in our address
+            dbg.wvr[i] = addr & ~((lldb::addr_t)3);
+            dbg.wcr[i] =  byte_address_select |       // Which bytes that follow the IMVA that we will watch
+                                    S_USER |                    // Stop only in user mode
+                                    (read ? WCR_LOAD : 0) |     // Stop on read access?
+                                    (write ? WCR_STORE : 0) |   // Stop on write access?
+                                    WCR_ENABLE;                 // Enable this watchpoint;
+
+            kret = WriteDBG();
+//            if (log) log->Printf ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() WriteDBG() => 0x%8.8x.", kret);
+
+            if (kret == KERN_SUCCESS)
+                return i;
+        }
+        else
+        {
+//            if (log) log->Printf ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint(): All hardware resources (%u) are in use.", num_hw_watchpoints);
+        }
+    }
+    return LLDB_INVALID_INDEX32;
+}
+
+bool
+RegisterContextDarwin_arm64::ClearHardwareWatchpoint (uint32_t hw_index)
+{
+    int kret = ReadDBG (false);
+
+    const uint32_t num_hw_points = NumSupportedHardwareWatchpoints();
+    if (kret == KERN_SUCCESS)
+    {
+        if (hw_index < num_hw_points)
+        {
+            dbg.wcr[hw_index] = 0;
+//            if (log) log->Printf ("RegisterContextDarwin_arm64::ClearHardwareWatchpoint( %u ) - WVR%u = 0x%8.8x  WCR%u = 0x%8.8x",
+//                    hw_index,
+//                    hw_index,
+//                    dbg.wvr[hw_index],
+//                    hw_index,
+//                    dbg.wcr[hw_index]);
+
+            kret = WriteDBG();
+
+            if (kret == KERN_SUCCESS)
+                return true;
+        }
+    }
+    return false;
+}
+
+#endif

Added: lldb/trunk/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h?rev=205113&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h (added)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h Sat Mar 29 13:54:20 2014
@@ -0,0 +1,296 @@
+//===-- RegisterContextDarwin_arm64.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_RegisterContextDarwin_arm64_h_
+#define liblldb_RegisterContextDarwin_arm64_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Target/RegisterContext.h"
+
+// Break only in privileged or user mode
+#define S_RSVD                  ((uint32_t)(0u << 1))
+#define S_PRIV                  ((uint32_t)(1u << 1))
+#define S_USER                  ((uint32_t)(2u << 1))
+#define S_PRIV_USER             ((S_PRIV) | (S_USER))
+
+#define WCR_ENABLE              ((uint32_t)(1u))
+
+// Watchpoint load/store
+#define WCR_LOAD                ((uint32_t)(1u << 3))
+#define WCR_STORE               ((uint32_t)(1u << 4))
+
+class RegisterContextDarwin_arm64 : public lldb_private::RegisterContext
+{
+public:
+
+    RegisterContextDarwin_arm64(lldb_private::Thread &thread, uint32_t concrete_frame_idx);
+
+    virtual
+    ~RegisterContextDarwin_arm64();
+
+    virtual void
+    InvalidateAllRegisters ();
+
+    virtual size_t
+    GetRegisterCount ();
+
+    virtual const lldb_private::RegisterInfo *
+    GetRegisterInfoAtIndex (size_t reg);
+
+    virtual size_t
+    GetRegisterSetCount ();
+
+    virtual const lldb_private::RegisterSet *
+    GetRegisterSet (size_t set);
+
+    virtual bool
+    ReadRegister (const lldb_private::RegisterInfo *reg_info, 
+                  lldb_private::RegisterValue &reg_value);
+    
+    virtual bool
+    WriteRegister (const lldb_private::RegisterInfo *reg_info,
+                   const lldb_private::RegisterValue &reg_value);
+    
+    virtual bool
+    ReadAllRegisterValues (lldb::DataBufferSP &data_sp);
+
+    virtual bool
+    WriteAllRegisterValues (const lldb::DataBufferSP &data_sp);
+
+    virtual uint32_t
+    ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num);
+
+    virtual uint32_t
+    NumSupportedHardwareWatchpoints ();
+
+    virtual uint32_t
+    SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write);
+
+    virtual bool
+    ClearHardwareWatchpoint (uint32_t hw_index);
+
+    // mirrors <mach/arm/thread_status.h> arm_thread_state64_t
+    struct GPR
+    {
+        uint64_t    x[29];  // x0-x28
+        uint64_t    fp;     // x29
+        uint64_t    lr;     // x30
+        uint64_t    sp;     // x31
+        uint64_t    pc;     // pc
+        uint32_t    cpsr;   // cpsr
+    };
+
+
+    struct VReg
+    {
+        uint8_t bytes[16];
+    };
+
+    // mirrors <mach/arm/thread_status.h> arm_neon_state64_t
+    struct FPU
+    {
+        VReg        v[32];
+        uint32_t    fpsr;
+        uint32_t    fpcr;
+    };
+
+    // mirrors <mach/arm/thread_status.h> arm_exception_state64_t
+    struct EXC
+    {
+        uint64_t    far;       // Virtual Fault Address
+        uint32_t    esr;       // Exception syndrome
+        uint32_t    exception; // number of arm exception token
+    };
+
+    // mirrors <mach/arm/thread_status.h> arm_debug_state64_t
+    struct DBG
+    {
+        uint64_t bvr[16];
+        uint64_t bcr[16];
+        uint64_t wvr[16];
+        uint64_t wcr[16];
+        uint64_t mdscr_el1;
+    };
+
+    static void
+    LogDBGRegisters (lldb_private::Log *log, const DBG& dbg);
+
+protected:
+
+    enum
+    {
+        GPRRegSet = 6,  // ARM_THREAD_STATE64
+        FPURegSet = 17, // ARM_NEON_STATE64
+        EXCRegSet = 7,  // ARM_EXCEPTION_STATE64
+        DBGRegSet = 15  // ARM_DEBUG_STATE64
+    };
+
+    enum
+    {
+        GPRWordCount = sizeof(GPR)/sizeof(uint32_t),  // ARM_THREAD_STATE64_COUNT
+        FPUWordCount = sizeof(FPU)/sizeof(uint32_t),  // ARM_NEON_STATE64_COUNT
+        EXCWordCount = sizeof(EXC)/sizeof(uint32_t),  // ARM_EXCEPTION_STATE64_COUNT
+        DBGWordCount = sizeof(DBG)/sizeof(uint32_t)   // ARM_DEBUG_STATE64_COUNT
+    };
+
+    enum
+    {
+        Read = 0,
+        Write = 1,
+        kNumErrors = 2
+    };
+
+    GPR gpr;
+    FPU fpu;
+    EXC exc;
+    DBG dbg;
+    int gpr_errs[2]; // Read/Write errors
+    int fpu_errs[2]; // Read/Write errors
+    int exc_errs[2]; // Read/Write errors
+    int dbg_errs[2]; // Read/Write errors
+
+    void
+    InvalidateAllRegisterStates()
+    {
+        SetError (GPRRegSet, Read, -1);
+        SetError (FPURegSet, Read, -1);
+        SetError (EXCRegSet, Read, -1);
+    }
+
+    int
+    GetError (int flavor, uint32_t err_idx) const
+    {
+        if (err_idx < kNumErrors)
+        {
+            switch (flavor)
+            {
+            // When getting all errors, just OR all values together to see if
+            // we got any kind of error.
+            case GPRRegSet:    return gpr_errs[err_idx];
+            case FPURegSet:    return fpu_errs[err_idx];
+            case EXCRegSet:    return exc_errs[err_idx];
+            case DBGRegSet:    return dbg_errs[err_idx];
+            default: break;
+            }
+        }
+        return -1;
+    }
+
+    bool
+    SetError (int flavor, uint32_t err_idx, int err)
+    {
+        if (err_idx < kNumErrors)
+        {
+            switch (flavor)
+            {
+            case GPRRegSet:
+                gpr_errs[err_idx] = err;
+                return true;
+
+            case FPURegSet:
+                fpu_errs[err_idx] = err;
+                return true;
+
+            case EXCRegSet:
+                exc_errs[err_idx] = err;
+                return true;
+
+            case DBGRegSet:
+                exc_errs[err_idx] = err;
+                return true;
+
+            default: break;
+            }
+        }
+        return false;
+    }
+
+    bool
+    RegisterSetIsCached (int set) const
+    {
+        return GetError(set, Read) == 0;
+    }
+
+    int
+    ReadGPR (bool force);
+
+    int
+    ReadFPU (bool force);
+
+    int
+    ReadEXC (bool force);
+
+    int
+    ReadDBG (bool force);
+
+    int
+    WriteGPR ();
+
+    int
+    WriteFPU ();
+
+    int
+    WriteEXC ();
+
+    int
+    WriteDBG ();
+
+    
+    // Subclasses override these to do the actual reading.
+    virtual int
+    DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
+    {
+        return -1;
+    }
+    
+    virtual int
+    DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu) = 0;
+    
+    virtual int
+    DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc) = 0;
+
+    virtual int
+    DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg) = 0;
+
+    virtual int
+    DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr) = 0;
+    
+    virtual int
+    DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu) = 0;
+    
+    virtual int
+    DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc) = 0;
+
+    virtual int
+    DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg) = 0;
+
+    int
+    ReadRegisterSet (uint32_t set, bool force);
+
+    int
+    WriteRegisterSet (uint32_t set);
+
+    static uint32_t
+    GetRegisterNumber (uint32_t reg_kind, uint32_t reg_num);
+
+    static int
+    GetSetForNativeRegNum (int reg_num);
+
+    static size_t
+    GetRegisterInfosCount ();
+
+    static const lldb_private::RegisterInfo *
+    GetRegisterInfos ();
+};
+
+#endif  // liblldb_RegisterContextDarwin_arm64_h_

Modified: lldb/trunk/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp Sat Mar 29 13:54:20 2014
@@ -149,7 +149,7 @@ RegisterContextMacOSXFrameBackchain::Rea
 
             // TOOD: need a better way to detect when "long double" types are
             // the same bytes size as "double"
-#if !defined(__arm__) && !defined(_MSC_VER) && !defined(__mips__)
+#if !defined(__arm__) && !defined(__arm64__) && !defined(_MSC_VER) && !defined(__mips__)
         case sizeof (long double):
             if (sizeof (long double) == sizeof(uint32_t))
             {

Modified: lldb/trunk/source/Plugins/Process/Utility/StopInfoMachException.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/StopInfoMachException.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/StopInfoMachException.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/StopInfoMachException.cpp Sat Mar 29 13:54:20 2014
@@ -439,6 +439,37 @@ StopInfoMachException::CreateStopReasonW
                     }
                     break;
 
+                case llvm::Triple::arm64:
+                {
+                    if (exc_code == 1 && exc_sub_code == 0) // EXC_ARM_BREAKPOINT
+                    {
+                        // This is hit when we single instruction step aka MDSCR_EL1 SS bit 0 is set
+                        return StopInfo::CreateStopReasonToTrace(thread);
+                    }
+                    if (exc_code == 0x102) // EXC_ARM_DA_DEBUG
+                    {
+                        // It's a watchpoint, then, if the exc_sub_code indicates a known/enabled
+                        // data break address from our watchpoint list.
+                        lldb::WatchpointSP wp_sp;
+                        if (target)
+                            wp_sp = target->GetWatchpointList().FindByAddress((lldb::addr_t)exc_sub_code);
+                        if (wp_sp && wp_sp->IsEnabled())
+                        {
+                            // Debugserver may piggyback the hardware index of the fired watchpoint in the exception data.
+                            // Set the hardware index if that's the case.
+                            if (exc_data_count >= 3)
+                                wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
+                            return StopInfo::CreateStopReasonWithWatchpointID(thread, wp_sp->GetID());
+                        }
+                        // EXC_ARM_DA_DEBUG seems to be reused for EXC_BREAKPOINT as well as EXC_BAD_ACCESS
+                        if (thread.GetTemporaryResumeState() == eStateStepping)
+                            return StopInfo::CreateStopReasonToTrace(thread);
+                    }
+                    // It looks like exc_sub_code has the 4 bytes of the instruction that triggered the 
+                    // exception, i.e. our breakpoint opcode
+                    is_actual_breakpoint = exc_code == 1;
+                }
+
                 default:
                     break;
                 }

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp Sat Mar 29 13:54:20 2014
@@ -27,6 +27,7 @@
 #include "lldb/Host/Endian.h"
 #include "lldb/Host/Host.h"
 #include "lldb/Host/TimeValue.h"
+#include "lldb/Target/Target.h"
 
 // Project includes
 #include "Utility/StringExtractorGDBRemote.h"
@@ -57,6 +58,7 @@ GDBRemoteCommunicationClient::GDBRemoteC
     m_supports_vCont_S (eLazyBoolCalculate),
     m_qHostInfo_is_valid (eLazyBoolCalculate),
     m_qProcessInfo_is_valid (eLazyBoolCalculate),
+    m_qGDBServerVersion_is_valid (eLazyBoolCalculate),
     m_supports_alloc_dealloc_memory (eLazyBoolCalculate),
     m_supports_memory_region_info  (eLazyBoolCalculate),
     m_supports_watchpoint_support_info  (eLazyBoolCalculate),
@@ -65,6 +67,7 @@ GDBRemoteCommunicationClient::GDBRemoteC
     m_attach_or_wait_reply(eLazyBoolCalculate),
     m_prepare_for_reg_writing_reply (eLazyBoolCalculate),
     m_supports_p (eLazyBoolCalculate),
+    m_avoid_g_packets (eLazyBoolCalculate),
     m_supports_QSaveRegisterState (eLazyBoolCalculate),
     m_supports_qXfer_auxv_read (eLazyBoolCalculate),
     m_supports_qXfer_libraries_read (eLazyBoolCalculate),
@@ -100,6 +103,8 @@ GDBRemoteCommunicationClient::GDBRemoteC
     m_os_build (),
     m_os_kernel (),
     m_hostname (),
+    m_gdb_server_name(),
+    m_gdb_server_version(UINT32_MAX),
     m_default_packet_timeout (0),
     m_max_packet_size (0)
 {
@@ -301,10 +306,12 @@ GDBRemoteCommunicationClient::ResetDisco
     m_supports_QSaveRegisterState = eLazyBoolCalculate;
     m_qHostInfo_is_valid = eLazyBoolCalculate;
     m_qProcessInfo_is_valid = eLazyBoolCalculate;
+    m_qGDBServerVersion_is_valid = eLazyBoolCalculate;
     m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
     m_supports_memory_region_info = eLazyBoolCalculate;
     m_prepare_for_reg_writing_reply = eLazyBoolCalculate;
     m_attach_or_wait_reply = eLazyBoolCalculate;
+    m_avoid_g_packets = eLazyBoolCalculate;
     m_supports_qXfer_auxv_read = eLazyBoolCalculate;
     m_supports_qXfer_libraries_read = eLazyBoolCalculate;
     m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate;
@@ -322,8 +329,18 @@ GDBRemoteCommunicationClient::ResetDisco
     m_supports_z4 = true;
     m_supports_QEnvironment = true;
     m_supports_QEnvironmentHexEncoded = true;
+    
     m_host_arch.Clear();
     m_process_arch.Clear();
+    m_os_version_major = UINT32_MAX;
+    m_os_version_minor = UINT32_MAX;
+    m_os_version_update = UINT32_MAX;
+    m_os_build.clear();
+    m_os_kernel.clear();
+    m_hostname.clear();
+    m_gdb_server_name.clear();
+    m_gdb_server_version = UINT32_MAX;
+    m_default_packet_timeout = 0;
 
     m_max_packet_size = 0;
 }
@@ -1314,6 +1331,41 @@ GDBRemoteCommunicationClient::SendLaunch
     return -1;
 }
 
+int
+GDBRemoteCommunicationClient::SendLaunchEventDataPacket (char const *data, bool *was_supported)
+{
+    if (data && *data != '\0')
+    {
+        StreamString packet;
+        packet.Printf("QSetProcessEvent:%s", data);
+        StringExtractorGDBRemote response;
+        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
+        {
+            if (response.IsOKResponse())
+            {
+                if (was_supported)
+                    *was_supported = true;
+                return 0;
+            }
+            else if (response.IsUnsupportedResponse())
+            {
+                if (was_supported)
+                    *was_supported = false;
+                return -1;
+            }
+            else
+            {
+                uint8_t error = response.GetError();
+                if (was_supported)
+                    *was_supported = true;
+                if (error)
+                    return error;
+            }
+        }
+    }
+    return -1;
+}
+
 bool
 GDBRemoteCommunicationClient::GetOSVersion (uint32_t &major, 
                                             uint32_t &minor, 
@@ -1394,6 +1446,69 @@ GDBRemoteCommunicationClient::GetProcess
     return m_process_arch;
 }
 
+bool
+GDBRemoteCommunicationClient::GetGDBServerVersion()
+{
+    if (m_qGDBServerVersion_is_valid == eLazyBoolCalculate)
+    {
+        m_gdb_server_name.clear();
+        m_gdb_server_version = 0;
+        m_qGDBServerVersion_is_valid = eLazyBoolNo;
+
+        StringExtractorGDBRemote response;
+        if (SendPacketAndWaitForResponse ("qGDBServerVersion", response, false) == PacketResult::Success)
+        {
+            if (response.IsNormalResponse())
+            {
+                std::string name;
+                std::string value;
+                bool success = false;
+                while (response.GetNameColonValue(name, value))
+                {
+                    if (name.compare("name") == 0)
+                    {
+                        success = true;
+                        m_gdb_server_name.swap(value);
+                    }
+                    else if (name.compare("version") == 0)
+                    {
+                        size_t dot_pos = value.find('.');
+                        if (dot_pos != std::string::npos)
+                            value[dot_pos] = '\0';
+                        const uint32_t version = Args::StringToUInt32(value.c_str(), UINT32_MAX, 0);
+                        if (version != UINT32_MAX)
+                        {
+                            success = true;
+                            m_gdb_server_version = version;
+                        }
+                    }
+                }
+                if (success)
+                    m_qGDBServerVersion_is_valid = eLazyBoolYes;
+            }
+        }
+    }
+    return m_qGDBServerVersion_is_valid == eLazyBoolYes;
+}
+
+const char *
+GDBRemoteCommunicationClient::GetGDBServerProgramName()
+{
+    if (GetGDBServerVersion())
+    {
+        if (!m_gdb_server_name.empty())
+            return m_gdb_server_name.c_str();
+    }
+    return NULL;
+}
+
+uint32_t
+GDBRemoteCommunicationClient::GetGDBServerProgramVersion()
+{
+    if (GetGDBServerVersion())
+        return m_gdb_server_version;
+    return 0;
+}
 
 bool
 GDBRemoteCommunicationClient::GetHostInfo (bool force)
@@ -1558,6 +1673,7 @@ GDBRemoteCommunicationClient::GetHostInf
                             {
                                 switch (m_host_arch.GetMachine())
                                 {
+                                case llvm::Triple::arm64:
                                 case llvm::Triple::arm:
                                 case llvm::Triple::thumb:
                                     os_name = "ios";
@@ -1598,6 +1714,7 @@ GDBRemoteCommunicationClient::GetHostInf
                         {
                             switch (m_host_arch.GetMachine())
                             {
+                                case llvm::Triple::arm64:
                                 case llvm::Triple::arm:
                                 case llvm::Triple::thumb:
                                     host_triple.setOS(llvm::Triple::IOS);
@@ -3229,6 +3346,38 @@ GDBRemoteCommunicationClient::CalculateM
 }
 
 bool
+GDBRemoteCommunicationClient::AvoidGPackets (ProcessGDBRemote *process)
+{
+    // Some targets have issues with g/G packets and we need to avoid using them
+    if (m_avoid_g_packets == eLazyBoolCalculate)
+    {
+        if (process)
+        {
+            m_avoid_g_packets = eLazyBoolNo;
+            const ArchSpec &arch = process->GetTarget().GetArchitecture();
+            if (arch.IsValid()
+                && arch.GetTriple().getVendor() == llvm::Triple::Apple
+                && arch.GetTriple().getOS() == llvm::Triple::IOS
+                && arch.GetTriple().getArch() == llvm::Triple::arm64)
+            {
+                m_avoid_g_packets = eLazyBoolYes;
+                uint32_t gdb_server_version = GetGDBServerProgramVersion();
+                if (gdb_server_version != 0)
+                {
+                    const char *gdb_server_name = GetGDBServerProgramName();
+                    if (gdb_server_name && strcmp(gdb_server_name, "debugserver") == 0)
+                    {
+                        if (gdb_server_version >= 310)
+                            m_avoid_g_packets = eLazyBoolNo;
+                    }
+                }
+            }
+        }
+    }
+    return m_avoid_g_packets == eLazyBoolYes;
+}
+
+bool
 GDBRemoteCommunicationClient::ReadRegister(lldb::tid_t tid, uint32_t reg, StringExtractorGDBRemote &response)
 {
     Mutex::Locker locker;

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h Sat Mar 29 13:54:20 2014
@@ -159,6 +159,10 @@ public:
 
     int
     SendLaunchArchPacket (const char *arch);
+    
+    int
+    SendLaunchEventDataPacket (const char *data, bool *was_supported = NULL);
+    
     //------------------------------------------------------------------
     /// Sends a "vAttach:PID" where PID is in hex. 
     ///
@@ -494,7 +498,16 @@ public:
     
     bool
     RestoreRegisterState (lldb::tid_t tid, uint32_t save_id);
+
+    const char *
+    GetGDBServerProgramName();
     
+    uint32_t
+    GetGDBServerProgramVersion();
+
+    bool
+    AvoidGPackets(ProcessGDBRemote *process);
+
 protected:
 
     PacketResult
@@ -505,6 +518,9 @@ protected:
     bool
     GetCurrentProcessInfo ();
 
+    bool
+    GetGDBServerVersion();
+
     //------------------------------------------------------------------
     // Classes that inherit from GDBRemoteCommunicationClient can see and modify these
     //------------------------------------------------------------------
@@ -519,6 +535,7 @@ protected:
     lldb_private::LazyBool m_supports_vCont_S;
     lldb_private::LazyBool m_qHostInfo_is_valid;
     lldb_private::LazyBool m_qProcessInfo_is_valid;
+    lldb_private::LazyBool m_qGDBServerVersion_is_valid;
     lldb_private::LazyBool m_supports_alloc_dealloc_memory;
     lldb_private::LazyBool m_supports_memory_region_info;
     lldb_private::LazyBool m_supports_watchpoint_support_info;
@@ -527,6 +544,7 @@ protected:
     lldb_private::LazyBool m_attach_or_wait_reply;
     lldb_private::LazyBool m_prepare_for_reg_writing_reply;
     lldb_private::LazyBool m_supports_p;
+    lldb_private::LazyBool m_avoid_g_packets;
     lldb_private::LazyBool m_supports_QSaveRegisterState;
     lldb_private::LazyBool m_supports_qXfer_auxv_read;
     lldb_private::LazyBool m_supports_qXfer_libraries_read;
@@ -574,6 +592,8 @@ protected:
     std::string m_os_build;
     std::string m_os_kernel;
     std::string m_hostname;
+    std::string m_gdb_server_name; // from reply to qGDBServerVersion, empty if qGDBServerVersion is not supported
+    uint32_t m_gdb_server_version; // from reply to qGDBServerVersion, zero if qGDBServerVersion is not supported
     uint32_t m_default_packet_timeout;
     uint64_t m_max_packet_size;  // as returned by qSupported
     

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp Sat Mar 29 13:54:20 2014
@@ -447,22 +447,21 @@ GDBRemoteCommunicationServer::Handle_qHo
     }
 #if defined(__APPLE__)
 
-#if defined(__arm__)
+#if defined(__arm__) || defined(__arm64__)
     // For iOS devices, we are connected through a USB Mux so we never pretend
     // to actually have a hostname as far as the remote lldb that is connecting
     // to this lldb-platform is concerned
     response.PutCString ("hostname:");
     response.PutCStringAsRawHex8("127.0.0.1");
     response.PutChar(';');
-#else   // #if defined(__arm__)
+#else   // #if defined(__arm__) || defined(__arm64__)
     if (Host::GetHostname (s))
     {
         response.PutCString ("hostname:");
         response.PutCStringAsRawHex8(s.c_str());
         response.PutChar(';');
     }
-
-#endif  // #if defined(__arm__)
+#endif  // #if defined(__arm__) || defined(__arm64__)
 
 #else   // #if defined(__APPLE__)
     if (Host::GetHostname (s))

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp Sat Mar 29 13:54:20 2014
@@ -21,6 +21,7 @@
 #include "lldb/Interpreter/PythonDataObjects.h"
 #endif
 #include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Target.h"
 #include "lldb/Utility/Utils.h"
 // Project includes
 #include "Utility/StringExtractorGDBRemote.h"
@@ -502,6 +503,8 @@ GDBRemoteRegisterContext::ReadAllRegiste
 
     StringExtractorGDBRemote response;
 
+    const bool use_g_packet = gdb_comm.AvoidGPackets ((ProcessGDBRemote *)process) == false;
+
     Mutex::Locker locker;
     if (gdb_comm.GetSequenceMutex (locker, "Didn't get sequence mutex for read all registers."))
     {
@@ -519,29 +522,62 @@ GDBRemoteRegisterContext::ReadAllRegiste
                 packet_len = ::snprintf (packet, sizeof(packet), "g");
             assert (packet_len < ((int)sizeof(packet) - 1));
 
-            if (gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false) == GDBRemoteCommunication::PacketResult::Success)
+            if (use_g_packet && gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false) == GDBRemoteCommunication::PacketResult::Success)
             {
-                if (response.IsErrorResponse())
-                    return false;
-
-                std::string &response_str = response.GetStringRef();
-                if (isxdigit(response_str[0]))
+                int packet_len = 0;
+                if (thread_suffix_supported)
+                    packet_len = ::snprintf (packet, sizeof(packet), "g;thread:%4.4" PRIx64, m_thread.GetProtocolID());
+                else
+                    packet_len = ::snprintf (packet, sizeof(packet), "g");
+                assert (packet_len < ((int)sizeof(packet) - 1));
+    
+                if (gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false) == GDBRemoteCommunication::PacketResult::Success)
                 {
-                    response_str.insert(0, 1, 'G');
-                    if (thread_suffix_supported)
+                    if (response.IsErrorResponse())
+                        return false;
+    
+                    std::string &response_str = response.GetStringRef();
+                    if (isxdigit(response_str[0]))
                     {
-                        char thread_id_cstr[64];
-                        ::snprintf (thread_id_cstr, sizeof(thread_id_cstr), ";thread:%4.4" PRIx64 ";", m_thread.GetProtocolID());
-                        response_str.append (thread_id_cstr);
+                        response_str.insert(0, 1, 'G');
+                        if (thread_suffix_supported)
+                        {
+                            char thread_id_cstr[64];
+                            ::snprintf (thread_id_cstr, sizeof(thread_id_cstr), ";thread:%4.4" PRIx64 ";", m_thread.GetProtocolID());
+                            response_str.append (thread_id_cstr);
+                        }
+                        data_sp.reset (new DataBufferHeap (response_str.c_str(), response_str.size()));
+                        return true;
                     }
-                    data_sp.reset (new DataBufferHeap (response_str.c_str(), response_str.size()));
-                    return true;
                 }
             }
+            else
+            {
+                // For the use_g_packet == false case, we're going to read each register 
+                // individually and store them as binary data in a buffer instead of as ascii
+                // characters.
+                const RegisterInfo *reg_info;
+
+                // data_sp will take ownership of this DataBufferHeap pointer soon.
+                DataBufferSP reg_ctx(new DataBufferHeap(m_reg_info.GetRegisterDataByteSize(), 0));
+
+                for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex (i)) != NULL; i++)
+                {
+                    if (reg_info->value_regs) // skip registers that are slices of real registers
+                        continue;
+                    ReadRegisterBytes (reg_info, m_reg_data);
+                    // ReadRegisterBytes saves the contents of the register in to the m_reg_data buffer
+                }
+                memcpy (reg_ctx->GetBytes(), m_reg_data.GetDataStart(), m_reg_info.GetRegisterDataByteSize());
+
+                data_sp = reg_ctx;
+                return true;
+            }
         }
     }
     else
     {
+
         Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS));
         if (log)
         {
@@ -575,6 +611,8 @@ GDBRemoteRegisterContext::WriteAllRegist
 
     GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote());
 
+    const bool use_g_packet = gdb_comm.AvoidGPackets ((ProcessGDBRemote *)process) == false;
+
     StringExtractorGDBRemote response;
     Mutex::Locker locker;
     if (gdb_comm.GetSequenceMutex (locker, "Didn't get sequence mutex for write all registers."))
@@ -588,63 +626,126 @@ GDBRemoteRegisterContext::WriteAllRegist
             // as well.
             const char *G_packet = (const char *)data_sp->GetBytes();
             size_t G_packet_len = data_sp->GetByteSize();
-            if (gdb_comm.SendPacketAndWaitForResponse (G_packet,
-                                                       G_packet_len,
-                                                       response,
-                                                       false) == GDBRemoteCommunication::PacketResult::Success)
+            if (use_g_packet
+                && gdb_comm.SendPacketAndWaitForResponse (G_packet,
+                                                          G_packet_len,
+                                                          response,
+                                                          false) == GDBRemoteCommunication::PacketResult::Success)
             {
-                if (response.IsOKResponse())
-                    return true;
-                else if (response.IsErrorResponse())
+                // The data_sp contains the entire G response packet including the
+                // G, and if the thread suffix is supported, it has the thread suffix
+                // as well.
+                const char *G_packet = (const char *)data_sp->GetBytes();
+                size_t G_packet_len = data_sp->GetByteSize();
+                if (gdb_comm.SendPacketAndWaitForResponse (G_packet,
+                                                           G_packet_len,
+                                                           response,
+                                                           false) == GDBRemoteCommunication::PacketResult::Success)
                 {
-                    uint32_t num_restored = 0;
-                    // We need to manually go through all of the registers and
-                    // restore them manually
-
-                    response.GetStringRef().assign (G_packet, G_packet_len);
-                    response.SetFilePos(1); // Skip the leading 'G'
-                    DataBufferHeap buffer (m_reg_data.GetByteSize(), 0);
-                    DataExtractor restore_data (buffer.GetBytes(),
-                                                buffer.GetByteSize(),
-                                                m_reg_data.GetByteOrder(),
-                                                m_reg_data.GetAddressByteSize());
-
-                    const uint32_t bytes_extracted = response.GetHexBytes ((void *)restore_data.GetDataStart(),
-                                                                           restore_data.GetByteSize(),
-                                                                           '\xcc');
-
-                    if (bytes_extracted < restore_data.GetByteSize())
-                        restore_data.SetData(restore_data.GetDataStart(), bytes_extracted, m_reg_data.GetByteOrder());
-
-                    //ReadRegisterBytes (const RegisterInfo *reg_info, RegisterValue &value, DataExtractor &data)
-                    const RegisterInfo *reg_info;
-                    // We have to march the offset of each register along in the
-                    // buffer to make sure we get the right offset.
-                    uint32_t reg_byte_offset = 0;
-                    for (uint32_t reg_idx=0; (reg_info = GetRegisterInfoAtIndex (reg_idx)) != NULL; ++reg_idx, reg_byte_offset += reg_info->byte_size)
+                    if (response.IsOKResponse())
+                        return true;
+                    else if (response.IsErrorResponse())
                     {
-                        const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+                        uint32_t num_restored = 0;
+                        // We need to manually go through all of the registers and
+                        // restore them manually
+    
+                        response.GetStringRef().assign (G_packet, G_packet_len);
+                        response.SetFilePos(1); // Skip the leading 'G'
 
-                        // Skip composite registers.
-                        if (reg_info->value_regs)
-                            continue;
-
-                        // Only write down the registers that need to be written
-                        // if we are going to be doing registers individually.
-                        bool write_reg = true;
-                        const uint32_t reg_byte_size = reg_info->byte_size;
+                        // G_packet_len is hex-ascii characters plus prefix 'G' plus suffix therad specifier.
+                        // This means buffer will be a little more than 2x larger than necessary but we resize
+                        // it down once we've extracted all hex ascii chars from the packet.
+                        DataBufferHeap buffer (G_packet_len, 0);
+                        DataExtractor restore_data (buffer.GetBytes(),
+                                                    buffer.GetByteSize(),
+                                                    m_reg_data.GetByteOrder(),
+                                                    m_reg_data.GetAddressByteSize());
+    
+                        const uint32_t bytes_extracted = response.GetHexBytes ((void *)restore_data.GetDataStart(),
+                                                                               restore_data.GetByteSize(),
+                                                                               '\xcc');
+    
+                        if (bytes_extracted < restore_data.GetByteSize())
+                            restore_data.SetData(restore_data.GetDataStart(), bytes_extracted, m_reg_data.GetByteOrder());
+    
+                        const RegisterInfo *reg_info;
+
+                        // The g packet contents may either include the slice registers (registers defined in
+                        // terms of other registers, e.g. eax is a subset of rax) or not.  The slice registers 
+                        // should NOT be in the g packet, but some implementations may incorrectly include them.
+                        // 
+                        // If the slice registers are included in the packet, we must step over the slice registers 
+                        // when parsing the packet -- relying on the RegisterInfo byte_offset field would be incorrect.
+                        // If the slice registers are not included, then using the byte_offset values into the
+                        // data buffer is the best way to find individual register values.
+
+                        int size_including_slice_registers = 0;
+                        int size_not_including_slice_registers = 0;
+                        int size_by_highest_offset = 0;
+
+                        for (uint32_t reg_idx=0; (reg_info = GetRegisterInfoAtIndex (reg_idx)) != NULL; ++reg_idx)
+                        {
+                            size_including_slice_registers += reg_info->byte_size;
+                            if (reg_info->value_regs == NULL)
+                                size_not_including_slice_registers += reg_info->byte_size;
+                            if (reg_info->byte_offset >= size_by_highest_offset)
+                                size_by_highest_offset = reg_info->byte_offset + reg_info->byte_size;
+                        }
+
+                        bool use_byte_offset_into_buffer;
+                        if (size_by_highest_offset == restore_data.GetByteSize())
+                        {
+                            // The size of the packet agrees with the highest offset: + size in the register file
+                            use_byte_offset_into_buffer = true;
+                        }
+                        else if (size_not_including_slice_registers == restore_data.GetByteSize())
+                        {
+                            // The size of the packet is the same as concenating all of the registers sequentially,
+                            // skipping the slice registers
+                            use_byte_offset_into_buffer = true;
+                        }
+                        else if (size_including_slice_registers == restore_data.GetByteSize())
+                        {
+                            // The slice registers are present in the packet (when they shouldn't be).
+                            // Don't try to use the RegisterInfo byte_offset into the restore_data, it will
+                            // point to the wrong place.
+                            use_byte_offset_into_buffer = false;
+                        }
+                        else {
+                            // None of our expected sizes match the actual g packet data we're looking at.
+                            // The most conservative approach here is to use the running total byte offset.
+                            use_byte_offset_into_buffer = false;
+                        }
 
-                        const char *restore_src = (const char *)restore_data.PeekData(reg_byte_offset, reg_byte_size);
-                        if (restore_src)
+                        // In case our register definitions don't include the correct offsets,
+                        // keep track of the size of each reg & compute offset based on that.
+                        uint32_t running_byte_offset = 0;
+                        for (uint32_t reg_idx=0; (reg_info = GetRegisterInfoAtIndex (reg_idx)) != NULL; ++reg_idx, running_byte_offset += reg_info->byte_size)
                         {
-                            if (GetRegisterIsValid(reg))
+                            // Skip composite aka slice registers (e.g. eax is a slice of rax).
+                            if (reg_info->value_regs)
+                                continue;
+
+                            const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+
+                            uint32_t register_offset;
+                            if (use_byte_offset_into_buffer)
+                            {
+                                register_offset = reg_info->byte_offset;
+                            }
+                            else
                             {
-                                const char *current_src = (const char *)m_reg_data.PeekData(reg_byte_offset, reg_byte_size);
-                                if (current_src)
-                                    write_reg = memcmp (current_src, restore_src, reg_byte_size) != 0;
+                                register_offset = running_byte_offset;
                             }
 
-                            if (write_reg)
+                            // Only write down the registers that need to be written
+                            // if we are going to be doing registers individually.
+                            bool write_reg = true;
+                            const uint32_t reg_byte_size = reg_info->byte_size;
+    
+                            const char *restore_src = (const char *)restore_data.PeekData(register_offset, reg_byte_size);
+                            if (restore_src)
                             {
                                 StreamString packet;
                                 packet.Printf ("P%x=", reg);
@@ -662,14 +763,88 @@ GDBRemoteRegisterContext::WriteAllRegist
                                                                           response,
                                                                           false) == GDBRemoteCommunication::PacketResult::Success)
                                 {
-                                    if (response.IsOKResponse())
-                                        ++num_restored;
+                                    const char *current_src = (const char *)m_reg_data.PeekData(register_offset, reg_byte_size);
+                                    if (current_src)
+                                        write_reg = memcmp (current_src, restore_src, reg_byte_size) != 0;
+                                }
+    
+                                if (write_reg)
+                                {
+                                    StreamString packet;
+                                    packet.Printf ("P%x=", reg);
+                                    packet.PutBytesAsRawHex8 (restore_src,
+                                                              reg_byte_size,
+                                                              lldb::endian::InlHostByteOrder(),
+                                                              lldb::endian::InlHostByteOrder());
+    
+                                    if (thread_suffix_supported)
+                                        packet.Printf (";thread:%4.4" PRIx64 ";", m_thread.GetProtocolID());
+    
+                                    SetRegisterIsValid(reg, false);
+                                    if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(),
+                                                                              packet.GetString().size(),
+                                                                              response,
+                                                                              false) == GDBRemoteCommunication::PacketResult::Success)
+                                    {
+                                        if (response.IsOKResponse())
+                                            ++num_restored;
+                                    }
                                 }
                             }
                         }
+                        return num_restored > 0;
+                    }
+                }
+            }
+            else
+            {
+                // For the use_g_packet == false case, we're going to write each register 
+                // individually.  The data buffer is binary data in this case, instead of 
+                // ascii characters.
+
+                bool arm64_debugserver = false;
+                if (m_thread.GetProcess().get())
+                {
+                    const ArchSpec &arch = m_thread.GetProcess()->GetTarget().GetArchitecture();
+                    if (arch.IsValid()
+                        && arch.GetMachine() == llvm::Triple::arm64
+                        && arch.GetTriple().getVendor() == llvm::Triple::Apple
+                        && arch.GetTriple().getOS() == llvm::Triple::IOS)
+                    {
+                        arm64_debugserver = true;
+                    }
+                }
+                uint32_t num_restored = 0;
+                const RegisterInfo *reg_info;
+                for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex (i)) != NULL; i++)
+                {
+                    if (reg_info->value_regs) // skip registers that are slices of real registers
+                        continue;
+                    // Skip the fpsr and fpcr floating point status/control register writing to
+                    // work around a bug in an older version of debugserver that would lead to
+                    // register context corruption when writing fpsr/fpcr.
+                    if (arm64_debugserver &&
+                        (strcmp (reg_info->name, "fpsr") == 0 || strcmp (reg_info->name, "fpcr") == 0))
+                    {
+                        continue;
+                    }
+                    StreamString packet;
+                    packet.Printf ("P%x=", reg_info->kinds[eRegisterKindLLDB]);
+                    packet.PutBytesAsRawHex8 (data_sp->GetBytes() + reg_info->byte_offset, reg_info->byte_size, lldb::endian::InlHostByteOrder(), lldb::endian::InlHostByteOrder());
+                    if (thread_suffix_supported)
+                        packet.Printf (";thread:%4.4" PRIx64 ";", m_thread.GetProtocolID());
+
+                    SetRegisterIsValid(reg_info, false);
+                    if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(),
+                                                              packet.GetString().size(),
+                                                              response,
+                                                              false) == GDBRemoteCommunication::PacketResult::Success)
+                    {
+                        if (response.IsOKResponse())
+                            ++num_restored;
                     }
-                    return num_restored > 0;
                 }
+                return num_restored > 0;
             }
         }
     }

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Sat Mar 29 13:54:20 2014
@@ -800,6 +800,10 @@ ProcessGDBRemote::DoLaunch (Module *exe_
 
             m_gdb_comm.SendLaunchArchPacket (m_target.GetArchitecture().GetArchitectureName());
             
+            const char * launch_event_data = launch_info.GetLaunchEventData();
+            if (launch_event_data != NULL && *launch_event_data != '\0')
+                m_gdb_comm.SendLaunchEventDataPacket (launch_event_data);
+            
             if (working_dir && working_dir[0])
             {
                 m_gdb_comm.SetWorkingDir (working_dir);
@@ -2608,7 +2612,7 @@ ProcessGDBRemote::LaunchAndConnectToDebu
         debugserver_launch_info.SetMonitorProcessCallback (MonitorDebugserverProcess, this, false);
         debugserver_launch_info.SetUserID(process_info.GetUserID());
 
-#if defined (__APPLE__) && defined (__arm__)
+#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__))
         // On iOS, still do a local connection using a random port
         const char *hostname = "127.0.0.1";
         uint16_t port = get_random_port ();
@@ -2924,13 +2928,33 @@ ProcessGDBRemote::AsyncThread (void *arg
                                         break;
 
                                     case eStateExited:
+                                    {
                                         process->SetLastStopPacket (response);
                                         process->ClearThreadIDList();
                                         response.SetFilePos(1);
-                                        process->SetExitStatus(response.GetHexU8(), NULL);
+                                        
+                                        int exit_status = response.GetHexU8();
+                                        const char *desc_cstr = NULL;
+                                        StringExtractor extractor;
+                                        std::string desc_string;
+                                        if (response.GetBytesLeft() > 0 && response.GetChar('-') == ';')
+                                        {
+                                            std::string desc_token;
+                                            while (response.GetNameColonValue (desc_token, desc_string))
+                                            {
+                                                if (desc_token == "description")
+                                                {
+                                                    extractor.GetStringRef().swap(desc_string);
+                                                    extractor.SetFilePos(0);
+                                                    extractor.GetHexByteString (desc_string);
+                                                    desc_cstr = desc_string.c_str();
+                                                }
+                                            }
+                                        }
+                                        process->SetExitStatus(exit_status, desc_cstr);
                                         done = true;
                                         break;
-
+                                    }
                                     case eStateInvalid:
                                         process->SetExitStatus(-1, "lost connection");
                                         break;
@@ -3066,6 +3090,25 @@ ProcessGDBRemote::GetDynamicLoader ()
     return m_dyld_ap.get();
 }
 
+Error
+ProcessGDBRemote::SendEventData(const char *data)
+{
+    int return_value;
+    bool was_supported;
+    
+    Error error;
+    
+    return_value = m_gdb_comm.SendLaunchEventDataPacket (data, &was_supported);
+    if (return_value != 0)
+    {
+        if (!was_supported)
+            error.SetErrorString("Sending events is not supported for this process.");
+        else
+            error.SetErrorStringWithFormat("Error sending event data: %d.", return_value);
+    }
+    return error;
+}
+
 const DataBufferSP
 ProcessGDBRemote::GetAuxvData()
 {
@@ -3079,7 +3122,6 @@ ProcessGDBRemote::GetAuxvData()
     return buf;
 }
 
-
 class CommandObjectProcessGDBRemotePacketHistory : public CommandObjectParsed
 {
 private:

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h Sat Mar 29 13:54:20 2014
@@ -221,13 +221,15 @@ public:
         return m_gdb_comm;
     }
     
+    virtual lldb_private::Error
+    SendEventData(const char *data);
+
     //----------------------------------------------------------------------
     // Override SetExitStatus so we can disconnect from the remote GDB server
     //----------------------------------------------------------------------
     virtual bool
     SetExitStatus (int exit_status, const char *cstr);
 
-
 protected:
     friend class ThreadGDBRemote;
     friend class GDBRemoteCommunicationClient;

Modified: lldb/trunk/source/Symbol/ClangASTType.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTType.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTType.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTType.cpp Sat Mar 29 13:54:20 2014
@@ -406,6 +406,102 @@ ClangASTType::IsFunctionType (bool *is_v
     return false;
 }
 
+// Used to detect "Homogeneous Floating-point Aggregates"
+uint32_t
+ClangASTType::IsHomogeneousAggregate (ClangASTType* base_type_ptr) const
+{
+    if (!IsValid())
+        return 0;
+    
+    QualType qual_type(GetCanonicalQualType());
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::Record:
+            if (GetCompleteType ())
+            {
+                const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+                if (cxx_record_decl)
+                {
+                    if (cxx_record_decl->getNumBases() ||
+                        cxx_record_decl->isDynamicClass())
+                        return 0;
+                }
+                const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
+                if (record_type)
+                {
+                    const RecordDecl *record_decl = record_type->getDecl();
+                    if (record_decl)
+                    {
+                        // We are looking for a structure that contains only floating point types
+                        RecordDecl::field_iterator field_pos, field_end = record_decl->field_end();
+                        uint32_t num_fields = 0;
+                        bool is_hva = false;
+                        bool is_hfa = false;
+                        QualType base_qual_type;
+                        for (field_pos = record_decl->field_begin(); field_pos != field_end; ++field_pos)
+                        {
+                            QualType field_qual_type = field_pos->getType();
+                            if (field_qual_type->isFloatingType())
+                            {
+                                if (field_qual_type->isComplexType())
+                                    return 0;
+                                else
+                                {
+                                    if (num_fields == 0)
+                                        base_qual_type = field_qual_type;
+                                    else
+                                    {
+                                        if (is_hva)
+                                            return 0;
+                                        is_hfa = true;
+                                        if (field_qual_type.getTypePtr() != base_qual_type.getTypePtr())
+                                            return 0;
+                                    }
+                                }
+                            }
+                            else if (field_qual_type->isVectorType() || field_qual_type->isExtVectorType())
+                            {
+                                const VectorType *array = cast<VectorType>(field_qual_type.getTypePtr());
+                                if (array && array->getNumElements() <= 4)
+                                {
+                                    if (num_fields == 0)
+                                        base_qual_type = array->getElementType();
+                                    else
+                                    {
+                                        if (is_hfa)
+                                            return 0;
+                                        is_hva = true;
+                                        if (field_qual_type.getTypePtr() != base_qual_type.getTypePtr())
+                                            return 0;
+                                    }
+                                }
+                                else
+                                    return 0;
+                            }
+                            else
+                                return 0;
+                            ++num_fields;
+                        }
+                        if (base_type_ptr)
+                            *base_type_ptr = ClangASTType (m_ast, base_qual_type);
+                        return num_fields;
+                    }
+                }
+            }
+            break;
+            
+        case clang::Type::Typedef:
+            return ClangASTType(m_ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsHomogeneousAggregate (base_type_ptr);
+            
+        case clang::Type::Elaborated:
+            return  ClangASTType(m_ast, cast<ElaboratedType>(qual_type)->getNamedType()).IsHomogeneousAggregate (base_type_ptr);
+        default:
+            break;
+    }
+    return 0;
+}
+
 size_t
 ClangASTType::GetNumberOfFunctionArguments () const
 {
@@ -6545,3 +6641,4 @@ lldb_private::operator != (const lldb_pr
 }
 
 
+

Modified: lldb/trunk/source/Target/Thread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Thread.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Target/Thread.cpp (original)
+++ lldb/trunk/source/Target/Thread.cpp Sat Mar 29 13:54:20 2014
@@ -2082,6 +2082,7 @@ Thread::GetUnwinder ()
             case llvm::Triple::x86_64:
             case llvm::Triple::x86:
             case llvm::Triple::arm:
+            case llvm::Triple::arm64:
             case llvm::Triple::thumb:
             case llvm::Triple::mips64:
             case llvm::Triple::hexagon:

Added: lldb/trunk/source/Utility/ARM64_DWARF_Registers.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/ARM64_DWARF_Registers.cpp?rev=205113&view=auto
==============================================================================
--- lldb/trunk/source/Utility/ARM64_DWARF_Registers.cpp (added)
+++ lldb/trunk/source/Utility/ARM64_DWARF_Registers.cpp Sat Mar 29 13:54:20 2014
@@ -0,0 +1,146 @@
+//===-- ARM64_DWARF_Registers.c ---------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ARM64_DWARF_Registers.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace arm64_dwarf;
+
+const char *
+arm64_dwarf::GetRegisterName (unsigned reg_num, bool altnernate_name)
+{
+    if (altnernate_name)
+    {
+        switch (reg_num)
+        {
+            case fp: return "x29"; 
+            case lr: return "x30"; 
+            case sp: return "x31"; 
+            default:
+                break;
+        }
+        return NULL;
+    }
+    
+    switch (reg_num)
+    {
+        case x0:       return "x0";
+        case x1:       return "x1";
+        case x2:       return "x2";
+        case x3:       return "x3";
+        case x4:       return "x4";
+        case x5:       return "x5";
+        case x6:       return "x6";
+        case x7:       return "x7";
+        case x8:       return "x8";
+        case x9:       return "x9";
+        case x10:      return "x10";
+        case x11:      return "x11";
+        case x12:      return "x12";
+        case x13:      return "x13";
+        case x14:      return "x14";
+        case x15:      return "x15";
+        case x16:      return "x16";
+        case x17:      return "x17";
+        case x18:      return "x18";
+        case x19:      return "x19";
+        case x20:      return "x20";
+        case x21:      return "x21";
+        case x22:      return "x22";
+        case x23:      return "x23";
+        case x24:      return "x24";
+        case x25:      return "x25";
+        case x26:      return "x26";
+        case x27:      return "x27";
+        case x28:      return "x28";
+        case fp:       return "fp";
+        case lr:       return "lr";
+        case sp:       return "sp";
+        case pc:       return "pc";
+        case cpsr:     return "cpsr";
+        case v0:       return "v0";
+        case v1:       return "v1";
+        case v2:       return "v2";
+        case v3:       return "v3";
+        case v4:       return "v4";
+        case v5:       return "v5";
+        case v6:       return "v6";
+        case v7:       return "v7";
+        case v8:       return "v8";
+        case v9:       return "v9";
+        case v10:      return "v10";
+        case v11:      return "v11";
+        case v12:      return "v12";
+        case v13:      return "v13";
+        case v14:      return "v14";
+        case v15:      return "v15";
+        case v16:      return "v16";
+        case v17:      return "v17";
+        case v18:      return "v18";
+        case v19:      return "v19";
+        case v20:      return "v20";
+        case v21:      return "v21";
+        case v22:      return "v22";
+        case v23:      return "v23";
+        case v24:      return "v24";
+        case v25:      return "v25";
+        case v26:      return "v26";
+        case v27:      return "v27";
+        case v28:      return "v28";
+        case v29:      return "v29";
+        case v30:      return "v30";
+        case v31:      return "v31";
+    }
+    return 0;
+}
+
+bool
+arm64_dwarf::GetRegisterInfo (unsigned reg_num, RegisterInfo &reg_info)
+{
+    ::memset (&reg_info, 0, sizeof(RegisterInfo));
+    ::memset (reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds));
+    
+    if (reg_num >= x0 && reg_num <= pc)
+    {
+        reg_info.byte_size = 8;
+        reg_info.format = eFormatHex;
+        reg_info.encoding = eEncodingUint;
+    }
+    else if (reg_num >= v0 && reg_num <= v31)
+    {
+        reg_info.byte_size = 16;
+        reg_info.format = eFormatVectorOfFloat32;
+        reg_info.encoding = eEncodingVector;
+    }
+    else if (reg_num == cpsr)
+    {
+        reg_info.byte_size = 4;
+        reg_info.format = eFormatHex;
+        reg_info.encoding = eEncodingUint;
+    }
+    else
+    {
+        return false;
+    }
+    
+    reg_info.name = arm64_dwarf::GetRegisterName (reg_num, false);
+    reg_info.alt_name = arm64_dwarf::GetRegisterName (reg_num, true);
+    reg_info.kinds[eRegisterKindDWARF] = reg_num;
+
+    switch (reg_num)
+    {            
+    case fp: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; break;
+    case lr: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA; break;
+    case sp: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP; break;
+    case pc: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; break;
+    default: break;
+    }
+    return true;
+}

Added: lldb/trunk/source/Utility/ARM64_DWARF_Registers.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/ARM64_DWARF_Registers.h?rev=205113&view=auto
==============================================================================
--- lldb/trunk/source/Utility/ARM64_DWARF_Registers.h (added)
+++ lldb/trunk/source/Utility/ARM64_DWARF_Registers.h Sat Mar 29 13:54:20 2014
@@ -0,0 +1,102 @@
+//===-- ARM64_DWARF_Registers.h ---------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef utility_ARM64_DWARF_Registers_h_
+#define utility_ARM64_DWARF_Registers_h_
+
+#include "lldb/lldb-private.h"
+
+namespace arm64_dwarf {
+    
+enum
+{
+    x0 = 0,
+    x1,
+    x2,
+    x3,
+    x4,
+    x5,
+    x6,
+    x7,
+    x8,
+    x9,
+    x10,
+    x11,
+    x12,
+    x13,
+    x14,
+    x15,
+    x16,
+    x17,
+    x18,
+    x19,
+    x20,
+    x21,
+    x22,
+    x23,
+    x24,
+    x25,
+    x26,
+    x27,
+    x28,
+    x29       = 29,   fp = x29,
+    x30       = 30,   lr = x30,
+    x31       = 31,   sp = x31,
+    pc        = 32,
+    cpsr  = 33,
+    // 34-63 reserved
+
+    // V0-V31 (128 bit vector registers)
+    v0        = 64,
+    v1,
+    v2,
+    v3,
+    v4,
+    v5,
+    v6,
+    v7,
+    v8,
+    v9,
+    v10,
+    v11,
+    v12,
+    v13,
+    v14,
+    v15,
+    v16,
+    v17,
+    v18,
+    v19,
+    v20,
+    v21,
+    v22,
+    v23,
+    v24,
+    v25,
+    v26,
+    v27,
+    v28,
+    v29,
+    v30,
+    v31
+
+    // 96-127 reserved
+};
+
+const char *
+GetRegisterName (unsigned reg_num, bool altnernate_name);
+    
+bool
+GetRegisterInfo (unsigned reg_num, 
+                 lldb_private::RegisterInfo &reg_info);
+
+}   // namespace arm64_dwarf
+
+#endif // utility_ARM64_DWARF_Registers_h_
+

Added: lldb/trunk/source/Utility/ARM64_GCC_Registers.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/ARM64_GCC_Registers.h?rev=205113&view=auto
==============================================================================
--- lldb/trunk/source/Utility/ARM64_GCC_Registers.h (added)
+++ lldb/trunk/source/Utility/ARM64_GCC_Registers.h Sat Mar 29 13:54:20 2014
@@ -0,0 +1,92 @@
+//===-- ARM64_gdb_Registers.h -------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef utility_ARM64_gdb_Registers_h_
+#define utility_ARM64_gdb_Registers_h_
+
+namespace arm64_gcc {
+    
+enum
+{
+    x0 = 0,
+    x1,
+    x2,
+    x3,
+    x4,
+    x5,
+    x6,
+    x7,
+    x8,
+    x9,
+    x10,
+    x11,
+    x12,
+    x13,
+    x14,
+    x15,
+    x16,
+    x17,
+    x18,
+    x19,
+    x20,
+    x21,
+    x22,
+    x23,
+    x24,
+    x25,
+    x26,
+    x27,
+    x28,
+    fp,       // aka x29
+    lr,       // aka x30
+    sp,       // aka x31 aka wzr
+    pc,       // value is 32
+    cpsr
+};
+
+enum
+{
+    v0 = 64,
+    v1,
+    v2,
+    v3,
+    v4,
+    v5,
+    v6,
+    v7,
+    v8,
+    v9,
+    v10,
+    v11,
+    v12,
+    v13,
+    v14,
+    v15,
+    v16,
+    v17,
+    v18,
+    v19,
+    v20,
+    v21,
+    v22,
+    v23,
+    v24,
+    v25,
+    v26,
+    v27,
+    v28,
+    v29,
+    v30,
+    v31  // 95
+};
+
+};
+
+#endif // utility_ARM64_gdb_Registers_h_
+

Modified: lldb/trunk/source/Utility/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/CMakeLists.txt?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/Utility/CMakeLists.txt (original)
+++ lldb/trunk/source/Utility/CMakeLists.txt Sat Mar 29 13:54:20 2014
@@ -2,6 +2,7 @@ set(LLVM_NO_RTTI 1)
 
 add_lldb_library(lldbUtility
   ARM_DWARF_Registers.cpp
+  ARM64_DWARF_Registers.cpp
   KQueue.cpp
   PseudoTerminal.cpp
   Range.cpp

Modified: lldb/trunk/source/lldb.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/lldb.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/source/lldb.cpp (original)
+++ lldb/trunk/source/lldb.cpp Sat Mar 29 13:54:20 2014
@@ -27,10 +27,13 @@
 
 #include "Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h"
 #include "Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h"
+#include "Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h"
 #include "Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h"
 #include "Plugins/Disassembler/llvm/DisassemblerLLVMC.h"
 #include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h"
 #include "Plugins/Instruction/ARM/EmulateInstructionARM.h"
+#include "Plugins/Instruction/ARM64/EmulateInstructionARM64.h"
+#include "Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h"
 #include "Plugins/JITLoader/GDB/JITLoaderGDB.h"
 #include "Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h"
 #include "Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h"
@@ -103,6 +106,7 @@ lldb_private::Initialize ()
         
         ABIMacOSX_i386::Initialize();
         ABIMacOSX_arm::Initialize();
+        ABIMacOSX_arm64::Initialize();
         ABISysV_x86_64::Initialize();
         DisassemblerLLVMC::Initialize();
         ObjectContainerBSDArchive::Initialize();
@@ -113,6 +117,7 @@ lldb_private::Initialize ()
         UnwindAssemblyInstEmulation::Initialize();
         UnwindAssembly_x86::Initialize();
         EmulateInstructionARM::Initialize ();
+        EmulateInstructionARM64::Initialize ();
         ObjectFilePECOFF::Initialize ();
         DynamicLoaderPOSIXDYLD::Initialize ();
         PlatformFreeBSD::Initialize();
@@ -188,6 +193,7 @@ lldb_private::Terminate ()
     PluginManager::Terminate();
     ABIMacOSX_i386::Terminate();
     ABIMacOSX_arm::Terminate();
+    ABIMacOSX_arm64::Terminate();
     ABISysV_x86_64::Terminate();
     DisassemblerLLVMC::Terminate();
     ObjectContainerBSDArchive::Terminate();
@@ -198,6 +204,7 @@ lldb_private::Terminate ()
     UnwindAssembly_x86::Terminate();
     UnwindAssemblyInstEmulation::Terminate();
     EmulateInstructionARM::Terminate ();
+    EmulateInstructionARM64::Terminate ();
     ObjectFilePECOFF::Terminate ();
     DynamicLoaderPOSIXDYLD::Terminate ();
     PlatformFreeBSD::Terminate();

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/main.m
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/main.m?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/main.m (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/main.m Sat Mar 29 13:54:20 2014
@@ -10,7 +10,7 @@
 #import <Foundation/Foundation.h>
 
 #if defined(__APPLE__)
-#if defined(__arm__)
+#if defined(__arm__) || defined(__arm64__)
 #define IOS
 #endif
 #endif

Modified: lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj Sat Mar 29 13:54:20 2014
@@ -9,6 +9,7 @@
 /* Begin PBXBuildFile section */
 		264D5D581293835600ED4C01 /* DNBArch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 264D5D571293835600ED4C01 /* DNBArch.cpp */; };
 		2660D9CE1192280900958FBD /* StringExtractor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2660D9CC1192280900958FBD /* StringExtractor.cpp */; };
+		266B5ED11460A68200E43F0A /* DNBArchImplARM64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266B5ECF1460A68200E43F0A /* DNBArchImplARM64.cpp */; };
 		26CE05A7115C360D0022F371 /* DNBError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637DE0C71334A0024798E /* DNBError.cpp */; };
 		26CE05A8115C36170022F371 /* DNBThreadResumeActions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260E7331114BFFE600D1DFB3 /* DNBThreadResumeActions.cpp */; };
 		26CE05A9115C36250022F371 /* debugserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A02918114AB9240029C479 /* debugserver.cpp */; };
@@ -18,12 +19,12 @@
 		26CE05AD115C36280022F371 /* RNBRemote.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A68FD60D10574500665A9E /* RNBRemote.cpp */; };
 		26CE05AE115C36320022F371 /* dbgnub-mig.defs in Sources */ = {isa = PBXBuildFile; fileRef = 26C637E80C71334A0024798E /* dbgnub-mig.defs */; settings = {ATTRIBUTES = (Client, Server, ); }; };
 		26CE05B0115C36340022F371 /* MachException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637EE0C71334A0024798E /* MachException.cpp */; };
-		26CE05B1115C36350022F371 /* MachProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637F00C71334A0024798E /* MachProcess.cpp */; };
+		26CE05B1115C36350022F371 /* MachProcess.mm in Sources */ = {isa = PBXBuildFile; fileRef = 26C637F00C71334A0024798E /* MachProcess.mm */; };
 		26CE05B2115C36360022F371 /* MachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637F20C71334A0024798E /* MachThread.cpp */; };
 		26CE05B3115C36370022F371 /* MachThreadList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637F40C71334A0024798E /* MachThreadList.cpp */; };
 		26CE05B4115C36380022F371 /* MachVMMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637F60C71334A0024798E /* MachVMMemory.cpp */; };
 		26CE05B5115C36380022F371 /* MachVMRegion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637F80C71334A0024798E /* MachVMRegion.cpp */; };
-		26CE05B6115C36390022F371 /* MachTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26B67DE10EE9BC30006C8BC0 /* MachTask.cpp */; };
+		26CE05B6115C36390022F371 /* MachTask.mm in Sources */ = {isa = PBXBuildFile; fileRef = 26B67DE10EE9BC30006C8BC0 /* MachTask.mm */; };
 		26CE05B7115C363B0022F371 /* DNB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637D60C71334A0024798E /* DNB.cpp */; };
 		26CE05B8115C363C0022F371 /* DNBBreakpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637D90C71334A0024798E /* DNBBreakpoint.cpp */; };
 		26CE05B9115C363D0022F371 /* DNBDataRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637DB0C71334A0024798E /* DNBDataRef.cpp */; };
@@ -56,6 +57,8 @@
 		26593A060D4931CC001C9FE3 /* ChangeLog */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ChangeLog; sourceTree = "<group>"; };
 		2660D9CC1192280900958FBD /* StringExtractor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringExtractor.cpp; path = ../../source/Utility/StringExtractor.cpp; sourceTree = SOURCE_ROOT; };
 		2660D9CD1192280900958FBD /* StringExtractor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StringExtractor.h; path = ../../source/Utility/StringExtractor.h; sourceTree = SOURCE_ROOT; };
+		266B5ECF1460A68200E43F0A /* DNBArchImplARM64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DNBArchImplARM64.cpp; sourceTree = "<group>"; };
+		266B5ED01460A68200E43F0A /* DNBArchImplARM64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DNBArchImplARM64.h; sourceTree = "<group>"; };
 		2672DBEE0EEF446700E92059 /* PThreadMutex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PThreadMutex.cpp; sourceTree = "<group>"; };
 		2675D4220CCEB705000F49AF /* DNBArchImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DNBArchImpl.cpp; path = arm/DNBArchImpl.cpp; sourceTree = "<group>"; };
 		2675D4230CCEB705000F49AF /* DNBArchImpl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DNBArchImpl.h; path = arm/DNBArchImpl.h; sourceTree = "<group>"; };
@@ -77,7 +80,7 @@
 		26A8FE1E0D11A77B00203048 /* DNBTimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DNBTimer.h; sourceTree = "<group>"; };
 		26ACA3340D3E956300A2120B /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
 		26B67DE00EE9BC30006C8BC0 /* MachTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachTask.h; sourceTree = "<group>"; };
-		26B67DE10EE9BC30006C8BC0 /* MachTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MachTask.cpp; sourceTree = "<group>"; };
+		26B67DE10EE9BC30006C8BC0 /* MachTask.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MachTask.mm; sourceTree = "<group>"; };
 		26C636AD0C71303A0024798E /* dbgnub-config.pl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; path = "dbgnub-config.pl"; sourceTree = "<group>"; };
 		26C637D60C71334A0024798E /* DNB.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DNB.cpp; sourceTree = "<group>"; };
 		26C637D70C71334A0024798E /* DNB.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DNB.h; sourceTree = "<group>"; };
@@ -99,7 +102,7 @@
 		26C637EB0C71334A0024798E /* DNBArchImplI386.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DNBArchImplI386.h; sourceTree = "<group>"; };
 		26C637EE0C71334A0024798E /* MachException.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MachException.cpp; sourceTree = "<group>"; };
 		26C637EF0C71334A0024798E /* MachException.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MachException.h; sourceTree = "<group>"; };
-		26C637F00C71334A0024798E /* MachProcess.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MachProcess.cpp; sourceTree = "<group>"; };
+		26C637F00C71334A0024798E /* MachProcess.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = MachProcess.mm; sourceTree = "<group>"; };
 		26C637F10C71334A0024798E /* MachProcess.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MachProcess.h; sourceTree = "<group>"; };
 		26C637F20C71334A0024798E /* MachThread.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MachThread.cpp; sourceTree = "<group>"; };
 		26C637F30C71334A0024798E /* MachThread.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MachThread.h; sourceTree = "<group>"; };
@@ -167,6 +170,15 @@
 			name = Products;
 			sourceTree = "<group>";
 		};
+		266B5ECE1460A68200E43F0A /* arm64 */ = {
+			isa = PBXGroup;
+			children = (
+				266B5ECF1460A68200E43F0A /* DNBArchImplARM64.cpp */,
+				266B5ED01460A68200E43F0A /* DNBArchImplARM64.h */,
+			);
+			path = arm64;
+			sourceTree = "<group>";
+		};
 		2675D41C0CCEB6CF000F49AF /* arm */ = {
 			isa = PBXGroup;
 			children = (
@@ -269,6 +281,7 @@
 				2695DD9B0D3EC160007E4CA2 /* CFString.cpp */,
 				26C637E70C71334A0024798E /* CFUtils.h */,
 				2675D41C0CCEB6CF000F49AF /* arm */,
+				266B5ECE1460A68200E43F0A /* arm64 */,
 				26C637E90C71334A0024798E /* i386 */,
 				26C637FA0C71334A0024798E /* ppc */,
 				26CF99A11142EB7400011AAB /* x86_64 */,
@@ -278,7 +291,7 @@
 				26C637EF0C71334A0024798E /* MachException.h */,
 				26C637EE0C71334A0024798E /* MachException.cpp */,
 				26C637F10C71334A0024798E /* MachProcess.h */,
-				26C637F00C71334A0024798E /* MachProcess.cpp */,
+				26C637F00C71334A0024798E /* MachProcess.mm */,
 				26C637F30C71334A0024798E /* MachThread.h */,
 				26C637F20C71334A0024798E /* MachThread.cpp */,
 				26C637F50C71334A0024798E /* MachThreadList.h */,
@@ -288,7 +301,7 @@
 				26C637F90C71334A0024798E /* MachVMRegion.h */,
 				26C637F80C71334A0024798E /* MachVMRegion.cpp */,
 				26B67DE00EE9BC30006C8BC0 /* MachTask.h */,
-				26B67DE10EE9BC30006C8BC0 /* MachTask.cpp */,
+				26B67DE10EE9BC30006C8BC0 /* MachTask.mm */,
 				9457ECF61419864100DFE7D8 /* stack_logging.h */,
 			);
 			path = MacOSX;
@@ -437,12 +450,12 @@
 				26CE05AD115C36280022F371 /* RNBRemote.cpp in Sources */,
 				26CE05AE115C36320022F371 /* dbgnub-mig.defs in Sources */,
 				26CE05B0115C36340022F371 /* MachException.cpp in Sources */,
-				26CE05B1115C36350022F371 /* MachProcess.cpp in Sources */,
+				26CE05B1115C36350022F371 /* MachProcess.mm in Sources */,
 				26CE05B2115C36360022F371 /* MachThread.cpp in Sources */,
 				26CE05B3115C36370022F371 /* MachThreadList.cpp in Sources */,
 				26CE05B4115C36380022F371 /* MachVMMemory.cpp in Sources */,
 				26CE05B5115C36380022F371 /* MachVMRegion.cpp in Sources */,
-				26CE05B6115C36390022F371 /* MachTask.cpp in Sources */,
+				26CE05B6115C36390022F371 /* MachTask.mm in Sources */,
 				26CE05B7115C363B0022F371 /* DNB.cpp in Sources */,
 				26CE05B8115C363C0022F371 /* DNBBreakpoint.cpp in Sources */,
 				26CE05B9115C363D0022F371 /* DNBDataRef.cpp in Sources */,
@@ -462,6 +475,7 @@
 				2660D9CE1192280900958FBD /* StringExtractor.cpp in Sources */,
 				264D5D581293835600ED4C01 /* DNBArch.cpp in Sources */,
 				4971AE7213D10F4F00649E37 /* HasAVX.s in Sources */,
+				266B5ED11460A68200E43F0A /* DNBArchImplARM64.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -472,8 +486,8 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				"ARCHS[sdk=iphoneos*]" = (
+					arm64,
 					armv7,
-					armv7s,
 				);
 				"ARCHS[sdk=macosx*]" = (
 					x86_64,
@@ -533,10 +547,7 @@
 		262419A11198A93E00067686 /* BuildAndIntegration */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				"ARCHS[sdk=iphoneos*]" = (
-					armv7,
-					armv7s,
-				);
+				"ARCHS[sdk=iphoneos*]" = arm64;
 				"ARCHS[sdk=macosx*]" = (
 					x86_64,
 					i386,
@@ -588,7 +599,7 @@
 				"OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
 					"-Wparentheses",
 					"-DWITH_LOCKDOWN",
-					"-DWITH_SPRINGBOARD",
+					"-DWITH_BKS",
 					"-DOS_OBJECT_USE_OBJC=0",
 				);
 				"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
@@ -601,6 +612,10 @@
 				"OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
 					"-framework",
 					SpringBoardServices,
+					"-framework",
+					BackBoardServices,
+					"-framework",
+					Foundation,
 					"-llockdown",
 				);
 				OTHER_MIGFLAGS = "-I$(DERIVED_FILE_DIR)";
@@ -640,7 +655,7 @@
 				"OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
 					"-Wparentheses",
 					"-DWITH_LOCKDOWN",
-					"-DWITH_SPRINGBOARD",
+					"-DWITH_BKS",
 					"-DOS_OBJECT_USE_OBJC=0",
 				);
 				"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
@@ -653,6 +668,10 @@
 				"OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
 					"-framework",
 					SpringBoardServices,
+					"-framework",
+					BackBoardServices,
+					"-framework",
+					Foundation,
 					"-llockdown",
 				);
 				OTHER_MIGFLAGS = "-I$(DERIVED_FILE_DIR)";
@@ -692,7 +711,7 @@
 				"OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
 					"-Wparentheses",
 					"-DWITH_LOCKDOWN",
-					"-DWITH_SPRINGBOARD",
+					"-DWITH_BKS",
 					"-DOS_OBJECT_USE_OBJC=0",
 				);
 				"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
@@ -705,7 +724,11 @@
 				"OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
 					"-framework",
 					SpringBoardServices,
+					"-framework",
+					BackBoardServices,
 					"-llockdown",
+					"-framework",
+					Foundation,
 				);
 				OTHER_MIGFLAGS = "-I$(DERIVED_FILE_DIR)";
 				PRODUCT_NAME = debugserver;
@@ -721,8 +744,8 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				"ARCHS[sdk=iphoneos*]" = (
+					arm64,
 					armv7,
-					armv7s,
 				);
 				"ARCHS[sdk=macosx*]" = (
 					x86_64,
@@ -776,7 +799,7 @@
 				"OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
 					"-Wparentheses",
 					"-DWITH_LOCKDOWN",
-					"-DWITH_SPRINGBOARD",
+					"-DWITH_BKS",
 					"-DOS_OBJECT_USE_OBJC=0",
 				);
 				"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
@@ -789,7 +812,11 @@
 				"OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
 					"-framework",
 					SpringBoardServices,
+					"-framework",
+					BackBoardServices,
 					"-llockdown",
+					"-framework",
+					Foundation,
 				);
 				OTHER_MIGFLAGS = "-I$(DERIVED_FILE_DIR)";
 				PRODUCT_NAME = debugserver;

Modified: lldb/trunk/tools/debugserver/source/DNB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/DNB.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/DNB.cpp (original)
+++ lldb/trunk/tools/debugserver/source/DNB.cpp Sat Mar 29 13:54:20 2014
@@ -26,6 +26,16 @@
 #include <vector>
 #include <libproc.h>
 
+#define TRY_KQUEUE 1
+
+#ifdef TRY_KQUEUE
+    #include <sys/event.h>
+    #include <sys/time.h>
+    #ifdef NOTE_EXIT_DETAIL
+        #define USE_KQUEUE
+    #endif
+#endif
+
 #include "MacOSX/MachProcess.h"
 #include "MacOSX/MachTask.h"
 #include "CFString.h"
@@ -123,6 +133,95 @@ GetProcessSP (nub_process_t pid, MachPro
     return false;
 }
 
+#ifdef USE_KQUEUE
+void *
+kqueue_thread (void *arg)
+{
+    int kq_id = (int) (intptr_t) arg;
+    
+    struct kevent death_event;
+    while (1)
+    {        
+        int n_events = kevent (kq_id, NULL, 0, &death_event, 1, NULL);
+        if (n_events == -1)
+        {
+            if (errno == EINTR)
+                continue;
+            else
+            {
+                DNBLogError ("kqueue failed with error: (%d): %s", errno, strerror(errno));
+                return NULL;
+            }
+        }
+        else if (death_event.flags & EV_ERROR)
+        {
+            int error_no = death_event.data;
+            const char *error_str = strerror(death_event.data);
+            if (error_str == NULL)
+                error_str = "Unknown error";
+            DNBLogError ("Failed to initialize kqueue event: (%d): %s", error_no, error_str );
+            return NULL;
+        }
+        else
+        {
+            int status;
+            pid_t child_pid = waitpid ((pid_t) death_event.ident, &status, 0);
+            if (death_event.data & NOTE_EXIT_MEMORY)
+            {
+                if (death_event.data & NOTE_VM_PRESSURE)
+                    DNBProcessSetExitInfo (child_pid, "Terminated due to Memory Pressure");
+                else if (death_event.data & NOTE_VM_ERROR)
+                    DNBProcessSetExitInfo (child_pid, "Terminated due to Memory Error");
+                else
+                    DNBProcessSetExitInfo (child_pid, "Terminated due to unknown Memory condition");
+            }
+            else if (death_event.data & NOTE_EXIT_DECRYPTFAIL)
+                    DNBProcessSetExitInfo (child_pid, "Terminated due to decrypt failure");
+            else if (death_event.data & NOTE_EXIT_CSERROR)
+                    DNBProcessSetExitInfo (child_pid, "Terminated due to code signing error");
+            
+            DNBLogThreadedIf(LOG_PROCESS, "waitpid_process_thread (): setting exit status for pid = %i to %i", child_pid, status);
+            DNBProcessSetExitStatus (child_pid, status);
+            return NULL;
+        }
+    }
+}
+
+static bool
+spawn_kqueue_thread (pid_t pid)
+{
+    pthread_t thread;
+    int kq_id;
+    
+    kq_id = kqueue();
+    if (kq_id == -1)
+    {
+        DNBLogError ("Could not get kqueue for pid = %i.", pid);
+        return false;
+    }
+
+    struct kevent reg_event;
+    
+    EV_SET(&reg_event, pid, EVFILT_PROC, EV_ADD, NOTE_EXIT|NOTE_EXIT_DETAIL, 0, NULL);
+    // Register the event:
+    int result = kevent (kq_id, &reg_event, 1, NULL, 0, NULL);
+    if (result != 0)
+    {
+        DNBLogError ("Failed to register kqueue NOTE_EXIT event for pid %i, error: %d.", pid, result);
+        return false;
+    }
+    
+    int ret = ::pthread_create (&thread, NULL, kqueue_thread, (void *)(intptr_t)kq_id);
+    
+    // pthread_create returns 0 if successful
+    if (ret == 0)
+    {
+        ::pthread_detach (thread);
+        return true;
+    }
+    return false;
+}
+#endif // #if USE_KQUEUE
 
 static void *
 waitpid_thread (void *arg)
@@ -161,10 +260,15 @@ waitpid_thread (void *arg)
     DNBProcessSetExitStatus (pid, -1);
     return NULL;
 }
-
 static bool
 spawn_waitpid_thread (pid_t pid)
 {
+#ifdef USE_KQUEUE
+    bool success = spawn_kqueue_thread (pid);
+    if (success)
+        return true;
+#endif
+
     pthread_t thread;
     int ret = ::pthread_create (&thread, NULL, waitpid_thread, (void *)(intptr_t)pid);
     // pthread_create returns 0 if successful
@@ -187,6 +291,7 @@ DNBProcessLaunch (const char *path,
                   bool no_stdio,
                   nub_launch_flavor_t launch_flavor,
                   int disable_aslr,
+                  const char *event_data,
                   char *err_str,
                   size_t err_len)
 {
@@ -229,7 +334,8 @@ DNBProcessLaunch (const char *path,
                                                stderr_path, 
                                                no_stdio, 
                                                launch_flavor, 
-                                               disable_aslr, 
+                                               disable_aslr,
+                                               event_data,
                                                launch_err);
         if (err_str)
         {
@@ -681,6 +787,19 @@ DNBProcessSignal (nub_process_t pid, int
     return false;
 }
 
+nub_bool_t
+DNBProcessSendEvent (nub_process_t pid, const char *event)
+{
+    MachProcessSP procSP;
+    if (GetProcessSP (pid, procSP))
+    {
+        // FIXME: Do something with the error...
+        DNBError send_error;
+        return procSP->SendEvent (event, send_error);
+    }
+    return false;
+}
+
 
 nub_bool_t
 DNBProcessIsAlive (nub_process_t pid)
@@ -733,6 +852,28 @@ DNBProcessSetExitStatus (nub_process_t p
     return false;
 }
 
+const char *
+DNBProcessGetExitInfo (nub_process_t pid)
+{
+    MachProcessSP procSP;
+    if (GetProcessSP (pid, procSP))
+    {
+        return procSP->GetExitInfo();
+    }
+    return NULL;
+}
+
+nub_bool_t
+DNBProcessSetExitInfo (nub_process_t pid, const char *info)
+{
+    MachProcessSP procSP;
+    if (GetProcessSP (pid, procSP))
+    {
+        procSP->SetExitInfo(info);
+        return true;
+    }
+    return false;
+}
 
 const char *
 DNBThreadGetName (nub_process_t pid, nub_thread_t tid)
@@ -2054,8 +2195,9 @@ DNBInitialize()
 #if defined (__i386__) || defined (__x86_64__)
     DNBArchImplI386::Initialize();
     DNBArchImplX86_64::Initialize();
-#elif defined (__arm__)
+#elif defined (__arm__) || defined (__arm64__)
     DNBArchMachARM::Initialize();
+    DNBArchMachARM64::Initialize();
 #endif
 }
 
@@ -2073,6 +2215,8 @@ DNBSetArchitecture (const char *arch)
             return DNBArchProtocol::SetArchitecture (CPU_TYPE_I386);
         else if ((strcasecmp (arch, "x86_64") == 0) || (strcasecmp (arch, "x86_64h") == 0))
             return DNBArchProtocol::SetArchitecture (CPU_TYPE_X86_64);
+        else if (strstr (arch, "arm64") == arch || strstr (arch, "armv8") == arch)
+            return DNBArchProtocol::SetArchitecture (CPU_TYPE_ARM64);
         else if (strstr (arch, "arm") == arch)
             return DNBArchProtocol::SetArchitecture (CPU_TYPE_ARM);
     }

Modified: lldb/trunk/tools/debugserver/source/DNB.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/DNB.h?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/DNB.h (original)
+++ lldb/trunk/tools/debugserver/source/DNB.h Sat Mar 29 13:54:20 2014
@@ -18,6 +18,12 @@
 #include <mach/thread_info.h>
 #include <string>
 
+#define DNB_EXPORT __attribute__((visibility("default")))
+
+#ifndef CPU_TYPE_ARM64
+#define CPU_TYPE_ARM64 ((cpu_type_t) 12 | 0x01000000)
+#endif
+
 typedef bool (*DNBShouldCancelCallback) (void *);
 
 void            DNBInitialize ();
@@ -37,7 +43,8 @@ nub_process_t   DNBProcessLaunch
                                          const char *stderr_path,
                                          bool no_stdio, 
                                          nub_launch_flavor_t launch_flavor, 
-                                         int disable_aslr, 
+                                         int disable_aslr,
+                                         const char *event_data,
                                          char *err_str, 
                                          size_t err_len);
 
@@ -52,43 +59,46 @@ nub_process_t   DNBProcessAttachWait
 //   explicit thread action can be made by making a thread action with a tid of
 //   INVALID_NUB_THREAD. If there is no default action, those threads will
 //   remain stopped.
-nub_bool_t      DNBProcessResume        (nub_process_t pid, const DNBThreadResumeAction *actions, size_t num_actions);
-nub_bool_t      DNBProcessHalt          (nub_process_t pid);
-nub_bool_t      DNBProcessDetach        (nub_process_t pid);
-nub_bool_t      DNBProcessSignal        (nub_process_t pid, int signal);
-nub_bool_t      DNBProcessKill          (nub_process_t pid);
-nub_size_t      DNBProcessMemoryRead    (nub_process_t pid, nub_addr_t addr, nub_size_t size, void *buf);
-nub_size_t      DNBProcessMemoryWrite   (nub_process_t pid, nub_addr_t addr, nub_size_t size, const void *buf);
-nub_addr_t      DNBProcessMemoryAllocate    (nub_process_t pid, nub_size_t size, uint32_t permissions);
-nub_bool_t      DNBProcessMemoryDeallocate  (nub_process_t pid, nub_addr_t addr);
-int             DNBProcessMemoryRegionInfo  (nub_process_t pid, nub_addr_t addr, DNBRegionInfo *region_info);
-std::string     DNBProcessGetProfileData (nub_process_t pid, DNBProfileDataScanType scanType);
-nub_bool_t      DNBProcessSetEnableAsyncProfiling   (nub_process_t pid, nub_bool_t enable, uint64_t interval_usec, DNBProfileDataScanType scan_type);
+nub_bool_t      DNBProcessResume        (nub_process_t pid, const DNBThreadResumeAction *actions, size_t num_actions) DNB_EXPORT;
+nub_bool_t      DNBProcessHalt          (nub_process_t pid) DNB_EXPORT;
+nub_bool_t      DNBProcessDetach        (nub_process_t pid) DNB_EXPORT;
+nub_bool_t      DNBProcessSignal        (nub_process_t pid, int signal) DNB_EXPORT;
+nub_bool_t      DNBProcessKill          (nub_process_t pid) DNB_EXPORT;
+nub_bool_t      DNBProcessSendEvent     (nub_process_t pid, const char *event) DNB_EXPORT;
+nub_size_t      DNBProcessMemoryRead    (nub_process_t pid, nub_addr_t addr, nub_size_t size, void *buf) DNB_EXPORT;
+nub_size_t      DNBProcessMemoryWrite   (nub_process_t pid, nub_addr_t addr, nub_size_t size, const void *buf) DNB_EXPORT;
+nub_addr_t      DNBProcessMemoryAllocate    (nub_process_t pid, nub_size_t size, uint32_t permissions) DNB_EXPORT;
+nub_bool_t      DNBProcessMemoryDeallocate  (nub_process_t pid, nub_addr_t addr) DNB_EXPORT;
+int             DNBProcessMemoryRegionInfo  (nub_process_t pid, nub_addr_t addr, DNBRegionInfo *region_info) DNB_EXPORT;
+std::string     DNBProcessGetProfileData (nub_process_t pid, DNBProfileDataScanType scanType) DNB_EXPORT;
+nub_bool_t      DNBProcessSetEnableAsyncProfiling   (nub_process_t pid, nub_bool_t enable, uint64_t interval_usec, DNBProfileDataScanType scan_type) DNB_EXPORT;
 
 //----------------------------------------------------------------------
 // Process status
 //----------------------------------------------------------------------
-nub_bool_t      DNBProcessIsAlive                       (nub_process_t pid);
-nub_state_t     DNBProcessGetState                      (nub_process_t pid);
-nub_bool_t      DNBProcessGetExitStatus                 (nub_process_t pid, int *status);
-nub_bool_t      DNBProcessSetExitStatus                 (nub_process_t pid, int status);
-nub_size_t      DNBProcessGetNumThreads                 (nub_process_t pid);
-nub_thread_t    DNBProcessGetCurrentThread              (nub_process_t pid);
-nub_thread_t    DNBProcessGetCurrentThreadMachPort      (nub_process_t pid);
-nub_thread_t    DNBProcessSetCurrentThread              (nub_process_t pid, nub_thread_t tid);
-nub_thread_t    DNBProcessGetThreadAtIndex              (nub_process_t pid, nub_size_t thread_idx);
-nub_bool_t      DNBProcessSyncThreadState               (nub_process_t pid, nub_thread_t tid);
-nub_addr_t      DNBProcessGetSharedLibraryInfoAddress   (nub_process_t pid);
-nub_bool_t      DNBProcessSharedLibrariesUpdated        (nub_process_t pid);
-nub_size_t      DNBProcessGetSharedLibraryInfo          (nub_process_t pid, nub_bool_t only_changed, DNBExecutableImageInfo **image_infos);
-nub_bool_t      DNBProcessSetNameToAddressCallback      (nub_process_t pid, DNBCallbackNameToAddress callback, void *baton);
-nub_bool_t      DNBProcessSetSharedLibraryInfoCallback  (nub_process_t pid, DNBCallbackCopyExecutableImageInfos callback, void *baton);
-nub_addr_t      DNBProcessLookupAddress                 (nub_process_t pid, const char *name, const char *shlib);
-nub_size_t      DNBProcessGetAvailableSTDOUT            (nub_process_t pid, char *buf, nub_size_t buf_size);
-nub_size_t      DNBProcessGetAvailableSTDERR            (nub_process_t pid, char *buf, nub_size_t buf_size);
-nub_size_t      DNBProcessGetAvailableProfileData       (nub_process_t pid, char *buf, nub_size_t buf_size);
-nub_size_t      DNBProcessGetStopCount                  (nub_process_t pid);
-uint32_t        DNBProcessGetCPUType                    (nub_process_t pid); 
+nub_bool_t      DNBProcessIsAlive                       (nub_process_t pid) DNB_EXPORT;
+nub_state_t     DNBProcessGetState                      (nub_process_t pid) DNB_EXPORT;
+nub_bool_t      DNBProcessGetExitStatus                 (nub_process_t pid, int *status) DNB_EXPORT;
+nub_bool_t      DNBProcessSetExitStatus                 (nub_process_t pid, int status) DNB_EXPORT;
+const char *    DNBProcessGetExitInfo                   (nub_process_t pid) DNB_EXPORT;
+nub_bool_t      DNBProcessSetExitInfo                   (nub_process_t pid, const char *info) DNB_EXPORT;
+nub_size_t      DNBProcessGetNumThreads                 (nub_process_t pid) DNB_EXPORT;
+nub_thread_t    DNBProcessGetCurrentThread              (nub_process_t pid) DNB_EXPORT;
+nub_thread_t    DNBProcessGetCurrentThreadMachPort      (nub_process_t pid) DNB_EXPORT;
+nub_thread_t    DNBProcessSetCurrentThread              (nub_process_t pid, nub_thread_t tid) DNB_EXPORT;
+nub_thread_t    DNBProcessGetThreadAtIndex              (nub_process_t pid, nub_size_t thread_idx) DNB_EXPORT;
+nub_bool_t      DNBProcessSyncThreadState               (nub_process_t pid, nub_thread_t tid) DNB_EXPORT;
+nub_addr_t      DNBProcessGetSharedLibraryInfoAddress   (nub_process_t pid) DNB_EXPORT;
+nub_bool_t      DNBProcessSharedLibrariesUpdated        (nub_process_t pid) DNB_EXPORT;
+nub_size_t      DNBProcessGetSharedLibraryInfo          (nub_process_t pid, nub_bool_t only_changed, DNBExecutableImageInfo **image_infos) DNB_EXPORT;
+nub_bool_t      DNBProcessSetNameToAddressCallback      (nub_process_t pid, DNBCallbackNameToAddress callback, void *baton) DNB_EXPORT;
+nub_bool_t      DNBProcessSetSharedLibraryInfoCallback  (nub_process_t pid, DNBCallbackCopyExecutableImageInfos callback, void *baton) DNB_EXPORT;
+nub_addr_t      DNBProcessLookupAddress                 (nub_process_t pid, const char *name, const char *shlib) DNB_EXPORT;
+nub_size_t      DNBProcessGetAvailableSTDOUT            (nub_process_t pid, char *buf, nub_size_t buf_size) DNB_EXPORT;
+nub_size_t      DNBProcessGetAvailableSTDERR            (nub_process_t pid, char *buf, nub_size_t buf_size) DNB_EXPORT;
+nub_size_t      DNBProcessGetAvailableProfileData       (nub_process_t pid, char *buf, nub_size_t buf_size) DNB_EXPORT;
+nub_size_t      DNBProcessGetStopCount                  (nub_process_t pid) DNB_EXPORT;
+uint32_t        DNBProcessGetCPUType                    (nub_process_t pid) DNB_EXPORT; 
 
 //----------------------------------------------------------------------
 // Process executable and arguments

Modified: lldb/trunk/tools/debugserver/source/DNBArch.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/DNBArch.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/DNBArch.cpp (original)
+++ lldb/trunk/tools/debugserver/source/DNBArch.cpp Sat Mar 29 13:54:20 2014
@@ -21,18 +21,7 @@
 
 typedef std::map<uint32_t, DNBArchPluginInfo> CPUPluginInfoMap;
 
-//#if defined (__i386__)
-//static uint32_t g_current_cpu_type = CPU_TYPE_I386;
-//#elif defined (__x86_64__)
-//static uint32_t g_current_cpu_type = CPU_TYPE_X86_64;
-#if defined (__i386__) || defined (__x86_64__)
 static uint32_t g_current_cpu_type = 0;
-#elif defined (__arm__) 
-static uint32_t g_current_cpu_type = CPU_TYPE_ARM;
-#else
-static uint32_t g_current_cpu_type = 0;
-#endif
-
 CPUPluginInfoMap g_arch_plugins;
 
 

Modified: lldb/trunk/tools/debugserver/source/DNBArch.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/DNBArch.h?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/DNBArch.h (original)
+++ lldb/trunk/tools/debugserver/source/DNBArch.h Sat Mar 29 13:54:20 2014
@@ -118,6 +118,7 @@ protected:
 
 
 #include "MacOSX/arm/DNBArchImpl.h"
+#include "MacOSX/arm64/DNBArchImplARM64.h"
 #include "MacOSX/i386/DNBArchImplI386.h"
 #include "MacOSX/x86_64/DNBArchImplX86_64.h"
 #include "MacOSX/ppc/DNBArchImpl.h"

Modified: lldb/trunk/tools/debugserver/source/DNBDefs.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/DNBDefs.h?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/DNBDefs.h (original)
+++ lldb/trunk/tools/debugserver/source/DNBDefs.h Sat Mar 29 13:54:20 2014
@@ -23,7 +23,7 @@
 //----------------------------------------------------------------------
 // Define nub_addr_t and the invalid address value from the architecture
 //----------------------------------------------------------------------
-#if defined (__x86_64__) || defined (__ppc64__)
+#if defined (__x86_64__) || defined (__ppc64__) || defined (__arm64__)
 
 //----------------------------------------------------------------------
 // 64 bit address architectures
@@ -90,11 +90,15 @@ typedef enum
 typedef enum
 {
     eLaunchFlavorDefault = 0,
-    eLaunchFlavorPosixSpawn,
-    eLaunchFlavorForkExec,
+    eLaunchFlavorPosixSpawn = 1,
+    eLaunchFlavorForkExec = 2,
 #ifdef WITH_SPRINGBOARD
-    eLaunchFlavorSpringBoard,
+    eLaunchFlavorSpringBoard = 3,
 #endif
+#ifdef WITH_BKS
+    eLaunchFlavorBKS = 4
+#endif
+
 } nub_launch_flavor_t;
 
 #define NUB_STATE_IS_RUNNING(s) ((s) == eStateAttaching ||\

Modified: lldb/trunk/tools/debugserver/source/DNBError.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/DNBError.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/DNBError.cpp (original)
+++ lldb/trunk/tools/debugserver/source/DNBError.cpp Sat Mar 29 13:54:20 2014
@@ -48,6 +48,16 @@ DNBError::AsString() const
             }
             break;
 #endif
+#ifdef WITH_BKS
+        case BackBoard:
+            {
+                // You have to call ObjC routines to get the error string from BackBoardServices.
+                // Not sure I want to make DNBError.cpp an .mm file.  For now just make sure you
+                // pre-populate the error string when you make the DNBError of type BackBoard.
+                m_str.assign("Should have set Backboard error when making the error string.");
+            }
+            break;
+#endif
         default:
             break;
         }

Modified: lldb/trunk/tools/debugserver/source/DNBError.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/DNBError.h?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/DNBError.h (original)
+++ lldb/trunk/tools/debugserver/source/DNBError.h Sat Mar 29 13:54:20 2014
@@ -26,10 +26,13 @@ public:
     typedef enum
     {
         Generic = 0,
-        MachKernel,
-        POSIX
+        MachKernel = 1,
+        POSIX = 2
 #ifdef WITH_SPRINGBOARD
-        , SpringBoard
+        , SpringBoard = 3
+#endif
+#ifdef WITH_BKS
+        , BackBoard = 4
 #endif
     } FlavorType;
 

Modified: lldb/trunk/tools/debugserver/source/MacOSX/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/CMakeLists.txt?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/CMakeLists.txt (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/CMakeLists.txt Sat Mar 29 13:54:20 2014
@@ -1,5 +1,6 @@
 set(LLVM_NO_RTTI 1)
 
+#add_subdirectory(arm64)
 #add_subdirectory(arm)
 add_subdirectory(i386)
 #add_subdirectory(ppc)
@@ -31,8 +32,8 @@ add_lldb_executable(debugserver
   CFData.cpp
   CFString.cpp
   MachException.cpp
-  MachProcess.cpp
-  MachTask.cpp
+  MachProcess.mm
+  MachTask.mm
   MachThread.cpp
   MachThreadList.cpp
   MachVMMemory.cpp

Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachException.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachException.h?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachException.h (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachException.h Sat Mar 29 13:54:20 2014
@@ -82,7 +82,7 @@ public:
         }
         bool IsBreakpoint() const
         {
-            return (exc_type == EXC_BREAKPOINT) || ((exc_type == EXC_SOFTWARE) && exc_data[0] == 1);
+            return (exc_type == EXC_BREAKPOINT || ((exc_type == EXC_SOFTWARE) && exc_data[0] == 1));
         }
         void Dump() const;
         void DumpStopReason() const;

Removed: lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp?rev=205112&view=auto
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp (removed)
@@ -1,2309 +0,0 @@
-//===-- MachProcess.cpp -----------------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//  Created by Greg Clayton on 6/15/07.
-//
-//===----------------------------------------------------------------------===//
-
-#include "DNB.h"
-#include <inttypes.h>
-#include <mach/mach.h>
-#include <signal.h>
-#include <spawn.h>
-#include <sys/fcntl.h>
-#include <sys/types.h>
-#include <sys/ptrace.h>
-#include <sys/stat.h>
-#include <sys/sysctl.h>
-#include <unistd.h>
-#include "MacOSX/CFUtils.h"
-#include "SysSignal.h"
-
-#include <algorithm>
-#include <map>
-
-#include "DNBDataRef.h"
-#include "DNBLog.h"
-#include "DNBThreadResumeActions.h"
-#include "DNBTimer.h"
-#include "MachProcess.h"
-#include "PseudoTerminal.h"
-
-#include "CFBundle.h"
-#include "CFData.h"
-#include "CFString.h"
-
-static CFStringRef CopyBundleIDForPath (const char *app_buncle_path, DNBError &err_str);
-
-#ifdef WITH_SPRINGBOARD
-
-#include <CoreFoundation/CoreFoundation.h>
-#include <SpringBoardServices/SpringBoardServer.h>
-#include <SpringBoardServices/SBSWatchdogAssertion.h>
-
-static bool
-IsSBProcess (nub_process_t pid)
-{
-    CFReleaser<CFArrayRef> appIdsForPID (::SBSCopyDisplayIdentifiersForProcessID(pid));
-    return appIdsForPID.get() != NULL;
-}
-
-#endif
-
-#if 0
-#define DEBUG_LOG(fmt, ...) printf(fmt, ## __VA_ARGS__)
-#else
-#define DEBUG_LOG(fmt, ...)
-#endif
-
-#ifndef MACH_PROCESS_USE_POSIX_SPAWN
-#define MACH_PROCESS_USE_POSIX_SPAWN 1
-#endif
-
-#ifndef _POSIX_SPAWN_DISABLE_ASLR
-#define _POSIX_SPAWN_DISABLE_ASLR       0x0100
-#endif
-
-MachProcess::MachProcess() :
-    m_pid               (0),
-    m_cpu_type          (0),
-    m_child_stdin       (-1),
-    m_child_stdout      (-1),
-    m_child_stderr      (-1),
-    m_path              (),
-    m_args              (),
-    m_task              (this),
-    m_flags             (eMachProcessFlagsNone),
-    m_stdio_thread      (0),
-    m_stdio_mutex       (PTHREAD_MUTEX_RECURSIVE),
-    m_stdout_data       (),
-    m_thread_actions    (),
-    m_profile_enabled   (false),
-    m_profile_interval_usec (0),
-    m_profile_thread    (0),
-    m_profile_data_mutex(PTHREAD_MUTEX_RECURSIVE),
-    m_profile_data      (),
-    m_thread_list        (),
-    m_exception_messages (),
-    m_exception_messages_mutex (PTHREAD_MUTEX_RECURSIVE),
-    m_state             (eStateUnloaded),
-    m_state_mutex       (PTHREAD_MUTEX_RECURSIVE),
-    m_events            (0, kAllEventsMask),
-    m_private_events    (0, kAllEventsMask),
-    m_breakpoints       (),
-    m_watchpoints       (),
-    m_name_to_addr_callback(NULL),
-    m_name_to_addr_baton(NULL),
-    m_image_infos_callback(NULL),
-    m_image_infos_baton(NULL),
-    m_did_exec (false)
-{
-    DNBLogThreadedIf(LOG_PROCESS | LOG_VERBOSE, "%s", __PRETTY_FUNCTION__);
-}
-
-MachProcess::~MachProcess()
-{
-    DNBLogThreadedIf(LOG_PROCESS | LOG_VERBOSE, "%s", __PRETTY_FUNCTION__);
-    Clear();
-}
-
-pid_t
-MachProcess::SetProcessID(pid_t pid)
-{
-    // Free any previous process specific data or resources
-    Clear();
-    // Set the current PID appropriately
-    if (pid == 0)
-        m_pid = ::getpid ();
-    else
-        m_pid = pid;
-    return m_pid;    // Return actualy PID in case a zero pid was passed in
-}
-
-nub_state_t
-MachProcess::GetState()
-{
-    // If any other threads access this we will need a mutex for it
-    PTHREAD_MUTEX_LOCKER(locker, m_state_mutex);
-    return m_state;
-}
-
-const char *
-MachProcess::ThreadGetName(nub_thread_t tid)
-{
-    return m_thread_list.GetName(tid);
-}
-
-nub_state_t
-MachProcess::ThreadGetState(nub_thread_t tid)
-{
-    return m_thread_list.GetState(tid);
-}
-
-
-nub_size_t
-MachProcess::GetNumThreads () const
-{
-    return m_thread_list.NumThreads();
-}
-
-nub_thread_t
-MachProcess::GetThreadAtIndex (nub_size_t thread_idx) const
-{
-    return m_thread_list.ThreadIDAtIndex(thread_idx);
-}
-
-nub_thread_t
-MachProcess::GetThreadIDForMachPortNumber (thread_t mach_port_number) const
-{
-    return m_thread_list.GetThreadIDByMachPortNumber (mach_port_number);
-}
-
-nub_bool_t
-MachProcess::SyncThreadState (nub_thread_t tid)
-{
-    MachThreadSP thread_sp(m_thread_list.GetThreadByID(tid));
-    if (!thread_sp)
-        return false;
-    kern_return_t kret = ::thread_abort_safely(thread_sp->MachPortNumber());
-    DNBLogThreadedIf (LOG_THREAD, "thread = 0x%8.8" PRIx32 " calling thread_abort_safely (tid) => %u (GetGPRState() for stop_count = %u)", thread_sp->MachPortNumber(), kret, thread_sp->Process()->StopCount());
-
-    if (kret == KERN_SUCCESS)
-        return true;
-    else
-        return false;
-    
-}
-
-nub_thread_t
-MachProcess::GetCurrentThread ()
-{
-    return m_thread_list.CurrentThreadID();
-}
-
-nub_thread_t
-MachProcess::GetCurrentThreadMachPort ()
-{
-    return m_thread_list.GetMachPortNumberByThreadID(m_thread_list.CurrentThreadID());
-}
-
-nub_thread_t
-MachProcess::SetCurrentThread(nub_thread_t tid)
-{
-    return m_thread_list.SetCurrentThread(tid);
-}
-
-bool
-MachProcess::GetThreadStoppedReason(nub_thread_t tid, struct DNBThreadStopInfo *stop_info)
-{
-    if (m_thread_list.GetThreadStoppedReason(tid, stop_info))
-    {
-        if (m_did_exec)
-            stop_info->reason = eStopTypeExec;
-        return true;
-    }
-    return false;
-}
-
-void
-MachProcess::DumpThreadStoppedReason(nub_thread_t tid) const
-{
-    return m_thread_list.DumpThreadStoppedReason(tid);
-}
-
-const char *
-MachProcess::GetThreadInfo(nub_thread_t tid) const
-{
-    return m_thread_list.GetThreadInfo(tid);
-}
-
-uint32_t
-MachProcess::GetCPUType ()
-{
-    if (m_cpu_type == 0 && m_pid != 0)
-        m_cpu_type = MachProcess::GetCPUTypeForLocalProcess (m_pid);
-    return m_cpu_type;
-}
-
-const DNBRegisterSetInfo *
-MachProcess::GetRegisterSetInfo (nub_thread_t tid, nub_size_t *num_reg_sets) const
-{
-    MachThreadSP thread_sp (m_thread_list.GetThreadByID (tid));
-    if (thread_sp)
-    {
-        DNBArchProtocol *arch = thread_sp->GetArchProtocol();
-        if (arch)
-            return arch->GetRegisterSetInfo (num_reg_sets);
-    }
-    *num_reg_sets = 0;
-    return NULL;
-}
-
-bool
-MachProcess::GetRegisterValue ( nub_thread_t tid, uint32_t set, uint32_t reg, DNBRegisterValue *value ) const
-{
-    return m_thread_list.GetRegisterValue(tid, set, reg, value);
-}
-
-bool
-MachProcess::SetRegisterValue ( nub_thread_t tid, uint32_t set, uint32_t reg, const DNBRegisterValue *value ) const
-{
-    return m_thread_list.SetRegisterValue(tid, set, reg, value);
-}
-
-void
-MachProcess::SetState(nub_state_t new_state)
-{
-    // If any other threads access this we will need a mutex for it
-    uint32_t event_mask = 0;
-
-    // Scope for mutex locker
-    {
-        PTHREAD_MUTEX_LOCKER(locker, m_state_mutex);
-        const nub_state_t old_state = m_state;
-
-        if (old_state == eStateExited)
-        {
-            DNBLogThreadedIf(LOG_PROCESS, "MachProcess::SetState(%s) ignoring new state since current state is exited", DNBStateAsString(new_state));
-        }
-        else if (old_state == new_state)
-        {
-            DNBLogThreadedIf(LOG_PROCESS, "MachProcess::SetState(%s) ignoring redundant state change...", DNBStateAsString(new_state));
-        }
-        else
-        {
-            if (NUB_STATE_IS_STOPPED(new_state))
-                event_mask = eEventProcessStoppedStateChanged;
-            else
-                event_mask = eEventProcessRunningStateChanged;
-
-            DNBLogThreadedIf(LOG_PROCESS, "MachProcess::SetState(%s) upating state (previous state was %s), event_mask = 0x%8.8x", DNBStateAsString(new_state), DNBStateAsString(old_state), event_mask);
-
-            m_state = new_state;
-            if (new_state == eStateStopped)
-                m_stop_count++;
-        }
-    }
-
-    if (event_mask != 0)
-    {
-        m_events.SetEvents (event_mask);
-        m_private_events.SetEvents (event_mask);
-        if (event_mask == eEventProcessStoppedStateChanged)
-            m_private_events.ResetEvents (eEventProcessRunningStateChanged);
-        else
-            m_private_events.ResetEvents (eEventProcessStoppedStateChanged);
-
-        // Wait for the event bit to reset if a reset ACK is requested
-        m_events.WaitForResetAck(event_mask);
-    }
-
-}
-
-void
-MachProcess::Clear(bool detaching)
-{
-    // Clear any cached thread list while the pid and task are still valid
-
-    m_task.Clear();
-    // Now clear out all member variables
-    m_pid = INVALID_NUB_PROCESS;
-    if (!detaching)
-        CloseChildFileDescriptors();
-        
-    m_path.clear();
-    m_args.clear();
-    SetState(eStateUnloaded);
-    m_flags = eMachProcessFlagsNone;
-    m_stop_count = 0;
-    m_thread_list.Clear();
-    {
-        PTHREAD_MUTEX_LOCKER(locker, m_exception_messages_mutex);
-        m_exception_messages.clear();
-    }
-    if (m_profile_thread)
-    {
-        pthread_join(m_profile_thread, NULL);
-        m_profile_thread = NULL;
-    }
-}
-
-
-bool
-MachProcess::StartSTDIOThread()
-{
-    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::%s ( )", __FUNCTION__);
-    // Create the thread that watches for the child STDIO
-    return ::pthread_create (&m_stdio_thread, NULL, MachProcess::STDIOThread, this) == 0;
-}
-
-void
-MachProcess::SetEnableAsyncProfiling(bool enable, uint64_t interval_usec, DNBProfileDataScanType scan_type)
-{
-    m_profile_enabled = enable;
-    m_profile_interval_usec = interval_usec;
-    m_profile_scan_type = scan_type;
-    
-    if (m_profile_enabled && (m_profile_thread == NULL))
-    {
-        StartProfileThread();
-    }
-    else if (!m_profile_enabled && m_profile_thread)
-    {
-        pthread_join(m_profile_thread, NULL);
-        m_profile_thread = NULL;
-    }
-}
-
-bool
-MachProcess::StartProfileThread()
-{
-    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::%s ( )", __FUNCTION__);
-    // Create the thread that profiles the inferior and reports back if enabled
-    return ::pthread_create (&m_profile_thread, NULL, MachProcess::ProfileThread, this) == 0;
-}
-
-
-nub_addr_t
-MachProcess::LookupSymbol(const char *name, const char *shlib)
-{
-    if (m_name_to_addr_callback != NULL && name && name[0])
-        return m_name_to_addr_callback(ProcessID(), name, shlib, m_name_to_addr_baton);
-    return INVALID_NUB_ADDRESS;
-}
-
-bool
-MachProcess::Resume (const DNBThreadResumeActions& thread_actions)
-{
-    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Resume ()");
-    nub_state_t state = GetState();
-
-    if (CanResume(state))
-    {
-        m_thread_actions = thread_actions;
-        PrivateResume();
-        return true;
-    }
-    else if (state == eStateRunning)
-    {
-        DNBLog("Resume() - task 0x%x is already running, ignoring...", m_task.TaskPort());
-        return true;
-    }
-    DNBLog("Resume() - task 0x%x has state %s, can't continue...", m_task.TaskPort(), DNBStateAsString(state));
-    return false;
-}
-
-bool
-MachProcess::Kill (const struct timespec *timeout_abstime)
-{
-    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Kill ()");
-    nub_state_t state = DoSIGSTOP(true, false, NULL);
-    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Kill() DoSIGSTOP() state = %s", DNBStateAsString(state));
-    errno = 0;
-    DNBLog ("Sending ptrace PT_KILL to terminate inferior process.");
-    ::ptrace (PT_KILL, m_pid, 0, 0);
-    DNBError err;
-    err.SetErrorToErrno();
-    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Kill() DoSIGSTOP() ::ptrace (PT_KILL, pid=%u, 0, 0) => 0x%8.8x (%s)", m_pid, err.Error(), err.AsString());
-    m_thread_actions = DNBThreadResumeActions (eStateRunning, 0);
-    PrivateResume ();
-    
-    // Try and reap the process without touching our m_events since
-    // we want the code above this to still get the eStateExited event
-    const uint32_t reap_timeout_usec = 1000000;    // Wait 1 second and try to reap the process
-    const uint32_t reap_interval_usec = 10000;  //
-    uint32_t reap_time_elapsed;
-    for (reap_time_elapsed = 0;
-         reap_time_elapsed < reap_timeout_usec;
-         reap_time_elapsed += reap_interval_usec)
-    {
-        if (GetState() == eStateExited)
-            break;
-        usleep(reap_interval_usec);
-    }
-    DNBLog ("Waited %u ms for process to be reaped (state = %s)", reap_time_elapsed/1000, DNBStateAsString(GetState()));
-    return true;
-}
-
-bool
-MachProcess::Signal (int signal, const struct timespec *timeout_abstime)
-{
-    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Signal (signal = %d, timeout = %p)", signal, timeout_abstime);
-    nub_state_t state = GetState();
-    if (::kill (ProcessID(), signal) == 0)
-    {
-        // If we were running and we have a timeout, wait for the signal to stop
-        if (IsRunning(state) && timeout_abstime)
-        {
-            DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Signal (signal = %d, timeout = %p) waiting for signal to stop process...", signal, timeout_abstime);
-            m_private_events.WaitForSetEvents(eEventProcessStoppedStateChanged, timeout_abstime);
-            state = GetState();
-            DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Signal (signal = %d, timeout = %p) state = %s", signal, timeout_abstime, DNBStateAsString(state));
-            return !IsRunning (state);
-        }
-        DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Signal (signal = %d, timeout = %p) not waiting...", signal, timeout_abstime);
-        return true;
-    }
-    DNBError err(errno, DNBError::POSIX);
-    err.LogThreadedIfError("kill (pid = %d, signo = %i)", ProcessID(), signal);
-    return false;
-
-}
-
-nub_state_t
-MachProcess::DoSIGSTOP (bool clear_bps_and_wps, bool allow_running, uint32_t *thread_idx_ptr)
-{
-    nub_state_t state = GetState();
-    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::DoSIGSTOP() state = %s", DNBStateAsString (state));
-
-    if (!IsRunning(state))
-    {
-        if (clear_bps_and_wps)
-        {
-            DisableAllBreakpoints (true);
-            DisableAllWatchpoints (true);
-            clear_bps_and_wps = false;
-        }
-
-        // If we already have a thread stopped due to a SIGSTOP, we don't have
-        // to do anything...
-        uint32_t thread_idx = m_thread_list.GetThreadIndexForThreadStoppedWithSignal (SIGSTOP);
-        if (thread_idx_ptr)
-            *thread_idx_ptr = thread_idx;
-        if (thread_idx != UINT32_MAX)
-            return GetState();
-
-        // No threads were stopped with a SIGSTOP, we need to run and halt the
-        // process with a signal
-        DNBLogThreadedIf(LOG_PROCESS, "MachProcess::DoSIGSTOP() state = %s -- resuming process", DNBStateAsString (state));
-        if (allow_running)
-            m_thread_actions = DNBThreadResumeActions (eStateRunning, 0);
-        else
-            m_thread_actions = DNBThreadResumeActions (eStateSuspended, 0);
-            
-        PrivateResume ();
-
-        // Reset the event that says we were indeed running
-        m_events.ResetEvents(eEventProcessRunningStateChanged);
-        state = GetState();
-    }
-
-    // We need to be stopped in order to be able to detach, so we need
-    // to send ourselves a SIGSTOP
-
-    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::DoSIGSTOP() state = %s -- sending SIGSTOP", DNBStateAsString (state));
-    struct timespec sigstop_timeout;
-    DNBTimer::OffsetTimeOfDay(&sigstop_timeout, 2, 0);
-    Signal (SIGSTOP, &sigstop_timeout);
-    if (clear_bps_and_wps)
-    {
-        DisableAllBreakpoints (true);
-        DisableAllWatchpoints (true);
-        //clear_bps_and_wps = false;
-    }
-    uint32_t thread_idx = m_thread_list.GetThreadIndexForThreadStoppedWithSignal (SIGSTOP);
-    if (thread_idx_ptr)
-        *thread_idx_ptr = thread_idx;
-    return GetState();
-}
-
-bool
-MachProcess::Detach()
-{
-    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Detach()");
-
-    uint32_t thread_idx = UINT32_MAX;
-    nub_state_t state = DoSIGSTOP(true, true, &thread_idx);
-    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Detach() DoSIGSTOP() returned %s", DNBStateAsString(state));
-
-    {
-        m_thread_actions.Clear();
-        DNBThreadResumeAction thread_action;
-        thread_action.tid = m_thread_list.ThreadIDAtIndex (thread_idx);
-        thread_action.state = eStateRunning;
-        thread_action.signal = -1;
-        thread_action.addr = INVALID_NUB_ADDRESS;
-        
-        m_thread_actions.Append (thread_action);
-        m_thread_actions.SetDefaultThreadActionIfNeeded (eStateRunning, 0);
-        
-        PTHREAD_MUTEX_LOCKER (locker, m_exception_messages_mutex);
-
-        ReplyToAllExceptions ();
-
-    }
-
-    m_task.ShutDownExcecptionThread();
-
-    // Detach from our process
-    errno = 0;
-    nub_process_t pid = m_pid;
-    int ret = ::ptrace (PT_DETACH, pid, (caddr_t)1, 0);
-    DNBError err(errno, DNBError::POSIX);
-    if (DNBLogCheckLogBit(LOG_PROCESS) || err.Fail() || (ret != 0))
-        err.LogThreaded("::ptrace (PT_DETACH, %u, (caddr_t)1, 0)", pid);
-
-    // Resume our task
-    m_task.Resume();
-
-    // NULL our task out as we have already retored all exception ports
-    m_task.Clear();
-
-    // Clear out any notion of the process we once were
-    const bool detaching = true;
-    Clear(detaching);
-
-    SetState(eStateDetached);
-
-    return true;
-}
-
-//----------------------------------------------------------------------
-// ReadMemory from the MachProcess level will always remove any software
-// breakpoints from the memory buffer before returning. If you wish to
-// read memory and see those traps, read from the MachTask
-// (m_task.ReadMemory()) as that version will give you what is actually
-// in inferior memory.
-//----------------------------------------------------------------------
-nub_size_t
-MachProcess::ReadMemory (nub_addr_t addr, nub_size_t size, void *buf)
-{
-    // We need to remove any current software traps (enabled software
-    // breakpoints) that we may have placed in our tasks memory.
-
-    // First just read the memory as is
-    nub_size_t bytes_read = m_task.ReadMemory(addr, size, buf);
-
-    // Then place any opcodes that fall into this range back into the buffer
-    // before we return this to callers.
-    if (bytes_read > 0)
-        m_breakpoints.RemoveTrapsFromBuffer (addr, bytes_read, buf);
-    return bytes_read;
-}
-
-//----------------------------------------------------------------------
-// WriteMemory from the MachProcess level will always write memory around
-// any software breakpoints. Any software breakpoints will have their
-// opcodes modified if they are enabled. Any memory that doesn't overlap
-// with software breakpoints will be written to. If you wish to write to
-// inferior memory without this interference, then write to the MachTask
-// (m_task.WriteMemory()) as that version will always modify inferior
-// memory.
-//----------------------------------------------------------------------
-nub_size_t
-MachProcess::WriteMemory (nub_addr_t addr, nub_size_t size, const void *buf)
-{
-    // We need to write any data that would go where any current software traps
-    // (enabled software breakpoints) any software traps (breakpoints) that we
-    // may have placed in our tasks memory.
-
-    std::vector<DNBBreakpoint *> bps;
-    
-    const size_t num_bps = m_breakpoints.FindBreakpointsThatOverlapRange(addr, size, bps);
-    if (num_bps == 0)
-        return m_task.WriteMemory(addr, size, buf);
-
-    nub_size_t bytes_written = 0;
-    nub_addr_t intersect_addr;
-    nub_size_t intersect_size;
-    nub_size_t opcode_offset;
-    const uint8_t *ubuf = (const uint8_t *)buf;
-
-    for (size_t i=0; i<num_bps; ++i)
-    {
-        DNBBreakpoint *bp = bps[i];
-
-        const bool intersects = bp->IntersectsRange(addr, size, &intersect_addr, &intersect_size, &opcode_offset);
-        assert(intersects);
-        assert(addr <= intersect_addr && intersect_addr < addr + size);
-        assert(addr < intersect_addr + intersect_size && intersect_addr + intersect_size <= addr + size);
-        assert(opcode_offset + intersect_size <= bp->ByteSize());
-        
-        // Check for bytes before this breakpoint
-        const nub_addr_t curr_addr = addr + bytes_written;
-        if (intersect_addr > curr_addr)
-        {
-            // There are some bytes before this breakpoint that we need to
-            // just write to memory
-            nub_size_t curr_size = intersect_addr - curr_addr;
-            nub_size_t curr_bytes_written = m_task.WriteMemory(curr_addr, curr_size, ubuf + bytes_written);
-            bytes_written += curr_bytes_written;
-            if (curr_bytes_written != curr_size)
-            {
-                // We weren't able to write all of the requested bytes, we
-                // are done looping and will return the number of bytes that
-                // we have written so far.
-                break;
-            }
-        }
-        
-        // Now write any bytes that would cover up any software breakpoints
-        // directly into the breakpoint opcode buffer
-        ::memcpy(bp->SavedOpcodeBytes() + opcode_offset, ubuf + bytes_written, intersect_size);
-        bytes_written += intersect_size;
-    }
-    
-    // Write any remaining bytes after the last breakpoint if we have any left
-    if (bytes_written < size)
-        bytes_written += m_task.WriteMemory(addr + bytes_written, size - bytes_written, ubuf + bytes_written);
-    
-    return bytes_written;
-}
-
-void
-MachProcess::ReplyToAllExceptions ()
-{
-    PTHREAD_MUTEX_LOCKER(locker, m_exception_messages_mutex);
-    if (m_exception_messages.empty() == false)
-    {
-        MachException::Message::iterator pos;
-        MachException::Message::iterator begin = m_exception_messages.begin();
-        MachException::Message::iterator end = m_exception_messages.end();
-        for (pos = begin; pos != end; ++pos)
-        {
-            DNBLogThreadedIf(LOG_EXCEPTIONS, "Replying to exception %u...", (uint32_t)std::distance(begin, pos));
-            int thread_reply_signal = 0;
-
-            nub_thread_t tid = m_thread_list.GetThreadIDByMachPortNumber (pos->state.thread_port);
-            const DNBThreadResumeAction *action = NULL;
-            if (tid != INVALID_NUB_THREAD)
-            {
-                action = m_thread_actions.GetActionForThread (tid, false);
-            }
-
-            if (action)
-            {
-                thread_reply_signal = action->signal;
-                if (thread_reply_signal)
-                    m_thread_actions.SetSignalHandledForThread (tid);
-            }
-
-            DNBError err (pos->Reply(this, thread_reply_signal));
-            if (DNBLogCheckLogBit(LOG_EXCEPTIONS))
-                err.LogThreadedIfError("Error replying to exception");
-        }
-
-        // Erase all exception message as we should have used and replied
-        // to them all already.
-        m_exception_messages.clear();
-    }
-}
-void
-MachProcess::PrivateResume ()
-{
-    PTHREAD_MUTEX_LOCKER (locker, m_exception_messages_mutex);
-
-    ReplyToAllExceptions ();
-//    bool stepOverBreakInstruction = step;
-
-    // Let the thread prepare to resume and see if any threads want us to
-    // step over a breakpoint instruction (ProcessWillResume will modify
-    // the value of stepOverBreakInstruction).
-    m_thread_list.ProcessWillResume (this, m_thread_actions);
-
-    // Set our state accordingly
-    if (m_thread_actions.NumActionsWithState(eStateStepping))
-        SetState (eStateStepping);
-    else
-        SetState (eStateRunning);
-
-    // Now resume our task.
-    m_task.Resume();
-}
-
-DNBBreakpoint *
-MachProcess::CreateBreakpoint(nub_addr_t addr, nub_size_t length, bool hardware)
-{
-    DNBLogThreadedIf(LOG_BREAKPOINTS, "MachProcess::CreateBreakpoint ( addr = 0x%8.8llx, length = %llu, hardware = %i)", (uint64_t)addr, (uint64_t)length, hardware);
-
-    DNBBreakpoint *bp = m_breakpoints.FindByAddress(addr);
-    if (bp)
-        bp->Retain();
-    else
-        bp =  m_breakpoints.Add(addr, length, hardware);
-
-    if (EnableBreakpoint(addr))
-    {
-        DNBLogThreadedIf(LOG_BREAKPOINTS, "MachProcess::CreateBreakpoint ( addr = 0x%8.8llx, length = %llu) => %p", (uint64_t)addr, (uint64_t)length, bp);
-        return bp;
-    }
-    else if (bp->Release() == 0)
-    {
-        m_breakpoints.Remove(addr);
-    }
-    // We failed to enable the breakpoint
-    return NULL;
-}
-
-DNBBreakpoint *
-MachProcess::CreateWatchpoint(nub_addr_t addr, nub_size_t length, uint32_t watch_flags, bool hardware)
-{
-    DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::CreateWatchpoint ( addr = 0x%8.8llx, length = %llu, flags = 0x%8.8x, hardware = %i)", (uint64_t)addr, (uint64_t)length, watch_flags, hardware);
-
-    DNBBreakpoint *wp = m_watchpoints.FindByAddress(addr);
-    // since the Z packets only send an address, we can only have one watchpoint at
-    // an address. If there is already one, we must refuse to create another watchpoint
-    if (wp)
-        return NULL;
-    
-    wp = m_watchpoints.Add(addr, length, hardware);
-    wp->SetIsWatchpoint(watch_flags);
-
-    if (EnableWatchpoint(addr))
-    {
-        DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::CreateWatchpoint ( addr = 0x%8.8llx, length = %llu) => %p", (uint64_t)addr, (uint64_t)length, wp);
-        return wp;
-    }
-    else
-    {
-        DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::CreateWatchpoint ( addr = 0x%8.8llx, length = %llu) => FAILED", (uint64_t)addr, (uint64_t)length);
-        m_watchpoints.Remove(addr);
-    }
-    // We failed to enable the watchpoint
-    return NULL;
-}
-
-void
-MachProcess::DisableAllBreakpoints (bool remove)
-{
-    DNBLogThreadedIf(LOG_BREAKPOINTS, "MachProcess::%s (remove = %d )", __FUNCTION__, remove);
-    
-    m_breakpoints.DisableAllBreakpoints (this);
-    
-    if (remove)
-        m_breakpoints.RemoveDisabled();
-}
-
-void
-MachProcess::DisableAllWatchpoints(bool remove)
-{
-    DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::%s (remove = %d )", __FUNCTION__, remove);
-    
-    m_watchpoints.DisableAllWatchpoints(this);
-    
-    if (remove)
-        m_watchpoints.RemoveDisabled();
-}
-
-bool
-MachProcess::DisableBreakpoint(nub_addr_t addr, bool remove)
-{
-    DNBBreakpoint *bp = m_breakpoints.FindByAddress(addr);
-    if (bp)
-    {
-        // After "exec" we might end up with a bunch of breakpoints that were disabled
-        // manually, just ignore them
-        if (!bp->IsEnabled())
-        {
-            // Breakpoint might have been disabled by an exec
-            if (remove && bp->Release() == 0)
-            {
-                m_thread_list.NotifyBreakpointChanged(bp);
-                m_breakpoints.Remove(addr);
-            }
-            return true;
-        }
-
-        // We have multiple references to this breakpoint, decrement the ref count
-        // and if it isn't zero, then return true;
-        if (remove && bp->Release() > 0)
-            return true;
-
-        DNBLogThreadedIf(LOG_BREAKPOINTS | LOG_VERBOSE, "MachProcess::DisableBreakpoint ( addr = 0x%8.8llx, remove = %d )", (uint64_t)addr, remove);
-
-        if (bp->IsHardware())
-        {
-            bool hw_disable_result = m_thread_list.DisableHardwareBreakpoint (bp);
-
-            if (hw_disable_result == true)
-            {
-                bp->SetEnabled(false);
-                // Let the thread list know that a breakpoint has been modified
-                if (remove)
-                {
-                    m_thread_list.NotifyBreakpointChanged(bp);
-                    m_breakpoints.Remove(addr);
-                }
-                DNBLogThreadedIf(LOG_BREAKPOINTS, "MachProcess::DisableBreakpoint ( addr = 0x%8.8llx, remove = %d ) (hardware) => success", (uint64_t)addr, remove);
-                return true;
-            }
-
-            return false;
-        }
-
-        const nub_size_t break_op_size = bp->ByteSize();
-        assert (break_op_size > 0);
-        const uint8_t * const break_op = DNBArchProtocol::GetBreakpointOpcode (bp->ByteSize());
-        if (break_op_size > 0)
-        {
-            // Clear a software breakoint instruction
-            uint8_t curr_break_op[break_op_size];
-            bool break_op_found = false;
-
-            // Read the breakpoint opcode
-            if (m_task.ReadMemory(addr, break_op_size, curr_break_op) == break_op_size)
-            {
-                bool verify = false;
-                if (bp->IsEnabled())
-                {
-                    // Make sure we have the a breakpoint opcode exists at this address
-                    if (memcmp(curr_break_op, break_op, break_op_size) == 0)
-                    {
-                        break_op_found = true;
-                        // We found a valid breakpoint opcode at this address, now restore
-                        // the saved opcode.
-                        if (m_task.WriteMemory(addr, break_op_size, bp->SavedOpcodeBytes()) == break_op_size)
-                        {
-                            verify = true;
-                        }
-                        else
-                        {
-                            DNBLogError("MachProcess::DisableBreakpoint ( addr = 0x%8.8llx, remove = %d ) memory write failed when restoring original opcode", (uint64_t)addr, remove);
-                        }
-                    }
-                    else
-                    {
-                        DNBLogWarning("MachProcess::DisableBreakpoint ( addr = 0x%8.8llx, remove = %d ) expected a breakpoint opcode but didn't find one.", (uint64_t)addr, remove);
-                        // Set verify to true and so we can check if the original opcode has already been restored
-                        verify = true;
-                    }
-                }
-                else
-                {
-                    DNBLogThreadedIf(LOG_BREAKPOINTS | LOG_VERBOSE, "MachProcess::DisableBreakpoint ( addr = 0x%8.8llx, remove = %d ) is not enabled", (uint64_t)addr, remove);
-                    // Set verify to true and so we can check if the original opcode is there
-                    verify = true;
-                }
-
-                if (verify)
-                {
-                    uint8_t verify_opcode[break_op_size];
-                    // Verify that our original opcode made it back to the inferior
-                    if (m_task.ReadMemory(addr, break_op_size, verify_opcode) == break_op_size)
-                    {
-                        // compare the memory we just read with the original opcode
-                        if (memcmp(bp->SavedOpcodeBytes(), verify_opcode, break_op_size) == 0)
-                        {
-                            // SUCCESS
-                            bp->SetEnabled(false);
-                            // Let the thread list know that a breakpoint has been modified
-                            if (remove && bp->Release() == 0)
-                            {
-                                m_thread_list.NotifyBreakpointChanged(bp);
-                                m_breakpoints.Remove(addr);
-                            }
-                            DNBLogThreadedIf(LOG_BREAKPOINTS, "MachProcess::DisableBreakpoint ( addr = 0x%8.8llx, remove = %d ) => success", (uint64_t)addr, remove);
-                            return true;
-                        }
-                        else
-                        {
-                            if (break_op_found)
-                                DNBLogError("MachProcess::DisableBreakpoint ( addr = 0x%8.8llx, remove = %d ) : failed to restore original opcode", (uint64_t)addr, remove);
-                            else
-                                DNBLogError("MachProcess::DisableBreakpoint ( addr = 0x%8.8llx, remove = %d ) : opcode changed", (uint64_t)addr, remove);
-                        }
-                    }
-                    else
-                    {
-                        DNBLogWarning("MachProcess::DisableBreakpoint: unable to disable breakpoint 0x%8.8llx", (uint64_t)addr);
-                    }
-                }
-            }
-            else
-            {
-                DNBLogWarning("MachProcess::DisableBreakpoint: unable to read memory at 0x%8.8llx", (uint64_t)addr);
-            }
-        }
-    }
-    else
-    {
-        DNBLogError("MachProcess::DisableBreakpoint ( addr = 0x%8.8llx, remove = %d ) invalid breakpoint address", (uint64_t)addr, remove);
-    }
-    return false;
-}
-
-bool
-MachProcess::DisableWatchpoint(nub_addr_t addr, bool remove)
-{
-    DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::%s(addr = 0x%8.8llx, remove = %d)", __FUNCTION__, (uint64_t)addr, remove);
-    DNBBreakpoint *wp = m_watchpoints.FindByAddress(addr);
-    if (wp)
-    {
-        // If we have multiple references to a watchpoint, removing the watchpoint shouldn't clear it
-        if (remove && wp->Release() > 0)
-            return true;
-
-        nub_addr_t addr = wp->Address();
-        DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::DisableWatchpoint ( addr = 0x%8.8llx, remove = %d )", (uint64_t)addr, remove);
-
-        if (wp->IsHardware())
-        {
-            bool hw_disable_result = m_thread_list.DisableHardwareWatchpoint (wp);
-
-            if (hw_disable_result == true)
-            {
-                wp->SetEnabled(false);
-                if (remove)
-                    m_watchpoints.Remove(addr);
-                DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::Disablewatchpoint ( addr = 0x%8.8llx, remove = %d ) (hardware) => success", (uint64_t)addr, remove);
-                return true;
-            }
-        }
-
-        // TODO: clear software watchpoints if we implement them
-    }
-    else
-    {
-        DNBLogError("MachProcess::DisableWatchpoint ( addr = 0x%8.8llx, remove = %d ) invalid watchpoint ID", (uint64_t)addr, remove);
-    }
-    return false;
-}
-
-
-uint32_t
-MachProcess::GetNumSupportedHardwareWatchpoints () const
-{
-    return m_thread_list.NumSupportedHardwareWatchpoints();
-}
-
-bool
-MachProcess::EnableBreakpoint(nub_addr_t addr)
-{
-    DNBLogThreadedIf(LOG_BREAKPOINTS, "MachProcess::EnableBreakpoint ( addr = 0x%8.8llx )", (uint64_t)addr);
-    DNBBreakpoint *bp = m_breakpoints.FindByAddress(addr);
-    if (bp)
-    {
-        if (bp->IsEnabled())
-        {
-            DNBLogWarning("MachProcess::EnableBreakpoint ( addr = 0x%8.8llx ): breakpoint already enabled.", (uint64_t)addr);
-            return true;
-        }
-        else
-        {
-            if (bp->HardwarePreferred())
-            {
-                bp->SetHardwareIndex(m_thread_list.EnableHardwareBreakpoint(bp));
-                if (bp->IsHardware())
-                {
-                    bp->SetEnabled(true);
-                    return true;
-                }
-            }
-
-            const nub_size_t break_op_size = bp->ByteSize();
-            assert (break_op_size != 0);
-            const uint8_t * const break_op = DNBArchProtocol::GetBreakpointOpcode (break_op_size);
-            if (break_op_size > 0)
-            {
-                // Save the original opcode by reading it
-                if (m_task.ReadMemory(addr, break_op_size, bp->SavedOpcodeBytes()) == break_op_size)
-                {
-                    // Write a software breakpoint in place of the original opcode
-                    if (m_task.WriteMemory(addr, break_op_size, break_op) == break_op_size)
-                    {
-                        uint8_t verify_break_op[4];
-                        if (m_task.ReadMemory(addr, break_op_size, verify_break_op) == break_op_size)
-                        {
-                            if (memcmp(break_op, verify_break_op, break_op_size) == 0)
-                            {
-                                bp->SetEnabled(true);
-                                // Let the thread list know that a breakpoint has been modified
-                                m_thread_list.NotifyBreakpointChanged(bp);
-                                DNBLogThreadedIf(LOG_BREAKPOINTS, "MachProcess::EnableBreakpoint ( addr = 0x%8.8llx ) : SUCCESS.", (uint64_t)addr);
-                                return true;
-                            }
-                            else
-                            {
-                                DNBLogError("MachProcess::EnableBreakpoint ( addr = 0x%8.8llx ): breakpoint opcode verification failed.", (uint64_t)addr);
-                            }
-                        }
-                        else
-                        {
-                            DNBLogError("MachProcess::EnableBreakpoint ( addr = 0x%8.8llx ): unable to read memory to verify breakpoint opcode.", (uint64_t)addr);
-                        }
-                    }
-                    else
-                    {
-                        DNBLogError("MachProcess::EnableBreakpoint ( addr = 0x%8.8llx ): unable to write breakpoint opcode to memory.", (uint64_t)addr);
-                    }
-                }
-                else
-                {
-                    DNBLogError("MachProcess::EnableBreakpoint ( addr = 0x%8.8llx ): unable to read memory at breakpoint address.", (uint64_t)addr);
-                }
-            }
-            else
-            {
-                DNBLogError("MachProcess::EnableBreakpoint ( addr = 0x%8.8llx ) no software breakpoint opcode for current architecture.", (uint64_t)addr);
-            }
-        }
-    }
-    return false;
-}
-
-bool
-MachProcess::EnableWatchpoint(nub_addr_t addr)
-{
-    DNBLogThreadedIf(LOG_WATCHPOINTS, "MachProcess::EnableWatchpoint(addr = 0x%8.8llx)", (uint64_t)addr);
-    DNBBreakpoint *wp = m_watchpoints.FindByAddress(addr);
-    if (wp)
-    {
-        nub_addr_t addr = wp->Address();
-        if (wp->IsEnabled())
-        {
-            DNBLogWarning("MachProcess::EnableWatchpoint(addr = 0x%8.8llx): watchpoint already enabled.", (uint64_t)addr);
-            return true;
-        }
-        else
-        {
-            // Currently only try and set hardware watchpoints.
-            wp->SetHardwareIndex(m_thread_list.EnableHardwareWatchpoint(wp));
-            if (wp->IsHardware())
-            {
-                wp->SetEnabled(true);
-                return true;
-            }
-            // TODO: Add software watchpoints by doing page protection tricks.
-        }
-    }
-    return false;
-}
-
-// Called by the exception thread when an exception has been received from
-// our process. The exception message is completely filled and the exception
-// data has already been copied.
-void
-MachProcess::ExceptionMessageReceived (const MachException::Message& exceptionMessage)
-{
-    PTHREAD_MUTEX_LOCKER (locker, m_exception_messages_mutex);
-
-    if (m_exception_messages.empty())
-        m_task.Suspend();
-
-    DNBLogThreadedIf(LOG_EXCEPTIONS, "MachProcess::ExceptionMessageReceived ( )");
-
-    // Use a locker to automatically unlock our mutex in case of exceptions
-    // Add the exception to our internal exception stack
-    m_exception_messages.push_back(exceptionMessage);
-}
-
-void
-MachProcess::ExceptionMessageBundleComplete()
-{
-    // We have a complete bundle of exceptions for our child process.
-    PTHREAD_MUTEX_LOCKER (locker, m_exception_messages_mutex);
-    DNBLogThreadedIf(LOG_EXCEPTIONS, "%s: %llu exception messages.", __PRETTY_FUNCTION__, (uint64_t)m_exception_messages.size());
-    if (!m_exception_messages.empty())
-    {
-        m_did_exec = false;
-        // First check for any SIGTRAP and make sure we didn't exec
-        const task_t task = m_task.TaskPort();
-        size_t i;
-        if (m_pid != 0)
-        {
-            for (i=0; i<m_exception_messages.size(); ++i)
-            {
-                if (m_exception_messages[i].state.task_port == task)
-                {
-                    const int signo = m_exception_messages[i].state.SoftSignal();
-                    if (signo == SIGTRAP)
-                    {
-                        // SIGTRAP could mean that we exec'ed. We need to check the
-                        // dyld all_image_infos.infoArray to see if it is NULL and if
-                        // so, say that we exec'ed.
-                        const nub_addr_t aii_addr = GetDYLDAllImageInfosAddress();
-                        if (aii_addr != INVALID_NUB_ADDRESS)
-                        {
-                            const nub_addr_t info_array_count_addr = aii_addr + 4;
-                            uint32_t info_array_count = 0;
-                            if (m_task.ReadMemory(info_array_count_addr, 4, &info_array_count) == 4)
-                            {
-                                if (info_array_count == 0)
-                                    m_did_exec = true;
-                            }
-                            else
-                            {
-                                DNBLog ("error: failed to read all_image_infos.infoArrayCount from 0x%8.8llx", (uint64_t)info_array_count_addr);
-                            }
-                        }
-                        break;
-                    }
-                }
-            }
-            
-            if (m_did_exec)
-            {
-                cpu_type_t process_cpu_type = MachProcess::GetCPUTypeForLocalProcess (m_pid);
-                if (m_cpu_type != process_cpu_type)
-                {
-                    DNBLog ("arch changed from 0x%8.8x to 0x%8.8x", m_cpu_type, process_cpu_type);
-                    m_cpu_type = process_cpu_type;
-                    DNBArchProtocol::SetArchitecture (process_cpu_type);
-                }
-                m_thread_list.Clear();
-                m_breakpoints.DisableAll();
-            }
-        }
-
-        // Let all threads recover from stopping and do any clean up based
-        // on the previous thread state (if any).
-        m_thread_list.ProcessDidStop(this);
-
-        // Let each thread know of any exceptions
-        for (i=0; i<m_exception_messages.size(); ++i)
-        {
-            // Let the thread list figure use the MachProcess to forward all exceptions
-            // on down to each thread.
-            if (m_exception_messages[i].state.task_port == task)
-                m_thread_list.NotifyException(m_exception_messages[i].state);
-            if (DNBLogCheckLogBit(LOG_EXCEPTIONS))
-                m_exception_messages[i].Dump();
-        }
-
-        if (DNBLogCheckLogBit(LOG_THREAD))
-            m_thread_list.Dump();
-
-        bool step_more = false;
-        if (m_thread_list.ShouldStop(step_more))
-        {
-            // Wait for the eEventProcessRunningStateChanged event to be reset
-            // before changing state to stopped to avoid race condition with
-            // very fast start/stops
-            struct timespec timeout;
-            //DNBTimer::OffsetTimeOfDay(&timeout, 0, 250 * 1000);   // Wait for 250 ms
-            DNBTimer::OffsetTimeOfDay(&timeout, 1, 0);  // Wait for 250 ms
-            m_events.WaitForEventsToReset(eEventProcessRunningStateChanged, &timeout);
-            SetState(eStateStopped);
-        }
-        else
-        {
-            // Resume without checking our current state.
-            PrivateResume ();
-        }
-    }
-    else
-    {
-        DNBLogThreadedIf(LOG_EXCEPTIONS, "%s empty exception messages bundle (%llu exceptions).", __PRETTY_FUNCTION__, (uint64_t)m_exception_messages.size());
-    }
-}
-
-nub_size_t
-MachProcess::CopyImageInfos ( struct DNBExecutableImageInfo **image_infos, bool only_changed)
-{
-    if (m_image_infos_callback != NULL)
-        return m_image_infos_callback(ProcessID(), image_infos, only_changed, m_image_infos_baton);
-    return 0;
-}
-
-void
-MachProcess::SharedLibrariesUpdated ( )
-{
-    uint32_t event_bits = eEventSharedLibsStateChange;
-    // Set the shared library event bit to let clients know of shared library
-    // changes
-    m_events.SetEvents(event_bits);
-    // Wait for the event bit to reset if a reset ACK is requested
-    m_events.WaitForResetAck(event_bits);
-}
-
-void
-MachProcess::AppendSTDOUT (char* s, size_t len)
-{
-    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::%s (<%llu> %s) ...", __FUNCTION__, (uint64_t)len, s);
-    PTHREAD_MUTEX_LOCKER (locker, m_stdio_mutex);
-    m_stdout_data.append(s, len);
-    m_events.SetEvents(eEventStdioAvailable);
-
-    // Wait for the event bit to reset if a reset ACK is requested
-    m_events.WaitForResetAck(eEventStdioAvailable);
-}
-
-size_t
-MachProcess::GetAvailableSTDOUT (char *buf, size_t buf_size)
-{
-    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::%s (&%p[%llu]) ...", __FUNCTION__, buf, (uint64_t)buf_size);
-    PTHREAD_MUTEX_LOCKER (locker, m_stdio_mutex);
-    size_t bytes_available = m_stdout_data.size();
-    if (bytes_available > 0)
-    {
-        if (bytes_available > buf_size)
-        {
-            memcpy(buf, m_stdout_data.data(), buf_size);
-            m_stdout_data.erase(0, buf_size);
-            bytes_available = buf_size;
-        }
-        else
-        {
-            memcpy(buf, m_stdout_data.data(), bytes_available);
-            m_stdout_data.clear();
-        }
-    }
-    return bytes_available;
-}
-
-nub_addr_t
-MachProcess::GetDYLDAllImageInfosAddress ()
-{
-    DNBError err;
-    return m_task.GetDYLDAllImageInfosAddress(err);
-}
-
-size_t
-MachProcess::GetAvailableSTDERR (char *buf, size_t buf_size)
-{
-    return 0;
-}
-
-void *
-MachProcess::STDIOThread(void *arg)
-{
-    MachProcess *proc = (MachProcess*) arg;
-    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::%s ( arg = %p ) thread starting...", __FUNCTION__, arg);
-
-    // We start use a base and more options so we can control if we
-    // are currently using a timeout on the mach_msg. We do this to get a
-    // bunch of related exceptions on our exception port so we can process
-    // then together. When we have multiple threads, we can get an exception
-    // per thread and they will come in consecutively. The main thread loop
-    // will start by calling mach_msg to without having the MACH_RCV_TIMEOUT
-    // flag set in the options, so we will wait forever for an exception on
-    // our exception port. After we get one exception, we then will use the
-    // MACH_RCV_TIMEOUT option with a zero timeout to grab all other current
-    // exceptions for our process. After we have received the last pending
-    // exception, we will get a timeout which enables us to then notify
-    // our main thread that we have an exception bundle avaiable. We then wait
-    // for the main thread to tell this exception thread to start trying to get
-    // exceptions messages again and we start again with a mach_msg read with
-    // infinite timeout.
-    DNBError err;
-    int stdout_fd = proc->GetStdoutFileDescriptor();
-    int stderr_fd = proc->GetStderrFileDescriptor();
-    if (stdout_fd == stderr_fd)
-        stderr_fd = -1;
-
-    while (stdout_fd >= 0 || stderr_fd >= 0)
-    {
-        ::pthread_testcancel ();
-
-        fd_set read_fds;
-        FD_ZERO (&read_fds);
-        if (stdout_fd >= 0)
-            FD_SET (stdout_fd, &read_fds);
-        if (stderr_fd >= 0)
-            FD_SET (stderr_fd, &read_fds);
-        int nfds = std::max<int>(stdout_fd, stderr_fd) + 1;
-
-        int num_set_fds = select (nfds, &read_fds, NULL, NULL, NULL);
-        DNBLogThreadedIf(LOG_PROCESS, "select (nfds, &read_fds, NULL, NULL, NULL) => %d", num_set_fds);
-
-        if (num_set_fds < 0)
-        {
-            int select_errno = errno;
-            if (DNBLogCheckLogBit(LOG_PROCESS))
-            {
-                err.SetError (select_errno, DNBError::POSIX);
-                err.LogThreadedIfError("select (nfds, &read_fds, NULL, NULL, NULL) => %d", num_set_fds);
-            }
-
-            switch (select_errno)
-            {
-            case EAGAIN:    // The kernel was (perhaps temporarily) unable to allocate the requested number of file descriptors, or we have non-blocking IO
-                break;
-            case EBADF:     // One of the descriptor sets specified an invalid descriptor.
-                return NULL;
-                break;
-            case EINTR:     // A signal was delivered before the time limit expired and before any of the selected events occurred.
-            case EINVAL:    // The specified time limit is invalid. One of its components is negative or too large.
-            default:        // Other unknown error
-                break;
-            }
-        }
-        else if (num_set_fds == 0)
-        {
-        }
-        else
-        {
-            char s[1024];
-            s[sizeof(s)-1] = '\0';  // Ensure we have NULL termination
-            int bytes_read = 0;
-            if (stdout_fd >= 0 && FD_ISSET (stdout_fd, &read_fds))
-            {
-                do
-                {
-                    bytes_read = ::read (stdout_fd, s, sizeof(s)-1);
-                    if (bytes_read < 0)
-                    {
-                        int read_errno = errno;
-                        DNBLogThreadedIf(LOG_PROCESS, "read (stdout_fd, ) => %d   errno: %d (%s)", bytes_read, read_errno, strerror(read_errno));
-                    }
-                    else if (bytes_read == 0)
-                    {
-                        // EOF...
-                        DNBLogThreadedIf(LOG_PROCESS, "read (stdout_fd, ) => %d  (reached EOF for child STDOUT)", bytes_read);
-                        stdout_fd = -1;
-                    }
-                    else if (bytes_read > 0)
-                    {
-                        proc->AppendSTDOUT(s, bytes_read);
-                    }
-
-                } while (bytes_read > 0);
-            }
-
-            if (stderr_fd >= 0 && FD_ISSET (stderr_fd, &read_fds))
-            {
-                do
-                {
-                    bytes_read = ::read (stderr_fd, s, sizeof(s)-1);
-                    if (bytes_read < 0)
-                    {
-                        int read_errno = errno;
-                        DNBLogThreadedIf(LOG_PROCESS, "read (stderr_fd, ) => %d   errno: %d (%s)", bytes_read, read_errno, strerror(read_errno));
-                    }
-                    else if (bytes_read == 0)
-                    {
-                        // EOF...
-                        DNBLogThreadedIf(LOG_PROCESS, "read (stderr_fd, ) => %d  (reached EOF for child STDERR)", bytes_read);
-                        stderr_fd = -1;
-                    }
-                    else if (bytes_read > 0)
-                    {
-                        proc->AppendSTDOUT(s, bytes_read);
-                    }
-
-                } while (bytes_read > 0);
-            }
-        }
-    }
-    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::%s (%p): thread exiting...", __FUNCTION__, arg);
-    return NULL;
-}
-
-
-void
-MachProcess::SignalAsyncProfileData (const char *info)
-{
-    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::%s (%s) ...", __FUNCTION__, info);
-    PTHREAD_MUTEX_LOCKER (locker, m_profile_data_mutex);
-    m_profile_data.push_back(info);
-    m_events.SetEvents(eEventProfileDataAvailable);
-    
-    // Wait for the event bit to reset if a reset ACK is requested
-    m_events.WaitForResetAck(eEventProfileDataAvailable);
-}
-
-
-size_t
-MachProcess::GetAsyncProfileData (char *buf, size_t buf_size)
-{
-    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::%s (&%p[%llu]) ...", __FUNCTION__, buf, (uint64_t)buf_size);
-    PTHREAD_MUTEX_LOCKER (locker, m_profile_data_mutex);
-    if (m_profile_data.empty())
-        return 0;
-    
-    size_t bytes_available = m_profile_data.front().size();
-    if (bytes_available > 0)
-    {
-        if (bytes_available > buf_size)
-        {
-            memcpy(buf, m_profile_data.front().data(), buf_size);
-            m_profile_data.front().erase(0, buf_size);
-            bytes_available = buf_size;
-        }
-        else
-        {
-            memcpy(buf, m_profile_data.front().data(), bytes_available);
-            m_profile_data.erase(m_profile_data.begin());
-        }
-    }
-    return bytes_available;
-}
-
-
-void *
-MachProcess::ProfileThread(void *arg)
-{
-    MachProcess *proc = (MachProcess*) arg;
-    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::%s ( arg = %p ) thread starting...", __FUNCTION__, arg);
-
-    while (proc->IsProfilingEnabled())
-    {
-        nub_state_t state = proc->GetState();
-        if (state == eStateRunning)
-        {
-            std::string data = proc->Task().GetProfileData(proc->GetProfileScanType());
-            if (!data.empty())
-            {
-                proc->SignalAsyncProfileData(data.c_str());
-            }
-        }
-        else if ((state == eStateUnloaded) || (state == eStateDetached) || (state == eStateUnloaded))
-        {
-            // Done. Get out of this thread.
-            break;
-        }
-        
-        // A simple way to set up the profile interval. We can also use select() or dispatch timer source if necessary.
-        usleep(proc->ProfileInterval());
-    }
-    return NULL;
-}
-
-
-pid_t
-MachProcess::AttachForDebug (pid_t pid, char *err_str, size_t err_len)
-{
-    // Clear out and clean up from any current state
-    Clear();
-    if (pid != 0)
-    {
-        DNBError err;
-        // Make sure the process exists...
-        if (::getpgid (pid) < 0)
-        {
-            err.SetErrorToErrno();
-            const char *err_cstr = err.AsString();
-            ::snprintf (err_str, err_len, "%s", err_cstr ? err_cstr : "No such process");
-            return INVALID_NUB_PROCESS;
-        }
-
-        SetState(eStateAttaching);
-        m_pid = pid;
-        // Let ourselves know we are going to be using SBS if the correct flag bit is set...
-#ifdef WITH_SPRINGBOARD
-        if (IsSBProcess(pid))
-            m_flags |= eMachProcessFlagsUsingSBS;
-#endif
-        if (!m_task.StartExceptionThread(err))
-        {
-            const char *err_cstr = err.AsString();
-            ::snprintf (err_str, err_len, "%s", err_cstr ? err_cstr : "unable to start the exception thread");
-            DNBLogThreadedIf(LOG_PROCESS, "error: failed to attach to pid %d", pid);
-            m_pid = INVALID_NUB_PROCESS;
-            return INVALID_NUB_PROCESS;
-        }
-
-        errno = 0;
-        if (::ptrace (PT_ATTACHEXC, pid, 0, 0))
-            err.SetError(errno);
-        else
-            err.Clear();
-
-        if (err.Success())
-        {
-            m_flags |= eMachProcessFlagsAttached;
-            // Sleep a bit to let the exception get received and set our process status
-            // to stopped.
-            ::usleep(250000);
-            DNBLogThreadedIf(LOG_PROCESS, "successfully attached to pid %d", pid);
-            return m_pid;
-        }
-        else
-        {
-            ::snprintf (err_str, err_len, "%s", err.AsString());
-            DNBLogThreadedIf(LOG_PROCESS, "error: failed to attach to pid %d", pid);
-        }
-    }
-    return INVALID_NUB_PROCESS;
-}
-
-// Do the process specific setup for attach.  If this returns NULL, then there's no
-// platform specific stuff to be done to wait for the attach.  If you get non-null,
-// pass that token to the CheckForProcess method, and then to CleanupAfterAttach.
-
-//  Call PrepareForAttach before attaching to a process that has not yet launched
-// This returns a token that can be passed to CheckForProcess, and to CleanupAfterAttach.
-// You should call CleanupAfterAttach to free the token, and do whatever other
-// cleanup seems good.
-
-const void *
-MachProcess::PrepareForAttach (const char *path, nub_launch_flavor_t launch_flavor, bool waitfor, DNBError &err_str)
-{
-#ifdef WITH_SPRINGBOARD
-    // Tell SpringBoard to halt the next launch of this application on startup.
-
-    if (!waitfor)
-        return NULL;
-
-    const char *app_ext = strstr(path, ".app");
-    const bool is_app = app_ext != NULL && (app_ext[4] == '\0' || app_ext[4] == '/');
-    if (!is_app)
-    {
-        DNBLogThreadedIf(LOG_PROCESS, "MachProcess::PrepareForAttach(): path '%s' doesn't contain .app, we can't tell springboard to wait for launch...", path);
-        return NULL;
-    }
-
-    if (launch_flavor != eLaunchFlavorSpringBoard
-        && launch_flavor != eLaunchFlavorDefault)
-        return NULL;
-
-    std::string app_bundle_path(path, app_ext + strlen(".app"));
-
-    CFStringRef bundleIDCFStr = CopyBundleIDForPath (app_bundle_path.c_str (), err_str);
-    std::string bundleIDStr;
-    CFString::UTF8(bundleIDCFStr, bundleIDStr);
-    DNBLogThreadedIf(LOG_PROCESS, "CopyBundleIDForPath (%s, err_str) returned @\"%s\"", app_bundle_path.c_str (), bundleIDStr.c_str());
-
-    if (bundleIDCFStr == NULL)
-    {
-        return NULL;
-    }
-
-    SBSApplicationLaunchError sbs_error = 0;
-
-    const char *stdout_err = "/dev/null";
-    CFString stdio_path;
-    stdio_path.SetFileSystemRepresentation (stdout_err);
-
-    DNBLogThreadedIf(LOG_PROCESS, "SBSLaunchApplicationForDebugging ( @\"%s\" , NULL, NULL, NULL, @\"%s\", @\"%s\", SBSApplicationDebugOnNextLaunch | SBSApplicationLaunchWaitForDebugger )", bundleIDStr.c_str(), stdout_err, stdout_err);
-    sbs_error = SBSLaunchApplicationForDebugging (bundleIDCFStr,
-                                                  (CFURLRef)NULL,         // openURL
-                                                  NULL, // launch_argv.get(),
-                                                  NULL, // launch_envp.get(),  // CFDictionaryRef environment
-                                                  stdio_path.get(),
-                                                  stdio_path.get(),
-                                                  SBSApplicationDebugOnNextLaunch | SBSApplicationLaunchWaitForDebugger);
-
-    if (sbs_error != SBSApplicationLaunchErrorSuccess)
-    {
-        err_str.SetError(sbs_error, DNBError::SpringBoard);
-        return NULL;
-    }
-
-    DNBLogThreadedIf(LOG_PROCESS, "Successfully set DebugOnNextLaunch.");
-    return bundleIDCFStr;
-# else
-  return NULL;
-#endif
-}
-
-// Pass in the token you got from PrepareForAttach.  If there is a process
-// for that token, then the pid will be returned, otherwise INVALID_NUB_PROCESS
-// will be returned.
-
-nub_process_t
-MachProcess::CheckForProcess (const void *attach_token)
-{
-    if (attach_token == NULL)
-        return INVALID_NUB_PROCESS;
-
-#ifdef WITH_SPRINGBOARD
-    CFStringRef bundleIDCFStr = (CFStringRef) attach_token;
-    Boolean got_it;
-    nub_process_t attach_pid;
-    got_it = SBSProcessIDForDisplayIdentifier(bundleIDCFStr, &attach_pid);
-    if (got_it)
-        return attach_pid;
-    else
-        return INVALID_NUB_PROCESS;
-#endif
-    return INVALID_NUB_PROCESS;
-}
-
-// Call this to clean up after you have either attached or given up on the attach.
-// Pass true for success if you have attached, false if you have not.
-// The token will also be freed at this point, so you can't use it after calling
-// this method.
-
-void
-MachProcess::CleanupAfterAttach (const void *attach_token, bool success, DNBError &err_str)
-{
-#ifdef WITH_SPRINGBOARD
-    if (attach_token == NULL)
-        return;
-
-    // Tell SpringBoard to cancel the debug on next launch of this application
-    // if we failed to attach
-    if (!success)
-    {
-        SBSApplicationLaunchError sbs_error = 0;
-        CFStringRef bundleIDCFStr = (CFStringRef) attach_token;
-
-        sbs_error = SBSLaunchApplicationForDebugging (bundleIDCFStr,
-                                                      (CFURLRef)NULL,
-                                                      NULL,
-                                                      NULL,
-                                                      NULL,
-                                                      NULL,
-                                                      SBSApplicationCancelDebugOnNextLaunch);
-
-        if (sbs_error != SBSApplicationLaunchErrorSuccess)
-        {
-            err_str.SetError(sbs_error, DNBError::SpringBoard);
-            return;
-        }
-    }
-
-    CFRelease((CFStringRef) attach_token);
-#endif
-}
-
-pid_t
-MachProcess::LaunchForDebug
-(
-    const char *path,
-    char const *argv[],
-    char const *envp[],
-    const char *working_directory, // NULL => dont' change, non-NULL => set working directory for inferior to this
-    const char *stdin_path,
-    const char *stdout_path,
-    const char *stderr_path,
-    bool no_stdio,
-    nub_launch_flavor_t launch_flavor,
-    int disable_aslr,
-    DNBError &launch_err
-)
-{
-    // Clear out and clean up from any current state
-    Clear();
-
-    DNBLogThreadedIf(LOG_PROCESS, "%s( path = '%s', argv = %p, envp = %p, launch_flavor = %u, disable_aslr = %d )", __FUNCTION__, path, argv, envp, launch_flavor, disable_aslr);
-
-    // Fork a child process for debugging
-    SetState(eStateLaunching);
-
-    switch (launch_flavor)
-    {
-    case eLaunchFlavorForkExec:
-        m_pid = MachProcess::ForkChildForPTraceDebugging (path, argv, envp, this, launch_err);
-        break;
-
-#ifdef WITH_SPRINGBOARD
-
-    case eLaunchFlavorSpringBoard:
-        {
-            //  .../whatever.app/whatever ?  
-            //  Or .../com.apple.whatever.app/whatever -- be careful of ".app" in "com.apple.whatever" here
-            const char *app_ext = strstr (path, ".app/");
-            if (app_ext == NULL)
-            {
-                // .../whatever.app ?
-                int len = strlen (path);
-                if (len > 5)
-                {
-                    if (strcmp (path + len - 4, ".app") == 0)
-                    {
-                        app_ext = path + len - 4;
-                    }
-                }
-            }
-            if (app_ext)
-            {
-                std::string app_bundle_path(path, app_ext + strlen(".app"));
-                if (SBLaunchForDebug (app_bundle_path.c_str(), argv, envp, no_stdio, launch_err) != 0)
-                    return m_pid; // A successful SBLaunchForDebug() returns and assigns a non-zero m_pid.
-                else
-                    break; // We tried a springboard launch, but didn't succeed lets get out
-            }
-        }
-        // In case the executable name has a ".app" fragment which confuses our debugserver,
-        // let's do an intentional fallthrough here...
-        launch_flavor = eLaunchFlavorPosixSpawn;
-
-#endif
-
-    case eLaunchFlavorPosixSpawn:
-        m_pid = MachProcess::PosixSpawnChildForPTraceDebugging (path, 
-                                                                DNBArchProtocol::GetArchitecture (),
-                                                                argv, 
-                                                                envp, 
-                                                                working_directory,
-                                                                stdin_path,
-                                                                stdout_path,
-                                                                stderr_path,
-                                                                no_stdio, 
-                                                                this, 
-                                                                disable_aslr, 
-                                                                launch_err);
-        break;
-
-    default:
-        // Invalid  launch
-        launch_err.SetError(NUB_GENERIC_ERROR, DNBError::Generic);
-        return INVALID_NUB_PROCESS;
-    }
-
-    if (m_pid == INVALID_NUB_PROCESS)
-    {
-        // If we don't have a valid process ID and no one has set the error,
-        // then return a generic error
-        if (launch_err.Success())
-            launch_err.SetError(NUB_GENERIC_ERROR, DNBError::Generic);
-    }
-    else
-    {
-        m_path = path;
-        size_t i;
-        char const *arg;
-        for (i=0; (arg = argv[i]) != NULL; i++)
-            m_args.push_back(arg);
-
-        m_task.StartExceptionThread(launch_err);
-        if (launch_err.Fail())
-        {
-            if (launch_err.AsString() == NULL)
-                launch_err.SetErrorString("unable to start the exception thread");
-            DNBLog ("Could not get inferior's Mach exception port, sending ptrace PT_KILL and exiting.");
-            ::ptrace (PT_KILL, m_pid, 0, 0);
-            m_pid = INVALID_NUB_PROCESS;
-            return INVALID_NUB_PROCESS;
-        }
-
-        StartSTDIOThread();
-
-        if (launch_flavor == eLaunchFlavorPosixSpawn)
-        {
-
-            SetState (eStateAttaching);
-            errno = 0;
-            int err = ::ptrace (PT_ATTACHEXC, m_pid, 0, 0);
-            if (err == 0)
-            {
-                m_flags |= eMachProcessFlagsAttached;
-                DNBLogThreadedIf(LOG_PROCESS, "successfully spawned pid %d", m_pid);
-                launch_err.Clear();
-            }
-            else
-            {
-                SetState (eStateExited);
-                DNBError ptrace_err(errno, DNBError::POSIX);
-                DNBLogThreadedIf(LOG_PROCESS, "error: failed to attach to spawned pid %d (err = %i, errno = %i (%s))", m_pid, err, ptrace_err.Error(), ptrace_err.AsString());
-                launch_err.SetError(NUB_GENERIC_ERROR, DNBError::Generic);
-            }
-        }
-        else
-        {
-            launch_err.Clear();
-        }
-    }
-    return m_pid;
-}
-
-pid_t
-MachProcess::PosixSpawnChildForPTraceDebugging
-(
-    const char *path,
-    cpu_type_t cpu_type,
-    char const *argv[],
-    char const *envp[],
-    const char *working_directory,
-    const char *stdin_path,
-    const char *stdout_path,
-    const char *stderr_path,
-    bool no_stdio,
-    MachProcess* process,
-    int disable_aslr,
-    DNBError& err
-)
-{
-    posix_spawnattr_t attr;
-    short flags;
-    DNBLogThreadedIf(LOG_PROCESS, "%s ( path='%s', argv=%p, envp=%p, working_dir=%s, stdin=%s, stdout=%s stderr=%s, no-stdio=%i)", 
-                     __FUNCTION__, 
-                     path, 
-                     argv, 
-                     envp,
-                     working_directory,
-                     stdin_path,
-                     stdout_path,
-                     stderr_path,
-                     no_stdio);
-
-    err.SetError( ::posix_spawnattr_init (&attr), DNBError::POSIX);
-    if (err.Fail() || DNBLogCheckLogBit(LOG_PROCESS))
-        err.LogThreaded("::posix_spawnattr_init ( &attr )");
-    if (err.Fail())
-        return INVALID_NUB_PROCESS;
-
-    flags = POSIX_SPAWN_START_SUSPENDED | POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK;
-    if (disable_aslr)
-        flags |= _POSIX_SPAWN_DISABLE_ASLR;
-
-    sigset_t no_signals;
-    sigset_t all_signals;
-    sigemptyset (&no_signals);
-    sigfillset (&all_signals);
-    ::posix_spawnattr_setsigmask(&attr, &no_signals);
-    ::posix_spawnattr_setsigdefault(&attr, &all_signals);
-
-    err.SetError( ::posix_spawnattr_setflags (&attr, flags), DNBError::POSIX);
-    if (err.Fail() || DNBLogCheckLogBit(LOG_PROCESS))
-        err.LogThreaded("::posix_spawnattr_setflags ( &attr, POSIX_SPAWN_START_SUSPENDED%s )", flags & _POSIX_SPAWN_DISABLE_ASLR ? " | _POSIX_SPAWN_DISABLE_ASLR" : "");
-    if (err.Fail())
-        return INVALID_NUB_PROCESS;
-
-    // Don't do this on SnowLeopard, _sometimes_ the TASK_BASIC_INFO will fail
-    // and we will fail to continue with our process...
-    
-    // On SnowLeopard we should set "DYLD_NO_PIE" in the inferior environment....
-     
-#if !defined(__arm__)
-
-    // We don't need to do this for ARM, and we really shouldn't now that we
-    // have multiple CPU subtypes and no posix_spawnattr call that allows us
-    // to set which CPU subtype to launch...
-    if (cpu_type != 0)
-    {
-        size_t ocount = 0;
-        err.SetError( ::posix_spawnattr_setbinpref_np (&attr, 1, &cpu_type, &ocount), DNBError::POSIX);
-        if (err.Fail() || DNBLogCheckLogBit(LOG_PROCESS))
-            err.LogThreaded("::posix_spawnattr_setbinpref_np ( &attr, 1, cpu_type = 0x%8.8x, count => %llu )", cpu_type, (uint64_t)ocount);
-
-        if (err.Fail() != 0 || ocount != 1)
-            return INVALID_NUB_PROCESS;
-    }
-#endif
-
-    PseudoTerminal pty;
-
-    posix_spawn_file_actions_t file_actions;
-    err.SetError( ::posix_spawn_file_actions_init (&file_actions), DNBError::POSIX);
-    int file_actions_valid = err.Success();
-    if (!file_actions_valid || DNBLogCheckLogBit(LOG_PROCESS))
-        err.LogThreaded("::posix_spawn_file_actions_init ( &file_actions )");
-    int pty_error = -1;
-    pid_t pid = INVALID_NUB_PROCESS;
-    if (file_actions_valid)
-    {
-        if (stdin_path == NULL && stdout_path == NULL && stderr_path == NULL && !no_stdio)
-        {
-            pty_error = pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY);
-            if (pty_error == PseudoTerminal::success)
-            {
-                stdin_path = stdout_path = stderr_path = pty.SlaveName();
-            }
-        }
-
-        // if no_stdio or std paths not supplied, then route to "/dev/null".
-        if (no_stdio || stdin_path == NULL || stdin_path[0] == '\0')
-            stdin_path = "/dev/null";
-        if (no_stdio || stdout_path == NULL || stdout_path[0] == '\0')
-            stdout_path = "/dev/null";
-        if (no_stdio || stderr_path == NULL || stderr_path[0] == '\0')
-            stderr_path = "/dev/null";
-
-        err.SetError( ::posix_spawn_file_actions_addopen (&file_actions,
-                                                          STDIN_FILENO,
-                                                          stdin_path,
-                                                          O_RDONLY | O_NOCTTY,
-                                                          0),
-                     DNBError::POSIX);
-        if (err.Fail() || DNBLogCheckLogBit (LOG_PROCESS))
-            err.LogThreaded ("::posix_spawn_file_actions_addopen (&file_actions, filedes=STDIN_FILENO, path='%s')", stdin_path);
-        
-        err.SetError( ::posix_spawn_file_actions_addopen (&file_actions,
-                                                          STDOUT_FILENO,
-                                                          stdout_path,
-                                                          O_WRONLY | O_NOCTTY | O_CREAT,
-                                                          0640),
-                     DNBError::POSIX);
-        if (err.Fail() || DNBLogCheckLogBit (LOG_PROCESS))
-            err.LogThreaded ("::posix_spawn_file_actions_addopen (&file_actions, filedes=STDOUT_FILENO, path='%s')", stdout_path);
-        
-        err.SetError( ::posix_spawn_file_actions_addopen (&file_actions,
-                                                          STDERR_FILENO,
-                                                          stderr_path,
-                                                          O_WRONLY | O_NOCTTY | O_CREAT,
-                                                          0640),
-                     DNBError::POSIX);
-        if (err.Fail() || DNBLogCheckLogBit (LOG_PROCESS))
-            err.LogThreaded ("::posix_spawn_file_actions_addopen (&file_actions, filedes=STDERR_FILENO, path='%s')", stderr_path);
-
-        // TODO: Verify if we can set the working directory back immediately
-        // after the posix_spawnp call without creating a race condition???
-        if (working_directory)
-            ::chdir (working_directory);
-        
-        err.SetError( ::posix_spawnp (&pid, path, &file_actions, &attr, (char * const*)argv, (char * const*)envp), DNBError::POSIX);
-        if (err.Fail() || DNBLogCheckLogBit(LOG_PROCESS))
-            err.LogThreaded("::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )", pid, path, &file_actions, &attr, argv, envp);
-    }
-    else
-    {
-        // TODO: Verify if we can set the working directory back immediately
-        // after the posix_spawnp call without creating a race condition???
-        if (working_directory)
-            ::chdir (working_directory);
-        
-        err.SetError( ::posix_spawnp (&pid, path, NULL, &attr, (char * const*)argv, (char * const*)envp), DNBError::POSIX);
-        if (err.Fail() || DNBLogCheckLogBit(LOG_PROCESS))
-            err.LogThreaded("::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )", pid, path, NULL, &attr, argv, envp);
-    }
-
-    // We have seen some cases where posix_spawnp was returning a valid
-    // looking pid even when an error was returned, so clear it out
-    if (err.Fail())
-        pid = INVALID_NUB_PROCESS;
-
-    if (pty_error == 0)
-    {
-        if (process != NULL)
-        {
-            int master_fd = pty.ReleaseMasterFD();
-            process->SetChildFileDescriptors(master_fd, master_fd, master_fd);
-        }
-    }
-    ::posix_spawnattr_destroy (&attr);
-
-    if (pid != INVALID_NUB_PROCESS)
-    {
-        cpu_type_t pid_cpu_type = MachProcess::GetCPUTypeForLocalProcess (pid);
-        DNBLogThreadedIf(LOG_PROCESS, "MachProcess::%s ( ) pid=%i, cpu_type=0x%8.8x", __FUNCTION__, pid, pid_cpu_type);
-        if (pid_cpu_type)
-            DNBArchProtocol::SetArchitecture (pid_cpu_type);
-    }
-
-    if (file_actions_valid)
-    {
-        DNBError err2;
-        err2.SetError( ::posix_spawn_file_actions_destroy (&file_actions), DNBError::POSIX);
-        if (err2.Fail() || DNBLogCheckLogBit(LOG_PROCESS))
-            err2.LogThreaded("::posix_spawn_file_actions_destroy ( &file_actions )");
-    }
-
-    return pid;
-}
-
-uint32_t
-MachProcess::GetCPUTypeForLocalProcess (pid_t pid)
-{
-    int mib[CTL_MAXNAME]={0,};
-    size_t len = CTL_MAXNAME;
-    if (::sysctlnametomib("sysctl.proc_cputype", mib, &len)) 
-        return 0;
-
-    mib[len] = pid;
-    len++;
-            
-    cpu_type_t cpu;
-    size_t cpu_len = sizeof(cpu);
-    if (::sysctl (mib, len, &cpu, &cpu_len, 0, 0))
-        cpu = 0;
-    return cpu;
-}
-
-pid_t
-MachProcess::ForkChildForPTraceDebugging
-(
-    const char *path,
-    char const *argv[],
-    char const *envp[],
-    MachProcess* process,
-    DNBError& launch_err
-)
-{
-    PseudoTerminal::Error pty_error = PseudoTerminal::success;
-
-    // Use a fork that ties the child process's stdin/out/err to a pseudo
-    // terminal so we can read it in our MachProcess::STDIOThread
-    // as unbuffered io.
-    PseudoTerminal pty;
-    pid_t pid = pty.Fork(pty_error);
-
-    if (pid < 0)
-    {
-        //--------------------------------------------------------------
-        // Error during fork.
-        //--------------------------------------------------------------
-        return pid;
-    }
-    else if (pid == 0)
-    {
-        //--------------------------------------------------------------
-        // Child process
-        //--------------------------------------------------------------
-        ::ptrace (PT_TRACE_ME, 0, 0, 0);    // Debug this process
-        ::ptrace (PT_SIGEXC, 0, 0, 0);    // Get BSD signals as mach exceptions
-
-        // If our parent is setgid, lets make sure we don't inherit those
-        // extra powers due to nepotism.
-        if (::setgid (getgid ()) == 0)
-        {
-
-            // Let the child have its own process group. We need to execute
-            // this call in both the child and parent to avoid a race condition
-            // between the two processes.
-            ::setpgid (0, 0);    // Set the child process group to match its pid
-
-            // Sleep a bit to before the exec call
-            ::sleep (1);
-
-            // Turn this process into
-            ::execv (path, (char * const *)argv);
-        }
-        // Exit with error code. Child process should have taken
-        // over in above exec call and if the exec fails it will
-        // exit the child process below.
-        ::exit (127);
-    }
-    else
-    {
-        //--------------------------------------------------------------
-        // Parent process
-        //--------------------------------------------------------------
-        // Let the child have its own process group. We need to execute
-        // this call in both the child and parent to avoid a race condition
-        // between the two processes.
-        ::setpgid (pid, pid);    // Set the child process group to match its pid
-
-        if (process != NULL)
-        {
-            // Release our master pty file descriptor so the pty class doesn't
-            // close it and so we can continue to use it in our STDIO thread
-            int master_fd = pty.ReleaseMasterFD();
-            process->SetChildFileDescriptors(master_fd, master_fd, master_fd);
-        }
-    }
-    return pid;
-}
-
-#ifdef WITH_SPRINGBOARD
-
-pid_t
-MachProcess::SBLaunchForDebug (const char *path, char const *argv[], char const *envp[], bool no_stdio, DNBError &launch_err)
-{
-    // Clear out and clean up from any current state
-    Clear();
-
-    DNBLogThreadedIf(LOG_PROCESS, "%s( '%s', argv)", __FUNCTION__, path);
-
-    // Fork a child process for debugging
-    SetState(eStateLaunching);
-    m_pid = MachProcess::SBForkChildForPTraceDebugging(path, argv, envp, no_stdio, this, launch_err);
-    if (m_pid != 0)
-    {
-        m_flags |= eMachProcessFlagsUsingSBS;
-        m_path = path;
-        size_t i;
-        char const *arg;
-        for (i=0; (arg = argv[i]) != NULL; i++)
-            m_args.push_back(arg);
-        m_task.StartExceptionThread(launch_err);
-        
-        if (launch_err.Fail())
-        {
-            if (launch_err.AsString() == NULL)
-                launch_err.SetErrorString("unable to start the exception thread");
-            DNBLog ("Could not get inferior's Mach exception port, sending ptrace PT_KILL and exiting.");
-            ::ptrace (PT_KILL, m_pid, 0, 0);
-            m_pid = INVALID_NUB_PROCESS;
-            return INVALID_NUB_PROCESS;
-        }
-
-        StartSTDIOThread();
-        SetState (eStateAttaching);
-        int err = ::ptrace (PT_ATTACHEXC, m_pid, 0, 0);
-        if (err == 0)
-        {
-            m_flags |= eMachProcessFlagsAttached;
-            DNBLogThreadedIf(LOG_PROCESS, "successfully attached to pid %d", m_pid);
-        }
-        else
-        {
-            SetState (eStateExited);
-            DNBLogThreadedIf(LOG_PROCESS, "error: failed to attach to pid %d", m_pid);
-        }
-    }
-    return m_pid;
-}
-
-#include <servers/bootstrap.h>
-
-// This returns a CFRetained pointer to the Bundle ID for app_bundle_path,
-// or NULL if there was some problem getting the bundle id.
-static CFStringRef
-CopyBundleIDForPath (const char *app_bundle_path, DNBError &err_str)
-{
-    CFBundle bundle(app_bundle_path);
-    CFStringRef bundleIDCFStr = bundle.GetIdentifier();
-    std::string bundleID;
-    if (CFString::UTF8(bundleIDCFStr, bundleID) == NULL)
-    {
-        struct stat app_bundle_stat;
-        char err_msg[PATH_MAX];
-
-        if (::stat (app_bundle_path, &app_bundle_stat) < 0)
-        {
-            err_str.SetError(errno, DNBError::POSIX);
-            snprintf(err_msg, sizeof(err_msg), "%s: \"%s\"", err_str.AsString(), app_bundle_path);
-            err_str.SetErrorString(err_msg);
-            DNBLogThreadedIf(LOG_PROCESS, "%s() error: %s", __FUNCTION__, err_msg);
-        }
-        else
-        {
-            err_str.SetError(-1, DNBError::Generic);
-            snprintf(err_msg, sizeof(err_msg), "failed to extract CFBundleIdentifier from %s", app_bundle_path);
-            err_str.SetErrorString(err_msg);
-            DNBLogThreadedIf(LOG_PROCESS, "%s() error: failed to extract CFBundleIdentifier from '%s'", __FUNCTION__, app_bundle_path);
-        }
-        return NULL;
-    }
-
-    DNBLogThreadedIf(LOG_PROCESS, "%s() extracted CFBundleIdentifier: %s", __FUNCTION__, bundleID.c_str());
-    CFRetain (bundleIDCFStr);
-
-    return bundleIDCFStr;
-}
-
-pid_t
-MachProcess::SBForkChildForPTraceDebugging (const char *app_bundle_path, char const *argv[], char const *envp[], bool no_stdio, MachProcess* process, DNBError &launch_err)
-{
-    DNBLogThreadedIf(LOG_PROCESS, "%s( '%s', argv, %p)", __FUNCTION__, app_bundle_path, process);
-    CFAllocatorRef alloc = kCFAllocatorDefault;
-
-    if (argv[0] == NULL)
-        return INVALID_NUB_PROCESS;
-
-    size_t argc = 0;
-    // Count the number of arguments
-    while (argv[argc] != NULL)
-        argc++;
-
-    // Enumerate the arguments
-    size_t first_launch_arg_idx = 1;
-    CFReleaser<CFMutableArrayRef> launch_argv;
-
-    if (argv[first_launch_arg_idx])
-    {
-        size_t launch_argc = argc > 0 ? argc - 1 : 0;
-        launch_argv.reset (::CFArrayCreateMutable (alloc, launch_argc, &kCFTypeArrayCallBacks));
-        size_t i;
-        char const *arg;
-        CFString launch_arg;
-        for (i=first_launch_arg_idx; (i < argc) && ((arg = argv[i]) != NULL); i++)
-        {
-            launch_arg.reset(::CFStringCreateWithCString (alloc, arg, kCFStringEncodingUTF8));
-            if (launch_arg.get() != NULL)
-                CFArrayAppendValue(launch_argv.get(), launch_arg.get());
-            else
-                break;
-        }
-    }
-
-    // Next fill in the arguments dictionary.  Note, the envp array is of the form
-    // Variable=value but SpringBoard wants a CF dictionary.  So we have to convert
-    // this here.
-
-    CFReleaser<CFMutableDictionaryRef> launch_envp;
-
-    if (envp[0])
-    {
-        launch_envp.reset(::CFDictionaryCreateMutable(alloc, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
-        const char *value;
-        int name_len;
-        CFString name_string, value_string;
-
-        for (int i = 0; envp[i] != NULL; i++)
-        {
-            value = strstr (envp[i], "=");
-
-            // If the name field is empty or there's no =, skip it.  Somebody's messing with us.
-            if (value == NULL || value == envp[i])
-                continue;
-
-            name_len = value - envp[i];
-
-            // Now move value over the "="
-            value++;
-
-            name_string.reset(::CFStringCreateWithBytes(alloc, (const UInt8 *) envp[i], name_len, kCFStringEncodingUTF8, false));
-            value_string.reset(::CFStringCreateWithCString(alloc, value, kCFStringEncodingUTF8));
-            CFDictionarySetValue (launch_envp.get(), name_string.get(), value_string.get());
-        }
-    }
-
-    CFString stdio_path;
-
-    PseudoTerminal pty;
-    if (!no_stdio)
-    {
-        PseudoTerminal::Error pty_err = pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY);
-        if (pty_err == PseudoTerminal::success)
-        {
-            const char* slave_name = pty.SlaveName();
-            DNBLogThreadedIf(LOG_PROCESS, "%s() successfully opened master pty, slave is %s", __FUNCTION__, slave_name);
-            if (slave_name && slave_name[0])
-            {
-                ::chmod (slave_name, S_IRWXU | S_IRWXG | S_IRWXO);
-                stdio_path.SetFileSystemRepresentation (slave_name);
-            }
-        }
-    }
-    
-    if (stdio_path.get() == NULL)
-    {
-        stdio_path.SetFileSystemRepresentation ("/dev/null");
-    }
-
-    CFStringRef bundleIDCFStr = CopyBundleIDForPath (app_bundle_path, launch_err);
-    if (bundleIDCFStr == NULL)
-        return INVALID_NUB_PROCESS;
-
-    std::string bundleID;
-    CFString::UTF8(bundleIDCFStr, bundleID);
-
-    // Find SpringBoard
-    SBSApplicationLaunchError sbs_error = 0;
-    sbs_error = SBSLaunchApplicationForDebugging (bundleIDCFStr,
-                                                  (CFURLRef)NULL,         // openURL
-                                                  launch_argv.get(),
-                                                  launch_envp.get(),  // CFDictionaryRef environment
-                                                  stdio_path.get(),
-                                                  stdio_path.get(),
-                                                  SBSApplicationLaunchWaitForDebugger | SBSApplicationLaunchUnlockDevice);
-
-
-    launch_err.SetError(sbs_error, DNBError::SpringBoard);
-
-    if (sbs_error == SBSApplicationLaunchErrorSuccess)
-    {
-        static const useconds_t pid_poll_interval = 200000;
-        static const useconds_t pid_poll_timeout = 30000000;
-
-        useconds_t pid_poll_total = 0;
-
-        nub_process_t pid = INVALID_NUB_PROCESS;
-        Boolean pid_found = SBSProcessIDForDisplayIdentifier(bundleIDCFStr, &pid);
-        // Poll until the process is running, as long as we are getting valid responses and the timeout hasn't expired
-        // A return PID of 0 means the process is not running, which may be because it hasn't been (asynchronously) started
-        // yet, or that it died very quickly (if you weren't using waitForDebugger).
-        while (!pid_found && pid_poll_total < pid_poll_timeout)
-        {
-            usleep (pid_poll_interval);
-            pid_poll_total += pid_poll_interval;
-            DNBLogThreadedIf(LOG_PROCESS, "%s() polling Springboard for pid for %s...", __FUNCTION__, bundleID.c_str());
-            pid_found = SBSProcessIDForDisplayIdentifier(bundleIDCFStr, &pid);
-        }
-
-        CFRelease (bundleIDCFStr);
-        if (pid_found)
-        {
-            if (process != NULL)
-            {
-                // Release our master pty file descriptor so the pty class doesn't
-                // close it and so we can continue to use it in our STDIO thread
-                int master_fd = pty.ReleaseMasterFD();
-                process->SetChildFileDescriptors(master_fd, master_fd, master_fd);
-            }
-            DNBLogThreadedIf(LOG_PROCESS, "%s() => pid = %4.4x", __FUNCTION__, pid);
-        }
-        else
-        {
-            DNBLogError("failed to lookup the process ID for CFBundleIdentifier %s.", bundleID.c_str());
-        }
-        return pid;
-    }
-
-    DNBLogError("unable to launch the application with CFBundleIdentifier '%s' sbs_error = %u", bundleID.c_str(), sbs_error);
-    return INVALID_NUB_PROCESS;
-}
-
-#endif // #ifdef WITH_SPRINGBOARD
-
-

Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h Sat Mar 29 13:54:20 2014
@@ -55,7 +55,8 @@ public:
                                             const char *stderr_path,
                                             bool no_stdio, 
                                             nub_launch_flavor_t launch_flavor, 
-                                            int disable_aslr, 
+                                            int disable_aslr,
+                                            const char *event_data,
                                             DNBError &err);
 
     static uint32_t         GetCPUTypeForLocalProcess (pid_t pid);
@@ -76,8 +77,14 @@ public:
     static const void *     PrepareForAttach (const char *path, nub_launch_flavor_t launch_flavor, bool waitfor, DNBError &err_str);
     static void             CleanupAfterAttach (const void *attach_token, bool success, DNBError &err_str);
     static nub_process_t    CheckForProcess (const void *attach_token);
+#ifdef WITH_BKS
+    pid_t                   BKSLaunchForDebug (const char *app_bundle_path, char const *argv[], char const *envp[], bool no_stdio, bool disable_aslr, const char *event_data, DNBError &launch_err);
+    pid_t                   BKSForkChildForPTraceDebugging (const char *path, char const *argv[], char const *envp[], bool no_stdio, bool disable_aslr, const char *event_data, DNBError &launch_err);
+    bool                    BKSSendEvent (const char *event, DNBError &error);
+    static void             BKSCleanupAfterAttach (const void *attach_token, DNBError &err_str);
+#endif
 #ifdef WITH_SPRINGBOARD
-    pid_t                   SBLaunchForDebug (const char *app_bundle_path, char const *argv[], char const *envp[], bool no_stdio, DNBError &launch_err);
+    pid_t                   SBLaunchForDebug (const char *app_bundle_path, char const *argv[], char const *envp[], bool no_stdio, bool disable_aslr, DNBError &launch_err);
     static pid_t            SBForkChildForPTraceDebugging (const char *path, char const *argv[], char const *envp[], bool no_stdio, MachProcess* process, DNBError &launch_err);
 #endif
     nub_addr_t              LookupSymbol (const char *name, const char *shlib);
@@ -94,6 +101,7 @@ public:
 
     bool                    Resume (const DNBThreadResumeActions& thread_actions);
     bool                    Signal  (int signal, const struct timespec *timeout_abstime = NULL);
+    bool                    SendEvent (const char *event, DNBError &send_err);
     bool                    Kill (const struct timespec *timeout_abstime = NULL);
     bool                    Detach ();
     nub_size_t              ReadMemory (nub_addr_t addr, nub_size_t size, void *buf);
@@ -213,6 +221,15 @@ public:
                                 m_exit_status = status;
                                 SetState(eStateExited);
                             }
+    const char *            GetExitInfo ()
+                            {
+                                return m_exit_info.c_str();
+                            }
+    
+    void                    SetExitInfo (const char *info)
+                            {
+                                m_exit_info.assign(info);
+                            }
 
     uint32_t                StopCount() const { return m_stop_count; }
     void                    SetChildFileDescriptors (int stdin_fileno, int stdout_fileno, int stderr_fileno)
@@ -248,6 +265,7 @@ public:
                             }
 
     bool                    ProcessUsingSpringBoard() const { return (m_flags & eMachProcessFlagsUsingSBS) != 0; }
+    bool                    ProcessUsingBackBoard() const { return (m_flags & eMachProcessFlagsUsingBKS) != 0; }
     
     DNBProfileDataScanType  GetProfileScanType () { return m_profile_scan_type; }
     
@@ -256,7 +274,8 @@ private:
     {
         eMachProcessFlagsNone = 0,
         eMachProcessFlagsAttached = (1 << 0),
-        eMachProcessFlagsUsingSBS = (1 << 1)
+        eMachProcessFlagsUsingSBS = (1 << 1),
+        eMachProcessFlagsUsingBKS = (1 << 2)
     };
     void                    Clear (bool detaching = false);
     void                    ReplyToAllExceptions ();
@@ -273,6 +292,7 @@ private:
     std::string                 m_path;                     // A path to the executable if we have one
     std::vector<std::string>    m_args;                     // The arguments with which the process was lauched
     int                         m_exit_status;              // The exit status for the process
+    std::string                 m_exit_info;                // Any extra info that we may have about the exit
     MachTask                    m_task;                     // The mach task for this process
     uint32_t                    m_flags;                    // Process specific flags (see eMachProcessFlags enums)
     uint32_t                    m_stop_count;               // A count of many times have we stopped
@@ -304,6 +324,7 @@ private:
     DNBCallbackCopyExecutableImageInfos
                                 m_image_infos_callback;
     void *                      m_image_infos_baton;
+    std::string                 m_bundle_id;                 // If we are a SB or BKS process, this will be our bundle ID.
     bool                        m_did_exec;
 };
 

Copied: lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.mm (from r205075, lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp)
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.mm?p2=lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.mm&p1=lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp&r1=205075&r2=205113&rev=205113&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.mm Sat Mar 29 13:54:20 2014
@@ -39,7 +39,7 @@
 #include "CFData.h"
 #include "CFString.h"
 
-static CFStringRef CopyBundleIDForPath (const char *app_buncle_path, DNBError &err_str);
+static CFStringRef CopyBundleIDForPath (const char *app_bundle_path, DNBError &err_str);
 
 #ifdef WITH_SPRINGBOARD
 
@@ -54,8 +54,44 @@ IsSBProcess (nub_process_t pid)
     return appIdsForPID.get() != NULL;
 }
 
-#endif
+#endif // WITH_SPRINGBOARD
+
+#ifdef WITH_BKS
+#import <Foundation/Foundation.h>
+extern "C"
+{
+#import <BackBoardServices/BackBoardServices.h>
+#import <BackBoardServices/BKSSystemService_LaunchServices.h>
+#import <BackBoardServices/BKSOpenApplicationConstants_Private.h>
+}
+
+static bool
+IsBKSProcess (nub_process_t pid)
+{
+    BKSApplicationStateMonitor *state_monitor = [[BKSApplicationStateMonitor alloc] init];
+    BKSApplicationState app_state = [state_monitor mostElevatedApplicationStateForPID: pid];
+    return app_state != BKSApplicationStateUnknown;
+}
+
+static void
+SetBKSError (BKSOpenApplicationErrorCode error_code, DNBError &error)
+{
+    error.SetError (error_code, DNBError::BackBoard);
+    NSString *err_nsstr = ::BKSOpenApplicationErrorCodeToString(error_code);
+    const char *err_str = NULL;
+    if (err_nsstr == NULL)
+        err_str = "unknown BKS error";
+    else
+    {
+        err_str = [err_nsstr UTF8String];
+        if (err_str == NULL)
+            err_str = "unknown BKS error";
+    }
+    error.SetErrorString(err_str);
+}
 
+static const int BKS_OPEN_APPLICATION_TIMEOUT_ERROR = 111;
+#endif // WITH_BKS
 #if 0
 #define DEBUG_LOG(fmt, ...) printf(fmt, ## __VA_ARGS__)
 #else
@@ -456,6 +492,18 @@ MachProcess::Signal (int signal, const s
 
 }
 
+bool
+MachProcess::SendEvent (const char *event, DNBError &send_err)
+{
+    DNBLogThreadedIf(LOG_PROCESS, "MachProcess::SendEvent (event = %s) to pid: %d", event, m_pid);
+    if (m_pid == INVALID_NUB_PROCESS)
+        return false;
+#if WITH_BKS
+    return BKSSendEvent (event, send_err);
+#endif
+    return true;
+}
+
 nub_state_t
 MachProcess::DoSIGSTOP (bool clear_bps_and_wps, bool allow_running, uint32_t *thread_idx_ptr)
 {
@@ -1475,8 +1523,11 @@ MachProcess::AttachForDebug (pid_t pid,
 
         SetState(eStateAttaching);
         m_pid = pid;
-        // Let ourselves know we are going to be using SBS if the correct flag bit is set...
-#ifdef WITH_SPRINGBOARD
+        // Let ourselves know we are going to be using SBS or BKS if the correct flag bit is set...
+#if defined (WITH_BKS)
+        if (IsBKSProcess (pid))
+            m_flags |= eMachProcessFlagsUsingBKS;
+#elif defined (WITH_SPRINGBOARD)
         if (IsSBProcess(pid))
             m_flags |= eMachProcessFlagsUsingSBS;
 #endif
@@ -1523,9 +1574,9 @@ MachProcess::AttachForDebug (pid_t pid,
 // cleanup seems good.
 
 const void *
-MachProcess::PrepareForAttach (const char *path, nub_launch_flavor_t launch_flavor, bool waitfor, DNBError &err_str)
+MachProcess::PrepareForAttach (const char *path, nub_launch_flavor_t launch_flavor, bool waitfor, DNBError &attach_err)
 {
-#ifdef WITH_SPRINGBOARD
+#if defined (WITH_SPRINGBOARD) || defined (WITH_BKS)
     // Tell SpringBoard to halt the next launch of this application on startup.
 
     if (!waitfor)
@@ -1535,50 +1586,142 @@ MachProcess::PrepareForAttach (const cha
     const bool is_app = app_ext != NULL && (app_ext[4] == '\0' || app_ext[4] == '/');
     if (!is_app)
     {
-        DNBLogThreadedIf(LOG_PROCESS, "MachProcess::PrepareForAttach(): path '%s' doesn't contain .app, we can't tell springboard to wait for launch...", path);
+        DNBLogThreadedIf(LOG_PROCESS, "MachProcess::PrepareForAttach(): path '%s' doesn't contain .app, "
+                                      "we can't tell springboard to wait for launch...",
+                                      path);
         return NULL;
     }
 
-    if (launch_flavor != eLaunchFlavorSpringBoard
-        && launch_flavor != eLaunchFlavorDefault)
+#if defined (WITH_BKS)
+    if (launch_flavor == eLaunchFlavorDefault)
+        launch_flavor = eLaunchFlavorBKS;
+    if (launch_flavor != eLaunchFlavorBKS)
+        return NULL;
+#elif defined (WITH_SPRINGBOARD)
+    if (launch_flavor == eLaunchFlavorDefault)
+        launch_flavor = eLaunchFlavorSpringBoard;
+    if (launch_flavor != eLaunchFlavorSpringBoard)
         return NULL;
+#endif
 
     std::string app_bundle_path(path, app_ext + strlen(".app"));
 
-    CFStringRef bundleIDCFStr = CopyBundleIDForPath (app_bundle_path.c_str (), err_str);
+    CFStringRef bundleIDCFStr = CopyBundleIDForPath (app_bundle_path.c_str (), attach_err);
     std::string bundleIDStr;
     CFString::UTF8(bundleIDCFStr, bundleIDStr);
-    DNBLogThreadedIf(LOG_PROCESS, "CopyBundleIDForPath (%s, err_str) returned @\"%s\"", app_bundle_path.c_str (), bundleIDStr.c_str());
+    DNBLogThreadedIf(LOG_PROCESS,
+                     "CopyBundleIDForPath (%s, err_str) returned @\"%s\"",
+                     app_bundle_path.c_str (),
+                     bundleIDStr.c_str());
 
     if (bundleIDCFStr == NULL)
     {
         return NULL;
     }
 
-    SBSApplicationLaunchError sbs_error = 0;
-
-    const char *stdout_err = "/dev/null";
-    CFString stdio_path;
-    stdio_path.SetFileSystemRepresentation (stdout_err);
+#if defined (WITH_BKS)
+    if (launch_flavor == eLaunchFlavorBKS)
+    {
+        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 
-    DNBLogThreadedIf(LOG_PROCESS, "SBSLaunchApplicationForDebugging ( @\"%s\" , NULL, NULL, NULL, @\"%s\", @\"%s\", SBSApplicationDebugOnNextLaunch | SBSApplicationLaunchWaitForDebugger )", bundleIDStr.c_str(), stdout_err, stdout_err);
-    sbs_error = SBSLaunchApplicationForDebugging (bundleIDCFStr,
-                                                  (CFURLRef)NULL,         // openURL
-                                                  NULL, // launch_argv.get(),
-                                                  NULL, // launch_envp.get(),  // CFDictionaryRef environment
-                                                  stdio_path.get(),
-                                                  stdio_path.get(),
-                                                  SBSApplicationDebugOnNextLaunch | SBSApplicationLaunchWaitForDebugger);
+        NSString *stdio_path = nil;
+        NSFileManager *file_manager = [NSFileManager defaultManager];
+        const char *null_path = "/dev/null";
+        stdio_path = [file_manager stringWithFileSystemRepresentation: null_path length: strlen(null_path)];
+
+        NSMutableDictionary *debug_options = [NSMutableDictionary dictionary];
+        NSMutableDictionary *options       = [NSMutableDictionary dictionary];
+
+        DNBLogThreadedIf(LOG_PROCESS, "Calling BKSSystemService openApplication: @\"%s\",options include stdio path: \"%s\", "
+                                      "BKSDebugOptionKeyDebugOnNextLaunch & BKSDebugOptionKeyWaitForDebugger )",
+                                      bundleIDStr.c_str(),
+                                      null_path);
+        
+        [debug_options setObject: stdio_path forKey: BKSDebugOptionKeyStandardOutPath];
+        [debug_options setObject: stdio_path forKey: BKSDebugOptionKeyStandardErrorPath];
+        [debug_options setObject: [NSNumber numberWithBool: YES] forKey: BKSDebugOptionKeyWaitForDebugger];
+        [debug_options setObject: [NSNumber numberWithBool: YES] forKey: BKSDebugOptionKeyDebugOnNextLaunch];
+        
+        [options setObject: debug_options forKey: BKSOpenApplicationOptionKeyDebuggingOptions];
 
-    if (sbs_error != SBSApplicationLaunchErrorSuccess)
+        BKSSystemService *system_service = [[BKSSystemService alloc] init];
+                
+        mach_port_t client_port = [system_service createClientPort];
+        __block dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
+        __block BKSOpenApplicationErrorCode attach_error_code = BKSOpenApplicationErrorCodeNone;
+        
+        NSString *bundleIDNSStr = (NSString *) bundleIDCFStr;
+        
+        [system_service openApplication: bundleIDNSStr
+                       options: options
+                       clientPort: client_port
+                       withResult: ^(NSError *error)
+                       {
+                            // The system service will cleanup the client port we created for us.
+                            if (error)
+                                attach_error_code = (BKSOpenApplicationErrorCode)[error code];
+                                                                       
+                            [system_service release];
+                            dispatch_semaphore_signal(semaphore);
+                        }
+        ];
+        
+        const uint32_t timeout_secs = 9;
+        
+        dispatch_time_t timeout = dispatch_time(DISPATCH_TIME_NOW, timeout_secs * NSEC_PER_SEC);
+        
+        long success = dispatch_semaphore_wait(semaphore, timeout) == 0;
+        
+        if (!success)
+        {
+            DNBLogError("timed out trying to launch %s.", bundleIDStr.c_str());
+            attach_err.SetErrorString("debugserver timed out waiting for openApplication to complete.");
+            attach_err.SetError (BKS_OPEN_APPLICATION_TIMEOUT_ERROR, DNBError::Generic);
+        }
+        else if (attach_error_code != BKSOpenApplicationErrorCodeNone)
+        {
+            SetBKSError (attach_error_code, attach_err);
+            DNBLogError("unable to launch the application with CFBundleIdentifier '%s' bks_error = %u",
+                        bundleIDStr.c_str(),
+                        attach_error_code);
+        }
+        dispatch_release(semaphore);
+        [pool drain];
+    }
+#elif defined (WITH_SPRINGBOARD)
+    if (launch_flavor == eLaunchFlavorSpringBoard)
     {
-        err_str.SetError(sbs_error, DNBError::SpringBoard);
-        return NULL;
+        SBSApplicationLaunchError sbs_error = 0;
+
+        const char *stdout_err = "/dev/null";
+        CFString stdio_path;
+        stdio_path.SetFileSystemRepresentation (stdout_err);
+
+        DNBLogThreadedIf(LOG_PROCESS, "SBSLaunchApplicationForDebugging ( @\"%s\" , NULL, NULL, NULL, @\"%s\", @\"%s\", "
+                                      "SBSApplicationDebugOnNextLaunch | SBSApplicationLaunchWaitForDebugger )",
+                                      bundleIDStr.c_str(),
+                                      stdout_err,
+                                      stdout_err);
+        
+        sbs_error = SBSLaunchApplicationForDebugging (bundleIDCFStr,
+                                                      (CFURLRef)NULL,         // openURL
+                                                      NULL, // launch_argv.get(),
+                                                      NULL, // launch_envp.get(),  // CFDictionaryRef environment
+                                                      stdio_path.get(),
+                                                      stdio_path.get(),
+                                                      SBSApplicationDebugOnNextLaunch | SBSApplicationLaunchWaitForDebugger);
+
+        if (sbs_error != SBSApplicationLaunchErrorSuccess)
+        {
+            attach_err.SetError(sbs_error, DNBError::SpringBoard);
+            return NULL;
+        }
     }
+#endif // WITH_SPRINGBOARD
 
     DNBLogThreadedIf(LOG_PROCESS, "Successfully set DebugOnNextLaunch.");
     return bundleIDCFStr;
-# else
+# else  // defined (WITH_SPRINGBOARD) || defined (WITH_BKS)
   return NULL;
 #endif
 }
@@ -1593,7 +1736,16 @@ MachProcess::CheckForProcess (const void
     if (attach_token == NULL)
         return INVALID_NUB_PROCESS;
 
-#ifdef WITH_SPRINGBOARD
+#if defined (WITH_BKS)
+    NSString *bundleIDNSStr = (NSString *) attach_token;
+    BKSSystemService *systemService = [[BKSSystemService alloc] init];
+    pid_t pid = [systemService pidForApplication: bundleIDNSStr];
+    [systemService release];
+    if (pid == 0)
+        return INVALID_NUB_PROCESS;
+    else
+        return pid;
+#elif defined (WITH_SPRINGBOARD)
     CFStringRef bundleIDCFStr = (CFStringRef) attach_token;
     Boolean got_it;
     nub_process_t attach_pid;
@@ -1602,8 +1754,9 @@ MachProcess::CheckForProcess (const void
         return attach_pid;
     else
         return INVALID_NUB_PROCESS;
-#endif
+#else
     return INVALID_NUB_PROCESS;
+#endif
 }
 
 // Call this to clean up after you have either attached or given up on the attach.
@@ -1614,10 +1767,18 @@ MachProcess::CheckForProcess (const void
 void
 MachProcess::CleanupAfterAttach (const void *attach_token, bool success, DNBError &err_str)
 {
-#ifdef WITH_SPRINGBOARD
     if (attach_token == NULL)
         return;
 
+#if defined (WITH_BKS)
+
+    if (!success)
+    {
+        BKSCleanupAfterAttach (attach_token, err_str);
+    }
+    CFRelease((CFStringRef) attach_token);
+    
+#elif defined (WITH_SPRINGBOARD)
     // Tell SpringBoard to cancel the debug on next launch of this application
     // if we failed to attach
     if (!success)
@@ -1657,6 +1818,7 @@ MachProcess::LaunchForDebug
     bool no_stdio,
     nub_launch_flavor_t launch_flavor,
     int disable_aslr,
+    const char *event_data,
     DNBError &launch_err
 )
 {
@@ -1673,7 +1835,23 @@ MachProcess::LaunchForDebug
     case eLaunchFlavorForkExec:
         m_pid = MachProcess::ForkChildForPTraceDebugging (path, argv, envp, this, launch_err);
         break;
-
+#ifdef WITH_BKS
+    case eLaunchFlavorBKS:
+        {
+            const char *app_ext = strstr(path, ".app");
+            if (app_ext && (app_ext[4] == '\0' || app_ext[4] == '/'))
+            {
+                std::string app_bundle_path(path, app_ext + strlen(".app"));
+                if (BKSLaunchForDebug (app_bundle_path.c_str(), argv, envp, no_stdio, disable_aslr, event_data, launch_err) != 0)
+                    return m_pid; // A successful SBLaunchForDebug() returns and assigns a non-zero m_pid.
+                else
+                    break; // We tried a BKS launch, but didn't succeed lets get out
+            }
+        }
+        // In case the executable name has a ".app" fragment which confuses our debugserver,
+        // let's do an intentional fallthrough here...
+        launch_flavor = eLaunchFlavorPosixSpawn;
+#endif
 #ifdef WITH_SPRINGBOARD
 
     case eLaunchFlavorSpringBoard:
@@ -1696,7 +1874,7 @@ MachProcess::LaunchForDebug
             if (app_ext)
             {
                 std::string app_bundle_path(path, app_ext + strlen(".app"));
-                if (SBLaunchForDebug (app_bundle_path.c_str(), argv, envp, no_stdio, launch_err) != 0)
+                if (SBLaunchForDebug (app_bundle_path.c_str(), argv, envp, no_stdio, disable_aslr, launch_err) != 0)
                     return m_pid; // A successful SBLaunchForDebug() returns and assigns a non-zero m_pid.
                 else
                     break; // We tried a springboard launch, but didn't succeed lets get out
@@ -2063,10 +2241,47 @@ MachProcess::ForkChildForPTraceDebugging
     return pid;
 }
 
+#if defined (WITH_SPRINGBOARD) || defined (WITH_BKS)
+// This returns a CFRetained pointer to the Bundle ID for app_bundle_path,
+// or NULL if there was some problem getting the bundle id.
+static CFStringRef
+CopyBundleIDForPath (const char *app_bundle_path, DNBError &err_str)
+{
+    CFBundle bundle(app_bundle_path);
+    CFStringRef bundleIDCFStr = bundle.GetIdentifier();
+    std::string bundleID;
+    if (CFString::UTF8(bundleIDCFStr, bundleID) == NULL)
+    {
+        struct stat app_bundle_stat;
+        char err_msg[PATH_MAX];
+
+        if (::stat (app_bundle_path, &app_bundle_stat) < 0)
+        {
+            err_str.SetError(errno, DNBError::POSIX);
+            snprintf(err_msg, sizeof(err_msg), "%s: \"%s\"", err_str.AsString(), app_bundle_path);
+            err_str.SetErrorString(err_msg);
+            DNBLogThreadedIf(LOG_PROCESS, "%s() error: %s", __FUNCTION__, err_msg);
+        }
+        else
+        {
+            err_str.SetError(-1, DNBError::Generic);
+            snprintf(err_msg, sizeof(err_msg), "failed to extract CFBundleIdentifier from %s", app_bundle_path);
+            err_str.SetErrorString(err_msg);
+            DNBLogThreadedIf(LOG_PROCESS, "%s() error: failed to extract CFBundleIdentifier from '%s'", __FUNCTION__, app_bundle_path);
+        }
+        return NULL;
+    }
+
+    DNBLogThreadedIf(LOG_PROCESS, "%s() extracted CFBundleIdentifier: %s", __FUNCTION__, bundleID.c_str());
+    CFRetain (bundleIDCFStr);
+
+    return bundleIDCFStr;
+}
+#endif // #if defined 9WITH_SPRINGBOARD) || defined (WITH_BKS)
 #ifdef WITH_SPRINGBOARD
 
 pid_t
-MachProcess::SBLaunchForDebug (const char *path, char const *argv[], char const *envp[], bool no_stdio, DNBError &launch_err)
+MachProcess::SBLaunchForDebug (const char *path, char const *argv[], char const *envp[], bool no_stdio, bool disable_aslr, DNBError &launch_err)
 {
     // Clear out and clean up from any current state
     Clear();
@@ -2115,42 +2330,6 @@ MachProcess::SBLaunchForDebug (const cha
 
 #include <servers/bootstrap.h>
 
-// This returns a CFRetained pointer to the Bundle ID for app_bundle_path,
-// or NULL if there was some problem getting the bundle id.
-static CFStringRef
-CopyBundleIDForPath (const char *app_bundle_path, DNBError &err_str)
-{
-    CFBundle bundle(app_bundle_path);
-    CFStringRef bundleIDCFStr = bundle.GetIdentifier();
-    std::string bundleID;
-    if (CFString::UTF8(bundleIDCFStr, bundleID) == NULL)
-    {
-        struct stat app_bundle_stat;
-        char err_msg[PATH_MAX];
-
-        if (::stat (app_bundle_path, &app_bundle_stat) < 0)
-        {
-            err_str.SetError(errno, DNBError::POSIX);
-            snprintf(err_msg, sizeof(err_msg), "%s: \"%s\"", err_str.AsString(), app_bundle_path);
-            err_str.SetErrorString(err_msg);
-            DNBLogThreadedIf(LOG_PROCESS, "%s() error: %s", __FUNCTION__, err_msg);
-        }
-        else
-        {
-            err_str.SetError(-1, DNBError::Generic);
-            snprintf(err_msg, sizeof(err_msg), "failed to extract CFBundleIdentifier from %s", app_bundle_path);
-            err_str.SetErrorString(err_msg);
-            DNBLogThreadedIf(LOG_PROCESS, "%s() error: failed to extract CFBundleIdentifier from '%s'", __FUNCTION__, app_bundle_path);
-        }
-        return NULL;
-    }
-
-    DNBLogThreadedIf(LOG_PROCESS, "%s() extracted CFBundleIdentifier: %s", __FUNCTION__, bundleID.c_str());
-    CFRetain (bundleIDCFStr);
-
-    return bundleIDCFStr;
-}
-
 pid_t
 MachProcess::SBForkChildForPTraceDebugging (const char *app_bundle_path, char const *argv[], char const *envp[], bool no_stdio, MachProcess* process, DNBError &launch_err)
 {
@@ -2244,10 +2423,13 @@ MachProcess::SBForkChildForPTraceDebuggi
     CFStringRef bundleIDCFStr = CopyBundleIDForPath (app_bundle_path, launch_err);
     if (bundleIDCFStr == NULL)
         return INVALID_NUB_PROCESS;
-
+    
+    // This is just for logging:
     std::string bundleID;
     CFString::UTF8(bundleIDCFStr, bundleID);
 
+    DNBLogThreadedIf(LOG_PROCESS, "%s() serialized launch arg array", __FUNCTION__);
+
     // Find SpringBoard
     SBSApplicationLaunchError sbs_error = 0;
     sbs_error = SBSLaunchApplicationForDebugging (bundleIDCFStr,
@@ -2306,4 +2488,419 @@ MachProcess::SBForkChildForPTraceDebuggi
 
 #endif // #ifdef WITH_SPRINGBOARD
 
+#ifdef WITH_BKS
+
+
+// This function runs the BKSSystemService method openApplication:options:clientPort:withResult,
+// messaging the app passed in bundleIDNSStr.
+// The function should be run inside of an NSAutoReleasePool.
+//
+// It will use the "options" dictionary passed in, and fill the error passed in if there is an error.
+// If return_pid is not NULL, we'll fetch the pid that was made for the bundleID.
+// If bundleIDNSStr is NULL, then the system application will be messaged.
 
+static bool
+CallBKSSystemServiceOpenApplication (NSString *bundleIDNSStr, NSDictionary *options, DNBError &error, pid_t *return_pid)
+{
+    // Now make our systemService:
+    BKSSystemService *system_service = [[BKSSystemService alloc] init];
+    
+    if (bundleIDNSStr == nil)
+    {
+        bundleIDNSStr = [system_service systemApplicationBundleIdentifier];
+        if (bundleIDNSStr == nil)
+        {
+            // Okay, no system app...
+            error.SetErrorString("No system application to message.");
+            return false;
+        }
+    }
+    
+    mach_port_t client_port = [system_service createClientPort];
+    __block dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
+    __block BKSOpenApplicationErrorCode open_app_error = BKSOpenApplicationErrorCodeNone;
+    bool wants_pid = (return_pid != NULL);
+    __block pid_t pid_in_block;
+    
+    const char *cstr = [bundleIDNSStr UTF8String];
+    if (!cstr)
+        cstr = "<Unknown Bundle ID>";
+    
+    DNBLog ("About to launch process for bundle ID: %s", cstr);
+    [system_service openApplication: bundleIDNSStr
+                    options: options
+                    clientPort: client_port
+                    withResult: ^(NSError *bks_error)
+                    {
+                        // The system service will cleanup the client port we created for us.
+                        if (bks_error)
+                            open_app_error = (BKSOpenApplicationErrorCode)[bks_error code];
+                                        
+                        if (open_app_error == BKSOpenApplicationErrorCodeNone)
+                        {
+                            if (wants_pid)
+                            {
+                                pid_in_block = [system_service pidForApplication: bundleIDNSStr];
+                                DNBLog("In completion handler, got pid for bundle id, pid: %d.", pid_in_block);
+                                DNBLogThreadedIf(LOG_PROCESS, "In completion handler, got pid for bundle id, pid: %d.", pid_in_block);
+                            }
+                            else
+                                DNBLogThreadedIf (LOG_PROCESS, "In completion handler: success.");
+                        }
+                        else
+                        {
+                            const char *error_str = [[bks_error localizedDescription] UTF8String];
+                            DNBLogThreadedIf(LOG_PROCESS, "In completion handler for send event, got error \"%s\"(%d).",
+                                             error_str ? error_str : "<unknown error>",
+                                             open_app_error);
+                            // REMOVE ME
+                            DNBLogError ("In completion handler for send event, got error \"%s\"(%d).",
+                                             error_str ? error_str : "<unknown error>",
+                                             open_app_error);
+                        }
+ 
+                        [system_service release];
+                        dispatch_semaphore_signal(semaphore);
+                    }
+
+    ];
+    
+    const uint32_t timeout_secs = 9;
+    
+    dispatch_time_t timeout = dispatch_time(DISPATCH_TIME_NOW, timeout_secs * NSEC_PER_SEC);
+    
+    long success = dispatch_semaphore_wait(semaphore, timeout) == 0;
+    
+    dispatch_release(semaphore);
+    
+    if (!success)
+    {
+        DNBLogError("timed out trying to send openApplication to %s.", cstr);
+        error.SetError (BKS_OPEN_APPLICATION_TIMEOUT_ERROR, DNBError::Generic);
+        error.SetErrorString ("timed out trying to launch app");
+    }
+    else if (open_app_error != BKSOpenApplicationErrorCodeNone)
+    {
+        SetBKSError (open_app_error, error);
+        DNBLogError("unable to launch the application with CFBundleIdentifier '%s' bks_error = %u", cstr, open_app_error);
+        success = false;
+    }
+    else if (wants_pid)
+    {
+        *return_pid = pid_in_block;
+        DNBLogThreadedIf (LOG_PROCESS, "Out of completion handler, pid from block %d and passing out: %d", pid_in_block, *return_pid);
+    }
+    
+
+    return success;
+}
+
+void
+MachProcess::BKSCleanupAfterAttach (const void *attach_token, DNBError &err_str)
+{
+    bool success;
+    
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    
+    // Instead of rewriting CopyBundleIDForPath for NSStrings, we'll just use toll-free bridging here:
+    NSString *bundleIDNSStr = (NSString *) attach_token;
+
+    // Okay, now let's assemble all these goodies into the BackBoardServices options mega-dictionary:
+    
+    // First we have the debug sub-dictionary:
+    NSMutableDictionary *debug_options = [NSMutableDictionary dictionary];
+    [debug_options setObject: [NSNumber numberWithBool: YES] forKey: BKSDebugOptionKeyCancelDebugOnNextLaunch];
+    
+    // That will go in the overall dictionary:
+    
+    NSMutableDictionary *options = [NSMutableDictionary dictionary];
+    [options setObject: debug_options forKey: BKSOpenApplicationOptionKeyDebuggingOptions];
+
+    success = CallBKSSystemServiceOpenApplication(bundleIDNSStr, options, err_str, NULL);
+    
+    if (!success)
+    {
+        DNBLogError ("error trying to cancel debug on next launch for %s: %s", [bundleIDNSStr UTF8String], err_str.AsString());
+    }
+
+    [pool drain];
+}
+
+bool
+AddEventDataToOptions (NSMutableDictionary *options, const char *event_data, DNBError &option_error)
+{
+    if (strcmp (event_data, "BackgroundContentFetching") == 0)
+    {
+        DNBLog("Setting ActivateForEvent key in options dictionary.");
+        NSDictionary *event_details = [NSDictionary dictionary];
+        NSDictionary *event_dictionary = [NSDictionary dictionaryWithObject:event_details forKey:BKSActivateForEventOptionTypeBackgroundContentFetching];
+        [options setObject: event_dictionary forKey: BKSOpenApplicationOptionKeyActivateForEvent];
+        return true;
+    }
+    else
+    {
+        DNBLogError ("Unrecognized event type: %s.  Ignoring.", event_data);
+        option_error.SetErrorString("Unrecognized event data.");
+        return false;
+    }
+    
+}
+
+pid_t
+MachProcess::BKSLaunchForDebug (const char *path, char const *argv[], char const *envp[], bool no_stdio, bool disable_aslr, const char *event_data, DNBError &launch_err)
+{
+    // Clear out and clean up from any current state
+    Clear();
+
+    DNBLogThreadedIf(LOG_PROCESS, "%s( '%s', argv)", __FUNCTION__, path);
+
+    // Fork a child process for debugging
+    SetState(eStateLaunching);
+    m_pid = BKSForkChildForPTraceDebugging(path, argv, envp, no_stdio, disable_aslr, event_data, launch_err);
+    if (m_pid != 0)
+    {
+        m_flags |= eMachProcessFlagsUsingBKS;
+        m_path = path;
+        size_t i;
+        char const *arg;
+        for (i=0; (arg = argv[i]) != NULL; i++)
+            m_args.push_back(arg);
+        m_task.StartExceptionThread(launch_err);
+        
+        if (launch_err.Fail())
+        {
+            if (launch_err.AsString() == NULL)
+                launch_err.SetErrorString("unable to start the exception thread");
+            DNBLog ("Could not get inferior's Mach exception port, sending ptrace PT_KILL and exiting.");
+            ::ptrace (PT_KILL, m_pid, 0, 0);
+            m_pid = INVALID_NUB_PROCESS;
+            return INVALID_NUB_PROCESS;
+        }
+
+        StartSTDIOThread();
+        SetState (eStateAttaching);
+        int err = ::ptrace (PT_ATTACHEXC, m_pid, 0, 0);
+        if (err == 0)
+        {
+            m_flags |= eMachProcessFlagsAttached;
+            DNBLogThreadedIf(LOG_PROCESS, "successfully attached to pid %d", m_pid);
+        }
+        else
+        {
+            SetState (eStateExited);
+            DNBLogThreadedIf(LOG_PROCESS, "error: failed to attach to pid %d", m_pid);
+        }
+    }
+    return m_pid;
+}
+
+pid_t
+MachProcess::BKSForkChildForPTraceDebugging (const char *app_bundle_path,
+                                             char const *argv[],
+                                             char const *envp[],
+                                             bool no_stdio,
+                                             bool disable_aslr,
+                                             const char *event_data,
+                                             DNBError &launch_err)
+{
+    if (argv[0] == NULL)
+        return INVALID_NUB_PROCESS;
+
+    DNBLogThreadedIf(LOG_PROCESS, "%s( '%s', argv, %p)", __FUNCTION__, app_bundle_path, this);
+    
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+    size_t argc = 0;
+    // Count the number of arguments
+    while (argv[argc] != NULL)
+        argc++;
+
+    // Enumerate the arguments
+    size_t first_launch_arg_idx = 1;
+
+    NSMutableArray *launch_argv = nil;
+    
+    if (argv[first_launch_arg_idx])
+    {
+        size_t launch_argc = argc > 0 ? argc - 1 : 0;
+        launch_argv = [NSMutableArray arrayWithCapacity: launch_argc];
+        size_t i;
+        char const *arg;
+        NSString *launch_arg;
+        for (i=first_launch_arg_idx; (i < argc) && ((arg = argv[i]) != NULL); i++)
+        {
+            launch_arg = [NSString stringWithUTF8String: arg];
+            // FIXME: Should we silently eat an argument that we can't convert into a UTF8 string?
+            if (launch_arg != nil)
+                [launch_argv addObject: launch_arg];
+            else
+                break;
+        }
+    }
+
+    NSMutableDictionary *launch_envp = nil;
+    if (envp[0])
+    {
+        launch_envp = [[NSMutableDictionary alloc] init];
+        const char *value;
+        int name_len;
+        NSString *name_string, *value_string;
+
+        for (int i = 0; envp[i] != NULL; i++)
+        {
+            value = strstr (envp[i], "=");
+
+            // If the name field is empty or there's no =, skip it.  Somebody's messing with us.
+            if (value == NULL || value == envp[i])
+                continue;
+
+            name_len = value - envp[i];
+
+            // Now move value over the "="
+            value++;
+            name_string = [[NSString alloc] initWithBytes: envp[i] length: name_len encoding: NSUTF8StringEncoding];
+            value_string = [NSString stringWithUTF8String: value];
+            [launch_envp setObject: value_string forKey: name_string];
+        }
+    }
+
+    NSString *stdio_path = nil;
+    NSFileManager *file_manager = [NSFileManager defaultManager];
+
+    PseudoTerminal pty;
+    if (!no_stdio)
+    {
+        PseudoTerminal::Error pty_err = pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY);
+        if (pty_err == PseudoTerminal::success)
+        {
+            const char* slave_name = pty.SlaveName();
+            DNBLogThreadedIf(LOG_PROCESS, "%s() successfully opened master pty, slave is %s", __FUNCTION__, slave_name);
+            if (slave_name && slave_name[0])
+            {
+                ::chmod (slave_name, S_IRWXU | S_IRWXG | S_IRWXO);
+                stdio_path = [file_manager stringWithFileSystemRepresentation: slave_name length: strlen(slave_name)];
+            }
+        }
+    }
+    
+    if (stdio_path == nil)
+    {
+        const char *null_path = "/dev/null";
+        stdio_path = [file_manager stringWithFileSystemRepresentation: null_path length: strlen(null_path)];
+    }
+    
+    CFStringRef bundleIDCFStr = CopyBundleIDForPath (app_bundle_path, launch_err);
+    if (bundleIDCFStr == NULL)
+    {
+        [pool drain];
+        return INVALID_NUB_PROCESS;
+    }
+
+    // Instead of rewriting CopyBundleIDForPath for NSStrings, we'll just use toll-free bridging here:
+    NSString *bundleIDNSStr = (NSString *) bundleIDCFStr;
+
+    // Okay, now let's assemble all these goodies into the BackBoardServices options mega-dictionary:
+    
+    // First we have the debug sub-dictionary:
+    NSMutableDictionary *debug_options = [NSMutableDictionary dictionary];
+    if (launch_argv != nil)
+        [debug_options setObject: launch_argv forKey: BKSDebugOptionKeyArguments];
+    if (launch_envp != nil)
+        [debug_options setObject: launch_envp forKey: BKSDebugOptionKeyEnvironment];
+
+    [debug_options setObject: stdio_path forKey: BKSDebugOptionKeyStandardOutPath];
+    [debug_options setObject: stdio_path forKey: BKSDebugOptionKeyStandardErrorPath];
+    [debug_options setObject: [NSNumber numberWithBool: YES] forKey: BKSDebugOptionKeyWaitForDebugger];
+    if (disable_aslr)
+        [debug_options setObject: [NSNumber numberWithBool: YES] forKey: BKSDebugOptionKeyDisableASLR];
+    
+    // That will go in the overall dictionary:
+    
+    NSMutableDictionary *options = [NSMutableDictionary dictionary];
+    [options setObject: debug_options forKey: BKSOpenApplicationOptionKeyDebuggingOptions];
+
+    // For now we only support one kind of event: the "fetch" event, which is indicated by the fact that its data
+    // is an empty dictionary.
+    if (event_data != NULL && *event_data != '\0')
+    {
+        if (!AddEventDataToOptions(options, event_data, launch_err))
+        {
+            [pool drain];
+            return INVALID_NUB_PROCESS;
+        }
+    }
+    
+    // And there are some other options at the top level in this dictionary:
+    [options setObject: [NSNumber numberWithBool: YES] forKey: BKSOpenApplicationOptionKeyUnlockDevice];
+
+    pid_t return_pid = INVALID_NUB_PROCESS;
+    bool success = CallBKSSystemServiceOpenApplication(bundleIDNSStr, options, launch_err, &return_pid);
+    
+    if (success)
+    {
+        int master_fd = pty.ReleaseMasterFD();
+        SetChildFileDescriptors(master_fd, master_fd, master_fd);
+        CFString::UTF8(bundleIDCFStr, m_bundle_id);
+    }
+    
+    [pool drain];
+
+    return return_pid;
+}
+
+bool
+MachProcess::BKSSendEvent (const char *event_data, DNBError &send_err)
+{
+    bool return_value = true;
+    
+    if (event_data == NULL || *event_data == '\0')
+    {
+        DNBLogError ("SendEvent called with NULL event data.");
+        send_err.SetErrorString("SendEvent called with empty event data");
+        return false;
+    }
+    
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    
+    if (strcmp (event_data, "BackgroundApplication") == 0)
+    {
+        // This is an event I cooked up.  What you actually do is foreground the system app, so:
+        return_value = CallBKSSystemServiceOpenApplication(nil, nil, send_err, NULL);
+        if (!return_value)
+        {
+            DNBLogError ("Failed to background application, error: %s.", send_err.AsString());
+        }
+    }
+    else
+    {
+        if (m_bundle_id.empty())
+        {
+            // See if we can figure out the bundle ID for this PID:
+            
+            DNBLogError ("Tried to send event \"%s\" to a process that has no bundle ID.", event_data);
+            return false;
+        }
+        
+        NSString *bundleIDNSStr = [NSString stringWithUTF8String:m_bundle_id.c_str()];
+        
+        NSMutableDictionary *options = [NSMutableDictionary dictionary];
+
+        if (!AddEventDataToOptions(options, event_data, send_err))
+        {
+            [pool drain];
+            return false;
+        }
+
+
+        return_value = CallBKSSystemServiceOpenApplication(bundleIDNSStr, options, send_err, NULL);
+        
+        if (!return_value)
+        {
+            DNBLogError ("Failed to send event: %s, error: %s.", event_data, send_err.AsString());
+        }
+    }
+    
+    [pool drain];
+    return return_value;
+}
+#endif // WITH_BKS

Removed: lldb/trunk/tools/debugserver/source/MacOSX/MachTask.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachTask.cpp?rev=205112&view=auto
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachTask.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachTask.cpp (removed)
@@ -1,1043 +0,0 @@
-//===-- MachTask.cpp --------------------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//----------------------------------------------------------------------
-//
-//  MachTask.cpp
-//  debugserver
-//
-//  Created by Greg Clayton on 12/5/08.
-//
-//===----------------------------------------------------------------------===//
-
-#include "MachTask.h"
-
-// C Includes
-
-#include <mach-o/dyld_images.h>
-#include <mach/mach_vm.h>
-#import <sys/sysctl.h>
-
-// C++ Includes
-#include <iomanip>
-#include <sstream>
-
-// Other libraries and framework includes
-// Project includes
-#include "CFUtils.h"
-#include "DNB.h"
-#include "DNBError.h"
-#include "DNBLog.h"
-#include "MachProcess.h"
-#include "DNBDataRef.h"
-#include "stack_logging.h"
-
-#ifdef WITH_SPRINGBOARD
-
-#include <CoreFoundation/CoreFoundation.h>
-#include <SpringBoardServices/SpringBoardServer.h>
-#include <SpringBoardServices/SBSWatchdogAssertion.h>
-
-#endif
-
-//----------------------------------------------------------------------
-// MachTask constructor
-//----------------------------------------------------------------------
-MachTask::MachTask(MachProcess *process) :
-    m_process (process),
-    m_task (TASK_NULL),
-    m_vm_memory (),
-    m_exception_thread (0),
-    m_exception_port (MACH_PORT_NULL)
-{
-    memset(&m_exc_port_info, 0, sizeof(m_exc_port_info));
-}
-
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-MachTask::~MachTask()
-{
-    Clear();
-}
-
-
-//----------------------------------------------------------------------
-// MachTask::Suspend
-//----------------------------------------------------------------------
-kern_return_t
-MachTask::Suspend()
-{
-    DNBError err;
-    task_t task = TaskPort();
-    err = ::task_suspend (task);
-    if (DNBLogCheckLogBit(LOG_TASK) || err.Fail())
-        err.LogThreaded("::task_suspend ( target_task = 0x%4.4x )", task);
-    return err.Error();
-}
-
-
-//----------------------------------------------------------------------
-// MachTask::Resume
-//----------------------------------------------------------------------
-kern_return_t
-MachTask::Resume()
-{
-    struct task_basic_info task_info;
-    task_t task = TaskPort();
-    if (task == TASK_NULL)
-        return KERN_INVALID_ARGUMENT;
-
-    DNBError err;
-    err = BasicInfo(task, &task_info);
-
-    if (err.Success())
-    {
-        // task_resume isn't counted like task_suspend calls are, are, so if the 
-        // task is not suspended, don't try and resume it since it is already 
-        // running
-        if (task_info.suspend_count > 0)
-        {
-            err = ::task_resume (task);
-            if (DNBLogCheckLogBit(LOG_TASK) || err.Fail())
-                err.LogThreaded("::task_resume ( target_task = 0x%4.4x )", task);
-        }
-    }
-    return err.Error();
-}
-
-//----------------------------------------------------------------------
-// MachTask::ExceptionPort
-//----------------------------------------------------------------------
-mach_port_t
-MachTask::ExceptionPort() const
-{
-    return m_exception_port;
-}
-
-//----------------------------------------------------------------------
-// MachTask::ExceptionPortIsValid
-//----------------------------------------------------------------------
-bool
-MachTask::ExceptionPortIsValid() const
-{
-    return MACH_PORT_VALID(m_exception_port);
-}
-
-
-//----------------------------------------------------------------------
-// MachTask::Clear
-//----------------------------------------------------------------------
-void
-MachTask::Clear()
-{
-    // Do any cleanup needed for this task
-    m_task = TASK_NULL;
-    m_exception_thread = 0;
-    m_exception_port = MACH_PORT_NULL;
-
-}
-
-
-//----------------------------------------------------------------------
-// MachTask::SaveExceptionPortInfo
-//----------------------------------------------------------------------
-kern_return_t
-MachTask::SaveExceptionPortInfo()
-{
-    return m_exc_port_info.Save(TaskPort());
-}
-
-//----------------------------------------------------------------------
-// MachTask::RestoreExceptionPortInfo
-//----------------------------------------------------------------------
-kern_return_t
-MachTask::RestoreExceptionPortInfo()
-{
-    return m_exc_port_info.Restore(TaskPort());
-}
-
-
-//----------------------------------------------------------------------
-// MachTask::ReadMemory
-//----------------------------------------------------------------------
-nub_size_t
-MachTask::ReadMemory (nub_addr_t addr, nub_size_t size, void *buf)
-{
-    nub_size_t n = 0;
-    task_t task = TaskPort();
-    if (task != TASK_NULL)
-    {
-        n = m_vm_memory.Read(task, addr, buf, size);
-
-        DNBLogThreadedIf(LOG_MEMORY, "MachTask::ReadMemory ( addr = 0x%8.8llx, size = %llu, buf = %p) => %llu bytes read", (uint64_t)addr, (uint64_t)size, buf, (uint64_t)n);
-        if (DNBLogCheckLogBit(LOG_MEMORY_DATA_LONG) || (DNBLogCheckLogBit(LOG_MEMORY_DATA_SHORT) && size <= 8))
-        {
-            DNBDataRef data((uint8_t*)buf, n, false);
-            data.Dump(0, n, addr, DNBDataRef::TypeUInt8, 16);
-        }
-    }
-    return n;
-}
-
-
-//----------------------------------------------------------------------
-// MachTask::WriteMemory
-//----------------------------------------------------------------------
-nub_size_t
-MachTask::WriteMemory (nub_addr_t addr, nub_size_t size, const void *buf)
-{
-    nub_size_t n = 0;
-    task_t task = TaskPort();
-    if (task != TASK_NULL)
-    {
-        n = m_vm_memory.Write(task, addr, buf, size);
-        DNBLogThreadedIf(LOG_MEMORY, "MachTask::WriteMemory ( addr = 0x%8.8llx, size = %llu, buf = %p) => %llu bytes written", (uint64_t)addr, (uint64_t)size, buf, (uint64_t)n);
-        if (DNBLogCheckLogBit(LOG_MEMORY_DATA_LONG) || (DNBLogCheckLogBit(LOG_MEMORY_DATA_SHORT) && size <= 8))
-        {
-            DNBDataRef data((uint8_t*)buf, n, false);
-            data.Dump(0, n, addr, DNBDataRef::TypeUInt8, 16);
-        }
-    }
-    return n;
-}
-
-//----------------------------------------------------------------------
-// MachTask::MemoryRegionInfo
-//----------------------------------------------------------------------
-int
-MachTask::GetMemoryRegionInfo (nub_addr_t addr, DNBRegionInfo *region_info)
-{
-    task_t task = TaskPort();
-    if (task == TASK_NULL)
-        return -1;
-
-    int ret = m_vm_memory.GetMemoryRegionInfo(task, addr, region_info);
-    DNBLogThreadedIf(LOG_MEMORY, "MachTask::MemoryRegionInfo ( addr = 0x%8.8llx ) => %i  (start = 0x%8.8llx, size = 0x%8.8llx, permissions = %u)",
-                     (uint64_t)addr, 
-                     ret,
-                     (uint64_t)region_info->addr,
-                     (uint64_t)region_info->size,
-                     region_info->permissions);
-    return ret;
-}
-
-#define TIME_VALUE_TO_TIMEVAL(a, r) do {        \
-(r)->tv_sec = (a)->seconds;                     \
-(r)->tv_usec = (a)->microseconds;               \
-} while (0)
-
-// We should consider moving this into each MacThread.
-static void get_threads_profile_data(DNBProfileDataScanType scanType, task_t task, nub_process_t pid, std::vector<uint64_t> &threads_id, std::vector<std::string> &threads_name, std::vector<uint64_t> &threads_used_usec)
-{
-    kern_return_t kr;
-    thread_act_array_t threads;
-    mach_msg_type_number_t tcnt;
-    
-    kr = task_threads(task, &threads, &tcnt);
-    if (kr != KERN_SUCCESS)
-        return;
-    
-    for (int i = 0; i < tcnt; i++)
-    {
-        thread_identifier_info_data_t identifier_info;
-        mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
-        kr = ::thread_info(threads[i], THREAD_IDENTIFIER_INFO, (thread_info_t)&identifier_info, &count);
-        if (kr != KERN_SUCCESS) continue;
-        
-        thread_basic_info_data_t basic_info;
-        count = THREAD_BASIC_INFO_COUNT;
-        kr = ::thread_info(threads[i], THREAD_BASIC_INFO, (thread_info_t)&basic_info, &count);
-        if (kr != KERN_SUCCESS) continue;
-
-        if ((basic_info.flags & TH_FLAGS_IDLE) == 0)
-        {
-            nub_thread_t tid = MachThread::GetGloballyUniqueThreadIDForMachPortID (threads[i]);
-            threads_id.push_back(tid);
-            
-            if ((scanType & eProfileThreadName) && (identifier_info.thread_handle != 0))
-            {
-                struct proc_threadinfo proc_threadinfo;
-                int len = ::proc_pidinfo(pid, PROC_PIDTHREADINFO, identifier_info.thread_handle, &proc_threadinfo, PROC_PIDTHREADINFO_SIZE);
-                if (len && proc_threadinfo.pth_name[0])
-                {
-                    threads_name.push_back(proc_threadinfo.pth_name);
-                }
-                else
-                {
-                    threads_name.push_back("");
-                }
-            }
-            else
-            {
-                threads_name.push_back("");
-            }
-            struct timeval tv;
-            struct timeval thread_tv;
-            TIME_VALUE_TO_TIMEVAL(&basic_info.user_time, &thread_tv);
-            TIME_VALUE_TO_TIMEVAL(&basic_info.system_time, &tv);
-            timeradd(&thread_tv, &tv, &thread_tv);
-            uint64_t used_usec = thread_tv.tv_sec * 1000000ULL + thread_tv.tv_usec;
-            threads_used_usec.push_back(used_usec);
-        }
-        
-        kr = mach_port_deallocate(mach_task_self(), threads[i]);
-    }
-    kr = mach_vm_deallocate(mach_task_self(), (mach_vm_address_t)(uintptr_t)threads, tcnt * sizeof(*threads));
-}
-
-#define RAW_HEXBASE     std::setfill('0') << std::hex << std::right
-#define DECIMAL         std::dec << std::setfill(' ')
-std::string
-MachTask::GetProfileData (DNBProfileDataScanType scanType)
-{
-    std::string result;
-    
-    static int32_t numCPU = -1;
-    struct host_cpu_load_info host_info;
-    if (scanType & eProfileHostCPU)
-    {
-        int32_t mib[] = {CTL_HW, HW_AVAILCPU};
-        size_t len = sizeof(numCPU);
-        if (numCPU == -1)
-        {
-            if (sysctl(mib, sizeof(mib) / sizeof(int32_t), &numCPU, &len, NULL, 0) != 0)
-                return result;
-        }
-        
-        mach_port_t localHost = mach_host_self();
-        mach_msg_type_number_t count = HOST_CPU_LOAD_INFO_COUNT;
-        kern_return_t kr = host_statistics(localHost, HOST_CPU_LOAD_INFO, (host_info_t)&host_info, &count);
-        if (kr != KERN_SUCCESS)
-            return result;
-    }
-    
-    task_t task = TaskPort();
-    if (task == TASK_NULL)
-        return result;
-    
-    struct task_basic_info task_info;
-    DNBError err;
-    err = BasicInfo(task, &task_info);
-    
-    if (!err.Success())
-        return result;
-    
-    uint64_t elapsed_usec = 0;
-    uint64_t task_used_usec = 0;
-    if (scanType & eProfileCPU)
-    {
-        // Get current used time.
-        struct timeval current_used_time;
-        struct timeval tv;
-        TIME_VALUE_TO_TIMEVAL(&task_info.user_time, &current_used_time);
-        TIME_VALUE_TO_TIMEVAL(&task_info.system_time, &tv);
-        timeradd(&current_used_time, &tv, &current_used_time);
-        task_used_usec = current_used_time.tv_sec * 1000000ULL + current_used_time.tv_usec;
-        
-        struct timeval current_elapsed_time;
-        int res = gettimeofday(&current_elapsed_time, NULL);
-        if (res == 0)
-        {
-            elapsed_usec = current_elapsed_time.tv_sec * 1000000ULL + current_elapsed_time.tv_usec;
-        }
-    }
-    
-    std::vector<uint64_t> threads_id;
-    std::vector<std::string> threads_name;
-    std::vector<uint64_t> threads_used_usec;
-
-    if (scanType & eProfileThreadsCPU)
-    {
-        get_threads_profile_data(scanType, task, m_process->ProcessID(), threads_id, threads_name, threads_used_usec);
-    }
-    
-    struct vm_statistics vm_stats;
-    uint64_t physical_memory;
-    mach_vm_size_t rprvt = 0;
-    mach_vm_size_t rsize = 0;
-    mach_vm_size_t vprvt = 0;
-    mach_vm_size_t vsize = 0;
-    mach_vm_size_t dirty_size = 0;
-    mach_vm_size_t purgeable = 0;
-    mach_vm_size_t anonymous = 0;
-    if (m_vm_memory.GetMemoryProfile(scanType, task, task_info, m_process->GetCPUType(), m_process->ProcessID(), vm_stats, physical_memory, rprvt, rsize, vprvt, vsize, dirty_size, purgeable, anonymous))
-    {
-        std::ostringstream profile_data_stream;
-        
-        if (scanType & eProfileHostCPU)
-        {
-            profile_data_stream << "num_cpu:" << numCPU << ';';
-            profile_data_stream << "host_user_ticks:" << host_info.cpu_ticks[CPU_STATE_USER] << ';';
-            profile_data_stream << "host_sys_ticks:" << host_info.cpu_ticks[CPU_STATE_SYSTEM] << ';';
-            profile_data_stream << "host_idle_ticks:" << host_info.cpu_ticks[CPU_STATE_IDLE] << ';';
-        }
-        
-        if (scanType & eProfileCPU)
-        {
-            profile_data_stream << "elapsed_usec:" << elapsed_usec << ';';
-            profile_data_stream << "task_used_usec:" << task_used_usec << ';';
-        }
-        
-        if (scanType & eProfileThreadsCPU)
-        {
-            int num_threads = threads_id.size();
-            for (int i=0; i<num_threads; i++)
-            {
-                profile_data_stream << "thread_used_id:" << std::hex << threads_id[i] << std::dec << ';';
-                profile_data_stream << "thread_used_usec:" << threads_used_usec[i] << ';';
-                
-                if (scanType & eProfileThreadName)
-                {
-                    profile_data_stream << "thread_used_name:";
-                    int len = threads_name[i].size();
-                    if (len)
-                    {
-                        const char *thread_name = threads_name[i].c_str();
-                        // Make sure that thread name doesn't interfere with our delimiter.
-                        profile_data_stream << RAW_HEXBASE << std::setw(2);
-                        const uint8_t *ubuf8 = (const uint8_t *)(thread_name);
-                        for (int j=0; j<len; j++)
-                        {
-                            profile_data_stream << (uint32_t)(ubuf8[j]);
-                        }
-                        // Reset back to DECIMAL.
-                        profile_data_stream << DECIMAL;
-                    }
-                    profile_data_stream << ';';
-                }
-            }
-        }
-        
-        if (scanType & eProfileHostMemory)
-            profile_data_stream << "total:" << physical_memory << ';';
-        
-        if (scanType & eProfileMemory)
-        {
-            static vm_size_t pagesize;
-            static bool calculated = false;
-            if (!calculated)
-            {
-                calculated = true;
-                pagesize = PageSize();
-            }
-            
-            profile_data_stream << "wired:" << vm_stats.wire_count * pagesize << ';';
-            profile_data_stream << "active:" << vm_stats.active_count * pagesize << ';';
-            profile_data_stream << "inactive:" << vm_stats.inactive_count * pagesize << ';';
-            uint64_t total_used_count = vm_stats.wire_count + vm_stats.inactive_count + vm_stats.active_count;
-            profile_data_stream << "used:" << total_used_count * pagesize << ';';
-            profile_data_stream << "free:" << vm_stats.free_count * pagesize << ';';
-            
-            profile_data_stream << "rprvt:" << rprvt << ';';
-            profile_data_stream << "rsize:" << rsize << ';';
-            profile_data_stream << "vprvt:" << vprvt << ';';
-            profile_data_stream << "vsize:" << vsize << ';';
-            
-            if (scanType & eProfileMemoryDirtyPage)
-                profile_data_stream << "dirty:" << dirty_size << ';';
-
-            if (scanType & eProfileMemoryAnonymous)
-            {
-                profile_data_stream << "purgeable:" << purgeable << ';';
-                profile_data_stream << "anonymous:" << anonymous << ';';
-            }
-        }
-        
-        profile_data_stream << "--end--;";
-        
-        result = profile_data_stream.str();
-    }
-    
-    return result;
-}
-
-
-//----------------------------------------------------------------------
-// MachTask::TaskPortForProcessID
-//----------------------------------------------------------------------
-task_t
-MachTask::TaskPortForProcessID (DNBError &err)
-{
-    if (m_task == TASK_NULL && m_process != NULL)
-        m_task = MachTask::TaskPortForProcessID(m_process->ProcessID(), err);
-    return m_task;
-}
-
-//----------------------------------------------------------------------
-// MachTask::TaskPortForProcessID
-//----------------------------------------------------------------------
-task_t
-MachTask::TaskPortForProcessID (pid_t pid, DNBError &err, uint32_t num_retries, uint32_t usec_interval)
-{
-    if (pid != INVALID_NUB_PROCESS)
-    {
-        DNBError err;
-        mach_port_t task_self = mach_task_self ();  
-        task_t task = TASK_NULL;
-        for (uint32_t i=0; i<num_retries; i++)
-        {   
-            err = ::task_for_pid ( task_self, pid, &task);
-
-            if (DNBLogCheckLogBit(LOG_TASK) || err.Fail())
-            {
-                char str[1024];
-                ::snprintf (str,
-                            sizeof(str),
-                            "::task_for_pid ( target_tport = 0x%4.4x, pid = %d, &task ) => err = 0x%8.8x (%s)",
-                            task_self,
-                            pid,
-                            err.Error(),
-                            err.AsString() ? err.AsString() : "success");
-                if (err.Fail())
-                    err.SetErrorString(str);
-                err.LogThreaded(str);
-            }
-
-            if (err.Success())
-                return task;
-
-            // Sleep a bit and try again
-            ::usleep (usec_interval);
-        }
-    }
-    return TASK_NULL;
-}
-
-
-//----------------------------------------------------------------------
-// MachTask::BasicInfo
-//----------------------------------------------------------------------
-kern_return_t
-MachTask::BasicInfo(struct task_basic_info *info)
-{
-    return BasicInfo (TaskPort(), info);
-}
-
-//----------------------------------------------------------------------
-// MachTask::BasicInfo
-//----------------------------------------------------------------------
-kern_return_t
-MachTask::BasicInfo(task_t task, struct task_basic_info *info)
-{
-    if (info == NULL)
-        return KERN_INVALID_ARGUMENT;
-
-    DNBError err;
-    mach_msg_type_number_t count = TASK_BASIC_INFO_COUNT;
-    err = ::task_info (task, TASK_BASIC_INFO, (task_info_t)info, &count);
-    const bool log_process = DNBLogCheckLogBit(LOG_TASK);
-    if (log_process || err.Fail())
-        err.LogThreaded("::task_info ( target_task = 0x%4.4x, flavor = TASK_BASIC_INFO, task_info_out => %p, task_info_outCnt => %u )", task, info, count);
-    if (DNBLogCheckLogBit(LOG_TASK) && DNBLogCheckLogBit(LOG_VERBOSE) && err.Success())
-    {
-        float user = (float)info->user_time.seconds + (float)info->user_time.microseconds / 1000000.0f;
-        float system = (float)info->user_time.seconds + (float)info->user_time.microseconds / 1000000.0f;
-        DNBLogThreaded ("task_basic_info = { suspend_count = %i, virtual_size = 0x%8.8llx, resident_size = 0x%8.8llx, user_time = %f, system_time = %f }",
-                        info->suspend_count, 
-                        (uint64_t)info->virtual_size, 
-                        (uint64_t)info->resident_size, 
-                        user, 
-                        system);
-    }
-    return err.Error();
-}
-
-
-//----------------------------------------------------------------------
-// MachTask::IsValid
-//
-// Returns true if a task is a valid task port for a current process.
-//----------------------------------------------------------------------
-bool
-MachTask::IsValid () const
-{
-    return MachTask::IsValid(TaskPort());
-}
-
-//----------------------------------------------------------------------
-// MachTask::IsValid
-//
-// Returns true if a task is a valid task port for a current process.
-//----------------------------------------------------------------------
-bool
-MachTask::IsValid (task_t task)
-{
-    if (task != TASK_NULL)
-    {
-        struct task_basic_info task_info;
-        return BasicInfo(task, &task_info) == KERN_SUCCESS;
-    }
-    return false;
-}
-
-
-bool
-MachTask::StartExceptionThread(DNBError &err)
-{
-    DNBLogThreadedIf(LOG_EXCEPTIONS, "MachTask::%s ( )", __FUNCTION__);
-    task_t task = TaskPortForProcessID(err);
-    if (MachTask::IsValid(task))
-    {
-        // Got the mach port for the current process
-        mach_port_t task_self = mach_task_self ();
-
-        // Allocate an exception port that we will use to track our child process
-        err = ::mach_port_allocate (task_self, MACH_PORT_RIGHT_RECEIVE, &m_exception_port);
-        if (err.Fail())
-            return false;
-
-        // Add the ability to send messages on the new exception port
-        err = ::mach_port_insert_right (task_self, m_exception_port, m_exception_port, MACH_MSG_TYPE_MAKE_SEND);
-        if (err.Fail())
-            return false;
-
-        // Save the original state of the exception ports for our child process
-        SaveExceptionPortInfo();
-
-        // We weren't able to save the info for our exception ports, we must stop...
-        if (m_exc_port_info.mask == 0)
-        {
-            err.SetErrorString("failed to get exception port info");
-            return false;
-        }
-
-        // Set the ability to get all exceptions on this port
-        err = ::task_set_exception_ports (task, m_exc_port_info.mask, m_exception_port, EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES, THREAD_STATE_NONE);
-        if (DNBLogCheckLogBit(LOG_EXCEPTIONS) || err.Fail())
-        {
-            err.LogThreaded("::task_set_exception_ports ( task = 0x%4.4x, exception_mask = 0x%8.8x, new_port = 0x%4.4x, behavior = 0x%8.8x, new_flavor = 0x%8.8x )",
-                            task,
-                            m_exc_port_info.mask,
-                            m_exception_port,
-                            (EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES),
-                            THREAD_STATE_NONE);
-        }
-
-        if (err.Fail())
-            return false;
-
-        // Create the exception thread
-        err = ::pthread_create (&m_exception_thread, NULL, MachTask::ExceptionThread, this);
-        return err.Success();
-    }
-    else
-    {
-        DNBLogError("MachTask::%s (): task invalid, exception thread start failed.", __FUNCTION__);
-    }
-    return false;
-}
-
-kern_return_t
-MachTask::ShutDownExcecptionThread()
-{
-    DNBError err;
-
-    err = RestoreExceptionPortInfo();
-
-    // NULL our our exception port and let our exception thread exit
-    mach_port_t exception_port = m_exception_port;
-    m_exception_port = NULL;
-
-    err.SetError(::pthread_cancel(m_exception_thread), DNBError::POSIX);
-    if (DNBLogCheckLogBit(LOG_TASK) || err.Fail())
-        err.LogThreaded("::pthread_cancel ( thread = %p )", m_exception_thread);
-
-    err.SetError(::pthread_join(m_exception_thread, NULL), DNBError::POSIX);
-    if (DNBLogCheckLogBit(LOG_TASK) || err.Fail())
-        err.LogThreaded("::pthread_join ( thread = %p, value_ptr = NULL)", m_exception_thread);
-
-    // Deallocate our exception port that we used to track our child process
-    mach_port_t task_self = mach_task_self ();
-    err = ::mach_port_deallocate (task_self, exception_port);
-    if (DNBLogCheckLogBit(LOG_TASK) || err.Fail())
-        err.LogThreaded("::mach_port_deallocate ( task = 0x%4.4x, name = 0x%4.4x )", task_self, exception_port);
-
-    return err.Error();
-}
-
-
-void *
-MachTask::ExceptionThread (void *arg)
-{
-    if (arg == NULL)
-        return NULL;
-
-    MachTask *mach_task = (MachTask*) arg;
-    MachProcess *mach_proc = mach_task->Process();
-    DNBLogThreadedIf(LOG_EXCEPTIONS, "MachTask::%s ( arg = %p ) starting thread...", __FUNCTION__, arg);
-
-    // We keep a count of the number of consecutive exceptions received so
-    // we know to grab all exceptions without a timeout. We do this to get a
-    // bunch of related exceptions on our exception port so we can process
-    // then together. When we have multiple threads, we can get an exception
-    // per thread and they will come in consecutively. The main loop in this
-    // thread can stop periodically if needed to service things related to this
-    // process.
-    // flag set in the options, so we will wait forever for an exception on
-    // our exception port. After we get one exception, we then will use the
-    // MACH_RCV_TIMEOUT option with a zero timeout to grab all other current
-    // exceptions for our process. After we have received the last pending
-    // exception, we will get a timeout which enables us to then notify
-    // our main thread that we have an exception bundle avaiable. We then wait
-    // for the main thread to tell this exception thread to start trying to get
-    // exceptions messages again and we start again with a mach_msg read with
-    // infinite timeout.
-    uint32_t num_exceptions_received = 0;
-    DNBError err;
-    task_t task = mach_task->TaskPort();
-    mach_msg_timeout_t periodic_timeout = 0;
-
-#ifdef WITH_SPRINGBOARD
-    mach_msg_timeout_t watchdog_elapsed = 0;
-    mach_msg_timeout_t watchdog_timeout = 60 * 1000;
-    pid_t pid = mach_proc->ProcessID();
-    CFReleaser<SBSWatchdogAssertionRef> watchdog;
-
-    if (mach_proc->ProcessUsingSpringBoard())
-    {
-        // Request a renewal for every 60 seconds if we attached using SpringBoard
-        watchdog.reset(::SBSWatchdogAssertionCreateForPID(NULL, pid, 60));
-        DNBLogThreadedIf(LOG_TASK, "::SBSWatchdogAssertionCreateForPID (NULL, %4.4x, 60 ) => %p", pid, watchdog.get());
-
-        if (watchdog.get())
-        {
-            ::SBSWatchdogAssertionRenew (watchdog.get());
-
-            CFTimeInterval watchdogRenewalInterval = ::SBSWatchdogAssertionGetRenewalInterval (watchdog.get());
-            DNBLogThreadedIf(LOG_TASK, "::SBSWatchdogAssertionGetRenewalInterval ( %p ) => %g seconds", watchdog.get(), watchdogRenewalInterval);
-            if (watchdogRenewalInterval > 0.0)
-            {
-                watchdog_timeout = (mach_msg_timeout_t)watchdogRenewalInterval * 1000;
-                if (watchdog_timeout > 3000)
-                    watchdog_timeout -= 1000;   // Give us a second to renew our timeout
-                else if (watchdog_timeout > 1000)
-                    watchdog_timeout -= 250;    // Give us a quarter of a second to renew our timeout
-            }
-        }
-        if (periodic_timeout == 0 || periodic_timeout > watchdog_timeout)
-            periodic_timeout = watchdog_timeout;
-    }
-#endif  // #ifdef WITH_SPRINGBOARD
-
-    while (mach_task->ExceptionPortIsValid())
-    {
-        ::pthread_testcancel ();
-
-        MachException::Message exception_message;
-
-
-        if (num_exceptions_received > 0)
-        {
-            // No timeout, just receive as many exceptions as we can since we already have one and we want
-            // to get all currently available exceptions for this task
-            err = exception_message.Receive(mach_task->ExceptionPort(), MACH_RCV_MSG | MACH_RCV_INTERRUPT | MACH_RCV_TIMEOUT, 0);
-        }
-        else if (periodic_timeout > 0)
-        {
-            // We need to stop periodically in this loop, so try and get a mach message with a valid timeout (ms)
-            err = exception_message.Receive(mach_task->ExceptionPort(), MACH_RCV_MSG | MACH_RCV_INTERRUPT | MACH_RCV_TIMEOUT, periodic_timeout);
-        }
-        else
-        {
-            // We don't need to parse all current exceptions or stop periodically,
-            // just wait for an exception forever.
-            err = exception_message.Receive(mach_task->ExceptionPort(), MACH_RCV_MSG | MACH_RCV_INTERRUPT, 0);
-        }
-
-        if (err.Error() == MACH_RCV_INTERRUPTED)
-        {
-            // If we have no task port we should exit this thread
-            if (!mach_task->ExceptionPortIsValid())
-            {
-                DNBLogThreadedIf(LOG_EXCEPTIONS, "thread cancelled...");
-                break;
-            }
-
-            // Make sure our task is still valid
-            if (MachTask::IsValid(task))
-            {
-                // Task is still ok
-                DNBLogThreadedIf(LOG_EXCEPTIONS, "interrupted, but task still valid, continuing...");
-                continue;
-            }
-            else
-            {
-                DNBLogThreadedIf(LOG_EXCEPTIONS, "task has exited...");
-                mach_proc->SetState(eStateExited);
-                // Our task has died, exit the thread.
-                break;
-            }
-        }
-        else if (err.Error() == MACH_RCV_TIMED_OUT)
-        {
-            if (num_exceptions_received > 0)
-            {
-                // We were receiving all current exceptions with a timeout of zero
-                // it is time to go back to our normal looping mode
-                num_exceptions_received = 0;
-
-                // Notify our main thread we have a complete exception message
-                // bundle available.
-                mach_proc->ExceptionMessageBundleComplete();
-
-                // in case we use a timeout value when getting exceptions...
-                // Make sure our task is still valid
-                if (MachTask::IsValid(task))
-                {
-                    // Task is still ok
-                    DNBLogThreadedIf(LOG_EXCEPTIONS, "got a timeout, continuing...");
-                    continue;
-                }
-                else
-                {
-                    DNBLogThreadedIf(LOG_EXCEPTIONS, "task has exited...");
-                    mach_proc->SetState(eStateExited);
-                    // Our task has died, exit the thread.
-                    break;
-                }
-                continue;
-            }
-
-#ifdef WITH_SPRINGBOARD
-            if (watchdog.get())
-            {
-                watchdog_elapsed += periodic_timeout;
-                if (watchdog_elapsed >= watchdog_timeout)
-                {
-                    DNBLogThreadedIf(LOG_TASK, "SBSWatchdogAssertionRenew ( %p )", watchdog.get());
-                    ::SBSWatchdogAssertionRenew (watchdog.get());
-                    watchdog_elapsed = 0;
-                }
-            }
-#endif
-        }
-        else if (err.Error() != KERN_SUCCESS)
-        {
-            DNBLogThreadedIf(LOG_EXCEPTIONS, "got some other error, do something about it??? nah, continuing for now...");
-            // TODO: notify of error?
-        }
-        else
-        {
-            if (exception_message.CatchExceptionRaise(task))
-            {
-                ++num_exceptions_received;
-                mach_proc->ExceptionMessageReceived(exception_message);
-            }
-        }
-    }
-
-#ifdef WITH_SPRINGBOARD
-    if (watchdog.get())
-    {
-        // TODO: change SBSWatchdogAssertionRelease to SBSWatchdogAssertionCancel when we
-        // all are up and running on systems that support it. The SBS framework has a #define
-        // that will forward SBSWatchdogAssertionRelease to SBSWatchdogAssertionCancel for now
-        // so it should still build either way.
-        DNBLogThreadedIf(LOG_TASK, "::SBSWatchdogAssertionRelease(%p)", watchdog.get());
-        ::SBSWatchdogAssertionRelease (watchdog.get());
-    }
-#endif  // #ifdef WITH_SPRINGBOARD
-
-    DNBLogThreadedIf(LOG_EXCEPTIONS, "MachTask::%s (%p): thread exiting...", __FUNCTION__, arg);
-    return NULL;
-}
-
-
-// So the TASK_DYLD_INFO used to just return the address of the all image infos
-// as a single member called "all_image_info". Then someone decided it would be
-// a good idea to rename this first member to "all_image_info_addr" and add a
-// size member called "all_image_info_size". This of course can not be detected
-// using code or #defines. So to hack around this problem, we define our own
-// version of the TASK_DYLD_INFO structure so we can guarantee what is inside it.
-
-struct hack_task_dyld_info {
-    mach_vm_address_t   all_image_info_addr;
-    mach_vm_size_t      all_image_info_size;
-};
-
-nub_addr_t
-MachTask::GetDYLDAllImageInfosAddress (DNBError& err)
-{
-    struct hack_task_dyld_info dyld_info;
-    mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
-    // Make sure that COUNT isn't bigger than our hacked up struct hack_task_dyld_info.
-    // If it is, then make COUNT smaller to match.
-    if (count > (sizeof(struct hack_task_dyld_info) / sizeof(natural_t)))
-        count = (sizeof(struct hack_task_dyld_info) / sizeof(natural_t));
-
-    task_t task = TaskPortForProcessID (err);
-    if (err.Success())
-    {
-        err = ::task_info (task, TASK_DYLD_INFO, (task_info_t)&dyld_info, &count);
-        if (err.Success())
-        {
-            // We now have the address of the all image infos structure
-            return dyld_info.all_image_info_addr;
-        }
-    }
-    return INVALID_NUB_ADDRESS;
-}
-
-
-//----------------------------------------------------------------------
-// MachTask::AllocateMemory
-//----------------------------------------------------------------------
-nub_addr_t
-MachTask::AllocateMemory (size_t size, uint32_t permissions)
-{
-    mach_vm_address_t addr;
-    task_t task = TaskPort();
-    if (task == TASK_NULL)
-        return INVALID_NUB_ADDRESS;
-
-    DNBError err;
-    err = ::mach_vm_allocate (task, &addr, size, TRUE);
-    if (err.Error() == KERN_SUCCESS)
-    {
-        // Set the protections:
-        vm_prot_t mach_prot = VM_PROT_NONE;
-        if (permissions & eMemoryPermissionsReadable)
-            mach_prot |= VM_PROT_READ;
-        if (permissions & eMemoryPermissionsWritable)
-            mach_prot |= VM_PROT_WRITE;
-        if (permissions & eMemoryPermissionsExecutable)
-            mach_prot |= VM_PROT_EXECUTE;
-
-
-        err = ::mach_vm_protect (task, addr, size, 0, mach_prot);
-        if (err.Error() == KERN_SUCCESS)
-        {
-            m_allocations.insert (std::make_pair(addr, size));
-            return addr;
-        }
-        ::mach_vm_deallocate (task, addr, size);
-    }
-    return INVALID_NUB_ADDRESS;
-}
-
-//----------------------------------------------------------------------
-// MachTask::DeallocateMemory
-//----------------------------------------------------------------------
-nub_bool_t
-MachTask::DeallocateMemory (nub_addr_t addr)
-{
-    task_t task = TaskPort();
-    if (task == TASK_NULL)
-        return false;
-
-    // We have to stash away sizes for the allocations...
-    allocation_collection::iterator pos, end = m_allocations.end();
-    for (pos = m_allocations.begin(); pos != end; pos++)
-    {
-        if ((*pos).first == addr)
-        {
-            m_allocations.erase(pos);
-#define ALWAYS_ZOMBIE_ALLOCATIONS 0
-            if (ALWAYS_ZOMBIE_ALLOCATIONS || getenv ("DEBUGSERVER_ZOMBIE_ALLOCATIONS"))
-            {
-                ::mach_vm_protect (task, (*pos).first, (*pos).second, 0, VM_PROT_NONE);
-                return true;
-            }
-            else
-                return ::mach_vm_deallocate (task, (*pos).first, (*pos).second) == KERN_SUCCESS;
-        }
-        
-    }
-    return false;
-}
-
-static void foundStackLog(mach_stack_logging_record_t record, void *context) {
-    *((bool*)context) = true;
-}
-
-bool
-MachTask::HasMallocLoggingEnabled ()
-{
-    bool found = false;
-    
-    __mach_stack_logging_enumerate_records(m_task, 0x0, foundStackLog, &found);
-    return found;
-}
-
-struct history_enumerator_impl_data
-{
-    MachMallocEvent *buffer;
-    uint32_t        *position;
-    uint32_t         count;
-};
-
-static void history_enumerator_impl(mach_stack_logging_record_t record, void* enum_obj)
-{
-    history_enumerator_impl_data *data = (history_enumerator_impl_data*)enum_obj;
-    
-    if (*data->position >= data->count)
-        return;
-    
-    data->buffer[*data->position].m_base_address = record.address;
-    data->buffer[*data->position].m_size = record.argument;
-    data->buffer[*data->position].m_event_id = record.stack_identifier;
-    data->buffer[*data->position].m_event_type = record.type_flags == stack_logging_type_alloc ?   eMachMallocEventTypeAlloc :
-                                                 record.type_flags == stack_logging_type_dealloc ? eMachMallocEventTypeDealloc :
-                                                                                                   eMachMallocEventTypeOther;
-    *data->position+=1;
-}
-
-bool
-MachTask::EnumerateMallocRecords (MachMallocEvent *event_buffer,
-                                  uint32_t buffer_size,
-                                  uint32_t *count)
-{
-    return EnumerateMallocRecords(0,
-                                  event_buffer,
-                                  buffer_size,
-                                  count);
-}
-
-bool
-MachTask::EnumerateMallocRecords (mach_vm_address_t address,
-                                  MachMallocEvent *event_buffer,
-                                  uint32_t buffer_size,
-                                  uint32_t *count)
-{
-    if (!event_buffer || !count)
-        return false;
-    
-    if (buffer_size == 0)
-        return false;
-    
-    *count = 0;
-    history_enumerator_impl_data data = { event_buffer, count, buffer_size };
-    __mach_stack_logging_enumerate_records(m_task, address, history_enumerator_impl, &data);
-    return (*count > 0);
-}
-
-bool
-MachTask::EnumerateMallocFrames (MachMallocEventId event_id,
-                                 mach_vm_address_t *function_addresses_buffer,
-                                 uint32_t buffer_size,
-                                 uint32_t *count)
-{
-    if (!function_addresses_buffer || !count)
-        return false;
-    
-    if (buffer_size == 0)
-        return false;
-    
-    __mach_stack_logging_frames_for_uniqued_stack(m_task, event_id, &function_addresses_buffer[0], buffer_size, count);
-    *count -= 1;
-    if (function_addresses_buffer[*count-1] < PageSize())
-        *count -= 1;
-    return (*count > 0);
-}
-
-nub_size_t
-MachTask::PageSize ()
-{
-    return m_vm_memory.PageSize (m_task);
-}

Copied: lldb/trunk/tools/debugserver/source/MacOSX/MachTask.mm (from r205075, lldb/trunk/tools/debugserver/source/MacOSX/MachTask.cpp)
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachTask.mm?p2=lldb/trunk/tools/debugserver/source/MacOSX/MachTask.mm&p1=lldb/trunk/tools/debugserver/source/MacOSX/MachTask.cpp&r1=205075&r2=205113&rev=205113&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachTask.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachTask.mm Sat Mar 29 13:54:20 2014
@@ -45,6 +45,15 @@
 
 #endif
 
+#ifdef WITH_BKS
+extern "C"
+{
+    #import <Foundation/Foundation.h>
+    #import <BackBoardServices/BackBoardServices.h> 
+    #import <BackBoardServices/BKSWatchdogAssertion.h>
+}
+#endif
+
 //----------------------------------------------------------------------
 // MachTask constructor
 //----------------------------------------------------------------------
@@ -693,7 +702,7 @@ MachTask::ExceptionThread (void *arg)
     task_t task = mach_task->TaskPort();
     mach_msg_timeout_t periodic_timeout = 0;
 
-#ifdef WITH_SPRINGBOARD
+#if defined (WITH_SPRINGBOARD) && !defined (WITH_BKS)
     mach_msg_timeout_t watchdog_elapsed = 0;
     mach_msg_timeout_t watchdog_timeout = 60 * 1000;
     pid_t pid = mach_proc->ProcessID();
@@ -723,7 +732,17 @@ MachTask::ExceptionThread (void *arg)
         if (periodic_timeout == 0 || periodic_timeout > watchdog_timeout)
             periodic_timeout = watchdog_timeout;
     }
-#endif  // #ifdef WITH_SPRINGBOARD
+#endif  // #if defined (WITH_SPRINGBOARD) && !defined (WITH_BKS)
+
+#ifdef WITH_BKS
+    CFReleaser<BKSWatchdogAssertionRef> watchdog;
+    if (mach_proc->ProcessUsingBackBoard())
+    {
+        pid_t pid = mach_proc->ProcessID();
+        CFAllocatorRef alloc = kCFAllocatorDefault;
+        watchdog.reset(::BKSWatchdogAssertionCreateForPID(alloc, pid));
+    }
+#endif // #ifdef WITH_BKS
 
     while (mach_task->ExceptionPortIsValid())
     {
@@ -804,7 +823,7 @@ MachTask::ExceptionThread (void *arg)
                 continue;
             }
 
-#ifdef WITH_SPRINGBOARD
+#if defined (WITH_SPRINGBOARD) && !defined (WITH_BKS)
             if (watchdog.get())
             {
                 watchdog_elapsed += periodic_timeout;
@@ -832,7 +851,7 @@ MachTask::ExceptionThread (void *arg)
         }
     }
 
-#ifdef WITH_SPRINGBOARD
+#if defined (WITH_SPRINGBOARD) && !defined (WITH_BKS)
     if (watchdog.get())
     {
         // TODO: change SBSWatchdogAssertionRelease to SBSWatchdogAssertionCancel when we
@@ -842,7 +861,7 @@ MachTask::ExceptionThread (void *arg)
         DNBLogThreadedIf(LOG_TASK, "::SBSWatchdogAssertionRelease(%p)", watchdog.get());
         ::SBSWatchdogAssertionRelease (watchdog.get());
     }
-#endif  // #ifdef WITH_SPRINGBOARD
+#endif  // #if defined (WITH_SPRINGBOARD) && !defined (WITH_BKS)
 
     DNBLogThreadedIf(LOG_EXCEPTIONS, "MachTask::%s (%p): thread exiting...", __FUNCTION__, arg);
     return NULL;

Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.cpp Sat Mar 29 13:54:20 2014
@@ -271,7 +271,6 @@ MachThreadList::UpdateThreadList(MachPro
     DNBLogThreadedIf (LOG_THREAD, "MachThreadList::UpdateThreadList (pid = %4.4x, update = %u) process stop count = %u", process->ProcessID(), update, process->StopCount());
     PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
 
-#if defined (__i386__) || defined (__x86_64__)
     if (process->StopCount() == 0)
     {
         int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, process->ProcessID() };
@@ -283,12 +282,18 @@ MachThreadList::UpdateThreadList(MachPro
             if (processInfo.kp_proc.p_flag & P_LP64)
                 is_64_bit = true;
         }
+#if defined (__i386__) || defined (__x86_64__)
         if (is_64_bit)
             DNBArchProtocol::SetArchitecture(CPU_TYPE_X86_64);
         else
             DNBArchProtocol::SetArchitecture(CPU_TYPE_I386);
-    }
+#elif defined (__arm__) || defined (__arm64__)
+        if (is_64_bit)
+            DNBArchProtocol::SetArchitecture(CPU_TYPE_ARM64);
+        else
+            DNBArchProtocol::SetArchitecture(CPU_TYPE_ARM);
 #endif
+    }
     
     if (m_threads.empty() || update)
     {

Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachVMMemory.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachVMMemory.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachVMMemory.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachVMMemory.cpp Sat Mar 29 13:54:20 2014
@@ -311,11 +311,18 @@ static bool InSharedRegion(mach_vm_addre
     mach_vm_address_t base = 0, size = 0;
     
     switch(type) {
+#if defined (CPU_TYPE_ARM64) && defined (SHARED_REGION_BASE_ARM64)
+        case CPU_TYPE_ARM64:
+            base = SHARED_REGION_BASE_ARM64;
+            size = SHARED_REGION_SIZE_ARM64;
+            break;
+#endif
+
         case CPU_TYPE_ARM:
             base = SHARED_REGION_BASE_ARM;
             size = SHARED_REGION_SIZE_ARM;
             break;
-            
+
         case CPU_TYPE_X86_64:
             base = SHARED_REGION_BASE_X86_64;
             size = SHARED_REGION_SIZE_X86_64;

Modified: lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp Sat Mar 29 13:54:20 2014
@@ -11,7 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#if defined (__arm__)
+#if defined (__arm__) || defined (__arm64__)
 
 #include "MacOSX/arm/DNBArchImpl.h"
 #include "MacOSX/MachProcess.h"
@@ -23,6 +23,7 @@
 #include "ARM_GCC_Registers.h"
 #include "ARM_DWARF_Registers.h"
 
+#include <inttypes.h>
 #include <sys/sysctl.h>
 
 // BCR address match type
@@ -65,6 +66,13 @@
 static const uint8_t g_arm_breakpoint_opcode[] = { 0xFE, 0xDE, 0xFF, 0xE7 };
 static const uint8_t g_thumb_breakpoint_opcode[] = { 0xFE, 0xDE };
 
+// A watchpoint may need to be implemented using two watchpoint registers.
+// e.g. watching an 8-byte region when the device can only watch 4-bytes.
+//
+// This stores the lo->hi mappings.  It's safe to initialize to all 0's
+// since hi > lo and therefore LoHi[i] cannot be 0.
+static uint32_t LoHi[16] = { 0 };
+
 // ARM constants used during decoding
 #define REG_RD          0
 #define LDM_REGLIST     1
@@ -278,9 +286,15 @@ DNBArchMachARM::GetDBGState(bool force)
         return KERN_SUCCESS;
 
     // Read the registers from our thread
+#if defined (ARM_DEBUG_STATE32) && defined (__arm64__)
+    mach_msg_type_number_t count = ARM_DEBUG_STATE32_COUNT;
+    kern_return_t kret = ::thread_get_state(m_thread->MachPortNumber(), ARM_DEBUG_STATE32, (thread_state_t)&m_state.dbg, &count);
+#else
     mach_msg_type_number_t count = ARM_DEBUG_STATE_COUNT;
     kern_return_t kret = ::thread_get_state(m_thread->MachPortNumber(), ARM_DEBUG_STATE, (thread_state_t)&m_state.dbg, &count);
+#endif
     m_state.SetError(set, Read, kret);
+
     return kret;
 }
 
@@ -318,6 +332,15 @@ kern_return_t
 DNBArchMachARM::SetDBGState(bool also_set_on_task)
 {
     int set = e_regSetDBG;
+#if defined (ARM_DEBUG_STATE32) && defined (__arm64__)
+    kern_return_t kret = ::thread_set_state (m_thread->MachPortNumber(), ARM_DEBUG_STATE32, (thread_state_t)&m_state.dbg, ARM_DEBUG_STATE32_COUNT);
+    if (also_set_on_task)
+    {
+        kern_return_t task_kret = ::task_set_state (m_thread->Process()->Task().TaskPort(), ARM_DEBUG_STATE32, (thread_state_t)&m_state.dbg, ARM_DEBUG_STATE32_COUNT);
+        if (task_kret != KERN_SUCCESS)
+             DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::SetDBGState failed to set debug control register state: 0x%8.8x.", kret);
+    }
+#else
     kern_return_t kret = ::thread_set_state (m_thread->MachPortNumber(), ARM_DEBUG_STATE, (thread_state_t)&m_state.dbg, ARM_DEBUG_STATE_COUNT);
     if (also_set_on_task)
     {
@@ -325,6 +348,7 @@ DNBArchMachARM::SetDBGState(bool also_se
         if (task_kret != KERN_SUCCESS)
              DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::SetDBGState failed to set debug control register state: 0x%8.8x.", kret);
     }
+#endif
 
     m_state.SetError(set, Write, kret);         // Set the current write error for this register set
     m_state.InvalidateRegisterSetState(set);    // Invalidate the current register state in case registers are read back differently
@@ -362,7 +386,7 @@ DNBArchMachARM::ThreadWillResume()
                 return;
             }
 
-            DisableHardwareWatchpoint0(m_watchpoint_hw_index, true, false);
+            DisableHardwareWatchpoint(m_watchpoint_hw_index, false);
             DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::ThreadWillResume() DisableHardwareWatchpoint(%d) called",
                              m_watchpoint_hw_index);
 
@@ -399,7 +423,7 @@ DNBArchMachARM::ThreadDidStop()
         {
             if (m_watchpoint_did_occur && m_watchpoint_hw_index >= 0)
             {
-                EnableHardwareWatchpoint0(m_watchpoint_hw_index, true, false);
+                ReenableHardwareWatchpoint(m_watchpoint_hw_index);
                 m_watchpoint_resume_single_step_enabled = false;
                 m_watchpoint_did_occur = false;
                 m_watchpoint_hw_index = -1;
@@ -443,18 +467,24 @@ DNBArchMachARM::NotifyException(MachExce
         case EXC_BREAKPOINT:
             if (exc.exc_data.size() == 2 && exc.exc_data[0] == EXC_ARM_DA_DEBUG)
             {
-                // exc_code = EXC_ARM_DA_DEBUG
-                //
-                // Check whether this corresponds to a watchpoint hit event.
-                // If yes, retrieve the exc_sub_code as the data break address.
-                if (!HasWatchpointOccurred())
-                    break;
-
                 // The data break address is passed as exc_data[1].
                 nub_addr_t addr = exc.exc_data[1];
                 // Find the hardware index with the side effect of possibly massaging the
                 // addr to return the starting address as seen from the debugger side.
                 uint32_t hw_index = GetHardwareWatchpointHit(addr);
+                DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::NotifyException watchpoint %d was hit on address 0x%llx", hw_index, (uint64_t) addr);
+                const int num_watchpoints = NumSupportedHardwareWatchpoints ();
+                for (int i = 0; i < num_watchpoints; i++)
+                {
+                    if (LoHi[i] != 0
+                        && LoHi[i] == hw_index 
+                        && LoHi[i] != i
+                        && GetWatchpointAddressByIndex (i) != INVALID_NUB_ADDRESS)
+                    {
+                        addr = GetWatchpointAddressByIndex (i);
+                        DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::NotifyException It is a linked watchpoint; rewritten to index %d addr 0x%llx", LoHi[i], (uint64_t) addr);
+                    }
+                }
                 if (hw_index != INVALID_NUB_HW_INDEX)
                 {
                     m_watchpoint_did_occur = true;
@@ -492,7 +522,6 @@ DNBArchMachARM::StepNotComplete ()
     return false;
 }
 
-
 // Set the single step bit in the processor status register.
 kern_return_t
 DNBArchMachARM::EnableHardwareSingleStep (bool enable)
@@ -516,6 +545,22 @@ DNBArchMachARM::EnableHardwareSingleStep
         return err.Error();
     }
 
+// The use of __arm64__ here is not ideal.  If debugserver is running on
+// an armv8 device, regardless of whether it was built for arch arm or arch arm64,
+// it needs to use the MDSCR_EL1 SS bit to single instruction step.
+
+#if defined (__arm64__)
+    if (enable)
+    {
+        DNBLogThreadedIf(LOG_STEP, "%s: Setting MDSCR_EL1 Single Step bit at pc 0x%llx", __FUNCTION__, (uint64_t) m_state.context.gpr.__pc);
+        m_state.dbg.__mdscr_el1 |= 1;  // Set bit 0 (single step, SS) in the MDSCR_EL1.
+    }
+    else
+    {
+        DNBLogThreadedIf(LOG_STEP, "%s: Clearing MDSCR_EL1 Single Step bit at pc 0x%llx", __FUNCTION__, (uint64_t) m_state.context.gpr.__pc);
+        m_state.dbg.__mdscr_el1 &= ~(1ULL);  // Clear bit 0 (single step, SS) in the MDSCR_EL1.
+    }
+#else
     const uint32_t i = 0;
     if (enable)
     {
@@ -577,6 +622,7 @@ DNBArchMachARM::EnableHardwareSingleStep
         // Just restore the state we had before we did single stepping
         m_state.dbg = m_dbg_save;
     }
+#endif
 
     return SetDBGState(false);
 }
@@ -677,6 +723,7 @@ DNBArchMachARM::NumSupportedHardwareBrea
         }
         else
         {
+#if !defined (__arm64__)
             // Read the DBGDIDR to get the number of available hardware breakpoints
             // However, in some of our current armv7 processors, hardware
             // breakpoints/watchpoints were not properly connected. So detect those
@@ -708,6 +755,7 @@ DNBArchMachARM::NumSupportedHardwareBrea
                         g_num_supported_hw_breakpoints = numBRPs;
                 }
             }
+#endif
         }
     }
     return g_num_supported_hw_breakpoints;
@@ -736,6 +784,7 @@ DNBArchMachARM::NumSupportedHardwareWatc
         }
         else
         {
+#if !defined (__arm64__)
             // Read the DBGDIDR to get the number of available hardware breakpoints
             // However, in some of our current armv7 processors, hardware
             // breakpoints/watchpoints were not properly connected. So detect those
@@ -766,6 +815,7 @@ DNBArchMachARM::NumSupportedHardwareWatc
                         g_num_supported_hw_watchpoints = numWRPs;
                 }
             }
+#endif
         }
     }
     return g_num_supported_hw_watchpoints;
@@ -873,9 +923,16 @@ DNBArchMachARM::DisableHardwareBreakpoin
     return false;
 }
 
-// This stores the lo->hi mappings.  It's safe to initialize to all 0's
-// since hi > lo and therefore LoHi[i] cannot be 0.
-static uint32_t LoHi[16] = { 0 };
+// ARM v7 watchpoints may be either word-size or double-word-size.
+// It's implementation defined which they can handle.  It looks like on an
+// armv8 device, armv7 processes can watch dwords.  But on a genuine armv7
+// device I tried, only word watchpoints are supported.
+
+#if defined (__arm64__)
+#define WATCHPOINTS_ARE_DWORD 1
+#else
+#undef WATCHPOINTS_ARE_DWORD
+#endif
 
 uint32_t
 DNBArchMachARM::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write, bool also_set_on_task)
@@ -893,16 +950,55 @@ DNBArchMachARM::EnableHardwareWatchpoint
     if (read == false && write == false)
         return INVALID_NUB_HW_INDEX;
 
-    // Divide-and-conquer for size == 8.
-    if (size == 8)
-    {
-        uint32_t lo = EnableHardwareWatchpoint(addr, 4, read, write, also_set_on_task);
+    // Otherwise, can't watch more than 8 bytes per WVR/WCR pair
+    if (size > 8)
+        return INVALID_NUB_HW_INDEX;
+
+    // Treat arm watchpoints as having an 8-byte alignment requirement.  You can put a watchpoint on a 4-byte
+    // offset address but you can only watch 4 bytes with that watchpoint.
+
+    // arm watchpoints on an 8-byte (double word) aligned addr can watch any bytes in that 
+    // 8-byte long region of memory.  They can watch the 1st byte, the 2nd byte, 3rd byte, etc, or any
+    // combination therein by setting the bits in the BAS [12:5] (Byte Address Select) field of
+    // the DBGWCRn_EL1 reg for the watchpoint.
+
+    // If the MASK [28:24] bits in the DBGWCRn_EL1 allow a single watchpoint to monitor a larger region
+    // of memory (16 bytes, 32 bytes, or 2GB) but the Byte Address Select bitfield then selects a larger
+    // range of bytes, instead of individual bytes.  See the ARMv8 Debug Architecture manual for details.
+    // This implementation does not currently use the MASK bits; the largest single region watched by a single
+    // watchpoint right now is 8-bytes.
+
+#if defined (WATCHPOINTS_ARE_DWORD)
+    nub_addr_t aligned_wp_address = addr & ~0x7;
+    uint32_t addr_dword_offset = addr & 0x7;
+    const int max_watchpoint_size = 8;
+#else
+    nub_addr_t aligned_wp_address = addr & ~0x3;
+    uint32_t addr_dword_offset = addr & 0x3;
+    const int max_watchpoint_size = 4;
+#endif
+
+    DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint aligned_wp_address is 0x%llx and addr_dword_offset is 0x%x", (uint64_t)aligned_wp_address, addr_dword_offset);
+
+    // Do we need to split up this logical watchpoint into two hardware watchpoint
+    // registers?
+    // e.g. a watchpoint of length 4 on address 6.  We need do this with
+    //   one watchpoint on address 0 with bytes 6 & 7 being monitored
+    //   one watchpoint on address 8 with bytes 0, 1, 2, 3 being monitored
+
+    if (addr_dword_offset + size > max_watchpoint_size)
+    {
+        DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint(addr = 0x%8.8llx, size = %zu) needs two hardware watchpoints slots to monitor", (uint64_t)addr, size);
+        int low_watchpoint_size = max_watchpoint_size - addr_dword_offset;
+        int high_watchpoint_size = addr_dword_offset + size - max_watchpoint_size;
+
+        uint32_t lo = EnableHardwareWatchpoint(addr, low_watchpoint_size, read, write, also_set_on_task);
         if (lo == INVALID_NUB_HW_INDEX)
             return INVALID_NUB_HW_INDEX;
-        uint32_t hi = EnableHardwareWatchpoint(addr+4, 4, read, write, also_set_on_task);
+        uint32_t hi = EnableHardwareWatchpoint (aligned_wp_address + max_watchpoint_size, high_watchpoint_size, read, write, also_set_on_task);
         if (hi == INVALID_NUB_HW_INDEX)
         {
-            DisableHardwareWatchpoint(lo, also_set_on_task);
+            DisableHardwareWatchpoint (lo, also_set_on_task);
             return INVALID_NUB_HW_INDEX;
         }
         // Tag this lo->hi mapping in our database.
@@ -910,36 +1006,16 @@ DNBArchMachARM::EnableHardwareWatchpoint
         return lo;
     }
 
-    // Otherwise, can't watch more than 4 bytes per WVR/WCR pair
-    if (size > 4)
-        return INVALID_NUB_HW_INDEX;
-
-    // We can only watch up to four bytes that follow a 4 byte aligned address
-    // per watchpoint register pair. Since we can only watch until the next 4
-    // byte boundary, we need to make sure we can properly encode this.
-
-    // addr_word_offset = addr % 4, i.e, is in set([0, 1, 2, 3])
-    //
-    //     +---+---+---+---+
-    //     | 0 | 1 | 2 | 3 |
-    //     +---+---+---+---+
-    //     ^
-    //     |
-    // word address (4-byte aligned) = addr & 0xFFFFFFFC => goes into WVR
-    //
-    // examples:
-    // 1. addr_word_offset = 1, size = 1 to watch a uint_8 => byte_mask = (0b0001 << 1) = 0b0010
-    // 2. addr_word_offset = 2, size = 2 to watch a uint_16 => byte_mask = (0b0011 << 2) = 0b1100
-    //
-    // where byte_mask goes into WCR[8:5]
-
-    uint32_t addr_word_offset = addr % 4;
-    DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint() - addr_word_offset = 0x%8.8x", addr_word_offset);
-
-    uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset;
-    DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint() - byte_mask = 0x%8.8x", byte_mask);
-    if (byte_mask > 0xfu)
-        return INVALID_NUB_HW_INDEX;
+    // At this point 
+    //  1 aligned_wp_address is the requested address rounded down to 8-byte alignment
+    //  2 addr_dword_offset is the offset into that double word (8-byte) region that we are watching
+    //  3 size is the number of bytes within that 8-byte region that we are watching
+
+    // Set the Byte Address Selects bits DBGWCRn_EL1 bits [12:5] based on the above.
+    // The bit shift and negation operation will give us 0b11 for 2, 0b1111 for 4, etc, up to 0b11111111 for 8.
+    // then we shift those bits left by the offset into this dword that we are interested in.
+    // e.g. if we are watching bytes 4,5,6,7 in a dword we want a BAS of 0b11110000.
+    uint32_t byte_address_select = ((1 << size) - 1) << addr_dword_offset;
 
     // Read the debug state
     kern_return_t kret = GetDBGState(true);
@@ -960,10 +1036,14 @@ DNBArchMachARM::EnableHardwareWatchpoint
         {
             //DumpDBGState(m_state.dbg);
 
-            // Make the byte_mask into a valid Byte Address Select mask
-            uint32_t byte_address_select = byte_mask << 5;
+            // Clear any previous LoHi joined-watchpoint that may have been in use
+            LoHi[i] = 0;
+
+            // shift our Byte Address Select bits up to the correct bit range for the DBGWCRn_EL1
+            byte_address_select = byte_address_select << 5;
+    
             // Make sure bits 1:0 are clear in our address
-            m_state.dbg.__wvr[i] = addr & ~((nub_addr_t)3);     // DVA (Data Virtual Address)
+            m_state.dbg.__wvr[i] = aligned_wp_address;          // DVA (Data Virtual Address)
             m_state.dbg.__wcr[i] =  byte_address_select |       // Which bytes that follow the DVA that we will watch
                                     S_USER |                    // Stop only in user mode
                                     (read ? WCR_LOAD : 0) |     // Stop on read access?
@@ -972,6 +1052,8 @@ DNBArchMachARM::EnableHardwareWatchpoint
 
             DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint() adding watchpoint on address 0x%llx with control register value 0x%x", (uint64_t) m_state.dbg.__wvr[i], (uint32_t) m_state.dbg.__wcr[i]);
 
+            // The kernel will set the MDE_ENABLE bit in the MDSCR_EL1 for us automatically, don't need to do it here.
+
             kret = SetDBGState(also_set_on_task);
             //DumpDBGState(m_state.dbg);
 
@@ -989,29 +1071,42 @@ DNBArchMachARM::EnableHardwareWatchpoint
 }
 
 bool
-DNBArchMachARM::EnableHardwareWatchpoint0 (uint32_t hw_index, bool Delegate, bool also_set_on_task)
+DNBArchMachARM::ReenableHardwareWatchpoint (uint32_t hw_index)
+{
+    // If this logical watchpoint # is actually implemented using
+    // two hardware watchpoint registers, re-enable both of them.
+
+    if (hw_index < NumSupportedHardwareWatchpoints() && LoHi[hw_index])
+    {
+        return ReenableHardwareWatchpoint_helper (hw_index) && ReenableHardwareWatchpoint_helper (LoHi[hw_index]);
+    }
+    else
+    {
+        return ReenableHardwareWatchpoint_helper (hw_index);
+    }
+}
+
+bool
+DNBArchMachARM::ReenableHardwareWatchpoint_helper (uint32_t hw_index)
 {
     kern_return_t kret = GetDBGState(false);
     if (kret != KERN_SUCCESS)
         return false;
-
     const uint32_t num_hw_points = NumSupportedHardwareWatchpoints();
     if (hw_index >= num_hw_points)
         return false;
 
-    if (Delegate && LoHi[hw_index]) {
-        // Enable lo and hi watchpoint hardware indexes.
-        return EnableHardwareWatchpoint0(hw_index, false, also_set_on_task) &&
-            EnableHardwareWatchpoint0(LoHi[hw_index], false, also_set_on_task);
-    }
+    m_state.dbg.__wvr[hw_index] = m_disabled_watchpoints[hw_index].addr;
+    m_state.dbg.__wcr[hw_index] = m_disabled_watchpoints[hw_index].control;
 
-    m_state.dbg.__wcr[hw_index] |= (nub_addr_t)WCR_ENABLE;
-    DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint( %u ) - WVR%u = 0x%8.8x  WCR%u = 0x%8.8x",
+    DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint( %u ) - WVR%u = 0x%8.8llx  WCR%u = 0x%8.8llx",
                      hw_index,
                      hw_index,
-                     m_state.dbg.__wvr[hw_index],
+                     (uint64_t) m_state.dbg.__wvr[hw_index],
                      hw_index,
-                     m_state.dbg.__wcr[hw_index]);
+                     (uint64_t) m_state.dbg.__wcr[hw_index]);
+
+   // The kernel will set the MDE_ENABLE bit in the MDSCR_EL1 for us automatically, don't need to do it here.
 
     kret = SetDBGState(false);
 
@@ -1021,10 +1116,18 @@ DNBArchMachARM::EnableHardwareWatchpoint
 bool
 DNBArchMachARM::DisableHardwareWatchpoint (uint32_t hw_index, bool also_set_on_task)
 {
-        return DisableHardwareWatchpoint0(hw_index, true, also_set_on_task);
+    if (hw_index < NumSupportedHardwareWatchpoints() && LoHi[hw_index])
+    {
+        return DisableHardwareWatchpoint_helper (hw_index, also_set_on_task) && DisableHardwareWatchpoint_helper (LoHi[hw_index], also_set_on_task);
+    }
+    else
+    {
+        return DisableHardwareWatchpoint_helper (hw_index, also_set_on_task);
+    }
 }
+
 bool
-DNBArchMachARM::DisableHardwareWatchpoint0 (uint32_t hw_index, bool Delegate, bool also_set_on_task)
+DNBArchMachARM::DisableHardwareWatchpoint_helper (uint32_t hw_index, bool also_set_on_task)
 {
     kern_return_t kret = GetDBGState(false);
     if (kret != KERN_SUCCESS)
@@ -1034,19 +1137,17 @@ DNBArchMachARM::DisableHardwareWatchpoin
     if (hw_index >= num_hw_points)
         return false;
 
-    if (Delegate && LoHi[hw_index]) {
-        // Disable lo and hi watchpoint hardware indexes.
-        return DisableHardwareWatchpoint0(hw_index, false, also_set_on_task) &&
-            DisableHardwareWatchpoint0(LoHi[hw_index], false, also_set_on_task);
-    }
+    m_disabled_watchpoints[hw_index].addr = m_state.dbg.__wvr[hw_index];
+    m_disabled_watchpoints[hw_index].control = m_state.dbg.__wcr[hw_index];
 
-    m_state.dbg.__wcr[hw_index] &= ~((nub_addr_t)WCR_ENABLE);
-    DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::DisableHardwareWatchpoint( %u ) - WVR%u = 0x%8.8x  WCR%u = 0x%8.8x",
+    m_state.dbg.__wvr[hw_index] = 0;
+    m_state.dbg.__wcr[hw_index] = 0;
+    DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::DisableHardwareWatchpoint( %u ) - WVR%u = 0x%8.8llx  WCR%u = 0x%8.8llx",
                      hw_index,
                      hw_index,
-                     m_state.dbg.__wvr[hw_index],
+                     (uint64_t) m_state.dbg.__wvr[hw_index],
                      hw_index,
-                     m_state.dbg.__wcr[hw_index]);
+                     (uint64_t) m_state.dbg.__wcr[hw_index]);
 
     kret = SetDBGState(also_set_on_task);
 
@@ -1079,7 +1180,11 @@ DNBArchMachARM::GetHardwareWatchpointHit
     DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::GetHardwareWatchpointHit() addr = 0x%llx", (uint64_t)addr);
 
     // This is the watchpoint value to match against, i.e., word address.
+#if defined (WATCHPOINTS_ARE_DWORD)
+    nub_addr_t wp_val = addr & ~((nub_addr_t)7); 
+#else
     nub_addr_t wp_val = addr & ~((nub_addr_t)3);
+#endif
     if (kret == KERN_SUCCESS)
     {
         DBG &debug_state = m_state.dbg;
@@ -1091,7 +1196,11 @@ DNBArchMachARM::GetHardwareWatchpointHit
                              "DNBArchMachARM::GetHardwareWatchpointHit() slot: %u (addr = 0x%llx).",
                              i, (uint64_t)wp_addr);
             if (wp_val == wp_addr) {
+#if defined (WATCHPOINTS_ARE_DWORD)
+                uint32_t byte_mask = bits(debug_state.__wcr[i], 12, 5);
+#else
                 uint32_t byte_mask = bits(debug_state.__wcr[i], 8, 5);
+#endif
 
                 // Sanity check the byte_mask, first.
                 if (LowestBitSet(byte_mask) < 0)
@@ -1106,36 +1215,18 @@ DNBArchMachARM::GetHardwareWatchpointHit
     return INVALID_NUB_HW_INDEX;
 }
 
-// ThreadWillResume() calls this to clear bits[5:2] (Method of entry bits) of
-// the Debug Status and Control Register (DSCR).
-// 
-// b0010 = a watchpoint occurred
-// b0000 is the reset value
-void
-DNBArchMachARM::ClearWatchpointOccurred()
-{
-    uint32_t register_DBGDSCR;
-    asm("mrc p14, 0, %0, c0, c1, 0" : "=r" (register_DBGDSCR));
-    if (bits(register_DBGDSCR, 5, 2) == WATCHPOINT_OCCURRED)
-    {
-        uint32_t mask = ~(0xF << 2);
-        register_DBGDSCR &= mask;
-        asm("mcr p14, 0, %0, c0, c1, 0" : "=r" (register_DBGDSCR));
-    }
-    return;
-}
-
-// NotifyException() calls this to double check that a watchpoint has occurred
-// by inspecting the bits[5:2] field of the Debug Status and Control Register
-// (DSCR).
-// 
-// b0010 = a watchpoint occurred
-bool
-DNBArchMachARM::HasWatchpointOccurred()
+nub_addr_t
+DNBArchMachARM::GetWatchpointAddressByIndex (uint32_t hw_index)
 {
-    uint32_t register_DBGDSCR;
-    asm("mrc p14, 0, %0, c0, c1, 0" : "=r" (register_DBGDSCR));
-    return (bits(register_DBGDSCR, 5, 2) == WATCHPOINT_OCCURRED);
+    kern_return_t kret = GetDBGState(true);
+    if (kret != KERN_SUCCESS)
+        return INVALID_NUB_ADDRESS;
+    const uint32_t num = NumSupportedHardwareWatchpoints();
+    if (hw_index >= num)
+        return INVALID_NUB_ADDRESS;
+    if (IsWatchpointEnabled (m_state.dbg, hw_index))
+        return GetWatchAddress (m_state.dbg, hw_index);
+    return INVALID_NUB_ADDRESS;
 }
 
 bool

Modified: lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h Sat Mar 29 13:54:20 2014
@@ -14,7 +14,7 @@
 #ifndef __DebugNubArchMachARM_h__
 #define __DebugNubArchMachARM_h__
 
-#if defined (__arm__)
+#if defined (__arm__) || defined (__arm64__)
 
 #include "DNBArch.h"
 
@@ -30,6 +30,7 @@ public:
     DNBArchMachARM(MachThread *thread) :
         m_thread(thread),
         m_state(),
+        m_disabled_watchpoints(),
         m_hw_single_chained_step_addr(INVALID_NUB_ADDRESS),
         m_last_decode_pc(INVALID_NUB_ADDRESS),
         m_watchpoint_hw_index(-1),
@@ -37,6 +38,7 @@ public:
         m_watchpoint_resume_single_step_enabled(false),
         m_saved_register_states()
     {
+        m_disabled_watchpoints.resize (16);
         memset(&m_dbg_save, 0, sizeof(m_dbg_save));
 #if defined (USE_ARM_DISASSEMBLER_FRAMEWORK)
         ThumbStaticsInit(&m_last_decode_thumb);
@@ -76,15 +78,22 @@ public:
     virtual uint32_t        NumSupportedHardwareBreakpoints();
     virtual uint32_t        NumSupportedHardwareWatchpoints();
     virtual uint32_t        EnableHardwareBreakpoint (nub_addr_t addr, nub_size_t size);
-    virtual uint32_t        EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write, bool also_set_on_task);
     virtual bool            DisableHardwareBreakpoint (uint32_t hw_break_index);
+
+    virtual uint32_t        EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write, bool also_set_on_task);
     virtual bool            DisableHardwareWatchpoint (uint32_t hw_break_index, bool also_set_on_task);
-    virtual bool            EnableHardwareWatchpoint0 (uint32_t hw_break_index, bool Delegate, bool also_set_on_task);
-    virtual bool            DisableHardwareWatchpoint0 (uint32_t hw_break_index, bool Delegate, bool also_set_on_task);
+    virtual bool            DisableHardwareWatchpoint_helper (uint32_t hw_break_index, bool also_set_on_task);
+    virtual bool            ReenableHardwareWatchpoint (uint32_t hw_break_index);
+    virtual bool            ReenableHardwareWatchpoint_helper (uint32_t hw_break_index);
+
     virtual bool            StepNotComplete ();
     virtual uint32_t        GetHardwareWatchpointHit(nub_addr_t &addr);
 
+#if defined (ARM_DEBUG_STATE32) && defined (__arm64__)
+    typedef arm_debug_state32_t DBG;
+#else
     typedef arm_debug_state_t DBG;
+#endif
 
 protected:
 
@@ -106,7 +115,11 @@ protected:
         e_regSetGPR = ARM_THREAD_STATE,
         e_regSetVFP = ARM_VFP_STATE,
         e_regSetEXC = ARM_EXCEPTION_STATE,
+#if defined (ARM_DEBUG_STATE32) && defined (__arm64__)
+        e_regSetDBG = ARM_DEBUG_STATE32,
+#else
         e_regSetDBG = ARM_DEBUG_STATE,
+#endif
         kNumRegisterSets
     } RegisterSet;
 
@@ -232,16 +245,26 @@ protected:
     kern_return_t SetEXCState ();
     kern_return_t SetDBGState (bool also_set_on_task);
 
-    // Helper functions for watchpoint implementaions.
-    static void ClearWatchpointOccurred();
-    static bool HasWatchpointOccurred();
-    static bool IsWatchpointEnabled(const DBG &debug_state, uint32_t hw_index);
-    static nub_addr_t GetWatchAddress(const DBG &debug_state, uint32_t hw_index);
+    bool IsWatchpointEnabled(const DBG &debug_state, uint32_t hw_index);
+    nub_addr_t GetWatchpointAddressByIndex (uint32_t hw_index);
+    nub_addr_t GetWatchAddress(const DBG &debug_state, uint32_t hw_index);
+
+    class disabled_watchpoint {
+    public:
+        disabled_watchpoint () { addr = 0; control = 0; }
+        nub_addr_t addr;
+        uint32_t   control;
+    };
 
 protected:
     MachThread *    m_thread;
     State           m_state;
     DBG             m_dbg_save;
+
+    // armv8 doesn't keep the disabled watchpoint values in the debug register context like armv7;
+    // we need to save them aside when we disable them temporarily.
+    std::vector<disabled_watchpoint> m_disabled_watchpoints;
+
     nub_addr_t      m_hw_single_chained_step_addr;
     nub_addr_t      m_last_decode_pc;
 

Added: lldb/trunk/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp?rev=205113&view=auto
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp (added)
+++ lldb/trunk/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp Sat Mar 29 13:54:20 2014
@@ -0,0 +1,2093 @@
+//===-- DNBArchMachARM64.cpp ------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Created by Greg Clayton on 6/25/07.
+//
+//===----------------------------------------------------------------------===//
+
+#if defined (__arm__) || defined (__arm64__)
+
+#include "MacOSX/arm64/DNBArchImplARM64.h"
+
+#if defined (ARM_THREAD_STATE64_COUNT)
+
+#include "MacOSX/MachProcess.h"
+#include "MacOSX/MachThread.h"
+#include "DNBBreakpoint.h"
+#include "DNBLog.h"
+#include "DNBRegisterInfo.h"
+#include "DNB.h"
+
+#include <inttypes.h>
+#include <sys/sysctl.h>
+
+// Break only in privileged or user mode
+// (PAC bits in the DBGWVRn_EL1 watchpoint control register)
+#define S_USER                  ((uint32_t)(2u << 1))
+
+#define BCR_ENABLE              ((uint32_t)(1u))
+#define WCR_ENABLE              ((uint32_t)(1u))
+
+// Watchpoint load/store
+// (LSC bits in the DBGWVRn_EL1 watchpoint control register)
+#define WCR_LOAD                ((uint32_t)(1u << 3))
+#define WCR_STORE               ((uint32_t)(1u << 4))
+
+// Enable breakpoint, watchpoint, and vector catch debug exceptions.
+// (MDE bit in the MDSCR_EL1 register.  Equivalent to the MDBGen bit in DBGDSCRext in Aarch32)
+#define MDE_ENABLE ((uint32_t)(1u << 15))
+
+// Single instruction step
+// (SS bit in the MDSCR_EL1 register)
+#define SS_ENABLE ((uint32_t)(1u))
+
+static const uint8_t g_arm64_breakpoint_opcode[] = { 0x00, 0x00, 0x20, 0xD4 }; // "brk #0", 0xd4200000 in BE byte order
+static const uint8_t g_arm_breakpoint_opcode[] = { 0xFE, 0xDE, 0xFF, 0xE7 };   // this armv7 insn also works in arm64
+
+// If we need to set one logical watchpoint by using
+// two hardware watchpoint registers, the watchpoint
+// will be split into a "high" and "low" watchpoint.
+// Record both of them in the LoHi array.
+
+// It's safe to initialize to all 0's since 
+// hi > lo and therefore LoHi[i] cannot be 0.
+static uint32_t LoHi[16] = { 0 };
+
+
+void
+DNBArchMachARM64::Initialize()
+{
+    DNBArchPluginInfo arch_plugin_info = 
+    {
+        CPU_TYPE_ARM64, 
+        DNBArchMachARM64::Create, 
+        DNBArchMachARM64::GetRegisterSetInfo,
+        DNBArchMachARM64::SoftwareBreakpointOpcode
+    };
+    
+    // Register this arch plug-in with the main protocol class
+    DNBArchProtocol::RegisterArchPlugin (arch_plugin_info);
+}
+
+
+DNBArchProtocol *
+DNBArchMachARM64::Create (MachThread *thread)
+{
+    DNBArchMachARM64 *obj = new DNBArchMachARM64 (thread);
+
+    return obj;
+}
+
+const uint8_t * const
+DNBArchMachARM64::SoftwareBreakpointOpcode (nub_size_t byte_size)
+{
+    return g_arm_breakpoint_opcode;
+}
+
+uint32_t
+DNBArchMachARM64::GetCPUType()
+{
+    return CPU_TYPE_ARM64;
+}
+
+uint64_t
+DNBArchMachARM64::GetPC(uint64_t failValue)
+{
+    // Get program counter
+    if (GetGPRState(false) == KERN_SUCCESS)
+        return m_state.context.gpr.__pc;
+    return failValue;
+}
+
+kern_return_t
+DNBArchMachARM64::SetPC(uint64_t value)
+{
+    // Get program counter
+    kern_return_t err = GetGPRState(false);
+    if (err == KERN_SUCCESS)
+    {
+        m_state.context.gpr.__pc = value;
+        err = SetGPRState();
+    }
+    return err == KERN_SUCCESS;
+}
+
+uint64_t
+DNBArchMachARM64::GetSP(uint64_t failValue)
+{
+    // Get stack pointer
+    if (GetGPRState(false) == KERN_SUCCESS)
+        return m_state.context.gpr.__sp;
+    return failValue;
+}
+
+kern_return_t
+DNBArchMachARM64::GetGPRState(bool force)
+{
+    int set = e_regSetGPR;
+    // Check if we have valid cached registers
+    if (!force && m_state.GetError(set, Read) == KERN_SUCCESS)
+        return KERN_SUCCESS;
+
+    // Read the registers from our thread
+    mach_msg_type_number_t count = e_regSetGPRCount;
+    kern_return_t kret = ::thread_get_state(m_thread->MachPortNumber(), ARM_THREAD_STATE64, (thread_state_t)&m_state.context.gpr, &count);
+    if (DNBLogEnabledForAny (LOG_THREAD))
+    {
+        uint64_t *x = &m_state.context.gpr.__x[0];
+        DNBLogThreaded("thread_get_state(0x%4.4x, %u, &gpr, %u) => 0x%8.8x (count = %u) regs"
+                       "\n   x0=%16.16llx"
+                       "\n   x1=%16.16llx"
+                       "\n   x2=%16.16llx"
+                       "\n   x3=%16.16llx"
+                       "\n   x4=%16.16llx"
+                       "\n   x5=%16.16llx"
+                       "\n   x6=%16.16llx"
+                       "\n   x7=%16.16llx"
+                       "\n   x8=%16.16llx"
+                       "\n   x9=%16.16llx"
+                       "\n  x10=%16.16llx"
+                       "\n  x11=%16.16llx"
+                       "\n  x12=%16.16llx"
+                       "\n  x13=%16.16llx"
+                       "\n  x14=%16.16llx"
+                       "\n  x15=%16.16llx"
+                       "\n  x16=%16.16llx"
+                       "\n  x17=%16.16llx"
+                       "\n  x18=%16.16llx"
+                       "\n  x19=%16.16llx"
+                       "\n  x20=%16.16llx"
+                       "\n  x21=%16.16llx"
+                       "\n  x22=%16.16llx"
+                       "\n  x23=%16.16llx"
+                       "\n  x24=%16.16llx"
+                       "\n  x25=%16.16llx"
+                       "\n  x26=%16.16llx"
+                       "\n  x27=%16.16llx"
+                       "\n  x28=%16.16llx"
+                       "\n   fp=%16.16llx"
+                       "\n   lr=%16.16llx"
+                       "\n   sp=%16.16llx"
+                       "\n   pc=%16.16llx"
+                       "\n cpsr=%8.8x", 
+                       m_thread->MachPortNumber(), 
+                       e_regSetGPR, 
+                       e_regSetGPRCount, 
+                       kret,
+                       count,
+                       x[0], 
+                       x[1], 
+                       x[2], 
+                       x[3], 
+                       x[4], 
+                       x[5], 
+                       x[6], 
+                       x[7], 
+                       x[8], 
+                       x[9], 
+                       x[0], 
+                       x[11], 
+                       x[12], 
+                       x[13], 
+                       x[14], 
+                       x[15], 
+                       x[16], 
+                       x[17], 
+                       x[18], 
+                       x[19], 
+                       x[20], 
+                       x[21], 
+                       x[22], 
+                       x[23], 
+                       x[24], 
+                       x[25], 
+                       x[26], 
+                       x[27], 
+                       x[28], 
+                       m_state.context.gpr.__fp,
+                       m_state.context.gpr.__lr,
+                       m_state.context.gpr.__sp,
+                       m_state.context.gpr.__pc,
+                       m_state.context.gpr.__cpsr);
+    }
+    m_state.SetError(set, Read, kret);
+    return kret;
+}
+
+kern_return_t
+DNBArchMachARM64::GetVFPState(bool force)
+{
+    int set = e_regSetVFP;
+    // Check if we have valid cached registers
+    if (!force && m_state.GetError(set, Read) == KERN_SUCCESS)
+        return KERN_SUCCESS;
+
+    // Read the registers from our thread
+    mach_msg_type_number_t count = e_regSetVFPCount;
+    kern_return_t kret = ::thread_get_state(m_thread->MachPortNumber(), ARM_NEON_STATE64, (thread_state_t)&m_state.context.vfp, &count);
+    if (DNBLogEnabledForAny (LOG_THREAD))
+    {
+#if defined (__arm64__)
+        DNBLogThreaded("thread_get_state(0x%4.4x, %u, &vfp, %u) => 0x%8.8x (count = %u) regs"
+                       "\n   q0  = 0x%16.16llx%16.16llx"
+                       "\n   q1  = 0x%16.16llx%16.16llx"
+                       "\n   q2  = 0x%16.16llx%16.16llx"
+                       "\n   q3  = 0x%16.16llx%16.16llx"
+                       "\n   q4  = 0x%16.16llx%16.16llx"
+                       "\n   q5  = 0x%16.16llx%16.16llx"
+                       "\n   q6  = 0x%16.16llx%16.16llx"
+                       "\n   q7  = 0x%16.16llx%16.16llx"
+                       "\n   q8  = 0x%16.16llx%16.16llx"
+                       "\n   q9  = 0x%16.16llx%16.16llx"
+                       "\n   q10 = 0x%16.16llx%16.16llx"
+                       "\n   q11 = 0x%16.16llx%16.16llx"
+                       "\n   q12 = 0x%16.16llx%16.16llx"
+                       "\n   q13 = 0x%16.16llx%16.16llx"
+                       "\n   q14 = 0x%16.16llx%16.16llx"
+                       "\n   q15 = 0x%16.16llx%16.16llx"
+                       "\n   q16 = 0x%16.16llx%16.16llx"
+                       "\n   q17 = 0x%16.16llx%16.16llx"
+                       "\n   q18 = 0x%16.16llx%16.16llx"
+                       "\n   q19 = 0x%16.16llx%16.16llx"
+                       "\n   q20 = 0x%16.16llx%16.16llx"
+                       "\n   q21 = 0x%16.16llx%16.16llx"
+                       "\n   q22 = 0x%16.16llx%16.16llx"
+                       "\n   q23 = 0x%16.16llx%16.16llx"
+                       "\n   q24 = 0x%16.16llx%16.16llx"
+                       "\n   q25 = 0x%16.16llx%16.16llx"
+                       "\n   q26 = 0x%16.16llx%16.16llx"
+                       "\n   q27 = 0x%16.16llx%16.16llx"
+                       "\n   q28 = 0x%16.16llx%16.16llx"
+                       "\n   q29 = 0x%16.16llx%16.16llx"
+                       "\n   q30 = 0x%16.16llx%16.16llx"
+                       "\n   q31 = 0x%16.16llx%16.16llx"
+                       "\n  fpsr = 0x%8.8x"
+                       "\n  fpcr = 0x%8.8x\n\n",
+                       m_thread->MachPortNumber(),
+                       e_regSetVFP, 
+                       e_regSetVFPCount, 
+                       kret,
+                       count,
+                       ((uint64_t *)&m_state.context.vfp.__v[0])[0] , ((uint64_t *)&m_state.context.vfp.__v[0])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[1])[0] , ((uint64_t *)&m_state.context.vfp.__v[1])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[2])[0] , ((uint64_t *)&m_state.context.vfp.__v[2])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[3])[0] , ((uint64_t *)&m_state.context.vfp.__v[3])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[4])[0] , ((uint64_t *)&m_state.context.vfp.__v[4])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[5])[0] , ((uint64_t *)&m_state.context.vfp.__v[5])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[6])[0] , ((uint64_t *)&m_state.context.vfp.__v[6])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[7])[0] , ((uint64_t *)&m_state.context.vfp.__v[7])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[8])[0] , ((uint64_t *)&m_state.context.vfp.__v[8])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[9])[0] , ((uint64_t *)&m_state.context.vfp.__v[9])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[10])[0], ((uint64_t *)&m_state.context.vfp.__v[10])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[11])[0], ((uint64_t *)&m_state.context.vfp.__v[11])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[12])[0], ((uint64_t *)&m_state.context.vfp.__v[12])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[13])[0], ((uint64_t *)&m_state.context.vfp.__v[13])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[14])[0], ((uint64_t *)&m_state.context.vfp.__v[14])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[15])[0], ((uint64_t *)&m_state.context.vfp.__v[15])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[16])[0], ((uint64_t *)&m_state.context.vfp.__v[16])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[17])[0], ((uint64_t *)&m_state.context.vfp.__v[17])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[18])[0], ((uint64_t *)&m_state.context.vfp.__v[18])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[19])[0], ((uint64_t *)&m_state.context.vfp.__v[19])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[20])[0], ((uint64_t *)&m_state.context.vfp.__v[20])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[21])[0], ((uint64_t *)&m_state.context.vfp.__v[21])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[22])[0], ((uint64_t *)&m_state.context.vfp.__v[22])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[23])[0], ((uint64_t *)&m_state.context.vfp.__v[23])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[24])[0], ((uint64_t *)&m_state.context.vfp.__v[24])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[25])[0], ((uint64_t *)&m_state.context.vfp.__v[25])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[26])[0], ((uint64_t *)&m_state.context.vfp.__v[26])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[27])[0], ((uint64_t *)&m_state.context.vfp.__v[27])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[28])[0], ((uint64_t *)&m_state.context.vfp.__v[28])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[29])[0], ((uint64_t *)&m_state.context.vfp.__v[29])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[30])[0], ((uint64_t *)&m_state.context.vfp.__v[30])[1],
+                       ((uint64_t *)&m_state.context.vfp.__v[31])[0], ((uint64_t *)&m_state.context.vfp.__v[31])[1],
+                       m_state.context.vfp.__fpsr,
+                       m_state.context.vfp.__fpcr);
+#endif
+    }
+    m_state.SetError(set, Read, kret);
+    return kret;
+}
+
+kern_return_t
+DNBArchMachARM64::GetEXCState(bool force)
+{
+    int set = e_regSetEXC;
+    // Check if we have valid cached registers
+    if (!force && m_state.GetError(set, Read) == KERN_SUCCESS)
+        return KERN_SUCCESS;
+
+    // Read the registers from our thread
+    mach_msg_type_number_t count = e_regSetEXCCount;
+    kern_return_t kret = ::thread_get_state(m_thread->MachPortNumber(), ARM_EXCEPTION_STATE64, (thread_state_t)&m_state.context.exc, &count);
+    m_state.SetError(set, Read, kret);
+    return kret;
+}
+
+static void
+DumpDBGState(const arm_debug_state_t& dbg)
+{
+    uint32_t i = 0;
+    for (i=0; i<16; i++)
+        DNBLogThreadedIf(LOG_STEP, "BVR%-2u/BCR%-2u = { 0x%8.8x, 0x%8.8x } WVR%-2u/WCR%-2u = { 0x%8.8x, 0x%8.8x }",
+            i, i, dbg.__bvr[i], dbg.__bcr[i],
+            i, i, dbg.__wvr[i], dbg.__wcr[i]);
+}
+
+kern_return_t
+DNBArchMachARM64::GetDBGState(bool force)
+{
+    int set = e_regSetDBG;
+
+    // Check if we have valid cached registers
+    if (!force && m_state.GetError(set, Read) == KERN_SUCCESS)
+        return KERN_SUCCESS;
+
+    // Read the registers from our thread
+    mach_msg_type_number_t count = e_regSetDBGCount;
+    kern_return_t kret = ::thread_get_state(m_thread->MachPortNumber(), ARM_DEBUG_STATE64, (thread_state_t)&m_state.dbg, &count);
+    m_state.SetError(set, Read, kret);
+
+    return kret;
+}
+
+kern_return_t
+DNBArchMachARM64::SetGPRState()
+{
+    int set = e_regSetGPR;
+    kern_return_t kret = ::thread_set_state(m_thread->MachPortNumber(), ARM_THREAD_STATE64, (thread_state_t)&m_state.context.gpr, e_regSetGPRCount);
+    m_state.SetError(set, Write, kret);         // Set the current write error for this register set
+    m_state.InvalidateRegisterSetState(set);    // Invalidate the current register state in case registers are read back differently
+    return kret;                                // Return the error code
+}
+
+kern_return_t
+DNBArchMachARM64::SetVFPState()
+{
+    int set = e_regSetVFP;
+    kern_return_t kret = ::thread_set_state (m_thread->MachPortNumber(), ARM_NEON_STATE64, (thread_state_t)&m_state.context.vfp, e_regSetVFPCount);
+    m_state.SetError(set, Write, kret);         // Set the current write error for this register set
+    m_state.InvalidateRegisterSetState(set);    // Invalidate the current register state in case registers are read back differently
+    return kret;                                // Return the error code
+}
+
+kern_return_t
+DNBArchMachARM64::SetEXCState()
+{
+    int set = e_regSetEXC;
+    kern_return_t kret = ::thread_set_state (m_thread->MachPortNumber(), ARM_EXCEPTION_STATE64, (thread_state_t)&m_state.context.exc, e_regSetEXCCount);
+    m_state.SetError(set, Write, kret);         // Set the current write error for this register set
+    m_state.InvalidateRegisterSetState(set);    // Invalidate the current register state in case registers are read back differently
+    return kret;                                // Return the error code
+}
+
+kern_return_t
+DNBArchMachARM64::SetDBGState(bool also_set_on_task)
+{
+    int set = e_regSetDBG;
+    kern_return_t kret = ::thread_set_state (m_thread->MachPortNumber(), ARM_DEBUG_STATE64, (thread_state_t)&m_state.dbg, e_regSetDBGCount);
+    if (also_set_on_task)
+    {
+        kern_return_t task_kret = task_set_state (m_thread->Process()->Task().TaskPort(), ARM_DEBUG_STATE64, (thread_state_t)&m_state.dbg, e_regSetDBGCount);
+        if (task_kret != KERN_SUCCESS)
+             DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM64::SetDBGState failed to set debug control register state: 0x%8.8x.", task_kret);
+    }
+    m_state.SetError(set, Write, kret);         // Set the current write error for this register set
+    m_state.InvalidateRegisterSetState(set);    // Invalidate the current register state in case registers are read back differently
+
+    return kret;                                // Return the error code
+}
+
+void
+DNBArchMachARM64::ThreadWillResume()
+{
+    // Do we need to step this thread? If so, let the mach thread tell us so.
+    if (m_thread->IsStepping())
+    {
+        EnableHardwareSingleStep(true);
+    }
+
+    // Disable the triggered watchpoint temporarily before we resume.
+    // Plus, we try to enable hardware single step to execute past the instruction which triggered our watchpoint.
+    if (m_watchpoint_did_occur)
+    {
+        if (m_watchpoint_hw_index >= 0)
+        {
+            kern_return_t kret = GetDBGState(false);
+            if (kret == KERN_SUCCESS && !IsWatchpointEnabled(m_state.dbg, m_watchpoint_hw_index)) {
+                // The watchpoint might have been disabled by the user.  We don't need to do anything at all
+                // to enable hardware single stepping.
+                m_watchpoint_did_occur = false;
+                m_watchpoint_hw_index = -1;
+                return;
+            }
+
+            DisableHardwareWatchpoint(m_watchpoint_hw_index, false);
+            DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::ThreadWillResume() DisableHardwareWatchpoint(%d) called",
+                             m_watchpoint_hw_index);
+
+            // Enable hardware single step to move past the watchpoint-triggering instruction.
+            m_watchpoint_resume_single_step_enabled = (EnableHardwareSingleStep(true) == KERN_SUCCESS);
+
+            // If we are not able to enable single step to move past the watchpoint-triggering instruction,
+            // at least we should reset the two watchpoint member variables so that the next time around
+            // this callback function is invoked, the enclosing logical branch is skipped.
+            if (!m_watchpoint_resume_single_step_enabled) {
+                // Reset the two watchpoint member variables.
+                m_watchpoint_did_occur = false;
+                m_watchpoint_hw_index = -1;
+                DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::ThreadWillResume() failed to enable single step");
+            }
+            else
+                DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::ThreadWillResume() succeeded to enable single step");
+        }
+    }
+}
+
+bool
+DNBArchMachARM64::NotifyException(MachException::Data& exc)
+{
+
+    switch (exc.exc_type)
+    {
+        default:
+            break;
+        case EXC_BREAKPOINT:
+            if (exc.exc_data.size() == 2 && exc.exc_data[0] == EXC_ARM_DA_DEBUG)
+            {
+                // The data break address is passed as exc_data[1].
+                nub_addr_t addr = exc.exc_data[1];
+                // Find the hardware index with the side effect of possibly massaging the
+                // addr to return the starting address as seen from the debugger side.
+                uint32_t hw_index = GetHardwareWatchpointHit(addr);
+
+                // One logical watchpoint was split into two watchpoint locations because
+                // it was too big.  If the watchpoint exception is indicating the 2nd half
+                // of the two-parter, find the address of the 1st half and report that --
+                // that's what lldb is going to expect to see.
+                DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::NotifyException watchpoint %d was hit on address 0x%llx", hw_index, (uint64_t) addr);
+                const int num_watchpoints = NumSupportedHardwareWatchpoints ();
+                for (int i = 0; i < num_watchpoints; i++)
+                {
+                   if (LoHi[i] != 0
+                       && LoHi[i] == hw_index 
+                       && LoHi[i] != i
+                       && GetWatchpointAddressByIndex (i) != INVALID_NUB_ADDRESS)
+                   {
+                       addr = GetWatchpointAddressByIndex (i);
+                       DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::NotifyException It is a linked watchpoint; rewritten to index %d addr 0x%llx", LoHi[i], (uint64_t) addr);
+                    }
+                }
+
+                if (hw_index != INVALID_NUB_HW_INDEX)
+                {
+                    m_watchpoint_did_occur = true;
+                    m_watchpoint_hw_index = hw_index;
+                    exc.exc_data[1] = addr;
+                    // Piggyback the hw_index in the exc.data.
+                    exc.exc_data.push_back(hw_index);
+                }
+
+                return true;
+            }
+            break;
+    }
+    return false;
+}
+
+bool
+DNBArchMachARM64::ThreadDidStop()
+{
+    bool success = true;
+    
+    m_state.InvalidateAllRegisterStates();
+
+    if (m_watchpoint_resume_single_step_enabled)
+    {
+        // Great!  We now disable the hardware single step as well as re-enable the hardware watchpoint.
+        // See also ThreadWillResume().
+        if (EnableHardwareSingleStep(false) == KERN_SUCCESS)
+        {
+            if (m_watchpoint_did_occur && m_watchpoint_hw_index >= 0)
+            {
+                ReenableHardwareWatchpoint(m_watchpoint_hw_index);
+                m_watchpoint_resume_single_step_enabled = false;
+                m_watchpoint_did_occur = false;
+                m_watchpoint_hw_index = -1;
+            }
+            else
+            {
+                DNBLogError("internal error detected: m_watchpoint_resume_step_enabled is true but (m_watchpoint_did_occur && m_watchpoint_hw_index >= 0) does not hold!");
+            }
+        }
+        else
+        {
+            DNBLogError("internal error detected: m_watchpoint_resume_step_enabled is true but unable to disable single step!");
+        }
+    }
+
+    // Are we stepping a single instruction?
+    if (GetGPRState(true) == KERN_SUCCESS)
+    {
+        // We are single stepping, was this the primary thread?
+        if (m_thread->IsStepping())
+        {
+            // This was the primary thread, we need to clear the trace
+            // bit if so.
+            success = EnableHardwareSingleStep(false) == KERN_SUCCESS;
+        }
+        else
+        {
+            // The MachThread will automatically restore the suspend count
+            // in ThreadDidStop(), so we don't need to do anything here if
+            // we weren't the primary thread the last time
+        }
+    }
+    return success;
+}
+
+// Set the single step bit in the processor status register.
+kern_return_t
+DNBArchMachARM64::EnableHardwareSingleStep (bool enable)
+{
+    DNBError err;
+    DNBLogThreadedIf(LOG_STEP, "%s( enable = %d )", __FUNCTION__, enable);
+
+    err = GetGPRState(false);
+
+    if (err.Fail())
+    {
+        err.LogThreaded("%s: failed to read the GPR registers", __FUNCTION__);
+        return err.Error();
+    }
+
+    err = GetDBGState(false);
+
+    if (err.Fail())
+    {
+        err.LogThreaded("%s: failed to read the DBG registers", __FUNCTION__);
+        return err.Error();
+    }
+
+    if (enable)
+    {
+        DNBLogThreadedIf(LOG_STEP, "%s: Setting MDSCR_EL1 Single Step bit at pc 0x%llx", __FUNCTION__, (uint64_t) m_state.context.gpr.__pc);
+        m_state.dbg.__mdscr_el1 |= SS_ENABLE;
+    }
+    else
+    {
+        DNBLogThreadedIf(LOG_STEP, "%s: Clearing MDSCR_EL1 Single Step bit at pc 0x%llx", __FUNCTION__, (uint64_t) m_state.context.gpr.__pc);
+        m_state.dbg.__mdscr_el1 &= ~(SS_ENABLE);
+    }
+
+    return SetDBGState(false);
+}
+
+// return 1 if bit "BIT" is set in "value"
+static inline uint32_t bit(uint32_t value, uint32_t bit)
+{
+    return (value >> bit) & 1u;
+}
+
+// return the bitfield "value[msbit:lsbit]".
+static inline uint64_t bits(uint64_t value, uint32_t msbit, uint32_t lsbit)
+{
+    assert(msbit >= lsbit);
+    uint64_t shift_left = sizeof(value) * 8 - 1 - msbit;
+    value <<= shift_left;           // shift anything above the msbit off of the unsigned edge
+    value >>= shift_left + lsbit;   // shift it back again down to the lsbit (including undoing any shift from above)
+    return value;                   // return our result
+}
+
+uint32_t
+DNBArchMachARM64::NumSupportedHardwareWatchpoints()
+{
+    // Set the init value to something that will let us know that we need to
+    // autodetect how many watchpoints are supported dynamically...
+    static uint32_t g_num_supported_hw_watchpoints = UINT_MAX;
+    if (g_num_supported_hw_watchpoints == UINT_MAX)
+    {
+        // Set this to zero in case we can't tell if there are any HW breakpoints
+        g_num_supported_hw_watchpoints = 0;
+        
+        
+        size_t len;
+        uint32_t n = 0;
+        len = sizeof (n);
+        if (::sysctlbyname("hw.optional.watchpoint", &n, &len, NULL, 0) == 0)
+        {
+            g_num_supported_hw_watchpoints = n;
+            DNBLogThreadedIf(LOG_THREAD, "hw.optional.watchpoint=%u", n);
+        }
+        else
+        {
+            // For AArch64 we would need to look at ID_AA64DFR0_EL1 but debugserver runs in EL0 so it can't
+            // access that reg.  The kernel should have filled in the sysctls based on it though.
+#if defined (__arm__)
+            uint32_t register_DBGDIDR;
+
+            asm("mrc p14, 0, %0, c0, c0, 0" : "=r" (register_DBGDIDR));
+            uint32_t numWRPs = bits(register_DBGDIDR, 31, 28);
+            // Zero is reserved for the WRP count, so don't increment it if it is zero
+            if (numWRPs > 0)
+                numWRPs++;
+            g_num_supported_hw_watchpoints = numWRPs;
+            DNBLogThreadedIf(LOG_THREAD, "Number of supported hw watchpoints via asm():  %d", g_num_supported_hw_watchpoints);
+#endif
+        }
+    }
+    return g_num_supported_hw_watchpoints;
+}
+
+uint32_t
+DNBArchMachARM64::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write, bool also_set_on_task)
+{
+    DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM64::EnableHardwareWatchpoint(addr = 0x%8.8llx, size = %zu, read = %u, write = %u)", (uint64_t)addr, size, read, write);
+
+    const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
+
+    // Can't watch zero bytes
+    if (size == 0)
+        return INVALID_NUB_HW_INDEX;
+
+    // We must watch for either read or write
+    if (read == false && write == false)
+        return INVALID_NUB_HW_INDEX;
+
+    // Otherwise, can't watch more than 8 bytes per WVR/WCR pair
+    if (size > 8)
+        return INVALID_NUB_HW_INDEX;
+
+    // arm64 watchpoints really have an 8-byte alignment requirement.  You can put a watchpoint on a 4-byte
+    // offset address but you can only watch 4 bytes with that watchpoint.
+
+    // arm64 watchpoints on an 8-byte (double word) aligned addr can watch any bytes in that 
+    // 8-byte long region of memory.  They can watch the 1st byte, the 2nd byte, 3rd byte, etc, or any
+    // combination therein by setting the bits in the BAS [12:5] (Byte Address Select) field of
+    // the DBGWCRn_EL1 reg for the watchpoint.
+
+    // If the MASK [28:24] bits in the DBGWCRn_EL1 allow a single watchpoint to monitor a larger region
+    // of memory (16 bytes, 32 bytes, or 2GB) but the Byte Address Select bitfield then selects a larger
+    // range of bytes, instead of individual bytes.  See the ARMv8 Debug Architecture manual for details.
+    // This implementation does not currently use the MASK bits; the largest single region watched by a single
+    // watchpoint right now is 8-bytes.
+
+    nub_addr_t aligned_wp_address = addr & ~0x7;
+    uint32_t addr_dword_offset = addr & 0x7;
+
+    // Do we need to split up this logical watchpoint into two hardware watchpoint
+    // registers?
+    // e.g. a watchpoint of length 4 on address 6.  We need do this with
+    //   one watchpoint on address 0 with bytes 6 & 7 being monitored
+    //   one watchpoint on address 8 with bytes 0, 1, 2, 3 being monitored
+
+    if (addr_dword_offset + size > 8)
+    {
+        DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM64::EnableHardwareWatchpoint(addr = 0x%8.8llx, size = %zu) needs two hardware watchpoints slots to monitor", (uint64_t)addr, size);
+        int low_watchpoint_size = 8 - addr_dword_offset;
+        int high_watchpoint_size = addr_dword_offset + size - 8;
+
+        uint32_t lo = EnableHardwareWatchpoint(addr, low_watchpoint_size, read, write, also_set_on_task);
+        if (lo == INVALID_NUB_HW_INDEX)
+            return INVALID_NUB_HW_INDEX;
+        uint32_t hi = EnableHardwareWatchpoint (aligned_wp_address + 8, high_watchpoint_size, read, write, also_set_on_task);
+        if (hi == INVALID_NUB_HW_INDEX)
+        {
+            DisableHardwareWatchpoint (lo, also_set_on_task);
+            return INVALID_NUB_HW_INDEX;
+        }
+        // Tag this lo->hi mapping in our database.
+        LoHi[lo] = hi;
+        return lo;
+    }
+
+    // At this point 
+    //  1 aligned_wp_address is the requested address rounded down to 8-byte alignment
+    //  2 addr_dword_offset is the offset into that double word (8-byte) region that we are watching
+    //  3 size is the number of bytes within that 8-byte region that we are watching
+
+    // Set the Byte Address Selects bits DBGWCRn_EL1 bits [12:5] based on the above.
+    // The bit shift and negation operation will give us 0b11 for 2, 0b1111 for 4, etc, up to 0b11111111 for 8.
+    // then we shift those bits left by the offset into this dword that we are interested in.
+    // e.g. if we are watching bytes 4,5,6,7 in a dword we want a BAS of 0b11110000.
+    uint32_t byte_address_select = ((1 << size) - 1) << addr_dword_offset;
+
+    // Read the debug state
+    kern_return_t kret = GetDBGState(false);
+
+    if (kret == KERN_SUCCESS)
+    {
+        // Check to make sure we have the needed hardware support
+        uint32_t i = 0;
+
+        for (i=0; i<num_hw_watchpoints; ++i)
+        {
+            if ((m_state.dbg.__wcr[i] & WCR_ENABLE) == 0)
+                break; // We found an available hw watchpoint slot (in i)
+        }
+
+        // See if we found an available hw watchpoint slot above
+        if (i < num_hw_watchpoints)
+        {
+            //DumpDBGState(m_state.dbg);
+
+            // Clear any previous LoHi joined-watchpoint that may have been in use
+            LoHi[i] = 0;
+
+            // shift our Byte Address Select bits up to the correct bit range for the DBGWCRn_EL1
+            byte_address_select = byte_address_select << 5;
+    
+            // Make sure bits 1:0 are clear in our address
+            m_state.dbg.__wvr[i] = aligned_wp_address;          // DVA (Data Virtual Address)
+            m_state.dbg.__wcr[i] =  byte_address_select |       // Which bytes that follow the DVA that we will watch
+                                    S_USER |                    // Stop only in user mode
+                                    (read ? WCR_LOAD : 0) |     // Stop on read access?
+                                    (write ? WCR_STORE : 0) |   // Stop on write access?
+                                    WCR_ENABLE;                 // Enable this watchpoint;
+
+            DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM64::EnableHardwareWatchpoint() adding watchpoint on address 0x%llx with control register value 0x%x", (uint64_t) m_state.dbg.__wvr[i], (uint32_t) m_state.dbg.__wcr[i]);
+
+            // The kernel will set the MDE_ENABLE bit in the MDSCR_EL1 for us automatically, don't need to do it here.
+
+            kret = SetDBGState(also_set_on_task);
+            //DumpDBGState(m_state.dbg);
+
+            DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM64::EnableHardwareWatchpoint() SetDBGState() => 0x%8.8x.", kret);
+
+            if (kret == KERN_SUCCESS)
+                return i;
+        }
+        else
+        {
+            DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM64::EnableHardwareWatchpoint(): All hardware resources (%u) are in use.", num_hw_watchpoints);
+        }
+    }
+    return INVALID_NUB_HW_INDEX;
+}
+
+bool
+DNBArchMachARM64::ReenableHardwareWatchpoint (uint32_t hw_index)
+{
+    // If this logical watchpoint # is actually implemented using
+    // two hardware watchpoint registers, re-enable both of them.
+
+    if (hw_index < NumSupportedHardwareWatchpoints() && LoHi[hw_index])
+    {
+        return ReenableHardwareWatchpoint_helper (hw_index) && ReenableHardwareWatchpoint_helper (LoHi[hw_index]);
+    }
+    else
+    {
+        return ReenableHardwareWatchpoint_helper (hw_index);
+    }
+}
+
+bool
+DNBArchMachARM64::ReenableHardwareWatchpoint_helper (uint32_t hw_index)
+{
+    kern_return_t kret = GetDBGState(false);
+    if (kret != KERN_SUCCESS)
+        return false;
+
+    const uint32_t num_hw_points = NumSupportedHardwareWatchpoints();
+    if (hw_index >= num_hw_points)
+        return false;
+
+    m_state.dbg.__wvr[hw_index] = m_disabled_watchpoints[hw_index].addr;
+    m_state.dbg.__wcr[hw_index] = m_disabled_watchpoints[hw_index].control;
+
+    DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM64::EnableHardwareWatchpoint( %u ) - WVR%u = 0x%8.8llx  WCR%u = 0x%8.8llx",
+                     hw_index,
+                     hw_index,
+                     (uint64_t) m_state.dbg.__wvr[hw_index],
+                     hw_index,
+                     (uint64_t) m_state.dbg.__wcr[hw_index]);
+
+   // The kernel will set the MDE_ENABLE bit in the MDSCR_EL1 for us automatically, don't need to do it here.
+
+    kret = SetDBGState(false);
+
+    return (kret == KERN_SUCCESS);
+}
+
+bool
+DNBArchMachARM64::DisableHardwareWatchpoint (uint32_t hw_index, bool also_set_on_task)
+{
+    if (hw_index < NumSupportedHardwareWatchpoints() && LoHi[hw_index])
+    {
+        return DisableHardwareWatchpoint_helper (hw_index, also_set_on_task) && DisableHardwareWatchpoint_helper (LoHi[hw_index], also_set_on_task);
+    }
+    else
+    {
+        return DisableHardwareWatchpoint_helper (hw_index, also_set_on_task);
+    }
+}
+
+bool
+DNBArchMachARM64::DisableHardwareWatchpoint_helper (uint32_t hw_index, bool also_set_on_task)
+{
+    kern_return_t kret = GetDBGState(false);
+    if (kret != KERN_SUCCESS)
+        return false;
+
+    const uint32_t num_hw_points = NumSupportedHardwareWatchpoints();
+    if (hw_index >= num_hw_points)
+        return false;
+
+    m_disabled_watchpoints[hw_index].addr = m_state.dbg.__wvr[hw_index];
+    m_disabled_watchpoints[hw_index].control = m_state.dbg.__wcr[hw_index];
+
+    m_state.dbg.__wcr[hw_index] &= ~((nub_addr_t)WCR_ENABLE);
+    DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM64::DisableHardwareWatchpoint( %u ) - WVR%u = 0x%8.8llx  WCR%u = 0x%8.8llx",
+                     hw_index,
+                     hw_index,
+                     (uint64_t) m_state.dbg.__wvr[hw_index],
+                     hw_index,
+                     (uint64_t) m_state.dbg.__wcr[hw_index]);
+
+    kret = SetDBGState(also_set_on_task);
+
+    return (kret == KERN_SUCCESS);
+}
+
+// This is for checking the Byte Address Select bits in the DBRWCRn_EL1 control register.
+// Returns -1 if the trailing bit patterns are not one of:
+// { 0b???????1, 0b??????10, 0b?????100, 0b????1000, 0b???10000, 0b??100000, 0b?1000000, 0b10000000 }.
+static inline
+int32_t
+LowestBitSet(uint32_t val)
+{
+    for (unsigned i = 0; i < 8; ++i) {
+        if (bit(val, i))
+            return i;
+    }
+    return -1;
+}
+
+// Iterate through the debug registers; return the index of the first watchpoint whose address matches.
+// As a side effect, the starting address as understood by the debugger is returned which could be
+// different from 'addr' passed as an in/out argument.
+uint32_t
+DNBArchMachARM64::GetHardwareWatchpointHit(nub_addr_t &addr)
+{
+    // Read the debug state
+    kern_return_t kret = GetDBGState(true);
+    //DumpDBGState(m_state.dbg);
+    DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM64::GetHardwareWatchpointHit() GetDBGState() => 0x%8.8x.", kret);
+    DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM64::GetHardwareWatchpointHit() addr = 0x%llx", (uint64_t)addr);
+
+    // This is the watchpoint value to match against, i.e., word address.
+    nub_addr_t wp_val = addr & ~((nub_addr_t)3);
+    if (kret == KERN_SUCCESS)
+    {
+        DBG &debug_state = m_state.dbg;
+        uint32_t i, num = NumSupportedHardwareWatchpoints();
+        for (i = 0; i < num; ++i)
+        {
+            nub_addr_t wp_addr = GetWatchAddress(debug_state, i);
+            DNBLogThreadedIf(LOG_WATCHPOINTS,
+                             "DNBArchMachARM64::GetHardwareWatchpointHit() slot: %u (addr = 0x%llx).",
+                             i, (uint64_t)wp_addr);
+            if (wp_val == wp_addr) {
+                uint32_t byte_mask = bits(debug_state.__wcr[i], 12, 5);
+
+                // Sanity check the byte_mask, first.
+                if (LowestBitSet(byte_mask) < 0)
+                    continue;
+
+                // Check that the watchpoint is enabled.
+                if (!IsWatchpointEnabled(debug_state, i))
+                    continue;
+    
+                // Compute the starting address (from the point of view of the debugger).
+                addr = wp_addr + LowestBitSet(byte_mask);
+                return i;
+            }
+        }
+    }
+    return INVALID_NUB_HW_INDEX;
+}
+
+nub_addr_t
+DNBArchMachARM64::GetWatchpointAddressByIndex (uint32_t hw_index)
+{
+    kern_return_t kret = GetDBGState(true);
+    if (kret != KERN_SUCCESS)
+        return INVALID_NUB_ADDRESS;
+    const uint32_t num = NumSupportedHardwareWatchpoints();
+    if (hw_index >= num)
+        return INVALID_NUB_ADDRESS;
+    if (IsWatchpointEnabled (m_state.dbg, hw_index))
+        return GetWatchAddress (m_state.dbg, hw_index);
+    return INVALID_NUB_ADDRESS;
+}
+
+bool
+DNBArchMachARM64::IsWatchpointEnabled(const DBG &debug_state, uint32_t hw_index)
+{
+    // Watchpoint Control Registers, bitfield definitions
+    // ...
+    // Bits    Value    Description
+    // [0]     0        Watchpoint disabled
+    //         1        Watchpoint enabled.
+    return (debug_state.__wcr[hw_index] & 1u);
+}
+
+nub_addr_t
+DNBArchMachARM64::GetWatchAddress(const DBG &debug_state, uint32_t hw_index)
+{
+    // Watchpoint Value Registers, bitfield definitions
+    // Bits        Description
+    // [31:2]      Watchpoint value (word address, i.e., 4-byte aligned)
+    // [1:0]       RAZ/SBZP
+    return bits(debug_state.__wvr[hw_index], 63, 0);
+}
+
+//----------------------------------------------------------------------
+// Register information defintions for 64 bit ARMv8.
+//----------------------------------------------------------------------
+enum gpr_regnums
+{
+    gpr_x0 = 0,
+    gpr_x1,
+    gpr_x2,
+    gpr_x3,
+    gpr_x4,
+    gpr_x5,
+    gpr_x6,
+    gpr_x7,
+    gpr_x8,
+    gpr_x9,
+    gpr_x10,
+    gpr_x11,
+    gpr_x12,
+    gpr_x13,
+    gpr_x14,
+    gpr_x15,
+    gpr_x16,
+    gpr_x17,
+    gpr_x18,
+    gpr_x19,
+    gpr_x20,
+    gpr_x21,
+    gpr_x22,
+    gpr_x23,
+    gpr_x24,
+    gpr_x25,
+    gpr_x26,
+    gpr_x27,
+    gpr_x28,
+    gpr_fp, gpr_x29 = gpr_fp,
+    gpr_lr,	gpr_x30 = gpr_lr,
+    gpr_sp,	gpr_x31 = gpr_sp,
+    gpr_pc,
+    gpr_cpsr,
+    gpr_w0,
+    gpr_w1,
+    gpr_w2,
+    gpr_w3,
+    gpr_w4,
+    gpr_w5,
+    gpr_w6,
+    gpr_w7,
+    gpr_w8,
+    gpr_w9,
+    gpr_w10,
+    gpr_w11,
+    gpr_w12,
+    gpr_w13,
+    gpr_w14,
+    gpr_w15,
+    gpr_w16,
+    gpr_w17,
+    gpr_w18,
+    gpr_w19,
+    gpr_w20,
+    gpr_w21,
+    gpr_w22,
+    gpr_w23,
+    gpr_w24,
+    gpr_w25,
+    gpr_w26,
+    gpr_w27,
+    gpr_w28
+
+};
+
+enum 
+{
+    vfp_v0 = 0,
+    vfp_v1,
+    vfp_v2,
+    vfp_v3,
+    vfp_v4,
+    vfp_v5,
+    vfp_v6,
+    vfp_v7,
+    vfp_v8,
+    vfp_v9,
+    vfp_v10,
+    vfp_v11,
+    vfp_v12,
+    vfp_v13,
+    vfp_v14,
+    vfp_v15,
+    vfp_v16,
+    vfp_v17,
+    vfp_v18,
+    vfp_v19,
+    vfp_v20,
+    vfp_v21,
+    vfp_v22,
+    vfp_v23,
+    vfp_v24,
+    vfp_v25,
+    vfp_v26,
+    vfp_v27,
+    vfp_v28,
+    vfp_v29,
+    vfp_v30,
+    vfp_v31,
+    vfp_fpsr,
+    vfp_fpcr,
+
+    // lower 32 bits of the corresponding vfp_v<n> reg.
+    vfp_s0,
+    vfp_s1,
+    vfp_s2,
+    vfp_s3,
+    vfp_s4,
+    vfp_s5,
+    vfp_s6,
+    vfp_s7,
+    vfp_s8,
+    vfp_s9,
+    vfp_s10,
+    vfp_s11,
+    vfp_s12,
+    vfp_s13,
+    vfp_s14,
+    vfp_s15,
+    vfp_s16,
+    vfp_s17,
+    vfp_s18,
+    vfp_s19,
+    vfp_s20,
+    vfp_s21,
+    vfp_s22,
+    vfp_s23,
+    vfp_s24,
+    vfp_s25,
+    vfp_s26,
+    vfp_s27,
+    vfp_s28,
+    vfp_s29,
+    vfp_s30,
+    vfp_s31,
+
+    // lower 64 bits of the corresponding vfp_v<n> reg.
+    vfp_d0,
+    vfp_d1,
+    vfp_d2,
+    vfp_d3,
+    vfp_d4,
+    vfp_d5,
+    vfp_d6,
+    vfp_d7,
+    vfp_d8,
+    vfp_d9,
+    vfp_d10,
+    vfp_d11,
+    vfp_d12,
+    vfp_d13,
+    vfp_d14,
+    vfp_d15,
+    vfp_d16,
+    vfp_d17,
+    vfp_d18,
+    vfp_d19,
+    vfp_d20,
+    vfp_d21,
+    vfp_d22,
+    vfp_d23,
+    vfp_d24,
+    vfp_d25,
+    vfp_d26,
+    vfp_d27,
+    vfp_d28,
+    vfp_d29,
+    vfp_d30,
+    vfp_d31
+};
+
+enum 
+{
+    exc_far = 0,
+    exc_esr,
+    exc_exception
+};
+
+// These numbers from the "DWARF for the ARM 64-bit Architecture (AArch64)" document.
+
+enum
+{
+    dwarf_x0 = 0,
+    dwarf_x1,
+    dwarf_x2,
+    dwarf_x3,
+    dwarf_x4,
+    dwarf_x5,
+    dwarf_x6,
+    dwarf_x7,
+    dwarf_x8,
+    dwarf_x9,
+    dwarf_x10,
+    dwarf_x11,
+    dwarf_x12,
+    dwarf_x13,
+    dwarf_x14,
+    dwarf_x15,
+    dwarf_x16,
+    dwarf_x17,
+    dwarf_x18,
+    dwarf_x19,
+    dwarf_x20,
+    dwarf_x21,
+    dwarf_x22,
+    dwarf_x23,
+    dwarf_x24,
+    dwarf_x25,
+    dwarf_x26,
+    dwarf_x27,
+    dwarf_x28,
+    dwarf_x29,
+    dwarf_x30,   
+    dwarf_x31,
+    dwarf_pc        = 32,
+    dwarf_elr_mode  = 33,
+    dwarf_fp = dwarf_x29,
+    dwarf_lr = dwarf_x30,
+    dwarf_sp = dwarf_x31,
+    // 34-63 reserved
+    
+    // V0-V31 (128 bit vector registers)
+    dwarf_v0        = 64,
+    dwarf_v1,
+    dwarf_v2,
+    dwarf_v3,
+    dwarf_v4,
+    dwarf_v5,
+    dwarf_v6,
+    dwarf_v7,
+    dwarf_v8,
+    dwarf_v9,
+    dwarf_v10,
+    dwarf_v11,
+    dwarf_v12,
+    dwarf_v13,
+    dwarf_v14,
+    dwarf_v15,
+    dwarf_v16,
+    dwarf_v17,
+    dwarf_v18,
+    dwarf_v19,
+    dwarf_v20,
+    dwarf_v21,
+    dwarf_v22,
+    dwarf_v23,
+    dwarf_v24,
+    dwarf_v25,
+    dwarf_v26,
+    dwarf_v27,
+    dwarf_v28,
+    dwarf_v29,
+    dwarf_v30,
+    dwarf_v31
+    
+    // 96-127 reserved
+};
+
+enum 
+{
+    gdb_gpr_x0 = 0,
+    gdb_gpr_x1,
+    gdb_gpr_x2,
+    gdb_gpr_x3,
+    gdb_gpr_x4,
+    gdb_gpr_x5,
+    gdb_gpr_x6,
+    gdb_gpr_x7,
+    gdb_gpr_x8,
+    gdb_gpr_x9,
+    gdb_gpr_x10,
+    gdb_gpr_x11,
+    gdb_gpr_x12,
+    gdb_gpr_x13,
+    gdb_gpr_x14,
+    gdb_gpr_x15,
+    gdb_gpr_x16,
+    gdb_gpr_x17,
+    gdb_gpr_x18,
+    gdb_gpr_x19,
+    gdb_gpr_x20,
+    gdb_gpr_x21,
+    gdb_gpr_x22,
+    gdb_gpr_x23,
+    gdb_gpr_x24,
+    gdb_gpr_x25,
+    gdb_gpr_x26,
+    gdb_gpr_x27,
+    gdb_gpr_x28,
+    gdb_gpr_fp,    // x29
+    gdb_gpr_lr,    // x30
+    gdb_gpr_sp,    // sp aka xsp
+    gdb_gpr_pc,
+    gdb_gpr_cpsr,
+    gdb_vfp_v0,
+    gdb_vfp_v1,
+    gdb_vfp_v2,
+    gdb_vfp_v3,
+    gdb_vfp_v4,
+    gdb_vfp_v5,
+    gdb_vfp_v6,
+    gdb_vfp_v7,
+    gdb_vfp_v8,
+    gdb_vfp_v9,
+    gdb_vfp_v10,
+    gdb_vfp_v11,
+    gdb_vfp_v12,
+    gdb_vfp_v13,
+    gdb_vfp_v14,
+    gdb_vfp_v15,
+    gdb_vfp_v16,
+    gdb_vfp_v17,
+    gdb_vfp_v18,
+    gdb_vfp_v19,
+    gdb_vfp_v20,
+    gdb_vfp_v21,
+    gdb_vfp_v22,
+    gdb_vfp_v23,
+    gdb_vfp_v24,
+    gdb_vfp_v25,
+    gdb_vfp_v26,
+    gdb_vfp_v27,
+    gdb_vfp_v28,
+    gdb_vfp_v29,
+    gdb_vfp_v30,
+    gdb_vfp_v31,
+    gdb_vfp_fpsr,
+    gdb_vfp_fpcr
+};
+
+const char *g_contained_x0[] {"x0", NULL };
+const char *g_contained_x1[] {"x1", NULL };
+const char *g_contained_x2[] {"x2", NULL };
+const char *g_contained_x3[] {"x3", NULL };
+const char *g_contained_x4[] {"x4", NULL };
+const char *g_contained_x5[] {"x5", NULL };
+const char *g_contained_x6[] {"x6", NULL };
+const char *g_contained_x7[] {"x7", NULL };
+const char *g_contained_x8[] {"x8", NULL };
+const char *g_contained_x9[] {"x9", NULL };
+const char *g_contained_x10[] {"x10", NULL };
+const char *g_contained_x11[] {"x11", NULL };
+const char *g_contained_x12[] {"x12", NULL };
+const char *g_contained_x13[] {"x13", NULL };
+const char *g_contained_x14[] {"x14", NULL };
+const char *g_contained_x15[] {"x15", NULL };
+const char *g_contained_x16[] {"x16", NULL };
+const char *g_contained_x17[] {"x17", NULL };
+const char *g_contained_x18[] {"x18", NULL };
+const char *g_contained_x19[] {"x19", NULL };
+const char *g_contained_x20[] {"x20", NULL };
+const char *g_contained_x21[] {"x21", NULL };
+const char *g_contained_x22[] {"x22", NULL };
+const char *g_contained_x23[] {"x23", NULL };
+const char *g_contained_x24[] {"x24", NULL };
+const char *g_contained_x25[] {"x25", NULL };
+const char *g_contained_x26[] {"x26", NULL };
+const char *g_contained_x27[] {"x27", NULL };
+const char *g_contained_x28[] {"x28", NULL };
+
+const char *g_invalidate_x0[] {"x0", "w0", NULL };
+const char *g_invalidate_x1[] {"x1", "w1", NULL };
+const char *g_invalidate_x2[] {"x2", "w2", NULL };
+const char *g_invalidate_x3[] {"x3", "w3", NULL };
+const char *g_invalidate_x4[] {"x4", "w4", NULL };
+const char *g_invalidate_x5[] {"x5", "w5", NULL };
+const char *g_invalidate_x6[] {"x6", "w6", NULL };
+const char *g_invalidate_x7[] {"x7", "w7", NULL };
+const char *g_invalidate_x8[] {"x8", "w8", NULL };
+const char *g_invalidate_x9[] {"x9", "w9", NULL };
+const char *g_invalidate_x10[] {"x10", "w10", NULL };
+const char *g_invalidate_x11[] {"x11", "w11", NULL };
+const char *g_invalidate_x12[] {"x12", "w12", NULL };
+const char *g_invalidate_x13[] {"x13", "w13", NULL };
+const char *g_invalidate_x14[] {"x14", "w14", NULL };
+const char *g_invalidate_x15[] {"x15", "w15", NULL };
+const char *g_invalidate_x16[] {"x16", "w16", NULL };
+const char *g_invalidate_x17[] {"x17", "w17", NULL };
+const char *g_invalidate_x18[] {"x18", "w18", NULL };
+const char *g_invalidate_x19[] {"x19", "w19", NULL };
+const char *g_invalidate_x20[] {"x20", "w20", NULL };
+const char *g_invalidate_x21[] {"x21", "w21", NULL };
+const char *g_invalidate_x22[] {"x22", "w22", NULL };
+const char *g_invalidate_x23[] {"x23", "w23", NULL };
+const char *g_invalidate_x24[] {"x24", "w24", NULL };
+const char *g_invalidate_x25[] {"x25", "w25", NULL };
+const char *g_invalidate_x26[] {"x26", "w26", NULL };
+const char *g_invalidate_x27[] {"x27", "w27", NULL };
+const char *g_invalidate_x28[] {"x28", "w28", NULL };
+
+#define GPR_OFFSET_IDX(idx) (offsetof (DNBArchMachARM64::GPR, __x[idx]))
+
+#define GPR_OFFSET_NAME(reg) (offsetof (DNBArchMachARM64::GPR , __##reg))
+
+// These macros will auto define the register name, alt name, register size,
+// register offset, encoding, format and native register. This ensures that
+// the register state structures are defined correctly and have the correct
+// sizes and offsets.
+#define DEFINE_GPR_IDX(idx, reg, alt, gen) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, 8, GPR_OFFSET_IDX(idx) , dwarf_##reg, dwarf_##reg, gen, gdb_gpr_##reg, NULL, g_invalidate_x##idx }
+#define DEFINE_GPR_NAME(reg, alt, gen)     { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, 8, GPR_OFFSET_NAME(reg), dwarf_##reg, dwarf_##reg, gen, gdb_gpr_##reg, NULL, NULL }
+#define DEFINE_PSEUDO_GPR_IDX(idx, reg)    { e_regSetGPR, gpr_##reg, #reg, NULL, Uint, Hex, 4, 0, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, g_contained_x##idx, g_invalidate_x##idx }
+
+//_STRUCT_ARM_THREAD_STATE64
+//{
+//	uint64_t    x[29];	/* General purpose registers x0-x28 */
+//	uint64_t    fp;		/* Frame pointer x29 */
+//	uint64_t    lr;		/* Link register x30 */
+//	uint64_t    sp;		/* Stack pointer x31 */
+//	uint64_t    pc;		/* Program counter */
+//	uint32_t    cpsr;	/* Current program status register */
+//};
+
+
+// General purpose registers
+const DNBRegisterInfo
+DNBArchMachARM64::g_gpr_registers[] =
+{
+    DEFINE_GPR_IDX ( 0,  x0, "arg1", GENERIC_REGNUM_ARG1  ),
+    DEFINE_GPR_IDX ( 1,  x1, "arg2", GENERIC_REGNUM_ARG2  ),
+    DEFINE_GPR_IDX ( 2,  x2, "arg3", GENERIC_REGNUM_ARG3  ),
+    DEFINE_GPR_IDX ( 3,  x3, "arg4", GENERIC_REGNUM_ARG4  ),
+    DEFINE_GPR_IDX ( 4,  x4, "arg5", GENERIC_REGNUM_ARG5  ),
+    DEFINE_GPR_IDX ( 5,  x5, "arg6", GENERIC_REGNUM_ARG6  ),
+    DEFINE_GPR_IDX ( 6,  x6,   NULL, INVALID_NUB_REGNUM   ),
+    DEFINE_GPR_IDX ( 7,  x7,   NULL, INVALID_NUB_REGNUM   ),
+    DEFINE_GPR_IDX ( 8,  x8,   NULL, INVALID_NUB_REGNUM   ),
+    DEFINE_GPR_IDX ( 9,  x9,   NULL, INVALID_NUB_REGNUM   ),
+    DEFINE_GPR_IDX (10, x10,   NULL, INVALID_NUB_REGNUM   ),
+    DEFINE_GPR_IDX (11, x11,   NULL, INVALID_NUB_REGNUM   ),
+    DEFINE_GPR_IDX (12, x12,   NULL, INVALID_NUB_REGNUM   ),
+    DEFINE_GPR_IDX (13, x13,   NULL, INVALID_NUB_REGNUM   ),
+    DEFINE_GPR_IDX (14, x14,   NULL, INVALID_NUB_REGNUM   ),
+    DEFINE_GPR_IDX (15, x15,   NULL, INVALID_NUB_REGNUM   ),
+    DEFINE_GPR_IDX (16, x16,   NULL, INVALID_NUB_REGNUM   ),
+    DEFINE_GPR_IDX (17, x17,   NULL, INVALID_NUB_REGNUM   ),
+    DEFINE_GPR_IDX (18, x18,   NULL, INVALID_NUB_REGNUM   ),
+    DEFINE_GPR_IDX (19, x19,   NULL, INVALID_NUB_REGNUM   ),
+    DEFINE_GPR_IDX (20, x20,   NULL, INVALID_NUB_REGNUM   ),
+    DEFINE_GPR_IDX (21, x21,   NULL, INVALID_NUB_REGNUM   ),
+    DEFINE_GPR_IDX (22, x22,   NULL, INVALID_NUB_REGNUM   ),
+    DEFINE_GPR_IDX (23, x23,   NULL, INVALID_NUB_REGNUM   ),
+    DEFINE_GPR_IDX (24, x24,   NULL, INVALID_NUB_REGNUM   ),
+    DEFINE_GPR_IDX (25, x25,   NULL, INVALID_NUB_REGNUM   ),
+    DEFINE_GPR_IDX (26, x26,   NULL, INVALID_NUB_REGNUM   ),
+    DEFINE_GPR_IDX (27, x27,   NULL, INVALID_NUB_REGNUM   ),
+    DEFINE_GPR_IDX (28, x28,   NULL, INVALID_NUB_REGNUM   ),
+    DEFINE_GPR_NAME (fp, "x29", GENERIC_REGNUM_FP),
+    DEFINE_GPR_NAME (lr, "x30", GENERIC_REGNUM_RA),
+    DEFINE_GPR_NAME (sp, "xsp",  GENERIC_REGNUM_SP),
+    DEFINE_GPR_NAME (pc,  NULL, GENERIC_REGNUM_PC),
+
+    // in armv7 we specify that writing to the CPSR should invalidate r8-12, sp, lr.
+    // this should be spcified for arm64 too even though debugserver is only used for
+    // userland debugging.
+    { e_regSetGPR, gpr_cpsr, "cpsr", "flags", Uint, Hex, 4, GPR_OFFSET_NAME(cpsr), dwarf_elr_mode, dwarf_elr_mode, INVALID_NUB_REGNUM, gdb_gpr_cpsr, NULL, NULL },
+
+    DEFINE_PSEUDO_GPR_IDX ( 0,  w0), 
+    DEFINE_PSEUDO_GPR_IDX ( 1,  w1), 
+    DEFINE_PSEUDO_GPR_IDX ( 2,  w2), 
+    DEFINE_PSEUDO_GPR_IDX ( 3,  w3), 
+    DEFINE_PSEUDO_GPR_IDX ( 4,  w4), 
+    DEFINE_PSEUDO_GPR_IDX ( 5,  w5), 
+    DEFINE_PSEUDO_GPR_IDX ( 6,  w6),
+    DEFINE_PSEUDO_GPR_IDX ( 7,  w7),
+    DEFINE_PSEUDO_GPR_IDX ( 8,  w8),
+    DEFINE_PSEUDO_GPR_IDX ( 9,  w9),
+    DEFINE_PSEUDO_GPR_IDX (10, w10),
+    DEFINE_PSEUDO_GPR_IDX (11, w11),
+    DEFINE_PSEUDO_GPR_IDX (12, w12),
+    DEFINE_PSEUDO_GPR_IDX (13, w13),
+    DEFINE_PSEUDO_GPR_IDX (14, w14),
+    DEFINE_PSEUDO_GPR_IDX (15, w15),
+    DEFINE_PSEUDO_GPR_IDX (16, w16),
+    DEFINE_PSEUDO_GPR_IDX (17, w17),
+    DEFINE_PSEUDO_GPR_IDX (18, w18),
+    DEFINE_PSEUDO_GPR_IDX (19, w19),
+    DEFINE_PSEUDO_GPR_IDX (20, w20),
+    DEFINE_PSEUDO_GPR_IDX (21, w21),
+    DEFINE_PSEUDO_GPR_IDX (22, w22),
+    DEFINE_PSEUDO_GPR_IDX (23, w23),
+    DEFINE_PSEUDO_GPR_IDX (24, w24),
+    DEFINE_PSEUDO_GPR_IDX (25, w25),
+    DEFINE_PSEUDO_GPR_IDX (26, w26),
+    DEFINE_PSEUDO_GPR_IDX (27, w27),
+    DEFINE_PSEUDO_GPR_IDX (28, w28)
+};
+
+const char *g_contained_v0[] {"v0", NULL };
+const char *g_contained_v1[] {"v1", NULL };
+const char *g_contained_v2[] {"v2", NULL };
+const char *g_contained_v3[] {"v3", NULL };
+const char *g_contained_v4[] {"v4", NULL };
+const char *g_contained_v5[] {"v5", NULL };
+const char *g_contained_v6[] {"v6", NULL };
+const char *g_contained_v7[] {"v7", NULL };
+const char *g_contained_v8[] {"v8", NULL };
+const char *g_contained_v9[] {"v9", NULL };
+const char *g_contained_v10[] {"v10", NULL };
+const char *g_contained_v11[] {"v11", NULL };
+const char *g_contained_v12[] {"v12", NULL };
+const char *g_contained_v13[] {"v13", NULL };
+const char *g_contained_v14[] {"v14", NULL };
+const char *g_contained_v15[] {"v15", NULL };
+const char *g_contained_v16[] {"v16", NULL };
+const char *g_contained_v17[] {"v17", NULL };
+const char *g_contained_v18[] {"v18", NULL };
+const char *g_contained_v19[] {"v19", NULL };
+const char *g_contained_v20[] {"v20", NULL };
+const char *g_contained_v21[] {"v21", NULL };
+const char *g_contained_v22[] {"v22", NULL };
+const char *g_contained_v23[] {"v23", NULL };
+const char *g_contained_v24[] {"v24", NULL };
+const char *g_contained_v25[] {"v25", NULL };
+const char *g_contained_v26[] {"v26", NULL };
+const char *g_contained_v27[] {"v27", NULL };
+const char *g_contained_v28[] {"v28", NULL };
+const char *g_contained_v29[] {"v29", NULL };
+const char *g_contained_v30[] {"v30", NULL };
+const char *g_contained_v31[] {"v31", NULL };
+
+const char *g_invalidate_v0[] {"v0", "d0", "s0", NULL };
+const char *g_invalidate_v1[] {"v1", "d1", "s1", NULL };
+const char *g_invalidate_v2[] {"v2", "d2", "s2", NULL };
+const char *g_invalidate_v3[] {"v3", "d3", "s3", NULL };
+const char *g_invalidate_v4[] {"v4", "d4", "s4", NULL };
+const char *g_invalidate_v5[] {"v5", "d5", "s5", NULL };
+const char *g_invalidate_v6[] {"v6", "d6", "s6", NULL };
+const char *g_invalidate_v7[] {"v7", "d7", "s7", NULL };
+const char *g_invalidate_v8[] {"v8", "d8", "s8", NULL };
+const char *g_invalidate_v9[] {"v9", "d9", "s9", NULL };
+const char *g_invalidate_v10[] {"v10", "d10", "s10", NULL };
+const char *g_invalidate_v11[] {"v11", "d11", "s11", NULL };
+const char *g_invalidate_v12[] {"v12", "d12", "s12", NULL };
+const char *g_invalidate_v13[] {"v13", "d13", "s13", NULL };
+const char *g_invalidate_v14[] {"v14", "d14", "s14", NULL };
+const char *g_invalidate_v15[] {"v15", "d15", "s15", NULL };
+const char *g_invalidate_v16[] {"v16", "d16", "s16", NULL };
+const char *g_invalidate_v17[] {"v17", "d17", "s17", NULL };
+const char *g_invalidate_v18[] {"v18", "d18", "s18", NULL };
+const char *g_invalidate_v19[] {"v19", "d19", "s19", NULL };
+const char *g_invalidate_v20[] {"v20", "d20", "s20", NULL };
+const char *g_invalidate_v21[] {"v21", "d21", "s21", NULL };
+const char *g_invalidate_v22[] {"v22", "d22", "s22", NULL };
+const char *g_invalidate_v23[] {"v23", "d23", "s23", NULL };
+const char *g_invalidate_v24[] {"v24", "d24", "s24", NULL };
+const char *g_invalidate_v25[] {"v25", "d25", "s25", NULL };
+const char *g_invalidate_v26[] {"v26", "d26", "s26", NULL };
+const char *g_invalidate_v27[] {"v27", "d27", "s27", NULL };
+const char *g_invalidate_v28[] {"v28", "d28", "s28", NULL };
+const char *g_invalidate_v29[] {"v29", "d29", "s29", NULL };
+const char *g_invalidate_v30[] {"v30", "d30", "s30", NULL };
+const char *g_invalidate_v31[] {"v31", "d31", "s31", NULL };
+
+#if defined (__arm64__)
+#define VFP_V_OFFSET_IDX(idx) (offsetof (DNBArchMachARM64::FPU, __v) + (idx * 16) + offsetof (DNBArchMachARM64::Context, vfp))
+#else
+#define VFP_V_OFFSET_IDX(idx) (offsetof (DNBArchMachARM64::FPU, opaque) + (idx * 16) + offsetof (DNBArchMachARM64::Context, vfp))
+#endif
+#define VFP_OFFSET_NAME(reg) (offsetof (DNBArchMachARM64::FPU, reg) + offsetof (DNBArchMachARM64::Context, vfp))
+#define EXC_OFFSET(reg)      (offsetof (DNBArchMachARM64::EXC, reg)  + offsetof (DNBArchMachARM64::Context, exc))
+
+//#define FLOAT_FORMAT Float
+#define DEFINE_VFP_V_IDX(idx) { e_regSetVFP, vfp_v##idx, "v" #idx, "q" #idx, Vector, VectorOfUInt8, 16, VFP_V_OFFSET_IDX(idx), INVALID_NUB_REGNUM, dwarf_v##idx, INVALID_NUB_REGNUM, gdb_vfp_v##idx, NULL, g_invalidate_v##idx }
+#define DEFINE_PSEUDO_VFP_S_IDX(idx) { e_regSetVFP, vfp_s##idx, "s" #idx, NULL, IEEE754, Float, 4, 0, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, g_contained_v##idx, g_invalidate_v##idx }
+#define DEFINE_PSEUDO_VFP_D_IDX(idx) { e_regSetVFP, vfp_d##idx, "d" #idx, NULL, IEEE754, Float, 8, 0, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, g_contained_v##idx, g_invalidate_v##idx }
+
+// Floating point registers
+const DNBRegisterInfo
+DNBArchMachARM64::g_vfp_registers[] =
+{
+    DEFINE_VFP_V_IDX ( 0),
+    DEFINE_VFP_V_IDX ( 1),
+    DEFINE_VFP_V_IDX ( 2),
+    DEFINE_VFP_V_IDX ( 3),
+    DEFINE_VFP_V_IDX ( 4),
+    DEFINE_VFP_V_IDX ( 5),
+    DEFINE_VFP_V_IDX ( 6),
+    DEFINE_VFP_V_IDX ( 7),
+    DEFINE_VFP_V_IDX ( 8),
+    DEFINE_VFP_V_IDX ( 9),
+    DEFINE_VFP_V_IDX (10),
+    DEFINE_VFP_V_IDX (11),
+    DEFINE_VFP_V_IDX (12),
+    DEFINE_VFP_V_IDX (13),
+    DEFINE_VFP_V_IDX (14),
+    DEFINE_VFP_V_IDX (15),
+    DEFINE_VFP_V_IDX (16),
+    DEFINE_VFP_V_IDX (17),
+    DEFINE_VFP_V_IDX (18),
+    DEFINE_VFP_V_IDX (19),
+    DEFINE_VFP_V_IDX (20),
+    DEFINE_VFP_V_IDX (21),
+    DEFINE_VFP_V_IDX (22),
+    DEFINE_VFP_V_IDX (23),
+    DEFINE_VFP_V_IDX (24),
+    DEFINE_VFP_V_IDX (25),
+    DEFINE_VFP_V_IDX (26),
+    DEFINE_VFP_V_IDX (27),
+    DEFINE_VFP_V_IDX (28),
+    DEFINE_VFP_V_IDX (29),
+    DEFINE_VFP_V_IDX (30),
+    DEFINE_VFP_V_IDX (31),
+    { e_regSetVFP, vfp_fpsr, "fpsr", NULL, Uint, Hex, 4, VFP_V_OFFSET_IDX (32) + 0, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+    { e_regSetVFP, vfp_fpcr, "fpcr", NULL, Uint, Hex, 4, VFP_V_OFFSET_IDX (32) + 4, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+
+    DEFINE_PSEUDO_VFP_S_IDX (0),
+    DEFINE_PSEUDO_VFP_S_IDX (1),
+    DEFINE_PSEUDO_VFP_S_IDX (2),
+    DEFINE_PSEUDO_VFP_S_IDX (3),
+    DEFINE_PSEUDO_VFP_S_IDX (4),
+    DEFINE_PSEUDO_VFP_S_IDX (5),
+    DEFINE_PSEUDO_VFP_S_IDX (6),
+    DEFINE_PSEUDO_VFP_S_IDX (7),
+    DEFINE_PSEUDO_VFP_S_IDX (8),
+    DEFINE_PSEUDO_VFP_S_IDX (9),
+    DEFINE_PSEUDO_VFP_S_IDX (10),
+    DEFINE_PSEUDO_VFP_S_IDX (11),
+    DEFINE_PSEUDO_VFP_S_IDX (12),
+    DEFINE_PSEUDO_VFP_S_IDX (13),
+    DEFINE_PSEUDO_VFP_S_IDX (14),
+    DEFINE_PSEUDO_VFP_S_IDX (15),
+    DEFINE_PSEUDO_VFP_S_IDX (16),
+    DEFINE_PSEUDO_VFP_S_IDX (17),
+    DEFINE_PSEUDO_VFP_S_IDX (18),
+    DEFINE_PSEUDO_VFP_S_IDX (19),
+    DEFINE_PSEUDO_VFP_S_IDX (20),
+    DEFINE_PSEUDO_VFP_S_IDX (21),
+    DEFINE_PSEUDO_VFP_S_IDX (22),
+    DEFINE_PSEUDO_VFP_S_IDX (23),
+    DEFINE_PSEUDO_VFP_S_IDX (24),
+    DEFINE_PSEUDO_VFP_S_IDX (25),
+    DEFINE_PSEUDO_VFP_S_IDX (26),
+    DEFINE_PSEUDO_VFP_S_IDX (27),
+    DEFINE_PSEUDO_VFP_S_IDX (28),
+    DEFINE_PSEUDO_VFP_S_IDX (29),
+    DEFINE_PSEUDO_VFP_S_IDX (30),
+    DEFINE_PSEUDO_VFP_S_IDX (31),
+
+    DEFINE_PSEUDO_VFP_D_IDX (0),
+    DEFINE_PSEUDO_VFP_D_IDX (1),
+    DEFINE_PSEUDO_VFP_D_IDX (2),
+    DEFINE_PSEUDO_VFP_D_IDX (3),
+    DEFINE_PSEUDO_VFP_D_IDX (4),
+    DEFINE_PSEUDO_VFP_D_IDX (5),
+    DEFINE_PSEUDO_VFP_D_IDX (6),
+    DEFINE_PSEUDO_VFP_D_IDX (7),
+    DEFINE_PSEUDO_VFP_D_IDX (8),
+    DEFINE_PSEUDO_VFP_D_IDX (9),
+    DEFINE_PSEUDO_VFP_D_IDX (10),
+    DEFINE_PSEUDO_VFP_D_IDX (11),
+    DEFINE_PSEUDO_VFP_D_IDX (12),
+    DEFINE_PSEUDO_VFP_D_IDX (13),
+    DEFINE_PSEUDO_VFP_D_IDX (14),
+    DEFINE_PSEUDO_VFP_D_IDX (15),
+    DEFINE_PSEUDO_VFP_D_IDX (16),
+    DEFINE_PSEUDO_VFP_D_IDX (17),
+    DEFINE_PSEUDO_VFP_D_IDX (18),
+    DEFINE_PSEUDO_VFP_D_IDX (19),
+    DEFINE_PSEUDO_VFP_D_IDX (20),
+    DEFINE_PSEUDO_VFP_D_IDX (21),
+    DEFINE_PSEUDO_VFP_D_IDX (22),
+    DEFINE_PSEUDO_VFP_D_IDX (23),
+    DEFINE_PSEUDO_VFP_D_IDX (24),
+    DEFINE_PSEUDO_VFP_D_IDX (25),
+    DEFINE_PSEUDO_VFP_D_IDX (26),
+    DEFINE_PSEUDO_VFP_D_IDX (27),
+    DEFINE_PSEUDO_VFP_D_IDX (28),
+    DEFINE_PSEUDO_VFP_D_IDX (29),
+    DEFINE_PSEUDO_VFP_D_IDX (30),
+    DEFINE_PSEUDO_VFP_D_IDX (31)
+
+};
+
+
+//_STRUCT_ARM_EXCEPTION_STATE64
+//{
+//	uint64_t	far; /* Virtual Fault Address */
+//	uint32_t	esr; /* Exception syndrome */
+//	uint32_t	exception; /* number of arm exception taken */
+//};
+
+// Exception registers
+const DNBRegisterInfo
+DNBArchMachARM64::g_exc_registers[] =
+{
+    { e_regSetEXC, exc_far        , "far"         , NULL, Uint, Hex, 8, EXC_OFFSET(__far)       , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+    { e_regSetEXC, exc_esr        , "esr"         , NULL, Uint, Hex, 4, EXC_OFFSET(__esr)       , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+    { e_regSetEXC, exc_exception  , "exception"   , NULL, Uint, Hex, 4, EXC_OFFSET(__exception) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL }
+};
+
+// Number of registers in each register set
+const size_t DNBArchMachARM64::k_num_gpr_registers = sizeof(g_gpr_registers)/sizeof(DNBRegisterInfo);
+const size_t DNBArchMachARM64::k_num_vfp_registers = sizeof(g_vfp_registers)/sizeof(DNBRegisterInfo);
+const size_t DNBArchMachARM64::k_num_exc_registers = sizeof(g_exc_registers)/sizeof(DNBRegisterInfo);
+const size_t DNBArchMachARM64::k_num_all_registers = k_num_gpr_registers + k_num_vfp_registers + k_num_exc_registers;
+
+//----------------------------------------------------------------------
+// Register set definitions. The first definitions at register set index
+// of zero is for all registers, followed by other registers sets. The
+// register information for the all register set need not be filled in.
+//----------------------------------------------------------------------
+const DNBRegisterSetInfo
+DNBArchMachARM64::g_reg_sets[] =
+{
+    { "ARM64 Registers",            NULL,               k_num_all_registers     },
+    { "General Purpose Registers",  g_gpr_registers,    k_num_gpr_registers     },
+    { "Floating Point Registers",   g_vfp_registers,    k_num_vfp_registers     },
+    { "Exception State Registers",  g_exc_registers,    k_num_exc_registers     }
+};
+// Total number of register sets for this architecture
+const size_t DNBArchMachARM64::k_num_register_sets = sizeof(g_reg_sets)/sizeof(DNBRegisterSetInfo);
+
+
+const DNBRegisterSetInfo *
+DNBArchMachARM64::GetRegisterSetInfo(nub_size_t *num_reg_sets)
+{
+    *num_reg_sets = k_num_register_sets;
+    return g_reg_sets;
+}
+
+bool
+DNBArchMachARM64::FixGenericRegisterNumber (int &set, int &reg)
+{
+    if (set == REGISTER_SET_GENERIC)
+    {
+        switch (reg)
+        {
+            case GENERIC_REGNUM_PC:     // Program Counter
+                set = e_regSetGPR;
+                reg = gpr_pc;
+                break;
+                
+            case GENERIC_REGNUM_SP:     // Stack Pointer
+                set = e_regSetGPR;
+                reg = gpr_sp;
+                break;
+                
+            case GENERIC_REGNUM_FP:     // Frame Pointer
+                set = e_regSetGPR;
+                reg = gpr_fp;
+                break;
+                
+            case GENERIC_REGNUM_RA:     // Return Address
+                set = e_regSetGPR;
+                reg = gpr_lr;
+                break;
+                
+            case GENERIC_REGNUM_FLAGS:  // Processor flags register
+                set = e_regSetGPR;
+                reg = gpr_cpsr;
+                break;
+                
+            case GENERIC_REGNUM_ARG1:
+            case GENERIC_REGNUM_ARG2:
+            case GENERIC_REGNUM_ARG3:
+            case GENERIC_REGNUM_ARG4:
+            case GENERIC_REGNUM_ARG5:
+            case GENERIC_REGNUM_ARG6:
+                set = e_regSetGPR;
+                reg = gpr_x0 + reg - GENERIC_REGNUM_ARG1;
+                break;
+                
+            default:
+                return false;
+        }
+    }
+    return true;
+}
+bool
+DNBArchMachARM64::GetRegisterValue(int set, int reg, DNBRegisterValue *value)
+{
+    if (!FixGenericRegisterNumber (set, reg))
+        return false;
+
+    if (GetRegisterState(set, false) != KERN_SUCCESS)
+        return false;
+
+    const DNBRegisterInfo *regInfo = m_thread->GetRegisterInfo(set, reg);
+    if (regInfo)
+    {
+        value->info = *regInfo;
+        switch (set)
+        {
+        case e_regSetGPR:
+            if (reg <= gpr_pc)
+            {
+                value->value.uint64 = m_state.context.gpr.__x[reg];
+                return true;
+            }
+            else if (reg == gpr_cpsr)
+            {
+                value->value.uint32 = m_state.context.gpr.__cpsr;
+                return true;
+            }
+            break;
+
+        case e_regSetVFP:
+
+            if (reg >= vfp_v0 && reg <= vfp_v31)
+            {
+#if defined (__arm64__)
+                memcpy (&value->value.v_uint8, &m_state.context.vfp.__v[reg - vfp_v0], 16);
+#else
+                memcpy (&value->value.v_uint8, ((uint8_t *) &m_state.context.vfp.opaque) + ((reg - vfp_v0) * 16), 16);
+#endif
+                return true;
+            }
+            else if (reg == vfp_fpsr)
+            {
+#if defined (__arm64__)
+                memcpy (&value->value.uint32, &m_state.context.vfp.__fpsr, 4);
+#else
+                memcpy (&value->value.uint32, ((uint8_t *) &m_state.context.vfp.opaque) + (32 * 16) + 0, 4);
+#endif
+                return true;
+            }
+            else if (reg == vfp_fpcr)
+            {
+#if defined (__arm64__)
+                memcpy (&value->value.uint32, &m_state.context.vfp.__fpcr, 4);
+#else
+                memcpy (&value->value.uint32, ((uint8_t *) &m_state.context.vfp.opaque) + (32 * 16) + 4, 4);
+#endif
+                return true;
+            }
+            else if (reg >= vfp_s0 && reg <= vfp_s31)
+            {
+#if defined (__arm64__)
+                memcpy (&value->value.v_uint8, &m_state.context.vfp.__v[reg - vfp_s0], 4);
+#else
+                memcpy (&value->value.v_uint8, ((uint8_t *) &m_state.context.vfp.opaque) + ((reg - vfp_s0) * 16), 4);
+#endif
+                return true;
+            }
+            else if (reg >= vfp_d0 && reg <= vfp_d31)
+            {
+#if defined (__arm64__)
+                memcpy (&value->value.v_uint8, &m_state.context.vfp.__v[reg - vfp_d0], 8);
+#else
+                memcpy (&value->value.v_uint8, ((uint8_t *) &m_state.context.vfp.opaque) + ((reg - vfp_d0) * 16), 8);
+#endif
+                return true;
+            }
+            break;
+
+        case e_regSetEXC:
+            if (reg == exc_far)
+            {
+                value->value.uint64 = m_state.context.exc.__far;
+                return true;
+            }
+            else if (reg == exc_esr)
+            {
+                value->value.uint32 = m_state.context.exc.__esr;
+                return true;
+            }
+            else if (reg == exc_exception)
+            {
+                value->value.uint32 = m_state.context.exc.__exception;
+                return true;
+            }
+            break;
+        }
+    }
+    return false;
+}
+
+bool
+DNBArchMachARM64::SetRegisterValue(int set, int reg, const DNBRegisterValue *value)
+{
+    if (!FixGenericRegisterNumber (set, reg))
+        return false;
+ 
+    if (GetRegisterState(set, false) != KERN_SUCCESS)
+        return false;
+
+    bool success = false;
+    const DNBRegisterInfo *regInfo = m_thread->GetRegisterInfo(set, reg);
+    if (regInfo)
+    {
+        switch (set)
+        {
+        case e_regSetGPR:
+            if (reg <= gpr_pc)
+            {
+                m_state.context.gpr.__x[reg] = value->value.uint64;
+                success = true;
+            }
+            else if (reg == gpr_cpsr)
+            {
+                m_state.context.gpr.__cpsr = value->value.uint32;
+                success = true;
+            }
+            break;
+            
+        case e_regSetVFP:
+            if (reg >= vfp_v0 && reg <= vfp_v31)
+            {
+#if defined (__arm64__)
+                memcpy (&m_state.context.vfp.__v[reg - vfp_v0], &value->value.v_uint8, 16);
+#else
+                memcpy (((uint8_t *) &m_state.context.vfp.opaque) + ((reg - vfp_v0) * 16), &value->value.v_uint8, 16);
+#endif
+                success = true;
+            }
+            else if (reg == vfp_fpsr)
+            {
+#if defined (__arm64__)
+                memcpy (&m_state.context.vfp.__fpsr, &value->value.uint32, 4);
+#else
+                memcpy (((uint8_t *) &m_state.context.vfp.opaque) + (32 * 16) + 0, &value->value.uint32, 4);
+#endif
+                success = true;
+            }
+            else if (reg == vfp_fpcr)
+            {
+#if defined (__arm64__)
+                memcpy (&m_state.context.vfp.__fpcr, &value->value.uint32, 4);
+#else
+                memcpy (((uint8_t *) m_state.context.vfp.opaque) + (32 * 16) + 4, &value->value.uint32, 4);
+#endif
+                success = true;
+            }
+            else if (reg >= vfp_s0 && reg <= vfp_s31)
+            {
+#if defined (__arm64__)
+                memcpy (&m_state.context.vfp.__v[reg - vfp_s0], &value->value.v_uint8, 4);
+#else
+                memcpy (((uint8_t *) &m_state.context.vfp.opaque) + ((reg - vfp_s0) * 16), &value->value.v_uint8, 4);
+#endif
+                success = true;
+            }
+            else if (reg >= vfp_d0 && reg <= vfp_d31)
+            {
+#if defined (__arm64__)
+                memcpy (&m_state.context.vfp.__v[reg - vfp_d0], &value->value.v_uint8, 8);
+#else
+                memcpy (((uint8_t *) &m_state.context.vfp.opaque) + ((reg - vfp_d0) * 16), &value->value.v_uint8, 8);
+#endif
+                success = true;
+            }
+            break;
+            
+        case e_regSetEXC:
+            if (reg == exc_far)
+            {
+                m_state.context.exc.__far = value->value.uint64;
+                success = true;
+            }
+            else if (reg == exc_esr)
+            {
+                m_state.context.exc.__esr = value->value.uint32;
+                success = true;
+            }
+            else if (reg == exc_exception)
+            {
+                m_state.context.exc.__exception = value->value.uint32;
+                success = true;
+            }
+            break;
+        }
+
+    }
+    if (success)
+        return SetRegisterState(set) == KERN_SUCCESS;
+    return false;
+}
+
+kern_return_t
+DNBArchMachARM64::GetRegisterState(int set, bool force)
+{
+    switch (set)
+    {
+    case e_regSetALL:   return GetGPRState(force) |
+                               GetVFPState(force) |
+                               GetEXCState(force) |
+                               GetDBGState(force);
+    case e_regSetGPR:   return GetGPRState(force);
+    case e_regSetVFP:   return GetVFPState(force);
+    case e_regSetEXC:   return GetEXCState(force);
+    case e_regSetDBG:   return GetDBGState(force);
+    default: break;
+    }
+    return KERN_INVALID_ARGUMENT;
+}
+
+kern_return_t
+DNBArchMachARM64::SetRegisterState(int set)
+{
+    // Make sure we have a valid context to set.
+    kern_return_t err = GetRegisterState(set, false);
+    if (err != KERN_SUCCESS)
+        return err;
+
+    switch (set)
+    {
+    case e_regSetALL:   return SetGPRState() |
+                               SetVFPState() |
+                               SetEXCState() |
+                               SetDBGState(false);
+    case e_regSetGPR:   return SetGPRState();
+    case e_regSetVFP:   return SetVFPState();
+    case e_regSetEXC:   return SetEXCState();
+    case e_regSetDBG:   return SetDBGState(false);
+    default: break;
+    }
+    return KERN_INVALID_ARGUMENT;
+}
+
+bool
+DNBArchMachARM64::RegisterSetStateIsValid (int set) const
+{
+    return m_state.RegsAreValid(set);
+}
+
+
+nub_size_t
+DNBArchMachARM64::GetRegisterContext (void *buf, nub_size_t buf_len)
+{
+    nub_size_t size = sizeof (m_state.context.gpr) +
+                      sizeof (m_state.context.vfp) +
+                      sizeof (m_state.context.exc);
+    
+    if (buf && buf_len)
+    {
+        if (size > buf_len)
+            size = buf_len;
+
+        bool force = false;
+        if (GetGPRState(force) | GetVFPState(force) | GetEXCState(force))
+            return 0;
+
+        // Copy each struct individually to avoid any padding that might be between the structs in m_state.context
+        uint8_t *p = (uint8_t *)buf;
+        ::memcpy (p, &m_state.context.gpr, sizeof(m_state.context.gpr));
+        p += sizeof(m_state.context.gpr);
+        ::memcpy (p, &m_state.context.vfp, sizeof(m_state.context.vfp));
+        p += sizeof(m_state.context.vfp);
+        ::memcpy (p, &m_state.context.exc, sizeof(m_state.context.exc));
+        p += sizeof(m_state.context.exc);
+        
+        size_t bytes_written = p - (uint8_t *)buf;
+        assert (bytes_written == size);
+    }
+    DNBLogThreadedIf (LOG_THREAD, "DNBArchMachARM64::GetRegisterContext (buf = %p, len = %zu) => %zu", buf, buf_len, size);
+    // Return the size of the register context even if NULL was passed in
+    return size;
+}
+
+nub_size_t
+DNBArchMachARM64::SetRegisterContext (const void *buf, nub_size_t buf_len)
+{
+    nub_size_t size = sizeof (m_state.context.gpr) +
+                      sizeof (m_state.context.vfp) +
+                      sizeof (m_state.context.exc);
+
+    if (buf == NULL || buf_len == 0)
+        size = 0;
+    
+    if (size)
+    {
+        if (size > buf_len)
+            size = buf_len;
+
+        // Copy each struct individually to avoid any padding that might be between the structs in m_state.context
+        uint8_t *p = (uint8_t *)buf;
+        ::memcpy (&m_state.context.gpr, p, sizeof(m_state.context.gpr));
+        p += sizeof(m_state.context.gpr);
+        ::memcpy (&m_state.context.vfp, p, sizeof(m_state.context.vfp));
+        p += sizeof(m_state.context.vfp);
+        ::memcpy (&m_state.context.exc, p, sizeof(m_state.context.exc));
+        p += sizeof(m_state.context.exc);
+        
+        size_t bytes_written = p - (uint8_t *)buf;
+        assert (bytes_written == size);
+        SetGPRState();
+        SetVFPState();
+        SetEXCState();
+    }
+    DNBLogThreadedIf (LOG_THREAD, "DNBArchMachARM64::SetRegisterContext (buf = %p, len = %zu) => %zu", buf, buf_len, size);
+    return size;
+}
+
+uint32_t
+DNBArchMachARM64::SaveRegisterState ()
+{
+    kern_return_t kret = ::thread_abort_safely(m_thread->MachPortNumber());
+    DNBLogThreadedIf (LOG_THREAD, "thread = 0x%4.4x calling thread_abort_safely (tid) => %u (SetGPRState() for stop_count = %u)", m_thread->MachPortNumber(), kret, m_thread->Process()->StopCount());
+    
+    // Always re-read the registers because above we call thread_abort_safely();
+    bool force = true;
+    
+    if ((kret = GetGPRState(force)) != KERN_SUCCESS)
+    {
+        DNBLogThreadedIf (LOG_THREAD, "DNBArchMachARM64::SaveRegisterState () error: GPR regs failed to read: %u ", kret);
+    }
+    else if ((kret = GetVFPState(force)) != KERN_SUCCESS)
+    {
+        DNBLogThreadedIf (LOG_THREAD, "DNBArchMachARM64::SaveRegisterState () error: %s regs failed to read: %u", "VFP", kret);
+    }
+    else
+    {
+        const uint32_t save_id = GetNextRegisterStateSaveID ();
+        m_saved_register_states[save_id] = m_state.context;
+        return save_id;
+    }
+    return UINT32_MAX;
+}
+
+bool
+DNBArchMachARM64::RestoreRegisterState (uint32_t save_id)
+{
+    SaveRegisterStates::iterator pos = m_saved_register_states.find(save_id);
+    if (pos != m_saved_register_states.end())
+    {
+        m_state.context.gpr = pos->second.gpr;
+        m_state.context.vfp = pos->second.vfp;
+        kern_return_t kret;
+        bool success = true;
+        if ((kret = SetGPRState()) != KERN_SUCCESS)
+        {
+            DNBLogThreadedIf (LOG_THREAD, "DNBArchMachARM64::RestoreRegisterState (save_id = %u) error: GPR regs failed to write: %u", save_id, kret);
+            success = false;
+        }
+        else if ((kret = SetVFPState()) != KERN_SUCCESS)
+        {
+            DNBLogThreadedIf (LOG_THREAD, "DNBArchMachARM64::RestoreRegisterState (save_id = %u) error: %s regs failed to write: %u", save_id, "VFP", kret);
+            success = false;
+        }
+        m_saved_register_states.erase(pos);
+        return success;
+    }
+    return false;
+}
+
+
+#endif  // #if defined (ARM_THREAD_STATE64_COUNT)
+#endif  // #if defined (__arm__)

Added: lldb/trunk/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.h?rev=205113&view=auto
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.h (added)
+++ lldb/trunk/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.h Sat Mar 29 13:54:20 2014
@@ -0,0 +1,272 @@
+//===-- DNBArchMachARM64.h --------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef __DNBArchImplARM64_h__
+#define __DNBArchImplARM64_h__
+
+#if defined (__arm__) || defined (__arm64__)
+
+#include <map>
+#include <mach/thread_status.h>
+
+#if defined (ARM_THREAD_STATE64_COUNT)
+
+#include "DNBArch.h"
+
+class MachThread;
+
+class DNBArchMachARM64 : public DNBArchProtocol
+{
+public:
+    enum { kMaxNumThumbITBreakpoints = 4 };
+
+    DNBArchMachARM64(MachThread *thread) :
+        m_thread(thread),
+        m_state(),
+        m_disabled_watchpoints(),
+        m_watchpoint_hw_index(-1),
+        m_watchpoint_did_occur(false),
+        m_watchpoint_resume_single_step_enabled(false),
+        m_saved_register_states()
+    {
+        m_disabled_watchpoints.resize (16);
+        memset(&m_dbg_save, 0, sizeof(m_dbg_save));
+    }
+
+    virtual ~DNBArchMachARM64()
+    {
+    }
+
+    static void Initialize();
+    static const DNBRegisterSetInfo *
+    GetRegisterSetInfo(nub_size_t *num_reg_sets);
+
+    virtual bool            GetRegisterValue(int set, int reg, DNBRegisterValue *value);
+    virtual bool            SetRegisterValue(int set, int reg, const DNBRegisterValue *value);
+    virtual nub_size_t      GetRegisterContext (void *buf, nub_size_t buf_len);
+    virtual nub_size_t      SetRegisterContext (const void *buf, nub_size_t buf_len);
+    virtual uint32_t        SaveRegisterState ();
+    virtual bool            RestoreRegisterState (uint32_t save_id);
+
+    virtual kern_return_t   GetRegisterState  (int set, bool force);
+    virtual kern_return_t   SetRegisterState  (int set);
+    virtual bool            RegisterSetStateIsValid (int set) const;
+
+    virtual uint64_t        GetPC(uint64_t failValue);    // Get program counter
+    virtual kern_return_t   SetPC(uint64_t value);
+    virtual uint64_t        GetSP(uint64_t failValue);    // Get stack pointer
+    virtual void            ThreadWillResume();
+    virtual bool            ThreadDidStop();
+    virtual bool            NotifyException(MachException::Data& exc);
+
+    static DNBArchProtocol *Create (MachThread *thread);
+    static const uint8_t * const SoftwareBreakpointOpcode (nub_size_t byte_size);
+    static uint32_t         GetCPUType();
+
+    virtual uint32_t        NumSupportedHardwareWatchpoints();
+    virtual uint32_t        EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write, bool also_set_on_task);
+    virtual bool            DisableHardwareWatchpoint (uint32_t hw_break_index, bool also_set_on_task);
+    virtual bool            DisableHardwareWatchpoint_helper (uint32_t hw_break_index, bool also_set_on_task);
+
+protected:
+
+
+    kern_return_t           EnableHardwareSingleStep (bool enable);
+    static bool             FixGenericRegisterNumber (int &set, int &reg);
+
+    typedef enum RegisterSetTag
+    {
+        e_regSetALL = REGISTER_SET_ALL,
+        e_regSetGPR, // ARM_THREAD_STATE64,
+        e_regSetVFP, // ARM_NEON_STATE64,
+        e_regSetEXC, // ARM_EXCEPTION_STATE64,
+        e_regSetDBG, // ARM_DEBUG_STATE64,
+        kNumRegisterSets
+    } RegisterSet;
+
+    enum 
+    {
+        e_regSetGPRCount = ARM_THREAD_STATE64_COUNT,
+        e_regSetVFPCount = ARM_NEON_STATE64_COUNT, 
+        e_regSetEXCCount = ARM_EXCEPTION_STATE64_COUNT,
+        e_regSetDBGCount = ARM_DEBUG_STATE64_COUNT,
+    };
+
+    enum
+    {
+        Read = 0,
+        Write = 1,
+        kNumErrors = 2
+    };
+    
+    typedef arm_thread_state64_t GPR;
+    typedef arm_neon_state64_t FPU;
+    typedef arm_exception_state64_t EXC;
+
+    static const DNBRegisterInfo g_gpr_registers[];
+    static const DNBRegisterInfo g_vfp_registers[];
+    static const DNBRegisterInfo g_exc_registers[];
+    static const DNBRegisterSetInfo g_reg_sets[];
+
+    static const size_t k_num_gpr_registers;
+    static const size_t k_num_vfp_registers;
+    static const size_t k_num_exc_registers;
+    static const size_t k_num_all_registers;
+    static const size_t k_num_register_sets;
+
+    struct Context
+    {
+        GPR gpr;
+        FPU vfp;
+        EXC exc;
+    };
+
+    struct State
+    {
+        Context                 context;
+        arm_debug_state64_t     dbg;
+        kern_return_t           gpr_errs[2];    // Read/Write errors
+        kern_return_t           vfp_errs[2];    // Read/Write errors
+        kern_return_t           exc_errs[2];    // Read/Write errors
+        kern_return_t           dbg_errs[2];    // Read/Write errors
+        State()
+        {
+            uint32_t i;
+            for (i=0; i<kNumErrors; i++)
+            {
+                gpr_errs[i] = -1;
+                vfp_errs[i] = -1;
+                exc_errs[i] = -1;
+                dbg_errs[i] = -1;
+            }
+        }
+        void InvalidateRegisterSetState(int set)
+        {
+            SetError (set, Read, -1);
+        }
+        
+        void
+        InvalidateAllRegisterStates()
+        {
+            SetError (e_regSetALL, Read, -1);
+        }
+        
+        kern_return_t GetError (int set, uint32_t err_idx) const
+        {
+            if (err_idx < kNumErrors)
+            {
+                switch (set)
+                {
+                // When getting all errors, just OR all values together to see if
+                // we got any kind of error.
+                case e_regSetALL:   return gpr_errs[err_idx] |
+                                           vfp_errs[err_idx] |
+                                           exc_errs[err_idx] |
+                                           dbg_errs[err_idx] ;
+                case e_regSetGPR:   return gpr_errs[err_idx];
+                case e_regSetVFP:   return vfp_errs[err_idx];
+                case e_regSetEXC:   return exc_errs[err_idx];
+                //case e_regSetDBG:   return dbg_errs[err_idx];
+                default: break;
+                }
+            }
+            return -1;
+        }
+        bool SetError (int set, uint32_t err_idx, kern_return_t err)
+        {
+            if (err_idx < kNumErrors)
+            {
+                switch (set)
+                {
+                case e_regSetALL:
+                    gpr_errs[err_idx] = err;
+                    vfp_errs[err_idx] = err;
+                    dbg_errs[err_idx] = err;
+                    exc_errs[err_idx] = err;
+                    return true;
+
+                case e_regSetGPR:
+                    gpr_errs[err_idx] = err;
+                    return true;
+
+                case e_regSetVFP:
+                    vfp_errs[err_idx] = err;
+                    return true;
+
+                case e_regSetEXC:
+                    exc_errs[err_idx] = err;
+                    return true;
+
+//                case e_regSetDBG:
+//                    dbg_errs[err_idx] = err;
+//                    return true;
+                default: break;
+                }
+            }
+            return false;
+        }
+        bool RegsAreValid (int set) const
+        {
+            return GetError(set, Read) == KERN_SUCCESS;
+        }
+    };
+
+    kern_return_t GetGPRState (bool force);
+    kern_return_t GetVFPState (bool force);
+    kern_return_t GetEXCState (bool force);
+    kern_return_t GetDBGState (bool force);
+
+    kern_return_t SetGPRState ();
+    kern_return_t SetVFPState ();
+    kern_return_t SetEXCState ();
+    kern_return_t SetDBGState (bool also_set_on_task);
+
+    // Helper functions for watchpoint implementaions.
+
+    typedef arm_debug_state64_t DBG;
+
+    void ClearWatchpointOccurred();
+    bool HasWatchpointOccurred();
+    bool IsWatchpointEnabled(const DBG &debug_state, uint32_t hw_index);
+    nub_addr_t GetWatchpointAddressByIndex (uint32_t hw_index);
+    nub_addr_t GetWatchAddress(const DBG &debug_state, uint32_t hw_index);
+    virtual bool            ReenableHardwareWatchpoint (uint32_t hw_break_index);
+    virtual bool            ReenableHardwareWatchpoint_helper (uint32_t hw_break_index);
+    virtual uint32_t        GetHardwareWatchpointHit(nub_addr_t &addr);
+
+
+    class disabled_watchpoint {
+    public:
+        disabled_watchpoint () { addr = 0; control = 0; }
+        nub_addr_t addr;
+        uint32_t   control;
+    };
+
+protected:
+    MachThread *    m_thread;
+    State           m_state;
+    arm_debug_state64_t m_dbg_save;
+
+    // arm64 doesn't keep the disabled watchpoint values in the debug register context like armv7;
+    // we need to save them aside when we disable them temporarily.
+    std::vector<disabled_watchpoint> m_disabled_watchpoints;
+
+    // The following member variables should be updated atomically.
+    int32_t         m_watchpoint_hw_index;
+    bool            m_watchpoint_did_occur;
+    bool            m_watchpoint_resume_single_step_enabled;
+    
+    typedef std::map<uint32_t, Context> SaveRegisterStates;
+    SaveRegisterStates m_saved_register_states;
+};
+
+#endif  // #if defined (ARM_THREAD_STATE64_COUNT)
+#endif  // #if defined (__arm__)
+#endif  // #ifndef __DNBArchImplARM64_h__

Modified: lldb/trunk/tools/debugserver/source/RNBContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBContext.h?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/RNBContext.h (original)
+++ lldb/trunk/tools/debugserver/source/RNBContext.h Sat Mar 29 13:54:20 2014
@@ -117,6 +117,9 @@ public:
     const char *    GetSTDOUTPath() { return m_stdout.empty() ? NULL : m_stdout.c_str(); }
     const char *    GetSTDERRPath() { return m_stderr.empty() ? NULL : m_stderr.c_str(); }
     const char *    GetWorkingDirPath() { return m_working_dir.empty() ? NULL : m_working_dir.c_str(); }
+
+    void            PushProcessEvent (const char *p) { m_process_event.assign(p); }
+    const char *    GetProcessEvent () { return m_process_event.c_str(); }
     
     void            SetDetachOnError(bool detach) { m_detach_on_error = detach; }
     bool            GetDetachOnError () { return m_detach_on_error; }
@@ -138,6 +141,7 @@ protected:
     std::vector<std::string> m_arg_vec;
     std::vector<std::string> m_env_vec; // This will be unparsed - entries FOO=value
     std::string     m_working_directory;
+    std::string     m_process_event;
     bool            m_detach_on_error;
 
     void    StartProcessStatusThread();

Modified: lldb/trunk/tools/debugserver/source/RNBDefs.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBDefs.h?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/RNBDefs.h (original)
+++ lldb/trunk/tools/debugserver/source/RNBDefs.h Sat Mar 29 13:54:20 2014
@@ -45,6 +45,10 @@ extern "C" const double debugserverVersi
 
 #define RNB_ARCH    "ppc"
 
+#elif defined (__arm64__)
+
+#define RNB_ARCH    "arm64"
+
 #elif defined (__arm__)
 
 #define RNB_ARCH    "armv7"

Modified: lldb/trunk/tools/debugserver/source/RNBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBRemote.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/RNBRemote.cpp (original)
+++ lldb/trunk/tools/debugserver/source/RNBRemote.cpp Sat Mar 29 13:54:20 2014
@@ -197,6 +197,7 @@ RNBRemote::CreatePacketTable  ()
     t.push_back (Packet (get_profile_data,              &RNBRemote::HandlePacket_GetProfileData, NULL, "qGetProfileData", "Return profiling data of the current target."));
     t.push_back (Packet (set_enable_profiling,          &RNBRemote::HandlePacket_SetEnableAsyncProfiling, NULL, "QSetEnableAsyncProfiling", "Enable or disable the profiling of current target."));
     t.push_back (Packet (watchpoint_support_info,       &RNBRemote::HandlePacket_WatchpointSupportInfo, NULL, "qWatchpointSupportInfo", "Return the number of supported hardware watchpoints"));
+    t.push_back (Packet (set_process_event,             &RNBRemote::HandlePacket_QSetProcessEvent, NULL, "QSetProcessEvent:", "Set a process event, to be passed to the process, can be set before the process is started, or after."));
     t.push_back (Packet (speed_test,                    &RNBRemote::HandlePacket_qSpeedTest, NULL, "qSpeedTest:", "Test the maximum speed at which packet can be sent/received."));
 }
 
@@ -791,8 +792,15 @@ RNBRemote::ThreadFunctionReadRemoteData(
 static cpu_type_t
 best_guess_cpu_type ()
 {
-#if defined (__arm__)
-    return CPU_TYPE_ARM;
+#if defined (__arm__) || defined (__arm64__)
+    if (sizeof (char *) == 8)
+    {
+        return CPU_TYPE_ARM64;
+    }   
+    else
+    {
+        return CPU_TYPE_ARM;
+    }   
 #elif defined (__i386__) || defined (__x86_64__)
     if (sizeof (char*) == 8)
     {
@@ -2085,6 +2093,26 @@ RNBRemote::HandlePacket_QLaunchArch (con
     return SendPacket ("E63");
 }
 
+rnb_err_t
+RNBRemote::HandlePacket_QSetProcessEvent (const char *p)
+{
+    p += sizeof ("QSetProcessEvent:") - 1;
+    // If the process is running, then send the event to the process, otherwise
+    // store it in the context.
+    if (Context().HasValidProcessID())
+    {
+        if (DNBProcessSendEvent (Context().ProcessID(), p))
+            return SendPacket("OK");
+        else
+            return SendPacket ("E80");
+    }
+    else
+    {
+        Context().PushProcessEvent(p);
+    }
+    return SendPacket ("OK");
+}
+
 void
 append_hex_value (std::ostream& ostrm, const uint8_t* buf, size_t buf_size, bool swap)
 {
@@ -2354,8 +2382,22 @@ RNBRemote::HandlePacket_last_signal (con
                     strncpy (pid_exited_packet, "W00", sizeof(pid_exited_packet)-1);
                     pid_exited_packet[sizeof(pid_exited_packet)-1] = '\0';
                 }
-
-                return SendPacket (pid_exited_packet);
+                
+                const char *exit_info = DNBProcessGetExitInfo (pid);
+                if (exit_info != NULL && *exit_info != '\0')
+                {
+                    std::ostringstream exit_packet;
+                    exit_packet << pid_exited_packet;
+                    exit_packet << ';';
+                    exit_packet << RAW_HEXBASE << "description";
+                    exit_packet << ':';
+                    for (size_t i = 0; exit_info[i] != '\0'; i++)
+                        exit_packet << RAWHEX8(exit_info[i]);
+                    exit_packet << ';';
+                    return SendPacket (exit_packet.str());
+                }
+                else
+                    return SendPacket (pid_exited_packet);
             }
             break;
     }
@@ -3767,7 +3809,7 @@ RNBRemote::HandlePacket_qHostInfo (const
     // The OS in the triple should be "ios" or "macosx" which doesn't match our
     // "Darwin" which gets returned from "kern.ostype", so we need to hardcode
     // this for now.
-    if (cputype == CPU_TYPE_ARM)
+    if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64)
     {
         strm << "ostype:ios;";
         // On armv7 we use "synchronous" watchpoints which means the exception is delivered before the instruction executes.
@@ -3868,6 +3910,14 @@ RNBRemote::HandlePacket_qProcessInfo (co
         rep << "cputype:" << std::hex << cputype << ";";
     }
 
+    bool host_cpu_is_64bit;
+    uint32_t is64bit_capable;
+    size_t is64bit_capable_len = sizeof (is64bit_capable);
+    if (sysctlbyname("hw.cpu64bit_capable", &is64bit_capable, &is64bit_capable_len, NULL, 0) == 0)
+        host_cpu_is_64bit = true;
+    else
+        host_cpu_is_64bit = false;
+
     uint32_t cpusubtype;
     size_t cpusubtype_len = sizeof(cpusubtype);
     if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &cpusubtype_len, NULL, 0) == 0)
@@ -3877,13 +3927,22 @@ RNBRemote::HandlePacket_qProcessInfo (co
             cpusubtype = CPU_SUBTYPE_X86_64_ALL;
         }
 
+        // We can query a process' cputype but we cannot query a process' cpusubtype.
+        // If the process has cputype CPU_TYPE_ARM, then it is an armv7 (32-bit process) and we 
+        // need to override the host cpusubtype (which is in the CPU_SUBTYPE_ARM64 subtype namespace)
+        // with a reasonable CPU_SUBTYPE_ARMV7 subtype.
+        if (host_cpu_is_64bit && cputype == CPU_TYPE_ARM)
+        {
+            cpusubtype = 11; //CPU_SUBTYPE_ARM_V7S;
+        }
+
         rep << "cpusubtype:" << std::hex << cpusubtype << ';';
     }
 
     // The OS in the triple should be "ios" or "macosx" which doesn't match our
     // "Darwin" which gets returned from "kern.ostype", so we need to hardcode
     // this for now.
-    if (cputype == CPU_TYPE_ARM)
+    if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64)
         rep << "ostype:ios;";
     else
         rep << "ostype:macosx;";
@@ -3914,6 +3973,20 @@ RNBRemote::HandlePacket_qProcessInfo (co
     }
 #elif defined (__arm__)
     rep << "ptrsize:4;";
+#elif defined (__arm64__) && defined (ARM_UNIFIED_THREAD_STATE)
+    nub_thread_t thread = DNBProcessGetCurrentThreadMachPort (pid);
+    kern_return_t kr;
+    arm_unified_thread_state_t gp_regs;
+    mach_msg_type_number_t gp_count = ARM_UNIFIED_THREAD_STATE_COUNT;
+    kr = thread_get_state (thread, ARM_UNIFIED_THREAD_STATE,
+                           (thread_state_t) &gp_regs, &gp_count);
+    if (kr == KERN_SUCCESS)
+    {
+        if (gp_regs.ash.flavor == ARM_THREAD_STATE64)
+            rep << "ptrsize:8;";
+        else
+            rep << "ptrsize:4;";
+    }
 #endif
 
     return SendPacket (rep.str());

Modified: lldb/trunk/tools/debugserver/source/RNBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBRemote.h?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/RNBRemote.h (original)
+++ lldb/trunk/tools/debugserver/source/RNBRemote.h Sat Mar 29 13:54:20 2014
@@ -119,6 +119,7 @@ public:
         watchpoint_support_info,        // 'qWatchpointSupportInfo:'
         allocate_memory,                // '_M'
         deallocate_memory,              // '_m'
+        set_process_event,               // 'QSetProcessEvent:'
         save_register_state,            // '_g'
         restore_register_state,         // '_G'
         speed_test,                     // 'qSpeedTest:'
@@ -197,6 +198,7 @@ public:
     rnb_err_t HandlePacket_QListThreadsInStopReply (const char *p);
     rnb_err_t HandlePacket_QSyncThreadState (const char *p);
     rnb_err_t HandlePacket_QPrefixRegisterPacketsWithThreadID (const char *p);
+    rnb_err_t HandlePacket_QSetProcessEvent (const char *p);
     rnb_err_t HandlePacket_last_signal (const char *p);
     rnb_err_t HandlePacket_m (const char *p);
     rnb_err_t HandlePacket_M (const char *p);

Modified: lldb/trunk/tools/debugserver/source/RNBServices.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBServices.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/RNBServices.cpp (original)
+++ lldb/trunk/tools/debugserver/source/RNBServices.cpp Sat Mar 29 13:54:20 2014
@@ -22,7 +22,9 @@
 #import "DNBLog.h"
 #include "MacOSX/CFUtils.h"
 
-#ifdef WITH_SPRINGBOARD
+// For now only SpringBoard has a notion of "Applications" that it can list for us.
+// So we have to use the SpringBoard API's here.
+#if defined (WITH_SPRINGBOARD) || defined (WITH_BKS)
 #import <SpringBoardServices/SpringBoardServices.h>
 #endif
 
@@ -30,7 +32,7 @@
 size_t GetAllInfos (std::vector<struct kinfo_proc>& proc_infos);
 
 int
-GetPrcoesses (CFMutableArrayRef plistMutableArray, bool all_users)
+GetProcesses (CFMutableArrayRef plistMutableArray, bool all_users)
 {
     if (plistMutableArray == NULL)
         return -1;
@@ -130,13 +132,12 @@ ListApplications(std::string& plist, boo
 
     const uid_t our_uid = getuid();
 
-#ifdef WITH_SPRINGBOARD
-
+#if defined (WITH_SPRINGBOARD) || defined (WITH_BKS)
     
     if (our_uid == 0)
     {
         bool all_users = true;
-        result = GetPrcoesses (plistMutableArray.get(), all_users);
+        result = GetProcesses (plistMutableArray.get(), all_users);
     }
     else
     {
@@ -190,10 +191,10 @@ ListApplications(std::string& plist, boo
             ::CFArrayAppendValue (plistMutableArray.get(), appInfoDict.get());
         }
     }
-#else
+#else // #if defined (WITH_SPRINGBOARD) || defined (WITH_BKS)
     // When root, show all processes
     bool all_users = (our_uid == 0);
-    result = GetPrcoesses (plistMutableArray.get(), all_users);
+    result = GetProcesses (plistMutableArray.get(), all_users);
 #endif
     
     CFReleaser<CFDataRef> plistData (::CFPropertyListCreateXMLData (alloc, plistMutableArray.get()));
@@ -223,16 +224,3 @@ ListApplications(std::string& plist, boo
     return result;
 
 }
-
-
-bool
-IsSBProcess (nub_process_t pid)
-{
-#ifdef WITH_SPRINGBOARD
-    CFReleaser<CFArrayRef> appIdsForPID (::SBSCopyDisplayIdentifiersForProcessID(pid));
-    return appIdsForPID.get() != NULL;
-#else
-    return false;
-#endif
-}
-

Modified: lldb/trunk/tools/debugserver/source/RNBServices.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBServices.h?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/RNBServices.h (original)
+++ lldb/trunk/tools/debugserver/source/RNBServices.h Sat Mar 29 13:54:20 2014
@@ -24,6 +24,5 @@
 #define DTSERVICES_APP_PID_KEY          CFSTR("pid")
 
 int ListApplications (std::string &plist, bool opt_runningApps, bool opt_debuggable);
-bool IsSBProcess (nub_process_t pid);
 
 #endif  // __RNBServices_h__

Modified: lldb/trunk/tools/debugserver/source/debugserver-entitlements.plist
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/debugserver-entitlements.plist?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/debugserver-entitlements.plist (original)
+++ lldb/trunk/tools/debugserver/source/debugserver-entitlements.plist Sat Mar 29 13:54:20 2014
@@ -4,6 +4,10 @@
 <dict>
 	<key>com.apple.springboard.debugapplications</key>
 	<true/>
+	<key>com.apple.backboardd.launchapplications</key>
+	<true/>
+	<key>com.apple.backboardd.debugapplications</key>
+	<true/>
 	<key>run-unsigned-code</key>
 	<true/>
 	<key>seatbelt-profiles</key>

Modified: lldb/trunk/tools/debugserver/source/debugserver.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/debugserver.cpp?rev=205113&r1=205112&r2=205113&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/debugserver.cpp (original)
+++ lldb/trunk/tools/debugserver/source/debugserver.cpp Sat Mar 29 13:54:20 2014
@@ -196,7 +196,13 @@ RNBRunLoopLaunchInferior (RNBRemote *rem
         // Our default launch method is posix spawn
         launch_flavor = eLaunchFlavorPosixSpawn;
 
-#ifdef WITH_SPRINGBOARD
+#if defined WITH_BKS
+        // Check if we have an app bundle, if so launch using BackBoard Services.
+        if (strstr(inferior_argv[0], ".app"))
+        {
+            launch_flavor = eLaunchFlavorBKS;
+        }
+#elif defined WITH_SPRINGBOARD
         // Check if we have an app bundle, if so launch using SpringBoard.
         if (strstr(inferior_argv[0], ".app"))
         {
@@ -217,6 +223,7 @@ RNBRunLoopLaunchInferior (RNBRemote *rem
     launch_err_str[0] = '\0';
     const char * cwd = (ctx.GetWorkingDirPath() != NULL ? ctx.GetWorkingDirPath()
                                                         : ctx.GetWorkingDirectory());
+    const char *process_event = ctx.GetProcessEvent();
     nub_process_t pid = DNBProcessLaunch (resolved_path,
                                           &inferior_argv[0],
                                           &inferior_envp[0],
@@ -227,6 +234,7 @@ RNBRunLoopLaunchInferior (RNBRemote *rem
                                           no_stdio,
                                           launch_flavor,
                                           g_disable_aslr,
+                                          process_event,
                                           launch_err_str,
                                           sizeof(launch_err_str));
 
@@ -878,6 +886,14 @@ main (int argc, char *argv[])
     //    signal (SIGINT, signal_handler);
     signal (SIGPIPE, signal_handler);
     signal (SIGHUP, signal_handler);
+    
+    // We're always sitting in waitpid or kevent waiting on our target process' death,
+    // we don't need no stinking SIGCHLD's...
+    
+    sigset_t sigset;
+    sigemptyset(&sigset);
+    sigaddset(&sigset, SIGCHLD);
+    sigprocmask(SIG_BLOCK, &sigset, NULL);
 
     g_remoteSP.reset (new RNBRemote ());
     
@@ -1051,15 +1067,23 @@ main (int argc, char *argv[])
                     else if (strcasestr(optarg, "spring") == optarg)
                         g_launch_flavor = eLaunchFlavorSpringBoard;
 #endif
+#ifdef WITH_BKS
+                    else if (strcasestr(optarg, "backboard") == optarg)
+                        g_launch_flavor = eLaunchFlavorBKS;
+#endif
+
                     else
                     {
                         RNBLogSTDERR ("error: invalid TYPE for the --launch=TYPE (-x TYPE) option: '%s'\n", optarg);
                         RNBLogSTDERR ("Valid values TYPE are:\n");
-                        RNBLogSTDERR ("  auto    Auto-detect the best launch method to use.\n");
-                        RNBLogSTDERR ("  posix   Launch the executable using posix_spawn.\n");
-                        RNBLogSTDERR ("  fork    Launch the executable using fork and exec.\n");
+                        RNBLogSTDERR ("  auto       Auto-detect the best launch method to use.\n");
+                        RNBLogSTDERR ("  posix      Launch the executable using posix_spawn.\n");
+                        RNBLogSTDERR ("  fork       Launch the executable using fork and exec.\n");
 #ifdef WITH_SPRINGBOARD
-                        RNBLogSTDERR ("  spring  Launch the executable through Springboard.\n");
+                        RNBLogSTDERR ("  spring     Launch the executable through Springboard.\n");
+#endif
+#ifdef WITH_BKS
+                        RNBLogSTDERR ("  backboard  Launch the executable through BackBoard Services.\n");
 #endif
                         exit (5);
                     }
@@ -1422,7 +1446,13 @@ main (int argc, char *argv[])
                         // Our default launch method is posix spawn
                         launch_flavor = eLaunchFlavorPosixSpawn;
 
-#ifdef WITH_SPRINGBOARD
+#if defined WITH_BKS
+                        // Check if we have an app bundle, if so launch using SpringBoard.
+                        if (waitfor_pid_name.find (".app") != std::string::npos)
+                        {
+                            launch_flavor = eLaunchFlavorBKS;
+                        }
+#elif defined WITH_SPRINGBOARD
                         // Check if we have an app bundle, if so launch using SpringBoard.
                         if (waitfor_pid_name.find (".app") != std::string::npos)
                         {





More information about the lldb-commits mailing list