summaryrefslogtreecommitdiff
path: root/tools/debugserver
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-08-20 18:01:57 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-08-20 18:01:57 +0000
commit88c643b6fec27eec436c8d138fee6346e92337d6 (patch)
tree82cd13b2f3cde1c9e5f79689ba4e6ba67694843f /tools/debugserver
parent94994d372d014ce4c8758b9605d63fae651bd8aa (diff)
Notes
Diffstat (limited to 'tools/debugserver')
-rw-r--r--tools/debugserver/CMakeLists.txt20
-rw-r--r--tools/debugserver/debugnub-exports2
-rw-r--r--tools/debugserver/debugserver.xcodeproj/project.pbxproj1901
-rw-r--r--tools/debugserver/debugserver.xcodeproj/project.xcworkspace/contents.xcworkspacedata7
-rw-r--r--tools/debugserver/debugserver.xcodeproj/xcshareddata/xcschemes/debugserver.xcscheme110
-rw-r--r--tools/debugserver/resources/lldb-debugserver-Info.plist21
-rw-r--r--tools/debugserver/scripts/diagnose-termination.d18
-rw-r--r--tools/debugserver/source/ARM_DWARF_Registers.h206
-rw-r--r--tools/debugserver/source/ARM_ehframe_Registers.h34
-rw-r--r--tools/debugserver/source/CMakeLists.txt310
-rw-r--r--tools/debugserver/source/ChangeLog1515
-rw-r--r--tools/debugserver/source/DNB.cpp1780
-rw-r--r--tools/debugserver/source/DNB.h247
-rw-r--r--tools/debugserver/source/DNBArch.cpp80
-rw-r--r--tools/debugserver/source/DNBArch.h127
-rw-r--r--tools/debugserver/source/DNBBreakpoint.cpp178
-rw-r--r--tools/debugserver/source/DNBBreakpoint.h149
-rw-r--r--tools/debugserver/source/DNBDataRef.cpp351
-rw-r--r--tools/debugserver/source/DNBDataRef.h125
-rw-r--r--tools/debugserver/source/DNBDefs.h373
-rw-r--r--tools/debugserver/source/DNBError.cpp116
-rw-r--r--tools/debugserver/source/DNBError.h98
-rw-r--r--tools/debugserver/source/DNBLog.cpp287
-rw-r--r--tools/debugserver/source/DNBLog.h153
-rw-r--r--tools/debugserver/source/DNBRegisterInfo.cpp252
-rw-r--r--tools/debugserver/source/DNBRegisterInfo.h30
-rw-r--r--tools/debugserver/source/DNBRuntimeAction.h24
-rw-r--r--tools/debugserver/source/DNBThreadResumeActions.cpp89
-rw-r--r--tools/debugserver/source/DNBThreadResumeActions.h66
-rw-r--r--tools/debugserver/source/DNBTimer.h145
-rw-r--r--tools/debugserver/source/JSON.cpp585
-rw-r--r--tools/debugserver/source/JSON.h303
-rw-r--r--tools/debugserver/source/JSONGenerator.h317
-rw-r--r--tools/debugserver/source/MacOSX/CFBundle.cpp80
-rw-r--r--tools/debugserver/source/MacOSX/CFBundle.h38
-rw-r--r--tools/debugserver/source/MacOSX/CFString.cpp163
-rw-r--r--tools/debugserver/source/MacOSX/CFString.h43
-rw-r--r--tools/debugserver/source/MacOSX/CFUtils.h78
-rw-r--r--tools/debugserver/source/MacOSX/CMakeLists.txt23
-rw-r--r--tools/debugserver/source/MacOSX/DarwinLog/ActivityStore.cpp14
-rw-r--r--tools/debugserver/source/MacOSX/DarwinLog/ActivityStore.h30
-rw-r--r--tools/debugserver/source/MacOSX/DarwinLog/ActivityStreamSPI.h191
-rw-r--r--tools/debugserver/source/MacOSX/DarwinLog/CMakeLists.txt15
-rw-r--r--tools/debugserver/source/MacOSX/DarwinLog/DarwinLogCollector.cpp698
-rw-r--r--tools/debugserver/source/MacOSX/DarwinLog/DarwinLogCollector.h114
-rw-r--r--tools/debugserver/source/MacOSX/DarwinLog/DarwinLogEvent.h27
-rw-r--r--tools/debugserver/source/MacOSX/DarwinLog/DarwinLogInterfaces.h25
-rw-r--r--tools/debugserver/source/MacOSX/DarwinLog/DarwinLogTypes.h22
-rw-r--r--tools/debugserver/source/MacOSX/DarwinLog/LogFilter.cpp12
-rw-r--r--tools/debugserver/source/MacOSX/DarwinLog/LogFilter.h30
-rw-r--r--tools/debugserver/source/MacOSX/DarwinLog/LogFilterChain.cpp42
-rw-r--r--tools/debugserver/source/MacOSX/DarwinLog/LogFilterChain.h38
-rw-r--r--tools/debugserver/source/MacOSX/DarwinLog/LogFilterExactMatch.cpp49
-rw-r--r--tools/debugserver/source/MacOSX/DarwinLog/LogFilterExactMatch.h31
-rw-r--r--tools/debugserver/source/MacOSX/DarwinLog/LogFilterRegex.cpp97
-rw-r--r--tools/debugserver/source/MacOSX/DarwinLog/LogFilterRegex.h44
-rw-r--r--tools/debugserver/source/MacOSX/DarwinLog/LogMessage.cpp14
-rw-r--r--tools/debugserver/source/MacOSX/DarwinLog/LogMessage.h40
-rw-r--r--tools/debugserver/source/MacOSX/DarwinLog/LogMessageOsLog.cpp68
-rw-r--r--tools/debugserver/source/MacOSX/DarwinLog/LogMessageOsLog.h59
-rw-r--r--tools/debugserver/source/MacOSX/Genealogy.cpp318
-rw-r--r--tools/debugserver/source/MacOSX/Genealogy.h120
-rw-r--r--tools/debugserver/source/MacOSX/GenealogySPI.h95
-rw-r--r--tools/debugserver/source/MacOSX/MachException.cpp513
-rw-r--r--tools/debugserver/source/MacOSX/MachException.h133
-rw-r--r--tools/debugserver/source/MacOSX/MachProcess.h448
-rw-r--r--tools/debugserver/source/MacOSX/MachProcess.mm3919
-rw-r--r--tools/debugserver/source/MacOSX/MachTask.h113
-rw-r--r--tools/debugserver/source/MacOSX/MachTask.mm962
-rw-r--r--tools/debugserver/source/MacOSX/MachThread.cpp783
-rw-r--r--tools/debugserver/source/MacOSX/MachThread.h170
-rw-r--r--tools/debugserver/source/MacOSX/MachThreadList.cpp582
-rw-r--r--tools/debugserver/source/MacOSX/MachThreadList.h97
-rw-r--r--tools/debugserver/source/MacOSX/MachVMMemory.cpp297
-rw-r--r--tools/debugserver/source/MacOSX/MachVMMemory.h48
-rw-r--r--tools/debugserver/source/MacOSX/MachVMRegion.cpp185
-rw-r--r--tools/debugserver/source/MacOSX/MachVMRegion.h73
-rw-r--r--tools/debugserver/source/MacOSX/OsLogger.cpp66
-rw-r--r--tools/debugserver/source/MacOSX/OsLogger.h20
-rw-r--r--tools/debugserver/source/MacOSX/ThreadInfo.h26
-rw-r--r--tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp2194
-rw-r--r--tools/debugserver/source/MacOSX/arm/DNBArchImpl.h275
-rw-r--r--tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp2104
-rw-r--r--tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.h249
-rw-r--r--tools/debugserver/source/MacOSX/dbgnub-mig.defs5
-rw-r--r--tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp2387
-rw-r--r--tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h239
-rw-r--r--tools/debugserver/source/MacOSX/i386/MachRegisterStatesI386.h242
-rw-r--r--tools/debugserver/source/MacOSX/ppc/DNBArchImpl.cpp492
-rw-r--r--tools/debugserver/source/MacOSX/ppc/DNBArchImpl.h160
-rw-r--r--tools/debugserver/source/MacOSX/stack_logging.h158
-rw-r--r--tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp2890
-rw-r--r--tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h242
-rw-r--r--tools/debugserver/source/MacOSX/x86_64/MachRegisterStatesX86_64.h314
-rw-r--r--tools/debugserver/source/PThreadCondition.h35
-rw-r--r--tools/debugserver/source/PThreadEvent.cpp200
-rw-r--r--tools/debugserver/source/PThreadEvent.h64
-rw-r--r--tools/debugserver/source/PThreadMutex.cpp67
-rw-r--r--tools/debugserver/source/PThreadMutex.h120
-rw-r--r--tools/debugserver/source/PseudoTerminal.cpp196
-rw-r--r--tools/debugserver/source/PseudoTerminal.h87
-rw-r--r--tools/debugserver/source/RNBContext.cpp297
-rw-r--r--tools/debugserver/source/RNBContext.h164
-rw-r--r--tools/debugserver/source/RNBDefs.h99
-rw-r--r--tools/debugserver/source/RNBRemote.cpp6256
-rw-r--r--tools/debugserver/source/RNBRemote.h433
-rw-r--r--tools/debugserver/source/RNBServices.cpp235
-rw-r--r--tools/debugserver/source/RNBServices.h29
-rw-r--r--tools/debugserver/source/RNBSocket.cpp392
-rw-r--r--tools/debugserver/source/RNBSocket.h79
-rw-r--r--tools/debugserver/source/StdStringExtractor.cpp401
-rw-r--r--tools/debugserver/source/StdStringExtractor.h121
-rw-r--r--tools/debugserver/source/SysSignal.cpp95
-rw-r--r--tools/debugserver/source/SysSignal.h22
-rw-r--r--tools/debugserver/source/TTYState.cpp94
-rw-r--r--tools/debugserver/source/TTYState.h59
-rw-r--r--tools/debugserver/source/com.apple.debugserver.applist.internal.plist16
-rw-r--r--tools/debugserver/source/com.apple.debugserver.applist.plist19
-rw-r--r--tools/debugserver/source/com.apple.debugserver.internal.plist15
-rw-r--r--tools/debugserver/source/com.apple.debugserver.plist18
-rw-r--r--tools/debugserver/source/com.apple.debugserver.posix.plist18
-rw-r--r--tools/debugserver/source/com.apple.internal.xpc.remote.debugserver.plist35
-rw-r--r--tools/debugserver/source/debugserver-entitlements.plist30
-rw-r--r--tools/debugserver/source/debugserver-macosx-entitlements.plist10
-rw-r--r--tools/debugserver/source/debugserver.cpp1684
-rw-r--r--tools/debugserver/source/libdebugserver.cpp383
-rw-r--r--tools/debugserver/source/libdebugserver.h15
127 files changed, 0 insertions, 44811 deletions
diff --git a/tools/debugserver/CMakeLists.txt b/tools/debugserver/CMakeLists.txt
deleted file mode 100644
index 1dc32434ba40..000000000000
--- a/tools/debugserver/CMakeLists.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-cmake_minimum_required(VERSION 3.4.3)
-
-project(Debugserver LANGUAGES C CXX ASM-ATT)
-
-if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
- set(CMAKE_MODULE_PATH
- ${CMAKE_MODULE_PATH}
- "${CMAKE_SOURCE_DIR}/../../cmake"
- "${CMAKE_SOURCE_DIR}/../../cmake/modules"
- )
-
- include(LLDBStandalone)
- include(debugserverConfig)
- include(AddLLDB)
-
- set(LLDB_SOURCE_DIR "${CMAKE_SOURCE_DIR}/../../")
- include_directories(${LLDB_SOURCE_DIR}/include)
-endif()
-
-add_subdirectory(source)
diff --git a/tools/debugserver/debugnub-exports b/tools/debugserver/debugnub-exports
deleted file mode 100644
index 662bf9308a6f..000000000000
--- a/tools/debugserver/debugnub-exports
+++ /dev/null
@@ -1,2 +0,0 @@
-_DNB*
-__DNB*
diff --git a/tools/debugserver/debugserver.xcodeproj/project.pbxproj b/tools/debugserver/debugserver.xcodeproj/project.pbxproj
deleted file mode 100644
index f4267b7633a2..000000000000
--- a/tools/debugserver/debugserver.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,1901 +0,0 @@
-// !$*UTF8*$!
-{
- archiveVersion = 1;
- classes = {
- };
- objectVersion = 46;
- objects = {
-
-/* Begin PBXBuildFile section */
- 23562ED61D342A5A00AB2BD4 /* ActivityStore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23562ED51D342A5A00AB2BD4 /* ActivityStore.cpp */; };
- 23562ED71D342A5A00AB2BD4 /* ActivityStore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23562ED51D342A5A00AB2BD4 /* ActivityStore.cpp */; };
- 26CE05C5115C36590022F371 /* CFBundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2695DD910D3EBFF6007E4CA2 /* CFBundle.cpp */; };
- 456F67641AD46CE9002850C2 /* CFBundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2695DD910D3EBFF6007E4CA2 /* CFBundle.cpp */; };
- 26CE05C3115C36580022F371 /* CFString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2695DD9B0D3EC160007E4CA2 /* CFString.cpp */; };
- 456F67621AD46CE9002850C2 /* CFString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2695DD9B0D3EC160007E4CA2 /* CFString.cpp */; };
- 26CE05CF115C36F70022F371 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26ACA3340D3E956300A2120B /* CoreFoundation.framework */; settings = {ATTRIBUTES = (Required, ); }; };
- 456F676B1AD46CE9002850C2 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26ACA3340D3E956300A2120B /* CoreFoundation.framework */; settings = {ATTRIBUTES = (Required, ); }; };
- 26CE05B7115C363B0022F371 /* DNB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637D60C71334A0024798E /* DNB.cpp */; };
- 456F67551AD46CE9002850C2 /* DNB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637D60C71334A0024798E /* DNB.cpp */; };
- 264D5D581293835600ED4C01 /* DNBArch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 264D5D571293835600ED4C01 /* DNBArch.cpp */; };
- 456F67671AD46CE9002850C2 /* DNBArch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 264D5D571293835600ED4C01 /* DNBArch.cpp */; };
- 26CE05C1115C36510022F371 /* DNBArchImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2675D4220CCEB705000F49AF /* DNBArchImpl.cpp */; };
- 26CE05C2115C36550022F371 /* DNBArchImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637FB0C71334A0024798E /* DNBArchImpl.cpp */; };
- 456F67601AD46CE9002850C2 /* DNBArchImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2675D4220CCEB705000F49AF /* DNBArchImpl.cpp */; };
- 456F67611AD46CE9002850C2 /* DNBArchImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637FB0C71334A0024798E /* DNBArchImpl.cpp */; };
- 266B5ED11460A68200E43F0A /* DNBArchImplARM64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266B5ECF1460A68200E43F0A /* DNBArchImplARM64.cpp */; };
- 456F67691AD46CE9002850C2 /* DNBArchImplARM64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266B5ECF1460A68200E43F0A /* DNBArchImplARM64.cpp */; };
- 26CE05C0115C364F0022F371 /* DNBArchImplI386.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637EA0C71334A0024798E /* DNBArchImplI386.cpp */; };
- 456F675F1AD46CE9002850C2 /* DNBArchImplI386.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637EA0C71334A0024798E /* DNBArchImplI386.cpp */; };
- 26CE05BF115C364D0022F371 /* DNBArchImplX86_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26CF99A21142EB7400011AAB /* DNBArchImplX86_64.cpp */; };
- 456F675E1AD46CE9002850C2 /* DNBArchImplX86_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26CF99A21142EB7400011AAB /* DNBArchImplX86_64.cpp */; };
- 26CE05B8115C363C0022F371 /* DNBBreakpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637D90C71334A0024798E /* DNBBreakpoint.cpp */; };
- 456F67571AD46CE9002850C2 /* DNBBreakpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637D90C71334A0024798E /* DNBBreakpoint.cpp */; };
- 26CE05B9115C363D0022F371 /* DNBDataRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637DB0C71334A0024798E /* DNBDataRef.cpp */; };
- 456F67581AD46CE9002850C2 /* DNBDataRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637DB0C71334A0024798E /* DNBDataRef.cpp */; };
- 26CE05A7115C360D0022F371 /* DNBError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637DE0C71334A0024798E /* DNBError.cpp */; };
- 456F67461AD46CE9002850C2 /* DNBError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637DE0C71334A0024798E /* DNBError.cpp */; };
- 26CE05BA115C363E0022F371 /* DNBLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637E00C71334A0024798E /* DNBLog.cpp */; };
- 456F67591AD46CE9002850C2 /* DNBLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637E00C71334A0024798E /* DNBLog.cpp */; };
- 26CE05BB115C363F0022F371 /* DNBRegisterInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637E20C71334A0024798E /* DNBRegisterInfo.cpp */; };
- 456F675A1AD46CE9002850C2 /* DNBRegisterInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637E20C71334A0024798E /* DNBRegisterInfo.cpp */; };
- 26CE05A8115C36170022F371 /* DNBThreadResumeActions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260E7331114BFFE600D1DFB3 /* DNBThreadResumeActions.cpp */; };
- 456F67471AD46CE9002850C2 /* DNBThreadResumeActions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260E7331114BFFE600D1DFB3 /* DNBThreadResumeActions.cpp */; };
- 23AE72E41D25DECF00945BCE /* DarwinLogCollector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23AE72E21D25DECF00945BCE /* DarwinLogCollector.cpp */; };
- 23AE72E51D25DEE100945BCE /* DarwinLogCollector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23AE72E21D25DECF00945BCE /* DarwinLogCollector.cpp */; };
- 49D404621E39260F00570CDC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 49D404611E39260F00570CDC /* Foundation.framework */; };
- AFA3FCA11E39984900218D5E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 49D404611E39260F00570CDC /* Foundation.framework */; };
- 456F67561AD46CE9002850C2 /* Genealogy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AFEC3363194A8B0B00FF05C6 /* Genealogy.cpp */; };
- AFEC3364194A8B0B00FF05C6 /* Genealogy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AFEC3363194A8B0B00FF05C6 /* Genealogy.cpp */; };
- 23043C9D1D35DBEC00FC25CA /* JSON.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 233B4EA51D2DB54300E98261 /* JSON.cpp */; };
- 233B4EA71D2DB54300E98261 /* JSON.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 233B4EA51D2DB54300E98261 /* JSON.cpp */; };
- 23AC04C61D2F41A00072351D /* LogFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23AC04C41D2F41A00072351D /* LogFilter.cpp */; };
- 23AC04C71D2F41A00072351D /* LogFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23AC04C41D2F41A00072351D /* LogFilter.cpp */; };
- 23AC04CA1D2F42250072351D /* LogFilterChain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23AC04C81D2F42250072351D /* LogFilterChain.cpp */; };
- 23AC04CB1D2F42250072351D /* LogFilterChain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23AC04C81D2F42250072351D /* LogFilterChain.cpp */; };
- 2307CCCB1D4A5D630016ABC0 /* LogFilterExactMatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 237821AE1D4917D20028B7A1 /* LogFilterExactMatch.cpp */; };
- 237821B01D4917D20028B7A1 /* LogFilterExactMatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 237821AE1D4917D20028B7A1 /* LogFilterExactMatch.cpp */; };
- 23AC04CF1D2F58AF0072351D /* LogFilterRegex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23AC04CD1D2F58AF0072351D /* LogFilterRegex.cpp */; };
- 23AC04D01D2F58AF0072351D /* LogFilterRegex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23AC04CD1D2F58AF0072351D /* LogFilterRegex.cpp */; };
- 23562ED91D342B0000AB2BD4 /* LogMessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23562ED81D342B0000AB2BD4 /* LogMessage.cpp */; };
- 23562EDA1D342B0000AB2BD4 /* LogMessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23562ED81D342B0000AB2BD4 /* LogMessage.cpp */; };
- 23562ED21D3424DF00AB2BD4 /* LogMessageOsLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23562ED01D3424DF00AB2BD4 /* LogMessageOsLog.cpp */; };
- 23562ED31D3424DF00AB2BD4 /* LogMessageOsLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23562ED01D3424DF00AB2BD4 /* LogMessageOsLog.cpp */; };
- 26CE05B0115C36340022F371 /* MachException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637EE0C71334A0024798E /* MachException.cpp */; };
- 456F674E1AD46CE9002850C2 /* MachException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637EE0C71334A0024798E /* MachException.cpp */; };
- 26CE05B1115C36350022F371 /* MachProcess.mm in Sources */ = {isa = PBXBuildFile; fileRef = 26C637F00C71334A0024798E /* MachProcess.mm */; };
- 456F674F1AD46CE9002850C2 /* MachProcess.mm in Sources */ = {isa = PBXBuildFile; fileRef = 26C637F00C71334A0024798E /* MachProcess.mm */; };
- 26CE05B6115C36390022F371 /* MachTask.mm in Sources */ = {isa = PBXBuildFile; fileRef = 26B67DE10EE9BC30006C8BC0 /* MachTask.mm */; };
- 456F67541AD46CE9002850C2 /* MachTask.mm in Sources */ = {isa = PBXBuildFile; fileRef = 26B67DE10EE9BC30006C8BC0 /* MachTask.mm */; };
- 26CE05B2115C36360022F371 /* MachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637F20C71334A0024798E /* MachThread.cpp */; };
- 456F67501AD46CE9002850C2 /* MachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637F20C71334A0024798E /* MachThread.cpp */; };
- 26CE05B3115C36370022F371 /* MachThreadList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637F40C71334A0024798E /* MachThreadList.cpp */; };
- 456F67511AD46CE9002850C2 /* MachThreadList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637F40C71334A0024798E /* MachThreadList.cpp */; };
- 26CE05B4115C36380022F371 /* MachVMMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637F60C71334A0024798E /* MachVMMemory.cpp */; };
- 456F67521AD46CE9002850C2 /* MachVMMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637F60C71334A0024798E /* MachVMMemory.cpp */; };
- 26CE05B5115C36380022F371 /* MachVMRegion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637F80C71334A0024798E /* MachVMRegion.cpp */; };
- 456F67531AD46CE9002850C2 /* MachVMRegion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637F80C71334A0024798E /* MachVMRegion.cpp */; };
- 23D1B0291D497E8B00FF831B /* OsLogger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23D1B0271D497E8B00FF831B /* OsLogger.cpp */; };
- 23D1B02A1D497E8B00FF831B /* OsLogger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23D1B0271D497E8B00FF831B /* OsLogger.cpp */; };
- 26CE05BC115C36420022F371 /* PThreadEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637FE0C71334A0024798E /* PThreadEvent.cpp */; };
- 456F675B1AD46CE9002850C2 /* PThreadEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637FE0C71334A0024798E /* PThreadEvent.cpp */; };
- 26CE05BD115C36430022F371 /* PThreadMutex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2672DBEE0EEF446700E92059 /* PThreadMutex.cpp */; };
- 456F675C1AD46CE9002850C2 /* PThreadMutex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2672DBEE0EEF446700E92059 /* PThreadMutex.cpp */; };
- 26CE05F1115C387C0022F371 /* PseudoTerminal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF67ABFF0D34604D0022D128 /* PseudoTerminal.cpp */; };
- 456F67651AD46CE9002850C2 /* PseudoTerminal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF67ABFF0D34604D0022D128 /* PseudoTerminal.cpp */; };
- 26CE05AA115C36260022F371 /* RNBContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A68F7E0D104EC800665A9E /* RNBContext.cpp */; };
- 456F67491AD46CE9002850C2 /* RNBContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A68F7E0D104EC800665A9E /* RNBContext.cpp */; };
- 26CE05AD115C36280022F371 /* RNBRemote.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A68FD60D10574500665A9E /* RNBRemote.cpp */; };
- 456F674C1AD46CE9002850C2 /* RNBRemote.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A68FD60D10574500665A9E /* RNBRemote.cpp */; };
- 26CE05AB115C36270022F371 /* RNBServices.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EF8878A00D9C797C001831DA /* RNBServices.cpp */; };
- 456F674A1AD46CE9002850C2 /* RNBServices.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EF8878A00D9C797C001831DA /* RNBServices.cpp */; };
- 26CE05AC115C36280022F371 /* RNBSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A68FB00D1054DA00665A9E /* RNBSocket.cpp */; };
- 456F674B1AD46CE9002850C2 /* RNBSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A68FB00D1054DA00665A9E /* RNBSocket.cpp */; };
- AF588449206077BD00A0CB5A /* SocketAddress.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D6631CA81E848FE9006A7B11 /* SocketAddress.cpp */; };
- D6631CA91E848FE9006A7B11 /* SocketAddress.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D6631CA81E848FE9006A7B11 /* SocketAddress.cpp */; };
- AF48558C1D75126800D19C07 /* StdStringExtractor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF48558B1D75126800D19C07 /* StdStringExtractor.cpp */; };
- AF48558D1D75127500D19C07 /* StdStringExtractor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF48558B1D75126800D19C07 /* StdStringExtractor.cpp */; };
- 23043C9E1D35DBFA00FC25CA /* StringConvert.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 233B4EA81D2DB96A00E98261 /* StringConvert.cpp */; };
- 233B4EA91D2DB96A00E98261 /* StringConvert.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 233B4EA81D2DB96A00E98261 /* StringConvert.cpp */; };
- 26CE05BE115C36440022F371 /* SysSignal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C638010C71334A0024798E /* SysSignal.cpp */; };
- 456F675D1AD46CE9002850C2 /* SysSignal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C638010C71334A0024798E /* SysSignal.cpp */; };
- 26CE05AE115C36320022F371 /* dbgnub-mig.defs in Sources */ = {isa = PBXBuildFile; fileRef = 26C637E80C71334A0024798E /* dbgnub-mig.defs */; settings = {ATTRIBUTES = (Client, Server, ); }; };
- 456F674D1AD46CE9002850C2 /* dbgnub-mig.defs in Sources */ = {isa = PBXBuildFile; fileRef = 26C637E80C71334A0024798E /* dbgnub-mig.defs */; settings = {ATTRIBUTES = (Client, Server, ); }; };
- 26CE05A9115C36250022F371 /* debugserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A02918114AB9240029C479 /* debugserver.cpp */; };
- 456F67481AD46CE9002850C2 /* debugserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A02918114AB9240029C479 /* debugserver.cpp */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXFileReference section */
- 23562ED51D342A5A00AB2BD4 /* ActivityStore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ActivityStore.cpp; sourceTree = "<group>"; };
- 23562ED41D3426DD00AB2BD4 /* ActivityStore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ActivityStore.h; sourceTree = "<group>"; };
- 23AE72E61D25DEFB00945BCE /* ActivityStreamSPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ActivityStreamSPI.h; sourceTree = "<group>"; };
- 2695DD910D3EBFF6007E4CA2 /* CFBundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CFBundle.cpp; sourceTree = "<group>"; };
- 2695DD920D3EBFF6007E4CA2 /* CFBundle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFBundle.h; sourceTree = "<group>"; };
- 2695DD9B0D3EC160007E4CA2 /* CFString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CFString.cpp; sourceTree = "<group>"; };
- 2695DD9A0D3EC160007E4CA2 /* CFString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFString.h; sourceTree = "<group>"; };
- 26C637E70C71334A0024798E /* CFUtils.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CFUtils.h; sourceTree = "<group>"; };
- 2307CCCC1D4A5DAE0016ABC0 /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; };
- 237821AD1D4917D20028B7A1 /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; };
- 26593A060D4931CC001C9FE3 /* ChangeLog */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ChangeLog; sourceTree = "<group>"; };
- 26ACA3340D3E956300A2120B /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
- 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>"; };
- 264D5D571293835600ED4C01 /* DNBArch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DNBArch.cpp; sourceTree = "<group>"; };
- 26C637D80C71334A0024798E /* DNBArch.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DNBArch.h; sourceTree = "<group>"; };
- 2675D4220CCEB705000F49AF /* DNBArchImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DNBArchImpl.cpp; path = arm/DNBArchImpl.cpp; sourceTree = "<group>"; };
- 26C637FB0C71334A0024798E /* DNBArchImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DNBArchImpl.cpp; sourceTree = "<group>"; };
- 2675D4230CCEB705000F49AF /* DNBArchImpl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DNBArchImpl.h; path = arm/DNBArchImpl.h; sourceTree = "<group>"; };
- 26C637FC0C71334A0024798E /* DNBArchImpl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DNBArchImpl.h; sourceTree = "<group>"; };
- 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>"; };
- 26C637EA0C71334A0024798E /* DNBArchImplI386.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DNBArchImplI386.cpp; sourceTree = "<group>"; };
- 26C637EB0C71334A0024798E /* DNBArchImplI386.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DNBArchImplI386.h; sourceTree = "<group>"; };
- 26CF99A21142EB7400011AAB /* DNBArchImplX86_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DNBArchImplX86_64.cpp; sourceTree = "<group>"; };
- 26CF99A31142EB7400011AAB /* DNBArchImplX86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DNBArchImplX86_64.h; sourceTree = "<group>"; };
- 26C637D90C71334A0024798E /* DNBBreakpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DNBBreakpoint.cpp; sourceTree = "<group>"; };
- 26C637DA0C71334A0024798E /* DNBBreakpoint.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DNBBreakpoint.h; sourceTree = "<group>"; };
- 26C637DB0C71334A0024798E /* DNBDataRef.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DNBDataRef.cpp; sourceTree = "<group>"; };
- 26C637DC0C71334A0024798E /* DNBDataRef.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DNBDataRef.h; sourceTree = "<group>"; };
- 26C637DD0C71334A0024798E /* DNBDefs.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = DNBDefs.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
- 26C637DE0C71334A0024798E /* DNBError.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DNBError.cpp; sourceTree = "<group>"; };
- 26C637DF0C71334A0024798E /* DNBError.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DNBError.h; sourceTree = "<group>"; };
- 26C637E00C71334A0024798E /* DNBLog.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DNBLog.cpp; sourceTree = "<group>"; };
- 26C637E10C71334A0024798E /* DNBLog.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DNBLog.h; sourceTree = "<group>"; };
- 26C637E20C71334A0024798E /* DNBRegisterInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DNBRegisterInfo.cpp; sourceTree = "<group>"; };
- 26C637E30C71334A0024798E /* DNBRegisterInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DNBRegisterInfo.h; sourceTree = "<group>"; };
- 260828DE0CBAF7F400F95054 /* DNBRuntimeAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DNBRuntimeAction.h; sourceTree = "<group>"; };
- 260E7331114BFFE600D1DFB3 /* DNBThreadResumeActions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DNBThreadResumeActions.cpp; sourceTree = "<group>"; };
- 260E7332114BFFE600D1DFB3 /* DNBThreadResumeActions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DNBThreadResumeActions.h; sourceTree = "<group>"; };
- 26A8FE1E0D11A77B00203048 /* DNBTimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DNBTimer.h; sourceTree = "<group>"; };
- 23AE72E21D25DECF00945BCE /* DarwinLogCollector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DarwinLogCollector.cpp; sourceTree = "<group>"; };
- 23AE72E31D25DECF00945BCE /* DarwinLogCollector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DarwinLogCollector.h; sourceTree = "<group>"; };
- 23CF6F5E1D28A3760088ADC9 /* DarwinLogEvent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DarwinLogEvent.h; sourceTree = "<group>"; };
- 23AC04CC1D2F42F10072351D /* DarwinLogInterfaces.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DarwinLogInterfaces.h; sourceTree = "<group>"; };
- 23562ECF1D34110D00AB2BD4 /* DarwinLogTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DarwinLogTypes.h; sourceTree = "<group>"; };
- 49D404611E39260F00570CDC /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
- AFEC3363194A8B0B00FF05C6 /* Genealogy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Genealogy.cpp; sourceTree = "<group>"; };
- AF0934BA18E12B92005A11FD /* Genealogy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Genealogy.h; sourceTree = "<group>"; };
- AF0934BB18E12B92005A11FD /* GenealogySPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GenealogySPI.h; sourceTree = "<group>"; };
- 233B4EA51D2DB54300E98261 /* JSON.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSON.cpp; sourceTree = "<group>"; };
- 233B4EA61D2DB54300E98261 /* JSON.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSON.h; sourceTree = "<group>"; };
- 264F679A1B2F9EB200140093 /* JSONGenerator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JSONGenerator.h; sourceTree = "<group>"; };
- 23AC04C41D2F41A00072351D /* LogFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LogFilter.cpp; sourceTree = "<group>"; };
- 23AC04C51D2F41A00072351D /* LogFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogFilter.h; sourceTree = "<group>"; };
- 23AC04C81D2F42250072351D /* LogFilterChain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LogFilterChain.cpp; sourceTree = "<group>"; };
- 23AC04C91D2F42250072351D /* LogFilterChain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogFilterChain.h; sourceTree = "<group>"; };
- 237821AE1D4917D20028B7A1 /* LogFilterExactMatch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LogFilterExactMatch.cpp; sourceTree = "<group>"; };
- 237821AF1D4917D20028B7A1 /* LogFilterExactMatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogFilterExactMatch.h; sourceTree = "<group>"; };
- 23AC04CD1D2F58AF0072351D /* LogFilterRegex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LogFilterRegex.cpp; sourceTree = "<group>"; };
- 23AC04CE1D2F58AF0072351D /* LogFilterRegex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogFilterRegex.h; sourceTree = "<group>"; };
- 23562ED81D342B0000AB2BD4 /* LogMessage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LogMessage.cpp; sourceTree = "<group>"; };
- 23AC04D11D2F60130072351D /* LogMessage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LogMessage.h; sourceTree = "<group>"; };
- 23562ED01D3424DF00AB2BD4 /* LogMessageOsLog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LogMessageOsLog.cpp; sourceTree = "<group>"; };
- 23562ED11D3424DF00AB2BD4 /* LogMessageOsLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogMessageOsLog.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>"; };
- 26C637F10C71334A0024798E /* MachProcess.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MachProcess.h; sourceTree = "<group>"; };
- 26C637F00C71334A0024798E /* MachProcess.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = MachProcess.mm; sourceTree = "<group>"; };
- 49F530111331519C008956F6 /* MachRegisterStatesI386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachRegisterStatesI386.h; sourceTree = "<group>"; };
- 49F5301213316D7F008956F6 /* MachRegisterStatesX86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachRegisterStatesX86_64.h; sourceTree = "<group>"; };
- 26B67DE00EE9BC30006C8BC0 /* MachTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachTask.h; sourceTree = "<group>"; };
- 26B67DE10EE9BC30006C8BC0 /* MachTask.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MachTask.mm; 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>"; };
- 26C637F40C71334A0024798E /* MachThreadList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MachThreadList.cpp; sourceTree = "<group>"; };
- 26C637F50C71334A0024798E /* MachThreadList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MachThreadList.h; sourceTree = "<group>"; };
- 26C637F60C71334A0024798E /* MachVMMemory.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MachVMMemory.cpp; sourceTree = "<group>"; };
- 26C637F70C71334A0024798E /* MachVMMemory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MachVMMemory.h; sourceTree = "<group>"; };
- 26C637F80C71334A0024798E /* MachVMRegion.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MachVMRegion.cpp; sourceTree = "<group>"; };
- 26C637F90C71334A0024798E /* MachVMRegion.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MachVMRegion.h; sourceTree = "<group>"; };
- 23D1B0271D497E8B00FF831B /* OsLogger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OsLogger.cpp; sourceTree = "<group>"; };
- 23D1B0281D497E8B00FF831B /* OsLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OsLogger.h; sourceTree = "<group>"; };
- 26C637FD0C71334A0024798E /* PThreadCondition.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PThreadCondition.h; sourceTree = "<group>"; };
- 26C637FE0C71334A0024798E /* PThreadEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PThreadEvent.cpp; sourceTree = "<group>"; };
- 26C637FF0C71334A0024798E /* PThreadEvent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PThreadEvent.h; sourceTree = "<group>"; };
- 2672DBEE0EEF446700E92059 /* PThreadMutex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PThreadMutex.cpp; sourceTree = "<group>"; };
- 26C638000C71334A0024798E /* PThreadMutex.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PThreadMutex.h; sourceTree = "<group>"; };
- AF67ABFF0D34604D0022D128 /* PseudoTerminal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PseudoTerminal.cpp; sourceTree = "<group>"; };
- AF67AC000D34604D0022D128 /* PseudoTerminal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PseudoTerminal.h; sourceTree = "<group>"; };
- 26A68F7E0D104EC800665A9E /* RNBContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RNBContext.cpp; sourceTree = "<group>"; };
- 26A68F7D0D104EC800665A9E /* RNBContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNBContext.h; sourceTree = "<group>"; };
- 26E6B9DA0D1329010037ECDD /* RNBDefs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNBDefs.h; sourceTree = "<group>"; };
- 26A68FD60D10574500665A9E /* RNBRemote.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RNBRemote.cpp; sourceTree = "<group>"; };
- 26A68FD50D10574500665A9E /* RNBRemote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNBRemote.h; sourceTree = "<group>"; };
- EF8878A00D9C797C001831DA /* RNBServices.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RNBServices.cpp; sourceTree = "<group>"; };
- EF88789F0D9C797C001831DA /* RNBServices.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNBServices.h; sourceTree = "<group>"; };
- 26A68FB00D1054DA00665A9E /* RNBSocket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RNBSocket.cpp; sourceTree = "<group>"; };
- 26A68FAF0D1054DA00665A9E /* RNBSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNBSocket.h; sourceTree = "<group>"; };
- D6631CA81E848FE9006A7B11 /* SocketAddress.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = SocketAddress.cpp; path = ../../source/Host/common/SocketAddress.cpp; sourceTree = "<group>"; };
- AF48558B1D75126800D19C07 /* StdStringExtractor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StdStringExtractor.cpp; sourceTree = "<group>"; };
- 233B4EA81D2DB96A00E98261 /* StringConvert.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringConvert.cpp; path = ../../../source/Host/common/StringConvert.cpp; sourceTree = "<group>"; };
- 26C638010C71334A0024798E /* SysSignal.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SysSignal.cpp; sourceTree = "<group>"; };
- 26C638020C71334A0024798E /* SysSignal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SysSignal.h; sourceTree = "<group>"; };
- 26C638050C71334A0024798E /* TTYState.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TTYState.cpp; sourceTree = "<group>"; };
- 26C638060C71334A0024798E /* TTYState.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TTYState.h; sourceTree = "<group>"; };
- 26203D1C1641EFB200A662F7 /* com.apple.debugserver.applist.internal.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.debugserver.applist.internal.plist; sourceTree = "<group>"; };
- EF88788B0D9C7558001831DA /* com.apple.debugserver.applist.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.debugserver.applist.plist; sourceTree = "<group>"; };
- 26203D1D1641EFB200A662F7 /* com.apple.debugserver.internal.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.debugserver.internal.plist; sourceTree = "<group>"; };
- 26A4BAED0D498B7D00A9BEAB /* com.apple.debugserver.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.debugserver.plist; sourceTree = "<group>"; };
- 269E8DF8164B2ED200AD65F6 /* com.apple.debugserver.posix.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.debugserver.posix.plist; sourceTree = "<group>"; };
- AF949ED620605DC2002A91F9 /* com.apple.internal.xpc.remote.debugserver.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = com.apple.internal.xpc.remote.debugserver.plist; sourceTree = "<group>"; };
- 26C637E80C71334A0024798E /* dbgnub-mig.defs */ = {isa = PBXFileReference; explicitFileType = sourcecode.mig; fileEncoding = 30; path = "dbgnub-mig.defs"; sourceTree = "<group>"; };
- 260FC7320E5B290400043FC9 /* debugnub-exports */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "debugnub-exports"; sourceTree = SOURCE_ROOT; };
- 26CE0594115C31C20022F371 /* debugserver */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = debugserver; sourceTree = BUILT_PRODUCTS_DIR; };
- 26242C390DDBD33C0054A4CC /* debugserver-entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "debugserver-entitlements.plist"; sourceTree = "<group>"; };
- AF61C60418F75ABC00B48D9D /* debugserver-macosx-entitlements.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "debugserver-macosx-entitlements.plist"; sourceTree = "<group>"; };
- 456F67721AD46CE9002850C2 /* debugserver-nonui */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "debugserver-nonui"; sourceTree = BUILT_PRODUCTS_DIR; };
- 26A02918114AB9240029C479 /* debugserver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debugserver.cpp; sourceTree = "<group>"; };
- 9457ECF61419864100DFE7D8 /* stack_logging.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = stack_logging.h; sourceTree = "<group>"; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
- 26CE0592115C31C20022F371 /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 49D404621E39260F00570CDC /* Foundation.framework in Frameworks */,
- 26CE05CF115C36F70022F371 /* CoreFoundation.framework in Frameworks */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- 456F676A1AD46CE9002850C2 /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 456F676B1AD46CE9002850C2 /* CoreFoundation.framework in Frameworks */,
- AFA3FCA11E39984900218D5E /* Foundation.framework in Frameworks */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
- 08FB7794FE84155DC02AAC07 /* dbgnub */ = {
- isa = PBXGroup;
- children = (
- D6631CA81E848FE9006A7B11 /* SocketAddress.cpp */,
- 26ACA3330D3E94F200A2120B /* Framework */,
- 26C637D50C71334A0024798E /* source */,
- 1AB674ADFE9D54B511CA2CBB /* Products */,
- 49D404601E39260F00570CDC /* Frameworks */,
- );
- name = dbgnub;
- sourceTree = "<group>";
- };
- 1AB674ADFE9D54B511CA2CBB /* Products */ = {
- isa = PBXGroup;
- children = (
- 26CE0594115C31C20022F371 /* debugserver */,
- 456F67721AD46CE9002850C2 /* debugserver-nonui */,
- );
- name = Products;
- sourceTree = "<group>";
- };
- 23AC04C31D2F3E9A0072351D /* DarwinLog */ = {
- isa = PBXGroup;
- children = (
- 237821AD1D4917D20028B7A1 /* CMakeLists.txt */,
- 23562ED41D3426DD00AB2BD4 /* ActivityStore.h */,
- 23562ED51D342A5A00AB2BD4 /* ActivityStore.cpp */,
- 23AE72E61D25DEFB00945BCE /* ActivityStreamSPI.h */,
- 23AE72E31D25DECF00945BCE /* DarwinLogCollector.h */,
- 23AE72E21D25DECF00945BCE /* DarwinLogCollector.cpp */,
- 23CF6F5E1D28A3760088ADC9 /* DarwinLogEvent.h */,
- 23AC04CC1D2F42F10072351D /* DarwinLogInterfaces.h */,
- 23562ECF1D34110D00AB2BD4 /* DarwinLogTypes.h */,
- 23AC04C51D2F41A00072351D /* LogFilter.h */,
- 23AC04C41D2F41A00072351D /* LogFilter.cpp */,
- 23AC04C91D2F42250072351D /* LogFilterChain.h */,
- 23AC04C81D2F42250072351D /* LogFilterChain.cpp */,
- 237821AF1D4917D20028B7A1 /* LogFilterExactMatch.h */,
- 237821AE1D4917D20028B7A1 /* LogFilterExactMatch.cpp */,
- 23AC04CE1D2F58AF0072351D /* LogFilterRegex.h */,
- 23AC04CD1D2F58AF0072351D /* LogFilterRegex.cpp */,
- 23AC04D11D2F60130072351D /* LogMessage.h */,
- 23562ED81D342B0000AB2BD4 /* LogMessage.cpp */,
- 23562ED11D3424DF00AB2BD4 /* LogMessageOsLog.h */,
- 23562ED01D3424DF00AB2BD4 /* LogMessageOsLog.cpp */,
- );
- path = DarwinLog;
- sourceTree = "<group>";
- };
- 266B5ECE1460A68200E43F0A /* arm64 */ = {
- isa = PBXGroup;
- children = (
- 266B5ECF1460A68200E43F0A /* DNBArchImplARM64.cpp */,
- 266B5ED01460A68200E43F0A /* DNBArchImplARM64.h */,
- );
- path = arm64;
- sourceTree = "<group>";
- };
- 2675D41C0CCEB6CF000F49AF /* arm */ = {
- isa = PBXGroup;
- children = (
- 2675D4220CCEB705000F49AF /* DNBArchImpl.cpp */,
- 2675D4230CCEB705000F49AF /* DNBArchImpl.h */,
- );
- name = arm;
- sourceTree = "<group>";
- };
- 26A028FE114AB6A60029C479 /* Resources */ = {
- isa = PBXGroup;
- children = (
- 26A4BAED0D498B7D00A9BEAB /* com.apple.debugserver.plist */,
- EF88788B0D9C7558001831DA /* com.apple.debugserver.applist.plist */,
- 269E8DF8164B2ED200AD65F6 /* com.apple.debugserver.posix.plist */,
- 26203D1C1641EFB200A662F7 /* com.apple.debugserver.applist.internal.plist */,
- 26203D1D1641EFB200A662F7 /* com.apple.debugserver.internal.plist */,
- AF949ED620605DC2002A91F9 /* com.apple.internal.xpc.remote.debugserver.plist */,
- 260FC7320E5B290400043FC9 /* debugnub-exports */,
- 26242C390DDBD33C0054A4CC /* debugserver-entitlements.plist */,
- AF61C60418F75ABC00B48D9D /* debugserver-macosx-entitlements.plist */,
- );
- name = Resources;
- sourceTree = "<group>";
- };
- 26A028FF114AB6BB0029C479 /* libdebugnub */ = {
- isa = PBXGroup;
- children = (
- 26C637E60C71334A0024798E /* MacOSX */,
- 260828DE0CBAF7F400F95054 /* DNBRuntimeAction.h */,
- 26A8FE1E0D11A77B00203048 /* DNBTimer.h */,
- 26C637D70C71334A0024798E /* DNB.h */,
- 26C637D60C71334A0024798E /* DNB.cpp */,
- 26C637D80C71334A0024798E /* DNBArch.h */,
- 264D5D571293835600ED4C01 /* DNBArch.cpp */,
- 26C637DA0C71334A0024798E /* DNBBreakpoint.h */,
- 26C637D90C71334A0024798E /* DNBBreakpoint.cpp */,
- 26C637DC0C71334A0024798E /* DNBDataRef.h */,
- 26C637DB0C71334A0024798E /* DNBDataRef.cpp */,
- 26C637DD0C71334A0024798E /* DNBDefs.h */,
- 26C637DF0C71334A0024798E /* DNBError.h */,
- 26C637DE0C71334A0024798E /* DNBError.cpp */,
- 26C637E10C71334A0024798E /* DNBLog.h */,
- 26C637E00C71334A0024798E /* DNBLog.cpp */,
- 26C637E30C71334A0024798E /* DNBRegisterInfo.h */,
- 26C637E20C71334A0024798E /* DNBRegisterInfo.cpp */,
- 260E7332114BFFE600D1DFB3 /* DNBThreadResumeActions.h */,
- 260E7331114BFFE600D1DFB3 /* DNBThreadResumeActions.cpp */,
- 233B4EA61D2DB54300E98261 /* JSON.h */,
- 233B4EA51D2DB54300E98261 /* JSON.cpp */,
- 264F679A1B2F9EB200140093 /* JSONGenerator.h */,
- AF67AC000D34604D0022D128 /* PseudoTerminal.h */,
- AF67ABFF0D34604D0022D128 /* PseudoTerminal.cpp */,
- 26C637FD0C71334A0024798E /* PThreadCondition.h */,
- 26C637FF0C71334A0024798E /* PThreadEvent.h */,
- 26C637FE0C71334A0024798E /* PThreadEvent.cpp */,
- 26C638000C71334A0024798E /* PThreadMutex.h */,
- 2672DBEE0EEF446700E92059 /* PThreadMutex.cpp */,
- 233B4EA81D2DB96A00E98261 /* StringConvert.cpp */,
- 26C638020C71334A0024798E /* SysSignal.h */,
- 26C638010C71334A0024798E /* SysSignal.cpp */,
- 26C638060C71334A0024798E /* TTYState.h */,
- 26C638050C71334A0024798E /* TTYState.cpp */,
- );
- name = libdebugnub;
- sourceTree = "<group>";
- };
- 26ACA3330D3E94F200A2120B /* Framework */ = {
- isa = PBXGroup;
- children = (
- 26ACA3340D3E956300A2120B /* CoreFoundation.framework */,
- );
- name = Framework;
- sourceTree = "<group>";
- };
- 26C637D50C71334A0024798E /* source */ = {
- isa = PBXGroup;
- children = (
- 26593A060D4931CC001C9FE3 /* ChangeLog */,
- 26DEFD6C0D104C23008A5A07 /* debugserver */,
- 26A028FF114AB6BB0029C479 /* libdebugnub */,
- );
- indentWidth = 4;
- path = source;
- sourceTree = "<group>";
- tabWidth = 4;
- usesTabs = 0;
- };
- 26C637E60C71334A0024798E /* MacOSX */ = {
- isa = PBXGroup;
- children = (
- 23AC04C31D2F3E9A0072351D /* DarwinLog */,
- 2695DD920D3EBFF6007E4CA2 /* CFBundle.h */,
- 2695DD910D3EBFF6007E4CA2 /* CFBundle.cpp */,
- 2695DD9A0D3EC160007E4CA2 /* CFString.h */,
- 2695DD9B0D3EC160007E4CA2 /* CFString.cpp */,
- 26C637E70C71334A0024798E /* CFUtils.h */,
- 2307CCCC1D4A5DAE0016ABC0 /* CMakeLists.txt */,
- 2675D41C0CCEB6CF000F49AF /* arm */,
- 266B5ECE1460A68200E43F0A /* arm64 */,
- 26C637E90C71334A0024798E /* i386 */,
- 26C637FA0C71334A0024798E /* ppc */,
- 26CF99A11142EB7400011AAB /* x86_64 */,
- 26C637E80C71334A0024798E /* dbgnub-mig.defs */,
- AFEC3363194A8B0B00FF05C6 /* Genealogy.cpp */,
- AF0934BA18E12B92005A11FD /* Genealogy.h */,
- AF0934BB18E12B92005A11FD /* GenealogySPI.h */,
- 26C637EF0C71334A0024798E /* MachException.h */,
- 26C637EE0C71334A0024798E /* MachException.cpp */,
- 26C637F10C71334A0024798E /* MachProcess.h */,
- 26C637F00C71334A0024798E /* MachProcess.mm */,
- 26C637F30C71334A0024798E /* MachThread.h */,
- 26C637F20C71334A0024798E /* MachThread.cpp */,
- 26C637F50C71334A0024798E /* MachThreadList.h */,
- 26C637F40C71334A0024798E /* MachThreadList.cpp */,
- 26C637F70C71334A0024798E /* MachVMMemory.h */,
- 26C637F60C71334A0024798E /* MachVMMemory.cpp */,
- 26C637F90C71334A0024798E /* MachVMRegion.h */,
- 26C637F80C71334A0024798E /* MachVMRegion.cpp */,
- 26B67DE00EE9BC30006C8BC0 /* MachTask.h */,
- 26B67DE10EE9BC30006C8BC0 /* MachTask.mm */,
- 23D1B0281D497E8B00FF831B /* OsLogger.h */,
- 23D1B0271D497E8B00FF831B /* OsLogger.cpp */,
- 9457ECF61419864100DFE7D8 /* stack_logging.h */,
- );
- path = MacOSX;
- sourceTree = "<group>";
- };
- 26C637E90C71334A0024798E /* i386 */ = {
- isa = PBXGroup;
- children = (
- 26C637EA0C71334A0024798E /* DNBArchImplI386.cpp */,
- 26C637EB0C71334A0024798E /* DNBArchImplI386.h */,
- 49F530111331519C008956F6 /* MachRegisterStatesI386.h */,
- );
- path = i386;
- sourceTree = "<group>";
- };
- 26C637FA0C71334A0024798E /* ppc */ = {
- isa = PBXGroup;
- children = (
- 26C637FB0C71334A0024798E /* DNBArchImpl.cpp */,
- 26C637FC0C71334A0024798E /* DNBArchImpl.h */,
- );
- path = ppc;
- sourceTree = "<group>";
- };
- 26CF99A11142EB7400011AAB /* x86_64 */ = {
- isa = PBXGroup;
- children = (
- 26CF99A21142EB7400011AAB /* DNBArchImplX86_64.cpp */,
- 26CF99A31142EB7400011AAB /* DNBArchImplX86_64.h */,
- 49F5301213316D7F008956F6 /* MachRegisterStatesX86_64.h */,
- );
- path = x86_64;
- sourceTree = "<group>";
- };
- 26DEFD6C0D104C23008A5A07 /* debugserver */ = {
- isa = PBXGroup;
- children = (
- 26A02918114AB9240029C479 /* debugserver.cpp */,
- 26A028FE114AB6A60029C479 /* Resources */,
- 26A68F7D0D104EC800665A9E /* RNBContext.h */,
- 26A68F7E0D104EC800665A9E /* RNBContext.cpp */,
- EF88789F0D9C797C001831DA /* RNBServices.h */,
- EF8878A00D9C797C001831DA /* RNBServices.cpp */,
- 26A68FAF0D1054DA00665A9E /* RNBSocket.h */,
- 26A68FB00D1054DA00665A9E /* RNBSocket.cpp */,
- 26A68FD50D10574500665A9E /* RNBRemote.h */,
- 26A68FD60D10574500665A9E /* RNBRemote.cpp */,
- 26E6B9DA0D1329010037ECDD /* RNBDefs.h */,
- AF48558B1D75126800D19C07 /* StdStringExtractor.cpp */,
- );
- name = debugserver;
- sourceTree = "<group>";
- usesTabs = 0;
- };
- 49D404601E39260F00570CDC /* Frameworks */ = {
- isa = PBXGroup;
- children = (
- 49D404611E39260F00570CDC /* Foundation.framework */,
- );
- name = Frameworks;
- sourceTree = "<group>";
- };
-/* End PBXGroup section */
-
-/* Begin PBXNativeTarget section */
- 26CE0593115C31C20022F371 /* debugserver */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = 26CE05A4115C31ED0022F371 /* Build configuration list for PBXNativeTarget "debugserver" */;
- buildPhases = (
- 26CE0591115C31C20022F371 /* Sources */,
- 26CE0592115C31C20022F371 /* Frameworks */,
- 4C3326CB18B2A2F600EB5DD7 /* ShellScript */,
- );
- buildRules = (
- );
- dependencies = (
- );
- name = debugserver;
- productName = "lldb-debugserver";
- productReference = 26CE0594115C31C20022F371 /* debugserver */;
- productType = "com.apple.product-type.tool";
- };
- 456F67431AD46CE9002850C2 /* debugserver-mini */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = 456F676D1AD46CE9002850C2 /* Build configuration list for PBXNativeTarget "debugserver-mini" */;
- buildPhases = (
- 456F67451AD46CE9002850C2 /* Sources */,
- 456F676A1AD46CE9002850C2 /* Frameworks */,
- );
- buildRules = (
- );
- dependencies = (
- );
- name = "debugserver-mini";
- productName = "lldb-debugserver";
- productReference = 456F67721AD46CE9002850C2 /* debugserver-nonui */;
- productType = "com.apple.product-type.tool";
- };
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
- 08FB7793FE84155DC02AAC07 /* Project object */ = {
- isa = PBXProject;
- attributes = {
- LastSwiftUpdateCheck = 0700;
- LastUpgradeCheck = 0720;
- };
- buildConfigurationList = 1DEB914E08733D8E0010E9CD /* Build configuration list for PBXProject "debugserver" */;
- compatibilityVersion = "Xcode 3.2";
- developmentRegion = English;
- hasScannedForEncodings = 1;
- knownRegions = (
- English,
- Japanese,
- French,
- German,
- );
- mainGroup = 08FB7794FE84155DC02AAC07 /* dbgnub */;
- projectDirPath = "";
- projectRoot = "";
- targets = (
- 26CE0593115C31C20022F371 /* debugserver */,
- 456F67431AD46CE9002850C2 /* debugserver-mini */,
- );
- };
-/* End PBXProject section */
-
-/* Begin PBXShellScriptBuildPhase section */
- 4C3326CB18B2A2F600EB5DD7 /* ShellScript */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- );
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = "/bin/sh -x";
- shellScript = "if [ \"${CONFIGURATION}\" != BuildAndIntegration ]\nthen\n if [ -n \"${DEBUGSERVER_USE_FROM_SYSTEM}\" ]\n then\n\t\tditto \"${DEVELOPER_DIR}/../SharedFrameworks/LLDB.framework/Resources/debugserver\" \"${TARGET_BUILD_DIR}/${TARGET_NAME}\"\n elif [ \"${DEBUGSERVER_DISABLE_CODESIGN}\" == \"\" ]\n then\n codesign -f -s lldb_codesign --entitlements ${SRCROOT}/../../resources/debugserver-macosx-entitlements.plist \"${TARGET_BUILD_DIR}/${TARGET_NAME}\"\n fi\nfi\n";
- };
-/* End PBXShellScriptBuildPhase section */
-
-/* Begin PBXSourcesBuildPhase section */
- 26CE0591115C31C20022F371 /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- D6631CA91E848FE9006A7B11 /* SocketAddress.cpp in Sources */,
- 26CE05A7115C360D0022F371 /* DNBError.cpp in Sources */,
- 26CE05A8115C36170022F371 /* DNBThreadResumeActions.cpp in Sources */,
- 26CE05A9115C36250022F371 /* debugserver.cpp in Sources */,
- AF48558C1D75126800D19C07 /* StdStringExtractor.cpp in Sources */,
- 26CE05AA115C36260022F371 /* RNBContext.cpp in Sources */,
- 26CE05AB115C36270022F371 /* RNBServices.cpp in Sources */,
- 23D1B0291D497E8B00FF831B /* OsLogger.cpp in Sources */,
- 26CE05AC115C36280022F371 /* RNBSocket.cpp in Sources */,
- 26CE05AD115C36280022F371 /* RNBRemote.cpp in Sources */,
- 26CE05AE115C36320022F371 /* dbgnub-mig.defs in Sources */,
- 26CE05B0115C36340022F371 /* MachException.cpp in Sources */,
- 26CE05B1115C36350022F371 /* MachProcess.mm in Sources */,
- 26CE05B2115C36360022F371 /* MachThread.cpp in Sources */,
- 233B4EA71D2DB54300E98261 /* JSON.cpp in Sources */,
- 26CE05B3115C36370022F371 /* MachThreadList.cpp in Sources */,
- 26CE05B4115C36380022F371 /* MachVMMemory.cpp in Sources */,
- 26CE05B5115C36380022F371 /* MachVMRegion.cpp in Sources */,
- 26CE05B6115C36390022F371 /* MachTask.mm in Sources */,
- 26CE05B7115C363B0022F371 /* DNB.cpp in Sources */,
- AFEC3364194A8B0B00FF05C6 /* Genealogy.cpp in Sources */,
- 23AC04CF1D2F58AF0072351D /* LogFilterRegex.cpp in Sources */,
- 233B4EA91D2DB96A00E98261 /* StringConvert.cpp in Sources */,
- 23562ED21D3424DF00AB2BD4 /* LogMessageOsLog.cpp in Sources */,
- 26CE05B8115C363C0022F371 /* DNBBreakpoint.cpp in Sources */,
- 26CE05B9115C363D0022F371 /* DNBDataRef.cpp in Sources */,
- 23AC04CA1D2F42250072351D /* LogFilterChain.cpp in Sources */,
- 23562ED61D342A5A00AB2BD4 /* ActivityStore.cpp in Sources */,
- 26CE05BA115C363E0022F371 /* DNBLog.cpp in Sources */,
- 23AC04C61D2F41A00072351D /* LogFilter.cpp in Sources */,
- 26CE05BB115C363F0022F371 /* DNBRegisterInfo.cpp in Sources */,
- 26CE05BC115C36420022F371 /* PThreadEvent.cpp in Sources */,
- 26CE05BD115C36430022F371 /* PThreadMutex.cpp in Sources */,
- 26CE05BE115C36440022F371 /* SysSignal.cpp in Sources */,
- 23AE72E41D25DECF00945BCE /* DarwinLogCollector.cpp in Sources */,
- 26CE05BF115C364D0022F371 /* DNBArchImplX86_64.cpp in Sources */,
- 26CE05C0115C364F0022F371 /* DNBArchImplI386.cpp in Sources */,
- 26CE05C1115C36510022F371 /* DNBArchImpl.cpp in Sources */,
- 26CE05C2115C36550022F371 /* DNBArchImpl.cpp in Sources */,
- 26CE05C5115C36590022F371 /* CFBundle.cpp in Sources */,
- 26CE05C3115C36580022F371 /* CFString.cpp in Sources */,
- 23562ED91D342B0000AB2BD4 /* LogMessage.cpp in Sources */,
- 26CE05F1115C387C0022F371 /* PseudoTerminal.cpp in Sources */,
- 264D5D581293835600ED4C01 /* DNBArch.cpp in Sources */,
- 237821B01D4917D20028B7A1 /* LogFilterExactMatch.cpp in Sources */,
- 266B5ED11460A68200E43F0A /* DNBArchImplARM64.cpp in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- 456F67451AD46CE9002850C2 /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 456F67461AD46CE9002850C2 /* DNBError.cpp in Sources */,
- 456F67471AD46CE9002850C2 /* DNBThreadResumeActions.cpp in Sources */,
- 456F67481AD46CE9002850C2 /* debugserver.cpp in Sources */,
- 23043C9D1D35DBEC00FC25CA /* JSON.cpp in Sources */,
- 456F67491AD46CE9002850C2 /* RNBContext.cpp in Sources */,
- 23D1B02A1D497E8B00FF831B /* OsLogger.cpp in Sources */,
- 456F674A1AD46CE9002850C2 /* RNBServices.cpp in Sources */,
- 456F674B1AD46CE9002850C2 /* RNBSocket.cpp in Sources */,
- 456F674C1AD46CE9002850C2 /* RNBRemote.cpp in Sources */,
- 456F674D1AD46CE9002850C2 /* dbgnub-mig.defs in Sources */,
- 456F674E1AD46CE9002850C2 /* MachException.cpp in Sources */,
- 456F674F1AD46CE9002850C2 /* MachProcess.mm in Sources */,
- 2307CCCB1D4A5D630016ABC0 /* LogFilterExactMatch.cpp in Sources */,
- 456F67501AD46CE9002850C2 /* MachThread.cpp in Sources */,
- 456F67511AD46CE9002850C2 /* MachThreadList.cpp in Sources */,
- 456F67521AD46CE9002850C2 /* MachVMMemory.cpp in Sources */,
- 456F67531AD46CE9002850C2 /* MachVMRegion.cpp in Sources */,
- 23562ED71D342A5A00AB2BD4 /* ActivityStore.cpp in Sources */,
- 456F67541AD46CE9002850C2 /* MachTask.mm in Sources */,
- 456F67551AD46CE9002850C2 /* DNB.cpp in Sources */,
- 456F67561AD46CE9002850C2 /* Genealogy.cpp in Sources */,
- 456F67571AD46CE9002850C2 /* DNBBreakpoint.cpp in Sources */,
- 456F67581AD46CE9002850C2 /* DNBDataRef.cpp in Sources */,
- 456F67591AD46CE9002850C2 /* DNBLog.cpp in Sources */,
- 23562ED31D3424DF00AB2BD4 /* LogMessageOsLog.cpp in Sources */,
- 456F675A1AD46CE9002850C2 /* DNBRegisterInfo.cpp in Sources */,
- 456F675B1AD46CE9002850C2 /* PThreadEvent.cpp in Sources */,
- 456F675C1AD46CE9002850C2 /* PThreadMutex.cpp in Sources */,
- 456F675D1AD46CE9002850C2 /* SysSignal.cpp in Sources */,
- 23AE72E51D25DEE100945BCE /* DarwinLogCollector.cpp in Sources */,
- 456F675E1AD46CE9002850C2 /* DNBArchImplX86_64.cpp in Sources */,
- 23562EDA1D342B0000AB2BD4 /* LogMessage.cpp in Sources */,
- 456F675F1AD46CE9002850C2 /* DNBArchImplI386.cpp in Sources */,
- 456F67601AD46CE9002850C2 /* DNBArchImpl.cpp in Sources */,
- 23AC04C71D2F41A00072351D /* LogFilter.cpp in Sources */,
- 23043C9E1D35DBFA00FC25CA /* StringConvert.cpp in Sources */,
- 456F67611AD46CE9002850C2 /* DNBArchImpl.cpp in Sources */,
- AF588449206077BD00A0CB5A /* SocketAddress.cpp in Sources */,
- 456F67621AD46CE9002850C2 /* CFString.cpp in Sources */,
- 23AC04CB1D2F42250072351D /* LogFilterChain.cpp in Sources */,
- AF48558D1D75127500D19C07 /* StdStringExtractor.cpp in Sources */,
- 456F67641AD46CE9002850C2 /* CFBundle.cpp in Sources */,
- 456F67651AD46CE9002850C2 /* PseudoTerminal.cpp in Sources */,
- 456F67671AD46CE9002850C2 /* DNBArch.cpp in Sources */,
- 23AC04D01D2F58AF0072351D /* LogFilterRegex.cpp in Sources */,
- 456F67691AD46CE9002850C2 /* DNBArchImplARM64.cpp in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXSourcesBuildPhase section */
-
-/* Begin XCBuildConfiguration section */
- 1DEB914F08733D8E0010E9CD /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- "ARCHS[sdk=iphoneos*]" = arm64;
- "ARCHS[sdk=macosx*]" = "$(ARCHS_STANDARD_64_BIT)";
- CLANG_WARN_BOOL_CONVERSION = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_UNREACHABLE_CODE = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- CODE_SIGN_IDENTITY = "";
- COPY_PHASE_STRIP = NO;
- CURRENT_PROJECT_VERSION = 360.99.0;
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- GCC_NO_COMMON_BLOCKS = YES;
- GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- LLDB_COMPRESSION_LDFLAGS = "-lcompression";
- LLDB_OS_LOG_CFLAGS = "-DLLDB_USE_OS_LOG=$(LLDB_USE_OS_LOG)";
- LLDB_USE_OS_LOG = 0;
- ONLY_ACTIVE_ARCH = YES;
- OTHER_CFLAGS = "";
- STRIP_INSTALLED_PRODUCT = NO;
- VERSIONING_SYSTEM = "apple-generic";
- VERSION_INFO_BUILDER = "$(USER)";
- };
- name = Debug;
- };
- 1DEB915008733D8E0010E9CD /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- "ARCHS[sdk=iphoneos*]" = arm64;
- "ARCHS[sdk=macosx*]" = "$(ARCHS_STANDARD_64_BIT)";
- CLANG_WARN_BOOL_CONVERSION = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_UNREACHABLE_CODE = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- CURRENT_PROJECT_VERSION = 360.99.0;
- DEAD_CODE_STRIPPING = YES;
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- GCC_NO_COMMON_BLOCKS = YES;
- GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- LLDB_COMPRESSION_LDFLAGS = "-lcompression";
- LLDB_ENERGY_LDFLAGS = "-lpmenergy -lpmsample";
- LLDB_OS_LOG_CFLAGS = "-DLLDB_USE_OS_LOG=$(LLDB_USE_OS_LOG)";
- LLDB_USE_OS_LOG = 0;
- ONLY_ACTIVE_ARCH = YES;
- OTHER_CFLAGS = "";
- STRIPFLAGS = "-x";
- STRIP_STYLE = debugging;
- VERSIONING_SYSTEM = "apple-generic";
- VERSION_INFO_BUILDER = "$(USER)";
- };
- name = Release;
- };
- 262419A11198A93E00067686 /* BuildAndIntegration */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- "ARCHS[sdk=iphoneos*]" = arm64;
- "ARCHS[sdk=macosx*]" = "$(ARCHS_STANDARD_64_BIT)";
- CLANG_WARN_BOOL_CONVERSION = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_UNREACHABLE_CODE = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- CURRENT_PROJECT_VERSION = 360.99.0;
- DEAD_CODE_STRIPPING = YES;
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- GCC_NO_COMMON_BLOCKS = YES;
- GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- LLDB_COMPRESSION_LDFLAGS = "-lcompression";
- LLDB_OS_LOG_CFLAGS = "-DLLDB_USE_OS_LOG=$(LLDB_USE_OS_LOG)";
- LLDB_USE_OS_LOG = 1;
- OTHER_CFLAGS = "";
- STRIPFLAGS = "-x";
- STRIP_STYLE = debugging;
- VERSIONING_SYSTEM = "apple-generic";
- VERSION_INFO_BUILDER = "$(USER)";
- };
- name = BuildAndIntegration;
- };
- 262419A21198A93E00067686 /* BuildAndIntegration */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
- CLANG_CXX_LIBRARY = "libc++";
- "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-entitlements.plist";
- "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "source/debugserver-macosx-entitlements.plist";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "-";
- "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
- COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 360.99.0;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks;
- "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = (
- "$(SDKROOT)/System/Library/PrivateFrameworks",
- "$(SDKROOT)/Developer/Library/PrivateFrameworks",
- );
- "FRAMEWORK_SEARCH_PATHS[sdk=macosx*][arch=*]" = "$(SDKROOT)/System/Library/PrivateFrameworks";
- GCC_C_LANGUAGE_STANDARD = c99;
- GCC_PREPROCESSOR_DEFINITIONS = LLDB_DEBUGSERVER_BUILDANDINTEGRATION;
- GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
- HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders;
- INSTALL_PATH = /usr/bin;
- "INSTALL_PATH[sdk=iphoneos*]" = /Developer/usr/bin/;
- LLDB_COMPRESSION_LDFLAGS = "-lcompression";
- LLDB_DEBUGSERVER = 1;
- LLDB_ENERGY_CFLAGS = "";
- "LLDB_ENERGY_CFLAGS[sdk=*internal]" = "-DLLDB_ENERGY";
- LLDB_ENERGY_LDFLAGS = "-lpmenergy -lpmsample";
- OTHER_CFLAGS = (
- "-Wparentheses",
- "$(LLDB_ENERGY_CFLAGS)",
- "-DDT_VARIANT_$(DT_VARIANT)",
- "$(LLDB_OS_LOG_CFLAGS)",
- );
- "OTHER_CFLAGS[sdk=iphoneos*]" = (
- "-Wparentheses",
- "-DWITH_LOCKDOWN",
- "-DWITH_FBS",
- "-DWITH_BKS",
- "-DOS_OBJECT_USE_OBJC=0",
- "$(LLDB_ENERGY_CFLAGS)",
- "$(LLDB_OS_LOG_CFLAGS)",
- "-isystem",
- "$(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders",
- );
- "OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
- OTHER_LDFLAGS = "";
- "OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
- "-framework",
- SpringBoardServices,
- "-framework",
- BackBoardServices,
- "-llockdown",
- "-framework",
- FrontBoardServices,
- "-framework",
- MobileCoreServices,
- "$(LLDB_ENERGY_LDFLAGS)",
- "$(LLDB_COMPRESSION_LDFLAGS)",
- );
- "OTHER_LDFLAGS[sdk=macosx*]" = (
- "-sectcreate",
- __TEXT,
- __info_plist,
- "$(PROJECT_DIR)/resources/lldb-debugserver-Info.plist",
- "$(LLDB_ENERGY_LDFLAGS)",
- "$(LLDB_COMPRESSION_LDFLAGS)",
- );
- OTHER_MIGFLAGS = "-I$(DERIVED_FILE_DIR)";
- PRODUCT_NAME = debugserver;
- SDKROOT = macosx;
- SKIP_INSTALL = YES;
- "SKIP_INSTALL[sdk=iphoneos*]" = NO;
- STRIP_INSTALLED_PRODUCT = YES;
- USER_HEADER_SEARCH_PATHS = "./source ../../source $(DERIVED_SOURCES_DIR) ../../include";
- ZERO_LINK = NO;
- };
- name = BuildAndIntegration;
- };
- 26CE0596115C31C30022F371 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
- CLANG_CXX_LIBRARY = "libc++";
- "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-entitlements.plist";
- "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "source/debugserver-macosx-entitlements.plist";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
- "CODE_SIGN_IDENTITY[sdk=macosx*]" = "";
- COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 360.99.0;
- FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks;
- "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = (
- "$(SDKROOT)/System/Library/PrivateFrameworks",
- "$(SDKROOT)/Developer/Library/PrivateFrameworks",
- );
- "FRAMEWORK_SEARCH_PATHS[sdk=macosx*][arch=*]" = "$(SDKROOT)/System/Library/PrivateFrameworks";
- GCC_C_LANGUAGE_STANDARD = c99;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_PREPROCESSOR_DEFINITIONS = LLDB_DEBUGSERVER_DEBUG;
- GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
- INSTALL_PATH = /usr/bin;
- LLDB_COMPRESSION_LDFLAGS = "-lcompression";
- LLDB_DEBUGSERVER = 1;
- LLDB_ENERGY_CFLAGS = "";
- "LLDB_ENERGY_CFLAGS[sdk=*internal]" = "-DLLDB_ENERGY";
- LLDB_ENERGY_LDFLAGS = "-lpmenergy -lpmsample";
- OTHER_CFLAGS = (
- "-Wparentheses",
- "-DDT_VARIANT_$(DT_VARIANT)",
- "$(LLDB_ENERGY_CFLAGS)",
- "$(LLDB_OS_LOG_CFLAGS)",
- );
- "OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
- "-Wparentheses",
- "-DWITH_LOCKDOWN",
- "-DWITH_BKS",
- "-DWITH_FBS",
- "-DOS_OBJECT_USE_OBJC=0",
- "$(LLDB_ENERGY_CFLAGS)",
- "$(LLDB_OS_LOG_CFLAGS)",
- "-isystem",
- "$(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders",
- );
- "OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
- OTHER_LDFLAGS = "";
- "OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
- "-framework",
- SpringBoardServices,
- "-framework",
- BackBoardServices,
- "-llockdown",
- "-framework",
- FrontBoardServices,
- "-framework",
- MobileCoreServices,
- "$(LLDB_ENERGY_LDFLAGS)",
- "$(LLDB_COMPRESSION_LDFLAGS)",
- );
- "OTHER_LDFLAGS[sdk=macosx*]" = (
- "-sectcreate",
- __TEXT,
- __info_plist,
- "$(PROJECT_DIR)/resources/lldb-debugserver-Info.plist",
- "$(LLDB_ENERGY_LDFLAGS)",
- "$(LLDB_COMPRESSION_LDFLAGS)",
- );
- OTHER_MIGFLAGS = "-I$(DERIVED_FILE_DIR)";
- PRODUCT_NAME = debugserver;
- "PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
- "PROVISIONING_PROFILE[sdk=macosx*]" = "";
- SDKROOT = macosx;
- SKIP_INSTALL = YES;
- USER_HEADER_SEARCH_PATHS = "./source ../../source $(DERIVED_SOURCES_DIR) ../../include";
- ZERO_LINK = NO;
- };
- name = Debug;
- };
- 26CE0597115C31C30022F371 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
- CLANG_CXX_LIBRARY = "libc++";
- "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-entitlements.plist";
- "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "source/debugserver-macosx-entitlements.plist";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
- "CODE_SIGN_IDENTITY[sdk=macosx*]" = "";
- COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 360.99.0;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks;
- "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = (
- "$(SDKROOT)/System/Library/PrivateFrameworks",
- "$(SDKROOT)/Developer/Library/PrivateFrameworks",
- );
- "FRAMEWORK_SEARCH_PATHS[sdk=macosx*][arch=*]" = "$(SDKROOT)/System/Library/PrivateFrameworks";
- GCC_C_LANGUAGE_STANDARD = c99;
- GCC_PREPROCESSOR_DEFINITIONS = LLDB_DEBUGSERVER_RELEASE;
- GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
- INSTALL_PATH = /usr/bin;
- LLDB_COMPRESSION_LDFLAGS = "-lcompression";
- LLDB_DEBUGSERVER = 1;
- LLDB_ENERGY_CFLAGS = "";
- "LLDB_ENERGY_CFLAGS[sdk=*.internal]" = "-DLLDB_ENERGY";
- LLDB_ENERGY_LDFLAGS = "-lpmenergy -lpmsample";
- OTHER_CFLAGS = (
- "-Wparentheses",
- "-DDT_VARIANT_$(DT_VARIANT)",
- "$(LLDB_ENERGY_CFLAGS)",
- "$(LLDB_OS_LOG_CFLAGS)",
- );
- "OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
- "-Wparentheses",
- "-DWITH_LOCKDOWN",
- "-DWITH_FBS",
- "-DWITH_BKS",
- "-DOS_OBJECT_USE_OBJC=0",
- "$(LLDB_ENERGY_CFLAGS)",
- "$(LLDB_OS_LOG_CFLAGS)",
- "-isystem",
- "$(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders",
- );
- "OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
- OTHER_LDFLAGS = "";
- "OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
- "-framework",
- SpringBoardServices,
- "-framework",
- BackBoardServices,
- "-llockdown",
- "-framework",
- FrontBoardServices,
- "-framework",
- MobileCoreServices,
- "$(LLDB_ENERGY_LDFLAGS)",
- "$(LLDB_COMPRESSION_LDFLAGS)",
- );
- "OTHER_LDFLAGS[sdk=macosx*]" = (
- "-sectcreate",
- __TEXT,
- __info_plist,
- "$(PROJECT_DIR)/resources/lldb-debugserver-Info.plist",
- "$(LLDB_ENERGY_LDFLAGS)",
- "$(LLDB_COMPRESSION_LDFLAGS)",
- );
- OTHER_MIGFLAGS = "-I$(DERIVED_FILE_DIR)";
- PRODUCT_NAME = debugserver;
- "PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
- "PROVISIONING_PROFILE[sdk=macosx*]" = "";
- SDKROOT = macosx;
- SKIP_INSTALL = YES;
- USER_HEADER_SEARCH_PATHS = "./source ../../source $(DERIVED_SOURCES_DIR) ../../include";
- ZERO_LINK = NO;
- };
- name = Release;
- };
- 456F676E1AD46CE9002850C2 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
- CLANG_CXX_LIBRARY = "libc++";
- CLANG_WARN_BOOL_CONVERSION = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_UNREACHABLE_CODE = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-entitlements.plist";
- "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "source/debugserver-macosx-entitlements.plist";
- CODE_SIGN_IDENTITY = "";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
- "CODE_SIGN_IDENTITY[sdk=macosx*]" = "";
- COPY_PHASE_STRIP = NO;
- CURRENT_PROJECT_VERSION = 360.99.0;
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks;
- "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = (
- "$(SDKROOT)/System/Library/PrivateFrameworks",
- "$(SDKROOT)/Developer/Library/PrivateFrameworks",
- );
- "FRAMEWORK_SEARCH_PATHS[sdk=macosx*][arch=*]" = "$(SDKROOT)/System/Library/PrivateFrameworks";
- GCC_C_LANGUAGE_STANDARD = c99;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_PREPROCESSOR_DEFINITIONS = LLDB_DEBUGSERVER_DEBUG;
- GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- INSTALL_PATH = /usr/local/bin;
- LLDB_COMPRESSION_LDFLAGS = "-lcompression";
- LLDB_DEBUGSERVER = 1;
- LLDB_ENERGY_CFLAGS = "";
- "LLDB_ENERGY_CFLAGS[sdk=*.internal]" = "-DLLDB_ENERGY";
- LLDB_ENERGY_LDFLAGS = "-lpmenergy -lpmsample";
- ONLY_ACTIVE_ARCH = YES;
- OTHER_CFLAGS = (
- "-Wparentheses",
- "-DDT_VARIANT_$(DT_VARIANT)",
- "$(LLDB_ENERGY_CFLAGS)",
- "$(LLDB_OS_LOG_CFLAGS)",
- );
- "OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
- "-Wparentheses",
- "-DOS_OBJECT_USE_OBJC=0",
- "-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui",
- "$(LLDB_ENERGY_CFLAGS)",
- "$(LLDB_OS_LOG_CFLAGS)",
- );
- "OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
- OTHER_LDFLAGS = "";
- "OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
- "-framework",
- Foundation,
- "$(LLDB_ENERGY_LDFLAGS)",
- "$(LLDB_COMPRESSION_LDFLAGS)",
- );
- "OTHER_LDFLAGS[sdk=macosx*]" = (
- "-sectcreate",
- __TEXT,
- __info_plist,
- "$(PROJECT_DIR)/resources/lldb-debugserver-Info.plist",
- "$(LLDB_ENERGY_LDFLAGS)",
- "$(LLDB_COMPRESSION_LDFLAGS)",
- );
- OTHER_MIGFLAGS = "-I$(DERIVED_FILE_DIR)";
- PRODUCT_NAME = "debugserver-nonui";
- "PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
- "PROVISIONING_PROFILE[sdk=macosx*]" = "";
- SDKROOT = macosx;
- SKIP_INSTALL = YES;
- STRIP_INSTALLED_PRODUCT = NO;
- USER_HEADER_SEARCH_PATHS = "./source ../../source $(DERIVED_SOURCES_DIR) ../../include";
- VERSIONING_SYSTEM = "apple-generic";
- VERSION_INFO_BUILDER = "$(USER)";
- ZERO_LINK = NO;
- };
- name = Debug;
- };
- 456F676F1AD46CE9002850C2 /* DebugClang */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
- CLANG_CXX_LIBRARY = "libc++";
- "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-entitlements.plist";
- "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "source/debugserver-macosx-entitlements.plist";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
- "CODE_SIGN_IDENTITY[sdk=macosx*]" = "";
- COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 360.99.0;
- FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks;
- "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = (
- "$(SDKROOT)/System/Library/PrivateFrameworks",
- "$(SDKROOT)/Developer/Library/PrivateFrameworks",
- );
- "FRAMEWORK_SEARCH_PATHS[sdk=macosx*][arch=*]" = "$(SDKROOT)/System/Library/PrivateFrameworks";
- GCC_C_LANGUAGE_STANDARD = c99;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_PREPROCESSOR_DEFINITIONS = LLDB_DEBUGSERVER_DEBUG;
- GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
- INSTALL_PATH = /usr/local/bin;
- LLDB_DEBUGSERVER = 1;
- LLDB_ENERGY_CFLAGS = "";
- "LLDB_ENERGY_CFLAGS[sdk=*.internal]" = "-DLLDB_ENERGY";
- LLDB_ENERGY_LDFLAGS = "-lpmenergy -lpmsample";
- OTHER_CFLAGS = (
- "$(LLDB_ENERGY_CFLAGS)",
- );
- "OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
- "-Wparentheses",
- "-DOS_OBJECT_USE_OBJC=0",
- "-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui",
- "$(LLDB_OS_LOG_CFLAGS)",
- );
- "OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
- OTHER_LDFLAGS = "";
- "OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
- "-framework",
- Foundation,
- "$(LLDB_ENERGY_LDFLAGS)",
- "$(LLDB_COMPRESSION_LDFLAGS)",
- );
- "OTHER_LDFLAGS[sdk=macosx*]" = (
- "-sectcreate",
- __TEXT,
- __info_plist,
- "$(PROJECT_DIR)/resources/lldb-debugserver-Info.plist",
- "$(LLDB_ENERGY_LDFLAGS)",
- "$(LLDB_COMPRESSION_LDFLAGS)",
- );
- OTHER_MIGFLAGS = "-I$(DERIVED_FILE_DIR)";
- PRODUCT_NAME = "debugserver-nonui";
- "PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
- "PROVISIONING_PROFILE[sdk=macosx*]" = "";
- SDKROOT = macosx;
- SKIP_INSTALL = YES;
- USER_HEADER_SEARCH_PATHS = "./source ../../source $(DERIVED_SOURCES_DIR) ../../include";
- ZERO_LINK = NO;
- };
- name = DebugClang;
- };
- 456F67701AD46CE9002850C2 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
- CLANG_CXX_LIBRARY = "libc++";
- "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-entitlements.plist";
- "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "source/debugserver-macosx-entitlements.plist";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
- "CODE_SIGN_IDENTITY[sdk=macosx*]" = "";
- COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 360.99.0;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks;
- "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = (
- "$(SDKROOT)/System/Library/PrivateFrameworks",
- "$(SDKROOT)/Developer/Library/PrivateFrameworks",
- );
- "FRAMEWORK_SEARCH_PATHS[sdk=macosx*][arch=*]" = "$(SDKROOT)/System/Library/PrivateFrameworks";
- GCC_C_LANGUAGE_STANDARD = c99;
- GCC_PREPROCESSOR_DEFINITIONS = LLDB_DEBUGSERVER_RELEASE;
- GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
- HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders;
- INSTALL_PATH = /usr/local/bin;
- LLDB_COMPRESSION_LDFLAGS = "-lcompression";
- LLDB_DEBUGSERVER = 1;
- LLDB_ENERGY_CFLAGS = "";
- "LLDB_ENERGY_CFLAGS[sdk=*.internal]" = "-DLLDB_ENERGY";
- LLDB_ENERGY_LDFLAGS = "-lpmenergy -lpmsample";
- OTHER_CFLAGS = (
- "$(LLDB_ENERGY_CFLAGS)",
- "-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui",
- "$(LLDB_OS_LOG_CFLAGS)",
- );
- "OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
- "-Wparentheses",
- "-DOS_OBJECT_USE_OBJC=0",
- "-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui",
- "$(LLDB_ENERGY_CFLAGS)",
- "$(LLDB_OS_LOG_CFLAGS)",
- );
- "OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
- OTHER_LDFLAGS = "";
- "OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
- "-framework",
- Foundation,
- "$(LLDB_ENERGY_LDFLAGS)",
- "$(LLDB_COMPRESSION_LDFLAGS)",
- );
- "OTHER_LDFLAGS[sdk=macosx*]" = (
- "-sectcreate",
- __TEXT,
- __info_plist,
- "$(PROJECT_DIR)/resources/lldb-debugserver-Info.plist",
- "$(LLDB_ENERGY_LDFLAGS)",
- "$(LLDB_COMPRESSION_LDFLAGS)",
- );
- OTHER_MIGFLAGS = "-I$(DERIVED_FILE_DIR)";
- PRODUCT_NAME = "debugserver-nonui";
- "PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
- "PROVISIONING_PROFILE[sdk=macosx*]" = "";
- SDKROOT = macosx;
- SKIP_INSTALL = YES;
- USER_HEADER_SEARCH_PATHS = "./source ../../source $(DERIVED_SOURCES_DIR) ../../include";
- ZERO_LINK = NO;
- };
- name = Release;
- };
- 456F67711AD46CE9002850C2 /* BuildAndIntegration */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
- CLANG_CXX_LIBRARY = "libc++";
- "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-entitlements.plist";
- "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "source/debugserver-macosx-entitlements.plist";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "-";
- "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
- COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 360.99.0;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks;
- "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = (
- "$(SDKROOT)/System/Library/PrivateFrameworks",
- "$(SDKROOT)/Developer/Library/PrivateFrameworks",
- );
- "FRAMEWORK_SEARCH_PATHS[sdk=macosx*][arch=*]" = "$(SDKROOT)/System/Library/PrivateFrameworks";
- GCC_C_LANGUAGE_STANDARD = c99;
- GCC_PREPROCESSOR_DEFINITIONS = LLDB_DEBUGSERVER_BUILDANDINTEGRATION;
- GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
- HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders;
- INSTALL_PATH = /usr/local/bin;
- "INSTALL_PATH[sdk=iphoneos*]" = /usr/local/bin;
- LLDB_DEBUGSERVER = 1;
- LLDB_ENERGY_CFLAGS = "";
- "LLDB_ENERGY_CFLAGS[sdk=*.internal]" = "-DLLDB_ENERGY";
- LLDB_ENERGY_LDFLAGS = "-lpmenergy -lpmsample";
- OTHER_CFLAGS = (
- "-Wparentheses",
- "$(LLDB_ENERGY_CFLAGS)",
- "-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui",
- "$(LLDB_OS_LOG_CFLAGS)",
- );
- "OTHER_CFLAGS[sdk=iphoneos*]" = (
- "-Wparentheses",
- "-DOS_OBJECT_USE_OBJC=0",
- "-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui",
- "$(LLDB_OS_LOG_CFLAGS)",
- );
- OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)";
- "OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
- "OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
- "-framework",
- Foundation,
- );
- "OTHER_LDFLAGS[sdk=macosx*]" = (
- "-sectcreate",
- __TEXT,
- __info_plist,
- "$(PROJECT_DIR)/resources/lldb-debugserver-Info.plist",
- "$(LLDB_ENERGY_LDFLAGS)",
- );
- OTHER_MIGFLAGS = "-I$(DERIVED_FILE_DIR)";
- PRODUCT_NAME = "debugserver-nonui";
- SDKROOT = macosx;
- SKIP_INSTALL = YES;
- "SKIP_INSTALL[sdk=iphoneos*]" = NO;
- STRIP_INSTALLED_PRODUCT = YES;
- USER_HEADER_SEARCH_PATHS = "./source ../../source $(DERIVED_SOURCES_DIR) ../../include";
- ZERO_LINK = NO;
- };
- name = BuildAndIntegration;
- };
- 4968B7A916657FAE00741ABB /* DebugClang */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- "ARCHS[sdk=iphoneos*]" = arm64;
- "ARCHS[sdk=macosx*]" = "$(ARCHS_STANDARD_64_BIT)";
- CLANG_WARN_BOOL_CONVERSION = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_UNREACHABLE_CODE = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- CODE_SIGN_IDENTITY = "";
- COPY_PHASE_STRIP = NO;
- CURRENT_PROJECT_VERSION = 360.99.0;
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- GCC_NO_COMMON_BLOCKS = YES;
- GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- LLDB_COMPRESSION_LDFLAGS = "-lcompression";
- LLDB_OS_LOG_CFLAGS = "-DLLDB_USE_OS_LOG=$(LLDB_USE_OS_LOG)";
- LLDB_USE_OS_LOG = 0;
- ONLY_ACTIVE_ARCH = YES;
- SDKROOT = macosx;
- STRIP_INSTALLED_PRODUCT = NO;
- VERSIONING_SYSTEM = "apple-generic";
- VERSION_INFO_BUILDER = "$(USER)";
- };
- name = DebugClang;
- };
- 4968B7AA16657FAE00741ABB /* DebugClang */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
- CLANG_CXX_LIBRARY = "libc++";
- "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-entitlements.plist";
- "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "source/debugserver-macosx-entitlements.plist";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
- "CODE_SIGN_IDENTITY[sdk=macosx*]" = "";
- COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 360.99.0;
- FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks;
- "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = (
- "$(SDKROOT)/System/Library/PrivateFrameworks",
- "$(SDKROOT)/Developer/Library/PrivateFrameworks",
- );
- "FRAMEWORK_SEARCH_PATHS[sdk=macosx*][arch=*]" = "$(SDKROOT)/System/Library/PrivateFrameworks";
- GCC_C_LANGUAGE_STANDARD = c99;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_PREPROCESSOR_DEFINITIONS = LLDB_DEBUGSERVER_DEBUG;
- GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
- INSTALL_PATH = /usr/bin;
- LLDB_COMPRESSION_LDFLAGS = "-lcompression";
- LLDB_DEBUGSERVER = 1;
- LLDB_ENERGY_CFLAGS = "";
- "LLDB_ENERGY_CFLAGS[sdk=*.internal]" = "-DLLDB_ENERGY";
- LLDB_ENERGY_LDFLAGS = "-lpmenergy -lpmsample";
- OTHER_CFLAGS = (
- "-Wparentheses",
- "-DDT_VARIANT_$(DT_VARIANT)",
- "$(LLDB_ENERGY_CFLAGS)",
- "$(LLDB_OS_LOG_CFLAGS)",
- );
- "OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
- "-Wparentheses",
- "-DWITH_LOCKDOWN",
- "-DWITH_FBS",
- "-DWITH_BKS",
- "-DOS_OBJECT_USE_OBJC=0",
- "$(LLDB_ENERGY_CFLAGS)",
- "$(LLDB_OS_LOG_CFLAGS)",
- "-isystem",
- "$(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders",
- );
- "OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
- "OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
- "-framework",
- SpringBoardServices,
- "-framework",
- BackBoardServices,
- "-llockdown",
- "-framework",
- FrontBoardServices,
- "-framework",
- MobileCoreServices,
- "$(LLDB_ENERGY_LDFLAGS)",
- "$(LLDB_COMPRESSION_LDFLAGS)",
- );
- "OTHER_LDFLAGS[sdk=macosx*]" = (
- "-sectcreate",
- __TEXT,
- __info_plist,
- "$(PROJECT_DIR)/resources/lldb-debugserver-Info.plist",
- "$(LLDB_ENERGY_LDFLAGS)",
- "$(LLDB_COMPRESSION_LDFLAGS)",
- );
- OTHER_MIGFLAGS = "-I$(DERIVED_FILE_DIR)";
- PRODUCT_NAME = debugserver;
- "PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
- "PROVISIONING_PROFILE[sdk=macosx*]" = "";
- SDKROOT = macosx;
- SKIP_INSTALL = YES;
- USER_HEADER_SEARCH_PATHS = "./source ../../source $(DERIVED_SOURCES_DIR) ../../include";
- ZERO_LINK = NO;
- };
- name = DebugClang;
- };
- 940AD5251B1FE3B10051E88F /* DebugPresubmission */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- "ARCHS[sdk=iphoneos*]" = arm64;
- "ARCHS[sdk=macosx*]" = "$(ARCHS_STANDARD_64_BIT)";
- CLANG_WARN_BOOL_CONVERSION = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_UNREACHABLE_CODE = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- CODE_SIGN_IDENTITY = "";
- COPY_PHASE_STRIP = NO;
- CURRENT_PROJECT_VERSION = 360.99.0;
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- GCC_NO_COMMON_BLOCKS = YES;
- GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- LLDB_COMPRESSION_LDFLAGS = "-lcompression";
- LLDB_OS_LOG_CFLAGS = "-DLLDB_USE_OS_LOG=$(LLDB_USE_OS_LOG)";
- LLDB_USE_OS_LOG = 0;
- ONLY_ACTIVE_ARCH = YES;
- SDKROOT = macosx;
- STRIP_INSTALLED_PRODUCT = NO;
- VERSIONING_SYSTEM = "apple-generic";
- VERSION_INFO_BUILDER = "$(USER)";
- };
- name = DebugPresubmission;
- };
- 940AD5261B1FE3B10051E88F /* DebugPresubmission */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
- CLANG_CXX_LIBRARY = "libc++";
- "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-entitlements.plist";
- "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "source/debugserver-macosx-entitlements.plist";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
- "CODE_SIGN_IDENTITY[sdk=macosx*]" = "";
- COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 360.99.0;
- FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks;
- "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = (
- "$(SDKROOT)/System/Library/PrivateFrameworks",
- "$(SDKROOT)/Developer/Library/PrivateFrameworks",
- );
- "FRAMEWORK_SEARCH_PATHS[sdk=macosx*][arch=*]" = "$(SDKROOT)/System/Library/PrivateFrameworks";
- GCC_C_LANGUAGE_STANDARD = c99;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_PREPROCESSOR_DEFINITIONS = LLDB_DEBUGSERVER_DEBUG;
- GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
- INSTALL_PATH = /usr/bin;
- LLDB_COMPRESSION_LDFLAGS = "-lcompression";
- LLDB_DEBUGSERVER = 1;
- LLDB_ENERGY_CFLAGS = "";
- "LLDB_ENERGY_CFLAGS[sdk=*.internal]" = "-DLLDB_ENERGY";
- LLDB_ENERGY_LDFLAGS = "-lpmenergy -lpmsample";
- OTHER_CFLAGS = (
- "-Wparentheses",
- "$(LLDB_ENERGY_CFLAGS)",
- "$(LLDB_OS_LOG_CFLAGS)",
- );
- "OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
- "-Wparentheses",
- "-DWITH_LOCKDOWN",
- "-DWITH_FBS",
- "-DWITH_BKS",
- "-DOS_OBJECT_USE_OBJC=0",
- "$(LLDB_ENERGY_CFLAGS)",
- "$(LLDB_OS_LOG_CFLAGS)",
- "-isystem",
- "$(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders",
- );
- "OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
- "OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
- "-framework",
- SpringBoardServices,
- "-framework",
- BackBoardServices,
- "-llockdown",
- "-framework",
- FrontBoardServices,
- "-framework",
- MobileCoreServices,
- "$(LLDB_ENERGY_LDFLAGS)",
- "$(LLDB_COMPRESSION_LDFLAGS)",
- );
- "OTHER_LDFLAGS[sdk=macosx*]" = (
- "-sectcreate",
- __TEXT,
- __info_plist,
- "$(PROJECT_DIR)/resources/lldb-debugserver-Info.plist",
- "$(LLDB_ENERGY_LDFLAGS)",
- "$(LLDB_COMPRESSION_LDFLAGS)",
- );
- OTHER_MIGFLAGS = "-I$(DERIVED_FILE_DIR)";
- PRODUCT_NAME = debugserver;
- "PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
- "PROVISIONING_PROFILE[sdk=macosx*]" = "";
- SDKROOT = macosx;
- SKIP_INSTALL = YES;
- USER_HEADER_SEARCH_PATHS = "./source ../../source $(DERIVED_SOURCES_DIR) ../../include";
- ZERO_LINK = NO;
- };
- name = DebugPresubmission;
- };
- 940AD5271B1FE3B10051E88F /* DebugPresubmission */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
- CLANG_CXX_LIBRARY = "libc++";
- "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-entitlements.plist";
- "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "source/debugserver-macosx-entitlements.plist";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
- "CODE_SIGN_IDENTITY[sdk=macosx*]" = "";
- COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 360.99.0;
- FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks;
- "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = (
- "$(SDKROOT)/System/Library/PrivateFrameworks",
- "$(SDKROOT)/Developer/Library/PrivateFrameworks",
- );
- "FRAMEWORK_SEARCH_PATHS[sdk=macosx*][arch=*]" = "$(SDKROOT)/System/Library/PrivateFrameworks";
- GCC_C_LANGUAGE_STANDARD = c99;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_PREPROCESSOR_DEFINITIONS = LLDB_DEBUGSERVER_DEBUG;
- GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
- INSTALL_PATH = /usr/local/bin;
- LLDB_DEBUGSERVER = 1;
- LLDB_ENERGY_CFLAGS = "";
- "LLDB_ENERGY_CFLAGS[sdk=*.internal]" = "-DLLDB_ENERGY";
- LLDB_ENERGY_LDFLAGS = "-lpmenergy -lpmsample";
- OTHER_CFLAGS = (
- "-Wparentheses",
- "$(LLDB_ENERGY_CFLAGS)",
- "-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui",
- "$(LLDB_OS_LOG_CFLAGS)",
- );
- "OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
- "-Wparentheses",
- "-DOS_OBJECT_USE_OBJC=0",
- "-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui",
- "$(LLDB_OS_LOG_CFLAGS)",
- );
- "OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
- "OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
- "-framework",
- Foundation,
- );
- "OTHER_LDFLAGS[sdk=macosx*]" = (
- "-sectcreate",
- __TEXT,
- __info_plist,
- "$(PROJECT_DIR)/resources/lldb-debugserver-Info.plist",
- "$(LLDB_ENERGY_LDFLAGS)",
- );
- OTHER_MIGFLAGS = "-I$(DERIVED_FILE_DIR)";
- PRODUCT_NAME = "debugserver-nonui";
- "PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
- "PROVISIONING_PROFILE[sdk=macosx*]" = "";
- SDKROOT = macosx;
- SKIP_INSTALL = YES;
- USER_HEADER_SEARCH_PATHS = "./source ../../source $(DERIVED_SOURCES_DIR) ../../include";
- ZERO_LINK = NO;
- };
- name = DebugPresubmission;
- };
- 94BA9B361B1A7C5700035A23 /* CustomSwift-Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- PRODUCT_NAME = "lldb-debugserver-nonui";
- };
- name = "CustomSwift-Debug";
- };
- 94BA9B371B1A7C5700035A23 /* CustomSwift-Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- PRODUCT_NAME = "lldb-debugserver-nonui";
- };
- name = "CustomSwift-Release";
- };
- 94D72C871ADF10AA00A3F718 /* CustomSwift-Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- "ARCHS[sdk=iphoneos*]" = arm64;
- "ARCHS[sdk=macosx*]" = "$(ARCHS_STANDARD_64_BIT)";
- CLANG_WARN_BOOL_CONVERSION = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_UNREACHABLE_CODE = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- CODE_SIGN_IDENTITY = "";
- COPY_PHASE_STRIP = NO;
- CURRENT_PROJECT_VERSION = 360.99.0;
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- GCC_NO_COMMON_BLOCKS = YES;
- GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- LLDB_COMPRESSION_LDFLAGS = "-lcompression";
- LLDB_OS_LOG_CFLAGS = "-DLLDB_USE_OS_LOG=$(LLDB_USE_OS_LOG)";
- LLDB_USE_OS_LOG = 0;
- ONLY_ACTIVE_ARCH = YES;
- SDKROOT = macosx;
- STRIP_INSTALLED_PRODUCT = NO;
- VERSIONING_SYSTEM = "apple-generic";
- VERSION_INFO_BUILDER = "$(USER)";
- };
- name = "CustomSwift-Debug";
- };
- 94D72C881ADF10AA00A3F718 /* CustomSwift-Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
- CLANG_CXX_LIBRARY = "libc++";
- "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-entitlements.plist";
- "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "source/debugserver-macosx-entitlements.plist";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
- "CODE_SIGN_IDENTITY[sdk=macosx*]" = "";
- COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 360.99.0;
- FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks;
- "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = (
- "$(SDKROOT)/System/Library/PrivateFrameworks",
- "$(SDKROOT)/Developer/Library/PrivateFrameworks",
- );
- "FRAMEWORK_SEARCH_PATHS[sdk=macosx*][arch=*]" = "$(SDKROOT)/System/Library/PrivateFrameworks";
- GCC_C_LANGUAGE_STANDARD = c99;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_PREPROCESSOR_DEFINITIONS = LLDB_DEBUGSERVER_DEBUG;
- GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
- INSTALL_PATH = /usr/bin;
- LLDB_COMPRESSION_LDFLAGS = "-lcompression";
- LLDB_DEBUGSERVER = 1;
- LLDB_ENERGY_CFLAGS = "";
- "LLDB_ENERGY_CFLAGS[sdk=*.internal]" = "-DLLDB_ENERGY";
- LLDB_ENERGY_LDFLAGS = "-lpmenergy -lpmsample";
- OTHER_CFLAGS = (
- "-Wparentheses",
- "-DDT_VARIANT_$(DT_VARIANT)",
- "$(LLDB_ENERGY_CFLAGS)",
- "$(LLDB_OS_LOG_CFLAGS)",
- );
- "OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
- "-Wparentheses",
- "-DWITH_LOCKDOWN",
- "-DWITH_BKS",
- "-DWITH_FBS",
- "-DOS_OBJECT_USE_OBJC=0",
- "$(LLDB_ENERGY_CFLAGS)",
- "$(LLDB_OS_LOG_CFLAGS)",
- "-isystem",
- "$(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders",
- );
- "OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
- OTHER_LDFLAGS = "";
- "OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
- "-framework",
- SpringBoardServices,
- "-framework",
- BackBoardServices,
- "-llockdown",
- "-framework",
- FrontBoardServices,
- "-framework",
- MobileCoreServices,
- "$(LLDB_ENERGY_LDFLAGS)",
- "$(LLDB_COMPRESSION_LDFLAGS)",
- );
- "OTHER_LDFLAGS[sdk=macosx*]" = (
- "-sectcreate",
- __TEXT,
- __info_plist,
- "$(PROJECT_DIR)/resources/lldb-debugserver-Info.plist",
- "$(LLDB_ENERGY_LDFLAGS)",
- "$(LLDB_COMPRESSION_LDFLAGS)",
- );
- OTHER_MIGFLAGS = "-I$(DERIVED_FILE_DIR)";
- PRODUCT_NAME = debugserver;
- "PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
- "PROVISIONING_PROFILE[sdk=macosx*]" = "";
- SDKROOT = macosx;
- SKIP_INSTALL = YES;
- USER_HEADER_SEARCH_PATHS = "./source ../../source $(DERIVED_SOURCES_DIR) ../../include";
- ZERO_LINK = NO;
- };
- name = "CustomSwift-Debug";
- };
- 94D72C891ADF10B000A3F718 /* CustomSwift-Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- "ARCHS[sdk=iphoneos*]" = arm64;
- "ARCHS[sdk=macosx*]" = "$(ARCHS_STANDARD_64_BIT)";
- CLANG_WARN_BOOL_CONVERSION = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_UNREACHABLE_CODE = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- CURRENT_PROJECT_VERSION = 360.99.0;
- DEAD_CODE_STRIPPING = YES;
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- GCC_NO_COMMON_BLOCKS = YES;
- GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- LLDB_COMPRESSION_LDFLAGS = "-lcompression";
- LLDB_OS_LOG_CFLAGS = "-DLLDB_USE_OS_LOG=$(LLDB_USE_OS_LOG)";
- LLDB_USE_OS_LOG = 0;
- ONLY_ACTIVE_ARCH = YES;
- SDKROOT = macosx;
- STRIPFLAGS = "-x";
- STRIP_STYLE = debugging;
- VERSIONING_SYSTEM = "apple-generic";
- VERSION_INFO_BUILDER = "$(USER)";
- };
- name = "CustomSwift-Release";
- };
- 94D72C8A1ADF10B000A3F718 /* CustomSwift-Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
- CLANG_CXX_LIBRARY = "libc++";
- "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-entitlements.plist";
- "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "source/debugserver-macosx-entitlements.plist";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
- "CODE_SIGN_IDENTITY[sdk=macosx*]" = "";
- COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 360.99.0;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks;
- "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = (
- "$(SDKROOT)/System/Library/PrivateFrameworks",
- "$(SDKROOT)/Developer/Library/PrivateFrameworks",
- );
- "FRAMEWORK_SEARCH_PATHS[sdk=macosx*][arch=*]" = "$(SDKROOT)/System/Library/PrivateFrameworks";
- GCC_C_LANGUAGE_STANDARD = c99;
- GCC_PREPROCESSOR_DEFINITIONS = LLDB_DEBUGSERVER_RELEASE;
- GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
- HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders;
- INSTALL_PATH = /usr/bin;
- LLDB_COMPRESSION_LDFLAGS = "-lcompression";
- LLDB_DEBUGSERVER = 1;
- LLDB_ENERGY_CFLAGS = "";
- "LLDB_ENERGY_CFLAGS[sdk=*.internal]" = "-DLLDB_ENERGY";
- LLDB_ENERGY_LDFLAGS = "-lpmenergy -lpmsample";
- OTHER_CFLAGS = (
- "-Wparentheses",
- "-DDT_VARIANT_$(DT_VARIANT)",
- "$(LLDB_ENERGY_CFLAGS)",
- "$(LLDB_OS_LOG_CFLAGS)",
- );
- "OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
- "-Wparentheses",
- "-DWITH_LOCKDOWN",
- "-DWITH_FBS",
- "-DWITH_BKS",
- "-DOS_OBJECT_USE_OBJC=0",
- "$(LLDB_ENERGY_CFLAGS)",
- "$(LLDB_OS_LOG_CFLAGS)",
- "-isystem",
- "$(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders",
- );
- "OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
- "OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
- "-framework",
- SpringBoardServices,
- "-framework",
- BackBoardServices,
- "-llockdown",
- "-framework",
- FrontBoardServices,
- "-framework",
- MobileCoreServices,
- "$(LLDB_ENERGY_LDFLAGS)",
- "$(LLDB_COMPRESSION_LDFLAGS)",
- );
- "OTHER_LDFLAGS[sdk=macosx*]" = (
- "-sectcreate",
- __TEXT,
- __info_plist,
- "$(PROJECT_DIR)/resources/lldb-debugserver-Info.plist",
- "$(LLDB_ENERGY_LDFLAGS)",
- "$(LLDB_COMPRESSION_LDFLAGS)",
- );
- OTHER_MIGFLAGS = "-I$(DERIVED_FILE_DIR)";
- PRODUCT_NAME = debugserver;
- "PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
- "PROVISIONING_PROFILE[sdk=macosx*]" = "";
- SDKROOT = macosx;
- SKIP_INSTALL = YES;
- USER_HEADER_SEARCH_PATHS = "./source ../../source $(DERIVED_SOURCES_DIR) ../../include";
- ZERO_LINK = NO;
- };
- name = "CustomSwift-Release";
- };
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
- 1DEB914E08733D8E0010E9CD /* Build configuration list for PBXProject "debugserver" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 1DEB914F08733D8E0010E9CD /* Debug */,
- 94D72C871ADF10AA00A3F718 /* CustomSwift-Debug */,
- 4968B7A916657FAE00741ABB /* DebugClang */,
- 940AD5251B1FE3B10051E88F /* DebugPresubmission */,
- 1DEB915008733D8E0010E9CD /* Release */,
- 94D72C891ADF10B000A3F718 /* CustomSwift-Release */,
- 262419A11198A93E00067686 /* BuildAndIntegration */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = BuildAndIntegration;
- };
- 26CE05A4115C31ED0022F371 /* Build configuration list for PBXNativeTarget "debugserver" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 26CE0596115C31C30022F371 /* Debug */,
- 94D72C881ADF10AA00A3F718 /* CustomSwift-Debug */,
- 4968B7AA16657FAE00741ABB /* DebugClang */,
- 940AD5261B1FE3B10051E88F /* DebugPresubmission */,
- 26CE0597115C31C30022F371 /* Release */,
- 94D72C8A1ADF10B000A3F718 /* CustomSwift-Release */,
- 262419A21198A93E00067686 /* BuildAndIntegration */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = BuildAndIntegration;
- };
- 456F676D1AD46CE9002850C2 /* Build configuration list for PBXNativeTarget "debugserver-mini" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 456F676E1AD46CE9002850C2 /* Debug */,
- 456F676F1AD46CE9002850C2 /* DebugClang */,
- 940AD5271B1FE3B10051E88F /* DebugPresubmission */,
- 456F67701AD46CE9002850C2 /* Release */,
- 456F67711AD46CE9002850C2 /* BuildAndIntegration */,
- 94BA9B361B1A7C5700035A23 /* CustomSwift-Debug */,
- 94BA9B371B1A7C5700035A23 /* CustomSwift-Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = BuildAndIntegration;
- };
-/* End XCConfigurationList section */
- };
- rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
-}
diff --git a/tools/debugserver/debugserver.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/tools/debugserver/debugserver.xcodeproj/project.xcworkspace/contents.xcworkspacedata
deleted file mode 100644
index c24931480d46..000000000000
--- a/tools/debugserver/debugserver.xcodeproj/project.xcworkspace/contents.xcworkspacedata
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<Workspace
- version = "1.0">
- <FileRef
- location = "self:debugserver.xcodeproj">
- </FileRef>
-</Workspace>
diff --git a/tools/debugserver/debugserver.xcodeproj/xcshareddata/xcschemes/debugserver.xcscheme b/tools/debugserver/debugserver.xcodeproj/xcshareddata/xcschemes/debugserver.xcscheme
deleted file mode 100644
index 2f27b5e4eff5..000000000000
--- a/tools/debugserver/debugserver.xcodeproj/xcshareddata/xcschemes/debugserver.xcscheme
+++ /dev/null
@@ -1,110 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<Scheme
- LastUpgradeVersion = "0720"
- version = "1.8">
- <BuildAction
- parallelizeBuildables = "NO"
- buildImplicitDependencies = "YES">
- <BuildActionEntries>
- <BuildActionEntry
- buildForTesting = "YES"
- buildForRunning = "YES"
- buildForProfiling = "YES"
- buildForArchiving = "YES"
- buildForAnalyzing = "YES">
- <BuildableReference
- BuildableIdentifier = "primary"
- BlueprintIdentifier = "26CE0593115C31C20022F371"
- BuildableName = "debugserver"
- BlueprintName = "debugserver"
- ReferencedContainer = "container:debugserver.xcodeproj">
- </BuildableReference>
- </BuildActionEntry>
- </BuildActionEntries>
- </BuildAction>
- <TestAction
- buildConfiguration = "Debug"
- selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
- selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.GDB"
- shouldUseLaunchSchemeArgsEnv = "YES">
- <Testables>
- </Testables>
- <MacroExpansion>
- <BuildableReference
- BuildableIdentifier = "primary"
- BlueprintIdentifier = "26CE0593115C31C20022F371"
- BuildableName = "debugserver"
- BlueprintName = "debugserver"
- ReferencedContainer = "container:debugserver.xcodeproj">
- </BuildableReference>
- </MacroExpansion>
- <EnvironmentVariables>
- <EnvironmentVariable
- key = "UBBY"
- value = ""
- isEnabled = "YES">
- </EnvironmentVariable>
- </EnvironmentVariables>
- <AdditionalOptions>
- </AdditionalOptions>
- </TestAction>
- <LaunchAction
- buildConfiguration = "Debug"
- selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
- selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- displayScaleIsEnabled = "NO"
- displayScale = "1.00"
- launchStyle = "0"
- useCustomWorkingDirectory = "NO"
- ignoresPersistentStateOnLaunch = "NO"
- debugDocumentVersioning = "YES"
- debugServiceExtension = "internal"
- allowLocationSimulation = "YES"
- queueDebuggingEnabled = "No">
- <BuildableProductRunnable
- runnableDebuggingMode = "0">
- <BuildableReference
- BuildableIdentifier = "primary"
- BlueprintIdentifier = "26CE0593115C31C20022F371"
- BuildableName = "debugserver"
- BlueprintName = "debugserver"
- ReferencedContainer = "container:debugserver.xcodeproj">
- </BuildableReference>
- </BuildableProductRunnable>
- <AdditionalOptions>
- </AdditionalOptions>
- </LaunchAction>
- <ProfileAction
- displayScaleIsEnabled = "NO"
- displayScale = "1.00"
- buildConfiguration = "Release"
- shouldUseLaunchSchemeArgsEnv = "YES"
- savedToolIdentifier = ""
- useCustomWorkingDirectory = "NO"
- debugDocumentVersioning = "YES">
- <BuildableProductRunnable
- runnableDebuggingMode = "0">
- <BuildableReference
- BuildableIdentifier = "primary"
- BlueprintIdentifier = "26CE0593115C31C20022F371"
- BuildableName = "debugserver"
- BlueprintName = "debugserver"
- ReferencedContainer = "container:debugserver.xcodeproj">
- </BuildableReference>
- </BuildableProductRunnable>
- <EnvironmentVariables>
- <EnvironmentVariable
- key = "UBBY"
- value = ""
- isEnabled = "YES">
- </EnvironmentVariable>
- </EnvironmentVariables>
- </ProfileAction>
- <AnalyzeAction
- buildConfiguration = "Debug">
- </AnalyzeAction>
- <ArchiveAction
- buildConfiguration = "Release"
- revealArchiveInOrganizer = "YES">
- </ArchiveAction>
-</Scheme>
diff --git a/tools/debugserver/resources/lldb-debugserver-Info.plist b/tools/debugserver/resources/lldb-debugserver-Info.plist
deleted file mode 100644
index 343325c2765c..000000000000
--- a/tools/debugserver/resources/lldb-debugserver-Info.plist
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>CFBundleDevelopmentRegion</key>
- <string>English</string>
- <key>CFBundleIdentifier</key>
- <string>com.apple.debugserver</string>
- <key>CFBundleInfoDictionaryVersion</key>
- <string>6.0</string>
- <key>CFBundleName</key>
- <string>debugserver</string>
- <key>CFBundleVersion</key>
- <string>2</string>
- <key>SecTaskAccess</key>
- <array>
- <string>allowed</string>
- <string>debug</string>
- </array>
-</dict>
-</plist>
diff --git a/tools/debugserver/scripts/diagnose-termination.d b/tools/debugserver/scripts/diagnose-termination.d
deleted file mode 100644
index d216c9750033..000000000000
--- a/tools/debugserver/scripts/diagnose-termination.d
+++ /dev/null
@@ -1,18 +0,0 @@
-fbt::exception_deliver:entry
-{
- printf("pid %d got an exception of type %d\n", pid, arg1);
- stack();
- ustack();
-}
-
-syscall::kill:entry
-{
- printf("pid %d called kill(%d, %d)\n", pid, arg0, arg1);
- ustack();
-}
-
-syscall::__pthread_kill:entry
-{
- printf("pid %d called pthread_kill(%p, %d)\n", pid, arg0, arg1);
- ustack();
-}
diff --git a/tools/debugserver/source/ARM_DWARF_Registers.h b/tools/debugserver/source/ARM_DWARF_Registers.h
deleted file mode 100644
index 037d28bf1304..000000000000
--- a/tools/debugserver/source/ARM_DWARF_Registers.h
+++ /dev/null
@@ -1,206 +0,0 @@
-//===-- ARM_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 ARM_DWARF_Registers_h_
-#define ARM_DWARF_Registers_h_
-
-enum {
- dwarf_r0 = 0,
- dwarf_r1,
- dwarf_r2,
- dwarf_r3,
- dwarf_r4,
- dwarf_r5,
- dwarf_r6,
- dwarf_r7,
- dwarf_r8,
- dwarf_r9,
- dwarf_r10,
- dwarf_r11,
- dwarf_r12,
- dwarf_sp,
- dwarf_lr,
- dwarf_pc,
- dwarf_cpsr,
-
- dwarf_s0 = 64,
- dwarf_s1,
- dwarf_s2,
- dwarf_s3,
- dwarf_s4,
- dwarf_s5,
- dwarf_s6,
- dwarf_s7,
- dwarf_s8,
- dwarf_s9,
- dwarf_s10,
- dwarf_s11,
- dwarf_s12,
- dwarf_s13,
- dwarf_s14,
- dwarf_s15,
- dwarf_s16,
- dwarf_s17,
- dwarf_s18,
- dwarf_s19,
- dwarf_s20,
- dwarf_s21,
- dwarf_s22,
- dwarf_s23,
- dwarf_s24,
- dwarf_s25,
- dwarf_s26,
- dwarf_s27,
- dwarf_s28,
- dwarf_s29,
- dwarf_s30,
- dwarf_s31,
-
- // FPA Registers 0-7
- dwarf_f0 = 96,
- dwarf_f1,
- dwarf_f2,
- dwarf_f3,
- dwarf_f4,
- dwarf_f5,
- dwarf_f6,
- dwarf_f7,
-
- // Intel wireless MMX general purpose registers 0 - 7
- dwarf_wCGR0 = 104,
- dwarf_wCGR1,
- dwarf_wCGR2,
- dwarf_wCGR3,
- dwarf_wCGR4,
- dwarf_wCGR5,
- dwarf_wCGR6,
- dwarf_wCGR7,
-
- // XScale accumulator register 0–7 (they do overlap with wCGR0 - wCGR7)
- dwarf_ACC0 = 104,
- dwarf_ACC1,
- dwarf_ACC2,
- dwarf_ACC3,
- dwarf_ACC4,
- dwarf_ACC5,
- dwarf_ACC6,
- dwarf_ACC7,
-
- // Intel wireless MMX data registers 0 - 15
- dwarf_wR0 = 112,
- dwarf_wR1,
- dwarf_wR2,
- dwarf_wR3,
- dwarf_wR4,
- dwarf_wR5,
- dwarf_wR6,
- dwarf_wR7,
- dwarf_wR8,
- dwarf_wR9,
- dwarf_wR10,
- dwarf_wR11,
- dwarf_wR12,
- dwarf_wR13,
- dwarf_wR14,
- dwarf_wR15,
-
- dwarf_spsr = 128,
- dwarf_spsr_fiq,
- dwarf_spsr_irq,
- dwarf_spsr_abt,
- dwarf_spsr_und,
- dwarf_spsr_svc,
-
- dwarf_r8_usr = 144,
- dwarf_r9_usr,
- dwarf_r10_usr,
- dwarf_r11_usr,
- dwarf_r12_usr,
- dwarf_r13_usr,
- dwarf_r14_usr,
- dwarf_r8_fiq,
- dwarf_r9_fiq,
- dwarf_r10_fiq,
- dwarf_r11_fiq,
- dwarf_r12_fiq,
- dwarf_r13_fiq,
- dwarf_r14_fiq,
- dwarf_r13_irq,
- dwarf_r14_irq,
- dwarf_r13_abt,
- dwarf_r14_abt,
- dwarf_r13_und,
- dwarf_r14_und,
- dwarf_r13_svc,
- dwarf_r14_svc,
-
- // Intel wireless MMX control register in co-processor 0 - 7
- dwarf_wC0 = 192,
- dwarf_wC1,
- dwarf_wC2,
- dwarf_wC3,
- dwarf_wC4,
- dwarf_wC5,
- dwarf_wC6,
- dwarf_wC7,
-
- // VFP-v3/Neon
- dwarf_d0 = 256,
- dwarf_d1,
- dwarf_d2,
- dwarf_d3,
- dwarf_d4,
- dwarf_d5,
- dwarf_d6,
- dwarf_d7,
- dwarf_d8,
- dwarf_d9,
- dwarf_d10,
- dwarf_d11,
- dwarf_d12,
- dwarf_d13,
- dwarf_d14,
- dwarf_d15,
- dwarf_d16,
- dwarf_d17,
- dwarf_d18,
- dwarf_d19,
- dwarf_d20,
- dwarf_d21,
- dwarf_d22,
- dwarf_d23,
- dwarf_d24,
- dwarf_d25,
- dwarf_d26,
- dwarf_d27,
- dwarf_d28,
- dwarf_d29,
- dwarf_d30,
- dwarf_d31,
-
- // Neon quadword registers
- dwarf_q0 = 288,
- dwarf_q1,
- dwarf_q2,
- dwarf_q3,
- dwarf_q4,
- dwarf_q5,
- dwarf_q6,
- dwarf_q7,
- dwarf_q8,
- dwarf_q9,
- dwarf_q10,
- dwarf_q11,
- dwarf_q12,
- dwarf_q13,
- dwarf_q14,
- dwarf_q15
-};
-
-#endif // ARM_DWARF_Registers_h_
diff --git a/tools/debugserver/source/ARM_ehframe_Registers.h b/tools/debugserver/source/ARM_ehframe_Registers.h
deleted file mode 100644
index 9d644b7dc50b..000000000000
--- a/tools/debugserver/source/ARM_ehframe_Registers.h
+++ /dev/null
@@ -1,34 +0,0 @@
-//===-- ARM_ehframe_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_ARM_ehframe_Registers_h_
-#define utility_ARM_ehframe_Registers_h_
-
-enum {
- ehframe_r0 = 0,
- ehframe_r1,
- ehframe_r2,
- ehframe_r3,
- ehframe_r4,
- ehframe_r5,
- ehframe_r6,
- ehframe_r7,
- ehframe_r8,
- ehframe_r9,
- ehframe_r10,
- ehframe_r11,
- ehframe_r12,
- ehframe_sp,
- ehframe_lr,
- ehframe_pc,
- ehframe_cpsr
-};
-
-#endif // utility_ARM_ehframe_Registers_h_
diff --git a/tools/debugserver/source/CMakeLists.txt b/tools/debugserver/source/CMakeLists.txt
deleted file mode 100644
index 860a0289d22c..000000000000
--- a/tools/debugserver/source/CMakeLists.txt
+++ /dev/null
@@ -1,310 +0,0 @@
-include(CheckCXXCompilerFlag)
-include(CheckLibraryExists)
-include_directories(${CMAKE_CURRENT_BINARY_DIR}/..)
-include_directories(${LLDB_SOURCE_DIR}/source)
-include_directories(MacOSX/DarwinLog)
-
-include_directories(MacOSX)
-
-set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++ -Wl,-sectcreate,__TEXT,__info_plist,${CMAKE_CURRENT_SOURCE_DIR}/../resources/lldb-debugserver-Info.plist")
-
-check_cxx_compiler_flag("-Wno-gnu-zero-variadic-macro-arguments"
- CXX_SUPPORTS_NO_GNU_ZERO_VARIADIC_MACRO_ARGUMENTS)
-if (CXX_SUPPORTS_NO_GNU_ZERO_VARIADIC_MACRO_ARGUMENTS)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-gnu-zero-variadic-macro-arguments")
-endif ()
-
-check_cxx_compiler_flag("-Wno-zero-length-array"
- CXX_SUPPORTS_NO_ZERO_LENGTH_ARRAY)
-if (CXX_SUPPORTS_NO_ZERO_LENGTH_ARRAY)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-zero-length-array")
-endif ()
-
-check_cxx_compiler_flag("-Wno-extended-offsetof"
- CXX_SUPPORTS_NO_EXTENDED_OFFSETOF)
-if (CXX_SUPPORTS_NO_EXTENDED_OFFSETOF)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-extended-offsetof")
-endif ()
-
-check_library_exists(compression compression_encode_buffer "" HAVE_LIBCOMPRESSION)
-
-add_subdirectory(MacOSX)
-
-set(generated_mach_interfaces
- ${CMAKE_CURRENT_BINARY_DIR}/mach_exc.h
- ${CMAKE_CURRENT_BINARY_DIR}/mach_excServer.c
- ${CMAKE_CURRENT_BINARY_DIR}/mach_excUser.c
- )
-add_custom_command(OUTPUT ${generated_mach_interfaces}
- COMMAND mig ${CMAKE_CURRENT_SOURCE_DIR}/MacOSX/dbgnub-mig.defs
- DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/MacOSX/dbgnub-mig.defs
- )
-
-set(DEBUGSERVER_VERS_GENERATED_FILE ${CMAKE_CURRENT_BINARY_DIR}/debugserver_vers.c)
-set_source_files_properties(${DEBUGSERVER_VERS_GENERATED_FILE} PROPERTIES GENERATED 1)
-
-add_custom_command(OUTPUT ${DEBUGSERVER_VERS_GENERATED_FILE}
- COMMAND ${LLDB_SOURCE_DIR}/scripts/generate-vers.pl
- ${LLDB_SOURCE_DIR}/lldb.xcodeproj/project.pbxproj debugserver
- > ${DEBUGSERVER_VERS_GENERATED_FILE}
- DEPENDS ${LLDB_SOURCE_DIR}/scripts/generate-vers.pl
- ${LLDB_SOURCE_DIR}/lldb.xcodeproj/project.pbxproj
- )
-
-set(lldbDebugserverCommonSources
- DNBArch.cpp
- DNBBreakpoint.cpp
- DNB.cpp
- DNBDataRef.cpp
- DNBError.cpp
- DNBLog.cpp
- DNBRegisterInfo.cpp
- DNBThreadResumeActions.cpp
- JSON.cpp
- StdStringExtractor.cpp
- # JSON reader depends on the following LLDB-common files
- ${LLDB_SOURCE_DIR}/source/Host/common/StringConvert.cpp
- ${LLDB_SOURCE_DIR}/source/Host/common/SocketAddress.cpp
- # end JSON reader dependencies
- libdebugserver.cpp
- PseudoTerminal.cpp
- PThreadEvent.cpp
- PThreadMutex.cpp
- RNBContext.cpp
- RNBRemote.cpp
- RNBServices.cpp
- RNBSocket.cpp
- SysSignal.cpp
- TTYState.cpp
-
- MacOSX/CFBundle.cpp
- MacOSX/CFString.cpp
- MacOSX/Genealogy.cpp
- MacOSX/MachException.cpp
- MacOSX/MachProcess.mm
- MacOSX/MachTask.mm
- MacOSX/MachThread.cpp
- MacOSX/MachThreadList.cpp
- MacOSX/MachVMMemory.cpp
- MacOSX/MachVMRegion.cpp
- MacOSX/OsLogger.cpp
- ${generated_mach_interfaces}
- ${DEBUGSERVER_VERS_GENERATED_FILE})
-
-add_library(lldbDebugserverCommon ${lldbDebugserverCommonSources})
-
-# LLDB-specific identity, currently used for code signing debugserver.
-set(LLDB_CODESIGN_IDENTITY "" CACHE STRING
- "Override code sign identity for debugserver and for use in tests; falls back to LLVM_CODESIGNING_IDENTITY if set or lldb_codesign otherwise (Darwin only)")
-
-# Determine which identity to use and store it in the separate cache entry.
-# We will query it later for LLDB_TEST_COMMON_ARGS.
-if(LLDB_CODESIGN_IDENTITY)
- set(LLDB_CODESIGN_IDENTITY_USED ${LLDB_CODESIGN_IDENTITY} CACHE INTERNAL "" FORCE)
-elseif(LLVM_CODESIGNING_IDENTITY)
- set(LLDB_CODESIGN_IDENTITY_USED ${LLVM_CODESIGNING_IDENTITY} CACHE INTERNAL "" FORCE)
-else()
- set(LLDB_CODESIGN_IDENTITY_USED lldb_codesign CACHE INTERNAL "" FORCE)
-endif()
-
-# Override locally, so the identity is used for targets created in this scope.
-set(LLVM_CODESIGNING_IDENTITY ${LLDB_CODESIGN_IDENTITY_USED})
-
-option(LLDB_NO_DEBUGSERVER "Disable the debugserver target" OFF)
-option(LLDB_USE_SYSTEM_DEBUGSERVER "Use the system's debugserver instead of building it from source (Darwin only)." OFF)
-
-# Incompatible options
-if(LLDB_NO_DEBUGSERVER AND LLDB_USE_SYSTEM_DEBUGSERVER)
- message(FATAL_ERROR "Inconsistent options: LLDB_NO_DEBUGSERVER and LLDB_USE_SYSTEM_DEBUGSERVER")
-endif()
-
-# Try to locate the system debugserver.
-# Subsequent feasibility checks depend on it.
-if(APPLE AND CMAKE_HOST_APPLE)
- execute_process(
- COMMAND xcode-select -p
- OUTPUT_VARIABLE xcode_dev_dir)
- string(STRIP ${xcode_dev_dir} xcode_dev_dir)
-
- set(debugserver_rel_path "LLDB.framework/Resources/debugserver")
- set(debugserver_shared "${xcode_dev_dir}/../SharedFrameworks/${debugserver_rel_path}")
- set(debugserver_private "${xcode_dev_dir}/Library/PrivateFrameworks/${debugserver_rel_path}")
-
- if(EXISTS ${debugserver_shared})
- set(system_debugserver ${debugserver_shared})
- elseif(EXISTS ${debugserver_private})
- set(system_debugserver ${debugserver_private})
- endif()
-endif()
-
-# Handle unavailability
-if(LLDB_USE_SYSTEM_DEBUGSERVER)
- if(system_debugserver)
- set(use_system_debugserver ON)
- elseif(APPLE AND CMAKE_HOST_APPLE)
- # Binary not found on system. Keep cached variable, to try again on reconfigure.
- message(SEND_ERROR
- "LLDB_USE_SYSTEM_DEBUGSERVER option set, but no debugserver found in:\
- ${debugserver_shared}\
- ${debugserver_private}")
- else()
- # Non-Apple target platform or non-Darwin host. Reset invalid cached variable.
- message(WARNING "Reverting invalid option LLDB_USE_SYSTEM_DEBUGSERVER (Darwin only)")
- set(LLDB_USE_SYSTEM_DEBUGSERVER OFF CACHE BOOL "" FORCE)
- endif()
-elseif(NOT LLDB_NO_DEBUGSERVER)
- # Default case: on Darwin we need the right code signing ID.
- # See lldb/docs/code-signing.txt for details.
- if(CMAKE_HOST_APPLE AND NOT LLVM_CODESIGNING_IDENTITY STREQUAL "lldb_codesign")
- set(problem "Cannot code sign debugserver with LLVM_CODESIGNING_IDENTITY '${LLVM_CODESIGNING_IDENTITY}'.")
- set(advice "Pass -DLLDB_CODESIGN_IDENTITY=lldb_codesign to override the LLVM value for debugserver.")
- if(system_debugserver)
- set(effect "Will fall back to system's debugserver.")
- set(use_system_debugserver ON)
- else()
- set(effect "debugserver will not be available.")
- endif()
- message(WARNING "${problem} ${effect} ${advice}")
- else()
- set(build_and_sign_debugserver ON)
- endif()
-endif()
-
-# TODO: We don't use the $<TARGET_FILE:debugserver> generator expression here,
-# because the value of DEBUGSERVER_PATH is used to build LLDB_DOTEST_ARGS,
-# which is used for configuring lldb-dotest.in, which does not have a generator
-# step at the moment.
-set(default_debugserver_path "${LLVM_RUNTIME_OUTPUT_INTDIR}/debugserver${CMAKE_EXECUTABLE_SUFFIX}")
-
-# Remember where debugserver binary goes and whether or not we have to test it.
-set(DEBUGSERVER_PATH "" CACHE FILEPATH "Path to debugserver")
-set(SKIP_TEST_DEBUGSERVER OFF CACHE BOOL "Building the in-tree debugserver was skipped")
-
-# Reset values in all cases in order to correctly support reconfigurations.
-if(use_system_debugserver)
- add_custom_target(debugserver
- COMMAND ${CMAKE_COMMAND} -E copy_if_different
- ${system_debugserver} ${LLVM_RUNTIME_OUTPUT_INTDIR}
- COMMENT "Copying the system debugserver to LLDB's binaries directory.")
-
- # Don't test debugserver itself.
- # Tests that require debugserver will use the copy.
- set(DEBUGSERVER_PATH ${default_debugserver_path} CACHE FILEPATH "" FORCE)
- set(SKIP_TEST_DEBUGSERVER ON CACHE BOOL "" FORCE)
-
- message(STATUS "Copy system debugserver from: ${system_debugserver}")
-elseif(build_and_sign_debugserver)
- # Build, sign and test debugserver (below)
- set(DEBUGSERVER_PATH ${default_debugserver_path} CACHE FILEPATH "" FORCE)
- set(SKIP_TEST_DEBUGSERVER OFF CACHE BOOL "" FORCE)
-
- message(STATUS "lldb debugserver: ${DEBUGSERVER_PATH}")
-else()
- # No tests for debugserver, no tests that require it.
- set(DEBUGSERVER_PATH "" CACHE FILEPATH "" FORCE)
- set(SKIP_TEST_DEBUGSERVER ON CACHE BOOL "" FORCE)
-
- message(STATUS "lldb debugserver will not be available.")
-endif()
-
-if(APPLE)
- if(IOS)
- find_library(BACKBOARD_LIBRARY BackBoardServices
- PATHS ${CMAKE_OSX_SYSROOT}/System/Library/PrivateFrameworks)
- find_library(FRONTBOARD_LIBRARY FrontBoardServices
- PATHS ${CMAKE_OSX_SYSROOT}/System/Library/PrivateFrameworks)
- find_library(SPRINGBOARD_LIBRARY SpringBoardServices
- PATHS ${CMAKE_OSX_SYSROOT}/System/Library/PrivateFrameworks)
- find_library(MOBILESERVICES_LIBRARY MobileCoreServices
- PATHS ${CMAKE_OSX_SYSROOT}/System/Library/PrivateFrameworks)
- find_library(LOCKDOWN_LIBRARY lockdown)
-
- if(NOT BACKBOARD_LIBRARY)
- set(SKIP_TEST_DEBUGSERVER ON CACHE BOOL "" FORCE)
- endif()
- else()
- find_library(COCOA_LIBRARY Cocoa)
- endif()
-endif()
-
-if(HAVE_LIBCOMPRESSION)
- set(LIBCOMPRESSION compression)
-endif()
-
-if(LLDB_USE_ENTITLEMENTS)
- if(IOS)
- set(entitlements ${CMAKE_CURRENT_SOURCE_DIR}/debugserver-entitlements.plist)
- else()
- # Same entitlements file as used for lldb-server
- set(entitlements ${LLDB_SOURCE_DIR}/resources/debugserver-macosx-entitlements.plist)
- endif()
-endif()
-
-if(build_and_sign_debugserver)
- target_link_libraries(lldbDebugserverCommon
- INTERFACE ${COCOA_LIBRARY}
- ${CORE_FOUNDATION_LIBRARY}
- ${FOUNDATION_LIBRARY}
- ${BACKBOARD_LIBRARY}
- ${FRONTBOARD_LIBRARY}
- ${SPRINGBOARD_LIBRARY}
- ${MOBILESERVICES_LIBRARY}
- ${LOCKDOWN_LIBRARY}
- lldbDebugserverArchSupport
- lldbDebugserverDarwin_DarwinLog
- ${LIBCOMPRESSION})
- if(HAVE_LIBCOMPRESSION)
- set_property(TARGET lldbDebugserverCommon APPEND PROPERTY
- COMPILE_DEFINITIONS HAVE_LIBCOMPRESSION)
- endif()
- set(LLVM_OPTIONAL_SOURCES ${lldbDebugserverCommonSources})
- add_lldb_tool(debugserver
- debugserver.cpp
-
- LINK_LIBS
- lldbDebugserverCommon
-
- ENTITLEMENTS
- ${entitlements}
- )
- if(IOS)
- set_property(TARGET lldbDebugserverCommon APPEND PROPERTY COMPILE_DEFINITIONS
- WITH_LOCKDOWN
- WITH_FBS
- WITH_BKS
- )
- set_property(TARGET debugserver APPEND PROPERTY COMPILE_DEFINITIONS
- WITH_LOCKDOWN
- WITH_FBS
- WITH_BKS
- )
- set_property(TARGET lldbDebugserverCommon APPEND PROPERTY COMPILE_FLAGS
- -F${CMAKE_OSX_SYSROOT}/System/Library/PrivateFrameworks
- )
- endif()
-endif()
-
-if(IOS)
- add_library(lldbDebugserverCommon_NonUI ${lldbDebugserverCommonSources})
- target_link_libraries(lldbDebugserverCommon_NonUI
- INTERFACE ${COCOA_LIBRARY}
- ${CORE_FOUNDATION_LIBRARY}
- ${FOUNDATION_LIBRARY}
- lldbDebugserverArchSupport
- lldbDebugserverDarwin_DarwinLog
- ${LIBCOMPRESSION})
- if(HAVE_LIBCOMPRESSION)
- set_property(TARGET lldbDebugserverCommon_NonUI APPEND PROPERTY
- COMPILE_DEFINITIONS HAVE_LIBCOMPRESSION)
- endif()
-
- add_lldb_tool(debugserver-nonui
- debugserver.cpp
-
- LINK_LIBS
- lldbDebugserverCommon_NonUI
-
- ENTITLEMENTS
- ${entitlements}
- )
-endif()
diff --git a/tools/debugserver/source/ChangeLog b/tools/debugserver/source/ChangeLog
deleted file mode 100644
index 898f2fba7b04..000000000000
--- a/tools/debugserver/source/ChangeLog
+++ /dev/null
@@ -1,1515 +0,0 @@
-2010-01-29 Greg Clayton <gclayton@apple.com>
-
- * MachProcess.cpp (MachProcess::PrepareForAttach): No longer use the
- SBSLaunchApplication macro from the SpringBoard.framework, use the actual
- function name SBSLaunchApplicationForDebugging.
- (MachProcess::CleanupAfterAttach): Ditto.
- (MachProcess::SBForkChildForPTraceDebugging): Ditto.
- (debugserver-entitlements.plist): Added the "seatbelt-profiles" entitlement
- so debugserver can be sandboxed.
-
-2009-07-06 Greg Clayton <gclayton@apple.com>
-
- * MachTask.cpp (MachTask::GetDYLDAllImageInfosAddress): Hack around bad
- kernel code that renamed the first member of the TASK_DYLD_INFO without
- any way to detect it has changed.
-
-2009-06-29 Greg Clayton <gclayton@apple.com>
-
- * DNB.cpp (GetAllInfosMatchingName): Correctly truncate process name string
- to MAXCOMLEN when searching kinfo_proc structs for process matches by name.
- * MachProcess.cpp (MachProcess::PrepareForAttach): Added logging when
- attaching to a program by name.
-
-2009-06-25 Greg Clayton <gclayton@apple.com>
-
- * DNB.cpp (DNBProcessLaunch): Added a stat on the incoming path that we are
- about to launch to make sure the file exists. If the file doesn't, then an
- appropriate error string is returned. Also if we fail to get the task for
- our process ID, we return an error string right away instead of letting the
- debug session go for a little bit and then later failing after a few more
- packets.
-
-2009-04-07 Jim Ingham <jingham@apple.com>
-
- * RNBRemote.h: Add vAttachWait
- * RNBRemote.cpp (RNBRemote::CreatePacketTable): Add vattachwait.
- (RNBRemoteShouldCancelCallback): New function.
- (RNBRemote::HandlePacket_v): Handle vattachwait.
- * RNBSocket.cpp (RNBSocket::Read): Mark the connection as closed when the
- port goes away.
- * DNB.cpp (DNBProcessAttachByName): New function.
- (DNBProcessAttach): Make this handle catching the attach when done and
- dealing with timeout & return conditions.
- (GetAllInfos): New function.
- (GetAlInfosMatchingName): New function.
- (DNBProcessAttachWait): New function.
- DNB.h: Declare DNBProcessAttachByName, DNBProcessAttachWait, change
- signature of DNBProcessAttach.
- * MachProcess.cpp (MachProcess::PrepareForAttach): New function.
- (MachProcess::CheckForProcess): New function.
- (MachProcess::CleanupAfterAttach): New function.
- (CopyBundleIDForPath): New function.
- (MachProcess::SBForkChildForPTraceDebugging): Convert to using
- CopyBundleIDForPath.
- * MachProcess.h: Declare PrepareForAttach, CleanupAfterAttach and
- CheckForProcess.
- * DNBTimer.h (TimeOfDayLaterThan): New function.
- * test-remotenub.cpp (RNBRunLoopGetStartModeFromRemote): Rename from
- RNBRunLoopGetArgsFromRemote, and handle vattachwait.
- (RNBRunLoopLaunchAttaching): Code was moved from here into DNBProcessAttach.
- (StartListening): New function.
- (GetAllProcessInfos, GetAllProcessInfosMatchingName): Moved to
- DNBProcess.cpp.
- (main): Handle attach waitfor, and make debugserver with only a host and
- port wait on commands from gdb.
-
-2009-04-03 Greg Clayton <gclayton@apple.com>
-
- * RNBRemote.h (PacketEnum): Added enum for qShlibInfoAddr.
- * RNBRemote.cpp (RNBRemote::CreatePacketTable) Added the qShlibInfoAddr
- packet definition to m_packets.
- (RNBRemote::GetPacket): Log when we run into an unimplemented packet.
- (RNBRemote::HandleReceivedPacket): Only log the packet when logging
- LOG_RNB_REMOTE.
- (RNBRemote::HandlePacket_q): Add support for the new qShlibInfoAddr packet.
- * DNB.h (DNBProcessGetSharedLibraryInfoAddress): New prototype.
- * DNB.cpp (DNBProcessGetSharedLibraryInfoAddress): New function.
- * MachTask.h (MachProcess::GetDYLDAllImageInfosAddress): New prototype.
- * MachTask.cpp (MachProcess::GetDYLDAllImageInfosAddress): New function.
-
-2009-04-01 Greg Clayton <gclayton@apple.com>
-
- * test-remotenub.cpp (main): Display the detailed error message if any when
- attaching fails.
-
-2009-03-25 Greg Clayton <gclayton@apple.com>
-
- * test-remotenub.cpp (RNBRunLoopGetArgsFromRemote): Cleaned up logging and
- removed time deltas form the messages.
- (RNBRunLoopLaunchAttaching): Ditto.
- (RNBRunLoopLaunchInferior): Ditto and also use new DNBProcessLaunch that
- takes an error string pointer.
- * RNBContext.h (class RNBContext): Removed the m_timer member.
- * RNBContext.cpp (RNBContext::StartProcessStatusThread): Cleaned up logging
- and removed time deltas form the messages.
- (RNBContext::ThreadFunctionProcessStatus): Ditto.
- * RNBSocket.h (class RNBSocket): Removed unused m_last_errno member and
- accessor functions.
- * RNBSocket.cpp (RNBSocket::Listen): Cleaned up logging and
- removed time deltas form the messages.
- (RNBSocket::ConnectToService): Ditto.
- (RNBSocket::Read): Ditto.
- (RNBSocket::Write): Ditto.
- (RNBSocket::SaveErrno): Removed.
- (RNBSocket::ClosePort): Don't call RNBSocket::SaveErrno().
- * RNBRemote.cpp (RNBRemote::RNBRemote): Cleaned up logging and
- removed time deltas form the messages.
- (RNBRemote::~RNBRemote): Ditto.
- (RNBRemote::SendPacket): Ditto.
- (RNBRemote::GetPacketPayload): Ditto.
- (RNBRemote::GetPacket): Ditto): Ditto.
- (RNBRemote::HandleAsyncPacket): Ditto.
- (RNBRemote::HandleReceivedPacket): Ditto.
- (RNBRemote::CommDataReceived): Ditto.
- * DNB.cpp (DNBProcessLaunch): Changed to take a eror string pointer with
- size for more desciptive error reporting (instead of a uint32_t pointer).
- * DNB.h (DNBProcessLaunch): Ditto.
- * DNBError.cpp (DNBError::AsString): Now returns NULL if there is no error.
- * DNBError.h (DNBError::SetErrorString): New accessor to allow custom error
- strings.
- * arm/DNBArchImpl.cpp (DNBArchMachARM::GetGPRState): Improved logging.
- * MachProcess.cpp (MachProcess::SBForkChildForPTraceDebugging): Improved
- error messages when a file doesn't exist, or when unable to extract the
- CFBundleIdentifier.
- * PThreadEvent.cpp (class PThreadEvent): Commented out all logging calls.
-
-2009-03-07 Greg Clayton <gclayton@apple.com>
-
- * test-remotenub.cpp (GetAllProcessInfosMatchingName): New function that
- returns matching kinfo_proc structs given a process name.
- (main): Enhanced the --attach option to be able to take a PROCNAME or
- a PID. Changed the --waitfor=PROCNAME option to ignore any existing
- processes with PROCNAME so we only catch new process invocations.
-
-2009-03-07 Greg Clayton <gclayton@apple.com>
-
- * RNBRemote.cpp (RNBRemote::HandlePacket_p): Use the correct get current
- thread function call so we get the correct thread registers.
-
-2009-03-03 Greg Clayton <gclayton@apple.com>
-
- * test-remotenub.cpp (g_isatty): New global that gets set to non-zero if
- STDOUT is a TTY in the beginning of main.
- (RNBLogSTDOUT): New macro that logs to STDOUT if g_isatty is non-zero, else
- it logs to asl.
- (RNBLogSTDERR): New macro that logs to STDERR if g_isatty is non-zero, else
- it logs to asl.
- (RNBRunLoopGetArgsFromRemote): Use new RNBLogSTDOUT/RNBLogSTDERR macros.
- (GetAllProcessInfos): Get all process info structs for everything on the
- system.
- (main): Implemented new --waitfor=NAME option to allow waiting for a process
- to run by polling the system processes. The new --waitfor-interval=N option
- allows fine control over the polling interval where N is the number of mirco
- seconds (usec) to wait between polls (defaults to 1000). The new
- --waitfor-duration=N allows a timeout in seconds to be specified when
- waiting for a process (defaults to infinite).
-
-2009-03-02 Greg Clayton <gclayton@apple.com>
-
- * DNBArchImpl.cpp (DNBArchMachARM::EvaluateNextInstructionForSoftwareBreakpointSetup):
- Take care of a case where no instructions execute in a Thumb IT block and
- the last of which is a branch.
-
-2009-02-10 Greg Clayton <gclayton@apple.com>
-
- * RNBRemote.h (PacketEnum): Added 'detach' enumeration.
- (RNBRemote::HandlePacket_D): New member function prototype.
- * RNBRemote.cpp (RNBRemote::CreatePacketTable): Added detach support.
- (RNBRemote::HandlePacket_D): New function for detach support.
-
-2009-02-10 Greg Clayton <gclayton@apple.com>
-
- * RNBRemote.cpp (RNBRemote::HandlePacket_UNIMPLEMENTED): Log this
- packet with the packet that is unimplemented.
- (RNBRemote::GetPacket): Call RNBRemote::HandlePacket_UNIMPLEMENTED()
- when we don't recognize a packet.
- (RNBRemote::HandleReceivedPacket): Don't reply to packets we don't
- recognize with unimplemented in this function as that should have
- already been done for us in RNBRemote::GetPacket().
-
-2009-02-10 Greg Clayton <gclayton@apple.com>
-
- * RNBRemote.h (PacketEnum): Added query_step_packet_supported.
- * RNBRemot.cpp (RNBRemote::CreatePacketTable): Added new
- qStepPacketSupported packet.
- (RNBRemote::HandlePacket_q): Added support for the new
- "qStepPacketSupported" packet.
- (RNBRemote::HandlePacket_G): Some cleanup when reading registers
- to avoid spurious console logging.
-
-2009-01-30 Greg Clayton <gclayton@apple.com>
-
- * debugserver-entitlements.plist: Changed the entitlement
- "run-invalid-allow" to "run-unsigned-code".
-
-2009-01-23 Greg Clayton <gclayton@apple.com>
-
- * DNBArchImpl.cpp (DNBArchMachARM::EvaluateNextInstructionForSoftwareBreakpointSetup):
- Merged Yusuf's changes to make software single stepping work.
- * test-remotenub.cpp (RNBRunLoopLaunchInferior): Call new
- DNBResolveExecutablePath function to resolve executable paths.
- * DNB.h (DNBResolveExecutablePath): New function prototype.
- * DNB.cpp (DNBResolveExecutablePath): New function that will resolve
- relative paths and also executable paths for executables that aren't relative
- but yet are in the shell PATH environment variable.
-
-2009-01-22 Greg Clayton <gclayton@apple.com>
-
- * DNBArchImpl.h (class DBNArchMachARM): Renamed member variable
- m_chained_hw_single_step_addr to m_hw_single_chained_step_addr. Added
- new member variables: m_sw_single_step_itblock_break_id, m_last_decode_pc,
- and m_sw_single_step_itblock_break_count. Renamed m_thumbStaticData to
- m_last_decode_thumb, and renamed m_decodedInstruction to m_last_decode_arm.
- (DBNArchMachARM::DecodeITBlockInstructions): New prototype.
- (DBNArchMachARM::DecodeInstructionUsingDisassembler): New prototype.
- (DBNArchMachARM::BreakpointHit): New prototype.
- * DNBArchImpl.cpp (DNBArchMachARM::ThreadDidStop): Disable any of the
- many software single step breakpoints if any are set.
- (DNBArchMachARM::StepNotComplete): Changed renamed member accesses.
- (DNBArchMachARM::DecodeITBlockInstructions): New function for software
- single stepping through Thumb IT blocks.
- (DNBArchMachARM::EnableHardwareSingleStep): Cleaned up logging.
- (DNBArchMachARM::ComputeNextPC): Ditto.
- (DNBArchMachARM::EvaluateNextInstructionForSoftwareBreakpointSetup): Now
- properly handles Thumb IT software single stepping.
- (DNBArchMachARM::SetSingleStepSoftwareBreakpoints): Ditto.
- (DNBArchMachARM::DecodeInstructionUsingDisassembler): New function.
- (DNBArchMachARM::BreakpointHit): New breakpoint callback function.
-
-2009-01-21 Greg Clayton <gclayton@apple.com>
-
- * MachProcess.cpp (MachProcess::PrivateResume): Set the process state before
- we actually resume so we are sure to get the events in the correct order.
-
-2009-01-16 Greg Clayton <gclayton@apple.com>
-
- * RNBRemote.cpp (RNBRemote::HandlePacket_last_signal): Include only
- registers which are to be expedited in the T packets.
- (RNBRemote::HandlePacket_p): Enable for all targets.
- (struct register_map_entry): Added an expedite member so we know which
- registers need to be sent up to the host with each stop reply packet.
- (register_map): Updated each array members' expedite member with an
- appropriate value.
-
-2009-01-16 Greg Clayton <gclayton@apple.com>
-
- * RNBRemote.cpp (RNBRemote::HandlePacket_s): Enabled the step command ("s"
- packet) for ARM now that libdebugnub.dylib can do both hardware and software
- single stepping.
-
-2009-01-13 Greg Clayton <gclayton@apple.com>
-
- *DNBArchImpl.cpp (bit): New function.
- (bits): New function.
- (DNBArchMachARM::ConditionPassed): Use new "bit" function.
- (DNBArchMachARM::ComputeNextPC): Use new "bit" function, remove inline
- assembly for "RSC" instruction so this compiles for armv7 (which defaults
- to thumb)
- (DNBArchMachARM::NumSupportedHardwareBreakpoints): Use new "bits" function.
- (DNBArchMachARM::NumSupportedHardwareWatchpoints): Use new "bits" function.
-
-2009-01-12 Greg Clayton <gclayton@apple.com>
-
- * DNBArch.h (DNBArchProtocol::NumSupportedHardwareBreakpoints()): Removed
- the "const" qualifier to allow arches to auto detect how many hardware
- breakpoints they have.
- (DNBArchProtocol::NumSupportedHardwareWatchpoints()): Removed the "const"
- qualifier to allow arches to auto detect how many hardware watchpoints they
- have.
- * DNBArchImpl.h (DNBArchMachARM::NumSupportedHardwareBreakpoints()): Auto
- detect how many BRP pairs are avialable and disable for armv7 for the time
- being (rdar://problem/6372672).
- (DNBArchMachARM::NumSupportedHardwareWatchpoints()): Auto detect how many
- WRP pairs are avialable and disable for armv7 for the time being
- (rdar://problem/6372672).
-
-2009-01-09 Greg Clayton <gclayton@apple.com>
-
- * test-remotenub.cpp (main): Filled in short argument versions for
- --applist (-t) and --lockdown (-k) options.
- * DNBArchImpl.h (DNBArchMachARM::ConditionPassed): New protected
- member function.
- (DNBArchMachARM::ComputeNextPC): New protected member function.
- (DNBArchMachARM::EvaluateNextInstructionForSoftwareBreakpointSetup): New
- protected member function.
- (DNBArchMachARM::m_thumbStaticData): New protected member variable.
- (DNBArchMachARM::m_decodedInstruction): New protected member variable.
- * DNBArchImpl.cpp (DNBArchMachARM::ThreadDidStop): Added extra code that
- will log and exit when we are verifying software single stepping (a
- compile time option).
- (DNBArchMachARM::ConditionPassed): New function.
- (DNBArchMachARM::ComputeNextPC): New function.
- (DNBArchMachARM::EvaluateNextInstructionForSoftwareBreakpointSetup): New
- function.
- (DNBArchMachARM::SetSingleStepSoftwareBreakpoints): Added the guts of the
- software single stepping.
- (DNBArchMachARM::NumSupportedHardwareBreakpoints): Prepared for adding
- auto detection code.
- (DNBArchMachARM::NumSupportedHardwareWatchpoints): Prepared for adding
- auto detection code.
-
-2008-12-11 Greg Clayton <gclayton@apple.com>
-
- * DNB.h (DNBProcessWaitForEvent): Renamed to DNBProcessWaitForEvents.
- (DNBProcessSetEvents): Removed (deprecated).
- (DNBProcessGetWaitForResetMask): Removed (unused).
- (DNBProcessSetWaitForResetMask): Removed (unused).
- (DNBProcessInterruptEvents): New function prototype.
- * DNB.cpp (DNBProcessWaitForEvent): Renamed to DNBProcessWaitForEvents.
- (DNBProcessSetEvents): Removed (deprecated).
- (DNBProcessGetWaitForResetMask): Removed (unused).
- (DNBProcessSetWaitForResetMask): Removed (unused).
- (DNBProcessInterruptEvents): New function that can be used to
- asynchronously interrupt infinite wait for events calls.
- RNBRemote.cpp (RNBRemote::HandlePacket_v): Call DNBProcessWaitForEvents.
- RNBContext.cpp (RNBContext::ThreadFunctionProcessStatus): Ditto.
- test-remotenub.cpp (RNBRunLoopLaunchInferior): Ditto.
- (RNBRunLoopLaunchAttaching): Ditto.
-
-2008-12-11 Greg Clayton <gclayton@apple.com>
-
- * DNB.cpp (GetProcessMap): Use new PTHREAD_MUTEX_LOCKER macro to ease
- debugging of deadlocks.
- (DNBProcessLaunch): Improved logging.
- (DNBProcessMemoryRead): Call MachProcess::ReadMemory so breakpoint
- opcodes can be removed from memory.
- (DNBProcessMemoryWrite): Call MachProcess::WriteMemory so that we work
- around enabled software breakpoint traps.
- * DNBLog.cpp (GetLogThreadedMutex): New function.
- (_DNBLogThreaded): Use new PTHREAD_MUTEX_LOCKER macro to ease
- debugging of deadlocks.
- (_DNBLogThreadedIf): Ditto.
- * DNBBreakpoint.h (DNBBreakpoint::IntersectsRange): New function.
- * DNBBreakpoint.cpp (DNBBreakpointList::FindIDByAddress): Improved
- logging.
- * MacOSX/MachThread.cpp (MachThread::MachThread): Improved logging.
- (MachThread::~MachThread): Ditto.
- (MachThread::Suspend): Ditto.
- (MachThread::Resume): Ditto.
- (MachThread::RestoreSuspendCount): Ditto.
- (MachThread::GetState): Use new PTHREAD_MUTEX_LOCKER macro to ease
- debugging of deadlocks.
- (MachThread::SetState): Ditto.
- * MacOSX/MachVMMemory.cpp (MachVMMemory::Read): Improved logging.
- (MachVMMemory::Write): Ditto.
- (MachVMMemory::WriteRegion): Ditto.
- * MacOSX/MachProcess.cpp (MachProcess::GetState): Use new
- PTHREAD_MUTEX_LOCKER macro to ease debugging of deadlocks.
- (MachProcess::SetState): Ditto.
- (MachProcess::Clear): Ditto.
- (MachProcess::PrivateResume): Ditto.
- (MachProcess::ReplyToAllExceptions): Ditto.
- (MachProcess::ExceptionMessageReceived): Ditto.
- (MachProcess::AppendSTDOUT): Ditto.
- (MachProcess::GetAvailableSTDOUT): Ditto.
- (MachProcess::ThreadFunctionSTDIO): Renamed from to
- MachProcess::STDIOThread.
- (MachProcess::StartSTDIOThread): Improved logging.
- (MachProcess::CreateBreakpoint): Ditto.
- (MachProcess::CreateWatchpoint): Ditto.
- (MachProcess::DisableAllBreakpoints): Ditto.
- (MachProcess::DisableBreakpoint): Ditto.
- (MachProcess::DisableWatchpoint): Ditto.
- (MachProcess::EnableBreakpoint): Ditto.
- (MachProcess::EnableWatchpoint): Ditto.
- (MachProcess::LaunchForDebug): Ditto.
- (MachProcess::PosixSpawnChildForPTraceDebugging): Ditto.
- (MachProcess::Detach): Reset the running event bit after resuming prior
- to issuing the SIGSTOP to avoid a pause.
- (MachProcess::RemoveTrapsFromBuffer): New function that removes
- breakpoint traps from a memory buffer.
- (MachProcess::ReadMemory): Read memory from the task, then removes any
- breakpoint traps prior to returning the buffer.
- (MachProcess::WriteMemory): Write memory and any needed data to the
- breakpoint saved opcodes for any software breakpoint traps that are
- enabled.
- * MacOSX/MachProcess.h (MachProcess::ThreadFunctionException): Removed.
- (MachProcess::ThreadFunctionSTDIO): Renamed to MachProcess::STDIOThread().
- (MachProcess::RemoveTrapsFromBuffer): New function.
- * MacOSX/MachVMRegion.cpp (MachVMRegion::SetProtections): Improved
- logging.
- (MachVMRegion::RestoreProtections): Ditto.
- (MachVMRegion::GetRegionForAddress): Ditto.
- * MacOSX/MachException.cpp (catch_mach_exception_raise_state): Improved
- logging.
- (catch_mach_exception_raise_state_identity): Ditto.
- (catch_mach_exception_raise): Ditto.
- (MachException::Message::Dump): Ditto.
- (MachException::Data::GetStopInfo): Ditto.
- (MachException::Message::Receive): Ditto.
- (MachException::Message::Reply): Ditto.
- (MachException::Data::Dump): Ditto.
- (MachException::PortInfo::Save): Ditto.
- (MachException::PortInfo::Restore): Ditto.
- * MacOSX/MachTask.cpp (MachTask::Suspend): Improved logging.
- (MachTask::Resume): Ditto.
- (MachTask::ReadMemory): Ditto.
- (MachTask::WriteMemory): Ditto.
- (MachTask::TaskPortForProcessID): Ditto.
- (MachTask::BasicInfo): Ditto.
- (MachTask::StartExceptionThread): Ditto.
- (MachTask::ShutDownExcecptionThread): Ditto and use pthread_cancel to
- interrupt the exception thread.
- (MachTask::ExceptionThread): Ditto and revert back to infinite timeout
- as pthread_cancel will break us out of infinite mach_msg receive calls.
- * MacOSX/MachThreadList.cpp (MachThreadList::UpdateThreadList): Improved
- logging.
- (MachThreadList::CurrentThread): Use new PTHREAD_MUTEX_LOCKER macro to
- ease debugging of deadlocks.
- * DNBTimer.h (DNBTimer::DNBTimer): Initialize the mutex with a recursive
- pthread.
- (DNBTimer::Reset): Use new PTHREAD_MUTEX_LOCKER macro to ease debugging
- of deadlocks.
- (DNBTimer::TotalMicroSeconds): Ditto.
- (DNBTimer::GetTime): Ditto.
- (DNBTimer::ElapsedMicroSeconds): Ditto.
- (DNBTimer::GetTimeOfDay): New class function.
- * DNBError.cpp (DNBError::LogThreaded): Improved logging.
- * test-dbgnub.cpp
- * PThreadMutex.h: Added the ability to debug deadlocks by defining
- DEBUG_PTHREAD_MUTEX_DEADLOCKS.
- * FunctionProfiler.cpp
- * PThreadEvent.cpp (PThreadEvent::NewEventBit): Use new
- PTHREAD_MUTEX_LOCKER macro to ease debugging of deadlocks.
- (PThreadEvent::FreeEventBits): Ditto.
- (PThreadEvent::GetEventBits): Ditto.
- (PThreadEvent::ReplaceEventBits): Ditto.
- (PThreadEvent::SetEvents): Ditto.
- (PThreadEvent::ResetEvents): Ditto.
- (PThreadEvent::WaitForSetEvents): Ditto.
- (PThreadEvent::WaitForEventsToReset): Ditto.
-
-2008-12-05 Greg Clayton <gclayton@apple.com>
-
- * DNBDefs.h (LOG_TASK): New log bit.
- * DNB.cpp (DNBProcessIsAlive): User newly abstracted MachTask class.
- (DNBProcessMemoryRead): Ditto.
- (DNBProcessMemoryWrite): Ditto.
- * DNBArchImpl.cpp (DNBArchMachARM::EnableHardwareSingleStep): Ditto.
- (DNBArchMachARM::SetSingleStepSoftwareBreakpoints) Ditto.
- * MachException.cpp (MachException::Message::Receive): Cleaned up logging
- so it doesn't always log timeout errors.
- (MachException::Message::Reply): Use abstracted MachTask class for any
- task related queries.
- (MachException::PortInfo::Save): Cleaned up logging.
- (MachException::PortInfo::Restore): Cleaned up logging and now return an
- error instead of the number of restored port infos.
- * MachProcess.cpp (class MachProcess): Abstracted out all of the task_t
- related stuff (suspend, resume, exception ports, exception thread, and
- more) into a new class MachTask.
- (MachProcess::Task): Now returns a reference to a MachTask class.
- (MachProcess::Clear): Uses new abstracted MachTask class.
- (MachProcess::Detach): Ditto.
- (MachProcess::PrivateResume): Ditto.
- (MachProcess::DisableBreakpoint): Ditto.
- (MachProcess::ExceptionMessageReceived): Ditto.
- (MachProcess::ExceptionMessageBundleComplete): Ditto.
- (MachProcess::AttachForDebug): Ditto.
- (MachProcess::LaunchForDebug): Ditto.
- (MachProcess::SBLaunchForDebug): Ditto.
- (MachProcess::TaskIsValid): Removed (replaced by similar functionality
- in the new MachTask class).
- (MachProcess::ExceptionPort): Ditto.
- (MachProcess::ExceptionPortIsValid): Ditto.
- (MachProcess::StartExceptionThread): Ditto.
- (MachProcess::Suspend): Ditto.
- (MachProcess::TaskResume): Ditto.
- (MachProcess::TaskBasicInfo): Ditto.
- (MachProcess::TaskBasicInfo): Ditto.
- (MachProcess::ReadMemory): Ditto.
- (MachProcess::WriteMemory): Ditto.
- (MachProcess::ThreadFunctionException): Ditto.
-
-2008-12-04 Greg Clayton <gclayton@apple.com>
-
- * DNB.h (DNBProcessSetEvents): New API function prototype.
- * DNB.cpp (DNBProcessSetEvents): New API function.
- (DNBProcessHalt): Send our process a SIGINT instead of suspending
- the task.
- * DNBDefs.h (NUB_STATE_IS_STOPPED): Removed up duplicate entry in macro.
- (eEventPrcoessAsyncInterrupt): New prcoess event bit that allows async
- interrupting of infinite DNBProcessWaitForEvent() function calls.
- * MachException.cpp (MachException::Message::Receive): Improved logging.
- (MachException::Message::Reply): Improved logging.
- * MachProcess.h (MachProcess::TaskBasicInfo): New member and static
- functions.
- * MachProcess.cpp (MachProcess::TaskIsValid): Use new TaskBasicInfo()
- member function.
- (MachProcess::Resume): Removed the detach parameter from the PrivateResume()
- function call.
- (MachProcess::Kill): Added a absolute timeout pointer to allow callers to
- wait for the signal to be received if the timeout is non-NULL.
- (MachProcess::TaskBasicInfo): New member and static function.
- (MachProcess::TaskResume): New function that resumes the task by making sure
- the suspend count is correctly ref counted.
- (MachProcess::Detach): When detaching from a process make sure it is
- stopped (SIGSTOP) first, then we can successfully detach. The exception
- thread now also properly exits.
- (MachProcess::PrivateResume): Call new TaskResume function, and removed the
- detach functionality.
- (MachProcess::DisableBreakpoint): Only notify the thread list that a
- breakpoint has changed if the breakpoint is going to be removed.
- (MachProcess::ThreadFunctionException): Added a permanent 1 second timeout
- for each call to mach_msg() so we can exit the thread in the event that
- we detach from a process/task.
- * test-debugnub (main): Modified to show an example of how to detach using
- a signal_handler to asynchronously receive a SIGINT and properly interrupt
- and detach from a running process.
-
-2008-11-26 Greg Clayton <gclayton@apple.com>
-
- * DNBDefs.h (LOG_STEP): New logging define.
- * DNBError.cpp (DNBError::LogThreaded): If there is no error, then
- log with "success: " as a prefix instead of "error: ".
- * arm/DBNArchImpl.cpp (DNBArchMachARM::EnableHardwareSingleStep): Log using
- new LOG_STEP instead of LOG_BREAKPOINTS.
- (DNBArchMachARM::SetSingleStepSoftwareBreakpoints): Ditto.
- * MachException.cpp (MachException::Message::Dump): Log exception header
- and reply header on two separate lines.
- * MachProcess.cpp (IsSBProcess): Check for NULL CFArrayRef returned from
- SBSCopyApplicationDisplayIdentifiers for SkankPhone.
- (MachProcess::Suspend): Check if process state is not running instead of
- having to receive an event after a timeout if one is given.
- (MachProcess::Detach): Deallocate the exception port when detaching and
- restore the inferior task exception ports prior to clearing and detaching.
- (MachProcess::PrivateResume): Grab the task's basic info and make sure we
- get the resume the correct number of times.
- (MachProcess::DisableBreakpoint): Removed unused variable opcode_restored
- and make sure the breakpoint is enabled before we start warning that
- our opcode wasn't there.
- * ppc/DBNArchImpl.cpp (DNBArchMachPPC::EnableHardwareSingleStep): Log
- using LOG_STEP instead of LOAD_BREAKPOINTS.
- * RNBServices.cpp (IsSBProcess): Check for NULL CFArrayRef returned from
- SBSCopyApplicationDisplayIdentifiers for SkankPhone.
-
-2008-11-26 Greg Clayton <gclayton@apple.com>
-
- * MachProcess.h (MachProcess::Suspend): Now takes an optional absolute
- timeout that, if non-NULL, will case the function to return after the
- process has been suspended and is in a stopped state. If the timeout is
- NULL, then no waiting will occur.
- * MachProcess.cpp (MachProcess::Suspend): Ditto.
- (MachProcess::Detach): Now replies to all exceptions, un-suspends all
- threads and resumes the task.
- (MachProcess::ReplyToAllExceptions): New function.
- (MachProcess::PrivateResume): Now takes an additional parameter named
- detach that will do the right thing when detaching from a process.
- * DNBArchImpl.h (DNBArchMachI386::ThreadWillResume): Returns void.
- * DNBArchImpl.cpp (DNBArchMachI386::ThreadWillResume): Returns void.
- * RNBServices.cpp (ListApplications): #ifdef-ed for ARM only as it
- currently uses SpringBoard.
- (IsSBProcess): Ditto.
- * test-remotenub.cpp (RNBRunLoopLaunchInferior): #ifdef-ed around
- ARM parts so it compiles for i386.
- (main): Ditto.
-
-2008-11-24 Greg Clayton <gclayton@apple.com>
-
- * DNBArchProtocol.h (DNBArchProtocol::ThreadWillResume): Now returns void.
- * DNBArchImpl.cpp (DNBArchMachARM::ThreadWillResume): Returns void and
- has hollowed out support for software single step.
- (DNBArchMachARM::ThreadDidStop): Has a debug mode that uses hardware single
- step to verify software single step that can be enabled by defining
- DNB_ARCH_MACH_ARM_DEBUG_SW_STEP.
- (DNBArchMachARM::SetSingleStepSoftwareBreakpoints): New function.
- * DNBArchImpl.h (DNBArchMachARM::ThreadWillResume): Returns void.
- (DNBArchMachARM::SetSingleStepSoftwareBreakpoints): New prototype.
- (DNBArchMachARM::m_sw_single_step_next_pc): New member variable.
- (DNBArchMachARM::m_sw_single_step_break_id): New member variable.
- * MachThread.cpp (MachThread::ThreadWillResume): Now returns void.
- * MachThread.h (MachThread::ThreadWillResume): Now returns void.
-
-2008-11-19 Greg Clayton <gclayton@apple.com>
-
- * DNBError.h (FlavorType): Added SpringBoard error type for arm builds.
- * DNBError.cpp (DNBError::AsString): Now returns SpringBoard error strings
- if the error type is SpringBoard.
- * test-remotenub.cpp (RNBRunLoopLaunchInferior): Set the error into
- RNBContext as either a POSIX error or a SpringBoard error.
- * RNBContext.h (m_launch_status): Changed this member to be a DNBError
- instead of a uint32_t.
- (RNBContext::LaunchStatus): Now returns a reference to the DNBError object
- in m_launch_status.
- * RNBContext.cpp (RNBContext::LaunchStatusAsString): Let DNBError handle
- any error string descriptions, including SpringBoard errors.
- * RNBRemote.cpp (RNBRemote::HandlePacket_q): Use new error class in
- RNBContext.
- (RNBRemote::HandlePacket_C): Return without an erroneous error when resuming
- a process with a signal.
- * DNBArch.h (DNBArchProtocol::StepNotComplete): New protocol function with
- default return value.
- * DNBArchImpl.cpp (DNBArchMachARM::StepNotComplete): New function.
- (DNBArchMachARM::EnableHardwareSingleStep): Handle hardware single stepping
- over 32 bit thumb instructions better so we always do a true instruction
- level single step.
- * MachProcess.cpp (MachProcess::ExceptionMessageBundleComplete): Now resumes
- if single stepping wasn't able to complete in a single run.
- * MachThread.cpp (MachThread::ShouldStop): Fills in new step_more parameter
- if stepping is not complete.
- * MachThreadList.cpp (MachThreadList::ShouldStop): Pass step_more parameter
- to each MachThread::ShouldStop call.
-
-2008-11-13 Greg Clayton <gclayton@apple.com>
-
- * MachProcess.cpp (MachProcess::PosixSpawnChildForPTraceDebugging): Don't
- call posix_spawnattr_setbinpref_np when launching with posix_spawn on ARM
- targets as it currently selects the incorrect slice due to multiple slices
- that contain the same cputype, yet they all have differing cpusubtypes.
-
-2008-11-04 Greg Clayton <gclayton@apple.com>
-
- * RNBRemote.h (GetContinueThread): Don't return the current thread when
- the continue thread is zero or -1.
- * RNBRemote.cpp (RNBRemote::HandlePacket_c): Resume the process if we
- have no continue thread set.
- (RNBRemote::HandlePacket_s): Ditto.
- (RNBRemote::HandlePacket_C): Ditto unless a continue address is specified
- in which case we will only succeed if we have one thread when the continue
- with signal and address doesn't have a continue thread specified.
- (RNBRemote::HandlePacket_S): Ditto.
- * DNB.cpp (DNBProcessResumeWithSignal): New function.
- (DNBProcessResume): Added better logging.
- (DNBProcessHalt): Ditto.
- (DNBThreadResume): Ditto.
- (DNBThreadResumeWithSignal): Ditto.
- * DNB.h (DNBProcessResumeWithSignal): New prototype.
- * DNBError.cpp (DNBError::LogThreaded): New function.
- * DNBError.h (DNBError::LogThreaded): New prototype.
- * DNBLog.cpp (_DNBLogThreaded): Added sequence ID for threaded logs.
- (_DNBLogThreadedIf): Ditto.
- * MachException.cpp (MachException::Data::GetStopInfo): Use new SoftSignal()
- accessor.
- (MachException::Data::DumpStopReason): Ditto.
- (MachException::Message::Reply): Added better logging and log using the
- soft signal if our task matches that in the exception.
- (MachException::Data::Dump): Added better logging.
- * MachException.h (IsSoftSignal): Removed.
- (SoftSignal): New function that returns the soft signal in the exception
- data if there is one, or zero otherwise.
- * MachProcess.cpp (MachProcess::Suspend): Improved logging.
- (MachProcess::Resume): Ditto.
- (MachProcess::PrivateResume): Handle the case where the process is told
- to resume with a signal by matching the signal up to the thread that had
- the soft signal if no thread id is specified.
- * MachThread.cpp (MachThread::Suspend): Improved logging.
- (MachThread::Resume): Improved logging.
- (MachThread::RestoreSuspendCount): Improved logging.
- (MachThread::Resume): Improved logging.
- (MachThread::Dump): Improved logging.
- * MachThreadList.cpp (MachThreadList::Dump): Improved logging.
-
-2008-10-22 Greg Clayton <gclayton@apple.com>
-
- * test-remotenub.cpp (RNBRunLoopMode): Added a new enum value
- eRNBRunLoopModeInferiorAttaching.
- (g_long_options): Added "--attach=PID" for attaching to existing processes
- and "--launch=(auto|posix|fork|springboard)" options.
- (RNBRunLoopLaunchInferior): Now launches process with new
- nub_launch_flavor_t enum that can be overridden with the --launch option.
- (RNBRunLoopLaunchAttaching): New function for attaching to existing
- processes.
- (main): Added command line option support for the "--attach" and "--launch"
- options and added attach to pid support and better logging.
- * DNB.cpp/h: (DNBProcessLaunch): Added nub_launch_flavor_t and error
- parameter for more precise control when launching processes.
- (DNBProcessSBLaunch): Removed function as launching with SpringBoard can
- now be done using DNBProcessLaunch with launch_flavor being set to
- eLaunchTypeSpringBoard (arm only).
- (DNBProcessSBAttach): Removed function (SpringBoard processes are now auto
- detected in the MachProcess::AttachForDebug function on ARM).
- * DNBDefs.h (NUB_GENERIC_ERROR): New generic error definition.
- (nub_launch_flavor_t): New enumeration used for control over process
- launching.
- * MachProcess.cpp (IsSBProcess): New function.
- (MachProcess::AttachForDebug): Removed flags parameter that was being used
- for SpringBoard flags and we now detect if a process belongs to SpringBoard
- by calling IsSBProcess.
- (MachProcess::LaunchForDebug): Now has launch parameter that tells it how
- to launch the inferior process and there is also an error code that gets
- returned. This function can now launch using fork + exec, posix_spawn,
- or SpringBoard on ARM targets.
- (MachProcess::SBLaunchForDebug): Now uses DNBError reference instead of
- uint32_t pointer for the error code.
- (MachProcess::SBForkChildForPTraceDebugging): Ditto.
-
-2008-10-22 Greg Clayton <gclayton@apple.com>
-
- * MacOSX/arm/DNBArchImpl.cpp (DNBArchMachARM::GetRegisterValue): Set
- register value to a uint32 value instead of a float64 value for s0 -
- s31.
-
-2008-10-17 Greg Clayton <gclayton@apple.com>
-
- * test-remotenub.cpp (RNBRunLoopLaunchInferior): Don't listen for
- the qLaunchSuccess if we aren't doing a lockdown connnection.
-
-2008-10-13 Greg Clayton <gclayton@apple.com>
-
- * RNBRemote.h (class RNBRemote): Added m_watchpoints member.
- * DNB.cpp (DNBBreakpointSet): Added boolean hardware parameter for
- requesting that a hardware breakpoint be set.
- (DNBWatchpointSet): New function.
- (DNBWatchpointClear): New function.
- (DNBWatchpointGetHitCount): New function.
- (DNBWatchpointGetIgnoreCount): New function.
- (DNBWatchpointSetIgnoreCount): New function.
- (DNBWatchpointSetCallback): New function.
- (DNBWatchpointPrint): New function.
- * DNBRegisterInfo.cpp (DNBRegisterValueClass::Dump): Modified to emit
- a single DNBLog() call so there aren't multiple newlines when logging
- to ASL.
- * RNBContext.cpp (RNBContext::ThreadFunctionProcessStatus): Use new
- process state changed events.
- * DNBBreakpoint.h (class DNBBreakpoint): Removed m_state member and
- added m_tid, m_enabled, m_hw_preferred, m_is_watchpoint, m_watch_read,
- m_watch_write, and m_hw_index.
- (DNBBreakpoint::ThreadID()): New accessor.
- (DNBBreakpoint::IsEnabled()): New accessor.
- (DNBBreakpoint::SetEnabled()): New accessor.
- (DNBBreakpoint::IsWatchpoint()): New accessor.
- (DNBBreakpoint::IsBreakpoint()): New accessor.
- (DNBBreakpoint::SetIsWatchpoint()): New accessor.
- (DNBBreakpoint::WatchpointRead()): New accessor.
- (DNBBreakpoint::WatchpointWrite()): New accessor.
- (DNBBreakpoint::HardwarePreferred()): New accessor.
- (DNBBreakpoint::IsHardware()): New accessor.
- (DNBBreakpoint::GetHardwareIndex()): New accessor.
- (DNBBreakpoint::SetHardwareIndex()): New accessor.
- (DNBBreakpoint::ThreadID()): New accessor.
- (DNBBreakpoint::GetState()): Removed accessor.
- (DNBBreakpoint::SetState()): Removed accessor.
- (DNBBreakpoint::AddBreakpoint()): Renamed to Add().
- (DNBBreakpoint::RemoveBreakpoint()): Renamed to Remove().
- (DNBBreakpoint::FindBreakIDForAddress()): Renamed to FindIDByAddress().
- (DNBBreakpoint::ShouldStopAtBreakpoint()): Renamed to ShouldStop().
- (DNBBreakpoint::SetBreakpointCallback()): Renamed to SetCallback().
- (DNBBreakpoint::FindBreakpointWithAddress()): Renamed to
- FindByAddress().
- (DNBBreakpoint::FindBreakpointWithBreakID()): Renamed to FindByID().
- (DNBBreakpoint::GetBreakpointAtIndex()): Renamed to GetByIndex().
- * FunctionProfiler.h: New header for subclass of DNBRuntimeAction.
- * RNBRemote.cpp (RNBRemote::HandlePacket_v): Use new process state
- changed events.
- (RNBRemote::HandlePacket_z): Implement the hardware breakpoint and
- watchpoint commands z1, Z1, z2, Z2, z3 and Z3
- * PThreadEvent.h (PThreadEvent::GetEventBits): Made member function
- const.
- (PThreadEvent::WaitForSetEvents): Ditto.
- (PThreadEvent::WaitForEventsToReset): Ditto.
- (PThreadEvent::WaitForResetAck): Ditto.
- (PThreadEvent::m_mutex): Made class member mutable.
- (PThreadEvent::m_set_condition): Made class member mutable.
- (PThreadEvent::m_reset_condition): New mutable class member.
- * ProfileObjectiveC.cpp
- * DNBArch.h (DNBArch::NotifyException): Now has default implementation
- that returns false.
- (DNBArch::NumSupportedHardwareBreakpoints): New virtual member
- function with a default implementation.
- (DNBArch::NumSupportedHardwareWatchpoints): Ditto.
- (DNBArch::EnableHardwareBreakpoint): Ditto.
- (DNBArch::EnableHardwareWatchpoint): Ditto.
- (DNBArch::DisableHardwareBreakpoint): Ditto.
- (DNBArch::DisableHardwareWatchpoint): Ditto.
- * DNB.h (DNBBreakpointSet): New take a HARDWARE parameter that allows
- requests for setting hardware breakpoints.
- (DNBWatchpointSet): New function prototype.
- (DNBWatchpointClear): New function prototype.
- (DNBWatchpointGetHitCount): New function prototype.
- (DNBWatchpointGetIgnoreCount): New function prototype.
- (DNBWatchpointSetIgnoreCount): New function prototype.
- (DNBWatchpointSetCallback): New function prototype.
- (DNBWatchpointPrint): New function prototype.
- * MacOSX/arm/DNBArchImpl.cpp: Added hardware breakpoint and watchpoint
- support for ARM.
- (DNBArchMachARM::GetCPUType): New function.
- (DNBArchMachARM::DumpDBGState): New function.
- (DNBArchMachARM::GetDBGState): New function.
- (DNBArchMachARM::SetDBGState): New function.
- (DNBArchMachARM::EnableHardwareSingleStep): New function.
- (DNBArchMachARM::EnableHardwareBreakpoint): New function.
- (DNBArchMachARM::NotifyException): Removed.
- (DNBArchMachARM::DisableHardwareBreakpoint): New function.
- (DNBArchMachARM::EnableHardwareWatchpoint): New function.
- (DNBArchMachARM::DisableHardwareWatchpoint): New function.
- * MacOSX/MachThread.cpp (MachThread::Suspend): Added better logging.
- (MachThread::Resume): Ditto.
- (MachThread::RestoreSuspendCount): Ditto.
- (MachThread::Dump): Ditto.
- (MachThread::EnableHardwareBreakpoint): New function.
- (MachThread::EnableHardwareWatchpoint): New function.
- (MachThread::DisableHardwareBreakpoint): New function.
- (MachThread::DisableHardwareWatchpoint): New function.
- * MacOSX/MachThreadList.h (MachThreadList::GetLastError): Removed.
- (MachThread::EnableHardwareBreakpoint): New prototype.
- (MachThread::DisableHardwareBreakpoint): New prototype.
- (MachThread::EnableHardwareWatchpoint): New prototype.
- (MachThread::DisableHardwareWatchpoint): New prototype.
- (class MachThread): Remove m_err member variable.
- * MacOSX/ppc/DNBArchImpl.cpp (DNBArchMachPPC::GetCPUType) New
- function.
- (DNBArchMachPPC::NotifyException): Removed.
- * MacOSX/ppc/DNBArchImpl.h (DNBArchMachPPC::NotifyException): Removed.
- * MacOSX/MachThread.h (MachThread::EnableHardwareBreakpoint): New
- prototype.
- (MachThread::EnableHardwareWatchpoint): New prototype.
- (MachThread::DisableHardwareBreakpoint): New prototype.
- (MachThread::DisableHardwareWatchpoint): New prototype.
- (class MachThread): Renambed class member m_exception to
- m_stop_exception.
- * MacOSX/MachProcess.cpp (MachProcess::SetState): Updated to use new
- process event enumerations.
- (MachProcess::PrivateResume): Added better logging.
- (MachProcess::CreateBreakpoint): Added bool HARDWARE parameter for
- requesting hardware breakpoints.
- (MachProcess::CreateWatchpoint): New function.
- (MachProcess::DisableAllWatchpoints): New function.
- (MachProcess::DisableWatchpoint): New function.
- (MachProcess::DumpWatchpoint): New function.
- (MachProcess::EnableBreakpoint): Enabled breakpoints in hardware if
- requested and supported.
- (MachProcess::DisableBreakpoint): Disable hardware breakpoints if that
- is how they were set.
- (MachProcess::EnableWatchpoint): New function.
- (MachProcess::ExceptionMessageBundleComplete): Wait for the
- eEventProcessRunningStateChanged event to be reset before changing
- state to stopped to avoid race condition with very fast start/stops.
- (MachProcess::LaunchForDebug): Added posix_spawn support.
- (MachProcess::PosixSpawnChildForPTraceDebugging): New function.
- * MacOSX/i386/DNBArchImpl.cpp (DNBArchMachI386::GetCPUType): New
- function.
- * MacOSX/i386/DNBArchImpl.h (DNBArchMachI386::GetCPUType): New
- prototype.
- * MacOSX/MachProcess.h (PosixSpawnChildForPTraceDebugging): New
- prototype.
- * MacOSX/MachException.cpp (class MachException::ThreadMessage):
- Renamed class to MachException::Data.
- * MacOSX/MachThreadList.cpp (class MachThreadList): Removed m_err
- class member.
- (MachThreadList::EnableHardwareBreakpoint): New function.
- (MachThreadList::DisableHardwareBreakpoint): New function.
- (MachThreadList::EnableHardwareWatchpoint): New function.
- (MachThreadList::DisableHardwareWatchpoint): New function.
- * MacOSX/MachException.h (class MachException::ThreadMessage):
- Renamed class to MachException::Data.
- * DNBDefs.h (nub_watch_t): New typedef.
- (INVALID_NUB_HW_INDEX): New macro definition.
- (WATCH_TYPE_READ): New macro definition.
- (WATCH_TYPE_WRITE): New macro definition.
- (NUB_STATE_IS_RUNNING): New macro to see if state is a running state.
- (NUB_STATE_IS_STOPPED): New macro to see if state is a stopped state.
- (eEventProcessStateChanged): Deprecated.
- (eEventProcessRunningStateChanged): New process event state.
- (eEventProcessStoppedStateChanged): New process event state.
- (LOG_WATCHPOINTS): New macro definition for logging watchpoints.
- * test-remotenub.cpp (RNBRunLoopLaunchInferior): Use new process
- event states.
- * FunctionProfiler.cpp: New class that allows single stepping through
- an address range for tracing exact call graphs.
-
-2008-09-22 Greg Clayton <gclayton@apple.com>
-
- * RNBRemote.h (GetContinueThread): If the continue thread is zero or
- -1 then return GetCurrentThread().
- * RNBRemote.cpp (m_packets): Made the vCont functions call
- RNBRemote::HandlePacket_v().
- (RNBRemote::HandlePacket_H): Cleaned up whitespace.
- (RNBRemote::HandlePacket_last_signal): Return actual signal values for
- EXE_SOFTWARE/EXC_SOFT_SIGNAL mach exceptions.
- (RNBRemote::HandlePacket_v): Implemented the 'vCont?' and 'vCont;'
- packets.
- (RNBRemote::HandlePacket_c): Handle the case where an address is
- provided.
- (RNBRemote::HandlePacket_C): Implemented the continue with signal
- including when an address is provided.
- (RNBRemote::HandlePacket_S): Implemented the step with signal
- including when an address is provided.
- * DNB.cpp (DNBProcessResume): Pass 0 as the signal when resuming
- a process without specifying a thread.
- (DNBThreadResume): Pass 0 as the signal when resuming a specific thread.
- (DNBThreadResumeWithSignal): New function.
- * DNB.h (DNBThreadResumeWithSignal): New prototype.
- * MachException.h (MachException::Message::Reply): Added a signal
- parameter.
- * MachException.cpp (MachException::Message::Reply): Update the thread
- with the new SIGNAL parameter instead of always zero so signals can be
- passed on to programs.
- * MachProcess.h (MachProcess::Resume): Added a signal parameter.
- * MachProcess.h (MachProcess::PrivateResume): Added a signal parameter.
- * MachProcess.cpp (MachProcess::Resume): Pass new SIGNAL parameter to
- MachProcess::PrivateResume.
- * MachProcess.cpp (MachProcess::PrivateResume): Pass new SIGNAL
- parameter to the mach exception reply.
-
-2008-08-08 Greg Clayton <gclayton@apple.com>
-
- * DNB.cpp (gProcessMap): Removed static C++ global.
- (GetProcessMap): New Function.
- (AddProcessToMap): New function.
- (RemoveProcessFromMap): New function.
- (GetProcessSP): Use new GetProcessMap function to get process list.
-
-2008-07-30 Greg Clayton <gclayton@apple.com>
-
- * debugserver-entitlements.plist (get-task-allow): Removed.
- (run-invalid-allow): Added boolean value set to TRUE.
-
-2008-04-18 Greg Clayton <gclayton@apple.com>
-
- * MachProcess.cpp (MachProcess::Task): Added getuid(), geteuid(),
- getgid(), getegid() to the log message if task for pid fails.
-
-2008-04-07 Greg Clayton <gclayton@apple.com>
-
- * RNBContext.cpp (RNBContext::LaunchStatusAsString): Removed unused
- tmp_str variable.
-
-2008-04-04 Greg Clayton <gclayton@apple.com>
-
- * CFString.cpp/h (UTF8): Made a static function that can convert
- a CFStringRef to UTF8.
-
-2008-04-04 Greg Clayton <gclayton@apple.com>
-
- * test-remotenub.cpp (main): Make sure we exit after we send the
- application list.
-
-2008-04-04 Greg Clayton <gclayton@apple.com>
-
- * RNBServices.h (IsSBProcess): New prototype;
- * RNBServices.cpp (IsSBProcess): New function that returns true it
- SpringBoard owns or knows about the process.
- * RNBRemote.cpp (RNBRemote::HandlePacket_v): Made attach work correctly.
- * DNB.cpp (DNBProcessSBAttach): New function for use when attaching to
- a process owned by SpringBoard.
- (DNBProcessAttach): Fixed an issue where a local was shadowing a
- parameter.
- * DNB.h (DNBProcessSBAttach): New prototype.
- * MachProcess.cpp (MachProcess::AttachForDebug): AttachForDebug now
- takes some flags so it knows to enable SpringBoard functionality.
- * MachProcess.h (MachProcess::AttachForDebug): Added flags parameter
- to prototype.
-
-2008-04-04 Greg Clayton <gclayton@apple.com>
-
- * test-remotenub.cpp (RNBRunLoopGetArgsFromRemote): Handle the new
- attach packet and watch for connection being lost.
- (main): handle the --applist option when there we aren't using lockdown
- by printing the results to stdout and exiting with appropriate error code
- if we failed. Also handle the new prototype for ListApplications.
- * RNBServices.h (ListApplications): Change first parameter to be a std::string
- that will get the contents of the plist so we can use this for more than
- just lockdown.
- * RNBServices.cpp (ListApplications): Change first parameter to be a std::string
- that will get the contents of the plist so we can use this for more than
- just lockdown and also fixed the logic so we actually create a full list of
- applications instead of just overwriting the first entry.
- * RNBRemote.h (PacketEnum): Added a new 'vattach' enum for the "vAttach;PID"
- gdb remote command.
- (RNBRemote::HandlePacket_v): New prototype;
- * RNBRemote.cpp (RNBRemote::CreatePacketTable): add the vattach packet definition
- to m_packets.
- (RNBRemote::HandlePacket_v): New function that handles attach to a process.
-
-2008-04-03 Jim Ingham <jingham@apple.com>
-
- * RNBRemote.h: Add query_launch_success to packet enum.
- * RNBRemote.cpp (RNBRemote::CreatePacketTable_): Add query_launch_success.
- (HandlePacket_q): Handle query_launch_success.
- * DNB.cpp (DNBProcessSBLaunch): Pass in launch_retval.
- * DNB.h: Change prototype of DNBProcessSBLaunch to take launch_retval.
- * RNBContext.cpp (RNBContext::LaunchStatusAsString): New function.
- * RNBContext.h (RNBContext): Add m_launch_status & accessors.
- * macosx/MachProcess.cpp (MachProcess::SBLaunchForDebug): Pass launch_retval.
- (MachProcess::SBForkChildForPTraceDebugging): Accept & set launch_retval.
- * Macosx/MachProcess.h: Change prototypes of SBLaunchForDebug &
- ForkChildForPTraceDebugging to accept launch_retval.
- * test-remotenub.cpp (RNBRunLoopLaunchInferior): Get the launch status and
- put it in the context, then wait for the qLaunchStatus packet.
-
-2008-04-03 Greg Clayton <gclayton@apple.com>
-
- * com.apple.debugserver.plist: Changed plist so debugserver
- runs as mobile user.
- * com.apple.debugserver.applist.plist: Ditto.
-
-2008-04-03 Greg Clayton <gclayton@apple.com>
-
- * MachProcess.cpp: (MachProcess::SBForkChildForPTraceDebugging):
- Increased SBS application launch timeout to 30 seconds.
-
-2008-03-27 Christopher Friesen <friesen@apple.com>
-
- * RNBServices.h: Pass tasks from SpringBoard as a plist
- * RNBServices.cpp: Ditto.
- * test-remotenub.cpp: added --applist flag
- * com.apple.debugserver.applist.plist: Agent plist
-
-2008-03-17 Jim Ingham <jingham@apple.com>
-
- * DNB.h: Pass envp to DNBProcessLaunch & DNBProcessSBLaunch.
- * DNB.cpp: Ditto.
- * MachProcess.h: Ditto for *LaunchForDebug and
- *ForkChildForPtraceDebugging.
- * MachProcess.cpp (MachProcess::LaunchForDebug): Pass on envp.
- (MachProcess::SBLaunchForDebug): Ditto.
- (MachProcess::ForkChildForPtraceDebugging): Accept envp, haven't actually
- implemented the passing yet.
- (MachProcess::SBForkChildForPtraceDebuggin): Accept envp, convert to
- CFDictionary and pass to SBSLaunchApplication.
- * RNBContext.h: Add environment to the context.
- * RBNContext.cpp (RNBContext::EnvironmentAtIndex): New function.
- * RNBRemote.h: Add set_environment_variable to the PacketEnum.
- * RNBRemote.cpp (RNBRemote::CreatePacketTable): Add QEnvironment:.
- * (RNBRemote::HandlePacket_Q): Ingest the environment variable.
- * test-remotenub.cpp (RNBRunLoppLaunchInferior): Convert the env
- array in the context into an array, and pass it to the DNBProcess*Launch
- methods.
-
-2008-03-17 Greg Clayton <gclayton@apple.com>
-
- * DNBBreakpoint.cpp (DNBBreakpointList::GetBreakpointAtIndex): New
- functions (const and non-const versions).
- * DNBBreakpoint.h (DNBBreakpointList::GetBreakpointAtIndex): New
- prototypes (const and non-const versions).
- * DNBError.h (DNBError::Success()): Don't use KERN_SUCCESS define.
- (DNBError::Fail()): Don't use KERN_SUCCESS define.
- * MachProcess.cpp (MachProcess::DisableAllBreakpoints): New function.
- (MachProcess::Detach): Added initial implementation that will halt
- the process, disable all breakpoints and call PT_DETACH.
- * MachProcess.h (MachProcess::DisableAllBreakpoints): New prototype.
-
-2008-03-04 Greg Clayton <gclayton@apple.com>
-
- * RNBRemote.h (RNBRemote::SendHexEncodedBytePacket): New prototype.
- * RNBRemote.cpp (RNBRemote::SendHexEncodedBytePacket): New function.
- (RNBRemote::SendSTDOUTPacket): Use SendHexEncodedBytePacket function
- to send bytes.
- (RNBRemote::SendSTDERRPacket): Ditto.
- (RNBRemote::HandlePacket_q): Return a valid thread info string for
- qThreadExtraInfo queries.
- * DNB.cpp (DNBThreadPrintStopReason): Commented out unused function.
- (DNBThreadGetInfo): New function.
- * DNB.h (DNBThreadPrintStopReason): Commented out prototype.
- (DNBThreadGetInfo): New prototype.
- * MachProcess.cpp (MachProcess::GetThreadInfo): New function.
- * MachProcess.h (MachProcess::GetThreadInfo): New prototype.
- * MachThreadList.cpp (MachThreadList::GetThreadInfo): New function.
- * MachThreadList.h (MachThreadList::GetThreadInfo): New prototype.
- * MachThread.cpp (MachThread::GetBasicInfoAsString): New function.
- (MachThread::InferiorThreadID): New function.
- * MachThread.cpp (MachThread::GetBasicInfoAsString): New prototype.
- (MachThread::InferiorThreadID): New prototype.
-
-2008-02-27 Greg Clayton <gclayton@apple.com>
-
- * RNBRemote.cpp (RNBRemote::HandlePacket_last_signal): Set the
- current thread when we notify a thread has stopped to subsequent
- g and p packets get the correct data.
-
-2008-02-26 Jason Molenda (jmolenda@apple.com)
-
- * RNBRemote.h: Add query_thread_extra_info enum.
- * RNBRemote.cpp: Add support for qThreadExtraInfo.
- Currently we return 'Ok' as the packet status for
- every thread.
-
-2008-02-26 Jason Molenda (jmolenda@apple.com)
-
- * RNBRemote.cpp (RNBRemote::HandlePacket_q): Correct handling
- of qfThreadInfo/qsThreadInfo.
-
-2008-02-20 Jason Molenda (jmolenda@apple.com)
-
- * RNBRemote.h: Change default for gdb's max incoming packet size to
- reflect the real default size.
- * RNBRemote.cpp (HandlePacket_Q): Correct the string comparisons for
- the QSetMaxPayloadSize and QSetMaxPacketSize packets.
-
-2008-02-19 Christopher Friesen <friesen@apple.com>
-
- * CFDataFormatters.c: CoreFoundation data formatters added to project.
-
-2008-02-19 Jason Molenda (jmolenda@apple.com)
-
- * RNBRemote.h: Record the max payload size, not the max packet
- size for less ambiguous meaning.
- * RNBRemote.cpp: Add support for QSetMaxPayloadSize: packet which
- should have a clearer meaning than QSetMaxPacketSize.
- QSetMaxPacketSize will be removed once we get have a chance to get
- a new debugserver and gdb submitted.
-
-2008-02-18 Jason Molenda (jmolenda@apple.com)
-
- * RNBRemote.h: Make default size 1024.
- * RNBRemote.cpp: Questionmark packet should stay under
- max_packet_size - 5 to allow for start, end, checksum and nul
- char bytes.
-
-2008-02-18 Jason Molenda (jmolenda@apple.com)
-
- * RNBRemote.h: Add m_max_packet_size to class defn.
- * RNBRemote.cpp: Initialize it, use it.
-
-2008-02-18 Jason Molenda (jmolenda@apple.com)
-
- * RNBRemote.h: Add set_max_packet_size.
- * RNBRemote.cpp: Add QSetMaxPacketSize packet handling.
-
-2008-02-18 Greg Clayton <gclayton@apple.com>
-
- * test-remotenub.cpp (HandleProcessStateChange): Call new
- RNBRemote::FlushSTDIO function.
- (RNBRunLoopInferiorExecuting): Ditto.
- * RNBRemote.h (RNBRemote::FlushSTDIO): New prototype.
- * RNBRemote.cpp (RNBRemote::FlushSTDIO): New function to
- centralize the stdio.
-
-2008-02-18 Greg Clayton <gclayton@apple.com>
-
- * DNB.cpp (DNBProcessWaitForEvent): Added timeout pointer as
- parameter that can be NULL for infinite timeout to simplify
- the DNB interface.
- (DNBProcessTimedWaitForEvent): Removed function.
- * DNB.h (DNBProcessWaitForEvent): Added timeout argument.
- (DNBProcessTimedWaitForEvent): Removed prototype.
- * DNBTimer.h (DNBTimer::OffsetTimeOfDay): New function.
- * CFString.cpp (CFString::GetLength() const): New function.
- * CFString.h (CFString::GetLength() const): New prototype.
- * MachProcess.h (MachProcess class): Removed m_attached and
- added m_flags.
- * MachProcess.cpp (MachProcess::AttachForDebug): Set m_flags
- to indicate we attached.
- (MachProcess::SBLaunchForDebug): Set m_flags to indicate we
- attached using SpringBoard and that we attached.
- (MachProcess::SBForkChildForPTraceDebugging): Changed to new
- SpringBoardServices API.
- (MachProcess::ThreadFunctionException): Added code that will
- renew a watchdog assertion when we launch apps through
- SpringBoardServices.
- * PThreadEvent.cpp (PThreadEvent::WaitForSetEvents): Simplified
- PThreadEvent API to have only one version of WaitForSetEvents
- that has an optional timeout pointer argument.
- * RNBContext.cpp (RNBContext::StopProcessStatusThread): Adapt
- to new PThreadEvent API changes.
- (RNBContext::ThreadFunctionProcessStatus): Adapt to new
- DNBProcessWaitForEvent API changes.
- * RNBRemote.cpp (RNBRemote::StopReadRemoteDataThread): Adapt
- to new PThreadEvent API changes.
- * test-remotenub.cpp (RNBRunLoopLaunchInferior): Adapt to new
- DNBProcessWaitForEvent API changes.
- (RNBRunLoopInferiorExecuting): Process STDIO first, then
- incoming packets.
-
-2008-02-14 Jason Molenda (jmolenda@apple.com)
-
- * MachProcess.cpp: (MachProcess::SBForkChildForPTraceDebugging):
- Set mode bits on slave side of pty.
-
-2008-02-12 Greg Clayton <gclayton@apple.com>
-
- * DNB.cpp (DNBEnableLogging): Removed function.
- (DNBThreadPrintStopReason): Removed the file handle from this
- function and use DNBLog calls.
- * DNB.h (DNBEnableLogging): Removed function prototype.
- (DNBThreadPrintStopReason): Removed the file handle
- from the function prototype in favor of using DNBLog calls.
- * DNBDataRef.cpp (DNBDataRef::Dump): Removed file handle to use
- DNBLog for the logging and print a log line each time a full line
- is ready for output after caching it in a local buffer.
- * DNBDataRef.cpp (DNBDataRef::Dump): Removed file handle from
- prototype.
- * DNBDefs.h (DNBCallbackLog): New callback prototype for all
- logging.
- DNBLog.cpp(g_debug_opt): Renamed to d_debug and made it a file
- static.
- (DNBLogGetDebug): New accessor function for g_debug.
- (DNBLogSetDebug): New accessor function for g_debug.
- (g_verbose): Made into a file static and added accessors.
- (DNBLogGetVerbose): New accessor function for g_verbose.
- (DNBLogSetVerbose): New accessor function for g_verbose.
- (DNBLogSetLogCallback): New function call that registers a logging
- callback for all logging in libdebugnub.dylib and any code that
- loads it.
- (DNBLogToASL): Removed function as it is deprecated in favor of
- using DNBLogSetLogCallback to register a callback function that
- implements the logging.
- (DNBLogToFile): Ditto.
- (DNBLogCloseLogFile): Ditto.
- (DNBLogToFile): Ditto.
- (DNBLogToFile): Ditto.
- (_DNBLogPuts): Removed unused function.
- (_DNBLogVAPrintf): Calls the callback function to do the logging
- if one has been registered.
- * DNBLog.h (DNBLOG_FLAG_FATAL): New defines that get passed to
- any registered logging callback functions.
- (DNBLOG_FLAG_FATAL): Ditto.
- (DNBLOG_FLAG_ERROR): Ditto.
- (DNBLOG_FLAG_WARNING): Ditto.
- (DNBLOG_FLAG_DEBUG): Ditto.
- (DNBLOG_FLAG_VERBOSE): Ditto.
- (DNBLOG_FLAG_THREADED): Ditto.
- (DNBLog*): All logging calls are now exported from libdebugnub.dylib
- so there aren't two copies (one in debugserver and one in debugnub).
- C99 vararg Macros wrap all logging calls so no var arg processing
- occurs when logging is disabled.
- * DNBRegisterInfo.cpp (DNBRegisterValueClass::Dump): Removed file
- handle and now use DNBLog calls.
- * DNBRegisterInfo.h (DNBRegisterValueClass::Dump): Removed file
- handle from prototype.
- * MachException.cpp (catch_mach_exception_raise_state_identity):
- Removed newlines from logging call.
- (catch_mach_exception_raise): Ditto.
- (MachException::Message::Dump): Removed file handle from params
- and removed newlines from logging call.
- (MachException::ThreadMessage::DumpStopReason): Removed file handle
- from params and use DNBLog for logging output.
- (MachException::ThreadMessage::Dump): Log using DNBLog instead of
- file handle.
- * MachProcess.cpp (MachProcess::DumpThreadStoppedReason): Ditto.
- (MachProcess::ReadMemory): Ditto.
- (MachProcess::WriteMemory): Ditto.
- (ExceptionMessageBundleComplete): Ditto.
- * MachThread.cpp (MachThread::Dump): Ditto.
- (MachThread::DumpRegisterState): Ditto.
- * MachThreadList.cpp (MachThreadList::DumpThreadStoppedReason): Ditto.
- (MachThreadList::Dump): Ditto.
- * RNBRemote.cpp (set_logging): Use new function callback registration
- calls when enabling ASL logging.
- test-remotenub.cpp (ASLLogCallback): New function to handle all ASL
- logging. This function gets registered with libdebugnub.dylib when we
- want to log using ASL.
- (FileLogCallback): New function to handle all file logging. This
- function gets registered with libdebugnub.dylib when we want to log
- to a 'FILE *'.
- (main): Register the logging callback functions when we want to log
- to file or using ASL.
-
-2008-02-12 Greg Clayton <gclayton@apple.com>
-
- * test-remotenub.cpp (main): Default to ASL logging with no log
- bits set to allow for warning and error logging.
- * RNBRemote.h (struct Breakpoint): New structure for ref counting
- breakpoints in Z and z packets.
- * RNBRemote.cpp (RNBRemote::SendPacket): Use new LOG_RNB_PACKETS
- defined when logging actual packet content.
- (RNBRemote::HandleAsyncPacket): Ditto.
- (RNBRemote::HandleReceivedPacket): Ditto.
- (RNBRemote::HandlePacket_z): Ref count the setting and removing
- of breakpoints with the Z and z packets using new struct
- RNBRemote::Breakpoint.
- * RNBDefs.h (LOG_RNB_PACKETS): New define for logging the sending
- and receiving of packets data.
- * DNB.cpp (DNBPrintf): Check for NULL file handle.
- * DNBBreakpoint.cpp (DNBBreakpoint::Dump): Ditto.
- (DNBBreakpointList::Dump): Ditto.
- * DNBDefs.h (LOG_EVENTS): New define for logging PThreadEvent.
- * DNBLog.cpp (g_debug_opt): Relocated outside of #if that turns off
- logging completely to allow option parsing code that uses it to
- still compile.
- (g_verbose): Ditto.
- * DNBLog.h (DNBLogToASL): Added prototype for when logging is
- disabled via preprocessor macro.
- (DNBLogToFile): Ditto.
- * DNBRegisterInfo.cpp (DNBRegisterValueClass::Dump): Check for NULL
- file handle.
- * MachException.cpp (MachException::ThreadMessage::DumpStopReason): Ditto.
- (MachException::ThreadMessage::Dump): Ditto.
- * MachProcess.cpp (MachProcess::CreateBreakpoint): Improved logging.
- (MachProcess::DisableBreakpoint): Verify the original opcode gets
- restored, improved logging and added unconditional logging for when
- things go wrong.
- (MachProcess::EnableBreakpoint): Verify the breakpoint opcode gets
- written, improved logging and added unconditional logging for when
- things go wrong.
- * MachThread.cpp (MachThread::Dump): Check for NULL file handle.
- * MachVMMemory.cpp (MachVMMemory::WriteRegion): Flush caches in inferior
- after writing to inferior memory.
- * PThreadEvent.cpp: Changed all logging calls to key off of LOG_EVENTS
- instead of LOG_VERBOSE.
- MachDYLD.cpp (MachDYLD::Dump): Check for NULL file handle.
- (MachDYLD::DYLIBInfo::Dump): Ditto.
- ProfileObjectiveC.cpp (ProfileObjectiveC::DumpStats): Ditto.
-
-2008-02-09 Jason Molenda (jmolenda@apple.com)
-
- * RNBRemote.cpp (set_logging): Log to ASL unconditionally when
- processing a QSetLogging packet.
-
-2008-02-06 Greg Clayton <gclayton@apple.com>
-
- * test-remotenub.cpp (main): Dup stdout and stderr to /dev/NULL
- when we use lockdown.
-
-2008-02-06 Greg Clayton <gclayton@apple.com>
-
- * RNBSocket.cpp (RNBSocket::Disconnect): Removed unused var ERR.
- * RNBRemote.cpp(RNBRemote::HandlePacket_Q): Removed unused var PID.
- * DNBError.cpp (DNBError::LogThreadedIfError): Removed unused var
- ERR_MSG.
- * test-remotenub.cpp (RNBRunLoopLaunchInferior): Removed unused
- variable EXECUTABLE_LENGTH.
- (main): Removed unused variable ARG_IDX.
-
-2008-02-06 Chris Marcellino (cmarcellino@apple.com) and Myke Olson (molson@apple.com)
-
- * MachProcess.cpp (SBForkChildForPTraceDebugging): Bring up to date with
- current SpringBoardServices.framework types and imports.
-
-2008-02-05 Jason Molenda (jmolenda@apple.com)
-
- * RNBRemote.cpp (set_logging): Remove the mode=file and filename=
- options to the QSetLogging packet. We're only going to support logging
- to ASL for now. Logging to a file can still be accomplished by the
- -l command line argument.
-
-2008-02-02 Christopher Friesen (cfriesen@apple.com)
-
- * Added libXcodeDebugerSupport.dylib target
- * XCDebuggerIntrospection.[hc]: Support for Xcode's debugger introspection.
-
-2008-02-01 Jason Molenda (jmolenda@apple.com)
-
- * DNBLog.cpp (DNBLogCloseLogFile): New function to close a logfile
- at exit.
- * DNBLog.h: Prototype.
- * test-remotenub.cpp (main): Close the log file before exiting.
-
-2008-02-01 Jason Molenda (jmolenda@apple.com)
-
- * RNBRemote.cpp (set_logging): Recognize the "filename=" argument
- to the QSetLogging directive.
- * DNBLog.cpp (DNBLogGetLogMask): New fun.c
- * DNBLog.h: Prototype.
-
-2008-01-31 Jason Molenda (jmolenda@apple.com)
-
- * DNBLog.cpp: Add ASL logging as a run-time selectable option.
- (DNBLogToASL, DNBLogToFile): Functions to switch between logging to
- a file and logging via ASL.
- * DNBLog.h: Prototypes.
- * RNBRemote.cpp (set_logging): Recognize the "mode=" field to enable
- asl logging. Skip unrecognized keys.
-
-2008-01-31 Greg Clayton (gclayton@apple.com)
-
- * DNB.cpp (sigchld_handler): Better logging when we get a
- SIGCHILD and we are watching for process related logging events.
- * test-remotenub.cpp (RNBRunLoopInferiorExecuting): Only reset
- events when we still have event bits set.
-
-2008-01-29 Jason Molenda (jmolenda@apple.com)
-
- * RNBRemote.h: Add set_logging_mode.
- * RNBRemote.cpp (RNBRemote::CreatePacketTable): Recognize
- QSetLogging.
-
-2008-01-29 Jason Molenda (jmolenda@apple.com)
-
- * RNBRemote.cpp (set_logging): New function to parse the QSetLogging
- packet.
- (RNBRemote::HandlePacket_Q): Call it.
-
-2008-01-28 Jason Molenda (jmolenda@apple.com)
-
- * RNBRemote.h: Minimal packet size is 1024 in our gdb now.
- * RNBRemote.cpp: Add the stop_pc value in big-endian order to the
- T response packet to make it a little easier to follow where gdb
- is stepping.
-
-2008-01-28 Greg Clayton <gclayton@apple.com>
-
- * RNBContext.h: Removed m_pid_state from RNBContext class so that
- it couldn't get out of sync with the actual process and its accessors
- SetProcessState() and GetProcessState().
- * RNBContext.cpp (RNBContext::ProcessStateRunning): Always return the
- current state of the process instead of a cached value.
- * test-remotenub.cpp (RNBRunLoopLaunchInferior): Remove call to
- deprecated RNBContext::SetProcessState().
- (HandleProcessStateChange): Ditto.
-
-2008-01-24 Greg Clayton (gclayton@apple.com)
-
- * RNBRemote.cpp (RNBRemote::HandlePacket_q): See if command starts with
- "qSymbol" (no trailing "s") and return the empty string.
-
-2008-01-24 Greg Clayton (gclayton@apple.com)
-
- * RNBRemote.cpp (RNBRemote::HandlePacket_q): See if command starts with
- "qSymbols" and return the empty string.
-
-2008-01-24 Greg Clayton (gclayton@apple.com)
-
- * DNBError.h (DNBError::DumpIfError): Removed prototype.
- * DNBError.cpp (DNBError::DumpIfError): Removed function.
- (DNBError::LogThreadedIfError): Output error as hex.
- * MachException.cpp (MachException::Message::Receive): Don't use
- DNBError::DumpIfError, now use DNBError::LogThreadedIfError.
- * MachProcess.cpp (MachProcess::StartExceptionThread): Ditto.
- (MachProcess::Suspend): Ditto.
- (MachProcess::SBForkChildForPTraceDebugging): Ditto.
- * MachVMMemory.cpp (MachVMMemory::Read): Cleaned up logging
- calls.
- (MachVMMemory::Write): Ditto.
- (MachVMMemory::WriteRegion): Added logging.
- * RNBContenxt.cpp (display_thread_info): Removed function.
- * RNBRemote.cpp (RNBRemote::GetPacket): Commented out stderr
- messages to avoid SpringBoard from killing us.
- (RNBRemote::HandlePacket_p): Ditto.
- (RNBRemote::HandlePacket_P): Ditto.
- (RNBRemote::HandlePacket_c): Ditto.
- (RNBRemote::HandlePacket_A): Removed code that was already
- * RNBSocket.cpp (RNBSocket::Listen): Commented out stdout
- messages to avoid SpringBoard from killing us.
- (RNBSocket::ConnectToService): Ditto.
-
-2008-01-24 Jim Ingham <jingham@apple.com>
-
- * RNBRemote.cpp (RNBRemote::HandlePacket_q): Reply "" to qSymbols
- and qOffsets.
-
-2008-01-23 Jason Molenda (jmolenda@apple.com)
-
- * RNBRemote.h: m_noack_mode to RNBRemote class.
- * RNBRemote.cpp: Change #ifdef NO_ACKS code blocks
- to use m_noack_mode instance variable.
- (RNBRemote::HandlePacket_Q): New function to handle
- QStartNoAckMode packet and set m_noack_mode appropriately.
- * test-remotenub.cpp: Remove NO_ACKS ifdefs.
-
-2008-01-22 Jason Molenda (jmolenda@apple.com)
-
- * RNBRemote.cpp (RNBRemote::CreatePacketTable): Recognize
- QStartNoAckMode as an unsupported remote protocol request.
- * RNBRemote.h: Add start_noack_mode enum entry.
-
-2008-01-22 Greg Clayton (gclayton@apple.com)
-
- * DNBLog.h: Removed C++ namespace for DNBLog (changed all DNBLog::
- to DNBLog) so C99 var arg macros can be used to completely disable
- all logging and any functions that may be called when making the
- variable arguments.
- * DNBLog.cpp: Ditto.
- * DNB.cpp: Ditto.
- * DNBBreakpoint.cpp: Ditto.
- * DNBError.cpp: Ditto.
- * MacOSX/MachDYLD.cpp: Ditto.
- * MacOSX/MachException.cpp: Ditto.
- * MacOSX/MachProcess.cpp: Ditto.
- * MacOSX/MachThread.cpp: Ditto.
- * MacOSX/MachThreadList.cpp: Ditto.
- * MacOSX/MachVMMemory.cpp: Ditto.
- * MacOSX/MachVMRegion.cpp: Ditto.
- * MacOSX/arm/DNBArchImpl.cpp: Ditto.
- * MacOSX/ppc/DNBArchImpl.cpp: Ditto.
- * PThreadEvent.cpp: Ditto.
- * RNBContext.cpp: Ditto.
- * RNBRemote.cpp: Ditto.
- * RNBSocket.cpp: Ditto.
- * test-remotenub.cpp: Ditto.
-
-2008-01-21 Jason Molenda (jmolenda@apple.com)
-
- * test-remotenub.cpp: Add NO_SPRINGBOARD for turning off SpringBoard
- dependency ala NO_ACKS.
-
-2008-01-18 Jason Molenda (jmolenda@apple.com)
-
- * RNBSocket.h (RNBSocket::RNBSocket): Take either a port # or
- an already-opened socket, with a boolean to indicate which it is.
- * RNBRemote.cpp (RNBRemote::RNBRemote): Ditto.
- * RNBRemote.h: Prototype update.
- * test-remotenub.cpp: Include lockdown.h. Take --lockdown command
- line arg, get the socket from liblockdown.dylib instead of opening
- our own socket if it is specified. --lockdown indicates that
- the program name/args will be provided via remote protocol instead
- of on the command line.
-
-2008-01-17 Jason Molenda (jmolenda@apple.com)
-
- * RNBRemote.cpp: Add NO_ACKS #ifdefs around code that computes
- the checksums and sends/expects the gdb remote protocol ACK packets.
- If NO_ACKS is defined, debugserver will not send or expect acks.
- * test-remotenub.cpp (main): Print a different version string
- if NO_ACKS is defined.
-
-2008-01-16 Greg Clayton (gclayton@apple.com)
-
- * PThreadEvent.cpp: Added this pointer to all logging calls.
-
-2008-01-16 Greg Clayton (gclayton@apple.com)
-
- * RNBSocket.cpp (RNBSocket::Connect()): Use TCP so we can try the
- TCP_NODELAY socket option.
- (RNBSocket::SetSocketOption()): New function.
- * RNBSocket.h (RNBSocket::SetSocketOption()): New class function.
-
-2008-01-14 Jason Molenda (jmolenda@apple.com)
-
- * RNBRemote.cpp (RNBRemote::HandlePacket_last_signal): When printing
- registers, skip over gdb regs which don't map to DNB regs.
-
-2008-01-14 Jim Ingham <jingham@apple.com>
-
- * ChangeLog - created.
- * RBNContext.h: Added m_arg_vec and accessors.
- * RNBContext.cpp (SetProcessID): New function.
- * RBNRemote.h: Added packet type to HandlePacket & HandleAsyncPacket
- * RNBRemote.cpp (HandlePacket, HandleAsyncPacket): Return type.
- (HandlePacket_A): Fix a few bugs.
- (HandlePacket_H): Return OK if target is not yet running.
- (HandlePacket_q): Return PID of 0 if target is not yet running.
- * testremotenub.cpp (RNBRunLoopGetArgsFromRemote): Implement.
- (RNBRunLoopLaunchInferior): Fetch arguments from context.
- (main) Store arguments in context, call RNBRunLoopGetArgsFromRemote
- if appropriate.
diff --git a/tools/debugserver/source/DNB.cpp b/tools/debugserver/source/DNB.cpp
deleted file mode 100644
index 4f212a73d64e..000000000000
--- a/tools/debugserver/source/DNB.cpp
+++ /dev/null
@@ -1,1780 +0,0 @@
-//===-- DNB.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 3/23/07.
-//
-//===----------------------------------------------------------------------===//
-
-#include "DNB.h"
-#include <inttypes.h>
-#include <libproc.h>
-#include <map>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/resource.h>
-#include <sys/stat.h>
-#include <sys/sysctl.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <vector>
-
-#if defined(__APPLE__)
-#include <pthread.h>
-#include <sched.h>
-#endif
-
-#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 "CFBundle.h"
-#include "CFString.h"
-#include "DNBDataRef.h"
-#include "DNBLog.h"
-#include "DNBThreadResumeActions.h"
-#include "DNBTimer.h"
-#include "MacOSX/DarwinLog/DarwinLogCollector.h"
-#include "MacOSX/Genealogy.h"
-#include "MacOSX/MachProcess.h"
-#include "MacOSX/MachTask.h"
-#include "MacOSX/ThreadInfo.h"
-
-typedef std::shared_ptr<MachProcess> MachProcessSP;
-typedef std::map<nub_process_t, MachProcessSP> ProcessMap;
-typedef ProcessMap::iterator ProcessMapIter;
-typedef ProcessMap::const_iterator ProcessMapConstIter;
-
-size_t GetAllInfos(std::vector<struct kinfo_proc> &proc_infos);
-static size_t
-GetAllInfosMatchingName(const char *process_name,
- std::vector<struct kinfo_proc> &matching_proc_infos);
-
-//----------------------------------------------------------------------
-// A Thread safe singleton to get a process map pointer.
-//
-// Returns a pointer to the existing process map, or a pointer to a
-// newly created process map if CAN_CREATE is non-zero.
-//----------------------------------------------------------------------
-static ProcessMap *GetProcessMap(bool can_create) {
- static ProcessMap *g_process_map_ptr = NULL;
-
- if (can_create && g_process_map_ptr == NULL) {
- static pthread_mutex_t g_process_map_mutex = PTHREAD_MUTEX_INITIALIZER;
- PTHREAD_MUTEX_LOCKER(locker, &g_process_map_mutex);
- if (g_process_map_ptr == NULL)
- g_process_map_ptr = new ProcessMap;
- }
- return g_process_map_ptr;
-}
-
-//----------------------------------------------------------------------
-// Add PID to the shared process pointer map.
-//
-// Return non-zero value if we succeed in adding the process to the map.
-// The only time this should fail is if we run out of memory and can't
-// allocate a ProcessMap.
-//----------------------------------------------------------------------
-static nub_bool_t AddProcessToMap(nub_process_t pid, MachProcessSP &procSP) {
- ProcessMap *process_map = GetProcessMap(true);
- if (process_map) {
- process_map->insert(std::make_pair(pid, procSP));
- return true;
- }
- return false;
-}
-
-//----------------------------------------------------------------------
-// Remove the shared pointer for PID from the process map.
-//
-// Returns the number of items removed from the process map.
-//----------------------------------------------------------------------
-// static size_t
-// RemoveProcessFromMap (nub_process_t pid)
-//{
-// ProcessMap* process_map = GetProcessMap(false);
-// if (process_map)
-// {
-// return process_map->erase(pid);
-// }
-// return 0;
-//}
-
-//----------------------------------------------------------------------
-// Get the shared pointer for PID from the existing process map.
-//
-// Returns true if we successfully find a shared pointer to a
-// MachProcess object.
-//----------------------------------------------------------------------
-static nub_bool_t GetProcessSP(nub_process_t pid, MachProcessSP &procSP) {
- ProcessMap *process_map = GetProcessMap(false);
- if (process_map != NULL) {
- ProcessMapIter pos = process_map->find(pid);
- if (pos != process_map->end()) {
- procSP = pos->second;
- return true;
- }
- }
- procSP.reset();
- return false;
-}
-
-#ifdef USE_KQUEUE
-void *kqueue_thread(void *arg) {
- int kq_id = (int)(intptr_t)arg;
-
-#if defined(__APPLE__)
- pthread_setname_np("kqueue thread");
-#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
- struct sched_param thread_param;
- int thread_sched_policy;
- if (pthread_getschedparam(pthread_self(), &thread_sched_policy,
- &thread_param) == 0) {
- thread_param.sched_priority = 47;
- pthread_setschedparam(pthread_self(), thread_sched_policy, &thread_param);
- }
-#endif
-#endif
-
- 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 = static_cast<int>(death_event.data);
- const char *error_str = strerror(error_no);
- 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;
- const pid_t pid = (pid_t)death_event.ident;
- const pid_t child_pid = waitpid(pid, &status, 0);
-
- bool exited = false;
- int signal = 0;
- int exit_status = 0;
- if (WIFSTOPPED(status)) {
- signal = WSTOPSIG(status);
- DNBLogThreadedIf(LOG_PROCESS, "waitpid (%i) -> STOPPED (signal = %i)",
- child_pid, signal);
- } else if (WIFEXITED(status)) {
- exit_status = WEXITSTATUS(status);
- exited = true;
- DNBLogThreadedIf(LOG_PROCESS, "waitpid (%i) -> EXITED (status = %i)",
- child_pid, exit_status);
- } else if (WIFSIGNALED(status)) {
- signal = WTERMSIG(status);
- if (child_pid == abs(pid)) {
- DNBLogThreadedIf(LOG_PROCESS,
- "waitpid (%i) -> SIGNALED and EXITED (signal = %i)",
- child_pid, signal);
- char exit_info[64];
- ::snprintf(exit_info, sizeof(exit_info),
- "Terminated due to signal %i", signal);
- DNBProcessSetExitInfo(child_pid, exit_info);
- exited = true;
- exit_status = INT8_MAX;
- } else {
- DNBLogThreadedIf(LOG_PROCESS,
- "waitpid (%i) -> SIGNALED (signal = %i)", child_pid,
- signal);
- }
- }
-
- if (exited) {
- if (death_event.data & NOTE_EXIT_MEMORY)
- DNBProcessSetExitInfo(child_pid, "Terminated due to memory issue");
- 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, exit_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_EXITSTATUS | 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) {
- const pid_t pid = (pid_t)(intptr_t)arg;
- int status;
-
-#if defined(__APPLE__)
- pthread_setname_np("waitpid thread");
-#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
- struct sched_param thread_param;
- int thread_sched_policy;
- if (pthread_getschedparam(pthread_self(), &thread_sched_policy,
- &thread_param) == 0) {
- thread_param.sched_priority = 47;
- pthread_setschedparam(pthread_self(), thread_sched_policy, &thread_param);
- }
-#endif
-#endif
-
- while (1) {
- pid_t child_pid = waitpid(pid, &status, 0);
- DNBLogThreadedIf(LOG_PROCESS, "waitpid_thread (): waitpid (pid = %i, "
- "&status, 0) => %i, status = %i, errno = %i",
- pid, child_pid, status, errno);
-
- if (child_pid < 0) {
- if (errno == EINTR)
- continue;
- break;
- } else {
- if (WIFSTOPPED(status)) {
- continue;
- } else // if (WIFEXITED(status) || WIFSIGNALED(status))
- {
- DNBLogThreadedIf(
- LOG_PROCESS,
- "waitpid_thread (): setting exit status for pid = %i to %i",
- child_pid, status);
- DNBProcessSetExitStatus(child_pid, status);
- return NULL;
- }
- }
- }
-
- // We should never exit as long as our child process is alive, so if we
- // do something else went wrong and we should exit...
- DNBLogThreadedIf(LOG_PROCESS, "waitpid_thread (): main loop exited, setting "
- "exit status to an invalid value (-1) for pid "
- "%i",
- pid);
- 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
- if (ret == 0) {
- ::pthread_detach(thread);
- return true;
- }
- return false;
-}
-
-nub_process_t DNBProcessLaunch(
- const char *path, char const *argv[], const char *envp[],
- const char *working_directory, // NULL => don't 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,
- const char *event_data, char *err_str, size_t err_len) {
- DNBLogThreadedIf(LOG_PROCESS, "%s ( path='%s', argv = %p, envp = %p, "
- "working_dir=%s, stdin=%s, stdout=%s, "
- "stderr=%s, no-stdio=%i, launch_flavor = %u, "
- "disable_aslr = %d, err = %p, err_len = "
- "%llu) called...",
- __FUNCTION__, path, static_cast<void *>(argv),
- static_cast<void *>(envp), working_directory, stdin_path,
- stdout_path, stderr_path, no_stdio, launch_flavor,
- disable_aslr, static_cast<void *>(err_str),
- static_cast<uint64_t>(err_len));
-
- if (err_str && err_len > 0)
- err_str[0] = '\0';
- struct stat path_stat;
- if (::stat(path, &path_stat) == -1) {
- char stat_error[256];
- ::strerror_r(errno, stat_error, sizeof(stat_error));
- snprintf(err_str, err_len, "%s (%s)", stat_error, path);
- return INVALID_NUB_PROCESS;
- }
-
- MachProcessSP processSP(new MachProcess);
- if (processSP.get()) {
- DNBError launch_err;
- pid_t pid = processSP->LaunchForDebug(path, argv, envp, working_directory,
- stdin_path, stdout_path, stderr_path,
- no_stdio, launch_flavor, disable_aslr,
- event_data, launch_err);
- if (err_str) {
- *err_str = '\0';
- if (launch_err.Fail()) {
- const char *launch_err_str = launch_err.AsString();
- if (launch_err_str) {
- strlcpy(err_str, launch_err_str, err_len - 1);
- err_str[err_len - 1] =
- '\0'; // Make sure the error string is terminated
- }
- }
- }
-
- DNBLogThreadedIf(LOG_PROCESS, "(DebugNub) new pid is %d...", pid);
-
- if (pid != INVALID_NUB_PROCESS) {
- // Spawn a thread to reap our child inferior process...
- spawn_waitpid_thread(pid);
-
- if (processSP->Task().TaskPortForProcessID(launch_err) == TASK_NULL) {
- // We failed to get the task for our process ID which is bad.
- // Kill our process otherwise it will be stopped at the entry
- // point and get reparented to someone else and never go away.
- DNBLog("Could not get task port for process, sending SIGKILL and "
- "exiting.");
- kill(SIGKILL, pid);
-
- if (err_str && err_len > 0) {
- if (launch_err.AsString()) {
- ::snprintf(err_str, err_len,
- "failed to get the task for process %i (%s)", pid,
- launch_err.AsString());
- } else {
- ::snprintf(err_str, err_len,
- "failed to get the task for process %i", pid);
- }
- }
- } else {
- bool res = AddProcessToMap(pid, processSP);
- UNUSED_IF_ASSERT_DISABLED(res);
- assert(res && "Couldn't add process to map!");
- return pid;
- }
- }
- }
- return INVALID_NUB_PROCESS;
-}
-
-// If there is one process with a given name, return the pid for that process.
-nub_process_t DNBProcessGetPIDByName(const char *name) {
- std::vector<struct kinfo_proc> matching_proc_infos;
- size_t num_matching_proc_infos =
- GetAllInfosMatchingName(name, matching_proc_infos);
- if (num_matching_proc_infos == 1) {
- return matching_proc_infos[0].kp_proc.p_pid;
- }
- return INVALID_NUB_PROCESS;
-}
-
-nub_process_t DNBProcessAttachByName(const char *name, struct timespec *timeout,
- char *err_str, size_t err_len) {
- if (err_str && err_len > 0)
- err_str[0] = '\0';
- std::vector<struct kinfo_proc> matching_proc_infos;
- size_t num_matching_proc_infos =
- GetAllInfosMatchingName(name, matching_proc_infos);
- if (num_matching_proc_infos == 0) {
- DNBLogError("error: no processes match '%s'\n", name);
- return INVALID_NUB_PROCESS;
- } else if (num_matching_proc_infos > 1) {
- DNBLogError("error: %llu processes match '%s':\n",
- (uint64_t)num_matching_proc_infos, name);
- size_t i;
- for (i = 0; i < num_matching_proc_infos; ++i)
- DNBLogError("%6u - %s\n", matching_proc_infos[i].kp_proc.p_pid,
- matching_proc_infos[i].kp_proc.p_comm);
- return INVALID_NUB_PROCESS;
- }
-
- return DNBProcessAttach(matching_proc_infos[0].kp_proc.p_pid, timeout,
- err_str, err_len);
-}
-
-nub_process_t DNBProcessAttach(nub_process_t attach_pid,
- struct timespec *timeout, char *err_str,
- size_t err_len) {
- if (err_str && err_len > 0)
- err_str[0] = '\0';
-
- pid_t pid = INVALID_NUB_PROCESS;
- MachProcessSP processSP(new MachProcess);
- if (processSP.get()) {
- DNBLogThreadedIf(LOG_PROCESS, "(DebugNub) attaching to pid %d...",
- attach_pid);
- pid = processSP->AttachForDebug(attach_pid, err_str, err_len);
-
- if (pid != INVALID_NUB_PROCESS) {
- bool res = AddProcessToMap(pid, processSP);
- UNUSED_IF_ASSERT_DISABLED(res);
- assert(res && "Couldn't add process to map!");
- spawn_waitpid_thread(pid);
- }
- }
-
- while (pid != INVALID_NUB_PROCESS) {
- // Wait for process to start up and hit entry point
- DNBLogThreadedIf(LOG_PROCESS, "%s DNBProcessWaitForEvent (%4.4x, "
- "eEventProcessRunningStateChanged | "
- "eEventProcessStoppedStateChanged, true, "
- "INFINITE)...",
- __FUNCTION__, pid);
- nub_event_t set_events =
- DNBProcessWaitForEvents(pid, eEventProcessRunningStateChanged |
- eEventProcessStoppedStateChanged,
- true, timeout);
-
- DNBLogThreadedIf(LOG_PROCESS, "%s DNBProcessWaitForEvent (%4.4x, "
- "eEventProcessRunningStateChanged | "
- "eEventProcessStoppedStateChanged, true, "
- "INFINITE) => 0x%8.8x",
- __FUNCTION__, pid, set_events);
-
- if (set_events == 0) {
- if (err_str && err_len > 0)
- snprintf(err_str, err_len, "operation timed out");
- pid = INVALID_NUB_PROCESS;
- } else {
- if (set_events & (eEventProcessRunningStateChanged |
- eEventProcessStoppedStateChanged)) {
- nub_state_t pid_state = DNBProcessGetState(pid);
- DNBLogThreadedIf(
- LOG_PROCESS,
- "%s process %4.4x state changed (eEventProcessStateChanged): %s",
- __FUNCTION__, pid, DNBStateAsString(pid_state));
-
- switch (pid_state) {
- case eStateInvalid:
- case eStateUnloaded:
- case eStateAttaching:
- case eStateLaunching:
- case eStateSuspended:
- break; // Ignore
-
- case eStateRunning:
- case eStateStepping:
- // Still waiting to stop at entry point...
- break;
-
- case eStateStopped:
- case eStateCrashed:
- return pid;
-
- case eStateDetached:
- case eStateExited:
- if (err_str && err_len > 0)
- snprintf(err_str, err_len, "process exited");
- return INVALID_NUB_PROCESS;
- }
- }
-
- DNBProcessResetEvents(pid, set_events);
- }
- }
-
- return INVALID_NUB_PROCESS;
-}
-
-size_t GetAllInfos(std::vector<struct kinfo_proc> &proc_infos) {
- size_t size = 0;
- int name[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL};
- u_int namelen = sizeof(name) / sizeof(int);
- int err;
-
- // Try to find out how many processes are around so we can
- // size the buffer appropriately. sysctl's man page specifically suggests
- // this approach, and says it returns a bit larger size than needed to
- // handle any new processes created between then and now.
-
- err = ::sysctl(name, namelen, NULL, &size, NULL, 0);
-
- if ((err < 0) && (err != ENOMEM)) {
- proc_infos.clear();
- perror("sysctl (mib, miblen, NULL, &num_processes, NULL, 0)");
- return 0;
- }
-
- // Increase the size of the buffer by a few processes in case more have
- // been spawned
- proc_infos.resize(size / sizeof(struct kinfo_proc));
- size = proc_infos.size() *
- sizeof(struct kinfo_proc); // Make sure we don't exceed our resize...
- err = ::sysctl(name, namelen, &proc_infos[0], &size, NULL, 0);
- if (err < 0) {
- proc_infos.clear();
- return 0;
- }
-
- // Trim down our array to fit what we actually got back
- proc_infos.resize(size / sizeof(struct kinfo_proc));
- return proc_infos.size();
-}
-
-static size_t
-GetAllInfosMatchingName(const char *full_process_name,
- std::vector<struct kinfo_proc> &matching_proc_infos) {
-
- matching_proc_infos.clear();
- if (full_process_name && full_process_name[0]) {
- // We only get the process name, not the full path, from the proc_info. So
- // just take the
- // base name of the process name...
- const char *process_name;
- process_name = strrchr(full_process_name, '/');
- if (process_name == NULL)
- process_name = full_process_name;
- else
- process_name++;
-
- const size_t process_name_len = strlen(process_name);
- std::vector<struct kinfo_proc> proc_infos;
- const size_t num_proc_infos = GetAllInfos(proc_infos);
- if (num_proc_infos > 0) {
- uint32_t i;
- for (i = 0; i < num_proc_infos; i++) {
- // Skip zombie processes and processes with unset status
- if (proc_infos[i].kp_proc.p_stat == 0 ||
- proc_infos[i].kp_proc.p_stat == SZOMB)
- continue;
-
- // Check for process by name. We only check the first MAXCOMLEN
- // chars as that is all that kp_proc.p_comm holds.
-
- if (::strncasecmp(process_name, proc_infos[i].kp_proc.p_comm,
- MAXCOMLEN) == 0) {
- if (process_name_len > MAXCOMLEN) {
- // We found a matching process name whose first MAXCOMLEN
- // characters match, but there is more to the name than
- // this. We need to get the full process name. Use proc_pidpath,
- // which will get
- // us the full path to the executed process.
-
- char proc_path_buf[PATH_MAX];
-
- int return_val = proc_pidpath(proc_infos[i].kp_proc.p_pid,
- proc_path_buf, PATH_MAX);
- if (return_val > 0) {
- // Okay, now search backwards from that to see if there is a
- // slash in the name. Note, even though we got all the args we
- // don't care
- // because the list data is just a bunch of concatenated null
- // terminated strings
- // so strrchr will start from the end of argv0.
-
- const char *argv_basename = strrchr(proc_path_buf, '/');
- if (argv_basename) {
- // Skip the '/'
- ++argv_basename;
- } else {
- // We didn't find a directory delimiter in the process argv[0],
- // just use what was in there
- argv_basename = proc_path_buf;
- }
-
- if (argv_basename) {
- if (::strncasecmp(process_name, argv_basename, PATH_MAX) == 0) {
- matching_proc_infos.push_back(proc_infos[i]);
- }
- }
- }
- } else {
- // We found a matching process, add it to our list
- matching_proc_infos.push_back(proc_infos[i]);
- }
- }
- }
- }
- }
- // return the newly added matches.
- return matching_proc_infos.size();
-}
-
-nub_process_t DNBProcessAttachWait(
- const char *waitfor_process_name, nub_launch_flavor_t launch_flavor,
- bool ignore_existing, struct timespec *timeout_abstime,
- useconds_t waitfor_interval, char *err_str, size_t err_len,
- DNBShouldCancelCallback should_cancel_callback, void *callback_data) {
- DNBError prepare_error;
- std::vector<struct kinfo_proc> exclude_proc_infos;
- size_t num_exclude_proc_infos;
-
- // If the PrepareForAttach returns a valid token, use MachProcess to check
- // for the process, otherwise scan the process table.
-
- const void *attach_token = MachProcess::PrepareForAttach(
- waitfor_process_name, launch_flavor, true, prepare_error);
-
- if (prepare_error.Fail()) {
- DNBLogError("Error in PrepareForAttach: %s", prepare_error.AsString());
- return INVALID_NUB_PROCESS;
- }
-
- if (attach_token == NULL) {
- if (ignore_existing)
- num_exclude_proc_infos =
- GetAllInfosMatchingName(waitfor_process_name, exclude_proc_infos);
- else
- num_exclude_proc_infos = 0;
- }
-
- DNBLogThreadedIf(LOG_PROCESS, "Waiting for '%s' to appear...\n",
- waitfor_process_name);
-
- // Loop and try to find the process by name
- nub_process_t waitfor_pid = INVALID_NUB_PROCESS;
-
- while (waitfor_pid == INVALID_NUB_PROCESS) {
- if (attach_token != NULL) {
- nub_process_t pid;
- pid = MachProcess::CheckForProcess(attach_token, launch_flavor);
- if (pid != INVALID_NUB_PROCESS) {
- waitfor_pid = pid;
- break;
- }
- } else {
-
- // Get the current process list, and check for matches that
- // aren't in our original list. If anyone wants to attach
- // to an existing process by name, they should do it with
- // --attach=PROCNAME. Else we will wait for the first matching
- // process that wasn't in our exclusion list.
- std::vector<struct kinfo_proc> proc_infos;
- const size_t num_proc_infos =
- GetAllInfosMatchingName(waitfor_process_name, proc_infos);
- for (size_t i = 0; i < num_proc_infos; i++) {
- nub_process_t curr_pid = proc_infos[i].kp_proc.p_pid;
- for (size_t j = 0; j < num_exclude_proc_infos; j++) {
- if (curr_pid == exclude_proc_infos[j].kp_proc.p_pid) {
- // This process was in our exclusion list, don't use it.
- curr_pid = INVALID_NUB_PROCESS;
- break;
- }
- }
-
- // If we didn't find CURR_PID in our exclusion list, then use it.
- if (curr_pid != INVALID_NUB_PROCESS) {
- // We found our process!
- waitfor_pid = curr_pid;
- break;
- }
- }
- }
-
- // If we haven't found our process yet, check for a timeout
- // and then sleep for a bit until we poll again.
- if (waitfor_pid == INVALID_NUB_PROCESS) {
- if (timeout_abstime != NULL) {
- // Check to see if we have a waitfor-duration option that
- // has timed out?
- if (DNBTimer::TimeOfDayLaterThan(*timeout_abstime)) {
- if (err_str && err_len > 0)
- snprintf(err_str, err_len, "operation timed out");
- DNBLogError("error: waiting for process '%s' timed out.\n",
- waitfor_process_name);
- return INVALID_NUB_PROCESS;
- }
- }
-
- // Call the should cancel callback as well...
-
- if (should_cancel_callback != NULL &&
- should_cancel_callback(callback_data)) {
- DNBLogThreadedIf(
- LOG_PROCESS,
- "DNBProcessAttachWait cancelled by should_cancel callback.");
- waitfor_pid = INVALID_NUB_PROCESS;
- break;
- }
-
- ::usleep(waitfor_interval); // Sleep for WAITFOR_INTERVAL, then poll again
- }
- }
-
- if (waitfor_pid != INVALID_NUB_PROCESS) {
- DNBLogThreadedIf(LOG_PROCESS, "Attaching to %s with pid %i...\n",
- waitfor_process_name, waitfor_pid);
- waitfor_pid =
- DNBProcessAttach(waitfor_pid, timeout_abstime, err_str, err_len);
- }
-
- bool success = waitfor_pid != INVALID_NUB_PROCESS;
- MachProcess::CleanupAfterAttach(attach_token, launch_flavor, success,
- prepare_error);
-
- return waitfor_pid;
-}
-
-nub_bool_t DNBProcessDetach(nub_process_t pid) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP)) {
- const bool remove = true;
- DNBLogThreaded(
- "Disabling breakpoints and watchpoints, and detaching from %d.", pid);
- procSP->DisableAllBreakpoints(remove);
- procSP->DisableAllWatchpoints(remove);
- return procSP->Detach();
- }
- return false;
-}
-
-nub_bool_t DNBProcessKill(nub_process_t pid) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP)) {
- return procSP->Kill();
- }
- return false;
-}
-
-nub_bool_t DNBProcessSignal(nub_process_t pid, int signal) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP)) {
- return procSP->Signal(signal);
- }
- return false;
-}
-
-nub_bool_t DNBProcessInterrupt(nub_process_t pid) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- return procSP->Interrupt();
- 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) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP)) {
- return MachTask::IsValid(procSP->Task().TaskPort());
- }
- return eStateInvalid;
-}
-
-//----------------------------------------------------------------------
-// Process and Thread state information
-//----------------------------------------------------------------------
-nub_state_t DNBProcessGetState(nub_process_t pid) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP)) {
- return procSP->GetState();
- }
- return eStateInvalid;
-}
-
-//----------------------------------------------------------------------
-// Process and Thread state information
-//----------------------------------------------------------------------
-nub_bool_t DNBProcessGetExitStatus(nub_process_t pid, int *status) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP)) {
- return procSP->GetExitStatus(status);
- }
- return false;
-}
-
-nub_bool_t DNBProcessSetExitStatus(nub_process_t pid, int status) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP)) {
- procSP->SetExitStatus(status);
- return true;
- }
- 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) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- return procSP->ThreadGetName(tid);
- return NULL;
-}
-
-nub_bool_t
-DNBThreadGetIdentifierInfo(nub_process_t pid, nub_thread_t tid,
- thread_identifier_info_data_t *ident_info) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- return procSP->GetThreadList().GetIdentifierInfo(tid, ident_info);
- return false;
-}
-
-nub_state_t DNBThreadGetState(nub_process_t pid, nub_thread_t tid) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP)) {
- return procSP->ThreadGetState(tid);
- }
- return eStateInvalid;
-}
-
-const char *DNBStateAsString(nub_state_t state) {
- switch (state) {
- case eStateInvalid:
- return "Invalid";
- case eStateUnloaded:
- return "Unloaded";
- case eStateAttaching:
- return "Attaching";
- case eStateLaunching:
- return "Launching";
- case eStateStopped:
- return "Stopped";
- case eStateRunning:
- return "Running";
- case eStateStepping:
- return "Stepping";
- case eStateCrashed:
- return "Crashed";
- case eStateDetached:
- return "Detached";
- case eStateExited:
- return "Exited";
- case eStateSuspended:
- return "Suspended";
- }
- return "nub_state_t ???";
-}
-
-Genealogy::ThreadActivitySP DNBGetGenealogyInfoForThread(nub_process_t pid,
- nub_thread_t tid,
- bool &timed_out) {
- Genealogy::ThreadActivitySP thread_activity_sp;
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- thread_activity_sp = procSP->GetGenealogyInfoForThread(tid, timed_out);
- return thread_activity_sp;
-}
-
-Genealogy::ProcessExecutableInfoSP DNBGetGenealogyImageInfo(nub_process_t pid,
- size_t idx) {
- Genealogy::ProcessExecutableInfoSP image_info_sp;
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP)) {
- image_info_sp = procSP->GetGenealogyImageInfo(idx);
- }
- return image_info_sp;
-}
-
-ThreadInfo::QoS DNBGetRequestedQoSForThread(nub_process_t pid, nub_thread_t tid,
- nub_addr_t tsd,
- uint64_t dti_qos_class_index) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP)) {
- return procSP->GetRequestedQoS(tid, tsd, dti_qos_class_index);
- }
- return ThreadInfo::QoS();
-}
-
-nub_addr_t DNBGetPThreadT(nub_process_t pid, nub_thread_t tid) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP)) {
- return procSP->GetPThreadT(tid);
- }
- return INVALID_NUB_ADDRESS;
-}
-
-nub_addr_t DNBGetDispatchQueueT(nub_process_t pid, nub_thread_t tid) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP)) {
- return procSP->GetDispatchQueueT(tid);
- }
- return INVALID_NUB_ADDRESS;
-}
-
-nub_addr_t
-DNBGetTSDAddressForThread(nub_process_t pid, nub_thread_t tid,
- uint64_t plo_pthread_tsd_base_address_offset,
- uint64_t plo_pthread_tsd_base_offset,
- uint64_t plo_pthread_tsd_entry_size) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP)) {
- return procSP->GetTSDAddressForThread(
- tid, plo_pthread_tsd_base_address_offset, plo_pthread_tsd_base_offset,
- plo_pthread_tsd_entry_size);
- }
- return INVALID_NUB_ADDRESS;
-}
-
-JSONGenerator::ObjectSP DNBGetLoadedDynamicLibrariesInfos(
- nub_process_t pid, nub_addr_t image_list_address, nub_addr_t image_count) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP)) {
- return procSP->GetLoadedDynamicLibrariesInfos(pid, image_list_address,
- image_count);
- }
- return JSONGenerator::ObjectSP();
-}
-
-JSONGenerator::ObjectSP DNBGetAllLoadedLibrariesInfos(nub_process_t pid) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP)) {
- return procSP->GetAllLoadedLibrariesInfos(pid);
- }
- return JSONGenerator::ObjectSP();
-}
-
-JSONGenerator::ObjectSP
-DNBGetLibrariesInfoForAddresses(nub_process_t pid,
- std::vector<uint64_t> &macho_addresses) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP)) {
- return procSP->GetLibrariesInfoForAddresses(pid, macho_addresses);
- }
- return JSONGenerator::ObjectSP();
-}
-
-JSONGenerator::ObjectSP DNBGetSharedCacheInfo(nub_process_t pid) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP)) {
- return procSP->GetSharedCacheInfo(pid);
- }
- return JSONGenerator::ObjectSP();
-}
-
-const char *DNBProcessGetExecutablePath(nub_process_t pid) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP)) {
- return procSP->Path();
- }
- return NULL;
-}
-
-nub_size_t DNBProcessGetArgumentCount(nub_process_t pid) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP)) {
- return procSP->ArgumentCount();
- }
- return 0;
-}
-
-const char *DNBProcessGetArgumentAtIndex(nub_process_t pid, nub_size_t idx) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP)) {
- return procSP->ArgumentAtIndex(idx);
- }
- return NULL;
-}
-
-//----------------------------------------------------------------------
-// Execution control
-//----------------------------------------------------------------------
-nub_bool_t DNBProcessResume(nub_process_t pid,
- const DNBThreadResumeAction *actions,
- size_t num_actions) {
- DNBLogThreadedIf(LOG_PROCESS, "%s(pid = %4.4x)", __FUNCTION__, pid);
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP)) {
- DNBThreadResumeActions thread_actions(actions, num_actions);
-
- // Below we add a default thread plan just in case one wasn't
- // provided so all threads always know what they were supposed to do
- if (thread_actions.IsEmpty()) {
- // No thread plans were given, so the default it to run all threads
- thread_actions.SetDefaultThreadActionIfNeeded(eStateRunning, 0);
- } else {
- // Some thread plans were given which means anything that wasn't
- // specified should remain stopped.
- thread_actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0);
- }
- return procSP->Resume(thread_actions);
- }
- return false;
-}
-
-nub_bool_t DNBProcessHalt(nub_process_t pid) {
- DNBLogThreadedIf(LOG_PROCESS, "%s(pid = %4.4x)", __FUNCTION__, pid);
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- return procSP->Signal(SIGSTOP);
- return false;
-}
-//
-// nub_bool_t
-// DNBThreadResume (nub_process_t pid, nub_thread_t tid, nub_bool_t step)
-//{
-// DNBLogThreadedIf(LOG_THREAD, "%s(pid = %4.4x, tid = %4.4x, step = %u)",
-// __FUNCTION__, pid, tid, (uint32_t)step);
-// MachProcessSP procSP;
-// if (GetProcessSP (pid, procSP))
-// {
-// return procSP->Resume(tid, step, 0);
-// }
-// return false;
-//}
-//
-// nub_bool_t
-// DNBThreadResumeWithSignal (nub_process_t pid, nub_thread_t tid, nub_bool_t
-// step, int signal)
-//{
-// DNBLogThreadedIf(LOG_THREAD, "%s(pid = %4.4x, tid = %4.4x, step = %u,
-// signal = %i)", __FUNCTION__, pid, tid, (uint32_t)step, signal);
-// MachProcessSP procSP;
-// if (GetProcessSP (pid, procSP))
-// {
-// return procSP->Resume(tid, step, signal);
-// }
-// return false;
-//}
-
-nub_event_t DNBProcessWaitForEvents(nub_process_t pid, nub_event_t event_mask,
- bool wait_for_set,
- struct timespec *timeout) {
- nub_event_t result = 0;
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP)) {
- if (wait_for_set)
- result = procSP->Events().WaitForSetEvents(event_mask, timeout);
- else
- result = procSP->Events().WaitForEventsToReset(event_mask, timeout);
- }
- return result;
-}
-
-void DNBProcessResetEvents(nub_process_t pid, nub_event_t event_mask) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- procSP->Events().ResetEvents(event_mask);
-}
-
-// Breakpoints
-nub_bool_t DNBBreakpointSet(nub_process_t pid, nub_addr_t addr, nub_size_t size,
- nub_bool_t hardware) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- return procSP->CreateBreakpoint(addr, size, hardware) != NULL;
- return false;
-}
-
-nub_bool_t DNBBreakpointClear(nub_process_t pid, nub_addr_t addr) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- return procSP->DisableBreakpoint(addr, true);
- return false; // Failed
-}
-
-//----------------------------------------------------------------------
-// Watchpoints
-//----------------------------------------------------------------------
-nub_bool_t DNBWatchpointSet(nub_process_t pid, nub_addr_t addr, nub_size_t size,
- uint32_t watch_flags, nub_bool_t hardware) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- return procSP->CreateWatchpoint(addr, size, watch_flags, hardware) != NULL;
- return false;
-}
-
-nub_bool_t DNBWatchpointClear(nub_process_t pid, nub_addr_t addr) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- return procSP->DisableWatchpoint(addr, true);
- return false; // Failed
-}
-
-//----------------------------------------------------------------------
-// Return the number of supported hardware watchpoints.
-//----------------------------------------------------------------------
-uint32_t DNBWatchpointGetNumSupportedHWP(nub_process_t pid) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- return procSP->GetNumSupportedHardwareWatchpoints();
- return 0;
-}
-
-//----------------------------------------------------------------------
-// Read memory in the address space of process PID. This call will take
-// care of setting and restoring permissions and breaking up the memory
-// read into multiple chunks as required.
-//
-// RETURNS: number of bytes actually read
-//----------------------------------------------------------------------
-nub_size_t DNBProcessMemoryRead(nub_process_t pid, nub_addr_t addr,
- nub_size_t size, void *buf) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- return procSP->ReadMemory(addr, size, buf);
- return 0;
-}
-
-uint64_t DNBProcessMemoryReadInteger(nub_process_t pid, nub_addr_t addr,
- nub_size_t integer_size,
- uint64_t fail_value) {
- union Integers {
- uint8_t u8;
- uint16_t u16;
- uint32_t u32;
- uint64_t u64;
- };
-
- if (integer_size <= sizeof(uint64_t)) {
- Integers ints;
- if (DNBProcessMemoryRead(pid, addr, integer_size, &ints) == integer_size) {
- switch (integer_size) {
- case 1:
- return ints.u8;
- case 2:
- return ints.u16;
- case 3:
- return ints.u32 & 0xffffffu;
- case 4:
- return ints.u32;
- case 5:
- return ints.u32 & 0x000000ffffffffffull;
- case 6:
- return ints.u32 & 0x0000ffffffffffffull;
- case 7:
- return ints.u32 & 0x00ffffffffffffffull;
- case 8:
- return ints.u64;
- }
- }
- }
- return fail_value;
-}
-
-nub_addr_t DNBProcessMemoryReadPointer(nub_process_t pid, nub_addr_t addr) {
- cpu_type_t cputype = DNBProcessGetCPUType(pid);
- if (cputype) {
- const nub_size_t pointer_size = (cputype & CPU_ARCH_ABI64) ? 8 : 4;
- return DNBProcessMemoryReadInteger(pid, addr, pointer_size, 0);
- }
- return 0;
-}
-
-std::string DNBProcessMemoryReadCString(nub_process_t pid, nub_addr_t addr) {
- std::string cstr;
- char buffer[256];
- const nub_size_t max_buffer_cstr_length = sizeof(buffer) - 1;
- buffer[max_buffer_cstr_length] = '\0';
- nub_size_t length = 0;
- nub_addr_t curr_addr = addr;
- do {
- nub_size_t bytes_read =
- DNBProcessMemoryRead(pid, curr_addr, max_buffer_cstr_length, buffer);
- if (bytes_read == 0)
- break;
- length = strlen(buffer);
- cstr.append(buffer, length);
- curr_addr += length;
- } while (length == max_buffer_cstr_length);
- return cstr;
-}
-
-std::string DNBProcessMemoryReadCStringFixed(nub_process_t pid, nub_addr_t addr,
- nub_size_t fixed_length) {
- std::string cstr;
- char buffer[fixed_length + 1];
- buffer[fixed_length] = '\0';
- nub_size_t bytes_read = DNBProcessMemoryRead(pid, addr, fixed_length, buffer);
- if (bytes_read > 0)
- cstr.assign(buffer);
- return cstr;
-}
-
-//----------------------------------------------------------------------
-// Write memory to the address space of process PID. This call will take
-// care of setting and restoring permissions and breaking up the memory
-// write into multiple chunks as required.
-//
-// RETURNS: number of bytes actually written
-//----------------------------------------------------------------------
-nub_size_t DNBProcessMemoryWrite(nub_process_t pid, nub_addr_t addr,
- nub_size_t size, const void *buf) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- return procSP->WriteMemory(addr, size, buf);
- return 0;
-}
-
-nub_addr_t DNBProcessMemoryAllocate(nub_process_t pid, nub_size_t size,
- uint32_t permissions) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- return procSP->Task().AllocateMemory(size, permissions);
- return 0;
-}
-
-nub_bool_t DNBProcessMemoryDeallocate(nub_process_t pid, nub_addr_t addr) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- return procSP->Task().DeallocateMemory(addr);
- return 0;
-}
-
-//----------------------------------------------------------------------
-// Find attributes of the memory region that contains ADDR for process PID,
-// if possible, and return a string describing those attributes.
-//
-// Returns 1 if we could find attributes for this region and OUTBUF can
-// be sent to the remote debugger.
-//
-// Returns 0 if we couldn't find the attributes for a region of memory at
-// that address and OUTBUF should not be sent.
-//
-// Returns -1 if this platform cannot look up information about memory regions
-// or if we do not yet have a valid launched process.
-//
-//----------------------------------------------------------------------
-int DNBProcessMemoryRegionInfo(nub_process_t pid, nub_addr_t addr,
- DNBRegionInfo *region_info) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- return procSP->Task().GetMemoryRegionInfo(addr, region_info);
-
- return -1;
-}
-
-std::string DNBProcessGetProfileData(nub_process_t pid,
- DNBProfileDataScanType scanType) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- return procSP->Task().GetProfileData(scanType);
-
- return std::string("");
-}
-
-nub_bool_t DNBProcessSetEnableAsyncProfiling(nub_process_t pid,
- nub_bool_t enable,
- uint64_t interval_usec,
- DNBProfileDataScanType scan_type) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP)) {
- procSP->SetEnableAsyncProfiling(enable, interval_usec, scan_type);
- return true;
- }
-
- return false;
-}
-
-//----------------------------------------------------------------------
-// Get the number of threads for the specified process.
-//----------------------------------------------------------------------
-nub_size_t DNBProcessGetNumThreads(nub_process_t pid) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- return procSP->GetNumThreads();
- return 0;
-}
-
-//----------------------------------------------------------------------
-// Get the thread ID of the current thread.
-//----------------------------------------------------------------------
-nub_thread_t DNBProcessGetCurrentThread(nub_process_t pid) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- return procSP->GetCurrentThread();
- return 0;
-}
-
-//----------------------------------------------------------------------
-// Get the mach port number of the current thread.
-//----------------------------------------------------------------------
-nub_thread_t DNBProcessGetCurrentThreadMachPort(nub_process_t pid) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- return procSP->GetCurrentThreadMachPort();
- return 0;
-}
-
-//----------------------------------------------------------------------
-// Change the current thread.
-//----------------------------------------------------------------------
-nub_thread_t DNBProcessSetCurrentThread(nub_process_t pid, nub_thread_t tid) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- return procSP->SetCurrentThread(tid);
- return INVALID_NUB_THREAD;
-}
-
-//----------------------------------------------------------------------
-// Dump a string describing a thread's stop reason to the specified file
-// handle
-//----------------------------------------------------------------------
-nub_bool_t DNBThreadGetStopReason(nub_process_t pid, nub_thread_t tid,
- struct DNBThreadStopInfo *stop_info) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- return procSP->GetThreadStoppedReason(tid, stop_info);
- return false;
-}
-
-//----------------------------------------------------------------------
-// Return string description for the specified thread.
-//
-// RETURNS: NULL if the thread isn't valid, else a NULL terminated C
-// string from a static buffer that must be copied prior to subsequent
-// calls.
-//----------------------------------------------------------------------
-const char *DNBThreadGetInfo(nub_process_t pid, nub_thread_t tid) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- return procSP->GetThreadInfo(tid);
- return NULL;
-}
-
-//----------------------------------------------------------------------
-// Get the thread ID given a thread index.
-//----------------------------------------------------------------------
-nub_thread_t DNBProcessGetThreadAtIndex(nub_process_t pid, size_t thread_idx) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- return procSP->GetThreadAtIndex(thread_idx);
- return INVALID_NUB_THREAD;
-}
-
-//----------------------------------------------------------------------
-// Do whatever is needed to sync the thread's register state with it's kernel
-// values.
-//----------------------------------------------------------------------
-nub_bool_t DNBProcessSyncThreadState(nub_process_t pid, nub_thread_t tid) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- return procSP->SyncThreadState(tid);
- return false;
-}
-
-nub_addr_t DNBProcessGetSharedLibraryInfoAddress(nub_process_t pid) {
- MachProcessSP procSP;
- DNBError err;
- if (GetProcessSP(pid, procSP))
- return procSP->Task().GetDYLDAllImageInfosAddress(err);
- return INVALID_NUB_ADDRESS;
-}
-
-nub_bool_t DNBProcessSharedLibrariesUpdated(nub_process_t pid) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP)) {
- procSP->SharedLibrariesUpdated();
- return true;
- }
- return false;
-}
-
-const char *DNBGetDeploymentInfo(nub_process_t pid,
- const struct load_command& lc,
- uint64_t load_command_address,
- uint32_t& major_version,
- uint32_t& minor_version,
- uint32_t& patch_version) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- return procSP->GetDeploymentInfo(lc, load_command_address,
- major_version, minor_version,
- patch_version);
- return nullptr;
-}
-
-
-//----------------------------------------------------------------------
-// Get the current shared library information for a process. Only return
-// the shared libraries that have changed since the last shared library
-// state changed event if only_changed is non-zero.
-//----------------------------------------------------------------------
-nub_size_t
-DNBProcessGetSharedLibraryInfo(nub_process_t pid, nub_bool_t only_changed,
- struct DNBExecutableImageInfo **image_infos) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- return procSP->CopyImageInfos(image_infos, only_changed);
-
- // If we have no process, then return NULL for the shared library info
- // and zero for shared library count
- *image_infos = NULL;
- return 0;
-}
-
-uint32_t DNBGetRegisterCPUType() {
- return DNBArchProtocol::GetRegisterCPUType();
-}
-//----------------------------------------------------------------------
-// Get the register set information for a specific thread.
-//----------------------------------------------------------------------
-const DNBRegisterSetInfo *DNBGetRegisterSetInfo(nub_size_t *num_reg_sets) {
- return DNBArchProtocol::GetRegisterSetInfo(num_reg_sets);
-}
-
-//----------------------------------------------------------------------
-// Read a register value by register set and register index.
-//----------------------------------------------------------------------
-nub_bool_t DNBThreadGetRegisterValueByID(nub_process_t pid, nub_thread_t tid,
- uint32_t set, uint32_t reg,
- DNBRegisterValue *value) {
- MachProcessSP procSP;
- ::bzero(value, sizeof(DNBRegisterValue));
- if (GetProcessSP(pid, procSP)) {
- if (tid != INVALID_NUB_THREAD)
- return procSP->GetRegisterValue(tid, set, reg, value);
- }
- return false;
-}
-
-nub_bool_t DNBThreadSetRegisterValueByID(nub_process_t pid, nub_thread_t tid,
- uint32_t set, uint32_t reg,
- const DNBRegisterValue *value) {
- if (tid != INVALID_NUB_THREAD) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- return procSP->SetRegisterValue(tid, set, reg, value);
- }
- return false;
-}
-
-nub_size_t DNBThreadGetRegisterContext(nub_process_t pid, nub_thread_t tid,
- void *buf, size_t buf_len) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP)) {
- if (tid != INVALID_NUB_THREAD)
- return procSP->GetThreadList().GetRegisterContext(tid, buf, buf_len);
- }
- ::bzero(buf, buf_len);
- return 0;
-}
-
-nub_size_t DNBThreadSetRegisterContext(nub_process_t pid, nub_thread_t tid,
- const void *buf, size_t buf_len) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP)) {
- if (tid != INVALID_NUB_THREAD)
- return procSP->GetThreadList().SetRegisterContext(tid, buf, buf_len);
- }
- return 0;
-}
-
-uint32_t DNBThreadSaveRegisterState(nub_process_t pid, nub_thread_t tid) {
- if (tid != INVALID_NUB_THREAD) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- return procSP->GetThreadList().SaveRegisterState(tid);
- }
- return 0;
-}
-nub_bool_t DNBThreadRestoreRegisterState(nub_process_t pid, nub_thread_t tid,
- uint32_t save_id) {
- if (tid != INVALID_NUB_THREAD) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- return procSP->GetThreadList().RestoreRegisterState(tid, save_id);
- }
- return false;
-}
-
-//----------------------------------------------------------------------
-// Read a register value by name.
-//----------------------------------------------------------------------
-nub_bool_t DNBThreadGetRegisterValueByName(nub_process_t pid, nub_thread_t tid,
- uint32_t reg_set,
- const char *reg_name,
- DNBRegisterValue *value) {
- MachProcessSP procSP;
- ::bzero(value, sizeof(DNBRegisterValue));
- if (GetProcessSP(pid, procSP)) {
- const struct DNBRegisterSetInfo *set_info;
- nub_size_t num_reg_sets = 0;
- set_info = DNBGetRegisterSetInfo(&num_reg_sets);
- if (set_info) {
- uint32_t set = reg_set;
- uint32_t reg;
- if (set == REGISTER_SET_ALL) {
- for (set = 1; set < num_reg_sets; ++set) {
- for (reg = 0; reg < set_info[set].num_registers; ++reg) {
- if (strcasecmp(reg_name, set_info[set].registers[reg].name) == 0)
- return procSP->GetRegisterValue(tid, set, reg, value);
- }
- }
- } else {
- for (reg = 0; reg < set_info[set].num_registers; ++reg) {
- if (strcasecmp(reg_name, set_info[set].registers[reg].name) == 0)
- return procSP->GetRegisterValue(tid, set, reg, value);
- }
- }
- }
- }
- return false;
-}
-
-//----------------------------------------------------------------------
-// Read a register set and register number from the register name.
-//----------------------------------------------------------------------
-nub_bool_t DNBGetRegisterInfoByName(const char *reg_name,
- DNBRegisterInfo *info) {
- const struct DNBRegisterSetInfo *set_info;
- nub_size_t num_reg_sets = 0;
- set_info = DNBGetRegisterSetInfo(&num_reg_sets);
- if (set_info) {
- uint32_t set, reg;
- for (set = 1; set < num_reg_sets; ++set) {
- for (reg = 0; reg < set_info[set].num_registers; ++reg) {
- if (strcasecmp(reg_name, set_info[set].registers[reg].name) == 0) {
- *info = set_info[set].registers[reg];
- return true;
- }
- }
- }
-
- for (set = 1; set < num_reg_sets; ++set) {
- uint32_t reg;
- for (reg = 0; reg < set_info[set].num_registers; ++reg) {
- if (set_info[set].registers[reg].alt == NULL)
- continue;
-
- if (strcasecmp(reg_name, set_info[set].registers[reg].alt) == 0) {
- *info = set_info[set].registers[reg];
- return true;
- }
- }
- }
- }
-
- ::bzero(info, sizeof(DNBRegisterInfo));
- return false;
-}
-
-//----------------------------------------------------------------------
-// Set the name to address callback function that this nub can use
-// for any name to address lookups that are needed.
-//----------------------------------------------------------------------
-nub_bool_t DNBProcessSetNameToAddressCallback(nub_process_t pid,
- DNBCallbackNameToAddress callback,
- void *baton) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP)) {
- procSP->SetNameToAddressCallback(callback, baton);
- return true;
- }
- return false;
-}
-
-//----------------------------------------------------------------------
-// Set the name to address callback function that this nub can use
-// for any name to address lookups that are needed.
-//----------------------------------------------------------------------
-nub_bool_t DNBProcessSetSharedLibraryInfoCallback(
- nub_process_t pid, DNBCallbackCopyExecutableImageInfos callback,
- void *baton) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP)) {
- procSP->SetSharedLibraryInfoCallback(callback, baton);
- return true;
- }
- return false;
-}
-
-nub_addr_t DNBProcessLookupAddress(nub_process_t pid, const char *name,
- const char *shlib) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP)) {
- return procSP->LookupSymbol(name, shlib);
- }
- return INVALID_NUB_ADDRESS;
-}
-
-nub_size_t DNBProcessGetAvailableSTDOUT(nub_process_t pid, char *buf,
- nub_size_t buf_size) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- return procSP->GetAvailableSTDOUT(buf, buf_size);
- return 0;
-}
-
-nub_size_t DNBProcessGetAvailableSTDERR(nub_process_t pid, char *buf,
- nub_size_t buf_size) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- return procSP->GetAvailableSTDERR(buf, buf_size);
- return 0;
-}
-
-nub_size_t DNBProcessGetAvailableProfileData(nub_process_t pid, char *buf,
- nub_size_t buf_size) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- return procSP->GetAsyncProfileData(buf, buf_size);
- return 0;
-}
-
-DarwinLogEventVector DNBProcessGetAvailableDarwinLogEvents(nub_process_t pid) {
- return DarwinLogCollector::GetEventsForProcess(pid);
-}
-
-nub_size_t DNBProcessGetStopCount(nub_process_t pid) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- return procSP->StopCount();
- return 0;
-}
-
-uint32_t DNBProcessGetCPUType(nub_process_t pid) {
- MachProcessSP procSP;
- if (GetProcessSP(pid, procSP))
- return procSP->GetCPUType();
- return 0;
-}
-
-nub_bool_t DNBResolveExecutablePath(const char *path, char *resolved_path,
- size_t resolved_path_size) {
- if (path == NULL || path[0] == '\0')
- return false;
-
- char max_path[PATH_MAX];
- std::string result;
- CFString::GlobPath(path, result);
-
- if (result.empty())
- result = path;
-
- struct stat path_stat;
- if (::stat(path, &path_stat) == 0) {
- if ((path_stat.st_mode & S_IFMT) == S_IFDIR) {
- CFBundle bundle(path);
- CFReleaser<CFURLRef> url(bundle.CopyExecutableURL());
- if (url.get()) {
- if (::CFURLGetFileSystemRepresentation(
- url.get(), true, (UInt8 *)resolved_path, resolved_path_size))
- return true;
- }
- }
- }
-
- if (realpath(path, max_path)) {
- // Found the path relatively...
- ::strlcpy(resolved_path, max_path, resolved_path_size);
- return strlen(resolved_path) + 1 < resolved_path_size;
- } else {
- // Not a relative path, check the PATH environment variable if the
- const char *PATH = getenv("PATH");
- if (PATH) {
- const char *curr_path_start = PATH;
- const char *curr_path_end;
- while (curr_path_start && *curr_path_start) {
- curr_path_end = strchr(curr_path_start, ':');
- if (curr_path_end == NULL) {
- result.assign(curr_path_start);
- curr_path_start = NULL;
- } else if (curr_path_end > curr_path_start) {
- size_t len = curr_path_end - curr_path_start;
- result.assign(curr_path_start, len);
- curr_path_start += len + 1;
- } else
- break;
-
- result += '/';
- result += path;
- struct stat s;
- if (stat(result.c_str(), &s) == 0) {
- ::strlcpy(resolved_path, result.c_str(), resolved_path_size);
- return result.size() + 1 < resolved_path_size;
- }
- }
- }
- }
- return false;
-}
-
-bool DNBGetOSVersionNumbers(uint64_t *major, uint64_t *minor, uint64_t *patch) {
- return MachProcess::GetOSVersionNumbers(major, minor, patch);
-}
-
-void DNBInitialize() {
- DNBLogThreadedIf(LOG_PROCESS, "DNBInitialize ()");
-#if defined(__i386__) || defined(__x86_64__)
- DNBArchImplI386::Initialize();
- DNBArchImplX86_64::Initialize();
-#elif defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
- DNBArchMachARM::Initialize();
- DNBArchMachARM64::Initialize();
-#endif
-}
-
-void DNBTerminate() {}
-
-nub_bool_t DNBSetArchitecture(const char *arch) {
- if (arch && arch[0]) {
- if (strcasecmp(arch, "i386") == 0)
- 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 ||
- strstr(arch, "aarch64") == arch)
- return DNBArchProtocol::SetArchitecture(CPU_TYPE_ARM64);
- else if (strstr(arch, "arm") == arch)
- return DNBArchProtocol::SetArchitecture(CPU_TYPE_ARM);
- }
- return false;
-}
diff --git a/tools/debugserver/source/DNB.h b/tools/debugserver/source/DNB.h
deleted file mode 100644
index bce2c6abafd1..000000000000
--- a/tools/debugserver/source/DNB.h
+++ /dev/null
@@ -1,247 +0,0 @@
-//===-- DNB.h ---------------------------------------------------*- 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 3/23/07.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __DNB_h__
-#define __DNB_h__
-
-#include "DNBDefs.h"
-#include "JSONGenerator.h"
-#include "MacOSX/DarwinLog/DarwinLogEvent.h"
-#include "MacOSX/Genealogy.h"
-#include "MacOSX/ThreadInfo.h"
-#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();
-void DNBTerminate();
-
-nub_bool_t DNBSetArchitecture(const char *arch);
-
-//----------------------------------------------------------------------
-// Process control
-//----------------------------------------------------------------------
-nub_process_t DNBProcessLaunch(
- const char *path, char const *argv[], const char *envp[],
- const char *working_directory, // NULL => don't 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,
- const char *event_data, char *err_str, size_t err_len);
-
-nub_process_t DNBProcessGetPIDByName(const char *name);
-nub_process_t DNBProcessAttach(nub_process_t pid, struct timespec *timeout,
- char *err_str, size_t err_len);
-nub_process_t DNBProcessAttachByName(const char *name, struct timespec *timeout,
- char *err_str, size_t err_len);
-nub_process_t
-DNBProcessAttachWait(const char *wait_name, nub_launch_flavor_t launch_flavor,
- bool ignore_existing, struct timespec *timeout,
- useconds_t interval, char *err_str, size_t err_len,
- DNBShouldCancelCallback should_cancel = NULL,
- void *callback_data = NULL);
-// Resume a process with exact instructions on what to do with each thread:
-// - If no thread actions are supplied (actions is NULL or num_actions is zero),
-// then all threads are continued.
-// - If any thread actions are supplied, then each thread will do as it is told
-// by the action. A default actions for any threads that don't have an
-// 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) 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 DNBProcessInterrupt(nub_process_t pid) 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;
-uint64_t DNBProcessMemoryReadInteger(nub_process_t pid, nub_addr_t addr,
- nub_size_t integer_size,
- uint64_t fail_value) DNB_EXPORT;
-nub_addr_t DNBProcessMemoryReadPointer(nub_process_t pid,
- nub_addr_t addr) DNB_EXPORT;
-std::string DNBProcessMemoryReadCString(nub_process_t pid,
- nub_addr_t addr) DNB_EXPORT;
-std::string
-DNBProcessMemoryReadCStringFixed(nub_process_t pid, nub_addr_t addr,
- nub_size_t fixed_length) 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;
-DarwinLogEventVector DNBProcessGetAvailableDarwinLogEvents(nub_process_t pid);
-
-//----------------------------------------------------------------------
-// Process status
-//----------------------------------------------------------------------
-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;
-const char *DNBGetDeploymentInfo(nub_process_t pid,
- const struct load_command& lc,
- uint64_t load_command_address,
- uint32_t& major_version,
- uint32_t& minor_version,
- uint32_t& patch_version);
-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
-//----------------------------------------------------------------------
-const char *DNBProcessGetExecutablePath(nub_process_t pid);
-const char *DNBProcessGetArgumentAtIndex(nub_process_t pid, nub_size_t idx);
-nub_size_t DNBProcessGetArgumentCount(nub_process_t pid);
-
-//----------------------------------------------------------------------
-// Process events
-//----------------------------------------------------------------------
-nub_event_t DNBProcessWaitForEvents(nub_process_t pid, nub_event_t event_mask,
- bool wait_for_set,
- struct timespec *timeout);
-void DNBProcessResetEvents(nub_process_t pid, nub_event_t event_mask);
-
-//----------------------------------------------------------------------
-// Thread functions
-//----------------------------------------------------------------------
-const char *DNBThreadGetName(nub_process_t pid, nub_thread_t tid);
-nub_bool_t
-DNBThreadGetIdentifierInfo(nub_process_t pid, nub_thread_t tid,
- thread_identifier_info_data_t *ident_info);
-nub_state_t DNBThreadGetState(nub_process_t pid, nub_thread_t tid);
-nub_bool_t DNBThreadGetRegisterValueByID(nub_process_t pid, nub_thread_t tid,
- uint32_t set, uint32_t reg,
- DNBRegisterValue *value);
-nub_bool_t DNBThreadSetRegisterValueByID(nub_process_t pid, nub_thread_t tid,
- uint32_t set, uint32_t reg,
- const DNBRegisterValue *value);
-nub_size_t DNBThreadGetRegisterContext(nub_process_t pid, nub_thread_t tid,
- void *buf, size_t buf_len);
-nub_size_t DNBThreadSetRegisterContext(nub_process_t pid, nub_thread_t tid,
- const void *buf, size_t buf_len);
-uint32_t DNBThreadSaveRegisterState(nub_process_t pid, nub_thread_t tid);
-nub_bool_t DNBThreadRestoreRegisterState(nub_process_t pid, nub_thread_t tid,
- uint32_t save_id);
-nub_bool_t DNBThreadGetRegisterValueByName(nub_process_t pid, nub_thread_t tid,
- uint32_t set, const char *name,
- DNBRegisterValue *value);
-nub_bool_t DNBThreadGetStopReason(nub_process_t pid, nub_thread_t tid,
- DNBThreadStopInfo *stop_info);
-const char *DNBThreadGetInfo(nub_process_t pid, nub_thread_t tid);
-Genealogy::ThreadActivitySP DNBGetGenealogyInfoForThread(nub_process_t pid,
- nub_thread_t tid,
- bool &timed_out);
-Genealogy::ProcessExecutableInfoSP DNBGetGenealogyImageInfo(nub_process_t pid,
- size_t idx);
-ThreadInfo::QoS DNBGetRequestedQoSForThread(nub_process_t pid, nub_thread_t tid,
- nub_addr_t tsd,
- uint64_t dti_qos_class_index);
-nub_addr_t DNBGetPThreadT(nub_process_t pid, nub_thread_t tid);
-nub_addr_t DNBGetDispatchQueueT(nub_process_t pid, nub_thread_t tid);
-nub_addr_t
-DNBGetTSDAddressForThread(nub_process_t pid, nub_thread_t tid,
- uint64_t plo_pthread_tsd_base_address_offset,
- uint64_t plo_pthread_tsd_base_offset,
- uint64_t plo_pthread_tsd_entry_size);
-JSONGenerator::ObjectSP DNBGetLoadedDynamicLibrariesInfos(
- nub_process_t pid, nub_addr_t image_list_address, nub_addr_t image_count);
-JSONGenerator::ObjectSP DNBGetAllLoadedLibrariesInfos(nub_process_t pid);
-JSONGenerator::ObjectSP
-DNBGetLibrariesInfoForAddresses(nub_process_t pid,
- std::vector<uint64_t> &macho_addresses);
-JSONGenerator::ObjectSP DNBGetSharedCacheInfo(nub_process_t pid);
-
-//
-//----------------------------------------------------------------------
-// Breakpoint functions
-//----------------------------------------------------------------------
-nub_bool_t DNBBreakpointSet(nub_process_t pid, nub_addr_t addr, nub_size_t size,
- nub_bool_t hardware);
-nub_bool_t DNBBreakpointClear(nub_process_t pid, nub_addr_t addr);
-
-//----------------------------------------------------------------------
-// Watchpoint functions
-//----------------------------------------------------------------------
-nub_bool_t DNBWatchpointSet(nub_process_t pid, nub_addr_t addr, nub_size_t size,
- uint32_t watch_flags, nub_bool_t hardware);
-nub_bool_t DNBWatchpointClear(nub_process_t pid, nub_addr_t addr);
-uint32_t DNBWatchpointGetNumSupportedHWP(nub_process_t pid);
-
-uint32_t DNBGetRegisterCPUType();
-const DNBRegisterSetInfo *DNBGetRegisterSetInfo(nub_size_t *num_reg_sets);
-nub_bool_t DNBGetRegisterInfoByName(const char *reg_name,
- DNBRegisterInfo *info);
-
-//----------------------------------------------------------------------
-// Other static nub information calls.
-//----------------------------------------------------------------------
-const char *DNBStateAsString(nub_state_t state);
-nub_bool_t DNBResolveExecutablePath(const char *path, char *resolved_path,
- size_t resolved_path_size);
-bool DNBGetOSVersionNumbers(uint64_t *major, uint64_t *minor, uint64_t *patch);
-
-#endif
diff --git a/tools/debugserver/source/DNBArch.cpp b/tools/debugserver/source/DNBArch.cpp
deleted file mode 100644
index 1312bcf7dfdd..000000000000
--- a/tools/debugserver/source/DNBArch.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-//===-- DNBArch.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/24/07.
-//
-//===----------------------------------------------------------------------===//
-
-#include "DNBArch.h"
-#include <assert.h>
-#include <mach/mach.h>
-
-#include <map>
-
-#include "DNBLog.h"
-
-typedef std::map<uint32_t, DNBArchPluginInfo> CPUPluginInfoMap;
-
-static uint32_t g_current_cpu_type = 0;
-CPUPluginInfoMap g_arch_plugins;
-
-static const DNBArchPluginInfo *GetArchInfo() {
- CPUPluginInfoMap::const_iterator pos =
- g_arch_plugins.find(g_current_cpu_type);
- if (pos != g_arch_plugins.end())
- return &pos->second;
- return NULL;
-}
-
-uint32_t DNBArchProtocol::GetArchitecture() { return g_current_cpu_type; }
-
-bool DNBArchProtocol::SetArchitecture(uint32_t cpu_type) {
- g_current_cpu_type = cpu_type;
- bool result = g_arch_plugins.find(g_current_cpu_type) != g_arch_plugins.end();
- DNBLogThreadedIf(
- LOG_PROCESS,
- "DNBArchProtocol::SetDefaultArchitecture (cpu_type=0x%8.8x) => %i",
- cpu_type, result);
- return result;
-}
-
-void DNBArchProtocol::RegisterArchPlugin(const DNBArchPluginInfo &arch_info) {
- if (arch_info.cpu_type)
- g_arch_plugins[arch_info.cpu_type] = arch_info;
-}
-
-uint32_t DNBArchProtocol::GetRegisterCPUType() {
- const DNBArchPluginInfo *arch_info = GetArchInfo();
- if (arch_info)
- return arch_info->cpu_type;
- return 0;
-}
-
-const DNBRegisterSetInfo *
-DNBArchProtocol::GetRegisterSetInfo(nub_size_t *num_reg_sets) {
- const DNBArchPluginInfo *arch_info = GetArchInfo();
- if (arch_info)
- return arch_info->GetRegisterSetInfo(num_reg_sets);
- *num_reg_sets = 0;
- return NULL;
-}
-
-DNBArchProtocol *DNBArchProtocol::Create(MachThread *thread) {
- const DNBArchPluginInfo *arch_info = GetArchInfo();
- if (arch_info)
- return arch_info->Create(thread);
- return NULL;
-}
-
-const uint8_t *DNBArchProtocol::GetBreakpointOpcode(nub_size_t byte_size) {
- const DNBArchPluginInfo *arch_info = GetArchInfo();
- if (arch_info)
- return arch_info->GetBreakpointOpcode(byte_size);
- return NULL;
-}
diff --git a/tools/debugserver/source/DNBArch.h b/tools/debugserver/source/DNBArch.h
deleted file mode 100644
index 317da70e6422..000000000000
--- a/tools/debugserver/source/DNBArch.h
+++ /dev/null
@@ -1,127 +0,0 @@
-//===-- DNBArch.h -----------------------------------------------*- 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/24/07.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __DebugNubArch_h__
-#define __DebugNubArch_h__
-
-#include "DNBDefs.h"
-#include "MacOSX/MachException.h"
-
-#include <mach/mach.h>
-#include <stdio.h>
-
-struct DNBRegisterValue;
-struct DNBRegisterSetInfo;
-class DNBArchProtocol;
-class MachThread;
-
-typedef DNBArchProtocol *(*DNBArchCallbackCreate)(MachThread *thread);
-typedef const DNBRegisterSetInfo *(*DNBArchCallbackGetRegisterSetInfo)(
- nub_size_t *num_reg_sets);
-typedef const uint8_t *(*DNBArchCallbackGetBreakpointOpcode)(
- nub_size_t byte_size);
-
-typedef struct DNBArchPluginInfoTag {
- uint32_t cpu_type;
- DNBArchCallbackCreate Create;
- DNBArchCallbackGetRegisterSetInfo GetRegisterSetInfo;
- DNBArchCallbackGetBreakpointOpcode GetBreakpointOpcode;
-} DNBArchPluginInfo;
-
-class DNBArchProtocol {
-public:
- static DNBArchProtocol *Create(MachThread *thread);
-
- static uint32_t GetRegisterCPUType();
-
- static const DNBRegisterSetInfo *GetRegisterSetInfo(nub_size_t *num_reg_sets);
-
- static const uint8_t *GetBreakpointOpcode(nub_size_t byte_size);
-
- static void RegisterArchPlugin(const DNBArchPluginInfo &arch_info);
-
- static uint32_t GetArchitecture();
-
- static bool SetArchitecture(uint32_t cpu_type);
-
- DNBArchProtocol() : m_save_id(0) {}
-
- virtual ~DNBArchProtocol() {}
- virtual bool GetRegisterValue(uint32_t set, uint32_t reg,
- DNBRegisterValue *value) = 0;
- virtual bool SetRegisterValue(uint32_t set, uint32_t reg,
- const DNBRegisterValue *value) = 0;
- virtual nub_size_t GetRegisterContext(void *buf, nub_size_t buf_len) = 0;
- virtual nub_size_t SetRegisterContext(const void *buf,
- nub_size_t buf_len) = 0;
- virtual uint32_t SaveRegisterState() = 0;
- virtual bool RestoreRegisterState(uint32_t save_id) = 0;
-
- virtual kern_return_t GetRegisterState(int set, bool force) = 0;
- virtual kern_return_t SetRegisterState(int set) = 0;
- virtual bool RegisterSetStateIsValid(int set) const = 0;
-
- virtual uint64_t GetPC(uint64_t failValue) = 0; // Get program counter
- virtual kern_return_t SetPC(uint64_t value) = 0;
- virtual uint64_t GetSP(uint64_t failValue) = 0; // Get stack pointer
- virtual void ThreadWillResume() = 0;
- virtual bool ThreadDidStop() = 0;
- virtual bool NotifyException(MachException::Data &exc) { return false; }
- virtual uint32_t NumSupportedHardwareBreakpoints() { return 0; }
- virtual uint32_t NumSupportedHardwareWatchpoints() { return 0; }
- virtual uint32_t EnableHardwareBreakpoint(nub_addr_t addr, nub_size_t size) {
- return INVALID_NUB_HW_INDEX;
- }
- virtual uint32_t EnableHardwareWatchpoint(nub_addr_t addr, nub_size_t size,
- bool read, bool write,
- bool also_set_on_task) {
- return INVALID_NUB_HW_INDEX;
- }
- virtual bool DisableHardwareBreakpoint(uint32_t hw_index) { return false; }
- virtual bool DisableHardwareWatchpoint(uint32_t hw_index,
- bool also_set_on_task) {
- return false;
- }
- virtual uint32_t GetHardwareWatchpointHit(nub_addr_t &addr) {
- return INVALID_NUB_HW_INDEX;
- }
- virtual bool StepNotComplete() { return false; }
-
-protected:
- friend class MachThread;
-
- uint32_t GetNextRegisterStateSaveID() { return ++m_save_id; }
-
- enum {
- Trans_Pending =
- 0, // Transaction is pending, and checkpoint state has been snapshotted.
- Trans_Done = 1, // Transaction is done, the current state is committed, and
- // checkpoint state is irrelevant.
- Trans_Rolled_Back = 2 // Transaction is done, the current state has been
- // rolled back to the checkpoint state.
- };
- virtual bool StartTransForHWP() { return true; }
- virtual bool RollbackTransForHWP() { return true; }
- virtual bool FinishTransForHWP() { return true; }
-
- uint32_t m_save_id; // An always incrementing integer ID used with
- // SaveRegisterState/RestoreRegisterState
-};
-
-#include "MacOSX/arm/DNBArchImpl.h"
-#include "MacOSX/arm64/DNBArchImplARM64.h"
-#include "MacOSX/i386/DNBArchImplI386.h"
-#include "MacOSX/ppc/DNBArchImpl.h"
-#include "MacOSX/x86_64/DNBArchImplX86_64.h"
-
-#endif
diff --git a/tools/debugserver/source/DNBBreakpoint.cpp b/tools/debugserver/source/DNBBreakpoint.cpp
deleted file mode 100644
index 89a91287f9e3..000000000000
--- a/tools/debugserver/source/DNBBreakpoint.cpp
+++ /dev/null
@@ -1,178 +0,0 @@
-//===-- DNBBreakpoint.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/29/07.
-//
-//===----------------------------------------------------------------------===//
-
-#include "DNBBreakpoint.h"
-#include "DNBLog.h"
-#include "MachProcess.h"
-#include <algorithm>
-#include <assert.h>
-#include <inttypes.h>
-
-#pragma mark-- DNBBreakpoint
-DNBBreakpoint::DNBBreakpoint(nub_addr_t addr, nub_size_t byte_size,
- bool hardware)
- : m_retain_count(1), m_byte_size(static_cast<uint32_t>(byte_size)),
- m_opcode(), m_addr(addr), m_enabled(0), m_hw_preferred(hardware),
- m_is_watchpoint(0), m_watch_read(0), m_watch_write(0),
- m_hw_index(INVALID_NUB_HW_INDEX) {}
-
-DNBBreakpoint::~DNBBreakpoint() {}
-
-void DNBBreakpoint::Dump() const {
- if (IsBreakpoint()) {
- DNBLog("DNBBreakpoint addr = 0x%llx state = %s type = %s breakpoint "
- "hw_index = %i",
- (uint64_t)m_addr, m_enabled ? "enabled " : "disabled",
- IsHardware() ? "hardware" : "software", GetHardwareIndex());
- } else {
- DNBLog("DNBBreakpoint addr = 0x%llx size = %llu state = %s type = %s "
- "watchpoint (%s%s) hw_index = %i",
- (uint64_t)m_addr, (uint64_t)m_byte_size,
- m_enabled ? "enabled " : "disabled",
- IsHardware() ? "hardware" : "software", m_watch_read ? "r" : "",
- m_watch_write ? "w" : "", GetHardwareIndex());
- }
-}
-
-#pragma mark-- DNBBreakpointList
-
-DNBBreakpointList::DNBBreakpointList() {}
-
-DNBBreakpointList::~DNBBreakpointList() {}
-
-DNBBreakpoint *DNBBreakpointList::Add(nub_addr_t addr, nub_size_t length,
- bool hardware) {
- m_breakpoints.insert(
- std::make_pair(addr, DNBBreakpoint(addr, length, hardware)));
- iterator pos = m_breakpoints.find(addr);
- return &pos->second;
-}
-
-bool DNBBreakpointList::Remove(nub_addr_t addr) {
- iterator pos = m_breakpoints.find(addr);
- if (pos != m_breakpoints.end()) {
- m_breakpoints.erase(pos);
- return true;
- }
- return false;
-}
-
-DNBBreakpoint *DNBBreakpointList::FindByAddress(nub_addr_t addr) {
- iterator pos = m_breakpoints.find(addr);
- if (pos != m_breakpoints.end())
- return &pos->second;
-
- return NULL;
-}
-
-const DNBBreakpoint *DNBBreakpointList::FindByAddress(nub_addr_t addr) const {
- const_iterator pos = m_breakpoints.find(addr);
- if (pos != m_breakpoints.end())
- return &pos->second;
-
- return NULL;
-}
-
-// Finds the next breakpoint at an address greater than or equal to "addr"
-size_t DNBBreakpointList::FindBreakpointsThatOverlapRange(
- nub_addr_t addr, nub_addr_t size, std::vector<DNBBreakpoint *> &bps) {
- bps.clear();
- iterator end = m_breakpoints.end();
- // Find the first breakpoint with an address >= to "addr"
- iterator pos = m_breakpoints.lower_bound(addr);
- if (pos != end) {
- if (pos != m_breakpoints.begin()) {
- // Watch out for a breakpoint at an address less than "addr" that might
- // still overlap
- iterator prev_pos = pos;
- --prev_pos;
- if (prev_pos->second.IntersectsRange(addr, size, NULL, NULL, NULL))
- bps.push_back(&pos->second);
- }
-
- while (pos != end) {
- // When we hit a breakpoint whose start address is greater than "addr +
- // size" we are done.
- // Do the math in a way that doesn't risk unsigned overflow with bad
- // input.
- if ((pos->second.Address() - addr) >= size)
- break;
-
- // Check if this breakpoint overlaps, and if it does, add it to the list
- if (pos->second.IntersectsRange(addr, size, NULL, NULL, NULL)) {
- bps.push_back(&pos->second);
- ++pos;
- }
- }
- }
- return bps.size();
-}
-
-void DNBBreakpointList::Dump() const {
- const_iterator pos;
- const_iterator end = m_breakpoints.end();
- for (pos = m_breakpoints.begin(); pos != end; ++pos)
- pos->second.Dump();
-}
-
-void DNBBreakpointList::DisableAll() {
- iterator pos, end = m_breakpoints.end();
- for (pos = m_breakpoints.begin(); pos != end; ++pos)
- pos->second.SetEnabled(false);
-}
-
-void DNBBreakpointList::RemoveTrapsFromBuffer(nub_addr_t addr, nub_size_t size,
- void *p) const {
- uint8_t *buf = (uint8_t *)p;
- const_iterator end = m_breakpoints.end();
- const_iterator pos = m_breakpoints.lower_bound(addr);
- while (pos != end && (pos->first < (addr + size))) {
- nub_addr_t intersect_addr;
- nub_size_t intersect_size;
- nub_size_t opcode_offset;
- const DNBBreakpoint &bp = pos->second;
- if (bp.IntersectsRange(addr, size, &intersect_addr, &intersect_size,
- &opcode_offset)) {
- 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());
- nub_size_t buf_offset = intersect_addr - addr;
- ::memcpy(buf + buf_offset, bp.SavedOpcodeBytes() + opcode_offset,
- intersect_size);
- }
- ++pos;
- }
-}
-
-void DNBBreakpointList::DisableAllBreakpoints(MachProcess *process) {
- iterator pos, end = m_breakpoints.end();
- for (pos = m_breakpoints.begin(); pos != end; ++pos)
- process->DisableBreakpoint(pos->second.Address(), false);
-}
-
-void DNBBreakpointList::DisableAllWatchpoints(MachProcess *process) {
- iterator pos, end = m_breakpoints.end();
- for (pos = m_breakpoints.begin(); pos != end; ++pos)
- process->DisableWatchpoint(pos->second.Address(), false);
-}
-
-void DNBBreakpointList::RemoveDisabled() {
- iterator pos = m_breakpoints.begin();
- while (pos != m_breakpoints.end()) {
- if (!pos->second.IsEnabled())
- pos = m_breakpoints.erase(pos);
- else
- ++pos;
- }
-}
diff --git a/tools/debugserver/source/DNBBreakpoint.h b/tools/debugserver/source/DNBBreakpoint.h
deleted file mode 100644
index 889478b28957..000000000000
--- a/tools/debugserver/source/DNBBreakpoint.h
+++ /dev/null
@@ -1,149 +0,0 @@
-//===-- DNBBreakpoint.h -----------------------------------------*- 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/29/07.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __DNBBreakpoint_h__
-#define __DNBBreakpoint_h__
-
-#include <mach/mach.h>
-
-#include <map>
-#include <vector>
-
-#include "DNBDefs.h"
-
-class MachProcess;
-
-class DNBBreakpoint {
-public:
- DNBBreakpoint(nub_addr_t m_addr, nub_size_t byte_size, bool hardware);
- ~DNBBreakpoint();
-
- nub_size_t ByteSize() const { return m_byte_size; }
- uint8_t *SavedOpcodeBytes() { return &m_opcode[0]; }
- const uint8_t *SavedOpcodeBytes() const { return &m_opcode[0]; }
- nub_addr_t Address() const { return m_addr; }
- // nub_thread_t ThreadID() const { return m_tid; }
- bool IsEnabled() const { return m_enabled; }
- bool IntersectsRange(nub_addr_t addr, nub_size_t size,
- nub_addr_t *intersect_addr, nub_size_t *intersect_size,
- nub_size_t *opcode_offset) const {
- // We only use software traps for software breakpoints
- if (IsBreakpoint() && IsEnabled() && !IsHardware()) {
- if (m_byte_size > 0) {
- const nub_addr_t bp_end_addr = m_addr + m_byte_size;
- const nub_addr_t end_addr = addr + size;
- // Is the breakpoint end address before the passed in start address?
- if (bp_end_addr <= addr)
- return false;
- // Is the breakpoint start address after passed in end address?
- if (end_addr <= m_addr)
- return false;
- if (intersect_addr || intersect_size || opcode_offset) {
- if (m_addr < addr) {
- if (intersect_addr)
- *intersect_addr = addr;
- if (intersect_size)
- *intersect_size =
- std::min<nub_addr_t>(bp_end_addr, end_addr) - addr;
- if (opcode_offset)
- *opcode_offset = addr - m_addr;
- } else {
- if (intersect_addr)
- *intersect_addr = m_addr;
- if (intersect_size)
- *intersect_size =
- std::min<nub_addr_t>(bp_end_addr, end_addr) - m_addr;
- if (opcode_offset)
- *opcode_offset = 0;
- }
- }
- return true;
- }
- }
- return false;
- }
- void SetEnabled(bool enabled) {
- if (!enabled)
- SetHardwareIndex(INVALID_NUB_HW_INDEX);
- m_enabled = enabled;
- }
- void SetIsWatchpoint(uint32_t type) {
- m_is_watchpoint = 1;
- m_watch_read = (type & WATCH_TYPE_READ) != 0;
- m_watch_write = (type & WATCH_TYPE_WRITE) != 0;
- }
- bool IsBreakpoint() const { return m_is_watchpoint == 0; }
- bool IsWatchpoint() const { return m_is_watchpoint == 1; }
- bool WatchpointRead() const { return m_watch_read != 0; }
- bool WatchpointWrite() const { return m_watch_write != 0; }
- bool HardwarePreferred() const { return m_hw_preferred; }
- bool IsHardware() const { return m_hw_index != INVALID_NUB_HW_INDEX; }
- uint32_t GetHardwareIndex() const { return m_hw_index; }
- void SetHardwareIndex(uint32_t hw_index) { m_hw_index = hw_index; }
- void Dump() const;
- uint32_t Retain() { return ++m_retain_count; }
- uint32_t Release() {
- if (m_retain_count == 0)
- return 0;
- return --m_retain_count;
- }
-
-private:
- uint32_t m_retain_count; // Each breakpoint is maintained by address and is
- // ref counted in case multiple people set a
- // breakpoint at the same address
- uint32_t m_byte_size; // Length in bytes of the breakpoint if set in memory
- uint8_t m_opcode[8]; // Saved opcode bytes
- nub_addr_t m_addr; // Address of this breakpoint
- uint32_t m_enabled : 1, // Flags for this breakpoint
- m_hw_preferred : 1, // 1 if this point has been requested to be set using
- // hardware (which may fail due to lack of resources)
- m_is_watchpoint : 1, // 1 if this is a watchpoint
- m_watch_read : 1, // 1 if we stop when the watched data is read from
- m_watch_write : 1; // 1 if we stop when the watched data is written to
- uint32_t
- m_hw_index; // The hardware resource index for this breakpoint/watchpoint
-};
-
-class DNBBreakpointList {
-public:
- DNBBreakpointList();
- ~DNBBreakpointList();
-
- DNBBreakpoint *Add(nub_addr_t addr, nub_size_t length, bool hardware);
- bool Remove(nub_addr_t addr);
- DNBBreakpoint *FindByAddress(nub_addr_t addr);
- const DNBBreakpoint *FindByAddress(nub_addr_t addr) const;
-
- size_t FindBreakpointsThatOverlapRange(nub_addr_t addr, nub_addr_t size,
- std::vector<DNBBreakpoint *> &bps);
-
- void Dump() const;
-
- size_t Size() const { return m_breakpoints.size(); }
- void DisableAll();
-
- void RemoveTrapsFromBuffer(nub_addr_t addr, nub_size_t size, void *buf) const;
-
- void DisableAllBreakpoints(MachProcess *process);
- void DisableAllWatchpoints(MachProcess *process);
- void RemoveDisabled();
-
-protected:
- typedef std::map<nub_addr_t, DNBBreakpoint> collection;
- typedef collection::iterator iterator;
- typedef collection::const_iterator const_iterator;
- collection m_breakpoints;
-};
-
-#endif
diff --git a/tools/debugserver/source/DNBDataRef.cpp b/tools/debugserver/source/DNBDataRef.cpp
deleted file mode 100644
index 8c12b0afac69..000000000000
--- a/tools/debugserver/source/DNBDataRef.cpp
+++ /dev/null
@@ -1,351 +0,0 @@
-//===-- DNBDataRef.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 1/11/06.
-//
-//===----------------------------------------------------------------------===//
-
-#include "DNBDataRef.h"
-#include "DNBLog.h"
-#include <assert.h>
-#include <ctype.h>
-#include <libkern/OSByteOrder.h>
-
-//----------------------------------------------------------------------
-// Constructor
-//----------------------------------------------------------------------
-
-DNBDataRef::DNBDataRef()
- : m_start(NULL), m_end(NULL), m_swap(false), m_ptrSize(0),
- m_addrPCRelative(INVALID_NUB_ADDRESS), m_addrTEXT(INVALID_NUB_ADDRESS),
- m_addrDATA(INVALID_NUB_ADDRESS) {}
-
-//----------------------------------------------------------------------
-// Constructor
-//----------------------------------------------------------------------
-
-DNBDataRef::DNBDataRef(const uint8_t *start, size_t size, bool swap)
- : m_start(start), m_end(start + size), m_swap(swap), m_ptrSize(0),
- m_addrPCRelative(INVALID_NUB_ADDRESS), m_addrTEXT(INVALID_NUB_ADDRESS),
- m_addrDATA(INVALID_NUB_ADDRESS) {}
-
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-
-DNBDataRef::~DNBDataRef() {}
-
-//----------------------------------------------------------------------
-// Get8
-//----------------------------------------------------------------------
-uint8_t DNBDataRef::Get8(offset_t *offset_ptr) const {
- uint8_t val = 0;
- if (ValidOffsetForDataOfSize(*offset_ptr, sizeof(val))) {
- val = *(m_start + *offset_ptr);
- *offset_ptr += sizeof(val);
- }
- return val;
-}
-
-//----------------------------------------------------------------------
-// Get16
-//----------------------------------------------------------------------
-uint16_t DNBDataRef::Get16(offset_t *offset_ptr) const {
- uint16_t val = 0;
- if (ValidOffsetForDataOfSize(*offset_ptr, sizeof(val))) {
- const uint8_t *p = m_start + *offset_ptr;
- memcpy(&val, p, sizeof(uint16_t));
-
- if (m_swap)
- val = OSSwapInt16(val);
-
- // Advance the offset
- *offset_ptr += sizeof(val);
- }
- return val;
-}
-
-//----------------------------------------------------------------------
-// Get32
-//----------------------------------------------------------------------
-uint32_t DNBDataRef::Get32(offset_t *offset_ptr) const {
- uint32_t val = 0;
- if (ValidOffsetForDataOfSize(*offset_ptr, sizeof(val))) {
- const uint8_t *p = m_start + *offset_ptr;
- memcpy(&val, p, sizeof(uint32_t));
- if (m_swap)
- val = OSSwapInt32(val);
-
- // Advance the offset
- *offset_ptr += sizeof(val);
- }
- return val;
-}
-
-//----------------------------------------------------------------------
-// Get64
-//----------------------------------------------------------------------
-uint64_t DNBDataRef::Get64(offset_t *offset_ptr) const {
- uint64_t val = 0;
- if (ValidOffsetForDataOfSize(*offset_ptr, sizeof(val))) {
- const uint8_t *p = m_start + *offset_ptr;
- memcpy(&val, p, sizeof(uint64_t));
- if (m_swap)
- val = OSSwapInt64(val);
-
- // Advance the offset
- *offset_ptr += sizeof(val);
- }
- return val;
-}
-
-//----------------------------------------------------------------------
-// GetMax32
-//
-// Used for calls when the size can vary. Fill in extra cases if they
-// are ever needed.
-//----------------------------------------------------------------------
-uint32_t DNBDataRef::GetMax32(offset_t *offset_ptr, uint32_t byte_size) const {
- switch (byte_size) {
- case 1:
- return Get8(offset_ptr);
- break;
- case 2:
- return Get16(offset_ptr);
- break;
- case 4:
- return Get32(offset_ptr);
- break;
- default:
- assert(false && "GetMax32 unhandled case!");
- break;
- }
- return 0;
-}
-
-//----------------------------------------------------------------------
-// GetMax64
-//
-// Used for calls when the size can vary. Fill in extra cases if they
-// are ever needed.
-//----------------------------------------------------------------------
-uint64_t DNBDataRef::GetMax64(offset_t *offset_ptr, uint32_t size) const {
- switch (size) {
- case 1:
- return Get8(offset_ptr);
- break;
- case 2:
- return Get16(offset_ptr);
- break;
- case 4:
- return Get32(offset_ptr);
- break;
- case 8:
- return Get64(offset_ptr);
- break;
- default:
- assert(false && "GetMax64 unhandled case!");
- break;
- }
- return 0;
-}
-
-//----------------------------------------------------------------------
-// GetPointer
-//
-// Extract a pointer value from the buffer. The pointer size must be
-// set prior to using this using one of the SetPointerSize functions.
-//----------------------------------------------------------------------
-uint64_t DNBDataRef::GetPointer(offset_t *offset_ptr) const {
- // Must set pointer size prior to using this call
- assert(m_ptrSize != 0);
- return GetMax64(offset_ptr, m_ptrSize);
-}
-//----------------------------------------------------------------------
-// GetCStr
-//----------------------------------------------------------------------
-const char *DNBDataRef::GetCStr(offset_t *offset_ptr,
- uint32_t fixed_length) const {
- const char *s = NULL;
- if (m_start < m_end) {
- s = (const char *)m_start + *offset_ptr;
-
- // Advance the offset
- if (fixed_length)
- *offset_ptr += fixed_length;
- else
- *offset_ptr += strlen(s) + 1;
- }
- return s;
-}
-
-//----------------------------------------------------------------------
-// GetData
-//----------------------------------------------------------------------
-const uint8_t *DNBDataRef::GetData(offset_t *offset_ptr,
- uint32_t length) const {
- const uint8_t *data = NULL;
- if (length > 0 && ValidOffsetForDataOfSize(*offset_ptr, length)) {
- data = m_start + *offset_ptr;
- *offset_ptr += length;
- }
- return data;
-}
-
-//----------------------------------------------------------------------
-// Get_ULEB128
-//----------------------------------------------------------------------
-uint64_t DNBDataRef::Get_ULEB128(offset_t *offset_ptr) const {
- uint64_t result = 0;
- if (m_start < m_end) {
- int shift = 0;
- const uint8_t *src = m_start + *offset_ptr;
- uint8_t byte;
- int bytecount = 0;
-
- while (src < m_end) {
- bytecount++;
- byte = *src++;
- result |= (uint64_t)(byte & 0x7f) << shift;
- shift += 7;
- if ((byte & 0x80) == 0)
- break;
- }
-
- *offset_ptr += bytecount;
- }
- return result;
-}
-
-//----------------------------------------------------------------------
-// Get_SLEB128
-//----------------------------------------------------------------------
-int64_t DNBDataRef::Get_SLEB128(offset_t *offset_ptr) const {
- int64_t result = 0;
-
- if (m_start < m_end) {
- int shift = 0;
- int size = sizeof(uint32_t) * 8;
- const uint8_t *src = m_start + *offset_ptr;
-
- uint8_t byte = 0;
- int bytecount = 0;
-
- while (src < m_end) {
- bytecount++;
- byte = *src++;
- result |= (int64_t)(byte & 0x7f) << shift;
- shift += 7;
- if ((byte & 0x80) == 0)
- break;
- }
-
- // Sign bit of byte is 2nd high order bit (0x40)
- if (shift < size && (byte & 0x40))
- result |= -(1ll << shift);
-
- *offset_ptr += bytecount;
- }
- return result;
-}
-
-//----------------------------------------------------------------------
-// Skip_LEB128
-//
-// Skips past ULEB128 and SLEB128 numbers (just updates the offset)
-//----------------------------------------------------------------------
-void DNBDataRef::Skip_LEB128(offset_t *offset_ptr) const {
- if (m_start < m_end) {
- const uint8_t *start = m_start + *offset_ptr;
- const uint8_t *src = start;
-
- while ((src < m_end) && (*src++ & 0x80))
- /* Do nothing */;
-
- *offset_ptr += src - start;
- }
-}
-
-uint32_t DNBDataRef::Dump(uint32_t startOffset, uint32_t endOffset,
- uint64_t offsetBase, DNBDataRef::Type type,
- uint32_t numPerLine, const char *format) {
- uint32_t offset;
- uint32_t count;
- char str[1024];
- str[0] = '\0';
- size_t str_offset = 0;
-
- for (offset = startOffset, count = 0;
- ValidOffset(offset) && offset < endOffset; ++count) {
- if ((count % numPerLine) == 0) {
- // Print out any previous string
- if (str[0] != '\0')
- DNBLog("%s", str);
- // Reset string offset and fill the current line string with address:
- str_offset = 0;
- str_offset += snprintf(str, sizeof(str), "0x%8.8llx:",
- (uint64_t)(offsetBase + (offset - startOffset)));
- }
-
- // Make sure we don't pass the bounds of our current string buffer on each
- // iteration through this loop
- if (str_offset >= sizeof(str)) {
- // The last snprintf consumed our string buffer, we will need to dump this
- // out
- // and reset the string with no address
- DNBLog("%s", str);
- str_offset = 0;
- str[0] = '\0';
- }
-
- // We already checked that there is at least some room in the string str
- // above, so it is safe to make
- // the snprintf call each time through this loop
- switch (type) {
- case TypeUInt8:
- str_offset += snprintf(str + str_offset, sizeof(str) - str_offset,
- format ? format : " %2.2x", Get8(&offset));
- break;
- case TypeChar: {
- char ch = Get8(&offset);
- str_offset += snprintf(str + str_offset, sizeof(str) - str_offset,
- format ? format : " %c", isprint(ch) ? ch : ' ');
- } break;
- case TypeUInt16:
- str_offset += snprintf(str + str_offset, sizeof(str) - str_offset,
- format ? format : " %4.4x", Get16(&offset));
- break;
- case TypeUInt32:
- str_offset += snprintf(str + str_offset, sizeof(str) - str_offset,
- format ? format : " %8.8x", Get32(&offset));
- break;
- case TypeUInt64:
- str_offset += snprintf(str + str_offset, sizeof(str) - str_offset,
- format ? format : " %16.16llx", Get64(&offset));
- break;
- case TypePointer:
- str_offset += snprintf(str + str_offset, sizeof(str) - str_offset,
- format ? format : " 0x%llx", GetPointer(&offset));
- break;
- case TypeULEB128:
- str_offset += snprintf(str + str_offset, sizeof(str) - str_offset,
- format ? format : " 0x%llx", Get_ULEB128(&offset));
- break;
- case TypeSLEB128:
- str_offset += snprintf(str + str_offset, sizeof(str) - str_offset,
- format ? format : " %lld", Get_SLEB128(&offset));
- break;
- }
- }
-
- if (str[0] != '\0')
- DNBLog("%s", str);
-
- return offset; // Return the offset at which we ended up
-}
diff --git a/tools/debugserver/source/DNBDataRef.h b/tools/debugserver/source/DNBDataRef.h
deleted file mode 100644
index 9a19f20227e6..000000000000
--- a/tools/debugserver/source/DNBDataRef.h
+++ /dev/null
@@ -1,125 +0,0 @@
-//===-- DNBDataRef.h --------------------------------------------*- 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 1/11/06.
-//
-//===----------------------------------------------------------------------===//
-//
-// DNBDataRef is a class that can extract data in normal or byte
-// swapped order from a data buffer that someone else owns. The data
-// buffer needs to remain intact as long as the DNBDataRef object
-// needs the data. Strings returned are pointers into the data buffer
-// and will need to be copied if they are needed after the data buffer
-// is no longer around.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __DNBDataRef_h__
-#define __DNBDataRef_h__
-
-#include "DNBDefs.h"
-#include <limits.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-
-class DNBDataRef {
-public:
- // For use with Dump
- typedef enum {
- TypeUInt8 = 0,
- TypeChar,
- TypeUInt16,
- TypeUInt32,
- TypeUInt64,
- TypePointer,
- TypeULEB128,
- TypeSLEB128
- } Type;
- typedef uint32_t offset_t;
- typedef nub_addr_t addr_t;
-
- DNBDataRef();
- DNBDataRef(const uint8_t *start, size_t size, bool swap);
- ~DNBDataRef();
- void Clear() {
- DNBDataRef::SetData(NULL, 0);
- m_swap = false;
- }
-
- size_t BytesLeft(size_t offset) const {
- const size_t size = GetSize();
- if (size > offset)
- return size - offset;
- return 0;
- }
-
- bool ValidOffset(offset_t offset) const { return BytesLeft(offset) > 0; }
- bool ValidOffsetForDataOfSize(offset_t offset, uint32_t num_bytes) const {
- return num_bytes <= BytesLeft(offset);
- }
- size_t GetSize() const { return m_end - m_start; }
- const uint8_t *GetDataStart() const { return m_start; }
- const uint8_t *GetDataEnd() const { return m_end; }
- bool GetSwap() const { return m_swap; }
- void SetSwap(bool swap) { m_swap = swap; }
- void SetData(const uint8_t *start, size_t size) {
- m_start = start;
- if (m_start != NULL)
- m_end = start + size;
- else
- m_end = NULL;
- }
- uint8_t GetPointerSize() const { return m_ptrSize; }
- void SetPointerSize(uint8_t size) { m_ptrSize = size; }
- void SetEHPtrBaseAddrPCRelative(addr_t addr = INVALID_NUB_ADDRESS) {
- m_addrPCRelative = addr;
- }
- void SetEHPtrBaseAddrTEXT(addr_t addr = INVALID_NUB_ADDRESS) {
- m_addrTEXT = addr;
- }
- void SetEHPtrBaseAddrDATA(addr_t addr = INVALID_NUB_ADDRESS) {
- m_addrDATA = addr;
- }
- uint8_t Get8(offset_t *offset_ptr) const;
- uint16_t Get16(offset_t *offset_ptr) const;
- uint32_t Get32(offset_t *offset_ptr) const;
- uint64_t Get64(offset_t *offset_ptr) const;
- uint32_t GetMax32(offset_t *offset_ptr, uint32_t byte_size) const;
- uint64_t GetMax64(offset_t *offset_ptr, uint32_t byte_size) const;
- uint64_t GetPointer(offset_t *offset_ptr) const;
- // uint64_t GetDwarfEHPtr(offset_t *offset_ptr, uint32_t eh_ptr_enc)
- // const;
- const char *GetCStr(offset_t *offset_ptr, uint32_t fixed_length = 0) const;
- const char *PeekCStr(offset_t offset) const {
- if (ValidOffset(offset))
- return (const char *)m_start + offset;
- return NULL;
- }
-
- const uint8_t *GetData(offset_t *offset_ptr, uint32_t length) const;
- uint64_t Get_ULEB128(offset_t *offset_ptr) const;
- int64_t Get_SLEB128(offset_t *offset_ptr) const;
- void Skip_LEB128(offset_t *offset_ptr) const;
-
- uint32_t Dump(offset_t startOffset, offset_t endOffset, uint64_t offsetBase,
- DNBDataRef::Type type, uint32_t numPerLine,
- const char *typeFormat = NULL);
-
-protected:
- const uint8_t *m_start;
- const uint8_t *m_end;
- bool m_swap;
- uint8_t m_ptrSize;
- addr_t m_addrPCRelative;
- addr_t m_addrTEXT;
- addr_t m_addrDATA;
-};
-
-#endif // #ifndef __DNBDataRef_h__
diff --git a/tools/debugserver/source/DNBDefs.h b/tools/debugserver/source/DNBDefs.h
deleted file mode 100644
index 46476490aa69..000000000000
--- a/tools/debugserver/source/DNBDefs.h
+++ /dev/null
@@ -1,373 +0,0 @@
-//===-- DNBDefs.h -----------------------------------------------*- 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/26/07.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __DNBDefs_h__
-#define __DNBDefs_h__
-
-#include <signal.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <sys/syslimits.h>
-#include <unistd.h>
-
-//----------------------------------------------------------------------
-// Define nub_addr_t and the invalid address value from the architecture
-//----------------------------------------------------------------------
-#if defined(__x86_64__) || defined(__ppc64__) || defined(__arm64__) || \
- defined(__aarch64__)
-
-//----------------------------------------------------------------------
-// 64 bit address architectures
-//----------------------------------------------------------------------
-typedef uint64_t nub_addr_t;
-#define INVALID_NUB_ADDRESS ((nub_addr_t)~0ull)
-
-#elif defined(__i386__) || defined(__powerpc__) || defined(__ppc__) || \
- defined(__arm__)
-
-//----------------------------------------------------------------------
-// 32 bit address architectures
-//----------------------------------------------------------------------
-
-typedef uint32_t nub_addr_t;
-#define INVALID_NUB_ADDRESS ((nub_addr_t)~0ul)
-
-#else
-
-//----------------------------------------------------------------------
-// Default to 64 bit address for unrecognized architectures.
-//----------------------------------------------------------------------
-
-#warning undefined architecture, defaulting to 8 byte addresses
-typedef uint64_t nub_addr_t;
-#define INVALID_NUB_ADDRESS ((nub_addr_t)~0ull)
-
-#endif
-
-typedef size_t nub_size_t;
-typedef ssize_t nub_ssize_t;
-typedef uint32_t nub_index_t;
-typedef pid_t nub_process_t;
-typedef uint64_t nub_thread_t;
-typedef uint32_t nub_event_t;
-typedef uint32_t nub_bool_t;
-
-#define INVALID_NUB_PROCESS ((nub_process_t)0)
-#define INVALID_NUB_THREAD ((nub_thread_t)0)
-#define INVALID_NUB_WATCH_ID ((nub_watch_t)0)
-#define INVALID_NUB_HW_INDEX UINT32_MAX
-#define INVALID_NUB_REGNUM UINT32_MAX
-#define NUB_GENERIC_ERROR UINT32_MAX
-
-// Watchpoint types
-#define WATCH_TYPE_READ (1u << 0)
-#define WATCH_TYPE_WRITE (1u << 1)
-
-typedef enum {
- eStateInvalid = 0,
- eStateUnloaded,
- eStateAttaching,
- eStateLaunching,
- eStateStopped,
- eStateRunning,
- eStateStepping,
- eStateCrashed,
- eStateDetached,
- eStateExited,
- eStateSuspended
-} nub_state_t;
-
-typedef enum {
- eLaunchFlavorDefault = 0,
- eLaunchFlavorPosixSpawn = 1,
- eLaunchFlavorForkExec = 2,
-#ifdef WITH_SPRINGBOARD
- eLaunchFlavorSpringBoard = 3,
-#endif
-#ifdef WITH_BKS
- eLaunchFlavorBKS = 4,
-#endif
-#ifdef WITH_FBS
- eLaunchFlavorFBS = 5
-#endif
-} nub_launch_flavor_t;
-
-#define NUB_STATE_IS_RUNNING(s) \
- ((s) == eStateAttaching || (s) == eStateLaunching || (s) == eStateRunning || \
- (s) == eStateStepping || (s) == eStateDetached)
-
-#define NUB_STATE_IS_STOPPED(s) \
- ((s) == eStateUnloaded || (s) == eStateStopped || (s) == eStateCrashed || \
- (s) == eStateExited)
-
-enum {
- eEventProcessRunningStateChanged =
- 1 << 0, // The process has changed state to running
- eEventProcessStoppedStateChanged =
- 1 << 1, // The process has changed state to stopped
- eEventSharedLibsStateChange =
- 1 << 2, // Shared libraries loaded/unloaded state has changed
- eEventStdioAvailable = 1 << 3, // Something is available on stdout/stderr
- eEventProfileDataAvailable = 1 << 4, // Profile data ready for retrieval
- kAllEventsMask = eEventProcessRunningStateChanged |
- eEventProcessStoppedStateChanged |
- eEventSharedLibsStateChange | eEventStdioAvailable |
- eEventProfileDataAvailable
-};
-
-#define LOG_VERBOSE (1u << 0)
-#define LOG_PROCESS (1u << 1)
-#define LOG_THREAD (1u << 2)
-#define LOG_EXCEPTIONS (1u << 3)
-#define LOG_SHLIB (1u << 4)
-#define LOG_MEMORY (1u << 5) // Log memory reads/writes calls
-#define LOG_MEMORY_DATA_SHORT (1u << 6) // Log short memory reads/writes bytes
-#define LOG_MEMORY_DATA_LONG (1u << 7) // Log all memory reads/writes bytes
-#define LOG_MEMORY_PROTECTIONS (1u << 8) // Log memory protection changes
-#define LOG_BREAKPOINTS (1u << 9)
-#define LOG_EVENTS (1u << 10)
-#define LOG_WATCHPOINTS (1u << 11)
-#define LOG_STEP (1u << 12)
-#define LOG_TASK (1u << 13)
-#define LOG_DARWIN_LOG (1u << 14)
-#define LOG_LO_USER (1u << 16)
-#define LOG_HI_USER (1u << 31)
-#define LOG_ALL 0xFFFFFFFFu
-#define LOG_DEFAULT \
- ((LOG_PROCESS) | (LOG_TASK) | (LOG_THREAD) | (LOG_EXCEPTIONS) | \
- (LOG_SHLIB) | (LOG_MEMORY) | (LOG_BREAKPOINTS) | (LOG_WATCHPOINTS) | \
- (LOG_STEP))
-
-#define REGISTER_SET_ALL 0
-// Generic Register set to be defined by each architecture for access to common
-// register values.
-#define REGISTER_SET_GENERIC ((uint32_t)0xFFFFFFFFu)
-#define GENERIC_REGNUM_PC 0 // Program Counter
-#define GENERIC_REGNUM_SP 1 // Stack Pointer
-#define GENERIC_REGNUM_FP 2 // Frame Pointer
-#define GENERIC_REGNUM_RA 3 // Return Address
-#define GENERIC_REGNUM_FLAGS 4 // Processor flags register
-#define GENERIC_REGNUM_ARG1 \
- 5 // The register that would contain pointer size or less argument 1 (if any)
-#define GENERIC_REGNUM_ARG2 \
- 6 // The register that would contain pointer size or less argument 2 (if any)
-#define GENERIC_REGNUM_ARG3 \
- 7 // The register that would contain pointer size or less argument 3 (if any)
-#define GENERIC_REGNUM_ARG4 \
- 8 // The register that would contain pointer size or less argument 4 (if any)
-#define GENERIC_REGNUM_ARG5 \
- 9 // The register that would contain pointer size or less argument 5 (if any)
-#define GENERIC_REGNUM_ARG6 \
- 10 // The register that would contain pointer size or less argument 6 (if any)
-#define GENERIC_REGNUM_ARG7 \
- 11 // The register that would contain pointer size or less argument 7 (if any)
-#define GENERIC_REGNUM_ARG8 \
- 12 // The register that would contain pointer size or less argument 8 (if any)
-
-enum DNBRegisterType {
- InvalidRegType = 0,
- Uint, // unsigned integer
- Sint, // signed integer
- IEEE754, // float
- Vector // vector registers
-};
-
-enum DNBRegisterFormat {
- InvalidRegFormat = 0,
- Binary,
- Decimal,
- Hex,
- Float,
- VectorOfSInt8,
- VectorOfUInt8,
- VectorOfSInt16,
- VectorOfUInt16,
- VectorOfSInt32,
- VectorOfUInt32,
- VectorOfFloat32,
- VectorOfUInt128
-};
-
-struct DNBRegisterInfo {
- uint32_t set; // Register set
- uint32_t reg; // Register number
- const char *name; // Name of this register
- const char *alt; // Alternate name
- uint16_t type; // Type of the register bits (DNBRegisterType)
- uint16_t format; // Default format for display (DNBRegisterFormat),
- uint32_t size; // Size in bytes of the register
- uint32_t offset; // Offset from the beginning of the register context
- uint32_t
- reg_ehframe; // eh_frame register number (INVALID_NUB_REGNUM when none)
- uint32_t reg_dwarf; // DWARF register number (INVALID_NUB_REGNUM when none)
- uint32_t
- reg_generic; // Generic register number (INVALID_NUB_REGNUM when none)
- uint32_t reg_debugserver; // The debugserver register number we'll use over
- // gdb-remote protocol (INVALID_NUB_REGNUM when
- // none)
- const char **value_regs; // If this register is a part of other registers,
- // list the register names terminated by NULL
- const char **update_regs; // If modifying this register will invalidate other
- // registers, list the register names terminated by
- // NULL
-};
-
-struct DNBRegisterSetInfo {
- const char *name; // Name of this register set
- const struct DNBRegisterInfo *registers; // An array of register descriptions
- nub_size_t num_registers; // The number of registers in REGISTERS array above
-};
-
-struct DNBThreadResumeAction {
- nub_thread_t tid; // The thread ID that this action applies to,
- // INVALID_NUB_THREAD for the default thread action
- nub_state_t state; // Valid values are eStateStopped/eStateSuspended,
- // eStateRunning, and eStateStepping.
- int signal; // When resuming this thread, resume it with this signal
- nub_addr_t addr; // If not INVALID_NUB_ADDRESS, then set the PC for the thread
- // to ADDR before resuming/stepping
-};
-
-enum DNBThreadStopType {
- eStopTypeInvalid = 0,
- eStopTypeSignal,
- eStopTypeException,
- eStopTypeExec
-};
-
-enum DNBMemoryPermissions {
- eMemoryPermissionsWritable = (1 << 0),
- eMemoryPermissionsReadable = (1 << 1),
- eMemoryPermissionsExecutable = (1 << 2)
-};
-
-#define DNB_THREAD_STOP_INFO_MAX_DESC_LENGTH 256
-#define DNB_THREAD_STOP_INFO_MAX_EXC_DATA 8
-
-//----------------------------------------------------------------------
-// DNBThreadStopInfo
-//
-// Describes the reason a thread stopped.
-//----------------------------------------------------------------------
-struct DNBThreadStopInfo {
- DNBThreadStopType reason;
- char description[DNB_THREAD_STOP_INFO_MAX_DESC_LENGTH];
- union {
- // eStopTypeSignal
- struct {
- uint32_t signo;
- } signal;
-
- // eStopTypeException
- struct {
- uint32_t type;
- nub_size_t data_count;
- nub_addr_t data[DNB_THREAD_STOP_INFO_MAX_EXC_DATA];
- } exception;
- } details;
-};
-
-struct DNBRegisterValue {
- struct DNBRegisterInfo info; // Register information for this register
- union {
- int8_t sint8;
- int16_t sint16;
- int32_t sint32;
- int64_t sint64;
- uint8_t uint8;
- uint16_t uint16;
- uint32_t uint32;
- uint64_t uint64;
- float float32;
- double float64;
- int8_t v_sint8[64];
- int16_t v_sint16[32];
- int32_t v_sint32[16];
- int64_t v_sint64[8];
- uint8_t v_uint8[64];
- uint16_t v_uint16[32];
- uint32_t v_uint32[16];
- uint64_t v_uint64[8];
- float v_float32[16];
- double v_float64[8];
- void *pointer;
- char *c_str;
- } value;
-};
-
-enum DNBSharedLibraryState { eShlibStateUnloaded = 0, eShlibStateLoaded = 1 };
-
-#ifndef DNB_MAX_SEGMENT_NAME_LENGTH
-#define DNB_MAX_SEGMENT_NAME_LENGTH 32
-#endif
-
-struct DNBSegment {
- char name[DNB_MAX_SEGMENT_NAME_LENGTH];
- nub_addr_t addr;
- nub_addr_t size;
-};
-
-struct DNBExecutableImageInfo {
- char name[PATH_MAX]; // Name of the executable image (usually a full path)
- uint32_t
- state; // State of the executable image (see enum DNBSharedLibraryState)
- nub_addr_t header_addr; // Executable header address
- uuid_t uuid; // Unique identifier for matching with symbols
- uint32_t
- num_segments; // Number of contiguous memory segments to in SEGMENTS array
- DNBSegment *segments; // Array of contiguous memory segments in executable
-};
-
-struct DNBRegionInfo {
- nub_addr_t addr;
- nub_addr_t size;
- uint32_t permissions;
-};
-
-enum DNBProfileDataScanType {
- eProfileHostCPU = (1 << 0),
- eProfileCPU = (1 << 1),
-
- eProfileThreadsCPU =
- (1 << 2), // By default excludes eProfileThreadName and eProfileQueueName.
- eProfileThreadName =
- (1 << 3), // Assume eProfileThreadsCPU, get thread name as well.
- eProfileQueueName =
- (1 << 4), // Assume eProfileThreadsCPU, get queue name as well.
-
- eProfileHostMemory = (1 << 5),
-
- eProfileMemory = (1 << 6),
- eProfileMemoryAnonymous =
- (1 << 8), // Assume eProfileMemory, get Anonymous memory as well.
-
- eProfileEnergy = (1 << 9),
-
- eProfileMemoryCap = (1 << 15),
-
- eProfileAll = 0xffffffff
-};
-
-typedef nub_addr_t (*DNBCallbackNameToAddress)(nub_process_t pid,
- const char *name,
- const char *shlib_regex,
- void *baton);
-typedef nub_size_t (*DNBCallbackCopyExecutableImageInfos)(
- nub_process_t pid, struct DNBExecutableImageInfo **image_infos,
- nub_bool_t only_changed, void *baton);
-typedef void (*DNBCallbackLog)(void *baton, uint32_t flags, const char *format,
- va_list args);
-
-#define UNUSED_IF_ASSERT_DISABLED(x) ((void)(x))
-
-#endif // #ifndef __DNBDefs_h__
diff --git a/tools/debugserver/source/DNBError.cpp b/tools/debugserver/source/DNBError.cpp
deleted file mode 100644
index cd04358a4eca..000000000000
--- a/tools/debugserver/source/DNBError.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-//===-- DNBError.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/26/07.
-//
-//===----------------------------------------------------------------------===//
-
-#include "DNBError.h"
-#include "CFString.h"
-#include "DNBLog.h"
-#include "PThreadMutex.h"
-
-#ifdef WITH_SPRINGBOARD
-#include <SpringBoardServices/SpringBoardServer.h>
-#endif
-
-const char *DNBError::AsString() const {
- if (Success())
- return NULL;
-
- if (m_str.empty()) {
- const char *s = NULL;
- switch (m_flavor) {
- case MachKernel:
- s = ::mach_error_string(m_err);
- break;
-
- case POSIX:
- s = ::strerror(m_err);
- break;
-
-#ifdef WITH_SPRINGBOARD
- case SpringBoard: {
- CFStringRef statusStr = SBSApplicationLaunchingErrorString(m_err);
- if (CFString::UTF8(statusStr, m_str) == NULL)
- m_str.clear();
- } 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
-#ifdef WITH_FBS
- case FrontBoard: {
- // You have to call ObjC routines to get the error string from
- // FrontBoardServices.
- // 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
- // FrontBoard.
- m_str.assign(
- "Should have set FrontBoard error when making the error string.");
- } break;
-#endif
- default:
- break;
- }
- if (s)
- m_str.assign(s);
- }
- if (m_str.empty())
- return NULL;
- return m_str.c_str();
-}
-
-void DNBError::LogThreadedIfError(const char *format, ...) const {
- if (Fail()) {
- char *arg_msg = NULL;
- va_list args;
- va_start(args, format);
- ::vasprintf(&arg_msg, format, args);
- va_end(args);
-
- if (arg_msg != NULL) {
- const char *err_str = AsString();
- if (err_str == NULL)
- err_str = "???";
- DNBLogThreaded("error: %s err = %s (0x%8.8x)", arg_msg, err_str, m_err);
- free(arg_msg);
- }
- }
-}
-
-void DNBError::LogThreaded(const char *format, ...) const {
- char *arg_msg = NULL;
- va_list args;
- va_start(args, format);
- ::vasprintf(&arg_msg, format, args);
- va_end(args);
-
- if (arg_msg != NULL) {
- if (Fail()) {
- const char *err_str = AsString();
- if (err_str == NULL)
- err_str = "???";
- DNBLogThreaded("error: %s err = %s (0x%8.8x)", arg_msg, err_str, m_err);
- } else {
- DNBLogThreaded("%s err = 0x%8.8x", arg_msg, m_err);
- }
- free(arg_msg);
- }
-}
diff --git a/tools/debugserver/source/DNBError.h b/tools/debugserver/source/DNBError.h
deleted file mode 100644
index 419f4b9492ed..000000000000
--- a/tools/debugserver/source/DNBError.h
+++ /dev/null
@@ -1,98 +0,0 @@
-//===-- DNBError.h ----------------------------------------------*- 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/26/07.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __DNBError_h__
-#define __DNBError_h__
-
-#include <errno.h>
-#include <mach/mach.h>
-#include <stdio.h>
-#include <string>
-
-class DNBError {
-public:
- typedef uint32_t ValueType;
- typedef enum {
- Generic = 0,
- MachKernel = 1,
- POSIX = 2
-#ifdef WITH_SPRINGBOARD
- ,
- SpringBoard = 3
-#endif
-#ifdef WITH_BKS
- ,
- BackBoard = 4
-#endif
-#ifdef WITH_FBS
- ,
- FrontBoard = 5
-#endif
- } FlavorType;
-
- explicit DNBError(ValueType err = 0, FlavorType flavor = Generic)
- : m_err(err), m_flavor(flavor) {}
-
- const char *AsString() const;
- void Clear() {
- m_err = 0;
- m_flavor = Generic;
- m_str.clear();
- }
- ValueType Status() const { return m_err; }
- FlavorType Flavor() const { return m_flavor; }
-
- ValueType operator=(kern_return_t err) {
- m_err = err;
- m_flavor = MachKernel;
- m_str.clear();
- return m_err;
- }
-
- void SetError(kern_return_t err) {
- m_err = err;
- m_flavor = MachKernel;
- m_str.clear();
- }
-
- void SetErrorToErrno() {
- m_err = errno;
- m_flavor = POSIX;
- m_str.clear();
- }
-
- void SetError(ValueType err, FlavorType flavor) {
- m_err = err;
- m_flavor = flavor;
- m_str.clear();
- }
-
- // Generic errors can set their own string values
- void SetErrorString(const char *err_str) {
- if (err_str && err_str[0])
- m_str = err_str;
- else
- m_str.clear();
- }
- bool Success() const { return m_err == 0; }
- bool Fail() const { return m_err != 0; }
- void LogThreadedIfError(const char *format, ...) const;
- void LogThreaded(const char *format, ...) const;
-
-protected:
- ValueType m_err;
- FlavorType m_flavor;
- mutable std::string m_str;
-};
-
-#endif // #ifndef __DNBError_h__
diff --git a/tools/debugserver/source/DNBLog.cpp b/tools/debugserver/source/DNBLog.cpp
deleted file mode 100644
index c3d42a2a84da..000000000000
--- a/tools/debugserver/source/DNBLog.cpp
+++ /dev/null
@@ -1,287 +0,0 @@
-//===-- DNBLog.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/18/07.
-//
-//===----------------------------------------------------------------------===//
-
-#include "DNBLog.h"
-
-static int g_debug = 0;
-static int g_verbose = 0;
-
-#if defined(DNBLOG_ENABLED)
-
-#include "PThreadMutex.h"
-#include <mach/mach.h>
-#include <pthread.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <unistd.h>
-
-uint32_t g_log_bits = 0;
-static DNBCallbackLog g_log_callback = NULL;
-static void *g_log_baton = NULL;
-
-int DNBLogGetDebug() { return g_debug; }
-
-void DNBLogSetDebug(int g) { g_debug = g; }
-
-int DNBLogGetVerbose() { return g_verbose; }
-
-void DNBLogSetVerbose(int v) { g_verbose = v; }
-
-bool DNBLogCheckLogBit(uint32_t bit) { return (g_log_bits & bit) != 0; }
-
-uint32_t DNBLogSetLogMask(uint32_t mask) {
- uint32_t old = g_log_bits;
- g_log_bits = mask;
- return old;
-}
-
-uint32_t DNBLogGetLogMask() { return g_log_bits; }
-
-void DNBLogSetLogCallback(DNBCallbackLog callback, void *baton) {
- g_log_callback = callback;
- g_log_baton = baton;
-}
-
-DNBCallbackLog DNBLogGetLogCallback() { return g_log_callback; }
-
-bool DNBLogEnabled() { return g_log_callback != NULL; }
-
-bool DNBLogEnabledForAny(uint32_t mask) {
- if (g_log_callback)
- return (g_log_bits & mask) != 0;
- return false;
-}
-static inline void _DNBLogVAPrintf(uint32_t flags, const char *format,
- va_list args) {
- static PThreadMutex g_LogThreadedMutex(PTHREAD_MUTEX_RECURSIVE);
- PTHREAD_MUTEX_LOCKER(locker, g_LogThreadedMutex);
-
- if (g_log_callback)
- g_log_callback(g_log_baton, flags, format, args);
-}
-
-void _DNBLog(uint32_t flags, const char *format, ...) {
- va_list args;
- va_start(args, format);
- _DNBLogVAPrintf(flags, format, args);
- va_end(args);
-}
-
-//----------------------------------------------------------------------
-// Print debug strings if and only if the global g_debug is set to
-// a non-zero value.
-//----------------------------------------------------------------------
-void _DNBLogDebug(const char *format, ...) {
- if (DNBLogEnabled() && g_debug) {
- va_list args;
- va_start(args, format);
- _DNBLogVAPrintf(DNBLOG_FLAG_DEBUG, format, args);
- va_end(args);
- }
-}
-
-//----------------------------------------------------------------------
-// Print debug strings if and only if the global g_debug is set to
-// a non-zero value.
-//----------------------------------------------------------------------
-void _DNBLogDebugVerbose(const char *format, ...) {
- if (DNBLogEnabled() && g_debug && g_verbose) {
- va_list args;
- va_start(args, format);
- _DNBLogVAPrintf(DNBLOG_FLAG_DEBUG | DNBLOG_FLAG_VERBOSE, format, args);
- va_end(args);
- }
-}
-
-static uint32_t g_message_id = 0;
-
-//----------------------------------------------------------------------
-// Prefix the formatted log string with process and thread IDs and
-// suffix it with a newline.
-//----------------------------------------------------------------------
-void _DNBLogThreaded(const char *format, ...) {
- if (DNBLogEnabled()) {
- // PTHREAD_MUTEX_LOCKER(locker, GetLogThreadedMutex());
-
- char *arg_msg = NULL;
- va_list args;
- va_start(args, format);
- ::vasprintf(&arg_msg, format, args);
- va_end(args);
-
- if (arg_msg != NULL) {
- static struct timeval g_timeval = {0, 0};
- static struct timeval tv;
- static struct timeval delta;
- gettimeofday(&tv, NULL);
- if (g_timeval.tv_sec == 0) {
- delta.tv_sec = 0;
- delta.tv_usec = 0;
- } else {
- timersub(&tv, &g_timeval, &delta);
- }
- g_timeval = tv;
-
- // Calling "mach_port_deallocate()" bumps the reference count on the
- // thread
- // port, so we need to deallocate it. mach_task_self() doesn't bump the
- // ref
- // count.
- thread_port_t thread_self = mach_thread_self();
-
- _DNBLog(DNBLOG_FLAG_THREADED, "%u +%lu.%06u sec [%4.4x/%4.4x]: %s",
- ++g_message_id, delta.tv_sec, delta.tv_usec, getpid(),
- thread_self, arg_msg);
-
- mach_port_deallocate(mach_task_self(), thread_self);
- free(arg_msg);
- }
- }
-}
-
-//----------------------------------------------------------------------
-// Prefix the formatted log string with process and thread IDs and
-// suffix it with a newline.
-//----------------------------------------------------------------------
-void _DNBLogThreadedIf(uint32_t log_bit, const char *format, ...) {
- if (DNBLogEnabled() && (log_bit & g_log_bits) == log_bit) {
- // PTHREAD_MUTEX_LOCKER(locker, GetLogThreadedMutex());
-
- char *arg_msg = NULL;
- va_list args;
- va_start(args, format);
- ::vasprintf(&arg_msg, format, args);
- va_end(args);
-
- if (arg_msg != NULL) {
- static struct timeval g_timeval = {0, 0};
- static struct timeval tv;
- static struct timeval delta;
- gettimeofday(&tv, NULL);
- if (g_timeval.tv_sec == 0) {
- delta.tv_sec = 0;
- delta.tv_usec = 0;
- } else {
- timersub(&tv, &g_timeval, &delta);
- }
- g_timeval = tv;
-
- // Calling "mach_port_deallocate()" bumps the reference count on the
- // thread
- // port, so we need to deallocate it. mach_task_self() doesn't bump the
- // ref
- // count.
- thread_port_t thread_self = mach_thread_self();
-
- _DNBLog(DNBLOG_FLAG_THREADED, "%u +%lu.%06u sec [%4.4x/%4.4x]: %s",
- ++g_message_id, delta.tv_sec, delta.tv_usec, getpid(),
- thread_self, arg_msg);
-
- mach_port_deallocate(mach_task_self(), thread_self);
-
- free(arg_msg);
- }
- }
-}
-
-//----------------------------------------------------------------------
-// Printing of errors that are not fatal.
-//----------------------------------------------------------------------
-void _DNBLogError(const char *format, ...) {
- if (DNBLogEnabled()) {
- char *arg_msg = NULL;
- va_list args;
- va_start(args, format);
- ::vasprintf(&arg_msg, format, args);
- va_end(args);
-
- if (arg_msg != NULL) {
- _DNBLog(DNBLOG_FLAG_ERROR, "error: %s", arg_msg);
- free(arg_msg);
- }
- }
-}
-
-//----------------------------------------------------------------------
-// Printing of errors that ARE fatal. Exit with ERR exit code
-// immediately.
-//----------------------------------------------------------------------
-void _DNBLogFatalError(int err, const char *format, ...) {
- if (DNBLogEnabled()) {
- char *arg_msg = NULL;
- va_list args;
- va_start(args, format);
- ::vasprintf(&arg_msg, format, args);
- va_end(args);
-
- if (arg_msg != NULL) {
- _DNBLog(DNBLOG_FLAG_ERROR | DNBLOG_FLAG_FATAL, "error: %s", arg_msg);
- free(arg_msg);
- }
- ::exit(err);
- }
-}
-
-//----------------------------------------------------------------------
-// Printing of warnings that are not fatal only if verbose mode is
-// enabled.
-//----------------------------------------------------------------------
-void _DNBLogVerbose(const char *format, ...) {
- if (DNBLogEnabled() && g_verbose) {
- va_list args;
- va_start(args, format);
- _DNBLogVAPrintf(DNBLOG_FLAG_VERBOSE, format, args);
- va_end(args);
- }
-}
-
-//----------------------------------------------------------------------
-// Printing of warnings that are not fatal only if verbose mode is
-// enabled.
-//----------------------------------------------------------------------
-void _DNBLogWarningVerbose(const char *format, ...) {
- if (DNBLogEnabled() && g_verbose) {
- char *arg_msg = NULL;
- va_list args;
- va_start(args, format);
- ::vasprintf(&arg_msg, format, args);
- va_end(args);
-
- if (arg_msg != NULL) {
- _DNBLog(DNBLOG_FLAG_WARNING | DNBLOG_FLAG_VERBOSE, "warning: %s",
- arg_msg);
- free(arg_msg);
- }
- }
-}
-//----------------------------------------------------------------------
-// Printing of warnings that are not fatal.
-//----------------------------------------------------------------------
-void _DNBLogWarning(const char *format, ...) {
- if (DNBLogEnabled()) {
- char *arg_msg = NULL;
- va_list args;
- va_start(args, format);
- ::vasprintf(&arg_msg, format, args);
- va_end(args);
-
- if (arg_msg != NULL) {
- _DNBLog(DNBLOG_FLAG_WARNING, "warning: %s", arg_msg);
- free(arg_msg);
- }
- }
-}
-
-#endif
diff --git a/tools/debugserver/source/DNBLog.h b/tools/debugserver/source/DNBLog.h
deleted file mode 100644
index 65181caa412d..000000000000
--- a/tools/debugserver/source/DNBLog.h
+++ /dev/null
@@ -1,153 +0,0 @@
-//===-- DNBLog.h ------------------------------------------------*- 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/18/07.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __DNBLog_h__
-#define __DNBLog_h__
-
-#include "DNBDefs.h"
-#include <stdint.h>
-#include <stdio.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// Flags that get filled in automatically before calling the log callback
-// function
-#define DNBLOG_FLAG_FATAL (1u << 0)
-#define DNBLOG_FLAG_ERROR (1u << 1)
-#define DNBLOG_FLAG_WARNING (1u << 2)
-#define DNBLOG_FLAG_DEBUG (1u << 3)
-#define DNBLOG_FLAG_VERBOSE (1u << 4)
-#define DNBLOG_FLAG_THREADED (1u << 5)
-
-#define DNBLOG_ENABLED
-
-#if defined(DNBLOG_ENABLED)
-
-void _DNBLog(uint32_t flags, const char *format, ...)
- __attribute__((format(printf, 2, 3)));
-void _DNBLogDebug(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
-void _DNBLogDebugVerbose(const char *fmt, ...)
- __attribute__((format(printf, 1, 2)));
-void _DNBLogThreaded(const char *fmt, ...)
- __attribute__((format(printf, 1, 2)));
-void _DNBLogThreadedIf(uint32_t mask, const char *fmt, ...)
- __attribute__((format(printf, 2, 3)));
-void _DNBLogError(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
-void _DNBLogFatalError(int err, const char *fmt, ...)
- __attribute__((format(printf, 2, 3)));
-void _DNBLogVerbose(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
-void _DNBLogWarning(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
-void _DNBLogWarningVerbose(const char *fmt, ...)
- __attribute__((format(printf, 1, 2)));
-bool DNBLogCheckLogBit(uint32_t bit);
-uint32_t DNBLogSetLogMask(uint32_t mask);
-uint32_t DNBLogGetLogMask();
-void DNBLogSetLogCallback(DNBCallbackLog callback, void *baton);
-DNBCallbackLog DNBLogGetLogCallback();
-bool DNBLogEnabled();
-bool DNBLogEnabledForAny(uint32_t mask);
-int DNBLogGetDebug();
-void DNBLogSetDebug(int g);
-int DNBLogGetVerbose();
-void DNBLogSetVerbose(int g);
-
-#define DNBLog(fmt, ...) \
- do { \
- if (DNBLogEnabled()) { \
- _DNBLog(0, fmt, ##__VA_ARGS__); \
- } \
- } while (0)
-#define DNBLogDebug(fmt, ...) \
- do { \
- if (DNBLogEnabled()) { \
- _DNBLogDebug(fmt, ##__VA_ARGS__); \
- } \
- } while (0)
-#define DNBLogDebugVerbose(fmt, ...) \
- do { \
- if (DNBLogEnabled()) { \
- _DNBLogDebugVerbose(fmt, ##__VA_ARGS__); \
- } \
- } while (0)
-#define DNBLogThreaded(fmt, ...) \
- do { \
- if (DNBLogEnabled()) { \
- _DNBLogThreaded(fmt, ##__VA_ARGS__); \
- } \
- } while (0)
-#define DNBLogThreadedIf(mask, fmt, ...) \
- do { \
- if (DNBLogEnabledForAny(mask)) { \
- _DNBLogThreaded(fmt, ##__VA_ARGS__); \
- } \
- } while (0)
-#define DNBLogError(fmt, ...) \
- do { \
- if (DNBLogEnabled()) { \
- _DNBLogError(fmt, ##__VA_ARGS__); \
- } \
- } while (0)
-#define DNBLogFatalError(err, fmt, ...) \
- do { \
- if (DNBLogEnabled()) { \
- _DNBLogFatalError(err, fmt, ##__VA_ARGS__); \
- } \
- } while (0)
-#define DNBLogVerbose(fmt, ...) \
- do { \
- if (DNBLogEnabled()) { \
- _DNBLogVerbose(fmt, ##__VA_ARGS__); \
- } \
- } while (0)
-#define DNBLogWarning(fmt, ...) \
- do { \
- if (DNBLogEnabled()) { \
- _DNBLogWarning(fmt, ##__VA_ARGS__); \
- } \
- } while (0)
-#define DNBLogWarningVerbose(fmt, ...) \
- do { \
- if (DNBLogEnabled()) { \
- _DNBLogWarningVerbose(fmt, ##__VA_ARGS__); \
- } \
- } while (0)
-
-#else // #if defined(DNBLOG_ENABLED)
-
-#define DNBLogDebug(...) ((void)0)
-#define DNBLogDebugVerbose(...) ((void)0)
-#define DNBLogThreaded(...) ((void)0)
-#define DNBLogThreadedIf(...) ((void)0)
-#define DNBLogError(...) ((void)0)
-#define DNBLogFatalError(...) ((void)0)
-#define DNBLogVerbose(...) ((void)0)
-#define DNBLogWarning(...) ((void)0)
-#define DNBLogWarningVerbose(...) ((void)0)
-#define DNBLogGetLogFile() ((FILE *)NULL)
-#define DNBLogSetLogFile(f) ((void)0)
-#define DNBLogCheckLogBit(bit) ((bool)false)
-#define DNBLogSetLogMask(mask) ((uint32_t)0u)
-#define DNBLogGetLogMask() ((uint32_t)0u)
-#define DNBLogToASL() ((void)0)
-#define DNBLogToFile() ((void)0)
-#define DNBLogCloseLogFile() ((void)0)
-
-#endif // #else defined(DNBLOG_ENABLED)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // #ifndef __DNBLog_h__
diff --git a/tools/debugserver/source/DNBRegisterInfo.cpp b/tools/debugserver/source/DNBRegisterInfo.cpp
deleted file mode 100644
index d0f6063fbce0..000000000000
--- a/tools/debugserver/source/DNBRegisterInfo.cpp
+++ /dev/null
@@ -1,252 +0,0 @@
-//===-- DNBRegisterInfo.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 8/3/07.
-//
-//===----------------------------------------------------------------------===//
-
-#include "DNBRegisterInfo.h"
-#include "DNBLog.h"
-#include <string.h>
-
-DNBRegisterValueClass::DNBRegisterValueClass(const DNBRegisterInfo *regInfo) {
- Clear();
- if (regInfo)
- info = *regInfo;
-}
-
-void DNBRegisterValueClass::Clear() {
- memset(&info, 0, sizeof(DNBRegisterInfo));
- memset(&value, 0, sizeof(value));
-}
-
-bool DNBRegisterValueClass::IsValid() const {
- return info.name != NULL && info.type != InvalidRegType && info.size > 0 &&
- info.size <= sizeof(value);
-}
-
-#define PRINT_COMMA_SEPARATOR \
- do { \
- if (pos < end) { \
- if (i > 0) { \
- strlcpy(pos, ", ", end - pos); \
- pos += 2; \
- } \
- } \
- } while (0)
-
-void DNBRegisterValueClass::Dump(const char *pre, const char *post) const {
- if (info.name != NULL) {
- char str[1024];
- char *pos;
- char *end = str + sizeof(str);
- if (info.format == Hex) {
- switch (info.size) {
- case 0:
- snprintf(str, sizeof(str), "%s",
- "error: invalid register size of zero.");
- break;
- case 1:
- snprintf(str, sizeof(str), "0x%2.2x", value.uint8);
- break;
- case 2:
- snprintf(str, sizeof(str), "0x%4.4x", value.uint16);
- break;
- case 4:
- snprintf(str, sizeof(str), "0x%8.8x", value.uint32);
- break;
- case 8:
- snprintf(str, sizeof(str), "0x%16.16llx", value.uint64);
- break;
- case 16:
- snprintf(str, sizeof(str), "0x%16.16llx%16.16llx", value.v_uint64[0],
- value.v_uint64[1]);
- break;
- default:
- strlcpy(str, "0x", 3);
- pos = str + 2;
- for (uint32_t i = 0; i < info.size; ++i) {
- if (pos < end)
- pos +=
- snprintf(pos, end - pos, "%2.2x", (uint32_t)value.v_uint8[i]);
- }
- break;
- }
- } else {
- switch (info.type) {
- case Uint:
- switch (info.size) {
- case 1:
- snprintf(str, sizeof(str), "%u", value.uint8);
- break;
- case 2:
- snprintf(str, sizeof(str), "%u", value.uint16);
- break;
- case 4:
- snprintf(str, sizeof(str), "%u", value.uint32);
- break;
- case 8:
- snprintf(str, sizeof(str), "%llu", value.uint64);
- break;
- default:
- snprintf(str, sizeof(str), "error: unsupported uint byte size %d.",
- info.size);
- break;
- }
- break;
-
- case Sint:
- switch (info.size) {
- case 1:
- snprintf(str, sizeof(str), "%d", value.sint8);
- break;
- case 2:
- snprintf(str, sizeof(str), "%d", value.sint16);
- break;
- case 4:
- snprintf(str, sizeof(str), "%d", value.sint32);
- break;
- case 8:
- snprintf(str, sizeof(str), "%lld", value.sint64);
- break;
- default:
- snprintf(str, sizeof(str), "error: unsupported sint byte size %d.",
- info.size);
- break;
- }
- break;
-
- case IEEE754:
- switch (info.size) {
- case 4:
- snprintf(str, sizeof(str), "%f", value.float32);
- break;
- case 8:
- snprintf(str, sizeof(str), "%g", value.float64);
- break;
- default:
- snprintf(str, sizeof(str), "error: unsupported float byte size %d.",
- info.size);
- break;
- }
- break;
-
- case Vector:
- if (info.size > 0) {
- switch (info.format) {
- case VectorOfSInt8:
- snprintf(str, sizeof(str), "%s", "sint8 { ");
- pos = str + strlen(str);
- for (uint32_t i = 0; i < info.size; ++i) {
- PRINT_COMMA_SEPARATOR;
- if (pos < end)
- pos +=
- snprintf(pos, end - pos, "%d", (int32_t)value.v_sint8[i]);
- }
- strlcat(str, " }", sizeof(str));
- break;
-
- default:
- DNBLogError(
- "unsupported vector format %d, defaulting to hex bytes.",
- info.format);
- [[clang::fallthrough]];
- case VectorOfUInt8:
- snprintf(str, sizeof(str), "%s", "uint8 { ");
- pos = str + strlen(str);
- for (uint32_t i = 0; i < info.size; ++i) {
- PRINT_COMMA_SEPARATOR;
- if (pos < end)
- pos +=
- snprintf(pos, end - pos, "%u", (uint32_t)value.v_uint8[i]);
- }
- break;
-
- case VectorOfSInt16:
- snprintf(str, sizeof(str), "%s", "sint16 { ");
- pos = str + strlen(str);
- for (uint32_t i = 0; i < info.size / 2; ++i) {
- PRINT_COMMA_SEPARATOR;
- if (pos < end)
- pos +=
- snprintf(pos, end - pos, "%d", (int32_t)value.v_sint16[i]);
- }
- break;
-
- case VectorOfUInt16:
- snprintf(str, sizeof(str), "%s", "uint16 { ");
- pos = str + strlen(str);
- for (uint32_t i = 0; i < info.size / 2; ++i) {
- PRINT_COMMA_SEPARATOR;
- if (pos < end)
- pos +=
- snprintf(pos, end - pos, "%u", (uint32_t)value.v_uint16[i]);
- }
- break;
-
- case VectorOfSInt32:
- snprintf(str, sizeof(str), "%s", "sint32 { ");
- pos = str + strlen(str);
- for (uint32_t i = 0; i < info.size / 4; ++i) {
- PRINT_COMMA_SEPARATOR;
- if (pos < end)
- pos +=
- snprintf(pos, end - pos, "%d", (int32_t)value.v_sint32[i]);
- }
- break;
-
- case VectorOfUInt32:
- snprintf(str, sizeof(str), "%s", "uint32 { ");
- pos = str + strlen(str);
- for (uint32_t i = 0; i < info.size / 4; ++i) {
- PRINT_COMMA_SEPARATOR;
- if (pos < end)
- pos +=
- snprintf(pos, end - pos, "%u", (uint32_t)value.v_uint32[i]);
- }
- break;
-
- case VectorOfFloat32:
- snprintf(str, sizeof(str), "%s", "float32 { ");
- pos = str + strlen(str);
- for (uint32_t i = 0; i < info.size / 4; ++i) {
- PRINT_COMMA_SEPARATOR;
- if (pos < end)
- pos += snprintf(pos, end - pos, "%f", value.v_float32[i]);
- }
- break;
-
- case VectorOfUInt128:
- snprintf(str, sizeof(str), "%s", "uint128 { ");
- pos = str + strlen(str);
- for (uint32_t i = 0; i < info.size / 16; ++i) {
- PRINT_COMMA_SEPARATOR;
- if (pos < end)
- pos += snprintf(pos, end - pos, "0x%16.16llx%16.16llx",
- value.v_uint64[i], value.v_uint64[i + 1]);
- }
- break;
- }
- strlcat(str, " }", sizeof(str));
- } else {
- snprintf(str, sizeof(str), "error: unsupported vector size %d.",
- info.size);
- }
- break;
-
- default:
- snprintf(str, sizeof(str), "error: unsupported register type %d.",
- info.type);
- break;
- }
- }
-
- DNBLog("%s%4s = %s%s", pre ? pre : "", info.name, str, post ? post : "");
- }
-}
diff --git a/tools/debugserver/source/DNBRegisterInfo.h b/tools/debugserver/source/DNBRegisterInfo.h
deleted file mode 100644
index d665e3cb9485..000000000000
--- a/tools/debugserver/source/DNBRegisterInfo.h
+++ /dev/null
@@ -1,30 +0,0 @@
-//===-- DNBRegisterInfo.h ---------------------------------------*- 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 8/3/07.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __DNBRegisterInfo_h__
-#define __DNBRegisterInfo_h__
-
-#include "DNBDefs.h"
-#include <stdint.h>
-#include <stdio.h>
-
-struct DNBRegisterValueClass : public DNBRegisterValue {
-#ifdef __cplusplus
- DNBRegisterValueClass(const DNBRegisterInfo *regInfo = NULL);
- void Clear();
- void Dump(const char *pre, const char *post) const;
- bool IsValid() const;
-#endif
-};
-
-#endif
diff --git a/tools/debugserver/source/DNBRuntimeAction.h b/tools/debugserver/source/DNBRuntimeAction.h
deleted file mode 100644
index 85d7bc1df0a5..000000000000
--- a/tools/debugserver/source/DNBRuntimeAction.h
+++ /dev/null
@@ -1,24 +0,0 @@
-//===-- DNBRuntimeAction.h --------------------------------------*- 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 10/8/07.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __DNBRuntimeAction_h__
-#define __DNBRuntimeAction_h__
-
-class DNBRuntimeAction {
- virtual void Initialize(nub_process_t pid) = 0;
- virtual void ProcessStateChanged(nub_state_t state) = 0;
- virtual void SharedLibraryStateChanged(DNBExecutableImageInfo *image_infos,
- nub_size_t num_image_infos) = 0;
-};
-
-#endif // #ifndef __DNBRuntimeAction_h__
diff --git a/tools/debugserver/source/DNBThreadResumeActions.cpp b/tools/debugserver/source/DNBThreadResumeActions.cpp
deleted file mode 100644
index 4a97abc20e24..000000000000
--- a/tools/debugserver/source/DNBThreadResumeActions.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-//===-- DNBThreadResumeActions.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 03/13/2010
-//
-//===----------------------------------------------------------------------===//
-
-#include "DNBThreadResumeActions.h"
-
-DNBThreadResumeActions::DNBThreadResumeActions()
- : m_actions(), m_signal_handled() {}
-
-DNBThreadResumeActions::DNBThreadResumeActions(
- const DNBThreadResumeAction *actions, size_t num_actions)
- : m_actions(), m_signal_handled() {
- if (actions && num_actions) {
- m_actions.assign(actions, actions + num_actions);
- m_signal_handled.assign(num_actions, false);
- }
-}
-
-DNBThreadResumeActions::DNBThreadResumeActions(nub_state_t default_action,
- int signal)
- : m_actions(), m_signal_handled() {
- SetDefaultThreadActionIfNeeded(default_action, signal);
-}
-
-void DNBThreadResumeActions::Append(const DNBThreadResumeAction &action) {
- m_actions.push_back(action);
- m_signal_handled.push_back(false);
-}
-
-void DNBThreadResumeActions::AppendAction(nub_thread_t tid, nub_state_t state,
- int signal, nub_addr_t addr) {
- DNBThreadResumeAction action = {tid, state, signal, addr};
- Append(action);
-}
-
-const DNBThreadResumeAction *
-DNBThreadResumeActions::GetActionForThread(nub_thread_t tid,
- bool default_ok) const {
- const size_t num_actions = m_actions.size();
- for (size_t i = 0; i < num_actions; ++i) {
- if (m_actions[i].tid == tid)
- return &m_actions[i];
- }
- if (default_ok && tid != INVALID_NUB_THREAD)
- return GetActionForThread(INVALID_NUB_THREAD, false);
- return NULL;
-}
-
-size_t DNBThreadResumeActions::NumActionsWithState(nub_state_t state) const {
- size_t count = 0;
- const size_t num_actions = m_actions.size();
- for (size_t i = 0; i < num_actions; ++i) {
- if (m_actions[i].state == state)
- ++count;
- }
- return count;
-}
-
-bool DNBThreadResumeActions::SetDefaultThreadActionIfNeeded(nub_state_t action,
- int signal) {
- if (GetActionForThread(INVALID_NUB_THREAD, true) == NULL) {
- // There isn't a default action so we do need to set it.
- DNBThreadResumeAction default_action = {INVALID_NUB_THREAD, action, signal,
- INVALID_NUB_ADDRESS};
- m_actions.push_back(default_action);
- m_signal_handled.push_back(false);
- return true; // Return true as we did add the default action
- }
- return false;
-}
-
-void DNBThreadResumeActions::SetSignalHandledForThread(nub_thread_t tid) const {
- if (tid != INVALID_NUB_THREAD) {
- const size_t num_actions = m_actions.size();
- for (size_t i = 0; i < num_actions; ++i) {
- if (m_actions[i].tid == tid)
- m_signal_handled[i] = true;
- }
- }
-}
diff --git a/tools/debugserver/source/DNBThreadResumeActions.h b/tools/debugserver/source/DNBThreadResumeActions.h
deleted file mode 100644
index 40d2da03e9e4..000000000000
--- a/tools/debugserver/source/DNBThreadResumeActions.h
+++ /dev/null
@@ -1,66 +0,0 @@
-//===-- DNBThreadResumeActions.h --------------------------------*- 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 03/13/2010
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __DNBThreadResumeActions_h__
-#define __DNBThreadResumeActions_h__
-
-#include <vector>
-
-#include "DNBDefs.h"
-
-class DNBThreadResumeActions {
-public:
- DNBThreadResumeActions();
-
- DNBThreadResumeActions(nub_state_t default_action, int signal);
-
- DNBThreadResumeActions(const DNBThreadResumeAction *actions,
- size_t num_actions);
-
- bool IsEmpty() const { return m_actions.empty(); }
-
- void Append(const DNBThreadResumeAction &action);
-
- void AppendAction(nub_thread_t tid, nub_state_t state, int signal = 0,
- nub_addr_t addr = INVALID_NUB_ADDRESS);
-
- void AppendResumeAll() { AppendAction(INVALID_NUB_THREAD, eStateRunning); }
-
- void AppendSuspendAll() { AppendAction(INVALID_NUB_THREAD, eStateStopped); }
-
- void AppendStepAll() { AppendAction(INVALID_NUB_THREAD, eStateStepping); }
-
- const DNBThreadResumeAction *GetActionForThread(nub_thread_t tid,
- bool default_ok) const;
-
- size_t NumActionsWithState(nub_state_t state) const;
-
- bool SetDefaultThreadActionIfNeeded(nub_state_t action, int signal);
-
- void SetSignalHandledForThread(nub_thread_t tid) const;
-
- const DNBThreadResumeAction *GetFirst() const { return m_actions.data(); }
-
- size_t GetSize() const { return m_actions.size(); }
-
- void Clear() {
- m_actions.clear();
- m_signal_handled.clear();
- }
-
-protected:
- std::vector<DNBThreadResumeAction> m_actions;
- mutable std::vector<bool> m_signal_handled;
-};
-
-#endif // #ifndef __DNBThreadResumeActions_h__
diff --git a/tools/debugserver/source/DNBTimer.h b/tools/debugserver/source/DNBTimer.h
deleted file mode 100644
index 881b8cdcde76..000000000000
--- a/tools/debugserver/source/DNBTimer.h
+++ /dev/null
@@ -1,145 +0,0 @@
-//===-- DNBTimer.h ----------------------------------------------*- 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 12/13/07.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __DNBTimer_h__
-#define __DNBTimer_h__
-
-#include "DNBDefs.h"
-#include "PThreadMutex.h"
-#include <memory>
-#include <stdint.h>
-#include <sys/time.h>
-
-class DNBTimer {
-public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- DNBTimer(bool threadSafe) : m_mutexAP() {
- if (threadSafe)
- m_mutexAP.reset(new PThreadMutex(PTHREAD_MUTEX_RECURSIVE));
- Reset();
- }
-
- DNBTimer(const DNBTimer &rhs) : m_mutexAP() {
- // Create a new mutex to make this timer thread safe as well if
- // the timer we are copying is thread safe
- if (rhs.IsThreadSafe())
- m_mutexAP.reset(new PThreadMutex(PTHREAD_MUTEX_RECURSIVE));
- m_timeval = rhs.m_timeval;
- }
-
- DNBTimer &operator=(const DNBTimer &rhs) {
- // Create a new mutex to make this timer thread safe as well if
- // the timer we are copying is thread safe
- if (rhs.IsThreadSafe())
- m_mutexAP.reset(new PThreadMutex(PTHREAD_MUTEX_RECURSIVE));
- m_timeval = rhs.m_timeval;
- return *this;
- }
-
- ~DNBTimer() {}
-
- bool IsThreadSafe() const { return m_mutexAP.get() != NULL; }
- //------------------------------------------------------------------
- // Reset the time value to now
- //------------------------------------------------------------------
- void Reset() {
- PTHREAD_MUTEX_LOCKER(locker, m_mutexAP.get());
- gettimeofday(&m_timeval, NULL);
- }
- //------------------------------------------------------------------
- // Get the total mircoseconds since Jan 1, 1970
- //------------------------------------------------------------------
- uint64_t TotalMicroSeconds() const {
- PTHREAD_MUTEX_LOCKER(locker, m_mutexAP.get());
- return (uint64_t)(m_timeval.tv_sec) * 1000000ull +
- (uint64_t)m_timeval.tv_usec;
- }
-
- void GetTime(uint64_t &sec, uint32_t &usec) const {
- PTHREAD_MUTEX_LOCKER(locker, m_mutexAP.get());
- sec = m_timeval.tv_sec;
- usec = m_timeval.tv_usec;
- }
- //------------------------------------------------------------------
- // Return the number of microseconds elapsed between now and the
- // m_timeval
- //------------------------------------------------------------------
- uint64_t ElapsedMicroSeconds(bool update) {
- PTHREAD_MUTEX_LOCKER(locker, m_mutexAP.get());
- struct timeval now;
- gettimeofday(&now, NULL);
- uint64_t now_usec =
- (uint64_t)(now.tv_sec) * 1000000ull + (uint64_t)now.tv_usec;
- uint64_t this_usec =
- (uint64_t)(m_timeval.tv_sec) * 1000000ull + (uint64_t)m_timeval.tv_usec;
- uint64_t elapsed = now_usec - this_usec;
- // Update the timer time value if requeseted
- if (update)
- m_timeval = now;
- return elapsed;
- }
-
- static uint64_t GetTimeOfDay() {
- struct timeval now;
- gettimeofday(&now, NULL);
- uint64_t now_usec =
- (uint64_t)(now.tv_sec) * 1000000ull + (uint64_t)now.tv_usec;
- return now_usec;
- }
-
- static void OffsetTimeOfDay(struct timespec *ts,
- __darwin_time_t sec_offset = 0,
- long nsec_offset = 0) {
- if (ts == NULL)
- return;
- // Get the current time in a timeval structure
- struct timeval now;
- gettimeofday(&now, NULL);
- // Morph it into a timespec
- TIMEVAL_TO_TIMESPEC(&now, ts);
- // Offset the timespec if requested
- if (sec_offset != 0 || nsec_offset != 0) {
- // Offset the nano seconds
- ts->tv_nsec += nsec_offset;
- // Offset the seconds taking into account a nano-second overflow
- ts->tv_sec = ts->tv_sec + ts->tv_nsec / 1000000000 + sec_offset;
- // Trim the nanoseconds back there was an overflow
- ts->tv_nsec = ts->tv_nsec % 1000000000;
- }
- }
- static bool TimeOfDayLaterThan(struct timespec &ts) {
- struct timespec now;
- OffsetTimeOfDay(&now);
- if (now.tv_sec > ts.tv_sec)
- return true;
- else if (now.tv_sec < ts.tv_sec)
- return false;
- else {
- if (now.tv_nsec > ts.tv_nsec)
- return true;
- else
- return false;
- }
- }
-
-protected:
- //------------------------------------------------------------------
- // Classes that inherit from DNBTimer can see and modify these
- //------------------------------------------------------------------
- std::unique_ptr<PThreadMutex> m_mutexAP;
- struct timeval m_timeval;
-};
-
-#endif // #ifndef __DNBTimer_h__
diff --git a/tools/debugserver/source/JSON.cpp b/tools/debugserver/source/JSON.cpp
deleted file mode 100644
index 439918b6fcc4..000000000000
--- a/tools/debugserver/source/JSON.cpp
+++ /dev/null
@@ -1,585 +0,0 @@
-//===--------------------- JSON.cpp -----------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "JSON.h"
-
-// C includes
-#include <assert.h>
-#include <limits.h>
-
-// C++ includes
-#include "lldb/Host/StringConvert.h"
-#include <iomanip>
-#include <sstream>
-
-using namespace lldb_private;
-
-std::string JSONString::json_string_quote_metachars(const std::string &s) {
- if (s.find('"') == std::string::npos)
- return s;
-
- std::string output;
- const size_t s_size = s.size();
- const char *s_chars = s.c_str();
- for (size_t i = 0; i < s_size; i++) {
- unsigned char ch = *(s_chars + i);
- if (ch == '"') {
- output.push_back('\\');
- }
- output.push_back(ch);
- }
- return output;
-}
-
-JSONString::JSONString() : JSONValue(JSONValue::Kind::String), m_data() {}
-
-JSONString::JSONString(const char *s)
- : JSONValue(JSONValue::Kind::String), m_data(s ? s : "") {}
-
-JSONString::JSONString(const std::string &s)
- : JSONValue(JSONValue::Kind::String), m_data(s) {}
-
-void JSONString::Write(std::ostream &s) {
- s << "\"" << json_string_quote_metachars(m_data).c_str() << "\"";
-}
-
-uint64_t JSONNumber::GetAsUnsigned() const {
- switch (m_data_type) {
- case DataType::Unsigned:
- return m_data.m_unsigned;
- case DataType::Signed:
- return (uint64_t)m_data.m_signed;
- case DataType::Double:
- return (uint64_t)m_data.m_double;
- }
-}
-
-int64_t JSONNumber::GetAsSigned() const {
- switch (m_data_type) {
- case DataType::Unsigned:
- return (int64_t)m_data.m_unsigned;
- case DataType::Signed:
- return m_data.m_signed;
- case DataType::Double:
- return (int64_t)m_data.m_double;
- }
-}
-
-double JSONNumber::GetAsDouble() const {
- switch (m_data_type) {
- case DataType::Unsigned:
- return (double)m_data.m_unsigned;
- case DataType::Signed:
- return (double)m_data.m_signed;
- case DataType::Double:
- return m_data.m_double;
- }
-}
-
-void JSONNumber::Write(std::ostream &s) {
- switch (m_data_type) {
- case DataType::Unsigned:
- s << m_data.m_unsigned;
- break;
- case DataType::Signed:
- s << m_data.m_signed;
- break;
- case DataType::Double:
- // Set max precision to emulate %g.
- s << std::setprecision(std::numeric_limits<double>::digits10 + 1);
- s << m_data.m_double;
- break;
- }
-}
-
-JSONTrue::JSONTrue() : JSONValue(JSONValue::Kind::True) {}
-
-void JSONTrue::Write(std::ostream &s) { s << "true"; }
-
-JSONFalse::JSONFalse() : JSONValue(JSONValue::Kind::False) {}
-
-void JSONFalse::Write(std::ostream &s) { s << "false"; }
-
-JSONNull::JSONNull() : JSONValue(JSONValue::Kind::Null) {}
-
-void JSONNull::Write(std::ostream &s) { s << "null"; }
-
-JSONObject::JSONObject() : JSONValue(JSONValue::Kind::Object) {}
-
-void JSONObject::Write(std::ostream &s) {
- bool first = true;
- s << '{';
- auto iter = m_elements.begin(), end = m_elements.end();
- for (; iter != end; iter++) {
- if (first)
- first = false;
- else
- s << ',';
- JSONString key(iter->first);
- JSONValue::SP value(iter->second);
- key.Write(s);
- s << ':';
- value->Write(s);
- }
- s << '}';
-}
-
-bool JSONObject::SetObject(const std::string &key, JSONValue::SP value) {
- if (key.empty() || nullptr == value.get())
- return false;
- m_elements[key] = value;
- return true;
-}
-
-JSONValue::SP JSONObject::GetObject(const std::string &key) const {
- auto iter = m_elements.find(key), end = m_elements.end();
- if (iter == end)
- return JSONValue::SP();
- return iter->second;
-}
-
-bool JSONObject::GetObjectAsBool(const std::string &key, bool &value) const {
- auto value_sp = GetObject(key);
- if (!value_sp) {
- // The given key doesn't exist, so we have no value.
- return false;
- }
-
- if (JSONTrue::classof(value_sp.get())) {
- // We have the value, and it is true.
- value = true;
- return true;
- } else if (JSONFalse::classof(value_sp.get())) {
- // We have the value, and it is false.
- value = false;
- return true;
- } else {
- // We don't have a valid bool value for the given key.
- return false;
- }
-}
-
-bool JSONObject::GetObjectAsString(const std::string &key,
- std::string &value) const {
- auto value_sp = GetObject(key);
- if (!value_sp) {
- // The given key doesn't exist, so we have no value.
- return false;
- }
-
- if (!JSONString::classof(value_sp.get()))
- return false;
-
- value = static_cast<JSONString *>(value_sp.get())->GetData();
- return true;
-}
-
-JSONArray::JSONArray() : JSONValue(JSONValue::Kind::Array) {}
-
-void JSONArray::Write(std::ostream &s) {
- bool first = true;
- s << '[';
- auto iter = m_elements.begin(), end = m_elements.end();
- for (; iter != end; iter++) {
- if (first)
- first = false;
- else
- s << ',';
- (*iter)->Write(s);
- }
- s << ']';
-}
-
-bool JSONArray::SetObject(Index i, JSONValue::SP value) {
- if (value.get() == nullptr)
- return false;
- if (i < m_elements.size()) {
- m_elements[i] = value;
- return true;
- }
- if (i == m_elements.size()) {
- m_elements.push_back(value);
- return true;
- }
- return false;
-}
-
-bool JSONArray::AppendObject(JSONValue::SP value) {
- if (value.get() == nullptr)
- return false;
- m_elements.push_back(value);
- return true;
-}
-
-JSONValue::SP JSONArray::GetObject(Index i) {
- if (i < m_elements.size())
- return m_elements[i];
- return JSONValue::SP();
-}
-
-JSONArray::Size JSONArray::GetNumElements() { return m_elements.size(); }
-
-JSONParser::JSONParser(const char *cstr) : StdStringExtractor(cstr) {}
-
-JSONParser::Token JSONParser::GetToken(std::string &value) {
- std::ostringstream error;
-
- value.clear();
- SkipSpaces();
- const uint64_t start_index = m_index;
- const char ch = GetChar();
- switch (ch) {
- case '{':
- return Token::ObjectStart;
- case '}':
- return Token::ObjectEnd;
- case '[':
- return Token::ArrayStart;
- case ']':
- return Token::ArrayEnd;
- case ',':
- return Token::Comma;
- case ':':
- return Token::Colon;
- case '\0':
- return Token::EndOfFile;
- case 't':
- if (GetChar() == 'r')
- if (GetChar() == 'u')
- if (GetChar() == 'e')
- return Token::True;
- break;
-
- case 'f':
- if (GetChar() == 'a')
- if (GetChar() == 'l')
- if (GetChar() == 's')
- if (GetChar() == 'e')
- return Token::False;
- break;
-
- case 'n':
- if (GetChar() == 'u')
- if (GetChar() == 'l')
- if (GetChar() == 'l')
- return Token::Null;
- break;
-
- case '"': {
- while (1) {
- bool was_escaped = false;
- int escaped_ch = GetEscapedChar(was_escaped);
- if (escaped_ch == -1) {
- error << "error: an error occurred getting a character from offset "
- << start_index;
- value = error.str();
- return Token::Status;
-
- } else {
- const bool is_end_quote = escaped_ch == '"';
- const bool is_null = escaped_ch == 0;
- if (was_escaped || (!is_end_quote && !is_null)) {
- if (CHAR_MIN <= escaped_ch && escaped_ch <= CHAR_MAX) {
- value.append(1, (char)escaped_ch);
- } else {
- error << "error: wide character support is needed for unicode "
- "character 0x"
- << std::setprecision(4) << std::hex << escaped_ch;
- error << " at offset " << start_index;
- value = error.str();
- return Token::Status;
- }
- } else if (is_end_quote) {
- return Token::String;
- } else if (is_null) {
- value = "error: missing end quote for string";
- return Token::Status;
- }
- }
- }
- } break;
-
- case '-':
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9': {
- bool done = false;
- bool got_decimal_point = false;
- uint64_t exp_index = 0;
- bool got_int_digits = (ch >= '0') && (ch <= '9');
- bool got_frac_digits = false;
- bool got_exp_digits = false;
- while (!done) {
- const char next_ch = PeekChar();
- switch (next_ch) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- if (exp_index != 0) {
- got_exp_digits = true;
- } else if (got_decimal_point) {
- got_frac_digits = true;
- } else {
- got_int_digits = true;
- }
- ++m_index; // Skip this character
- break;
-
- case '.':
- if (got_decimal_point) {
- error << "error: extra decimal point found at offset " << start_index;
- value = error.str();
- return Token::Status;
- } else {
- got_decimal_point = true;
- ++m_index; // Skip this character
- }
- break;
-
- case 'e':
- case 'E':
- if (exp_index != 0) {
- error << "error: extra exponent character found at offset "
- << start_index;
- value = error.str();
- return Token::Status;
- } else {
- exp_index = m_index;
- ++m_index; // Skip this character
- }
- break;
-
- case '+':
- case '-':
- // The '+' and '-' can only come after an exponent character...
- if (exp_index == m_index - 1) {
- ++m_index; // Skip the exponent sign character
- } else {
- error << "error: unexpected " << next_ch << " character at offset "
- << start_index;
- value = error.str();
- return Token::Status;
- }
- break;
-
- default:
- done = true;
- break;
- }
- }
-
- if (m_index > start_index) {
- value = m_packet.substr(start_index, m_index - start_index);
- if (got_decimal_point) {
- if (exp_index != 0) {
- // We have an exponent, make sure we got exponent digits
- if (got_exp_digits) {
- return Token::Float;
- } else {
- error << "error: got exponent character but no exponent digits at "
- "offset in float value \""
- << value.c_str() << "\"";
- value = error.str();
- return Token::Status;
- }
- } else {
- // No exponent, but we need at least one decimal after the decimal
- // point
- if (got_frac_digits) {
- return Token::Float;
- } else {
- error << "error: no digits after decimal point \"" << value.c_str()
- << "\"";
- value = error.str();
- return Token::Status;
- }
- }
- } else {
- // No decimal point
- if (got_int_digits) {
- // We need at least some integer digits to make an integer
- return Token::Integer;
- } else {
- error << "error: no digits negate sign \"" << value.c_str() << "\"";
- value = error.str();
- return Token::Status;
- }
- }
- } else {
- error << "error: invalid number found at offset " << start_index;
- value = error.str();
- return Token::Status;
- }
- } break;
- default:
- break;
- }
- error << "error: failed to parse token at offset " << start_index
- << " (around character '" << ch << "')";
- value = error.str();
- return Token::Status;
-}
-
-int JSONParser::GetEscapedChar(bool &was_escaped) {
- was_escaped = false;
- const char ch = GetChar();
- if (ch == '\\') {
- was_escaped = true;
- const char ch2 = GetChar();
- switch (ch2) {
- case '"':
- case '\\':
- case '/':
- default:
- break;
-
- case 'b':
- return '\b';
- case 'f':
- return '\f';
- case 'n':
- return '\n';
- case 'r':
- return '\r';
- case 't':
- return '\t';
- case 'u': {
- const int hi_byte = DecodeHexU8();
- const int lo_byte = DecodeHexU8();
- if (hi_byte >= 0 && lo_byte >= 0)
- return hi_byte << 8 | lo_byte;
- return -1;
- } break;
- }
- return ch2;
- }
- return ch;
-}
-
-JSONValue::SP JSONParser::ParseJSONObject() {
- // The "JSONParser::Token::ObjectStart" token should have already been
- // consumed
- // by the time this function is called
- std::unique_ptr<JSONObject> dict_up(new JSONObject());
-
- std::string value;
- std::string key;
- while (1) {
- JSONParser::Token token = GetToken(value);
-
- if (token == JSONParser::Token::String) {
- key.swap(value);
- token = GetToken(value);
- if (token == JSONParser::Token::Colon) {
- JSONValue::SP value_sp = ParseJSONValue();
- if (value_sp)
- dict_up->SetObject(key, value_sp);
- else
- break;
- }
- } else if (token == JSONParser::Token::ObjectEnd) {
- return JSONValue::SP(dict_up.release());
- } else if (token == JSONParser::Token::Comma) {
- continue;
- } else {
- break;
- }
- }
- return JSONValue::SP();
-}
-
-JSONValue::SP JSONParser::ParseJSONArray() {
- // The "JSONParser::Token::ObjectStart" token should have already been
- // consumed
- // by the time this function is called
- std::unique_ptr<JSONArray> array_up(new JSONArray());
-
- std::string value;
- std::string key;
- while (1) {
- JSONValue::SP value_sp = ParseJSONValue();
- if (value_sp)
- array_up->AppendObject(value_sp);
- else
- break;
-
- JSONParser::Token token = GetToken(value);
- if (token == JSONParser::Token::Comma) {
- continue;
- } else if (token == JSONParser::Token::ArrayEnd) {
- return JSONValue::SP(array_up.release());
- } else {
- break;
- }
- }
- return JSONValue::SP();
-}
-
-JSONValue::SP JSONParser::ParseJSONValue() {
- std::string value;
- const JSONParser::Token token = GetToken(value);
- switch (token) {
- case JSONParser::Token::ObjectStart:
- return ParseJSONObject();
-
- case JSONParser::Token::ArrayStart:
- return ParseJSONArray();
-
- case JSONParser::Token::Integer: {
- if (value.front() == '-') {
- bool success = false;
- int64_t sval = StringConvert::ToSInt64(value.c_str(), 0, 0, &success);
- if (success)
- return JSONValue::SP(new JSONNumber(sval));
- } else {
- bool success = false;
- uint64_t uval = StringConvert::ToUInt64(value.c_str(), 0, 0, &success);
- if (success)
- return JSONValue::SP(new JSONNumber(uval));
- }
- } break;
-
- case JSONParser::Token::Float: {
- bool success = false;
- double val = StringConvert::ToDouble(value.c_str(), 0.0, &success);
- if (success)
- return JSONValue::SP(new JSONNumber(val));
- } break;
-
- case JSONParser::Token::String:
- return JSONValue::SP(new JSONString(value));
-
- case JSONParser::Token::True:
- return JSONValue::SP(new JSONTrue());
-
- case JSONParser::Token::False:
- return JSONValue::SP(new JSONFalse());
-
- case JSONParser::Token::Null:
- return JSONValue::SP(new JSONNull());
-
- default:
- break;
- }
- return JSONValue::SP();
-}
diff --git a/tools/debugserver/source/JSON.h b/tools/debugserver/source/JSON.h
deleted file mode 100644
index 252ff021f912..000000000000
--- a/tools/debugserver/source/JSON.h
+++ /dev/null
@@ -1,303 +0,0 @@
-//===---------------------JSON.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_JSON_h_
-#define utility_JSON_h_
-
-#include "StdStringExtractor.h"
-
-// C includes
-#include <inttypes.h>
-#include <stdint.h>
-
-// C++ includes
-#include <map>
-#include <memory>
-#include <ostream>
-#include <string>
-#include <vector>
-
-class JSONValue {
-public:
- virtual void Write(std::ostream &s) = 0;
-
- typedef std::shared_ptr<JSONValue> SP;
-
- enum class Kind { String, Number, True, False, Null, Object, Array };
-
- JSONValue(Kind k) : m_kind(k) {}
-
- Kind GetKind() const { return m_kind; }
-
- virtual ~JSONValue() = default;
-
-private:
- const Kind m_kind;
-};
-
-class JSONString : public JSONValue {
-public:
- JSONString();
- JSONString(const char *s);
- JSONString(const std::string &s);
-
- JSONString(const JSONString &s) = delete;
- JSONString &operator=(const JSONString &s) = delete;
-
- void Write(std::ostream &s) override;
-
- typedef std::shared_ptr<JSONString> SP;
-
- std::string GetData() { return m_data; }
-
- static bool classof(const JSONValue *V) {
- return V->GetKind() == JSONValue::Kind::String;
- }
-
- ~JSONString() override = default;
-
-private:
- static std::string json_string_quote_metachars(const std::string &);
-
- std::string m_data;
-};
-
-class JSONNumber : public JSONValue {
-public:
- typedef std::shared_ptr<JSONNumber> SP;
-
- // We cretae a constructor for all integer and floating point type with using
- // templates and
- // SFINAE to avoid having ambiguous overloads because of the implicit type
- // promotion. If we
- // would have constructors only with int64_t, uint64_t and double types then
- // constructing a
- // JSONNumber from an int32_t (or any other similar type) would fail to
- // compile.
-
- template <typename T, typename std::enable_if<
- std::is_integral<T>::value &&
- std::is_unsigned<T>::value>::type * = nullptr>
- explicit JSONNumber(T u)
- : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Unsigned) {
- m_data.m_unsigned = u;
- }
-
- template <typename T,
- typename std::enable_if<std::is_integral<T>::value &&
- std::is_signed<T>::value>::type * = nullptr>
- explicit JSONNumber(T s)
- : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Signed) {
- m_data.m_signed = s;
- }
-
- template <typename T, typename std::enable_if<
- std::is_floating_point<T>::value>::type * = nullptr>
- explicit JSONNumber(T d)
- : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Double) {
- m_data.m_double = d;
- }
-
- ~JSONNumber() override = default;
-
- JSONNumber(const JSONNumber &s) = delete;
- JSONNumber &operator=(const JSONNumber &s) = delete;
-
- void Write(std::ostream &s) override;
-
- uint64_t GetAsUnsigned() const;
-
- int64_t GetAsSigned() const;
-
- double GetAsDouble() const;
-
- static bool classof(const JSONValue *V) {
- return V->GetKind() == JSONValue::Kind::Number;
- }
-
-private:
- enum class DataType : uint8_t { Unsigned, Signed, Double } m_data_type;
-
- union {
- uint64_t m_unsigned;
- int64_t m_signed;
- double m_double;
- } m_data;
-};
-
-class JSONTrue : public JSONValue {
-public:
- JSONTrue();
-
- JSONTrue(const JSONTrue &s) = delete;
- JSONTrue &operator=(const JSONTrue &s) = delete;
-
- void Write(std::ostream &s) override;
-
- typedef std::shared_ptr<JSONTrue> SP;
-
- static bool classof(const JSONValue *V) {
- return V->GetKind() == JSONValue::Kind::True;
- }
-
- ~JSONTrue() override = default;
-};
-
-class JSONFalse : public JSONValue {
-public:
- JSONFalse();
-
- JSONFalse(const JSONFalse &s) = delete;
- JSONFalse &operator=(const JSONFalse &s) = delete;
-
- void Write(std::ostream &s) override;
-
- typedef std::shared_ptr<JSONFalse> SP;
-
- static bool classof(const JSONValue *V) {
- return V->GetKind() == JSONValue::Kind::False;
- }
-
- ~JSONFalse() override = default;
-};
-
-class JSONNull : public JSONValue {
-public:
- JSONNull();
-
- JSONNull(const JSONNull &s) = delete;
- JSONNull &operator=(const JSONNull &s) = delete;
-
- void Write(std::ostream &s) override;
-
- typedef std::shared_ptr<JSONNull> SP;
-
- static bool classof(const JSONValue *V) {
- return V->GetKind() == JSONValue::Kind::Null;
- }
-
- ~JSONNull() override = default;
-};
-
-class JSONObject : public JSONValue {
-public:
- JSONObject();
-
- JSONObject(const JSONObject &s) = delete;
- JSONObject &operator=(const JSONObject &s) = delete;
-
- void Write(std::ostream &s) override;
-
- typedef std::shared_ptr<JSONObject> SP;
-
- static bool classof(const JSONValue *V) {
- return V->GetKind() == JSONValue::Kind::Object;
- }
-
- bool SetObject(const std::string &key, JSONValue::SP value);
-
- JSONValue::SP GetObject(const std::string &key) const;
-
- // -------------------------------------------------------------------------
- /// Return keyed value as bool
- ///
- /// @param[in] key
- /// The value of the key to lookup
- ///
- /// @param[out] value
- /// The value of the key as a bool. Undefined if the key doesn't
- /// exist or if the key is not either true or false.
- ///
- /// @return
- /// true if the key existed as was a bool value; false otherwise.
- /// Note the return value is *not* the value of the bool, use
- /// \b value for that.
- // -------------------------------------------------------------------------
- bool GetObjectAsBool(const std::string &key, bool &value) const;
-
- bool GetObjectAsString(const std::string &key, std::string &value) const;
-
- ~JSONObject() override = default;
-
-private:
- typedef std::map<std::string, JSONValue::SP> Map;
- typedef Map::iterator Iterator;
- Map m_elements;
-};
-
-class JSONArray : public JSONValue {
-public:
- JSONArray();
-
- JSONArray(const JSONArray &s) = delete;
- JSONArray &operator=(const JSONArray &s) = delete;
-
- void Write(std::ostream &s) override;
-
- typedef std::shared_ptr<JSONArray> SP;
-
- static bool classof(const JSONValue *V) {
- return V->GetKind() == JSONValue::Kind::Array;
- }
-
-private:
- typedef std::vector<JSONValue::SP> Vector;
- typedef Vector::iterator Iterator;
- typedef Vector::size_type Index;
- typedef Vector::size_type Size;
-
-public:
- bool SetObject(Index i, JSONValue::SP value);
-
- bool AppendObject(JSONValue::SP value);
-
- JSONValue::SP GetObject(Index i);
-
- Size GetNumElements();
-
- ~JSONArray() override = default;
-
- Vector m_elements;
-};
-
-class JSONParser : public StdStringExtractor {
-public:
- enum Token {
- Invalid,
- Status,
- ObjectStart,
- ObjectEnd,
- ArrayStart,
- ArrayEnd,
- Comma,
- Colon,
- String,
- Integer,
- Float,
- True,
- False,
- Null,
- EndOfFile
- };
-
- JSONParser(const char *cstr);
-
- int GetEscapedChar(bool &was_escaped);
-
- Token GetToken(std::string &value);
-
- JSONValue::SP ParseJSONValue();
-
-protected:
- JSONValue::SP ParseJSONObject();
-
- JSONValue::SP ParseJSONArray();
-};
-
-#endif // utility_JSON_h_
diff --git a/tools/debugserver/source/JSONGenerator.h b/tools/debugserver/source/JSONGenerator.h
deleted file mode 100644
index 0ac5e0bb768c..000000000000
--- a/tools/debugserver/source/JSONGenerator.h
+++ /dev/null
@@ -1,317 +0,0 @@
-//===-- JSONGenerator.h ----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __JSONGenerator_h_
-#define __JSONGenerator_h_
-
-
-#include <iomanip>
-#include <sstream>
-#include <string>
-#include <utility>
-#include <vector>
-
-//----------------------------------------------------------------------
-/// @class JSONGenerator JSONGenerator.h
-/// A class which can construct structured data for the sole purpose
-/// of printing it in JSON format.
-///
-/// A stripped down version of lldb's StructuredData objects which are much
-/// general purpose. This variant is intended only for assembling information
-/// and printing it as a JSON string.
-//----------------------------------------------------------------------
-
-class JSONGenerator {
-public:
- class Object;
- class Array;
- class Integer;
- class Float;
- class Boolean;
- class String;
- class Dictionary;
- class Generic;
-
- typedef std::shared_ptr<Object> ObjectSP;
- typedef std::shared_ptr<Array> ArraySP;
- typedef std::shared_ptr<Integer> IntegerSP;
- typedef std::shared_ptr<Float> FloatSP;
- typedef std::shared_ptr<Boolean> BooleanSP;
- typedef std::shared_ptr<String> StringSP;
- typedef std::shared_ptr<Dictionary> DictionarySP;
- typedef std::shared_ptr<Generic> GenericSP;
-
- enum class Type {
- eTypeInvalid = -1,
- eTypeNull = 0,
- eTypeGeneric,
- eTypeArray,
- eTypeInteger,
- eTypeFloat,
- eTypeBoolean,
- eTypeString,
- eTypeDictionary
- };
-
- class Object : public std::enable_shared_from_this<Object> {
- public:
- Object(Type t = Type::eTypeInvalid) : m_type(t) {}
-
- virtual ~Object() {}
-
- virtual bool IsValid() const { return true; }
-
- virtual void Clear() { m_type = Type::eTypeInvalid; }
-
- Type GetType() const { return m_type; }
-
- void SetType(Type t) { m_type = t; }
-
- Array *GetAsArray() {
- if (m_type == Type::eTypeArray)
- return (Array *)this;
- return NULL;
- }
-
- Dictionary *GetAsDictionary() {
- if (m_type == Type::eTypeDictionary)
- return (Dictionary *)this;
- return NULL;
- }
-
- Integer *GetAsInteger() {
- if (m_type == Type::eTypeInteger)
- return (Integer *)this;
- return NULL;
- }
-
- Float *GetAsFloat() {
- if (m_type == Type::eTypeFloat)
- return (Float *)this;
- return NULL;
- }
-
- Boolean *GetAsBoolean() {
- if (m_type == Type::eTypeBoolean)
- return (Boolean *)this;
- return NULL;
- }
-
- String *GetAsString() {
- if (m_type == Type::eTypeString)
- return (String *)this;
- return NULL;
- }
-
- Generic *GetAsGeneric() {
- if (m_type == Type::eTypeGeneric)
- return (Generic *)this;
- return NULL;
- }
-
- virtual void Dump(std::ostream &s) const = 0;
-
- private:
- Type m_type;
- };
-
- class Array : public Object {
- public:
- Array() : Object(Type::eTypeArray) {}
-
- virtual ~Array() {}
-
- void AddItem(ObjectSP item) { m_items.push_back(item); }
-
- void Dump(std::ostream &s) const override {
- s << "[";
- const size_t arrsize = m_items.size();
- for (size_t i = 0; i < arrsize; ++i) {
- m_items[i]->Dump(s);
- if (i + 1 < arrsize)
- s << ",";
- }
- s << "]";
- }
-
- protected:
- typedef std::vector<ObjectSP> collection;
- collection m_items;
- };
-
- class Integer : public Object {
- public:
- Integer(uint64_t value = 0) : Object(Type::eTypeInteger), m_value(value) {}
-
- virtual ~Integer() {}
-
- void SetValue(uint64_t value) { m_value = value; }
-
- void Dump(std::ostream &s) const override { s << m_value; }
-
- protected:
- uint64_t m_value;
- };
-
- class Float : public Object {
- public:
- Float(double d = 0.0) : Object(Type::eTypeFloat), m_value(d) {}
-
- virtual ~Float() {}
-
- void SetValue(double value) { m_value = value; }
-
- void Dump(std::ostream &s) const override { s << m_value; }
-
- protected:
- double m_value;
- };
-
- class Boolean : public Object {
- public:
- Boolean(bool b = false) : Object(Type::eTypeBoolean), m_value(b) {}
-
- virtual ~Boolean() {}
-
- void SetValue(bool value) { m_value = value; }
-
- void Dump(std::ostream &s) const override {
- if (m_value)
- s << "true";
- else
- s << "false";
- }
-
- protected:
- bool m_value;
- };
-
- class String : public Object {
- public:
- String() : Object(Type::eTypeString), m_value() {}
-
- String(const std::string &s) : Object(Type::eTypeString), m_value(s) {}
-
- String(const std::string &&s) : Object(Type::eTypeString), m_value(s) {}
-
- void SetValue(const std::string &string) { m_value = string; }
-
- void Dump(std::ostream &s) const override {
- std::string quoted;
- const size_t strsize = m_value.size();
- for (size_t i = 0; i < strsize; ++i) {
- char ch = m_value[i];
- if (ch == '"')
- quoted.push_back('\\');
- quoted.push_back(ch);
- }
- s << '"' << quoted.c_str() << '"';
- }
-
- protected:
- std::string m_value;
- };
-
- class Dictionary : public Object {
- public:
- Dictionary() : Object(Type::eTypeDictionary), m_dict() {}
-
- virtual ~Dictionary() {}
-
- void AddItem(std::string key, ObjectSP value) {
- m_dict.push_back(Pair(key, value));
- }
-
- void AddIntegerItem(std::string key, uint64_t value) {
- AddItem(key, ObjectSP(new Integer(value)));
- }
-
- void AddFloatItem(std::string key, double value) {
- AddItem(key, ObjectSP(new Float(value)));
- }
-
- void AddStringItem(std::string key, std::string value) {
- AddItem(key, ObjectSP(new String(std::move(value))));
- }
-
- void AddBytesAsHexASCIIString(std::string key, const uint8_t *src,
- size_t src_len) {
- if (src && src_len) {
- std::ostringstream strm;
- for (size_t i = 0; i < src_len; i++)
- strm << std::setfill('0') << std::hex << std::right << std::setw(2)
- << ((uint32_t)(src[i]));
- AddItem(key, ObjectSP(new String(std::move(strm.str()))));
- } else {
- AddItem(key, ObjectSP(new String()));
- }
- }
-
- void AddBooleanItem(std::string key, bool value) {
- AddItem(key, ObjectSP(new Boolean(value)));
- }
-
- void Dump(std::ostream &s) const override {
- bool have_printed_one_elem = false;
- s << "{";
- for (collection::const_iterator iter = m_dict.begin();
- iter != m_dict.end(); ++iter) {
- if (!have_printed_one_elem) {
- have_printed_one_elem = true;
- } else {
- s << ",";
- }
- s << "\"" << iter->first.c_str() << "\":";
- iter->second->Dump(s);
- }
- s << "}";
- }
-
- protected:
- // Keep the dictionary as a vector so the dictionary doesn't reorder itself
- // when you dump it
- // We aren't accessing keys by name, so this won't affect performance
- typedef std::pair<std::string, ObjectSP> Pair;
- typedef std::vector<Pair> collection;
- collection m_dict;
- };
-
- class Null : public Object {
- public:
- Null() : Object(Type::eTypeNull) {}
-
- virtual ~Null() {}
-
- bool IsValid() const override { return false; }
-
- void Dump(std::ostream &s) const override { s << "null"; }
-
- protected:
- };
-
- class Generic : public Object {
- public:
- explicit Generic(void *object = nullptr)
- : Object(Type::eTypeGeneric), m_object(object) {}
-
- void SetValue(void *value) { m_object = value; }
-
- void *GetValue() const { return m_object; }
-
- bool IsValid() const override { return m_object != nullptr; }
-
- void Dump(std::ostream &s) const override;
-
- private:
- void *m_object;
- };
-
-}; // class JSONGenerator
-
-#endif // __JSONGenerator_h_
diff --git a/tools/debugserver/source/MacOSX/CFBundle.cpp b/tools/debugserver/source/MacOSX/CFBundle.cpp
deleted file mode 100644
index 40f82b4243e0..000000000000
--- a/tools/debugserver/source/MacOSX/CFBundle.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-//===-- CFBundle.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 1/16/08.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CFBundle.h"
-#include "CFString.h"
-
-//----------------------------------------------------------------------
-// CFBundle constructor
-//----------------------------------------------------------------------
-CFBundle::CFBundle(const char *path)
- : CFReleaser<CFBundleRef>(), m_bundle_url() {
- if (path && path[0])
- SetPath(path);
-}
-
-//----------------------------------------------------------------------
-// CFBundle copy constructor
-//----------------------------------------------------------------------
-CFBundle::CFBundle(const CFBundle &rhs)
- : CFReleaser<CFBundleRef>(rhs), m_bundle_url(rhs.m_bundle_url) {}
-
-//----------------------------------------------------------------------
-// CFBundle copy constructor
-//----------------------------------------------------------------------
-CFBundle &CFBundle::operator=(const CFBundle &rhs) {
- if (this != &rhs)
- *this = rhs;
- return *this;
-}
-
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-CFBundle::~CFBundle() {}
-
-//----------------------------------------------------------------------
-// Set the path for a bundle by supplying a
-//----------------------------------------------------------------------
-bool CFBundle::SetPath(const char *path) {
- CFAllocatorRef alloc = kCFAllocatorDefault;
- // Release our old bundle and ULR
- reset(); // This class is a CFReleaser<CFBundleRef>
- m_bundle_url.reset();
- // Make a CFStringRef from the supplied path
- CFString cf_path;
- cf_path.SetFileSystemRepresentation(path);
- if (cf_path.get()) {
- // Make our Bundle URL
- m_bundle_url.reset(::CFURLCreateWithFileSystemPath(
- alloc, cf_path.get(), kCFURLPOSIXPathStyle, true));
- if (m_bundle_url.get()) {
- reset(::CFBundleCreate(alloc, m_bundle_url.get()));
- }
- }
- return get() != NULL;
-}
-
-CFStringRef CFBundle::GetIdentifier() const {
- CFBundleRef bundle = get();
- if (bundle != NULL)
- return ::CFBundleGetIdentifier(bundle);
- return NULL;
-}
-
-CFURLRef CFBundle::CopyExecutableURL() const {
- CFBundleRef bundle = get();
- if (bundle != NULL)
- return CFBundleCopyExecutableURL(bundle);
- return NULL;
-}
diff --git a/tools/debugserver/source/MacOSX/CFBundle.h b/tools/debugserver/source/MacOSX/CFBundle.h
deleted file mode 100644
index 09957af534b3..000000000000
--- a/tools/debugserver/source/MacOSX/CFBundle.h
+++ /dev/null
@@ -1,38 +0,0 @@
-//===-- CFBundle.h ----------------------------------------------*- 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 1/16/08.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __CFBundle_h__
-#define __CFBundle_h__
-
-#include "CFUtils.h"
-
-class CFBundle : public CFReleaser<CFBundleRef> {
-public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- CFBundle(const char *path = NULL);
- CFBundle(const CFBundle &rhs);
- CFBundle &operator=(const CFBundle &rhs);
- virtual ~CFBundle();
- bool SetPath(const char *path);
-
- CFStringRef GetIdentifier() const;
-
- CFURLRef CopyExecutableURL() const;
-
-protected:
- CFReleaser<CFURLRef> m_bundle_url;
-};
-
-#endif // #ifndef __CFBundle_h__
diff --git a/tools/debugserver/source/MacOSX/CFString.cpp b/tools/debugserver/source/MacOSX/CFString.cpp
deleted file mode 100644
index 84ad56774d7c..000000000000
--- a/tools/debugserver/source/MacOSX/CFString.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-//===-- CFString.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 1/16/08.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CFString.h"
-#include <glob.h>
-#include <string>
-
-//----------------------------------------------------------------------
-// CFString constructor
-//----------------------------------------------------------------------
-CFString::CFString(CFStringRef s) : CFReleaser<CFStringRef>(s) {}
-
-//----------------------------------------------------------------------
-// CFString copy constructor
-//----------------------------------------------------------------------
-CFString::CFString(const CFString &rhs) : CFReleaser<CFStringRef>(rhs) {}
-
-//----------------------------------------------------------------------
-// CFString copy constructor
-//----------------------------------------------------------------------
-CFString &CFString::operator=(const CFString &rhs) {
- if (this != &rhs)
- *this = rhs;
- return *this;
-}
-
-CFString::CFString(const char *cstr, CFStringEncoding cstr_encoding)
- : CFReleaser<CFStringRef>() {
- if (cstr && cstr[0]) {
- reset(
- ::CFStringCreateWithCString(kCFAllocatorDefault, cstr, cstr_encoding));
- }
-}
-
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-CFString::~CFString() {}
-
-const char *CFString::GetFileSystemRepresentation(std::string &s) {
- return CFString::FileSystemRepresentation(get(), s);
-}
-
-CFStringRef CFString::SetFileSystemRepresentation(const char *path) {
- CFStringRef new_value = NULL;
- if (path && path[0])
- new_value =
- ::CFStringCreateWithFileSystemRepresentation(kCFAllocatorDefault, path);
- reset(new_value);
- return get();
-}
-
-CFStringRef CFString::SetFileSystemRepresentationFromCFType(CFTypeRef cf_type) {
- CFStringRef new_value = NULL;
- if (cf_type != NULL) {
- CFTypeID cf_type_id = ::CFGetTypeID(cf_type);
-
- if (cf_type_id == ::CFStringGetTypeID()) {
- // Retain since we are using the existing object
- new_value = (CFStringRef)::CFRetain(cf_type);
- } else if (cf_type_id == ::CFURLGetTypeID()) {
- new_value =
- ::CFURLCopyFileSystemPath((CFURLRef)cf_type, kCFURLPOSIXPathStyle);
- }
- }
- reset(new_value);
- return get();
-}
-
-CFStringRef
-CFString::SetFileSystemRepresentationAndExpandTilde(const char *path) {
- std::string expanded_path;
- if (CFString::GlobPath(path, expanded_path))
- SetFileSystemRepresentation(expanded_path.c_str());
- else
- reset();
- return get();
-}
-
-const char *CFString::UTF8(std::string &str) {
- return CFString::UTF8(get(), str);
-}
-
-// Static function that puts a copy of the UTF8 contents of CF_STR into STR
-// and returns the C string pointer that is contained in STR when successful,
-// else
-// NULL is returned. This allows the std::string parameter to own the extracted
-// string,
-// and also allows that string to be returned as a C string pointer that can be
-// used.
-
-const char *CFString::UTF8(CFStringRef cf_str, std::string &str) {
- if (cf_str) {
- const CFStringEncoding encoding = kCFStringEncodingUTF8;
- CFIndex max_utf8_str_len = CFStringGetLength(cf_str);
- max_utf8_str_len =
- CFStringGetMaximumSizeForEncoding(max_utf8_str_len, encoding);
- if (max_utf8_str_len > 0) {
- str.resize(max_utf8_str_len);
- if (!str.empty()) {
- if (CFStringGetCString(cf_str, &str[0], str.size(), encoding)) {
- str.resize(strlen(str.c_str()));
- return str.c_str();
- }
- }
- }
- }
- return NULL;
-}
-
-// Static function that puts a copy of the file system representation of CF_STR
-// into STR and returns the C string pointer that is contained in STR when
-// successful, else NULL is returned. This allows the std::string parameter
-// to own the extracted string, and also allows that string to be returned as
-// a C string pointer that can be used.
-
-const char *CFString::FileSystemRepresentation(CFStringRef cf_str,
- std::string &str) {
- if (cf_str) {
- CFIndex max_length =
- ::CFStringGetMaximumSizeOfFileSystemRepresentation(cf_str);
- if (max_length > 0) {
- str.resize(max_length);
- if (!str.empty()) {
- if (::CFStringGetFileSystemRepresentation(cf_str, &str[0],
- str.size())) {
- str.erase(::strlen(str.c_str()));
- return str.c_str();
- }
- }
- }
- }
- str.erase();
- return NULL;
-}
-
-CFIndex CFString::GetLength() const {
- CFStringRef str = get();
- if (str)
- return CFStringGetLength(str);
- return 0;
-}
-
-const char *CFString::GlobPath(const char *path, std::string &expanded_path) {
- glob_t globbuf;
- if (::glob(path, GLOB_TILDE, NULL, &globbuf) == 0) {
- expanded_path = globbuf.gl_pathv[0];
- ::globfree(&globbuf);
- } else
- expanded_path.clear();
-
- return expanded_path.c_str();
-}
diff --git a/tools/debugserver/source/MacOSX/CFString.h b/tools/debugserver/source/MacOSX/CFString.h
deleted file mode 100644
index 18d60a5a74bd..000000000000
--- a/tools/debugserver/source/MacOSX/CFString.h
+++ /dev/null
@@ -1,43 +0,0 @@
-//===-- CFString.h ----------------------------------------------*- 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 1/16/08.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __CFString_h__
-#define __CFString_h__
-
-#include "CFUtils.h"
-#include <iosfwd>
-
-class CFString : public CFReleaser<CFStringRef> {
-public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- CFString(CFStringRef cf_str = NULL);
- CFString(const char *s, CFStringEncoding encoding = kCFStringEncodingUTF8);
- CFString(const CFString &rhs);
- CFString &operator=(const CFString &rhs);
- virtual ~CFString();
-
- const char *GetFileSystemRepresentation(std::string &str);
- CFStringRef SetFileSystemRepresentation(const char *path);
- CFStringRef SetFileSystemRepresentationFromCFType(CFTypeRef cf_type);
- CFStringRef SetFileSystemRepresentationAndExpandTilde(const char *path);
- const char *UTF8(std::string &str);
- CFIndex GetLength() const;
- static const char *UTF8(CFStringRef cf_str, std::string &str);
- static const char *FileSystemRepresentation(CFStringRef cf_str,
- std::string &str);
- static const char *GlobPath(const char *path, std::string &expanded_path);
-};
-
-#endif // #ifndef __CFString_h__
diff --git a/tools/debugserver/source/MacOSX/CFUtils.h b/tools/debugserver/source/MacOSX/CFUtils.h
deleted file mode 100644
index a904cd0ea6f0..000000000000
--- a/tools/debugserver/source/MacOSX/CFUtils.h
+++ /dev/null
@@ -1,78 +0,0 @@
-//===-- CFUtils.h -----------------------------------------------*- 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 3/5/07.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __CFUtils_h__
-#define __CFUtils_h__
-
-#include <CoreFoundation/CoreFoundation.h>
-
-#ifdef __cplusplus
-
-//----------------------------------------------------------------------
-// Templatized CF helper class that can own any CF pointer and will
-// call CFRelease() on any valid pointer it owns unless that pointer is
-// explicitly released using the release() member function.
-//----------------------------------------------------------------------
-template <class T> class CFReleaser {
-public:
- // Type names for the avlue
- typedef T element_type;
-
- // Constructors and destructors
- CFReleaser(T ptr = NULL) : _ptr(ptr) {}
- CFReleaser(const CFReleaser &copy) : _ptr(copy.get()) {
- if (get())
- ::CFRetain(get());
- }
- virtual ~CFReleaser() { reset(); }
-
- // Assignments
- CFReleaser &operator=(const CFReleaser<T> &copy) {
- if (copy != *this) {
- // Replace our owned pointer with the new one
- reset(copy.get());
- // Retain the current pointer that we own
- if (get())
- ::CFRetain(get());
- }
- }
- // Get the address of the contained type
- T *ptr_address() { return &_ptr; }
-
- // Access the pointer itself
- const T get() const { return _ptr; }
- T get() { return _ptr; }
-
- // Set a new value for the pointer and CFRelease our old
- // value if we had a valid one.
- void reset(T ptr = NULL) {
- if (ptr != _ptr) {
- if (_ptr != NULL)
- ::CFRelease(_ptr);
- _ptr = ptr;
- }
- }
-
- // Release ownership without calling CFRelease
- T release() {
- T tmp = _ptr;
- _ptr = NULL;
- return tmp;
- }
-
-private:
- element_type _ptr;
-};
-
-#endif // #ifdef __cplusplus
-#endif // #ifndef __CFUtils_h__
diff --git a/tools/debugserver/source/MacOSX/CMakeLists.txt b/tools/debugserver/source/MacOSX/CMakeLists.txt
deleted file mode 100644
index 28877d122d94..000000000000
--- a/tools/debugserver/source/MacOSX/CMakeLists.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-if("${CMAKE_OSX_ARCHITECTURES}" MATCHES ".*arm.*")
- list(APPEND SOURCES arm/DNBArchImpl.cpp arm64/DNBArchImplARM64.cpp)
- include_directories(${CURRENT_SOURCE_DIR}/arm ${CURRENT_SOURCE_DIR}/arm64)
-endif()
-
-if(NOT CMAKE_OSX_ARCHITECTURES OR "${CMAKE_OSX_ARCHITECTURES}" MATCHES ".*86.*")
- list(APPEND SOURCES i386/DNBArchImplI386.cpp x86_64/DNBArchImplX86_64.cpp)
- include_directories(${CURRENT_SOURCE_DIR}/i386 ${CURRENT_SOURCE_DIR}/x86_64)
-endif()
-
-if("${CMAKE_OSX_ARCHITECTURES}" MATCHES ".*ppc.*")
- list(APPEND SOURCES ppc/DNBArchImpl.cpp)
- include_directories(${CURRENT_SOURCE_DIR}/ppc)
-endif()
-
-add_subdirectory(DarwinLog)
-
-include_directories(..)
-
-include_directories(${LLDB_SOURCE_DIR}/tools/debugserver/source)
-add_library(lldbDebugserverArchSupport
- ${SOURCES}
- )
diff --git a/tools/debugserver/source/MacOSX/DarwinLog/ActivityStore.cpp b/tools/debugserver/source/MacOSX/DarwinLog/ActivityStore.cpp
deleted file mode 100644
index 2cb653894db4..000000000000
--- a/tools/debugserver/source/MacOSX/DarwinLog/ActivityStore.cpp
+++ /dev/null
@@ -1,14 +0,0 @@
-//===-- ActivityStore.cpp ---------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ActivityStore.h"
-
-ActivityStore::ActivityStore() {}
-
-ActivityStore::~ActivityStore() {}
diff --git a/tools/debugserver/source/MacOSX/DarwinLog/ActivityStore.h b/tools/debugserver/source/MacOSX/DarwinLog/ActivityStore.h
deleted file mode 100644
index 35e0a85ad514..000000000000
--- a/tools/debugserver/source/MacOSX/DarwinLog/ActivityStore.h
+++ /dev/null
@@ -1,30 +0,0 @@
-//===-- ActivityStore.h -----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef ActivityStore_h
-#define ActivityStore_h
-
-#include <string>
-
-#include "ActivityStreamSPI.h"
-
-class ActivityStore {
-public:
- virtual ~ActivityStore();
-
- virtual const char *GetActivityForID(os_activity_id_t activity_id) const = 0;
-
- virtual std::string
- GetActivityChainForID(os_activity_id_t activity_id) const = 0;
-
-protected:
- ActivityStore();
-};
-
-#endif /* ActivityStore_h */
diff --git a/tools/debugserver/source/MacOSX/DarwinLog/ActivityStreamSPI.h b/tools/debugserver/source/MacOSX/DarwinLog/ActivityStreamSPI.h
deleted file mode 100644
index 8aebc79e6ec8..000000000000
--- a/tools/debugserver/source/MacOSX/DarwinLog/ActivityStreamSPI.h
+++ /dev/null
@@ -1,191 +0,0 @@
-//===-- ActivityStreamAPI.h -------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef ActivityStreamSPI_h
-#define ActivityStreamSPI_h
-
-#include <sys/time.h>
-#include <xpc/xpc.h>
-
-#define OS_ACTIVITY_MAX_CALLSTACK 32
-
-// Enums
-
-enum {
- OS_ACTIVITY_STREAM_PROCESS_ONLY = 0x00000001,
- OS_ACTIVITY_STREAM_SKIP_DECODE = 0x00000002,
- OS_ACTIVITY_STREAM_PAYLOAD = 0x00000004,
- OS_ACTIVITY_STREAM_HISTORICAL = 0x00000008,
- OS_ACTIVITY_STREAM_CALLSTACK = 0x00000010,
- OS_ACTIVITY_STREAM_DEBUG = 0x00000020,
- OS_ACTIVITY_STREAM_BUFFERED = 0x00000040,
- OS_ACTIVITY_STREAM_NO_SENSITIVE = 0x00000080,
- OS_ACTIVITY_STREAM_INFO = 0x00000100,
- OS_ACTIVITY_STREAM_PROMISCUOUS = 0x00000200,
- OS_ACTIVITY_STREAM_PRECISE_TIMESTAMPS = 0x00000200
-};
-typedef uint32_t os_activity_stream_flag_t;
-
-enum {
- OS_ACTIVITY_STREAM_TYPE_ACTIVITY_CREATE = 0x0201,
- OS_ACTIVITY_STREAM_TYPE_ACTIVITY_TRANSITION = 0x0202,
- OS_ACTIVITY_STREAM_TYPE_ACTIVITY_USERACTION = 0x0203,
-
- OS_ACTIVITY_STREAM_TYPE_TRACE_MESSAGE = 0x0300,
-
- OS_ACTIVITY_STREAM_TYPE_LOG_MESSAGE = 0x0400,
- OS_ACTIVITY_STREAM_TYPE_LEGACY_LOG_MESSAGE = 0x0480,
-
- OS_ACTIVITY_STREAM_TYPE_SIGNPOST_BEGIN = 0x0601,
- OS_ACTIVITY_STREAM_TYPE_SIGNPOST_END = 0x0602,
- OS_ACTIVITY_STREAM_TYPE_SIGNPOST_EVENT = 0x0603,
-
- OS_ACTIVITY_STREAM_TYPE_STATEDUMP_EVENT = 0x0A00,
-};
-typedef uint32_t os_activity_stream_type_t;
-
-enum {
- OS_ACTIVITY_STREAM_EVENT_STARTED = 1,
- OS_ACTIVITY_STREAM_EVENT_STOPPED = 2,
- OS_ACTIVITY_STREAM_EVENT_FAILED = 3,
- OS_ACTIVITY_STREAM_EVENT_CHUNK_STARTED = 4,
- OS_ACTIVITY_STREAM_EVENT_CHUNK_FINISHED = 5,
-};
-typedef uint32_t os_activity_stream_event_t;
-
-// Types
-
-typedef uint64_t os_activity_id_t;
-typedef struct os_activity_stream_s *os_activity_stream_t;
-typedef struct os_activity_stream_entry_s *os_activity_stream_entry_t;
-
-#define OS_ACTIVITY_STREAM_COMMON() \
- uint64_t trace_id; \
- uint64_t timestamp; \
- uint64_t thread; \
- const uint8_t *image_uuid; \
- const char *image_path; \
- struct timeval tv_gmt; \
- struct timezone tz; \
- uint32_t offset
-
-typedef struct os_activity_stream_common_s {
- OS_ACTIVITY_STREAM_COMMON();
-} * os_activity_stream_common_t;
-
-struct os_activity_create_s {
- OS_ACTIVITY_STREAM_COMMON();
- const char *name;
- os_activity_id_t creator_aid;
- uint64_t unique_pid;
-};
-
-struct os_activity_transition_s {
- OS_ACTIVITY_STREAM_COMMON();
- os_activity_id_t transition_id;
-};
-
-typedef struct os_log_message_s {
- OS_ACTIVITY_STREAM_COMMON();
- const char *format;
- const uint8_t *buffer;
- size_t buffer_sz;
- const uint8_t *privdata;
- size_t privdata_sz;
- const char *subsystem;
- const char *category;
- uint32_t oversize_id;
- uint8_t ttl;
- bool persisted;
-} * os_log_message_t;
-
-typedef struct os_trace_message_v2_s {
- OS_ACTIVITY_STREAM_COMMON();
- const char *format;
- const void *buffer;
- size_t bufferLen;
- xpc_object_t __unsafe_unretained payload;
-} * os_trace_message_v2_t;
-
-typedef struct os_activity_useraction_s {
- OS_ACTIVITY_STREAM_COMMON();
- const char *action;
- bool persisted;
-} * os_activity_useraction_t;
-
-typedef struct os_signpost_s {
- OS_ACTIVITY_STREAM_COMMON();
- const char *format;
- const uint8_t *buffer;
- size_t buffer_sz;
- const uint8_t *privdata;
- size_t privdata_sz;
- const char *subsystem;
- const char *category;
- uint64_t duration_nsec;
- uint32_t callstack_depth;
- uint64_t callstack[OS_ACTIVITY_MAX_CALLSTACK];
-} * os_signpost_t;
-
-typedef struct os_activity_statedump_s {
- OS_ACTIVITY_STREAM_COMMON();
- char *message;
- size_t message_size;
- char image_path_buffer[PATH_MAX];
-} * os_activity_statedump_t;
-
-struct os_activity_stream_entry_s {
- os_activity_stream_type_t type;
-
- // information about the process streaming the data
- pid_t pid;
- uint64_t proc_id;
- const uint8_t *proc_imageuuid;
- const char *proc_imagepath;
-
- // the activity associated with this streamed event
- os_activity_id_t activity_id;
- os_activity_id_t parent_id;
-
- union {
- struct os_activity_stream_common_s common;
- struct os_activity_create_s activity_create;
- struct os_activity_transition_s activity_transition;
- struct os_log_message_s log_message;
- struct os_trace_message_v2_s trace_message;
- struct os_activity_useraction_s useraction;
- struct os_signpost_s signpost;
- struct os_activity_statedump_s statedump;
- };
-};
-
-// Blocks
-
-typedef bool (^os_activity_stream_block_t)(os_activity_stream_entry_t entry,
- int error);
-
-typedef void (^os_activity_stream_event_block_t)(
- os_activity_stream_t stream, os_activity_stream_event_t event);
-
-// SPI entry point prototypes
-
-typedef os_activity_stream_t (*os_activity_stream_for_pid_t)(
- pid_t pid, os_activity_stream_flag_t flags,
- os_activity_stream_block_t stream_block);
-
-typedef void (*os_activity_stream_resume_t)(os_activity_stream_t stream);
-
-typedef void (*os_activity_stream_cancel_t)(os_activity_stream_t stream);
-
-typedef char *(*os_log_copy_formatted_message_t)(os_log_message_t log_message);
-
-typedef void (*os_activity_stream_set_event_handler_t)(
- os_activity_stream_t stream, os_activity_stream_event_block_t block);
-
-#endif /* ActivityStreamSPI_h */
diff --git a/tools/debugserver/source/MacOSX/DarwinLog/CMakeLists.txt b/tools/debugserver/source/MacOSX/DarwinLog/CMakeLists.txt
deleted file mode 100644
index dffa357f1e68..000000000000
--- a/tools/debugserver/source/MacOSX/DarwinLog/CMakeLists.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-# Due to sources including headers like:
-# #include "MacOSX/i386/DNBArchImplI386.h"
-# we must include the grandparent directory...
-include_directories(${LLDB_SOURCE_DIR}/tools/debugserver/source)
-
-add_library(lldbDebugserverDarwin_DarwinLog
- ActivityStore.cpp
- DarwinLogCollector.cpp
- LogFilter.cpp
- LogFilterChain.cpp
- LogFilterExactMatch.cpp
- LogFilterRegex.cpp
- LogMessage.cpp
- LogMessageOsLog.cpp
- )
diff --git a/tools/debugserver/source/MacOSX/DarwinLog/DarwinLogCollector.cpp b/tools/debugserver/source/MacOSX/DarwinLog/DarwinLogCollector.cpp
deleted file mode 100644
index 1e833c4cb165..000000000000
--- a/tools/debugserver/source/MacOSX/DarwinLog/DarwinLogCollector.cpp
+++ /dev/null
@@ -1,698 +0,0 @@
-//===-- DarwinLogCollector.cpp ----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "DarwinLogCollector.h"
-#include "ActivityStreamSPI.h"
-
-#include <dlfcn.h>
-
-#include <cinttypes>
-#include <mutex>
-#include <vector>
-
-#include "DNB.h"
-#include "DNBLog.h"
-#include "DarwinLogTypes.h"
-#include "LogFilterChain.h"
-#include "LogFilterExactMatch.h"
-#include "LogFilterRegex.h"
-#include "LogMessageOsLog.h"
-#include "MachProcess.h"
-#include "RNBContext.h"
-#include "RNBDefs.h"
-#include "RNBRemote.h"
-
-// Use an anonymous namespace for variables and methods that have no
-// reason to leak out through the interface.
-namespace {
-/// Specify max depth that the activity parent-child chain will search
-/// back to get the full activity chain name. If we do more than this,
-/// we assume either we hit a loop or it's just too long.
-static const size_t MAX_ACTIVITY_CHAIN_DEPTH = 10;
-
-// Used to tap into and retrieve logs from target process.
-// (Consumer of os_log).
-static os_activity_stream_for_pid_t s_os_activity_stream_for_pid;
-static os_activity_stream_resume_t s_os_activity_stream_resume;
-static os_activity_stream_cancel_t s_os_activity_stream_cancel;
-static os_log_copy_formatted_message_t s_os_log_copy_formatted_message;
-static os_activity_stream_set_event_handler_t
- s_os_activity_stream_set_event_handler;
-
-bool LookupSPICalls() {
- static std::once_flag s_once_flag;
- static bool s_has_spi;
-
- std::call_once(s_once_flag, [] {
- dlopen ("/System/Library/PrivateFrameworks/LoggingSupport.framework/LoggingSupport", RTLD_NOW);
- s_os_activity_stream_for_pid = (os_activity_stream_for_pid_t)dlsym(
- RTLD_DEFAULT, "os_activity_stream_for_pid");
- s_os_activity_stream_resume = (os_activity_stream_resume_t)dlsym(
- RTLD_DEFAULT, "os_activity_stream_resume");
- s_os_activity_stream_cancel = (os_activity_stream_cancel_t)dlsym(
- RTLD_DEFAULT, "os_activity_stream_cancel");
- s_os_log_copy_formatted_message = (os_log_copy_formatted_message_t)dlsym(
- RTLD_DEFAULT, "os_log_copy_formatted_message");
- s_os_activity_stream_set_event_handler =
- (os_activity_stream_set_event_handler_t)dlsym(
- RTLD_DEFAULT, "os_activity_stream_set_event_handler");
-
- // We'll indicate we're all set if every function entry point
- // was found.
- s_has_spi = (s_os_activity_stream_for_pid != nullptr) &&
- (s_os_activity_stream_resume != nullptr) &&
- (s_os_activity_stream_cancel != nullptr) &&
- (s_os_log_copy_formatted_message != nullptr) &&
- (s_os_activity_stream_set_event_handler != nullptr);
- if (s_has_spi) {
- DNBLogThreadedIf(LOG_DARWIN_LOG, "Found os_log SPI calls.");
- // Tell LogMessageOsLog how to format messages when search
- // criteria requires it.
- LogMessageOsLog::SetFormatterFunction(s_os_log_copy_formatted_message);
- } else {
- DNBLogThreadedIf(LOG_DARWIN_LOG, "Failed to find os_log SPI "
- "calls.");
- }
- });
-
- return s_has_spi;
-}
-
-using Mutex = std::mutex;
-static Mutex s_collector_mutex;
-static std::vector<DarwinLogCollectorSP> s_collectors;
-
-static void TrackCollector(const DarwinLogCollectorSP &collector_sp) {
- std::lock_guard<Mutex> locker(s_collector_mutex);
- if (std::find(s_collectors.begin(), s_collectors.end(), collector_sp) !=
- s_collectors.end()) {
- DNBLogThreadedIf(LOG_DARWIN_LOG,
- "attempted to add same collector multiple times");
- return;
- }
- s_collectors.push_back(collector_sp);
-}
-
-static void StopTrackingCollector(const DarwinLogCollectorSP &collector_sp) {
- std::lock_guard<Mutex> locker(s_collector_mutex);
- s_collectors.erase(
- std::remove(s_collectors.begin(), s_collectors.end(), collector_sp),
- s_collectors.end());
-}
-
-static DarwinLogCollectorSP FindCollectorForProcess(pid_t pid) {
- std::lock_guard<Mutex> locker(s_collector_mutex);
- for (const auto &collector_sp : s_collectors) {
- if (collector_sp && (collector_sp->GetProcessID() == pid))
- return collector_sp;
- }
- return DarwinLogCollectorSP();
-}
-
-static FilterTarget TargetStringToEnum(const std::string &filter_target_name) {
- if (filter_target_name == "activity")
- return eFilterTargetActivity;
- else if (filter_target_name == "activity-chain")
- return eFilterTargetActivityChain;
- else if (filter_target_name == "category")
- return eFilterTargetCategory;
- else if (filter_target_name == "message")
- return eFilterTargetMessage;
- else if (filter_target_name == "subsystem")
- return eFilterTargetSubsystem;
- else
- return eFilterTargetInvalid;
-}
-
-class Configuration {
-public:
- Configuration(const JSONObject &config)
- : m_is_valid(false),
- m_activity_stream_flags(OS_ACTIVITY_STREAM_PROCESS_ONLY),
- m_filter_chain_sp(nullptr) {
- // Parse out activity stream flags
- if (!ParseSourceFlags(config)) {
- m_is_valid = false;
- return;
- }
-
- // Parse filter rules
- if (!ParseFilterRules(config)) {
- m_is_valid = false;
- return;
- }
-
- // Everything worked.
- m_is_valid = true;
- }
-
- bool ParseSourceFlags(const JSONObject &config) {
- // Get the source-flags dictionary.
- auto source_flags_sp = config.GetObject("source-flags");
- if (!source_flags_sp)
- return false;
- if (!JSONObject::classof(source_flags_sp.get()))
- return false;
-
- const JSONObject &source_flags =
- *static_cast<JSONObject *>(source_flags_sp.get());
-
- // Parse out the flags.
- bool include_any_process = false;
- bool include_callstacks = false;
- bool include_info_level = false;
- bool include_debug_level = false;
- bool live_stream = false;
-
- if (!source_flags.GetObjectAsBool("any-process", include_any_process)) {
- DNBLogThreadedIf(LOG_DARWIN_LOG, "Source-flag 'any-process' missing from "
- "configuration.");
- return false;
- }
- if (!source_flags.GetObjectAsBool("callstacks", include_callstacks)) {
- // We currently suppress the availability of this on the lldb
- // side. We include here for devices when we enable in the
- // future.
- // DNBLogThreadedIf(LOG_DARWIN_LOG,
- // "Source-flag 'callstacks' missing from "
- // "configuration.");
-
- // OK. We just skip callstacks.
- // return false;
- }
- if (!source_flags.GetObjectAsBool("info-level", include_info_level)) {
- DNBLogThreadedIf(LOG_DARWIN_LOG, "Source-flag 'info-level' missing from "
- "configuration.");
- return false;
- }
- if (!source_flags.GetObjectAsBool("debug-level", include_debug_level)) {
- DNBLogThreadedIf(LOG_DARWIN_LOG, "Source-flag 'debug-level' missing from "
- "configuration.");
- return false;
- }
- if (!source_flags.GetObjectAsBool("live-stream", live_stream)) {
- DNBLogThreadedIf(LOG_DARWIN_LOG, "Source-flag 'live-stream' missing from "
- "configuration.");
- return false;
- }
-
- // Setup the SPI flags based on this.
- m_activity_stream_flags = 0;
- if (!include_any_process)
- m_activity_stream_flags |= OS_ACTIVITY_STREAM_PROCESS_ONLY;
- if (include_callstacks)
- m_activity_stream_flags |= OS_ACTIVITY_STREAM_CALLSTACK;
- if (include_info_level)
- m_activity_stream_flags |= OS_ACTIVITY_STREAM_INFO;
- if (include_debug_level)
- m_activity_stream_flags |= OS_ACTIVITY_STREAM_DEBUG;
- if (!live_stream)
- m_activity_stream_flags |= OS_ACTIVITY_STREAM_BUFFERED;
-
- DNBLogThreadedIf(LOG_DARWIN_LOG, "m_activity_stream_flags = 0x%03x",
- m_activity_stream_flags);
-
- return true;
- }
-
- bool ParseFilterRules(const JSONObject &config) {
- // Retrieve the default rule.
- bool filter_default_accept = true;
- if (!config.GetObjectAsBool("filter-fall-through-accepts",
- filter_default_accept)) {
- DNBLogThreadedIf(LOG_DARWIN_LOG, "Setting 'filter-fall-through-accepts' "
- "missing from configuration.");
- return false;
- }
- m_filter_chain_sp.reset(new LogFilterChain(filter_default_accept));
- DNBLogThreadedIf(LOG_DARWIN_LOG, "DarwinLog no-match rule: %s.",
- filter_default_accept ? "accept" : "reject");
-
- // If we don't have the filter-rules array, we're done.
- auto filter_rules_sp = config.GetObject("filter-rules");
- if (!filter_rules_sp) {
- DNBLogThreadedIf(LOG_DARWIN_LOG,
- "No 'filter-rules' config element, all log "
- "entries will use the no-match action (%s).",
- filter_default_accept ? "accept" : "reject");
- return true;
- }
- if (!JSONArray::classof(filter_rules_sp.get()))
- return false;
- const JSONArray &rules_config =
- *static_cast<JSONArray *>(filter_rules_sp.get());
-
- // Create the filters.
- for (auto &rule_sp : rules_config.m_elements) {
- if (!JSONObject::classof(rule_sp.get()))
- return false;
- const JSONObject &rule_config = *static_cast<JSONObject *>(rule_sp.get());
-
- // Get whether this filter accepts or rejects.
- bool filter_accepts = true;
- if (!rule_config.GetObjectAsBool("accept", filter_accepts)) {
- DNBLogThreadedIf(LOG_DARWIN_LOG, "Filter 'accept' element missing.");
- return false;
- }
-
- // Grab the target log field attribute for the match.
- std::string target_attribute;
- if (!rule_config.GetObjectAsString("attribute", target_attribute)) {
- DNBLogThreadedIf(LOG_DARWIN_LOG, "Filter 'attribute' element missing.");
- return false;
- }
- auto target_enum = TargetStringToEnum(target_attribute);
- if (target_enum == eFilterTargetInvalid) {
- DNBLogThreadedIf(LOG_DARWIN_LOG, "Filter attribute '%s' unsupported.",
- target_attribute.c_str());
- return false;
- }
-
- // Handle operation-specific fields and filter creation.
- std::string filter_type;
- if (!rule_config.GetObjectAsString("type", filter_type)) {
- DNBLogThreadedIf(LOG_DARWIN_LOG, "Filter 'type' element missing.");
- return false;
- }
- DNBLogThreadedIf(LOG_DARWIN_LOG, "Reading filter of type '%s'",
- filter_type.c_str());
-
- LogFilterSP filter_sp;
- if (filter_type == "regex") {
- // Grab the regex for the match.
- std::string regex;
- if (!rule_config.GetObjectAsString("regex", regex)) {
- DNBLogError("Regex filter missing 'regex' element.");
- return false;
- }
- DNBLogThreadedIf(LOG_DARWIN_LOG, "regex for filter: \"%s\"",
- regex.c_str());
-
- // Create the regex filter.
- auto regex_filter =
- new LogFilterRegex(filter_accepts, target_enum, regex);
- filter_sp.reset(regex_filter);
-
- // Validate that the filter is okay.
- if (!regex_filter->IsValid()) {
- DNBLogError("Invalid regex in filter: "
- "regex=\"%s\", error=%s",
- regex.c_str(), regex_filter->GetErrorAsCString());
- return false;
- }
- } else if (filter_type == "match") {
- // Grab the regex for the match.
- std::string exact_text;
- if (!rule_config.GetObjectAsString("exact_text", exact_text)) {
- DNBLogError("Exact match filter missing "
- "'exact_text' element.");
- return false;
- }
-
- // Create the filter.
- filter_sp.reset(
- new LogFilterExactMatch(filter_accepts, target_enum, exact_text));
- }
-
- // Add the filter to the chain.
- m_filter_chain_sp->AppendFilter(filter_sp);
- }
- return true;
- }
-
- bool IsValid() const { return m_is_valid; }
-
- os_activity_stream_flag_t GetActivityStreamFlags() const {
- return m_activity_stream_flags;
- }
-
- const LogFilterChainSP &GetLogFilterChain() const {
- return m_filter_chain_sp;
- }
-
-private:
- bool m_is_valid;
- os_activity_stream_flag_t m_activity_stream_flags;
- LogFilterChainSP m_filter_chain_sp;
-};
-}
-
-bool DarwinLogCollector::IsSupported() {
- // We're supported if we have successfully looked up the SPI entry points.
- return LookupSPICalls();
-}
-
-bool DarwinLogCollector::StartCollectingForProcess(nub_process_t pid,
- const JSONObject &config) {
- // If we're currently collecting for this process, kill the existing
- // collector.
- if (CancelStreamForProcess(pid)) {
- DNBLogThreadedIf(LOG_DARWIN_LOG,
- "%s() killed existing DarwinLog collector for pid %d.",
- __FUNCTION__, pid);
- }
-
- // If the process isn't alive, we're done.
- if (!DNBProcessIsAlive(pid)) {
- DNBLogThreadedIf(LOG_DARWIN_LOG,
- "%s() cannot collect for pid %d: process not alive.",
- __FUNCTION__, pid);
- return false;
- }
-
- // Validate the configuration.
- auto spi_config = Configuration(config);
- if (!spi_config.IsValid()) {
- DNBLogThreadedIf(LOG_DARWIN_LOG,
- "%s() invalid configuration, will not enable log "
- "collection",
- __FUNCTION__);
- return false;
- }
-
- // Create the stream collector that will manage collected data
- // for this pid.
- DarwinLogCollectorSP collector_sp(
- new DarwinLogCollector(pid, spi_config.GetLogFilterChain()));
- std::weak_ptr<DarwinLogCollector> collector_wp(collector_sp);
-
- // Setup the stream handling block.
- os_activity_stream_block_t block =
- ^bool(os_activity_stream_entry_t entry, int error) {
- // Check if our collector is still alive.
- DarwinLogCollectorSP inner_collector_sp = collector_wp.lock();
- if (!inner_collector_sp)
- return false;
- return inner_collector_sp->HandleStreamEntry(entry, error);
- };
-
- os_activity_stream_event_block_t stream_event_block = ^void(
- os_activity_stream_t stream, os_activity_stream_event_t event) {
- switch (event) {
- case OS_ACTIVITY_STREAM_EVENT_STARTED:
- DNBLogThreadedIf(LOG_DARWIN_LOG,
- "received stream event: "
- "OS_ACTIVITY_STREAM_EVENT_STARTED, stream %p.",
- (void *)stream);
- break;
- case OS_ACTIVITY_STREAM_EVENT_STOPPED:
- DNBLogThreadedIf(LOG_DARWIN_LOG,
- "received stream event: "
- "OS_ACTIVITY_STREAM_EVENT_STOPPED, stream %p.",
- (void *)stream);
- break;
- case OS_ACTIVITY_STREAM_EVENT_FAILED:
- DNBLogThreadedIf(LOG_DARWIN_LOG,
- "received stream event: "
- "OS_ACTIVITY_STREAM_EVENT_FAILED, stream %p.",
- (void *)stream);
- break;
- case OS_ACTIVITY_STREAM_EVENT_CHUNK_STARTED:
- DNBLogThreadedIf(LOG_DARWIN_LOG,
- "received stream event: "
- "OS_ACTIVITY_STREAM_EVENT_CHUNK_STARTED, stream %p.",
- (void *)stream);
- break;
- case OS_ACTIVITY_STREAM_EVENT_CHUNK_FINISHED:
- DNBLogThreadedIf(LOG_DARWIN_LOG,
- "received stream event: "
- "OS_ACTIVITY_STREAM_EVENT_CHUNK_FINISHED, stream %p.",
- (void *)stream);
- break;
- }
- };
-
- // Create the stream.
- os_activity_stream_t activity_stream = (*s_os_activity_stream_for_pid)(
- pid, spi_config.GetActivityStreamFlags(), block);
- collector_sp->SetActivityStream(activity_stream);
-
- // Specify the stream-related event handler.
- (*s_os_activity_stream_set_event_handler)(activity_stream,
- stream_event_block);
-
- // Start the stream.
- (*s_os_activity_stream_resume)(activity_stream);
-
- TrackCollector(collector_sp);
- return true;
-}
-
-DarwinLogEventVector
-DarwinLogCollector::GetEventsForProcess(nub_process_t pid) {
- auto collector_sp = FindCollectorForProcess(pid);
- if (!collector_sp) {
- // We're not tracking a stream for this process.
- return DarwinLogEventVector();
- }
-
- return collector_sp->RemoveEvents();
-}
-
-bool DarwinLogCollector::CancelStreamForProcess(nub_process_t pid) {
- auto collector_sp = FindCollectorForProcess(pid);
- if (!collector_sp) {
- // We're not tracking a stream for this process.
- return false;
- }
-
- collector_sp->CancelActivityStream();
- StopTrackingCollector(collector_sp);
-
- return true;
-}
-
-const char *
-DarwinLogCollector::GetActivityForID(os_activity_id_t activity_id) const {
- auto find_it = m_activity_map.find(activity_id);
- return (find_it != m_activity_map.end()) ? find_it->second.m_name.c_str()
- : nullptr;
-}
-
-/// Retrieve the full parent-child chain for activity names. These
-/// can be arbitrarily deep. This method assumes the caller has already
-/// locked the activity mutex.
-void DarwinLogCollector::GetActivityChainForID_internal(
- os_activity_id_t activity_id, std::string &result, size_t depth) const {
- if (depth > MAX_ACTIVITY_CHAIN_DEPTH) {
- // Terminating condition - too deeply nested.
- return;
- } else if (activity_id == 0) {
- // Terminating condition - no activity.
- return;
- }
-
- auto find_it = m_activity_map.find(activity_id);
- if (find_it == m_activity_map.end()) {
- // Terminating condition - no data for activity_id.
- return;
- }
-
- // Activity name becomes parent activity name chain + ':' + our activity
- // name.
- GetActivityChainForID_internal(find_it->second.m_parent_id, result,
- depth + 1);
- if (!result.empty())
- result += ':';
- result += find_it->second.m_name;
-}
-
-std::string
-DarwinLogCollector::GetActivityChainForID(os_activity_id_t activity_id) const {
- std::string result;
- {
- std::lock_guard<std::mutex> locker(m_activity_info_mutex);
- GetActivityChainForID_internal(activity_id, result, 1);
- }
- return result;
-}
-
-DarwinLogCollector::DarwinLogCollector(nub_process_t pid,
- const LogFilterChainSP &filter_chain_sp)
- : ActivityStore(), m_pid(pid), m_activity_stream(0), m_events(),
- m_events_mutex(), m_filter_chain_sp(filter_chain_sp),
- m_activity_info_mutex(), m_activity_map() {}
-
-DarwinLogCollector::~DarwinLogCollector() {
- // Cancel the stream.
- if (m_activity_stream) {
- DNBLogThreadedIf(LOG_DARWIN_LOG, "tearing down activity stream "
- "collector for %d",
- m_pid);
- (*s_os_activity_stream_cancel)(m_activity_stream);
- m_activity_stream = 0;
- } else {
- DNBLogThreadedIf(LOG_DARWIN_LOG, "no stream to tear down for %d", m_pid);
- }
-}
-
-void DarwinLogCollector::SignalDataAvailable() {
- RNBRemoteSP remoteSP(g_remoteSP);
- if (!remoteSP) {
- // We're done. This is unexpected.
- StopTrackingCollector(shared_from_this());
- return;
- }
-
- RNBContext &ctx = remoteSP->Context();
- ctx.Events().SetEvents(RNBContext::event_darwin_log_data_available);
- // Wait for the main thread to consume this notification if it requested
- // we wait for it.
- ctx.Events().WaitForResetAck(RNBContext::event_darwin_log_data_available);
-}
-
-void DarwinLogCollector::SetActivityStream(
- os_activity_stream_t activity_stream) {
- m_activity_stream = activity_stream;
-}
-
-bool DarwinLogCollector::HandleStreamEntry(os_activity_stream_entry_t entry,
- int error) {
- if ((error == 0) && (entry != nullptr)) {
- if (entry->pid != m_pid) {
- // For now, skip messages not originating from our process.
- // Later we might want to keep all messages related to an event
- // that we're tracking, even when it came from another process,
- // possibly doing work on our behalf.
- return true;
- }
-
- switch (entry->type) {
- case OS_ACTIVITY_STREAM_TYPE_ACTIVITY_CREATE:
- DNBLogThreadedIf(
- LOG_DARWIN_LOG, "received activity create: "
- "%s, creator aid %" PRIu64 ", unique_pid %" PRIu64
- "(activity id=%" PRIu64 ", parent id=%" PRIu64 ")",
- entry->activity_create.name, entry->activity_create.creator_aid,
- entry->activity_create.unique_pid, entry->activity_id,
- entry->parent_id);
- {
- std::lock_guard<std::mutex> locker(m_activity_info_mutex);
- m_activity_map.insert(
- std::make_pair(entry->activity_id,
- ActivityInfo(entry->activity_create.name,
- entry->activity_id, entry->parent_id)));
- }
- break;
-
- case OS_ACTIVITY_STREAM_TYPE_ACTIVITY_TRANSITION:
- DNBLogThreadedIf(
- LOG_DARWIN_LOG, "received activity transition:"
- "new aid: %" PRIu64 "(activity id=%" PRIu64
- ", parent id=%" PRIu64 ", tid %" PRIu64 ")",
- entry->activity_transition.transition_id, entry->activity_id,
- entry->parent_id, entry->activity_transition.thread);
- break;
-
- case OS_ACTIVITY_STREAM_TYPE_LOG_MESSAGE: {
- DNBLogThreadedIf(
- LOG_DARWIN_LOG, "received log message: "
- "(activity id=%" PRIu64 ", parent id=%" PRIu64 ", "
- "tid %" PRIu64 "): format %s",
- entry->activity_id, entry->parent_id, entry->log_message.thread,
- entry->log_message.format ? entry->log_message.format
- : "<invalid-format>");
-
- // Do the real work here.
- {
- // Ensure our process is still alive. If not, we can
- // cancel the collection.
- if (!DNBProcessIsAlive(m_pid)) {
- // We're outta here. This is the manner in which we
- // stop collecting for a process.
- StopTrackingCollector(shared_from_this());
- return false;
- }
-
- LogMessageOsLog os_log_message(*this, *entry);
- if (!m_filter_chain_sp ||
- !m_filter_chain_sp->GetAcceptMessage(os_log_message)) {
- // This log message was rejected by the filter,
- // so stop processing it now.
- return true;
- }
-
- // Copy over the relevant bits from the message.
- const struct os_log_message_s &log_message = entry->log_message;
-
- DarwinLogEventSP message_sp(new DarwinLogEvent());
- // Indicate this event is a log message event.
- message_sp->AddStringItem("type", "log");
-
- // Add the message contents (fully expanded).
- // Consider expanding on the remote side.
- // Then we don't pay for expansion until when it is
- // used.
- const char *message_text = os_log_message.GetMessage();
- if (message_text)
- message_sp->AddStringItem("message", message_text);
-
- // Add some useful data fields.
- message_sp->AddIntegerItem("timestamp", log_message.timestamp);
-
- // Do we want to do all activity name resolution on this
- // side? Maybe. For now, send IDs and ID->name mappings
- // and fix this up on that side. Later, when we add
- // debugserver-side filtering, we'll want to get the
- // activity names over here, so we should probably
- // just send them as resolved strings.
- message_sp->AddIntegerItem("activity_id", entry->activity_id);
- message_sp->AddIntegerItem("parent_id", entry->parent_id);
- message_sp->AddIntegerItem("thread_id", log_message.thread);
- if (log_message.subsystem && strlen(log_message.subsystem) > 0)
- message_sp->AddStringItem("subsystem", log_message.subsystem);
- if (log_message.category && strlen(log_message.category) > 0)
- message_sp->AddStringItem("category", log_message.category);
- if (entry->activity_id != 0) {
- std::string activity_chain =
- GetActivityChainForID(entry->activity_id);
- if (!activity_chain.empty())
- message_sp->AddStringItem("activity-chain", activity_chain);
- }
-
- // Add it to the list for later collection.
- {
- std::lock_guard<std::mutex> locker(m_events_mutex);
- m_events.push_back(message_sp);
- }
- SignalDataAvailable();
- }
- break;
- }
- }
- } else {
- DNBLogThreadedIf(LOG_DARWIN_LOG, "HandleStreamEntry: final call, "
- "error %d",
- error);
- }
- return true;
-}
-
-DarwinLogEventVector DarwinLogCollector::RemoveEvents() {
- DarwinLogEventVector returned_events;
- {
- std::lock_guard<std::mutex> locker(m_events_mutex);
- returned_events.swap(m_events);
- }
- DNBLogThreadedIf(LOG_DARWIN_LOG, "DarwinLogCollector::%s(): removing %lu "
- "queued log entries",
- __FUNCTION__, returned_events.size());
- return returned_events;
-}
-
-void DarwinLogCollector::CancelActivityStream() {
- if (!m_activity_stream)
- return;
-
- DNBLogThreadedIf(LOG_DARWIN_LOG, "DarwinLogCollector::%s(): canceling "
- "activity stream %p",
- __FUNCTION__, reinterpret_cast<void *>(m_activity_stream));
- (*s_os_activity_stream_cancel)(m_activity_stream);
- m_activity_stream = nullptr;
-}
diff --git a/tools/debugserver/source/MacOSX/DarwinLog/DarwinLogCollector.h b/tools/debugserver/source/MacOSX/DarwinLog/DarwinLogCollector.h
deleted file mode 100644
index a7d4e8a774c2..000000000000
--- a/tools/debugserver/source/MacOSX/DarwinLog/DarwinLogCollector.h
+++ /dev/null
@@ -1,114 +0,0 @@
-//===-- DarwinLogCollector.h ------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef DarwinLogCollector_h
-#define DarwinLogCollector_h
-
-#include <sys/types.h>
-
-#include <memory>
-#include <mutex>
-#include <unordered_map>
-
-#include "ActivityStore.h"
-#include "ActivityStreamSPI.h"
-#include "DNBDefs.h"
-#include "DarwinLogEvent.h"
-#include "DarwinLogInterfaces.h"
-#include "JSON.h"
-
-class DarwinLogCollector;
-typedef std::shared_ptr<DarwinLogCollector> DarwinLogCollectorSP;
-
-class DarwinLogCollector
- : public std::enable_shared_from_this<DarwinLogCollector>,
- public ActivityStore {
-public:
- //------------------------------------------------------------------
- /// Return whether the os_log and activity tracing SPI is available.
- ///
- /// @return \b true if the activity stream support is available,
- /// \b false otherwise.
- //------------------------------------------------------------------
- static bool IsSupported();
-
- //------------------------------------------------------------------
- /// Return a log function suitable for DNBLog to use as the internal
- /// logging function.
- ///
- /// @return a DNBLog-style logging function if IsSupported() returns
- /// true; otherwise, returns nullptr.
- //------------------------------------------------------------------
- static DNBCallbackLog GetLogFunction();
-
- static bool StartCollectingForProcess(nub_process_t pid,
- const JSONObject &config);
-
- static bool CancelStreamForProcess(nub_process_t pid);
-
- static DarwinLogEventVector GetEventsForProcess(nub_process_t pid);
-
- ~DarwinLogCollector();
-
- pid_t GetProcessID() const { return m_pid; }
-
- //------------------------------------------------------------------
- // ActivityStore API
- //------------------------------------------------------------------
- const char *GetActivityForID(os_activity_id_t activity_id) const override;
-
- std::string
- GetActivityChainForID(os_activity_id_t activity_id) const override;
-
-private:
- DarwinLogCollector() = delete;
- DarwinLogCollector(const DarwinLogCollector &) = delete;
- DarwinLogCollector &operator=(const DarwinLogCollector &) = delete;
-
- explicit DarwinLogCollector(nub_process_t pid,
- const LogFilterChainSP &filter_chain_sp);
-
- void SignalDataAvailable();
-
- void SetActivityStream(os_activity_stream_t activity_stream);
-
- bool HandleStreamEntry(os_activity_stream_entry_t entry, int error);
-
- DarwinLogEventVector RemoveEvents();
-
- void CancelActivityStream();
-
- void GetActivityChainForID_internal(os_activity_id_t activity_id,
- std::string &result, size_t depth) const;
-
- struct ActivityInfo {
- ActivityInfo(const char *name, os_activity_id_t activity_id,
- os_activity_id_t parent_activity_id)
- : m_name(name), m_id(activity_id), m_parent_id(parent_activity_id) {}
-
- const std::string m_name;
- const os_activity_id_t m_id;
- const os_activity_id_t m_parent_id;
- };
-
- using ActivityMap = std::unordered_map<os_activity_id_t, ActivityInfo>;
-
- const nub_process_t m_pid;
- os_activity_stream_t m_activity_stream;
- DarwinLogEventVector m_events;
- std::mutex m_events_mutex;
- LogFilterChainSP m_filter_chain_sp;
-
- /// Mutex to protect activity info (activity name and parent structures)
- mutable std::mutex m_activity_info_mutex;
- /// Map of activity id to ActivityInfo
- ActivityMap m_activity_map;
-};
-
-#endif /* LogStreamCollector_h */
diff --git a/tools/debugserver/source/MacOSX/DarwinLog/DarwinLogEvent.h b/tools/debugserver/source/MacOSX/DarwinLog/DarwinLogEvent.h
deleted file mode 100644
index 6be3b81f3e10..000000000000
--- a/tools/debugserver/source/MacOSX/DarwinLog/DarwinLogEvent.h
+++ /dev/null
@@ -1,27 +0,0 @@
-//===-- DarwinLogEvent.h ----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef DarwinLogEvent_h
-#define DarwinLogEvent_h
-
-#include <memory>
-#include <vector>
-
-#include "JSONGenerator.h"
-
-// =============================================================================
-/// Each discrete unit of information is described as an event, such as
-/// the emission of a single log message.
-// =============================================================================
-
-using DarwinLogEvent = JSONGenerator::Dictionary;
-using DarwinLogEventSP = std::shared_ptr<DarwinLogEvent>;
-using DarwinLogEventVector = std::vector<DarwinLogEventSP>;
-
-#endif
diff --git a/tools/debugserver/source/MacOSX/DarwinLog/DarwinLogInterfaces.h b/tools/debugserver/source/MacOSX/DarwinLog/DarwinLogInterfaces.h
deleted file mode 100644
index afb979f6cfe4..000000000000
--- a/tools/debugserver/source/MacOSX/DarwinLog/DarwinLogInterfaces.h
+++ /dev/null
@@ -1,25 +0,0 @@
-//===-- DarwinLogInterfaces.h -----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef DarwinLogInterfaces_h
-#define DarwinLogInterfaces_h
-
-#include <memory>
-
-class ActivityStore;
-
-class LogFilter;
-using LogFilterSP = std::shared_ptr<LogFilter>;
-
-class LogFilterChain;
-using LogFilterChainSP = std::shared_ptr<LogFilterChain>;
-
-class LogMessage;
-
-#endif /* DarwinLogInterfaces_h */
diff --git a/tools/debugserver/source/MacOSX/DarwinLog/DarwinLogTypes.h b/tools/debugserver/source/MacOSX/DarwinLog/DarwinLogTypes.h
deleted file mode 100644
index e285e732e565..000000000000
--- a/tools/debugserver/source/MacOSX/DarwinLog/DarwinLogTypes.h
+++ /dev/null
@@ -1,22 +0,0 @@
-//===-- DarwinLogTypes.h ----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef DarwinLogTypes_h
-#define DarwinLogTypes_h
-
-enum FilterTarget {
- eFilterTargetInvalid,
- eFilterTargetActivity,
- eFilterTargetActivityChain,
- eFilterTargetCategory,
- eFilterTargetMessage,
- eFilterTargetSubsystem
-};
-
-#endif /* DarwinLogTypes_h */
diff --git a/tools/debugserver/source/MacOSX/DarwinLog/LogFilter.cpp b/tools/debugserver/source/MacOSX/DarwinLog/LogFilter.cpp
deleted file mode 100644
index d78419d46617..000000000000
--- a/tools/debugserver/source/MacOSX/DarwinLog/LogFilter.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
-//===-- LogFilter.cpp -------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "LogFilter.h"
-
-LogFilter::~LogFilter() {}
diff --git a/tools/debugserver/source/MacOSX/DarwinLog/LogFilter.h b/tools/debugserver/source/MacOSX/DarwinLog/LogFilter.h
deleted file mode 100644
index 92caac297258..000000000000
--- a/tools/debugserver/source/MacOSX/DarwinLog/LogFilter.h
+++ /dev/null
@@ -1,30 +0,0 @@
-//===-- LogFilter.h ---------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LogFilter_h
-#define LogFilter_h
-
-#include "DarwinLogInterfaces.h"
-
-class LogFilter {
-public:
- virtual ~LogFilter();
-
- virtual bool DoesMatch(const LogMessage &message) const = 0;
-
- bool MatchesAreAccepted() const { return m_matches_accept; }
-
-protected:
- LogFilter(bool matches_accept) : m_matches_accept(matches_accept) {}
-
-private:
- bool m_matches_accept;
-};
-
-#endif /* LogFilter_h */
diff --git a/tools/debugserver/source/MacOSX/DarwinLog/LogFilterChain.cpp b/tools/debugserver/source/MacOSX/DarwinLog/LogFilterChain.cpp
deleted file mode 100644
index 12fbe77a9069..000000000000
--- a/tools/debugserver/source/MacOSX/DarwinLog/LogFilterChain.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-//===-- LogFilterChain.cpp --------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "LogFilterChain.h"
-
-#include "LogFilter.h"
-
-LogFilterChain::LogFilterChain(bool default_accept)
- : m_filters(), m_default_accept(default_accept) {}
-
-void LogFilterChain::AppendFilter(const LogFilterSP &filter_sp) {
- if (filter_sp)
- m_filters.push_back(filter_sp);
-}
-
-void LogFilterChain::ClearFilterChain() { m_filters.clear(); }
-
-bool LogFilterChain::GetDefaultAccepts() const { return m_default_accept; }
-
-void LogFilterChain::SetDefaultAccepts(bool default_accept) {
- m_default_accept = default_accept;
-}
-
-bool LogFilterChain::GetAcceptMessage(const LogMessage &message) const {
- for (auto filter_sp : m_filters) {
- if (filter_sp->DoesMatch(message)) {
- // This message matches this filter. If the filter accepts matches,
- // this message matches; otherwise, it rejects matches.
- return filter_sp->MatchesAreAccepted();
- }
- }
-
- // None of the filters matched. Therefore, we do whatever the
- // default fall-through rule says.
- return m_default_accept;
-}
diff --git a/tools/debugserver/source/MacOSX/DarwinLog/LogFilterChain.h b/tools/debugserver/source/MacOSX/DarwinLog/LogFilterChain.h
deleted file mode 100644
index e4888361e71f..000000000000
--- a/tools/debugserver/source/MacOSX/DarwinLog/LogFilterChain.h
+++ /dev/null
@@ -1,38 +0,0 @@
-//===-- LogFilterChain.h ----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LogFilterChain_h
-#define LogFilterChain_h
-
-#include <vector>
-
-#include "DarwinLogInterfaces.h"
-
-class LogFilterChain {
-public:
- LogFilterChain(bool default_accept);
-
- void AppendFilter(const LogFilterSP &filter_sp);
-
- void ClearFilterChain();
-
- bool GetDefaultAccepts() const;
-
- void SetDefaultAccepts(bool default_accepts);
-
- bool GetAcceptMessage(const LogMessage &message) const;
-
-private:
- using FilterVector = std::vector<LogFilterSP>;
-
- FilterVector m_filters;
- bool m_default_accept;
-};
-
-#endif /* LogFilterChain_hpp */
diff --git a/tools/debugserver/source/MacOSX/DarwinLog/LogFilterExactMatch.cpp b/tools/debugserver/source/MacOSX/DarwinLog/LogFilterExactMatch.cpp
deleted file mode 100644
index c8034fe1f222..000000000000
--- a/tools/debugserver/source/MacOSX/DarwinLog/LogFilterExactMatch.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-//===-- LogFilterExactMatch.cpp ---------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "LogFilterExactMatch.h"
-#include "LogMessage.h"
-
-LogFilterExactMatch::LogFilterExactMatch(bool match_accepts,
- FilterTarget filter_target,
- const std::string &match_text)
- : LogFilter(match_accepts), m_filter_target(filter_target),
- m_match_text(match_text) {}
-
-bool LogFilterExactMatch::DoesMatch(const LogMessage &message) const {
- switch (m_filter_target) {
- case eFilterTargetActivity:
- // Empty fields never match a condition.
- if (!message.HasActivity())
- return false;
- return m_match_text == message.GetActivity();
- case eFilterTargetActivityChain:
- // Empty fields never match a condition.
- if (!message.HasActivity())
- return false;
- return m_match_text == message.GetActivityChain();
- case eFilterTargetCategory:
- // Empty fields never match a condition.
- if (!message.HasCategory())
- return false;
- return m_match_text == message.GetCategory();
- case eFilterTargetMessage: {
- const char *message_text = message.GetMessage();
- return (message_text != nullptr) && (m_match_text == message_text);
- }
- case eFilterTargetSubsystem:
- // Empty fields never match a condition.
- if (!message.HasSubsystem())
- return false;
- return m_match_text == message.GetSubsystem();
- default:
- // We don't know this type.
- return false;
- }
-}
diff --git a/tools/debugserver/source/MacOSX/DarwinLog/LogFilterExactMatch.h b/tools/debugserver/source/MacOSX/DarwinLog/LogFilterExactMatch.h
deleted file mode 100644
index dd514bc82744..000000000000
--- a/tools/debugserver/source/MacOSX/DarwinLog/LogFilterExactMatch.h
+++ /dev/null
@@ -1,31 +0,0 @@
-//===-- LogFilterExactMatch.h -----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LogFilterExactMatch_h
-#define LogFilterExactMatch_h
-
-#include <string>
-
-#include "DarwinLogInterfaces.h"
-#include "DarwinLogTypes.h"
-#include "LogFilter.h"
-
-class LogFilterExactMatch : public LogFilter {
-public:
- LogFilterExactMatch(bool match_accepts, FilterTarget filter_target,
- const std::string &match_text);
-
- bool DoesMatch(const LogMessage &message) const override;
-
-private:
- const FilterTarget m_filter_target;
- const std::string m_match_text;
-};
-
-#endif
diff --git a/tools/debugserver/source/MacOSX/DarwinLog/LogFilterRegex.cpp b/tools/debugserver/source/MacOSX/DarwinLog/LogFilterRegex.cpp
deleted file mode 100644
index d21ce81c832c..000000000000
--- a/tools/debugserver/source/MacOSX/DarwinLog/LogFilterRegex.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-//===-- LogFilterRegex.cpp --------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "LogFilterRegex.h"
-
-#include "DNBLog.h"
-#include "LogMessage.h"
-
-//----------------------------------------------------------------------
-// Enable enhanced mode if it is available. This allows for things like
-// \d for digit, \s for space, and many more, but it isn't available
-// everywhere.
-//----------------------------------------------------------------------
-#if defined(REG_ENHANCED)
-#define DEFAULT_COMPILE_FLAGS (REG_ENHANCED | REG_EXTENDED)
-#else
-#define DEFAULT_COMPILE_FLAGS (REG_EXTENDED)
-#endif
-
-LogFilterRegex::LogFilterRegex(bool match_accepts, FilterTarget filter_target,
- const std::string &regex)
- : LogFilter(match_accepts), m_filter_target(filter_target),
- m_regex_text(regex), m_regex(), m_is_valid(false), m_error_text() {
- // Clear it.
- memset(&m_regex, 0, sizeof(m_regex));
-
- // Compile it.
- if (!regex.empty()) {
- auto comp_err = ::regcomp(&m_regex, regex.c_str(), DEFAULT_COMPILE_FLAGS);
- m_is_valid = (comp_err == 0);
- if (!m_is_valid) {
- char buffer[256];
- buffer[0] = '\0';
- ::regerror(comp_err, &m_regex, buffer, sizeof(buffer));
- m_error_text = buffer;
- }
- }
-}
-
-LogFilterRegex::~LogFilterRegex() {
- if (m_is_valid) {
- // Free the regex internals.
- regfree(&m_regex);
- }
-}
-
-bool LogFilterRegex::DoesMatch(const LogMessage &message) const {
- switch (m_filter_target) {
- case eFilterTargetActivity:
- // Empty fields never match a condition.
- if (!message.HasActivity())
- return false;
- return ::regexec(&m_regex, message.GetActivity(), 0, nullptr, 0) == 0;
- case eFilterTargetActivityChain:
- // Empty fields never match a condition.
- if (!message.HasActivity())
- return false;
- return ::regexec(&m_regex, message.GetActivityChain().c_str(), 0, nullptr,
- 0) == 0;
- case eFilterTargetCategory:
- // Empty fields never match a condition.
- if (!message.HasCategory())
- return false;
- return ::regexec(&m_regex, message.GetCategory(), 0, nullptr, 0) == 0;
- case eFilterTargetMessage: {
- const char *message_text = message.GetMessage();
- if (!message_text) {
- DNBLogThreadedIf(LOG_DARWIN_LOG,
- "LogFilterRegex: regex "
- "\"%s\" no match due to nullptr message.",
- m_regex_text.c_str());
- return false;
- }
-
- bool match = ::regexec(&m_regex, message_text, 0, nullptr, 0) == 0;
- DNBLogThreadedIf(LOG_DARWIN_LOG, "LogFilterRegex: regex "
- "\"%s\" %s message \"%s\".",
- m_regex_text.c_str(), match ? "matches" : "does not match",
- message_text);
- return match;
- }
- case eFilterTargetSubsystem:
- // Empty fields never match a condition.
- if (!message.HasSubsystem())
- return false;
- return ::regexec(&m_regex, message.GetSubsystem(), 0, nullptr, 0) == 0;
- default:
- // We don't know this type.
- return false;
- }
-}
diff --git a/tools/debugserver/source/MacOSX/DarwinLog/LogFilterRegex.h b/tools/debugserver/source/MacOSX/DarwinLog/LogFilterRegex.h
deleted file mode 100644
index 4a5939217f07..000000000000
--- a/tools/debugserver/source/MacOSX/DarwinLog/LogFilterRegex.h
+++ /dev/null
@@ -1,44 +0,0 @@
-//===-- LogFilterRegex.h ----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LogFilterRegex_h
-#define LogFilterRegex_h
-
-// C includes
-#include <regex.h>
-
-// C++ includes
-#include <string>
-
-#include "DarwinLogInterfaces.h"
-#include "DarwinLogTypes.h"
-#include "LogFilter.h"
-
-class LogFilterRegex : public LogFilter {
-public:
- LogFilterRegex(bool match_accepts, FilterTarget filter_target,
- const std::string &regex);
-
- virtual ~LogFilterRegex();
-
- bool IsValid() const { return m_is_valid; }
-
- const char *GetErrorAsCString() const { return m_error_text.c_str(); }
-
- bool DoesMatch(const LogMessage &message) const override;
-
-private:
- const FilterTarget m_filter_target;
- const std::string m_regex_text;
- regex_t m_regex;
- bool m_is_valid;
- std::string m_error_text;
-};
-
-#endif /* LogFilterSubsystemRegex_hpp */
diff --git a/tools/debugserver/source/MacOSX/DarwinLog/LogMessage.cpp b/tools/debugserver/source/MacOSX/DarwinLog/LogMessage.cpp
deleted file mode 100644
index 5a31087f2316..000000000000
--- a/tools/debugserver/source/MacOSX/DarwinLog/LogMessage.cpp
+++ /dev/null
@@ -1,14 +0,0 @@
-//===-- LogMessage.cpp ------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "LogMessage.h"
-
-LogMessage::LogMessage() {}
-
-LogMessage::~LogMessage() {}
diff --git a/tools/debugserver/source/MacOSX/DarwinLog/LogMessage.h b/tools/debugserver/source/MacOSX/DarwinLog/LogMessage.h
deleted file mode 100644
index bbc975133ece..000000000000
--- a/tools/debugserver/source/MacOSX/DarwinLog/LogMessage.h
+++ /dev/null
@@ -1,40 +0,0 @@
-//===-- LogMessage.h --------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LogMessage_h
-#define LogMessage_h
-
-#include <string>
-
-class LogMessage {
-public:
- virtual ~LogMessage();
-
- virtual bool HasActivity() const = 0;
-
- virtual const char *GetActivity() const = 0;
-
- virtual std::string GetActivityChain() const = 0;
-
- virtual bool HasCategory() const = 0;
-
- virtual const char *GetCategory() const = 0;
-
- virtual bool HasSubsystem() const = 0;
-
- virtual const char *GetSubsystem() const = 0;
-
- // This can be expensive, so once we ask for it, we'll cache the result.
- virtual const char *GetMessage() const = 0;
-
-protected:
- LogMessage();
-};
-
-#endif /* LogMessage_h */
diff --git a/tools/debugserver/source/MacOSX/DarwinLog/LogMessageOsLog.cpp b/tools/debugserver/source/MacOSX/DarwinLog/LogMessageOsLog.cpp
deleted file mode 100644
index 91347eaf12c7..000000000000
--- a/tools/debugserver/source/MacOSX/DarwinLog/LogMessageOsLog.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-//===-- LogMessageOsLog.cpp -------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "LogMessageOsLog.h"
-
-#include "ActivityStore.h"
-#include "ActivityStreamSPI.h"
-
-namespace {
-static os_log_copy_formatted_message_t s_log_copy_formatted_message;
-}
-
-void LogMessageOsLog::SetFormatterFunction(
- os_log_copy_formatted_message_t format_func) {
- s_log_copy_formatted_message = format_func;
-}
-
-LogMessageOsLog::LogMessageOsLog(const ActivityStore &activity_store,
- ActivityStreamEntry &entry)
- : LogMessage(), m_activity_store(activity_store), m_entry(entry),
- m_message() {}
-
-bool LogMessageOsLog::HasActivity() const { return m_entry.activity_id != 0; }
-
-const char *LogMessageOsLog::GetActivity() const {
- return m_activity_store.GetActivityForID(m_entry.activity_id);
-}
-
-std::string LogMessageOsLog::GetActivityChain() const {
- return m_activity_store.GetActivityChainForID(m_entry.activity_id);
-}
-
-bool LogMessageOsLog::HasCategory() const {
- return m_entry.log_message.category && (m_entry.log_message.category[0] != 0);
-}
-
-const char *LogMessageOsLog::GetCategory() const {
- return m_entry.log_message.category;
-}
-
-bool LogMessageOsLog::HasSubsystem() const {
- return m_entry.log_message.subsystem &&
- (m_entry.log_message.subsystem[0] != 0);
-}
-
-const char *LogMessageOsLog::GetSubsystem() const {
- return m_entry.log_message.subsystem;
-}
-
-const char *LogMessageOsLog::GetMessage() const {
- if (m_message.empty()) {
- std::unique_ptr<char[]> formatted_message(
- s_log_copy_formatted_message(&m_entry.log_message));
- if (formatted_message)
- m_message = formatted_message.get();
- // else
- // TODO log
- }
-
- // This is safe to return as we're not modifying it once we've formatted it.
- return m_message.c_str();
-}
diff --git a/tools/debugserver/source/MacOSX/DarwinLog/LogMessageOsLog.h b/tools/debugserver/source/MacOSX/DarwinLog/LogMessageOsLog.h
deleted file mode 100644
index 18103e031592..000000000000
--- a/tools/debugserver/source/MacOSX/DarwinLog/LogMessageOsLog.h
+++ /dev/null
@@ -1,59 +0,0 @@
-//===-- LogMessageOsLog.h ---------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LogMessageOsLog_h
-#define LogMessageOsLog_h
-
-#include "DarwinLogInterfaces.h"
-
-#include "ActivityStreamSPI.h"
-#include "LogMessage.h"
-
-using ActivityStreamEntry = struct os_activity_stream_entry_s;
-
-// -----------------------------------------------------------------------------
-/// Provides a unified wrapper around os_log()-style log messages.
-///
-/// The lifetime of this class is intended to be very short. The caller
-/// must ensure that the passed in ActivityStore and ActivityStreamEntry
-/// outlive this LogMessageOsLog entry.
-// -----------------------------------------------------------------------------
-
-class LogMessageOsLog : public LogMessage {
-public:
- static void SetFormatterFunction(os_log_copy_formatted_message_t format_func);
-
- LogMessageOsLog(const ActivityStore &activity_store,
- ActivityStreamEntry &entry);
-
- // API methods
-
- bool HasActivity() const override;
-
- const char *GetActivity() const override;
-
- std::string GetActivityChain() const override;
-
- bool HasCategory() const override;
-
- const char *GetCategory() const override;
-
- bool HasSubsystem() const override;
-
- const char *GetSubsystem() const override;
-
- const char *GetMessage() const override;
-
-private:
- const ActivityStore &m_activity_store;
- ActivityStreamEntry &m_entry;
- mutable std::string m_message;
-};
-
-#endif /* LogMessageOsLog_h */
diff --git a/tools/debugserver/source/MacOSX/Genealogy.cpp b/tools/debugserver/source/MacOSX/Genealogy.cpp
deleted file mode 100644
index 1473a53fcbea..000000000000
--- a/tools/debugserver/source/MacOSX/Genealogy.cpp
+++ /dev/null
@@ -1,318 +0,0 @@
-///===-- Activity.cpp ---------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include <Availability.h>
-#include <dlfcn.h>
-#include <string>
-#include <uuid/uuid.h>
-
-#include "DNBDefs.h"
-#include "Genealogy.h"
-#include "GenealogySPI.h"
-#include "MachThreadList.h"
-
-//---------------------------
-/// Constructor
-//---------------------------
-
-Genealogy::Genealogy()
- : m_os_activity_diagnostic_for_pid(nullptr),
- m_os_activity_iterate_processes(nullptr),
- m_os_activity_iterate_breadcrumbs(nullptr),
- m_os_activity_iterate_messages(nullptr),
- m_os_activity_iterate_activities(nullptr), m_os_trace_get_type(nullptr),
- m_os_trace_copy_formatted_message(nullptr),
- m_os_activity_for_thread(nullptr), m_os_activity_for_task_thread(nullptr),
- m_thread_activities(), m_process_executable_infos(),
- m_diagnosticd_call_timed_out(false) {
- m_os_activity_diagnostic_for_pid =
- (bool (*)(pid_t, os_activity_t, uint32_t, os_diagnostic_block_t))dlsym(
- RTLD_DEFAULT, "os_activity_diagnostic_for_pid");
- m_os_activity_iterate_processes =
- (void (*)(os_activity_process_list_t, bool (^)(os_activity_process_t)))
- dlsym(RTLD_DEFAULT, "os_activity_iterate_processes");
- m_os_activity_iterate_breadcrumbs =
- (void (*)(os_activity_process_t, bool (^)(os_activity_breadcrumb_t)))
- dlsym(RTLD_DEFAULT, "os_activity_iterate_breadcrumbs");
- m_os_activity_iterate_messages = (void (*)(
- os_trace_message_list_t, os_activity_process_t,
- bool (^)(os_trace_message_t)))dlsym(RTLD_DEFAULT,
- "os_activity_iterate_messages");
- m_os_activity_iterate_activities = (void (*)(
- os_activity_list_t, os_activity_process_t,
- bool (^)(os_activity_entry_t)))dlsym(RTLD_DEFAULT,
- "os_activity_iterate_activities");
- m_os_trace_get_type =
- (uint8_t(*)(os_trace_message_t))dlsym(RTLD_DEFAULT, "os_trace_get_type");
- m_os_trace_copy_formatted_message = (char *(*)(os_trace_message_t))dlsym(
- RTLD_DEFAULT, "os_trace_copy_formatted_message");
- m_os_activity_for_thread =
- (os_activity_t(*)(os_activity_process_t, uint64_t))dlsym(
- RTLD_DEFAULT, "os_activity_for_thread");
- m_os_activity_for_task_thread = (os_activity_t(*)(task_t, uint64_t))dlsym(
- RTLD_DEFAULT, "os_activity_for_task_thread");
- m_os_activity_messages_for_thread = (os_trace_message_list_t(*)(
- os_activity_process_t process, os_activity_t activity,
- uint64_t thread_id))dlsym(RTLD_DEFAULT,
- "os_activity_messages_for_thread");
-}
-
-Genealogy::ThreadActivitySP
-Genealogy::GetGenealogyInfoForThread(pid_t pid, nub_thread_t tid,
- const MachThreadList &thread_list,
- task_t task, bool &timed_out) {
- ThreadActivitySP activity;
- //
- // if we've timed out trying to get the activities, don't try again at this
- // process stop.
- // (else we'll need to hit the timeout for every thread we're asked about.)
- // We'll try again at the next public stop.
-
- if (m_thread_activities.size() == 0 && !m_diagnosticd_call_timed_out) {
- GetActivities(pid, thread_list, task);
- }
- std::map<nub_thread_t, ThreadActivitySP>::const_iterator search;
- search = m_thread_activities.find(tid);
- if (search != m_thread_activities.end()) {
- activity = search->second;
- }
- timed_out = m_diagnosticd_call_timed_out;
- return activity;
-}
-
-void Genealogy::Clear() {
- m_thread_activities.clear();
- m_diagnosticd_call_timed_out = false;
-}
-
-void Genealogy::GetActivities(pid_t pid, const MachThreadList &thread_list,
- task_t task) {
- if (m_os_activity_diagnostic_for_pid != nullptr &&
- m_os_activity_iterate_processes != nullptr &&
- m_os_activity_iterate_breadcrumbs != nullptr &&
- m_os_activity_iterate_messages != nullptr &&
- m_os_activity_iterate_activities != nullptr &&
- m_os_trace_get_type != nullptr &&
- m_os_trace_copy_formatted_message != nullptr &&
- (m_os_activity_for_thread != nullptr ||
- m_os_activity_for_task_thread != nullptr)) {
- __block dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
- __block BreadcrumbList breadcrumbs;
- __block ActivityList activities;
- __block MessageList messages;
- __block std::map<nub_thread_t, uint64_t> thread_activity_mapping;
-
- os_activity_diagnostic_flag_t flags =
- OS_ACTIVITY_DIAGNOSTIC_ALL_ACTIVITIES |
- OS_ACTIVITY_DIAGNOSTIC_PROCESS_ONLY;
- if (m_os_activity_diagnostic_for_pid(
- pid, 0, flags, ^(os_activity_process_list_t processes, int error) {
- if (error == 0) {
- m_os_activity_iterate_processes(processes, ^bool(
- os_activity_process_t
- process_info) {
- if (pid == process_info->pid) {
- // Collect all the Breadcrumbs
- m_os_activity_iterate_breadcrumbs(
- process_info,
- ^bool(os_activity_breadcrumb_t breadcrumb) {
- Breadcrumb bc;
- bc.breadcrumb_id = breadcrumb->breadcrumb_id;
- bc.activity_id = breadcrumb->activity_id;
- bc.timestamp = breadcrumb->timestamp;
- if (breadcrumb->name)
- bc.name = breadcrumb->name;
- breadcrumbs.push_back(bc);
- return true;
- });
-
- // Collect all the Activites
- m_os_activity_iterate_activities(
- process_info->activities, process_info,
- ^bool(os_activity_entry_t activity) {
- Activity ac;
- ac.activity_start = activity->activity_start;
- ac.activity_id = activity->activity_id;
- ac.parent_id = activity->parent_id;
- if (activity->activity_name)
- ac.activity_name = activity->activity_name;
- if (activity->reason)
- ac.reason = activity->reason;
- activities.push_back(ac);
- return true;
- });
-
- // Collect all the Messages -- messages not associated with
- // any thread
- m_os_activity_iterate_messages(
- process_info->messages, process_info,
- ^bool(os_trace_message_t trace_msg) {
- Message msg;
- msg.timestamp = trace_msg->timestamp;
- msg.trace_id = trace_msg->trace_id;
- msg.thread = trace_msg->thread;
- msg.type = m_os_trace_get_type(trace_msg);
- msg.activity_id = 0;
- if (trace_msg->image_uuid && trace_msg->image_path) {
- ProcessExecutableInfoSP process_info_sp(
- new ProcessExecutableInfo());
- uuid_copy(process_info_sp->image_uuid,
- trace_msg->image_uuid);
- process_info_sp->image_path = trace_msg->image_path;
- msg.process_info_index =
- AddProcessExecutableInfo(process_info_sp);
- }
- const char *message_text =
- m_os_trace_copy_formatted_message(trace_msg);
- if (message_text)
- msg.message = message_text;
- messages.push_back(msg);
- return true;
- });
-
- // Discover which activities are said to be running on
- // threads currently
- const nub_size_t num_threads = thread_list.NumThreads();
- for (nub_size_t i = 0; i < num_threads; ++i) {
- nub_thread_t thread_id = thread_list.ThreadIDAtIndex(i);
- os_activity_t act = 0;
- if (m_os_activity_for_task_thread != nullptr) {
- act = m_os_activity_for_task_thread(task, thread_id);
- } else if (m_os_activity_for_thread != nullptr) {
- act = m_os_activity_for_thread(process_info, thread_id);
- }
- if (act != 0)
- thread_activity_mapping[thread_id] = act;
- }
-
- // Collect all Messages -- messages associated with a thread
-
- // When there's no genealogy information, an early version
- // of os_activity_messages_for_thread
- // can crash in rare circumstances. Check to see if this
- // process has any activities before
- // making the call to get messages.
- if (process_info->activities != nullptr &&
- thread_activity_mapping.size() > 0) {
- std::map<nub_thread_t, uint64_t>::const_iterator iter;
- for (iter = thread_activity_mapping.begin();
- iter != thread_activity_mapping.end(); ++iter) {
- nub_thread_t thread_id = iter->first;
- os_activity_t act = iter->second;
- os_trace_message_list_t this_thread_messages =
- m_os_activity_messages_for_thread(process_info, act,
- thread_id);
- m_os_activity_iterate_messages(
- this_thread_messages, process_info,
- ^bool(os_trace_message_t trace_msg) {
- Message msg;
- msg.timestamp = trace_msg->timestamp;
- msg.trace_id = trace_msg->trace_id;
- msg.thread = trace_msg->thread;
- msg.type = m_os_trace_get_type(trace_msg);
- msg.activity_id = act;
- if (trace_msg->image_uuid &&
- trace_msg->image_path) {
- ProcessExecutableInfoSP process_info_sp(
- new ProcessExecutableInfo());
- uuid_copy(process_info_sp->image_uuid,
- trace_msg->image_uuid);
- process_info_sp->image_path =
- trace_msg->image_path;
- msg.process_info_index =
- AddProcessExecutableInfo(process_info_sp);
- }
- const char *message_text =
- m_os_trace_copy_formatted_message(trace_msg);
- if (message_text)
- msg.message = message_text;
- messages.push_back(msg);
- return true;
- });
- }
- }
- }
- return true;
- });
- }
- dispatch_semaphore_signal(semaphore);
- }) == true) {
- // Wait for the diagnosticd xpc calls to all finish up -- or half a second
- // to elapse.
- dispatch_time_t timeout =
- dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC / 2);
- bool success = dispatch_semaphore_wait(semaphore, timeout) == 0;
- if (!success) {
- m_diagnosticd_call_timed_out = true;
- return;
- }
- }
-
- // breadcrumbs, activities, and messages have all now been filled in.
-
- std::map<nub_thread_t, uint64_t>::const_iterator iter;
- for (iter = thread_activity_mapping.begin();
- iter != thread_activity_mapping.end(); ++iter) {
- nub_thread_t thread_id = iter->first;
- uint64_t activity_id = iter->second;
- ActivityList::const_iterator activity_search;
- for (activity_search = activities.begin();
- activity_search != activities.end(); ++activity_search) {
- if (activity_search->activity_id == activity_id) {
- ThreadActivitySP thread_activity_sp(new ThreadActivity());
- thread_activity_sp->current_activity = *activity_search;
-
- BreadcrumbList::const_iterator breadcrumb_search;
- for (breadcrumb_search = breadcrumbs.begin();
- breadcrumb_search != breadcrumbs.end(); ++breadcrumb_search) {
- if (breadcrumb_search->activity_id == activity_id) {
- thread_activity_sp->breadcrumbs.push_back(*breadcrumb_search);
- }
- }
- MessageList::const_iterator message_search;
- for (message_search = messages.begin();
- message_search != messages.end(); ++message_search) {
- if (message_search->thread == thread_id) {
- thread_activity_sp->messages.push_back(*message_search);
- }
- }
-
- m_thread_activities[thread_id] = thread_activity_sp;
- break;
- }
- }
- }
- }
-}
-
-uint32_t
-Genealogy::AddProcessExecutableInfo(ProcessExecutableInfoSP process_exe_info) {
- const uint32_t info_size =
- static_cast<uint32_t>(m_process_executable_infos.size());
- for (uint32_t idx = 0; idx < info_size; ++idx) {
- if (uuid_compare(m_process_executable_infos[idx]->image_uuid,
- process_exe_info->image_uuid) == 0) {
- return idx + 1;
- }
- }
- m_process_executable_infos.push_back(process_exe_info);
- return info_size + 1;
-}
-
-Genealogy::ProcessExecutableInfoSP
-Genealogy::GetProcessExecutableInfosAtIndex(size_t idx) {
- ProcessExecutableInfoSP info_sp;
- if (idx > 0) {
- idx--;
- if (idx <= m_process_executable_infos.size()) {
- info_sp = m_process_executable_infos[idx];
- }
- }
- return info_sp;
-}
diff --git a/tools/debugserver/source/MacOSX/Genealogy.h b/tools/debugserver/source/MacOSX/Genealogy.h
deleted file mode 100644
index f398b63c6d92..000000000000
--- a/tools/debugserver/source/MacOSX/Genealogy.h
+++ /dev/null
@@ -1,120 +0,0 @@
-//===-- Activity.h -----------------------------------------------*- C++
-//-*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __Genealogy_h__
-#define __Genealogy_h__
-
-#include <mach/task.h>
-#include <map>
-#include <pthread.h>
-#include <string>
-#include <vector>
-
-#include "GenealogySPI.h"
-#include "MachThreadList.h"
-
-class Genealogy {
-public:
- Genealogy();
-
- ~Genealogy() {}
-
- void Clear();
-
- struct Breadcrumb {
- uint32_t breadcrumb_id;
- uint64_t activity_id;
- uint64_t timestamp;
- std::string name;
- };
-
- struct Activity {
- uint64_t activity_start;
- uint64_t activity_id;
- uint64_t parent_id;
- std::string activity_name;
- std::string reason;
- };
-
- struct Message {
- uint64_t timestamp;
- uint64_t activity_id;
- uint64_t trace_id;
- uint64_t thread;
- uint8_t type; // OS_TRACE_TYPE_RELEASE, OS_TRACE_TYPE_DEBUG,
- // OS_TRACE_TYPE_ERROR, OS_TRACE_TYPE_FAULT
- uint32_t process_info_index; // index # of the image uuid/file path, 0 means
- // unknown
- std::string message;
- };
-
- typedef std::vector<Message> MessageList;
- typedef std::vector<Breadcrumb> BreadcrumbList;
- typedef std::vector<Activity> ActivityList;
-
- struct ThreadActivity {
- Activity current_activity;
- MessageList messages;
- BreadcrumbList breadcrumbs; // should be 0 or 1 breadcrumbs; no more than 1
- // BC for any given activity
- };
-
- typedef std::shared_ptr<ThreadActivity> ThreadActivitySP;
-
- ThreadActivitySP GetGenealogyInfoForThread(pid_t pid, nub_thread_t tid,
- const MachThreadList &thread_list,
- task_t task, bool &timed_out);
-
- struct ProcessExecutableInfo {
- std::string image_path;
- uuid_t image_uuid;
- };
-
- typedef std::shared_ptr<ProcessExecutableInfo> ProcessExecutableInfoSP;
-
- ProcessExecutableInfoSP GetProcessExecutableInfosAtIndex(size_t idx);
-
- uint32_t AddProcessExecutableInfo(ProcessExecutableInfoSP process_exe_info);
-
-private:
- void GetActivities(pid_t pid, const MachThreadList &thread_list, task_t task);
-
- // the spi we need to call into libtrace - look them up via dlsym at runtime
- bool (*m_os_activity_diagnostic_for_pid)(pid_t pid, os_activity_t activity,
- uint32_t flags,
- os_diagnostic_block_t block);
- void (*m_os_activity_iterate_processes)(
- os_activity_process_list_t processes,
- bool (^iterator)(os_activity_process_t process_info));
- void (*m_os_activity_iterate_breadcrumbs)(
- os_activity_process_t process_info,
- bool (^iterator)(os_activity_breadcrumb_t breadcrumb));
- void (*m_os_activity_iterate_messages)(
- os_trace_message_list_t messages, os_activity_process_t process_info,
- bool (^iterator)(os_trace_message_t tracemsg));
- void (*m_os_activity_iterate_activities)(
- os_activity_list_t activities, os_activity_process_t process_info,
- bool (^iterator)(os_activity_entry_t activity));
- uint8_t (*m_os_trace_get_type)(os_trace_message_t trace_msg);
- char *(*m_os_trace_copy_formatted_message)(os_trace_message_t trace_msg);
- os_activity_t (*m_os_activity_for_thread)(os_activity_process_t process,
- uint64_t thread_id);
- os_activity_t (*m_os_activity_for_task_thread)(task_t target,
- uint64_t thread_id);
- os_trace_message_list_t (*m_os_activity_messages_for_thread)(
- os_activity_process_t process, os_activity_t activity,
- uint64_t thread_id);
-
- std::map<nub_thread_t, ThreadActivitySP> m_thread_activities;
- std::vector<ProcessExecutableInfoSP> m_process_executable_infos;
- bool m_diagnosticd_call_timed_out;
-};
-
-#endif // __Genealogy_h__
diff --git a/tools/debugserver/source/MacOSX/GenealogySPI.h b/tools/debugserver/source/MacOSX/GenealogySPI.h
deleted file mode 100644
index de9db2d2e64a..000000000000
--- a/tools/debugserver/source/MacOSX/GenealogySPI.h
+++ /dev/null
@@ -1,95 +0,0 @@
-//===-- ActivitySPI.h -------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//===----------------------------------------------------------------------===//
-
-#ifndef __GenealogySPI_h__
-#define __GenealogySPI_h__
-
-#include <xpc/xpc.h>
-
-typedef void *os_activity_process_list_t;
-typedef void *os_activity_list_t;
-typedef void *os_trace_message_list_t;
-typedef struct os_activity_watch_s *os_activity_watch_t;
-typedef uint64_t os_activity_t;
-
-struct os_activity_breadcrumb_s {
- uint32_t breadcrumb_id;
- uint64_t activity_id;
- uint64_t timestamp;
- const char *name;
-};
-
-typedef struct os_activity_breadcrumb_s *os_activity_breadcrumb_t;
-
-typedef struct os_trace_message_s {
- uint64_t trace_id;
- uint64_t thread;
- uint64_t timestamp;
- uint32_t offset;
- xpc_object_t __unsafe_unretained payload;
- const uint8_t *image_uuid;
- const char *image_path;
- const char *format;
- const void *buffer;
- size_t bufferLen;
-} * os_trace_message_t;
-
-typedef struct os_activity_process_s {
- os_activity_process_list_t child_procs;
- os_trace_message_list_t messages;
- os_activity_list_t activities;
- void *breadcrumbs;
- uint64_t proc_id;
- const uint8_t *image_uuid;
- const char *image_path;
- pid_t pid;
-} * os_activity_process_t;
-
-typedef struct os_activity_entry_s {
- uint64_t activity_start;
- os_activity_t activity_id;
- os_activity_t parent_id;
- const char *activity_name;
- const char *reason;
- os_trace_message_list_t messages;
-} * os_activity_entry_t;
-
-enum {
- OS_ACTIVITY_DIAGNOSTIC_DEFAULT = 0x00000000,
- OS_ACTIVITY_DIAGNOSTIC_PROCESS_ONLY = 0x00000001,
- OS_ACTIVITY_DIAGNOSTIC_SKIP_DECODE = 0x00000002,
- OS_ACTIVITY_DIAGNOSTIC_FLATTENED = 0x00000004,
- OS_ACTIVITY_DIAGNOSTIC_ALL_ACTIVITIES = 0x00000008,
- OS_ACTIVITY_DIAGNOSTIC_MAX = 0x0000000f
-};
-typedef uint32_t os_activity_diagnostic_flag_t;
-
-enum {
- OS_ACTIVITY_WATCH_DEFAULT = 0x00000000,
- OS_ACTIVITY_WATCH_PROCESS_ONLY = 0x00000001,
- OS_ACTIVITY_WATCH_SKIP_DECODE = 0x00000002,
- OS_ACTIVITY_WATCH_PAYLOAD = 0x00000004,
- OS_ACTIVITY_WATCH_ERRORS = 0x00000008,
- OS_ACTIVITY_WATCH_FAULTS = 0x00000010,
- OS_ACTIVITY_WATCH_MAX = 0x0000001f
-};
-typedef uint32_t os_activity_watch_flag_t;
-
-// Return values from os_trace_get_type()
-#define OS_TRACE_TYPE_RELEASE (1u << 0)
-#define OS_TRACE_TYPE_DEBUG (1u << 1)
-#define OS_TRACE_TYPE_ERROR ((1u << 6) | (1u << 0))
-#define OS_TRACE_TYPE_FAULT ((1u << 7) | (1u << 6) | (1u << 0))
-
-typedef void (^os_activity_watch_block_t)(os_activity_watch_t watch,
- os_activity_process_t process_info,
- bool canceled);
-typedef void (^os_diagnostic_block_t)(os_activity_process_list_t processes,
- int error);
-
-#endif
diff --git a/tools/debugserver/source/MacOSX/MachException.cpp b/tools/debugserver/source/MacOSX/MachException.cpp
deleted file mode 100644
index 01e5892d487d..000000000000
--- a/tools/debugserver/source/MacOSX/MachException.cpp
+++ /dev/null
@@ -1,513 +0,0 @@
-//===-- MachException.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/18/07.
-//
-//===----------------------------------------------------------------------===//
-
-#include "MachException.h"
-#include "DNB.h"
-#include "DNBError.h"
-#include "DNBLog.h"
-#include "MachProcess.h"
-#include "PThreadMutex.h"
-#include "SysSignal.h"
-#include <errno.h>
-#include <sys/ptrace.h>
-#include <sys/types.h>
-
-// Routine mach_exception_raise
-extern "C" kern_return_t
-catch_mach_exception_raise(mach_port_t exception_port, mach_port_t thread,
- mach_port_t task, exception_type_t exception,
- mach_exception_data_t code,
- mach_msg_type_number_t codeCnt);
-
-extern "C" kern_return_t catch_mach_exception_raise_state(
- mach_port_t exception_port, exception_type_t exception,
- const mach_exception_data_t code, mach_msg_type_number_t codeCnt,
- int *flavor, const thread_state_t old_state,
- mach_msg_type_number_t old_stateCnt, thread_state_t new_state,
- mach_msg_type_number_t *new_stateCnt);
-
-// Routine mach_exception_raise_state_identity
-extern "C" kern_return_t catch_mach_exception_raise_state_identity(
- mach_port_t exception_port, mach_port_t thread, mach_port_t task,
- exception_type_t exception, mach_exception_data_t code,
- mach_msg_type_number_t codeCnt, int *flavor, thread_state_t old_state,
- mach_msg_type_number_t old_stateCnt, thread_state_t new_state,
- mach_msg_type_number_t *new_stateCnt);
-
-extern "C" boolean_t mach_exc_server(mach_msg_header_t *InHeadP,
- mach_msg_header_t *OutHeadP);
-
-// Note: g_message points to the storage allocated to catch the data from
-// catching the current exception raise. It's populated when we catch a raised
-// exception which can't immediately be replied to.
-//
-// If it becomes possible to catch exceptions from multiple threads
-// simultaneously, accesses to g_message would need to be mutually exclusive.
-static MachException::Data *g_message = NULL;
-
-extern "C" kern_return_t catch_mach_exception_raise_state(
- mach_port_t exc_port, exception_type_t exc_type,
- const mach_exception_data_t exc_data, mach_msg_type_number_t exc_data_count,
- int *flavor, const thread_state_t old_state,
- mach_msg_type_number_t old_stateCnt, thread_state_t new_state,
- mach_msg_type_number_t *new_stateCnt) {
- if (DNBLogCheckLogBit(LOG_EXCEPTIONS)) {
- DNBLogThreaded("::%s ( exc_port = 0x%4.4x, exc_type = %d ( %s ), exc_data "
- "= 0x%llx, exc_data_count = %d)",
- __FUNCTION__, exc_port, exc_type,
- MachException::Name(exc_type), (uint64_t)exc_data,
- exc_data_count);
- }
- return KERN_FAILURE;
-}
-
-extern "C" kern_return_t catch_mach_exception_raise_state_identity(
- mach_port_t exc_port, mach_port_t thread_port, mach_port_t task_port,
- exception_type_t exc_type, mach_exception_data_t exc_data,
- mach_msg_type_number_t exc_data_count, int *flavor,
- thread_state_t old_state, mach_msg_type_number_t old_stateCnt,
- thread_state_t new_state, mach_msg_type_number_t *new_stateCnt) {
- if (DNBLogCheckLogBit(LOG_EXCEPTIONS)) {
- DNBLogThreaded("::%s ( exc_port = 0x%4.4x, thd_port = 0x%4.4x, tsk_port = "
- "0x%4.4x, exc_type = %d ( %s ), exc_data[%d] = { 0x%llx, "
- "0x%llx })",
- __FUNCTION__, exc_port, thread_port, task_port, exc_type,
- MachException::Name(exc_type), exc_data_count,
- (uint64_t)(exc_data_count > 0 ? exc_data[0] : 0xBADDBADD),
- (uint64_t)(exc_data_count > 1 ? exc_data[1] : 0xBADDBADD));
- }
-
- return KERN_FAILURE;
-}
-
-extern "C" kern_return_t
-catch_mach_exception_raise(mach_port_t exc_port, mach_port_t thread_port,
- mach_port_t task_port, exception_type_t exc_type,
- mach_exception_data_t exc_data,
- mach_msg_type_number_t exc_data_count) {
- if (DNBLogCheckLogBit(LOG_EXCEPTIONS)) {
- DNBLogThreaded("::%s ( exc_port = 0x%4.4x, thd_port = 0x%4.4x, tsk_port = "
- "0x%4.4x, exc_type = %d ( %s ), exc_data[%d] = { 0x%llx, "
- "0x%llx })",
- __FUNCTION__, exc_port, thread_port, task_port, exc_type,
- MachException::Name(exc_type), exc_data_count,
- (uint64_t)(exc_data_count > 0 ? exc_data[0] : 0xBADDBADD),
- (uint64_t)(exc_data_count > 1 ? exc_data[1] : 0xBADDBADD));
- }
- g_message->exc_type = 0;
- g_message->exc_data.clear();
-
- if (task_port == g_message->task_port) {
- g_message->task_port = task_port;
- g_message->thread_port = thread_port;
- g_message->exc_type = exc_type;
- g_message->AppendExceptionData(exc_data, exc_data_count);
- return KERN_SUCCESS;
- } else if (!MachTask::IsValid(g_message->task_port)) {
- // Our original exception port isn't valid anymore check for a SIGTRAP
- if (exc_type == EXC_SOFTWARE && exc_data_count == 2 &&
- exc_data[0] == EXC_SOFT_SIGNAL && exc_data[1] == SIGTRAP) {
- // We got a SIGTRAP which indicates we might have exec'ed and possibly
- // lost our old task port during the exec, so we just need to switch over
- // to using this new task port
- g_message->task_port = task_port;
- g_message->thread_port = thread_port;
- g_message->exc_type = exc_type;
- g_message->AppendExceptionData(exc_data, exc_data_count);
- return KERN_SUCCESS;
- }
- }
- return KERN_FAILURE;
-}
-
-void MachException::Message::Dump() const {
- DNBLogThreadedIf(LOG_EXCEPTIONS, " exc_msg { bits = 0x%8.8x size = 0x%8.8x "
- "remote-port = 0x%8.8x local-port = 0x%8.8x "
- "reserved = 0x%8.8x id = 0x%8.8x } ",
- exc_msg.hdr.msgh_bits, exc_msg.hdr.msgh_size,
- exc_msg.hdr.msgh_remote_port, exc_msg.hdr.msgh_local_port,
- exc_msg.hdr.msgh_reserved, exc_msg.hdr.msgh_id);
-
- DNBLogThreadedIf(LOG_EXCEPTIONS, "reply_msg { bits = 0x%8.8x size = 0x%8.8x "
- "remote-port = 0x%8.8x local-port = 0x%8.8x "
- "reserved = 0x%8.8x id = 0x%8.8x }",
- reply_msg.hdr.msgh_bits, reply_msg.hdr.msgh_size,
- reply_msg.hdr.msgh_remote_port,
- reply_msg.hdr.msgh_local_port, reply_msg.hdr.msgh_reserved,
- reply_msg.hdr.msgh_id);
-
- state.Dump();
-}
-
-bool MachException::Data::GetStopInfo(
- struct DNBThreadStopInfo *stop_info) const {
- // Zero out the structure.
- memset(stop_info, 0, sizeof(struct DNBThreadStopInfo));
-
- if (exc_type == 0) {
- stop_info->reason = eStopTypeInvalid;
- return true;
- }
-
- // We always stop with a mach exceptions
- stop_info->reason = eStopTypeException;
- // Save the EXC_XXXX exception type
- stop_info->details.exception.type = exc_type;
-
- // Fill in a text description
- const char *exc_name = MachException::Name(exc_type);
- char *desc = stop_info->description;
- const char *end_desc = desc + DNB_THREAD_STOP_INFO_MAX_DESC_LENGTH;
- if (exc_name)
- desc +=
- snprintf(desc, DNB_THREAD_STOP_INFO_MAX_DESC_LENGTH, "%s", exc_name);
- else
- desc +=
- snprintf(desc, DNB_THREAD_STOP_INFO_MAX_DESC_LENGTH, "%i", exc_type);
-
- stop_info->details.exception.data_count = exc_data.size();
-
- int soft_signal = SoftSignal();
- if (soft_signal) {
- if (desc < end_desc) {
- const char *sig_str = SysSignal::Name(soft_signal);
- snprintf(desc, end_desc - desc, " EXC_SOFT_SIGNAL( %i ( %s ))",
- soft_signal, sig_str ? sig_str : "unknown signal");
- }
- } else {
- // No special disassembly for exception data, just
- size_t idx;
- if (desc < end_desc) {
- desc += snprintf(desc, end_desc - desc, " data[%llu] = {",
- (uint64_t)stop_info->details.exception.data_count);
-
- for (idx = 0;
- desc < end_desc && idx < stop_info->details.exception.data_count;
- ++idx)
- desc += snprintf(
- desc, end_desc - desc, "0x%llx%c", (uint64_t)exc_data[idx],
- ((idx + 1 == stop_info->details.exception.data_count) ? '}' : ','));
- }
- }
-
- // Copy the exception data
- size_t i;
- for (i = 0; i < stop_info->details.exception.data_count; i++)
- stop_info->details.exception.data[i] = exc_data[i];
-
- return true;
-}
-
-void MachException::Data::DumpStopReason() const {
- int soft_signal = SoftSignal();
- if (soft_signal) {
- const char *signal_str = SysSignal::Name(soft_signal);
- if (signal_str)
- DNBLog("signal(%s)", signal_str);
- else
- DNBLog("signal(%i)", soft_signal);
- return;
- }
- DNBLog("%s", Name(exc_type));
-}
-
-kern_return_t MachException::Message::Receive(mach_port_t port,
- mach_msg_option_t options,
- mach_msg_timeout_t timeout,
- mach_port_t notify_port) {
- DNBError err;
- const bool log_exceptions = DNBLogCheckLogBit(LOG_EXCEPTIONS);
- mach_msg_timeout_t mach_msg_timeout =
- options & MACH_RCV_TIMEOUT ? timeout : 0;
- if (log_exceptions && ((options & MACH_RCV_TIMEOUT) == 0)) {
- // Dump this log message if we have no timeout in case it never returns
- DNBLogThreaded("::mach_msg ( msg->{bits = %#x, size = %u remote_port = "
- "%#x, local_port = %#x, reserved = 0x%x, id = 0x%x}, option "
- "= %#x, send_size = 0, rcv_size = %llu, rcv_name = %#x, "
- "timeout = %u, notify = %#x)",
- exc_msg.hdr.msgh_bits, exc_msg.hdr.msgh_size,
- exc_msg.hdr.msgh_remote_port, exc_msg.hdr.msgh_local_port,
- exc_msg.hdr.msgh_reserved, exc_msg.hdr.msgh_id, options,
- (uint64_t)sizeof(exc_msg.data), port, mach_msg_timeout,
- notify_port);
- }
-
- err = ::mach_msg(&exc_msg.hdr,
- options, // options
- 0, // Send size
- sizeof(exc_msg.data), // Receive size
- port, // exception port to watch for exception on
- mach_msg_timeout, // timeout in msec (obeyed only if
- // MACH_RCV_TIMEOUT is ORed into the
- // options parameter)
- notify_port);
-
- // Dump any errors we get
- if (log_exceptions) {
- err.LogThreaded("::mach_msg ( msg->{bits = %#x, size = %u remote_port = "
- "%#x, local_port = %#x, reserved = 0x%x, id = 0x%x}, "
- "option = %#x, send_size = %u, rcv_size = %u, rcv_name = "
- "%#x, timeout = %u, notify = %#x)",
- exc_msg.hdr.msgh_bits, exc_msg.hdr.msgh_size,
- exc_msg.hdr.msgh_remote_port, exc_msg.hdr.msgh_local_port,
- exc_msg.hdr.msgh_reserved, exc_msg.hdr.msgh_id, options, 0,
- sizeof(exc_msg.data), port, mach_msg_timeout, notify_port);
- }
- return err.Status();
-}
-
-bool MachException::Message::CatchExceptionRaise(task_t task) {
- bool success = false;
- state.task_port = task;
- g_message = &state;
- // The exc_server function is the MIG generated server handling function
- // to handle messages from the kernel relating to the occurrence of an
- // exception in a thread. Such messages are delivered to the exception port
- // set via thread_set_exception_ports or task_set_exception_ports. When an
- // exception occurs in a thread, the thread sends an exception message to
- // its exception port, blocking in the kernel waiting for the receipt of a
- // reply. The exc_server function performs all necessary argument handling
- // for this kernel message and calls catch_exception_raise,
- // catch_exception_raise_state or catch_exception_raise_state_identity,
- // which should handle the exception. If the called routine returns
- // KERN_SUCCESS, a reply message will be sent, allowing the thread to
- // continue from the point of the exception; otherwise, no reply message
- // is sent and the called routine must have dealt with the exception
- // thread directly.
- if (mach_exc_server(&exc_msg.hdr, &reply_msg.hdr)) {
- success = true;
- } else if (DNBLogCheckLogBit(LOG_EXCEPTIONS)) {
- DNBLogThreaded("mach_exc_server returned zero...");
- }
- g_message = NULL;
- return success;
-}
-
-kern_return_t MachException::Message::Reply(MachProcess *process, int signal) {
- // Reply to the exception...
- DNBError err;
-
- // If we had a soft signal, we need to update the thread first so it can
- // continue without signaling
- int soft_signal = state.SoftSignal();
- if (soft_signal) {
- int state_pid = -1;
- if (process->Task().TaskPort() == state.task_port) {
- // This is our task, so we can update the signal to send to it
- state_pid = process->ProcessID();
- soft_signal = signal;
- } else {
- err = ::pid_for_task(state.task_port, &state_pid);
- }
-
- assert(state_pid != -1);
- if (state_pid != -1) {
- errno = 0;
- if (::ptrace(PT_THUPDATE, state_pid,
- (caddr_t)((uintptr_t)state.thread_port), soft_signal) != 0)
- err.SetError(errno, DNBError::POSIX);
- else
- err.Clear();
-
- if (DNBLogCheckLogBit(LOG_EXCEPTIONS) || err.Fail())
- err.LogThreaded("::ptrace (request = PT_THUPDATE, pid = 0x%4.4x, tid = "
- "0x%4.4x, signal = %i)",
- state_pid, state.thread_port, soft_signal);
- }
- }
-
- DNBLogThreadedIf(
- LOG_EXCEPTIONS, "::mach_msg ( msg->{bits = %#x, size = %u, remote_port = "
- "%#x, local_port = %#x, reserved = 0x%x, id = 0x%x}, "
- "option = %#x, send_size = %u, rcv_size = %u, rcv_name = "
- "%#x, timeout = %u, notify = %#x)",
- reply_msg.hdr.msgh_bits, reply_msg.hdr.msgh_size,
- reply_msg.hdr.msgh_remote_port, reply_msg.hdr.msgh_local_port,
- reply_msg.hdr.msgh_reserved, reply_msg.hdr.msgh_id,
- MACH_SEND_MSG | MACH_SEND_INTERRUPT, reply_msg.hdr.msgh_size, 0,
- MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
-
- err = ::mach_msg(&reply_msg.hdr, MACH_SEND_MSG | MACH_SEND_INTERRUPT,
- reply_msg.hdr.msgh_size, 0, MACH_PORT_NULL,
- MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
-
- if (err.Fail()) {
- if (err.Status() == MACH_SEND_INTERRUPTED) {
- if (DNBLogCheckLogBit(LOG_EXCEPTIONS))
- err.LogThreaded("::mach_msg() - send interrupted");
- // TODO: keep retrying to reply???
- } else {
- if (state.task_port == process->Task().TaskPort()) {
- DNBLogThreaded("error: mach_msg() returned an error when replying to a "
- "mach exception: error = %u",
- err.Status());
- } else {
- if (DNBLogCheckLogBit(LOG_EXCEPTIONS))
- err.LogThreaded("::mach_msg() - failed (child of task)");
- }
- }
- }
-
- return err.Status();
-}
-
-void MachException::Data::Dump() const {
- const char *exc_type_name = MachException::Name(exc_type);
- DNBLogThreadedIf(
- LOG_EXCEPTIONS, " state { task_port = 0x%4.4x, thread_port = "
- "0x%4.4x, exc_type = %i (%s) ...",
- task_port, thread_port, exc_type, exc_type_name ? exc_type_name : "???");
-
- const size_t exc_data_count = exc_data.size();
- // Dump any special exception data contents
- int soft_signal = SoftSignal();
- if (soft_signal != 0) {
- const char *sig_str = SysSignal::Name(soft_signal);
- DNBLogThreadedIf(LOG_EXCEPTIONS,
- " exc_data: EXC_SOFT_SIGNAL (%i (%s))",
- soft_signal, sig_str ? sig_str : "unknown signal");
- } else {
- // No special disassembly for this data, just dump the data
- size_t idx;
- for (idx = 0; idx < exc_data_count; ++idx) {
- DNBLogThreadedIf(LOG_EXCEPTIONS, " exc_data[%llu]: 0x%llx",
- (uint64_t)idx, (uint64_t)exc_data[idx]);
- }
- }
-}
-
-// The EXC_MASK_ALL value hard-coded here so that lldb can be built
-// on a new OS with an older deployment target . The new OS may have
-// an addition to its EXC_MASK_ALL that the old OS will not recognize -
-// <mach/exception_types.h> doesn't vary the value based on the deployment
-// target. So we need a known set of masks that can be assumed to be
-// valid when running on an older OS. We'll fall back to trying
-// PREV_EXC_MASK_ALL if the EXC_MASK_ALL value lldb was compiled with is
-// not recognized.
-
-#define PREV_EXC_MASK_ALL (EXC_MASK_BAD_ACCESS | \
- EXC_MASK_BAD_INSTRUCTION | \
- EXC_MASK_ARITHMETIC | \
- EXC_MASK_EMULATION | \
- EXC_MASK_SOFTWARE | \
- EXC_MASK_BREAKPOINT | \
- EXC_MASK_SYSCALL | \
- EXC_MASK_MACH_SYSCALL | \
- EXC_MASK_RPC_ALERT | \
- EXC_MASK_RESOURCE | \
- EXC_MASK_GUARD | \
- EXC_MASK_MACHINE)
-
-#define LLDB_EXC_MASK EXC_MASK_ALL
-
-kern_return_t MachException::PortInfo::Save(task_t task) {
- DNBLogThreadedIf(LOG_EXCEPTIONS | LOG_VERBOSE,
- "MachException::PortInfo::Save ( task = 0x%4.4x )", task);
- // Be careful to be able to have debugserver built on a newer OS than what
- // it is currently running on by being able to start with all exceptions
- // and back off to just what is supported on the current system
- DNBError err;
-
- mask = LLDB_EXC_MASK;
-
- count = (sizeof(ports) / sizeof(ports[0]));
- err = ::task_get_exception_ports(task, mask, masks, &count, ports, behaviors,
- flavors);
- if (DNBLogCheckLogBit(LOG_EXCEPTIONS) || err.Fail())
- err.LogThreaded("::task_get_exception_ports ( task = 0x%4.4x, mask = 0x%x, "
- "maskCnt => %u, ports, behaviors, flavors )",
- task, mask, count);
-
- if (err.Status() == KERN_INVALID_ARGUMENT && mask != PREV_EXC_MASK_ALL) {
- mask = PREV_EXC_MASK_ALL;
- count = (sizeof(ports) / sizeof(ports[0]));
- err = ::task_get_exception_ports(task, mask, masks, &count, ports,
- behaviors, flavors);
- if (DNBLogCheckLogBit(LOG_EXCEPTIONS) || err.Fail())
- err.LogThreaded("::task_get_exception_ports ( task = 0x%4.4x, mask = "
- "0x%x, maskCnt => %u, ports, behaviors, flavors )",
- task, mask, count);
- }
- if (err.Fail()) {
- mask = 0;
- count = 0;
- }
- return err.Status();
-}
-
-kern_return_t MachException::PortInfo::Restore(task_t task) {
- DNBLogThreadedIf(LOG_EXCEPTIONS | LOG_VERBOSE,
- "MachException::PortInfo::Restore( task = 0x%4.4x )", task);
- uint32_t i = 0;
- DNBError err;
- if (count > 0) {
- for (i = 0; i < count; i++) {
- err = ::task_set_exception_ports(task, masks[i], ports[i], behaviors[i],
- flavors[i]);
- 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, masks[i], ports[i], behaviors[i], flavors[i]);
- // Bail if we encounter any errors
- }
-
- if (err.Fail())
- break;
- }
- }
- count = 0;
- return err.Status();
-}
-
-const char *MachException::Name(exception_type_t exc_type) {
- switch (exc_type) {
- case EXC_BAD_ACCESS:
- return "EXC_BAD_ACCESS";
- case EXC_BAD_INSTRUCTION:
- return "EXC_BAD_INSTRUCTION";
- case EXC_ARITHMETIC:
- return "EXC_ARITHMETIC";
- case EXC_EMULATION:
- return "EXC_EMULATION";
- case EXC_SOFTWARE:
- return "EXC_SOFTWARE";
- case EXC_BREAKPOINT:
- return "EXC_BREAKPOINT";
- case EXC_SYSCALL:
- return "EXC_SYSCALL";
- case EXC_MACH_SYSCALL:
- return "EXC_MACH_SYSCALL";
- case EXC_RPC_ALERT:
- return "EXC_RPC_ALERT";
- case EXC_CRASH:
- return "EXC_CRASH";
- case EXC_RESOURCE:
- return "EXC_RESOURCE";
-#ifdef EXC_GUARD
- case EXC_GUARD:
- return "EXC_GUARD";
-#endif
-#ifdef EXC_CORPSE_NOTIFY
- case EXC_CORPSE_NOTIFY:
- return "EXC_CORPSE_NOTIFY";
-#endif
-#ifdef EXC_CORPSE_VARIANT_BIT
- case EXC_CORPSE_VARIANT_BIT:
- return "EXC_CORPSE_VARIANT_BIT";
-#endif
- default:
- break;
- }
- return NULL;
-}
diff --git a/tools/debugserver/source/MacOSX/MachException.h b/tools/debugserver/source/MacOSX/MachException.h
deleted file mode 100644
index e1af12def10a..000000000000
--- a/tools/debugserver/source/MacOSX/MachException.h
+++ /dev/null
@@ -1,133 +0,0 @@
-//===-- MachException.h -----------------------------------------*- 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/18/07.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __MachException_h__
-#define __MachException_h__
-
-#include <mach/mach.h>
-#include <vector>
-
-class MachProcess;
-class PThreadMutex;
-
-typedef union MachMessageTag {
- mach_msg_header_t hdr;
- char data[1024];
-} MachMessage;
-
-class MachException {
-public:
- struct PortInfo {
- exception_mask_t mask; // the exception mask for this device which may be a
- // subset of EXC_MASK_ALL...
- exception_mask_t masks[EXC_TYPES_COUNT];
- mach_port_t ports[EXC_TYPES_COUNT];
- exception_behavior_t behaviors[EXC_TYPES_COUNT];
- thread_state_flavor_t flavors[EXC_TYPES_COUNT];
- mach_msg_type_number_t count;
-
- kern_return_t Save(task_t task);
- kern_return_t Restore(task_t task);
- };
-
- struct Data {
- task_t task_port;
- thread_t thread_port;
- exception_type_t exc_type;
- std::vector<mach_exception_data_type_t> exc_data;
- Data()
- : task_port(TASK_NULL), thread_port(THREAD_NULL), exc_type(0),
- exc_data() {}
-
- void Clear() {
- task_port = TASK_NULL;
- thread_port = THREAD_NULL;
- exc_type = 0;
- exc_data.clear();
- }
- bool IsValid() const {
- return task_port != TASK_NULL && thread_port != THREAD_NULL &&
- exc_type != 0;
- }
- // Return the SoftSignal for this MachException data, or zero if there is
- // none
- int SoftSignal() const {
- if (exc_type == EXC_SOFTWARE && exc_data.size() == 2 &&
- exc_data[0] == EXC_SOFT_SIGNAL)
- return static_cast<int>(exc_data[1]);
- return 0;
- }
- bool IsBreakpoint() const {
- return (exc_type == EXC_BREAKPOINT ||
- ((exc_type == EXC_SOFTWARE) && exc_data[0] == 1));
- }
- void AppendExceptionData(mach_exception_data_t Data,
- mach_msg_type_number_t Count) {
- mach_exception_data_type_t Buf;
- for (mach_msg_type_number_t i = 0; i < Count; ++i) {
- // Perform an unaligned copy.
- memcpy(&Buf, Data + i, sizeof(mach_exception_data_type_t));
- exc_data.push_back(Buf);
- }
- }
- void Dump() const;
- void DumpStopReason() const;
- bool GetStopInfo(struct DNBThreadStopInfo *stop_info) const;
- };
-
- struct Message {
- MachMessage exc_msg;
- MachMessage reply_msg;
- Data state;
-
- Message() : state() {
- memset(&exc_msg, 0, sizeof(exc_msg));
- memset(&reply_msg, 0, sizeof(reply_msg));
- }
- bool CatchExceptionRaise(task_t task);
- void Dump() const;
- kern_return_t Reply(MachProcess *process, int signal);
- kern_return_t Receive(mach_port_t receive_port, mach_msg_option_t options,
- mach_msg_timeout_t timeout,
- mach_port_t notify_port = MACH_PORT_NULL);
-
- typedef std::vector<Message> collection;
- typedef collection::iterator iterator;
- typedef collection::const_iterator const_iterator;
- };
-
- enum {
- e_actionForward, // Forward signal to inferior process
- e_actionStop, // Stop when this signal is received
- };
- struct Action {
- task_t task_port; // Set to TASK_NULL for any TASK
- thread_t thread_port; // Set to THREAD_NULL for any thread
- exception_type_t exc_mask; // Mach exception mask to watch for
- std::vector<mach_exception_data_type_t> exc_data_mask; // Mask to apply to
- // exception data, or
- // empty to ignore
- // exc_data value for
- // exception
- std::vector<mach_exception_data_type_t> exc_data_value; // Value to compare
- // to exception data
- // after masking, or
- // empty to ignore
- // exc_data value
- // for exception
- uint8_t flags; // Action flags describing what to do with the exception
- };
- static const char *Name(exception_type_t exc_type);
-};
-
-#endif
diff --git a/tools/debugserver/source/MacOSX/MachProcess.h b/tools/debugserver/source/MacOSX/MachProcess.h
deleted file mode 100644
index 2fb4dc5dbb6e..000000000000
--- a/tools/debugserver/source/MacOSX/MachProcess.h
+++ /dev/null
@@ -1,448 +0,0 @@
-//===-- MachProcess.h -------------------------------------------*- 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.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __MachProcess_h__
-#define __MachProcess_h__
-
-#include <CoreFoundation/CoreFoundation.h>
-#include <mach-o/loader.h>
-#include <mach/mach.h>
-#include <pthread.h>
-#include <sys/signal.h>
-#include <uuid/uuid.h>
-#include <vector>
-
-#include "DNBBreakpoint.h"
-#include "DNBDefs.h"
-#include "DNBError.h"
-#include "DNBThreadResumeActions.h"
-#include "Genealogy.h"
-#include "JSONGenerator.h"
-#include "MachException.h"
-#include "MachTask.h"
-#include "MachThreadList.h"
-#include "MachVMMemory.h"
-#include "PThreadCondition.h"
-#include "PThreadEvent.h"
-#include "PThreadMutex.h"
-#include "ThreadInfo.h"
-
-class DNBThreadResumeActions;
-
-class MachProcess {
-public:
- //----------------------------------------------------------------------
- // Constructors and Destructors
- //----------------------------------------------------------------------
- MachProcess();
- ~MachProcess();
-
- // A structure that can hold everything debugserver needs to know from
- // a binary's Mach-O header / load commands.
-
- struct mach_o_segment {
- std::string name;
- uint64_t vmaddr;
- uint64_t vmsize;
- uint64_t fileoff;
- uint64_t filesize;
- uint64_t maxprot;
- uint64_t initprot;
- uint64_t nsects;
- uint64_t flags;
- };
-
- struct mach_o_information {
- struct mach_header_64 mach_header;
- std::vector<struct mach_o_segment> segments;
- uuid_t uuid;
- std::string min_version_os_name;
- std::string min_version_os_version;
- };
-
- struct binary_image_information {
- std::string filename;
- uint64_t load_address;
- uint64_t mod_date; // may not be available - 0 if so
- struct mach_o_information macho_info;
-
- binary_image_information()
- : filename(), load_address(INVALID_NUB_ADDRESS), mod_date(0) {}
- };
-
- //----------------------------------------------------------------------
- // Child process control
- //----------------------------------------------------------------------
- pid_t AttachForDebug(pid_t pid, char *err_str, size_t err_len);
- pid_t LaunchForDebug(const char *path, 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, nub_launch_flavor_t launch_flavor,
- int disable_aslr, const char *event_data, DNBError &err);
-
- static uint32_t GetCPUTypeForLocalProcess(pid_t pid);
- static pid_t ForkChildForPTraceDebugging(const char *path, char const *argv[],
- char const *envp[],
- MachProcess *process, DNBError &err);
- static pid_t 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);
- nub_addr_t GetDYLDAllImageInfosAddress();
- 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,
- nub_launch_flavor_t launch_flavor,
- bool success, DNBError &err_str);
- static nub_process_t CheckForProcess(const void *attach_token,
- nub_launch_flavor_t launch_flavor);
-#if defined(WITH_BKS) || defined(WITH_FBS)
- pid_t BoardServiceLaunchForDebug(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 BoardServiceForkChildForPTraceDebugging(
- const char *path, char const *argv[], char const *envp[], bool no_stdio,
- bool disable_aslr, const char *event_data, DNBError &launch_err);
- bool BoardServiceSendEvent(const char *event, DNBError &error);
-#endif
- static bool GetOSVersionNumbers(uint64_t *major, uint64_t *minor,
- uint64_t *patch);
-#ifdef WITH_BKS
- static void BKSCleanupAfterAttach(const void *attach_token,
- DNBError &err_str);
-#endif // WITH_BKS
-#ifdef WITH_FBS
- static void FBSCleanupAfterAttach(const void *attach_token,
- DNBError &err_str);
-#endif // WITH_FBS
-#ifdef WITH_SPRINGBOARD
- 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 // WITH_SPRINGBOARD
- nub_addr_t LookupSymbol(const char *name, const char *shlib);
- void SetNameToAddressCallback(DNBCallbackNameToAddress callback,
- void *baton) {
- m_name_to_addr_callback = callback;
- m_name_to_addr_baton = baton;
- }
- void
- SetSharedLibraryInfoCallback(DNBCallbackCopyExecutableImageInfos callback,
- void *baton) {
- m_image_infos_callback = callback;
- m_image_infos_baton = baton;
- }
-
- bool Resume(const DNBThreadResumeActions &thread_actions);
- bool Signal(int signal, const struct timespec *timeout_abstime = NULL);
- bool Interrupt();
- 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);
- nub_size_t WriteMemory(nub_addr_t addr, nub_size_t size, const void *buf);
-
- //----------------------------------------------------------------------
- // Path and arg accessors
- //----------------------------------------------------------------------
- const char *Path() const { return m_path.c_str(); }
- size_t ArgumentCount() const { return m_args.size(); }
- const char *ArgumentAtIndex(size_t arg_idx) const {
- if (arg_idx < m_args.size())
- return m_args[arg_idx].c_str();
- return NULL;
- }
-
- //----------------------------------------------------------------------
- // Breakpoint functions
- //----------------------------------------------------------------------
- DNBBreakpoint *CreateBreakpoint(nub_addr_t addr, nub_size_t length,
- bool hardware);
- bool DisableBreakpoint(nub_addr_t addr, bool remove);
- void DisableAllBreakpoints(bool remove);
- bool EnableBreakpoint(nub_addr_t addr);
- DNBBreakpointList &Breakpoints() { return m_breakpoints; }
- const DNBBreakpointList &Breakpoints() const { return m_breakpoints; }
-
- //----------------------------------------------------------------------
- // Watchpoint functions
- //----------------------------------------------------------------------
- DNBBreakpoint *CreateWatchpoint(nub_addr_t addr, nub_size_t length,
- uint32_t watch_type, bool hardware);
- bool DisableWatchpoint(nub_addr_t addr, bool remove);
- void DisableAllWatchpoints(bool remove);
- bool EnableWatchpoint(nub_addr_t addr);
- uint32_t GetNumSupportedHardwareWatchpoints() const;
- DNBBreakpointList &Watchpoints() { return m_watchpoints; }
- const DNBBreakpointList &Watchpoints() const { return m_watchpoints; }
-
- //----------------------------------------------------------------------
- // Exception thread functions
- //----------------------------------------------------------------------
- bool StartSTDIOThread();
- static void *STDIOThread(void *arg);
- void ExceptionMessageReceived(const MachException::Message &exceptionMessage);
- task_t ExceptionMessageBundleComplete();
- void SharedLibrariesUpdated();
- nub_size_t CopyImageInfos(struct DNBExecutableImageInfo **image_infos,
- bool only_changed);
-
- //----------------------------------------------------------------------
- // Profile functions
- //----------------------------------------------------------------------
- void SetEnableAsyncProfiling(bool enable, uint64_t internal_usec,
- DNBProfileDataScanType scan_type);
- bool IsProfilingEnabled() { return m_profile_enabled; }
- useconds_t ProfileInterval() { return m_profile_interval_usec; }
- bool StartProfileThread();
- static void *ProfileThread(void *arg);
- void SignalAsyncProfileData(const char *info);
- size_t GetAsyncProfileData(char *buf, size_t buf_size);
-
- //----------------------------------------------------------------------
- // Accessors
- //----------------------------------------------------------------------
- pid_t ProcessID() const { return m_pid; }
- bool ProcessIDIsValid() const { return m_pid > 0; }
- pid_t SetProcessID(pid_t pid);
- MachTask &Task() { return m_task; }
- const MachTask &Task() const { return m_task; }
-
- PThreadEvent &Events() { return m_events; }
- const DNBRegisterSetInfo *GetRegisterSetInfo(nub_thread_t tid,
- nub_size_t *num_reg_sets) const;
- bool GetRegisterValue(nub_thread_t tid, uint32_t set, uint32_t reg,
- DNBRegisterValue *reg_value) const;
- bool SetRegisterValue(nub_thread_t tid, uint32_t set, uint32_t reg,
- const DNBRegisterValue *value) const;
- nub_bool_t SyncThreadState(nub_thread_t tid);
- const char *ThreadGetName(nub_thread_t tid);
- nub_state_t ThreadGetState(nub_thread_t tid);
- ThreadInfo::QoS GetRequestedQoS(nub_thread_t tid, nub_addr_t tsd,
- uint64_t dti_qos_class_index);
- nub_addr_t GetPThreadT(nub_thread_t tid);
- nub_addr_t GetDispatchQueueT(nub_thread_t tid);
- nub_addr_t
- GetTSDAddressForThread(nub_thread_t tid,
- uint64_t plo_pthread_tsd_base_address_offset,
- uint64_t plo_pthread_tsd_base_offset,
- uint64_t plo_pthread_tsd_entry_size);
- const char *
- GetDeploymentInfo(const struct load_command&, uint64_t load_command_address,
- uint32_t& major_version, uint32_t& minor_version,
- uint32_t& patch_version);
- bool GetMachOInformationFromMemory(nub_addr_t mach_o_header_addr,
- int wordsize,
- struct mach_o_information &inf);
- JSONGenerator::ObjectSP FormatDynamicLibrariesIntoJSON(
- const std::vector<struct binary_image_information> &image_infos);
- void GetAllLoadedBinariesViaDYLDSPI(
- std::vector<struct binary_image_information> &image_infos);
- JSONGenerator::ObjectSP GetLoadedDynamicLibrariesInfos(
- nub_process_t pid, nub_addr_t image_list_address, nub_addr_t image_count);
- JSONGenerator::ObjectSP
- GetLibrariesInfoForAddresses(nub_process_t pid,
- std::vector<uint64_t> &macho_addresses);
- JSONGenerator::ObjectSP GetAllLoadedLibrariesInfos(nub_process_t pid);
- JSONGenerator::ObjectSP GetSharedCacheInfo(nub_process_t pid);
-
- nub_size_t GetNumThreads() const;
- nub_thread_t GetThreadAtIndex(nub_size_t thread_idx) const;
- nub_thread_t GetCurrentThread();
- nub_thread_t GetCurrentThreadMachPort();
- nub_thread_t SetCurrentThread(nub_thread_t tid);
- MachThreadList &GetThreadList() { return m_thread_list; }
- bool GetThreadStoppedReason(nub_thread_t tid,
- struct DNBThreadStopInfo *stop_info);
- void DumpThreadStoppedReason(nub_thread_t tid) const;
- const char *GetThreadInfo(nub_thread_t tid) const;
-
- nub_thread_t GetThreadIDForMachPortNumber(thread_t mach_port_number) const;
-
- uint32_t GetCPUType();
- nub_state_t GetState();
- void SetState(nub_state_t state);
- bool IsRunning(nub_state_t state) {
- return state == eStateRunning || IsStepping(state);
- }
- bool IsStepping(nub_state_t state) { return state == eStateStepping; }
- bool CanResume(nub_state_t state) { return state == eStateStopped; }
-
- bool GetExitStatus(int *status) {
- if (GetState() == eStateExited) {
- if (status)
- *status = m_exit_status;
- return true;
- }
- return false;
- }
- void SetExitStatus(int status) {
- m_exit_status = status;
- SetState(eStateExited);
- }
- const char *GetExitInfo() { return m_exit_info.c_str(); }
-
- void SetExitInfo(const char *info);
-
- uint32_t StopCount() const { return m_stop_count; }
- void SetChildFileDescriptors(int stdin_fileno, int stdout_fileno,
- int stderr_fileno) {
- m_child_stdin = stdin_fileno;
- m_child_stdout = stdout_fileno;
- m_child_stderr = stderr_fileno;
- }
-
- int GetStdinFileDescriptor() const { return m_child_stdin; }
- int GetStdoutFileDescriptor() const { return m_child_stdout; }
- int GetStderrFileDescriptor() const { return m_child_stderr; }
- void AppendSTDOUT(char *s, size_t len);
- size_t GetAvailableSTDOUT(char *buf, size_t buf_size);
- size_t GetAvailableSTDERR(char *buf, size_t buf_size);
- void CloseChildFileDescriptors() {
- if (m_child_stdin >= 0) {
- ::close(m_child_stdin);
- m_child_stdin = -1;
- }
- if (m_child_stdout >= 0) {
- ::close(m_child_stdout);
- m_child_stdout = -1;
- }
- if (m_child_stderr >= 0) {
- ::close(m_child_stderr);
- m_child_stderr = -1;
- }
- }
-
- bool ProcessUsingSpringBoard() const {
- return (m_flags & eMachProcessFlagsUsingSBS) != 0;
- }
- bool ProcessUsingBackBoard() const {
- return (m_flags & eMachProcessFlagsUsingBKS) != 0;
- }
-
- Genealogy::ThreadActivitySP GetGenealogyInfoForThread(nub_thread_t tid,
- bool &timed_out);
-
- Genealogy::ProcessExecutableInfoSP GetGenealogyImageInfo(size_t idx);
-
- DNBProfileDataScanType GetProfileScanType() { return m_profile_scan_type; }
-
-private:
- enum {
- eMachProcessFlagsNone = 0,
- eMachProcessFlagsAttached = (1 << 0),
- eMachProcessFlagsUsingSBS = (1 << 1),
- eMachProcessFlagsUsingBKS = (1 << 2),
- eMachProcessFlagsUsingFBS = (1 << 3)
- };
- void Clear(bool detaching = false);
- void ReplyToAllExceptions();
- void PrivateResume();
-
- uint32_t Flags() const { return m_flags; }
- nub_state_t DoSIGSTOP(bool clear_bps_and_wps, bool allow_running,
- uint32_t *thread_idx_ptr);
-
- pid_t m_pid; // Process ID of child process
- cpu_type_t m_cpu_type; // The CPU type of this process
- int m_child_stdin;
- int m_child_stdout;
- int m_child_stderr;
- 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
- pthread_t m_stdio_thread; // Thread ID for the thread that watches for child
- // process stdio
- PThreadMutex m_stdio_mutex; // Multithreaded protection for stdio
- std::string m_stdout_data;
-
- bool m_profile_enabled; // A flag to indicate if profiling is enabled
- useconds_t m_profile_interval_usec; // If enable, the profiling interval in
- // microseconds
- DNBProfileDataScanType
- m_profile_scan_type; // Indicates what needs to be profiled
- pthread_t
- m_profile_thread; // Thread ID for the thread that profiles the inferior
- PThreadMutex
- m_profile_data_mutex; // Multithreaded protection for profile info data
- std::vector<std::string>
- m_profile_data; // Profile data, must be protected by m_profile_data_mutex
-
- DNBThreadResumeActions m_thread_actions; // The thread actions for the current
- // MachProcess::Resume() call
- MachException::Message::collection m_exception_messages; // A collection of
- // exception messages
- // caught when
- // listening to the
- // exception port
- PThreadMutex m_exception_messages_mutex; // Multithreaded protection for
- // m_exception_messages
-
- MachThreadList m_thread_list; // A list of threads that is maintained/updated
- // after each stop
- Genealogy m_activities; // A list of activities that is updated after every
- // stop lazily
- nub_state_t m_state; // The state of our process
- PThreadMutex m_state_mutex; // Multithreaded protection for m_state
- PThreadEvent m_events; // Process related events in the child processes
- // lifetime can be waited upon
- PThreadEvent m_private_events; // Used to coordinate running and stopping the
- // process without affecting m_events
- DNBBreakpointList m_breakpoints; // Breakpoint list for this process
- DNBBreakpointList m_watchpoints; // Watchpoint list for this process
- DNBCallbackNameToAddress m_name_to_addr_callback;
- void *m_name_to_addr_baton;
- 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.
- int m_sent_interrupt_signo; // When we call MachProcess::Interrupt(), we want
- // to send a single signal
- // to the inferior and only send the signal if we aren't already stopped.
- // If we end up sending a signal to stop the process we store it until we
- // receive an exception with this signal. This helps us to verify we got
- // the signal that interrupted the process. We might stop due to another
- // reason after an interrupt signal is sent, so this helps us ensure that
- // we don't report a spurious stop on the next resume.
- int m_auto_resume_signo; // If we resume the process and still haven't
- // received our interrupt signal
- // acknownledgement, we will shortly after the next resume. We store the
- // interrupt signal in this variable so when we get the interrupt signal
- // as the sole reason for the process being stopped, we can auto resume
- // the process.
- bool m_did_exec;
-
- void *(*m_dyld_process_info_create)(task_t task, uint64_t timestamp,
- kern_return_t *kernelError);
- void (*m_dyld_process_info_for_each_image)(
- void *info, void (^callback)(uint64_t machHeaderAddress,
- const uuid_t uuid, const char *path));
- void (*m_dyld_process_info_release)(void *info);
- void (*m_dyld_process_info_get_cache)(void *info, void *cacheInfo);
-};
-
-#endif // __MachProcess_h__
diff --git a/tools/debugserver/source/MacOSX/MachProcess.mm b/tools/debugserver/source/MacOSX/MachProcess.mm
deleted file mode 100644
index a3b905d05150..000000000000
--- a/tools/debugserver/source/MacOSX/MachProcess.mm
+++ /dev/null
@@ -1,3919 +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 "MacOSX/CFUtils.h"
-#include "SysSignal.h"
-#include <dlfcn.h>
-#include <inttypes.h>
-#include <mach-o/loader.h>
-#include <mach/mach.h>
-#include <mach/task.h>
-#include <pthread.h>
-#include <signal.h>
-#include <spawn.h>
-#include <sys/fcntl.h>
-#include <sys/ptrace.h>
-#include <sys/stat.h>
-#include <sys/sysctl.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <uuid/uuid.h>
-
-#include <algorithm>
-#include <map>
-
-#import <Foundation/Foundation.h>
-
-#include "DNBDataRef.h"
-#include "DNBLog.h"
-#include "DNBThreadResumeActions.h"
-#include "DNBTimer.h"
-#include "MachProcess.h"
-#include "PseudoTerminal.h"
-
-#include "CFBundle.h"
-#include "CFString.h"
-
-#ifdef WITH_SPRINGBOARD
-
-#include <CoreFoundation/CoreFoundation.h>
-#include <SpringBoardServices/SBSWatchdogAssertion.h>
-#include <SpringBoardServices/SpringBoardServer.h>
-
-static bool IsSBProcess(nub_process_t pid) {
- CFReleaser<CFArrayRef> appIdsForPID(
- ::SBSCopyDisplayIdentifiersForProcessID(pid));
- return appIdsForPID.get() != NULL;
-}
-
-#endif // WITH_SPRINGBOARD
-
-#if defined(WITH_SPRINGBOARD) || defined(WITH_BKS) || defined(WITH_FBS)
-// 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);
-#endif
-
-#if defined(WITH_BKS) || defined(WITH_FBS)
-#import <Foundation/Foundation.h>
-static const int OPEN_APPLICATION_TIMEOUT_ERROR = 111;
-typedef void (*SetErrorFunction)(NSInteger, DNBError &);
-typedef bool (*CallOpenApplicationFunction)(NSString *bundleIDNSStr,
- NSDictionary *options,
- DNBError &error, pid_t *return_pid);
-// This function runs the BKSSystemService (or FBSSystemService) 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.
-
-template <typename OpenFlavor, typename ErrorFlavor,
- ErrorFlavor no_error_enum_value, SetErrorFunction error_function>
-static bool CallBoardSystemServiceOpenApplication(NSString *bundleIDNSStr,
- NSDictionary *options,
- DNBError &error,
- pid_t *return_pid) {
- // Now make our systemService:
- OpenFlavor *system_service = [[OpenFlavor 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 ErrorFlavor open_app_error = no_error_enum_value;
- bool wants_pid = (return_pid != NULL);
- __block pid_t pid_in_block;
-
- const char *cstr = [bundleIDNSStr UTF8String];
- if (!cstr)
- cstr = "<Unknown Bundle ID>";
-
- NSString *description = [options description];
- DNBLog("About to launch process for bundle ID: %s - options:\n%s", cstr,
- [description UTF8String]);
- [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 = (ErrorFlavor)[bks_error code];
-
- if (open_app_error == no_error_enum_value) {
- 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 =
- [(NSString *)[bks_error localizedDescription] UTF8String];
- DNBLogThreadedIf(LOG_PROCESS, "In completion handler for send "
- "event, got error \"%s\"(%ld).",
- error_str ? error_str : "<unknown error>",
- open_app_error);
- // REMOVE ME
- DNBLogError("In completion handler for send event, got error "
- "\"%s\"(%ld).",
- error_str ? error_str : "<unknown error>",
- open_app_error);
- }
-
- [system_service release];
- dispatch_semaphore_signal(semaphore);
- }
-
- ];
-
- const uint32_t timeout_secs = 30;
-
- 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(OPEN_APPLICATION_TIMEOUT_ERROR, DNBError::Generic);
- error.SetErrorString("timed out trying to launch app");
- } else if (open_app_error != no_error_enum_value) {
- error_function(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;
-}
-#endif
-
-#if defined(WITH_BKS) || defined(WITH_FBS)
-static void SplitEventData(const char *data, std::vector<std::string> &elements)
-{
- elements.clear();
- if (!data)
- return;
-
- const char *start = data;
-
- while (*start != '\0') {
- const char *token = strchr(start, ':');
- if (!token) {
- elements.push_back(std::string(start));
- return;
- }
- if (token != start)
- elements.push_back(std::string(start, token - start));
- start = ++token;
- }
-}
-#endif
-
-#ifdef WITH_BKS
-#import <Foundation/Foundation.h>
-extern "C" {
-#import <BackBoardServices/BKSOpenApplicationConstants_Private.h>
-#import <BackBoardServices/BKSSystemService_LaunchServices.h>
-#import <BackBoardServices/BackBoardServices.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(NSInteger error_code, DNBError &error) {
- error.SetError(error_code, DNBError::BackBoard);
- NSString *err_nsstr = ::BKSOpenApplicationErrorCodeToString(
- (BKSOpenApplicationErrorCode)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 bool BKSAddEventDataToOptions(NSMutableDictionary *options,
- const char *event_data,
- DNBError &option_error) {
- std::vector<std::string> values;
- SplitEventData(event_data, values);
- bool found_one = false;
- for (std::string value : values)
- {
- if (value.compare("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];
- found_one = true;
- } else if (value.compare("ActivateSuspended") == 0) {
- DNBLog("Setting ActivateSuspended key in options dictionary.");
- [options setObject:@YES forKey: BKSOpenApplicationOptionKeyActivateSuspended];
- found_one = true;
- } else {
- DNBLogError("Unrecognized event type: %s. Ignoring.", value.c_str());
- option_error.SetErrorString("Unrecognized event data");
- }
- }
- return found_one;
-}
-
-static NSMutableDictionary *BKSCreateOptionsDictionary(
- const char *app_bundle_path, NSMutableArray *launch_argv,
- NSMutableDictionary *launch_envp, NSString *stdio_path, bool disable_aslr,
- const char *event_data) {
- 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];
- // And there are some other options at the top level in this dictionary:
- [options setObject:[NSNumber numberWithBool:YES]
- forKey:BKSOpenApplicationOptionKeyUnlockDevice];
-
- DNBError error;
- BKSAddEventDataToOptions(options, event_data, error);
-
- return options;
-}
-
-static CallOpenApplicationFunction BKSCallOpenApplicationFunction =
- CallBoardSystemServiceOpenApplication<
- BKSSystemService, BKSOpenApplicationErrorCode,
- BKSOpenApplicationErrorCodeNone, SetBKSError>;
-#endif // WITH_BKS
-
-#ifdef WITH_FBS
-#import <Foundation/Foundation.h>
-extern "C" {
-#import <FrontBoardServices/FBSOpenApplicationConstants_Private.h>
-#import <FrontBoardServices/FBSSystemService_LaunchServices.h>
-#import <FrontBoardServices/FrontBoardServices.h>
-#import <MobileCoreServices/LSResourceProxy.h>
-#import <MobileCoreServices/MobileCoreServices.h>
-}
-
-#ifdef WITH_BKS
-static bool IsFBSProcess(nub_process_t pid) {
- BKSApplicationStateMonitor *state_monitor =
- [[BKSApplicationStateMonitor alloc] init];
- BKSApplicationState app_state =
- [state_monitor mostElevatedApplicationStateForPID:pid];
- return app_state != BKSApplicationStateUnknown;
-}
-#else
-static bool IsFBSProcess(nub_process_t pid) {
- // FIXME: What is the FBS equivalent of BKSApplicationStateMonitor
- return true;
-}
-#endif
-
-static void SetFBSError(NSInteger error_code, DNBError &error) {
- error.SetError((DNBError::ValueType)error_code, DNBError::FrontBoard);
- NSString *err_nsstr = ::FBSOpenApplicationErrorCodeToString(
- (FBSOpenApplicationErrorCode)error_code);
- const char *err_str = NULL;
- if (err_nsstr == NULL)
- err_str = "unknown FBS error";
- else {
- err_str = [err_nsstr UTF8String];
- if (err_str == NULL)
- err_str = "unknown FBS error";
- }
- error.SetErrorString(err_str);
-}
-
-static bool FBSAddEventDataToOptions(NSMutableDictionary *options,
- const char *event_data,
- DNBError &option_error) {
- std::vector<std::string> values;
- SplitEventData(event_data, values);
- bool found_one = false;
- for (std::string value : values)
- {
- if (value.compare("BackgroundContentFetching") == 0) {
- DNBLog("Setting ActivateForEvent key in options dictionary.");
- NSDictionary *event_details = [NSDictionary dictionary];
- NSDictionary *event_dictionary = [NSDictionary
- dictionaryWithObject:event_details
- forKey:
- FBSActivateForEventOptionTypeBackgroundContentFetching];
- [options setObject:event_dictionary
- forKey:FBSOpenApplicationOptionKeyActivateForEvent];
- found_one = true;
- } else if (value.compare("ActivateSuspended") == 0) {
- DNBLog("Setting ActivateSuspended key in options dictionary.");
- [options setObject:@YES forKey: FBSOpenApplicationOptionKeyActivateSuspended];
- found_one = true;
- } else {
- DNBLogError("Unrecognized event type: %s. Ignoring.", value.c_str());
- option_error.SetErrorString("Unrecognized event data.");
- }
- }
- return found_one;
-}
-
-static NSMutableDictionary *
-FBSCreateOptionsDictionary(const char *app_bundle_path,
- NSMutableArray *launch_argv,
- NSDictionary *launch_envp, NSString *stdio_path,
- bool disable_aslr, const char *event_data) {
- NSMutableDictionary *debug_options = [NSMutableDictionary dictionary];
-
- if (launch_argv != nil)
- [debug_options setObject:launch_argv forKey:FBSDebugOptionKeyArguments];
- if (launch_envp != nil)
- [debug_options setObject:launch_envp forKey:FBSDebugOptionKeyEnvironment];
-
- [debug_options setObject:stdio_path forKey:FBSDebugOptionKeyStandardOutPath];
- [debug_options setObject:stdio_path
- forKey:FBSDebugOptionKeyStandardErrorPath];
- [debug_options setObject:[NSNumber numberWithBool:YES]
- forKey:FBSDebugOptionKeyWaitForDebugger];
- if (disable_aslr)
- [debug_options setObject:[NSNumber numberWithBool:YES]
- forKey:FBSDebugOptionKeyDisableASLR];
-
- // That will go in the overall dictionary:
-
- NSMutableDictionary *options = [NSMutableDictionary dictionary];
- [options setObject:debug_options
- forKey:FBSOpenApplicationOptionKeyDebuggingOptions];
- // And there are some other options at the top level in this dictionary:
- [options setObject:[NSNumber numberWithBool:YES]
- forKey:FBSOpenApplicationOptionKeyUnlockDevice];
-
- // We have to get the "sequence ID & UUID" for this app bundle path and send
- // them to FBS:
-
- NSURL *app_bundle_url =
- [NSURL fileURLWithPath:[NSString stringWithUTF8String:app_bundle_path]
- isDirectory:YES];
- LSApplicationProxy *app_proxy =
- [LSApplicationProxy applicationProxyForBundleURL:app_bundle_url];
- if (app_proxy) {
- DNBLog("Sending AppProxy info: sequence no: %lu, GUID: %s.",
- app_proxy.sequenceNumber,
- [app_proxy.cacheGUID.UUIDString UTF8String]);
- [options
- setObject:[NSNumber numberWithUnsignedInteger:app_proxy.sequenceNumber]
- forKey:FBSOpenApplicationOptionKeyLSSequenceNumber];
- [options setObject:app_proxy.cacheGUID.UUIDString
- forKey:FBSOpenApplicationOptionKeyLSCacheGUID];
- }
-
- DNBError error;
- FBSAddEventDataToOptions(options, event_data, error);
-
- return options;
-}
-static CallOpenApplicationFunction FBSCallOpenApplicationFunction =
- CallBoardSystemServiceOpenApplication<
- FBSSystemService, FBSOpenApplicationErrorCode,
- FBSOpenApplicationErrorCodeNone, SetFBSError>;
-#endif // WITH_FBS
-
-#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_profile_enabled(false), m_profile_interval_usec(0), m_profile_thread(0),
- m_profile_data_mutex(PTHREAD_MUTEX_RECURSIVE), m_profile_data(),
- m_thread_actions(), m_exception_messages(),
- m_exception_messages_mutex(PTHREAD_MUTEX_RECURSIVE), m_thread_list(),
- m_activities(), 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_sent_interrupt_signo(0), m_auto_resume_signo(0), m_did_exec(false),
- m_dyld_process_info_create(nullptr),
- m_dyld_process_info_for_each_image(nullptr),
- m_dyld_process_info_release(nullptr),
- m_dyld_process_info_get_cache(nullptr) {
- m_dyld_process_info_create =
- (void *(*)(task_t task, uint64_t timestamp, kern_return_t * kernelError))
- dlsym(RTLD_DEFAULT, "_dyld_process_info_create");
- m_dyld_process_info_for_each_image =
- (void (*)(void *info, void (^)(uint64_t machHeaderAddress,
- const uuid_t uuid, const char *path)))
- dlsym(RTLD_DEFAULT, "_dyld_process_info_for_each_image");
- m_dyld_process_info_release =
- (void (*)(void *info))dlsym(RTLD_DEFAULT, "_dyld_process_info_release");
- m_dyld_process_info_get_cache = (void (*)(void *info, void *cacheInfo))dlsym(
- RTLD_DEFAULT, "_dyld_process_info_get_cache");
-
- 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 actually 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;
-}
-
-ThreadInfo::QoS MachProcess::GetRequestedQoS(nub_thread_t tid, nub_addr_t tsd,
- uint64_t dti_qos_class_index) {
- return m_thread_list.GetRequestedQoS(tid, tsd, dti_qos_class_index);
-}
-
-nub_addr_t MachProcess::GetPThreadT(nub_thread_t tid) {
- return m_thread_list.GetPThreadT(tid);
-}
-
-nub_addr_t MachProcess::GetDispatchQueueT(nub_thread_t tid) {
- return m_thread_list.GetDispatchQueueT(tid);
-}
-
-nub_addr_t MachProcess::GetTSDAddressForThread(
- nub_thread_t tid, uint64_t plo_pthread_tsd_base_address_offset,
- uint64_t plo_pthread_tsd_base_offset, uint64_t plo_pthread_tsd_entry_size) {
- return m_thread_list.GetTSDAddressForThread(
- tid, plo_pthread_tsd_base_address_offset, plo_pthread_tsd_base_offset,
- plo_pthread_tsd_entry_size);
-}
-
-
-const char *MachProcess::GetDeploymentInfo(const struct load_command& lc,
- uint64_t load_command_address,
- uint32_t& major_version,
- uint32_t& minor_version,
- uint32_t& patch_version) {
- uint32_t cmd = lc.cmd & ~LC_REQ_DYLD;
- bool lc_cmd_known =
- cmd == LC_VERSION_MIN_IPHONEOS || cmd == LC_VERSION_MIN_MACOSX ||
- cmd == LC_VERSION_MIN_TVOS || cmd == LC_VERSION_MIN_WATCHOS;
-
- if (lc_cmd_known) {
- struct version_min_command vers_cmd;
- if (ReadMemory(load_command_address, sizeof(struct version_min_command),
- &vers_cmd) != sizeof(struct version_min_command)) {
- return nullptr;
- }
- major_version = vers_cmd.sdk >> 16;
- minor_version = (vers_cmd.sdk >> 8) & 0xffu;
- patch_version = vers_cmd.sdk & 0xffu;
-
- switch (cmd) {
- case LC_VERSION_MIN_IPHONEOS:
- return "ios";
- case LC_VERSION_MIN_MACOSX:
- return "macosx";
- case LC_VERSION_MIN_TVOS:
- return "tvos";
- case LC_VERSION_MIN_WATCHOS:
- return "watchos";
- default:
- return nullptr;
- }
- }
-#if defined (LC_BUILD_VERSION)
-#ifndef PLATFORM_IOSSIMULATOR
-#define PLATFORM_IOSSIMULATOR 7
-#define PLATFORM_TVOSSIMULATOR 8
-#define PLATFORM_WATCHOSSIMULATOR 9
-#endif
- if (cmd == LC_BUILD_VERSION) {
- struct build_version_command build_vers;
- if (ReadMemory(load_command_address, sizeof(struct build_version_command),
- &build_vers) != sizeof(struct build_version_command)) {
- return nullptr;
- }
- major_version = build_vers.sdk >> 16;;
- minor_version = (build_vers.sdk >> 8) & 0xffu;
- patch_version = build_vers.sdk & 0xffu;
-
- switch (build_vers.platform) {
- case PLATFORM_MACOS:
- return "macosx";
- case PLATFORM_IOS:
- case PLATFORM_IOSSIMULATOR:
- return "ios";
- case PLATFORM_TVOS:
- case PLATFORM_TVOSSIMULATOR:
- return "tvos";
- case PLATFORM_WATCHOS:
- case PLATFORM_WATCHOSSIMULATOR:
- return "watchos";
- case PLATFORM_BRIDGEOS:
- return "bridgeos";
- }
- }
-#endif
- return nullptr;
-}
-
-// Given an address, read the mach-o header and load commands out of memory to
-// fill in
-// the mach_o_information "inf" object.
-//
-// Returns false if there was an error in reading this mach-o file header/load
-// commands.
-
-bool MachProcess::GetMachOInformationFromMemory(
- nub_addr_t mach_o_header_addr, int wordsize,
- struct mach_o_information &inf) {
- uint64_t load_cmds_p;
- if (wordsize == 4) {
- struct mach_header header;
- if (ReadMemory(mach_o_header_addr, sizeof(struct mach_header), &header) !=
- sizeof(struct mach_header)) {
- return false;
- }
- load_cmds_p = mach_o_header_addr + sizeof(struct mach_header);
- inf.mach_header.magic = header.magic;
- inf.mach_header.cputype = header.cputype;
- // high byte of cpusubtype is used for "capability bits", v.
- // CPU_SUBTYPE_MASK, CPU_SUBTYPE_LIB64 in machine.h
- inf.mach_header.cpusubtype = header.cpusubtype & 0x00ffffff;
- inf.mach_header.filetype = header.filetype;
- inf.mach_header.ncmds = header.ncmds;
- inf.mach_header.sizeofcmds = header.sizeofcmds;
- inf.mach_header.flags = header.flags;
- } else {
- struct mach_header_64 header;
- if (ReadMemory(mach_o_header_addr, sizeof(struct mach_header_64),
- &header) != sizeof(struct mach_header_64)) {
- return false;
- }
- load_cmds_p = mach_o_header_addr + sizeof(struct mach_header_64);
- inf.mach_header.magic = header.magic;
- inf.mach_header.cputype = header.cputype;
- // high byte of cpusubtype is used for "capability bits", v.
- // CPU_SUBTYPE_MASK, CPU_SUBTYPE_LIB64 in machine.h
- inf.mach_header.cpusubtype = header.cpusubtype & 0x00ffffff;
- inf.mach_header.filetype = header.filetype;
- inf.mach_header.ncmds = header.ncmds;
- inf.mach_header.sizeofcmds = header.sizeofcmds;
- inf.mach_header.flags = header.flags;
- }
- for (uint32_t j = 0; j < inf.mach_header.ncmds; j++) {
- struct load_command lc;
- if (ReadMemory(load_cmds_p, sizeof(struct load_command), &lc) !=
- sizeof(struct load_command)) {
- return false;
- }
- if (lc.cmd == LC_SEGMENT) {
- struct segment_command seg;
- if (ReadMemory(load_cmds_p, sizeof(struct segment_command), &seg) !=
- sizeof(struct segment_command)) {
- return false;
- }
- struct mach_o_segment this_seg;
- char name[17];
- ::memset(name, 0, sizeof(name));
- memcpy(name, seg.segname, sizeof(seg.segname));
- this_seg.name = name;
- this_seg.vmaddr = seg.vmaddr;
- this_seg.vmsize = seg.vmsize;
- this_seg.fileoff = seg.fileoff;
- this_seg.filesize = seg.filesize;
- this_seg.maxprot = seg.maxprot;
- this_seg.initprot = seg.initprot;
- this_seg.nsects = seg.nsects;
- this_seg.flags = seg.flags;
- inf.segments.push_back(this_seg);
- }
- if (lc.cmd == LC_SEGMENT_64) {
- struct segment_command_64 seg;
- if (ReadMemory(load_cmds_p, sizeof(struct segment_command_64), &seg) !=
- sizeof(struct segment_command_64)) {
- return false;
- }
- struct mach_o_segment this_seg;
- char name[17];
- ::memset(name, 0, sizeof(name));
- memcpy(name, seg.segname, sizeof(seg.segname));
- this_seg.name = name;
- this_seg.vmaddr = seg.vmaddr;
- this_seg.vmsize = seg.vmsize;
- this_seg.fileoff = seg.fileoff;
- this_seg.filesize = seg.filesize;
- this_seg.maxprot = seg.maxprot;
- this_seg.initprot = seg.initprot;
- this_seg.nsects = seg.nsects;
- this_seg.flags = seg.flags;
- inf.segments.push_back(this_seg);
- }
- if (lc.cmd == LC_UUID) {
- struct uuid_command uuidcmd;
- if (ReadMemory(load_cmds_p, sizeof(struct uuid_command), &uuidcmd) ==
- sizeof(struct uuid_command))
- uuid_copy(inf.uuid, uuidcmd.uuid);
- }
-
- uint32_t major_version, minor_version, patch_version;
- if (const char *platform = GetDeploymentInfo(lc, load_cmds_p,
- major_version, minor_version,
- patch_version)) {
- inf.min_version_os_name = platform;
- inf.min_version_os_version = "";
- inf.min_version_os_version += std::to_string(major_version);
- inf.min_version_os_version += ".";
- inf.min_version_os_version += std::to_string(minor_version);
- if (patch_version != 0) {
- inf.min_version_os_version += ".";
- inf.min_version_os_version += std::to_string(patch_version);
- }
- }
-
- load_cmds_p += lc.cmdsize;
- }
- return true;
-}
-
-// Given completely filled in array of binary_image_information structures,
-// create a JSONGenerator object
-// with all the details we want to send to lldb.
-JSONGenerator::ObjectSP MachProcess::FormatDynamicLibrariesIntoJSON(
- const std::vector<struct binary_image_information> &image_infos) {
-
- JSONGenerator::ArraySP image_infos_array_sp(new JSONGenerator::Array());
-
- const size_t image_count = image_infos.size();
-
- for (size_t i = 0; i < image_count; i++) {
- JSONGenerator::DictionarySP image_info_dict_sp(
- new JSONGenerator::Dictionary());
- image_info_dict_sp->AddIntegerItem("load_address",
- image_infos[i].load_address);
- image_info_dict_sp->AddIntegerItem("mod_date", image_infos[i].mod_date);
- image_info_dict_sp->AddStringItem("pathname", image_infos[i].filename);
-
- uuid_string_t uuidstr;
- uuid_unparse_upper(image_infos[i].macho_info.uuid, uuidstr);
- image_info_dict_sp->AddStringItem("uuid", uuidstr);
-
- if (!image_infos[i].macho_info.min_version_os_name.empty() &&
- !image_infos[i].macho_info.min_version_os_version.empty()) {
- image_info_dict_sp->AddStringItem(
- "min_version_os_name", image_infos[i].macho_info.min_version_os_name);
- image_info_dict_sp->AddStringItem(
- "min_version_os_sdk",
- image_infos[i].macho_info.min_version_os_version);
- }
-
- JSONGenerator::DictionarySP mach_header_dict_sp(
- new JSONGenerator::Dictionary());
- mach_header_dict_sp->AddIntegerItem(
- "magic", image_infos[i].macho_info.mach_header.magic);
- mach_header_dict_sp->AddIntegerItem(
- "cputype", (uint32_t)image_infos[i].macho_info.mach_header.cputype);
- mach_header_dict_sp->AddIntegerItem(
- "cpusubtype",
- (uint32_t)image_infos[i].macho_info.mach_header.cpusubtype);
- mach_header_dict_sp->AddIntegerItem(
- "filetype", image_infos[i].macho_info.mach_header.filetype);
- mach_header_dict_sp->AddIntegerItem ("flags",
- image_infos[i].macho_info.mach_header.flags);
-
- // DynamicLoaderMacOSX doesn't currently need these fields, so
- // don't send them.
- // mach_header_dict_sp->AddIntegerItem ("ncmds",
- // image_infos[i].macho_info.mach_header.ncmds);
- // mach_header_dict_sp->AddIntegerItem ("sizeofcmds",
- // image_infos[i].macho_info.mach_header.sizeofcmds);
- image_info_dict_sp->AddItem("mach_header", mach_header_dict_sp);
-
- JSONGenerator::ArraySP segments_sp(new JSONGenerator::Array());
- for (size_t j = 0; j < image_infos[i].macho_info.segments.size(); j++) {
- JSONGenerator::DictionarySP segment_sp(new JSONGenerator::Dictionary());
- segment_sp->AddStringItem("name",
- image_infos[i].macho_info.segments[j].name);
- segment_sp->AddIntegerItem("vmaddr",
- image_infos[i].macho_info.segments[j].vmaddr);
- segment_sp->AddIntegerItem("vmsize",
- image_infos[i].macho_info.segments[j].vmsize);
- segment_sp->AddIntegerItem("fileoff",
- image_infos[i].macho_info.segments[j].fileoff);
- segment_sp->AddIntegerItem(
- "filesize", image_infos[i].macho_info.segments[j].filesize);
- segment_sp->AddIntegerItem("maxprot",
- image_infos[i].macho_info.segments[j].maxprot);
-
- // DynamicLoaderMacOSX doesn't currently need these fields,
- // so don't send them.
- // segment_sp->AddIntegerItem ("initprot",
- // image_infos[i].macho_info.segments[j].initprot);
- // segment_sp->AddIntegerItem ("nsects",
- // image_infos[i].macho_info.segments[j].nsects);
- // segment_sp->AddIntegerItem ("flags",
- // image_infos[i].macho_info.segments[j].flags);
- segments_sp->AddItem(segment_sp);
- }
- image_info_dict_sp->AddItem("segments", segments_sp);
-
- image_infos_array_sp->AddItem(image_info_dict_sp);
- }
-
- JSONGenerator::DictionarySP reply_sp(new JSONGenerator::Dictionary());
- ;
- reply_sp->AddItem("images", image_infos_array_sp);
-
- return reply_sp;
-}
-
-// Get the shared library information using the old (pre-macOS 10.12, pre-iOS
-// 10, pre-tvOS 10, pre-watchOS 3)
-// code path. We'll be given the address of an array of structures in the form
-// {void* load_addr, void* mod_date, void* pathname}
-//
-// In macOS 10.12 etc and newer, we'll use SPI calls into dyld to gather this
-// information.
-JSONGenerator::ObjectSP MachProcess::GetLoadedDynamicLibrariesInfos(
- nub_process_t pid, nub_addr_t image_list_address, nub_addr_t image_count) {
- JSONGenerator::DictionarySP reply_sp;
-
- int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid};
- struct kinfo_proc processInfo;
- size_t bufsize = sizeof(processInfo);
- if (sysctl(mib, (unsigned)(sizeof(mib) / sizeof(int)), &processInfo, &bufsize,
- NULL, 0) == 0 &&
- bufsize > 0) {
- uint32_t pointer_size = 4;
- if (processInfo.kp_proc.p_flag & P_LP64)
- pointer_size = 8;
-
- std::vector<struct binary_image_information> image_infos;
- size_t image_infos_size = image_count * 3 * pointer_size;
-
- uint8_t *image_info_buf = (uint8_t *)malloc(image_infos_size);
- if (image_info_buf == NULL) {
- return reply_sp;
- }
- if (ReadMemory(image_list_address, image_infos_size, image_info_buf) !=
- image_infos_size) {
- return reply_sp;
- }
-
- //// First the image_infos array with (load addr, pathname, mod date)
- ///tuples
-
- for (size_t i = 0; i < image_count; i++) {
- struct binary_image_information info;
- nub_addr_t pathname_address;
- if (pointer_size == 4) {
- uint32_t load_address_32;
- uint32_t pathname_address_32;
- uint32_t mod_date_32;
- ::memcpy(&load_address_32, image_info_buf + (i * 3 * pointer_size), 4);
- ::memcpy(&pathname_address_32,
- image_info_buf + (i * 3 * pointer_size) + pointer_size, 4);
- ::memcpy(&mod_date_32, image_info_buf + (i * 3 * pointer_size) +
- pointer_size + pointer_size,
- 4);
- info.load_address = load_address_32;
- info.mod_date = mod_date_32;
- pathname_address = pathname_address_32;
- } else {
- uint64_t load_address_64;
- uint64_t pathname_address_64;
- uint64_t mod_date_64;
- ::memcpy(&load_address_64, image_info_buf + (i * 3 * pointer_size), 8);
- ::memcpy(&pathname_address_64,
- image_info_buf + (i * 3 * pointer_size) + pointer_size, 8);
- ::memcpy(&mod_date_64, image_info_buf + (i * 3 * pointer_size) +
- pointer_size + pointer_size,
- 8);
- info.load_address = load_address_64;
- info.mod_date = mod_date_64;
- pathname_address = pathname_address_64;
- }
- char strbuf[17];
- info.filename = "";
- uint64_t pathname_ptr = pathname_address;
- bool still_reading = true;
- while (still_reading &&
- ReadMemory(pathname_ptr, sizeof(strbuf) - 1, strbuf) ==
- sizeof(strbuf) - 1) {
- strbuf[sizeof(strbuf) - 1] = '\0';
- info.filename += strbuf;
- pathname_ptr += sizeof(strbuf) - 1;
- // Stop if we found nul byte indicating the end of the string
- for (size_t i = 0; i < sizeof(strbuf) - 1; i++) {
- if (strbuf[i] == '\0') {
- still_reading = false;
- break;
- }
- }
- }
- uuid_clear(info.macho_info.uuid);
- image_infos.push_back(info);
- }
- if (image_infos.size() == 0) {
- return reply_sp;
- }
-
- free(image_info_buf);
-
- //// Second, read the mach header / load commands for all the dylibs
-
- for (size_t i = 0; i < image_count; i++) {
- if (!GetMachOInformationFromMemory(image_infos[i].load_address,
- pointer_size,
- image_infos[i].macho_info)) {
- return reply_sp;
- }
- }
-
- //// Third, format all of the above in the JSONGenerator object.
-
- return FormatDynamicLibrariesIntoJSON(image_infos);
- }
-
- return reply_sp;
-}
-
-// From dyld SPI header dyld_process_info.h
-typedef void *dyld_process_info;
-struct dyld_process_cache_info {
- uuid_t cacheUUID; // UUID of cache used by process
- uint64_t cacheBaseAddress; // load address of dyld shared cache
- bool noCache; // process is running without a dyld cache
- bool privateCache; // process is using a private copy of its dyld cache
-};
-
-// Use the dyld SPI present in macOS 10.12, iOS 10, tvOS 10, watchOS 3 and newer
-// to get
-// the load address, uuid, and filenames of all the libraries.
-// This only fills in those three fields in the 'struct
-// binary_image_information' - call
-// GetMachOInformationFromMemory to fill in the mach-o header/load command
-// details.
-void MachProcess::GetAllLoadedBinariesViaDYLDSPI(
- std::vector<struct binary_image_information> &image_infos) {
- kern_return_t kern_ret;
- if (m_dyld_process_info_create) {
- dyld_process_info info =
- m_dyld_process_info_create(m_task.TaskPort(), 0, &kern_ret);
- if (info) {
- m_dyld_process_info_for_each_image(
- info,
- ^(uint64_t mach_header_addr, const uuid_t uuid, const char *path) {
- struct binary_image_information image;
- image.filename = path;
- uuid_copy(image.macho_info.uuid, uuid);
- image.load_address = mach_header_addr;
- image_infos.push_back(image);
- });
- m_dyld_process_info_release(info);
- }
- }
-}
-
-// Fetch information about all shared libraries using the dyld SPIs that exist
-// in
-// macOS 10.12, iOS 10, tvOS 10, watchOS 3 and newer.
-JSONGenerator::ObjectSP
-MachProcess::GetAllLoadedLibrariesInfos(nub_process_t pid) {
- JSONGenerator::DictionarySP reply_sp;
-
- int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid};
- struct kinfo_proc processInfo;
- size_t bufsize = sizeof(processInfo);
- if (sysctl(mib, (unsigned)(sizeof(mib) / sizeof(int)), &processInfo, &bufsize,
- NULL, 0) == 0 &&
- bufsize > 0) {
- uint32_t pointer_size = 4;
- if (processInfo.kp_proc.p_flag & P_LP64)
- pointer_size = 8;
-
- std::vector<struct binary_image_information> image_infos;
- GetAllLoadedBinariesViaDYLDSPI(image_infos);
- const size_t image_count = image_infos.size();
- for (size_t i = 0; i < image_count; i++) {
- GetMachOInformationFromMemory(image_infos[i].load_address, pointer_size,
- image_infos[i].macho_info);
- }
- return FormatDynamicLibrariesIntoJSON(image_infos);
- }
- return reply_sp;
-}
-
-// Fetch information about the shared libraries at the given load addresses
-// using the
-// dyld SPIs that exist in macOS 10.12, iOS 10, tvOS 10, watchOS 3 and newer.
-JSONGenerator::ObjectSP MachProcess::GetLibrariesInfoForAddresses(
- nub_process_t pid, std::vector<uint64_t> &macho_addresses) {
- JSONGenerator::DictionarySP reply_sp;
-
- int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid};
- struct kinfo_proc processInfo;
- size_t bufsize = sizeof(processInfo);
- if (sysctl(mib, (unsigned)(sizeof(mib) / sizeof(int)), &processInfo, &bufsize,
- NULL, 0) == 0 &&
- bufsize > 0) {
- uint32_t pointer_size = 4;
- if (processInfo.kp_proc.p_flag & P_LP64)
- pointer_size = 8;
-
- std::vector<struct binary_image_information> all_image_infos;
- GetAllLoadedBinariesViaDYLDSPI(all_image_infos);
-
- std::vector<struct binary_image_information> image_infos;
- const size_t macho_addresses_count = macho_addresses.size();
- const size_t all_image_infos_count = all_image_infos.size();
- for (size_t i = 0; i < macho_addresses_count; i++) {
- for (size_t j = 0; j < all_image_infos_count; j++) {
- if (all_image_infos[j].load_address == macho_addresses[i]) {
- image_infos.push_back(all_image_infos[j]);
- }
- }
- }
-
- const size_t image_infos_count = image_infos.size();
- for (size_t i = 0; i < image_infos_count; i++) {
- GetMachOInformationFromMemory(image_infos[i].load_address, pointer_size,
- image_infos[i].macho_info);
- }
- return FormatDynamicLibrariesIntoJSON(image_infos);
- }
- return reply_sp;
-}
-
-// From dyld's internal podyld_process_info.h:
-
-JSONGenerator::ObjectSP MachProcess::GetSharedCacheInfo(nub_process_t pid) {
- JSONGenerator::DictionarySP reply_sp(new JSONGenerator::Dictionary());
- ;
- kern_return_t kern_ret;
- if (m_dyld_process_info_create && m_dyld_process_info_get_cache) {
- dyld_process_info info =
- m_dyld_process_info_create(m_task.TaskPort(), 0, &kern_ret);
- if (info) {
- struct dyld_process_cache_info shared_cache_info;
- m_dyld_process_info_get_cache(info, &shared_cache_info);
-
- reply_sp->AddIntegerItem("shared_cache_base_address",
- shared_cache_info.cacheBaseAddress);
-
- uuid_string_t uuidstr;
- uuid_unparse_upper(shared_cache_info.cacheUUID, uuidstr);
- reply_sp->AddStringItem("shared_cache_uuid", uuidstr);
-
- reply_sp->AddBooleanItem("no_shared_cache", shared_cache_info.noCache);
- reply_sp->AddBooleanItem("shared_cache_private_cache",
- shared_cache_info.privateCache);
-
- m_dyld_process_info_release(info);
- }
- }
- return reply_sp;
-}
-
-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();
- }
- m_activities.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 = static_cast<useconds_t>(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.Status(), 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::Interrupt() {
- nub_state_t state = GetState();
- if (IsRunning(state)) {
- if (m_sent_interrupt_signo == 0) {
- m_sent_interrupt_signo = SIGSTOP;
- if (Signal(m_sent_interrupt_signo)) {
- DNBLogThreadedIf(
- LOG_PROCESS,
- "MachProcess::Interrupt() - sent %i signal to interrupt process",
- m_sent_interrupt_signo);
- return true;
- } else {
- m_sent_interrupt_signo = 0;
- DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Interrupt() - failed to "
- "send %i signal to interrupt process",
- m_sent_interrupt_signo);
- }
- } else {
- DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Interrupt() - previously "
- "sent an interrupt signal %i that hasn't "
- "been received yet, interrupt aborted",
- m_sent_interrupt_signo);
- }
- } else {
- DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Interrupt() - process already "
- "stopped, no interrupt sent");
- }
- return false;
-}
-
-bool MachProcess::Signal(int signal, const struct timespec *timeout_abstime) {
- DNBLogThreadedIf(LOG_PROCESS,
- "MachProcess::Signal (signal = %d, timeout = %p)", signal,
- reinterpret_cast<const void *>(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, reinterpret_cast<const void *>(timeout_abstime));
- m_private_events.WaitForSetEvents(eEventProcessStoppedStateChanged,
- timeout_abstime);
- state = GetState();
- DNBLogThreadedIf(
- LOG_PROCESS,
- "MachProcess::Signal (signal = %d, timeout = %p) state = %s", signal,
- reinterpret_cast<const void *>(timeout_abstime),
- DNBStateAsString(state));
- return !IsRunning(state);
- }
- DNBLogThreadedIf(
- LOG_PROCESS,
- "MachProcess::Signal (signal = %d, timeout = %p) not waiting...",
- signal, reinterpret_cast<const void *>(timeout_abstime));
- return true;
- }
- DNBError err(errno, DNBError::POSIX);
- err.LogThreadedIfError("kill (pid = %d, signo = %i)", ProcessID(), signal);
- return false;
-}
-
-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;
-// FIXME: Shouldn't we use the launch flavor we were started with?
-#if defined(WITH_FBS) || defined(WITH_BKS)
- return BoardServiceSendEvent(event, send_err);
-#endif
- return true;
-}
-
-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();
- m_activities.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 restored 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);
- UNUSED_IF_ASSERT_DISABLED(intersects);
- 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()) {
- 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);
-
- m_auto_resume_signo = m_sent_interrupt_signo;
- if (m_auto_resume_signo)
- DNBLogThreadedIf(LOG_PROCESS, "MachProcess::PrivateResume() - task 0x%x "
- "resuming (with unhandled interrupt signal "
- "%i)...",
- m_task.TaskPort(), m_auto_resume_signo);
- else
- DNBLogThreadedIf(LOG_PROCESS,
- "MachProcess::PrivateResume() - task 0x%x resuming...",
- m_task.TaskPort());
-
- 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,
- reinterpret_cast<void *>(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,
- reinterpret_cast<void *>(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) {
- 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 breakpoint 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 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) {
- 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);
-}
-
-task_t 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());
- bool auto_resume = false;
- 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) {
- bool received_interrupt = false;
- uint32_t num_task_exceptions = 0;
- for (i = 0; i < m_exception_messages.size(); ++i) {
- if (m_exception_messages[i].state.task_port == task) {
- ++num_task_exceptions;
- 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;
- // Force the task port to update itself in case the task port
- // changed after exec
- DNBError err;
- const task_t old_task = m_task.TaskPort();
- const task_t new_task =
- m_task.TaskPortForProcessID(err, true);
- if (old_task != new_task)
- DNBLogThreadedIf(
- LOG_PROCESS,
- "exec: task changed from 0x%4.4x to 0x%4.4x", old_task,
- new_task);
- }
- } else {
- DNBLog("error: failed to read all_image_infos.infoArrayCount "
- "from 0x%8.8llx",
- (uint64_t)info_array_count_addr);
- }
- }
- break;
- } else if (m_sent_interrupt_signo != 0 &&
- signo == m_sent_interrupt_signo) {
- received_interrupt = true;
- }
- }
- }
-
- 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_activities.Clear();
- m_breakpoints.DisableAll();
- }
-
- if (m_sent_interrupt_signo != 0) {
- if (received_interrupt) {
- DNBLogThreadedIf(LOG_PROCESS,
- "MachProcess::ExceptionMessageBundleComplete(): "
- "process successfully interrupted with signal %i",
- m_sent_interrupt_signo);
-
- // Mark that we received the interrupt signal
- m_sent_interrupt_signo = 0;
- // Not check if we had a case where:
- // 1 - We called MachProcess::Interrupt() but we stopped for another
- // reason
- // 2 - We called MachProcess::Resume() (but still haven't gotten the
- // interrupt signal)
- // 3 - We are now incorrectly stopped because we are handling the
- // interrupt signal we missed
- // 4 - We might need to resume if we stopped only with the interrupt
- // signal that we never handled
- if (m_auto_resume_signo != 0) {
- // Only auto_resume if we stopped with _only_ the interrupt signal
- if (num_task_exceptions == 1) {
- auto_resume = true;
- DNBLogThreadedIf(LOG_PROCESS, "MachProcess::"
- "ExceptionMessageBundleComplete(): "
- "auto resuming due to unhandled "
- "interrupt signal %i",
- m_auto_resume_signo);
- }
- m_auto_resume_signo = 0;
- }
- } else {
- DNBLogThreadedIf(LOG_PROCESS, "MachProcess::"
- "ExceptionMessageBundleComplete(): "
- "didn't get signal %i after "
- "MachProcess::Interrupt()",
- m_sent_interrupt_signo);
- }
- }
- }
-
- // Let all threads recover from stopping and do any clean up based
- // on the previous thread state (if any).
- m_thread_list.ProcessDidStop(this);
- m_activities.Clear();
-
- // 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) && !auto_resume) {
- // 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());
- }
- return m_task.TaskPort();
-}
-
-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::SetExitInfo(const char *info) {
- if (info && info[0]) {
- DNBLogThreadedIf(LOG_PROCESS, "MachProcess::%s(\"%s\")", __FUNCTION__,
- info);
- m_exit_info.assign(info);
- } else {
- DNBLogThreadedIf(LOG_PROCESS, "MachProcess::%s(NULL)", __FUNCTION__);
- m_exit_info.clear();
- }
-}
-
-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__,
- reinterpret_cast<void *>(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);
-
-#if defined(__APPLE__)
- pthread_setname_np("stdio monitoring thread");
-#endif
-
- // 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 available. 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
- ssize_t 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, ) => %zd errno: %d (%s)",
- bytes_read, read_errno, strerror(read_errno));
- } else if (bytes_read == 0) {
- // EOF...
- DNBLogThreadedIf(
- LOG_PROCESS,
- "read (stdout_fd, ) => %zd (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, ) => %zd errno: %d (%s)",
- bytes_read, read_errno, strerror(read_errno));
- } else if (bytes_read == 0) {
- // EOF...
- DNBLogThreadedIf(
- LOG_PROCESS,
- "read (stderr_fd, ) => %zd (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__,
- reinterpret_cast<void *>(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);
-
-#if defined(__APPLE__)
- pthread_setname_np("performance profiling thread");
-#endif
-
- 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 or BKS if the correct flag
-// bit is set...
-#if defined(WITH_FBS) || defined(WITH_BKS)
- bool found_app_flavor = false;
-#endif
-
-#if defined(WITH_FBS)
- if (!found_app_flavor && IsFBSProcess(pid)) {
- found_app_flavor = true;
- m_flags |= eMachProcessFlagsUsingFBS;
- }
-#elif defined(WITH_BKS)
- if (!found_app_flavor && IsBKSProcess(pid)) {
- found_app_flavor = true;
- m_flags |= eMachProcessFlagsUsingBKS;
- }
-#elif defined(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;
-}
-
-Genealogy::ThreadActivitySP
-MachProcess::GetGenealogyInfoForThread(nub_thread_t tid, bool &timed_out) {
- return m_activities.GetGenealogyInfoForThread(m_pid, tid, m_thread_list,
- m_task.TaskPort(), timed_out);
-}
-
-Genealogy::ProcessExecutableInfoSP
-MachProcess::GetGenealogyImageInfo(size_t idx) {
- return m_activities.GetProcessExecutableInfosAtIndex(idx);
-}
-
-bool MachProcess::GetOSVersionNumbers(uint64_t *major, uint64_t *minor,
- uint64_t *patch) {
-#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \
- (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101000)
- return false;
-#else
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
- NSOperatingSystemVersion vers =
- [[NSProcessInfo processInfo] operatingSystemVersion];
- if (major)
- *major = vers.majorVersion;
- if (minor)
- *minor = vers.minorVersion;
- if (patch)
- *patch = vers.patchVersion;
-
- [pool drain];
-
- return true;
-#endif
-}
-
-// 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 &attach_err) {
-#if defined(WITH_SPRINGBOARD) || defined(WITH_BKS) || defined(WITH_FBS)
- // 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 defined(WITH_FBS)
- if (launch_flavor == eLaunchFlavorDefault)
- launch_flavor = eLaunchFlavorFBS;
- if (launch_flavor != eLaunchFlavorFBS)
- return NULL;
-#elif 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(), 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());
-
- if (bundleIDCFStr == NULL) {
- return NULL;
- }
-
-#if defined(WITH_FBS)
- if (launch_flavor == eLaunchFlavorFBS) {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
- 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:FBSDebugOptionKeyStandardOutPath];
- [debug_options setObject:stdio_path
- forKey:FBSDebugOptionKeyStandardErrorPath];
- [debug_options setObject:[NSNumber numberWithBool:YES]
- forKey:FBSDebugOptionKeyWaitForDebugger];
- [debug_options setObject:[NSNumber numberWithBool:YES]
- forKey:FBSDebugOptionKeyDebugOnNextLaunch];
-
- [options setObject:debug_options
- forKey:FBSOpenApplicationOptionKeyDebuggingOptions];
-
- FBSSystemService *system_service = [[FBSSystemService alloc] init];
-
- mach_port_t client_port = [system_service createClientPort];
- __block dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
- __block FBSOpenApplicationErrorCode attach_error_code =
- FBSOpenApplicationErrorCodeNone;
-
- 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 =
- (FBSOpenApplicationErrorCode)[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(OPEN_APPLICATION_TIMEOUT_ERROR, DNBError::Generic);
- } else if (attach_error_code != FBSOpenApplicationErrorCodeNone) {
- SetFBSError(attach_error_code, attach_err);
- DNBLogError("unable to launch the application with CFBundleIdentifier "
- "'%s' bks_error = %ld",
- bundleIDStr.c_str(), (NSInteger)attach_error_code);
- }
- dispatch_release(semaphore);
- [pool drain];
- }
-#endif
-#if defined(WITH_BKS)
- if (launch_flavor == eLaunchFlavorBKS) {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
- 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];
-
- 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(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 = %ld",
- bundleIDStr.c_str(), attach_error_code);
- }
- dispatch_release(semaphore);
- [pool drain];
- }
-#endif
-
-#if defined(WITH_SPRINGBOARD)
- if (launch_flavor == eLaunchFlavorSpringBoard) {
- 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 // !(defined (WITH_SPRINGBOARD) || defined (WITH_BKS) || defined
- // (WITH_FBS))
- 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,
- nub_launch_flavor_t launch_flavor) {
- if (attach_token == NULL)
- return INVALID_NUB_PROCESS;
-
-#if defined(WITH_FBS)
- if (launch_flavor == eLaunchFlavorFBS) {
- NSString *bundleIDNSStr = (NSString *)attach_token;
- FBSSystemService *systemService = [[FBSSystemService alloc] init];
- pid_t pid = [systemService pidForApplication:bundleIDNSStr];
- [systemService release];
- if (pid == 0)
- return INVALID_NUB_PROCESS;
- else
- return pid;
- }
-#endif
-
-#if defined(WITH_BKS)
- if (launch_flavor == eLaunchFlavorBKS) {
- 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;
- }
-#endif
-
-#if defined(WITH_SPRINGBOARD)
- if (launch_flavor == eLaunchFlavorSpringBoard) {
- 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,
- nub_launch_flavor_t launch_flavor,
- bool success, DNBError &err_str) {
- if (attach_token == NULL)
- return;
-
-#if defined(WITH_FBS)
- if (launch_flavor == eLaunchFlavorFBS) {
- if (!success) {
- FBSCleanupAfterAttach(attach_token, err_str);
- }
- CFRelease((CFStringRef)attach_token);
- }
-#endif
-
-#if defined(WITH_BKS)
-
- if (launch_flavor == eLaunchFlavorBKS) {
- if (!success) {
- BKSCleanupAfterAttach(attach_token, err_str);
- }
- CFRelease((CFStringRef)attach_token);
- }
-#endif
-
-#if defined(WITH_SPRINGBOARD)
- // Tell SpringBoard to cancel the debug on next launch of this application
- // if we failed to attach
- if (launch_flavor == eMachProcessFlagsUsingSpringBoard) {
- 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 => don't 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,
- const char *event_data, 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, reinterpret_cast<const void *>(argv),
- reinterpret_cast<const void *>(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_FBS
- case eLaunchFlavorFBS: {
- 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"));
- m_flags |= eMachProcessFlagsUsingFBS;
- if (BoardServiceLaunchForDebug(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 FBS launch, but didn't succeed lets get out
- }
- } break;
-#endif
-#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"));
- m_flags |= eMachProcessFlagsUsingBKS;
- if (BoardServiceLaunchForDebug(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
- }
- } break;
-#endif
-#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,
- 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
- }
- } break;
-
-#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.Status(),
- 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, reinterpret_cast<const void *>(argv),
- reinterpret_cast<const void *>(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,
- const_cast<char *const *>(argv),
- const_cast<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,
- const_cast<char *const *>(argv),
- const_cast<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, static_cast<u_int>(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::Status 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) {
- //--------------------------------------------------------------
- // Status 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, const_cast<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;
-}
-
-#if defined(WITH_SPRINGBOARD) || defined(WITH_BKS) || defined(WITH_FBS)
-// 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 (WITH_SPRINGBOARD) || defined (WITH_BKS) || defined
- // (WITH_FBS)
-#ifdef WITH_SPRINGBOARD
-
-pid_t 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();
-
- 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>
-
-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::Status 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;
-
- // 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,
- (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
-
-#if defined(WITH_BKS) || defined(WITH_FBS)
-pid_t MachProcess::BoardServiceLaunchForDebug(
- const char *path, char const *argv[], char const *envp[], bool no_stdio,
- bool disable_aslr, const char *event_data, DNBError &launch_err) {
- DNBLogThreadedIf(LOG_PROCESS, "%s( '%s', argv)", __FUNCTION__, path);
-
- // Fork a child process for debugging
- SetState(eStateLaunching);
- m_pid = BoardServiceForkChildForPTraceDebugging(
- path, argv, envp, no_stdio, disable_aslr, event_data, launch_err);
- if (m_pid != 0) {
- 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::BoardServiceForkChildForPTraceDebugging(
- 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::Status 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:
-
- NSMutableDictionary *options = nullptr;
- pid_t return_pid = INVALID_NUB_PROCESS;
- bool success = false;
-
-#ifdef WITH_BKS
- if (m_flags & eMachProcessFlagsUsingBKS) {
- options =
- BKSCreateOptionsDictionary(app_bundle_path, launch_argv, launch_envp,
- stdio_path, disable_aslr, event_data);
- success = BKSCallOpenApplicationFunction(bundleIDNSStr, options, launch_err,
- &return_pid);
- }
-#endif
-#ifdef WITH_FBS
- if (m_flags & eMachProcessFlagsUsingFBS) {
- options =
- FBSCreateOptionsDictionary(app_bundle_path, launch_argv, launch_envp,
- stdio_path, disable_aslr, event_data);
- success = FBSCallOpenApplicationFunction(bundleIDNSStr, options, launch_err,
- &return_pid);
- }
-#endif
-
- 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::BoardServiceSendEvent(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:
-#ifdef WITH_BKS
- if (m_flags & eMachProcessFlagsUsingBKS) {
- return_value = BKSCallOpenApplicationFunction(nil, nil, send_err, NULL);
- }
-#endif
-#ifdef WITH_FBS
- if (m_flags & eMachProcessFlagsUsingFBS) {
- return_value = FBSCallOpenApplicationFunction(nil, nil, send_err, NULL);
- }
-#endif
- 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];
-
-#ifdef WITH_BKS
- if (m_flags & eMachProcessFlagsUsingBKS) {
- if (!BKSAddEventDataToOptions(options, event_data, send_err)) {
- [pool drain];
- return false;
- }
- return_value = BKSCallOpenApplicationFunction(bundleIDNSStr, options,
- send_err, NULL);
- DNBLogThreadedIf(LOG_PROCESS,
- "Called BKSCallOpenApplicationFunction to send event.");
- }
-#endif
-#ifdef WITH_FBS
- if (m_flags & eMachProcessFlagsUsingFBS) {
- if (!FBSAddEventDataToOptions(options, event_data, send_err)) {
- [pool drain];
- return false;
- }
- return_value = FBSCallOpenApplicationFunction(bundleIDNSStr, options,
- send_err, NULL);
- DNBLogThreadedIf(LOG_PROCESS,
- "Called FBSCallOpenApplicationFunction to send event.");
- }
-#endif
-
- if (!return_value) {
- DNBLogError("Failed to send event: %s, error: %s.", event_data,
- send_err.AsString());
- }
- }
-
- [pool drain];
- return return_value;
-}
-#endif // defined(WITH_BKS) || defined (WITH_FBS)
-
-#ifdef WITH_BKS
-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 =
- BKSCallOpenApplicationFunction(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];
-}
-#endif // WITH_BKS
-
-#ifdef WITH_FBS
-void MachProcess::FBSCleanupAfterAttach(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:FBSDebugOptionKeyCancelDebugOnNextLaunch];
-
- // That will go in the overall dictionary:
-
- NSMutableDictionary *options = [NSMutableDictionary dictionary];
- [options setObject:debug_options
- forKey:FBSOpenApplicationOptionKeyDebuggingOptions];
-
- success =
- FBSCallOpenApplicationFunction(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];
-}
-#endif // WITH_FBS
diff --git a/tools/debugserver/source/MacOSX/MachTask.h b/tools/debugserver/source/MacOSX/MachTask.h
deleted file mode 100644
index 1fe74ddec56c..000000000000
--- a/tools/debugserver/source/MacOSX/MachTask.h
+++ /dev/null
@@ -1,113 +0,0 @@
-//===-- MachTask.h ----------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//----------------------------------------------------------------------
-//
-// MachTask.h
-// debugserver
-//
-// Created by Greg Clayton on 12/5/08.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __MachTask_h__
-#define __MachTask_h__
-
-#include <mach/mach.h>
-#include <sys/socket.h>
-#include <map>
-#include <string>
-#include "DNBDefs.h"
-#include "MachException.h"
-#include "MachVMMemory.h"
-#include "PThreadMutex.h"
-
-class MachProcess;
-
-typedef uint64_t MachMallocEventId;
-
-enum MachMallocEventType {
- eMachMallocEventTypeAlloc = 2,
- eMachMallocEventTypeDealloc = 4,
- eMachMallocEventTypeOther = 1
-};
-
-struct MachMallocEvent {
- mach_vm_address_t m_base_address;
- uint64_t m_size;
- MachMallocEventType m_event_type;
- MachMallocEventId m_event_id;
-};
-
-class MachTask {
-public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- MachTask(MachProcess *process);
- virtual ~MachTask();
-
- void Clear();
-
- kern_return_t Suspend();
- kern_return_t Resume();
-
- nub_size_t ReadMemory(nub_addr_t addr, nub_size_t size, void *buf);
- nub_size_t WriteMemory(nub_addr_t addr, nub_size_t size, const void *buf);
- int GetMemoryRegionInfo(nub_addr_t addr, DNBRegionInfo *region_info);
- std::string GetProfileData(DNBProfileDataScanType scanType);
-
- nub_addr_t AllocateMemory(nub_size_t size, uint32_t permissions);
- nub_bool_t DeallocateMemory(nub_addr_t addr);
-
- mach_port_t ExceptionPort() const;
- bool ExceptionPortIsValid() const;
- kern_return_t SaveExceptionPortInfo();
- kern_return_t RestoreExceptionPortInfo();
- kern_return_t ShutDownExcecptionThread();
-
- bool StartExceptionThread(DNBError &err);
- nub_addr_t GetDYLDAllImageInfosAddress(DNBError &err);
- kern_return_t BasicInfo(struct task_basic_info *info);
- static kern_return_t BasicInfo(task_t task, struct task_basic_info *info);
- bool IsValid() const;
- static bool IsValid(task_t task);
- static void *ExceptionThread(void *arg);
- void TaskPortChanged(task_t task);
- task_t TaskPort() const { return m_task; }
- task_t TaskPortForProcessID(DNBError &err, bool force = false);
- static task_t TaskPortForProcessID(pid_t pid, DNBError &err,
- uint32_t num_retries = 10,
- uint32_t usec_interval = 10000);
-
- MachProcess *Process() { return m_process; }
- const MachProcess *Process() const { return m_process; }
-
- nub_size_t PageSize();
-
-protected:
- MachProcess *m_process; // The mach process that owns this MachTask
- task_t m_task;
- MachVMMemory m_vm_memory; // Special mach memory reading class that will take
- // care of watching for page and region boundaries
- MachException::PortInfo
- m_exc_port_info; // Saved settings for all exception ports
- pthread_t m_exception_thread; // Thread ID for the exception thread in case we
- // need it
- mach_port_t m_exception_port; // Exception port on which we will receive child
- // exceptions
-
- typedef std::map<mach_vm_address_t, size_t> allocation_collection;
- allocation_collection m_allocations;
-
-private:
- MachTask(const MachTask &); // Outlaw
- MachTask &operator=(const MachTask &rhs); // Outlaw
-};
-
-#endif // __MachTask_h__
diff --git a/tools/debugserver/source/MacOSX/MachTask.mm b/tools/debugserver/source/MacOSX/MachTask.mm
deleted file mode 100644
index d05f50029f16..000000000000
--- a/tools/debugserver/source/MacOSX/MachTask.mm
+++ /dev/null
@@ -1,962 +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>
-
-#if defined(__APPLE__)
-#include <pthread.h>
-#include <sched.h>
-#endif
-
-// C++ Includes
-#include <iomanip>
-#include <sstream>
-
-// Other libraries and framework includes
-// Project includes
-#include "CFUtils.h"
-#include "DNB.h"
-#include "DNBDataRef.h"
-#include "DNBError.h"
-#include "DNBLog.h"
-#include "MachProcess.h"
-
-#ifdef WITH_SPRINGBOARD
-
-#include <CoreFoundation/CoreFoundation.h>
-#include <SpringBoardServices/SBSWatchdogAssertion.h>
-#include <SpringBoardServices/SpringBoardServer.h>
-
-#endif
-
-#ifdef WITH_BKS
-extern "C" {
-#import <BackBoardServices/BKSWatchdogAssertion.h>
-#import <BackBoardServices/BackBoardServices.h>
-#import <Foundation/Foundation.h>
-}
-#endif
-
-#include <AvailabilityMacros.h>
-
-#ifdef LLDB_ENERGY
-#include <mach/mach_time.h>
-#include <pmenergy.h>
-#include <pmsample.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.Status();
-}
-
-//----------------------------------------------------------------------
-// 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.Status();
-}
-
-//----------------------------------------------------------------------
-// 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, static_cast<DNBDataRef::offset_t>(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((const uint8_t *)buf, n, false);
- data.Dump(0, static_cast<DNBDataRef::offset_t>(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 (mach_msg_type_number_t 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);
- }
-
- mach_port_deallocate(mach_task_self(), threads[i]);
- }
- 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;
-
- pid_t pid = m_process->ProcessID();
-
- 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, pid, threads_id, threads_name,
- threads_used_usec);
- }
-
- vm_statistics64_data_t vminfo;
- uint64_t physical_memory = 0;
- uint64_t anonymous = 0;
- uint64_t phys_footprint = 0;
- uint64_t memory_cap = 0;
- if (m_vm_memory.GetMemoryProfile(scanType, task, task_info,
- m_process->GetCPUType(), pid, vminfo,
- physical_memory, anonymous,
- phys_footprint, memory_cap)) {
- 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) {
- const size_t num_threads = threads_id.size();
- for (size_t 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:";
- const size_t 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 (size_t 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 = vm_kernel_page_size;
-
- // This mimicks Activity Monitor.
- uint64_t total_used_count =
- (physical_memory / pagesize) -
- (vminfo.free_count - vminfo.speculative_count) -
- vminfo.external_page_count - vminfo.purgeable_count;
- profile_data_stream << "used:" << total_used_count * pagesize << ';';
-
- if (scanType & eProfileMemoryAnonymous) {
- profile_data_stream << "anonymous:" << anonymous << ';';
- }
-
- profile_data_stream << "phys_footprint:" << phys_footprint << ';';
- }
-
- if (scanType & eProfileMemoryCap) {
- profile_data_stream << "mem_cap:" << memory_cap << ';';
- }
-
-#ifdef LLDB_ENERGY
- if (scanType & eProfileEnergy) {
- struct rusage_info_v2 info;
- int rc = proc_pid_rusage(pid, RUSAGE_INFO_V2, (rusage_info_t *)&info);
- if (rc == 0) {
- uint64_t now = mach_absolute_time();
- pm_task_energy_data_t pm_energy;
- memset(&pm_energy, 0, sizeof(pm_energy));
- /*
- * Disable most features of pm_sample_pid. It will gather
- * network/GPU/WindowServer information; fill in the rest.
- */
- pm_sample_task_and_pid(task, pid, &pm_energy, now,
- PM_SAMPLE_ALL & ~PM_SAMPLE_NAME &
- ~PM_SAMPLE_INTERVAL & ~PM_SAMPLE_CPU &
- ~PM_SAMPLE_DISK);
- pm_energy.sti.total_user = info.ri_user_time;
- pm_energy.sti.total_system = info.ri_system_time;
- pm_energy.sti.task_interrupt_wakeups = info.ri_interrupt_wkups;
- pm_energy.sti.task_platform_idle_wakeups = info.ri_pkg_idle_wkups;
- pm_energy.diskio_bytesread = info.ri_diskio_bytesread;
- pm_energy.diskio_byteswritten = info.ri_diskio_byteswritten;
- pm_energy.pageins = info.ri_pageins;
-
- uint64_t total_energy =
- (uint64_t)(pm_energy_impact(&pm_energy) * NSEC_PER_SEC);
- // uint64_t process_age = now - info.ri_proc_start_abstime;
- // uint64_t avg_energy = 100.0 * (double)total_energy /
- // (double)process_age;
-
- profile_data_stream << "energy:" << total_energy << ';';
- }
- }
-#endif
-
- profile_data_stream << "--end--;";
-
- result = profile_data_stream.str();
- }
-
- return result;
-}
-
-//----------------------------------------------------------------------
-// MachTask::TaskPortForProcessID
-//----------------------------------------------------------------------
-task_t MachTask::TaskPortForProcessID(DNBError &err, bool force) {
- if (((m_task == TASK_NULL) || force) && 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.Status(),
- 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.Status();
-}
-
-//----------------------------------------------------------------------
-// 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 = 0;
-
- 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.Status();
-}
-
-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);
-
-#if defined(__APPLE__)
- pthread_setname_np("exception monitoring thread");
-#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
- struct sched_param thread_param;
- int thread_sched_policy;
- if (pthread_getschedparam(pthread_self(), &thread_sched_policy,
- &thread_param) == 0) {
- thread_param.sched_priority = 47;
- pthread_setschedparam(pthread_self(), thread_sched_policy, &thread_param);
- }
-#endif
-#endif
-
- // 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 available. 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;
-
-#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();
- 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 // #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()) {
- ::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.Status() == 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.Status() == 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 and get the possibly updated task port back
- // from the process in case we exec'ed and our task port changed
- task = 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;
- }
- }
-
-#if defined(WITH_SPRINGBOARD) && !defined(WITH_BKS)
- 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.Status() != 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)) {
- if (exception_message.state.task_port != task) {
- if (exception_message.state.IsValid()) {
- // We exec'ed and our task port changed on us.
- DNBLogThreadedIf(LOG_EXCEPTIONS,
- "task port changed from 0x%4.4x to 0x%4.4x",
- task, exception_message.state.task_port);
- task = exception_message.state.task_port;
- mach_task->TaskPortChanged(exception_message.state.task_port);
- }
- }
- ++num_exceptions_received;
- mach_proc->ExceptionMessageReceived(exception_message);
- }
- }
- }
-
-#if defined(WITH_SPRINGBOARD) && !defined(WITH_BKS)
- 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 // #if defined (WITH_SPRINGBOARD) && !defined (WITH_BKS)
-
- 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.Status() == 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.Status() == 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;
-}
-
-void MachTask::TaskPortChanged(task_t task)
-{
- m_task = task;
-}
diff --git a/tools/debugserver/source/MacOSX/MachThread.cpp b/tools/debugserver/source/MacOSX/MachThread.cpp
deleted file mode 100644
index 062e1c3d9edf..000000000000
--- a/tools/debugserver/source/MacOSX/MachThread.cpp
+++ /dev/null
@@ -1,783 +0,0 @@
-//===-- MachThread.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/19/07.
-//
-//===----------------------------------------------------------------------===//
-
-#include "MachThread.h"
-#include "DNB.h"
-#include "DNBLog.h"
-#include "MachProcess.h"
-#include "ThreadInfo.h"
-#include <dlfcn.h>
-#include <inttypes.h>
-#include <mach/thread_policy.h>
-
-static uint32_t GetSequenceID() {
- static uint32_t g_nextID = 0;
- return ++g_nextID;
-}
-
-MachThread::MachThread(MachProcess *process, bool is_64_bit,
- uint64_t unique_thread_id, thread_t mach_port_num)
- : m_process(process), m_unique_id(unique_thread_id),
- m_mach_port_number(mach_port_num), m_seq_id(GetSequenceID()),
- m_state(eStateUnloaded), m_state_mutex(PTHREAD_MUTEX_RECURSIVE),
- m_suspend_count(0), m_stop_exception(),
- m_arch_ap(DNBArchProtocol::Create(this)), m_reg_sets(NULL),
- m_num_reg_sets(0), m_ident_info(), m_proc_threadinfo(),
- m_dispatch_queue_name(), m_is_64_bit(is_64_bit),
- m_pthread_qos_class_decode(nullptr) {
- nub_size_t num_reg_sets = 0;
- m_reg_sets = m_arch_ap->GetRegisterSetInfo(&num_reg_sets);
- m_num_reg_sets = num_reg_sets;
-
- m_pthread_qos_class_decode =
- (unsigned int (*)(unsigned long, int *, unsigned long *))dlsym(
- RTLD_DEFAULT, "_pthread_qos_class_decode");
-
- // Get the thread state so we know if a thread is in a state where we can't
- // muck with it and also so we get the suspend count correct in case it was
- // already suspended
- GetBasicInfo();
- DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE,
- "MachThread::MachThread ( process = %p, tid = 0x%8.8" PRIx64
- ", seq_id = %u )",
- reinterpret_cast<void *>(&m_process), m_unique_id, m_seq_id);
-}
-
-MachThread::~MachThread() {
- DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE,
- "MachThread::~MachThread() for tid = 0x%8.8" PRIx64 " (%u)",
- m_unique_id, m_seq_id);
-}
-
-void MachThread::Suspend() {
- DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )",
- __FUNCTION__);
- if (MachPortNumberIsValid(m_mach_port_number)) {
- DNBError err(::thread_suspend(m_mach_port_number), DNBError::MachKernel);
- if (err.Success())
- m_suspend_count++;
- if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail())
- err.LogThreaded("::thread_suspend (%4.4" PRIx32 ")", m_mach_port_number);
- }
-}
-
-void MachThread::Resume(bool others_stopped) {
- DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )",
- __FUNCTION__);
- if (MachPortNumberIsValid(m_mach_port_number)) {
- SetSuspendCountBeforeResume(others_stopped);
- }
-}
-
-bool MachThread::SetSuspendCountBeforeResume(bool others_stopped) {
- DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )",
- __FUNCTION__);
- DNBError err;
- if (!MachPortNumberIsValid(m_mach_port_number))
- return false;
-
- integer_t times_to_resume;
-
- if (others_stopped) {
- if (GetBasicInfo()) {
- times_to_resume = m_basic_info.suspend_count;
- m_suspend_count = -(times_to_resume - m_suspend_count);
- } else
- times_to_resume = 0;
- } else {
- times_to_resume = m_suspend_count;
- m_suspend_count = 0;
- }
-
- if (times_to_resume > 0) {
- while (times_to_resume > 0) {
- err = ::thread_resume(m_mach_port_number);
- if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail())
- err.LogThreaded("::thread_resume (%4.4" PRIx32 ")", m_mach_port_number);
- if (err.Success())
- --times_to_resume;
- else {
- if (GetBasicInfo())
- times_to_resume = m_basic_info.suspend_count;
- else
- times_to_resume = 0;
- }
- }
- }
- return true;
-}
-
-bool MachThread::RestoreSuspendCountAfterStop() {
- DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )",
- __FUNCTION__);
- DNBError err;
- if (!MachPortNumberIsValid(m_mach_port_number))
- return false;
-
- if (m_suspend_count > 0) {
- while (m_suspend_count > 0) {
- err = ::thread_resume(m_mach_port_number);
- if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail())
- err.LogThreaded("::thread_resume (%4.4" PRIx32 ")", m_mach_port_number);
- if (err.Success())
- --m_suspend_count;
- else {
- if (GetBasicInfo())
- m_suspend_count = m_basic_info.suspend_count;
- else
- m_suspend_count = 0;
- return false; // ???
- }
- }
- } else if (m_suspend_count < 0) {
- while (m_suspend_count < 0) {
- err = ::thread_suspend(m_mach_port_number);
- if (err.Success())
- ++m_suspend_count;
- if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail()) {
- err.LogThreaded("::thread_suspend (%4.4" PRIx32 ")",
- m_mach_port_number);
- return false;
- }
- }
- }
- return true;
-}
-
-const char *MachThread::GetBasicInfoAsString() const {
- static char g_basic_info_string[1024];
- struct thread_basic_info basicInfo;
-
- if (GetBasicInfo(m_mach_port_number, &basicInfo)) {
-
- // char run_state_str[32];
- // size_t run_state_str_size = sizeof(run_state_str);
- // switch (basicInfo.run_state)
- // {
- // case TH_STATE_RUNNING: strlcpy(run_state_str, "running",
- // run_state_str_size); break;
- // case TH_STATE_STOPPED: strlcpy(run_state_str, "stopped",
- // run_state_str_size); break;
- // case TH_STATE_WAITING: strlcpy(run_state_str, "waiting",
- // run_state_str_size); break;
- // case TH_STATE_UNINTERRUPTIBLE: strlcpy(run_state_str,
- // "uninterruptible", run_state_str_size); break;
- // case TH_STATE_HALTED: strlcpy(run_state_str, "halted",
- // run_state_str_size); break;
- // default: snprintf(run_state_str,
- // run_state_str_size, "%d", basicInfo.run_state); break; // ???
- // }
- float user = (float)basicInfo.user_time.seconds +
- (float)basicInfo.user_time.microseconds / 1000000.0f;
- float system = (float)basicInfo.user_time.seconds +
- (float)basicInfo.user_time.microseconds / 1000000.0f;
- snprintf(g_basic_info_string, sizeof(g_basic_info_string),
- "Thread 0x%8.8" PRIx64 ": user=%f system=%f cpu=%d sleep_time=%d",
- m_unique_id, user, system, basicInfo.cpu_usage,
- basicInfo.sleep_time);
-
- return g_basic_info_string;
- }
- return NULL;
-}
-
-// Finds the Mach port number for a given thread in the inferior process' port
-// namespace.
-thread_t MachThread::InferiorThreadID() const {
- mach_msg_type_number_t i;
- mach_port_name_array_t names;
- mach_port_type_array_t types;
- mach_msg_type_number_t ncount, tcount;
- thread_t inferior_tid = INVALID_NUB_THREAD;
- task_t my_task = ::mach_task_self();
- task_t task = m_process->Task().TaskPort();
-
- kern_return_t kret =
- ::mach_port_names(task, &names, &ncount, &types, &tcount);
- if (kret == KERN_SUCCESS) {
-
- for (i = 0; i < ncount; i++) {
- mach_port_t my_name;
- mach_msg_type_name_t my_type;
-
- kret = ::mach_port_extract_right(task, names[i], MACH_MSG_TYPE_COPY_SEND,
- &my_name, &my_type);
- if (kret == KERN_SUCCESS) {
- ::mach_port_deallocate(my_task, my_name);
- if (my_name == m_mach_port_number) {
- inferior_tid = names[i];
- break;
- }
- }
- }
- // Free up the names and types
- ::vm_deallocate(my_task, (vm_address_t)names,
- ncount * sizeof(mach_port_name_t));
- ::vm_deallocate(my_task, (vm_address_t)types,
- tcount * sizeof(mach_port_type_t));
- }
- return inferior_tid;
-}
-
-bool MachThread::IsUserReady() {
- if (m_basic_info.run_state == 0)
- GetBasicInfo();
-
- switch (m_basic_info.run_state) {
- default:
- case TH_STATE_UNINTERRUPTIBLE:
- break;
-
- case TH_STATE_RUNNING:
- case TH_STATE_STOPPED:
- case TH_STATE_WAITING:
- case TH_STATE_HALTED:
- return true;
- }
- return false;
-}
-
-struct thread_basic_info *MachThread::GetBasicInfo() {
- if (MachThread::GetBasicInfo(m_mach_port_number, &m_basic_info))
- return &m_basic_info;
- return NULL;
-}
-
-bool MachThread::GetBasicInfo(thread_t thread,
- struct thread_basic_info *basicInfoPtr) {
- if (MachPortNumberIsValid(thread)) {
- unsigned int info_count = THREAD_BASIC_INFO_COUNT;
- kern_return_t err = ::thread_info(thread, THREAD_BASIC_INFO,
- (thread_info_t)basicInfoPtr, &info_count);
- if (err == KERN_SUCCESS)
- return true;
- }
- ::memset(basicInfoPtr, 0, sizeof(struct thread_basic_info));
- return false;
-}
-
-bool MachThread::ThreadIDIsValid(uint64_t thread) { return thread != 0; }
-
-bool MachThread::MachPortNumberIsValid(thread_t thread) {
- return thread != THREAD_NULL;
-}
-
-bool MachThread::GetRegisterState(int flavor, bool force) {
- return m_arch_ap->GetRegisterState(flavor, force) == KERN_SUCCESS;
-}
-
-bool MachThread::SetRegisterState(int flavor) {
- return m_arch_ap->SetRegisterState(flavor) == KERN_SUCCESS;
-}
-
-uint64_t MachThread::GetPC(uint64_t failValue) {
- // Get program counter
- return m_arch_ap->GetPC(failValue);
-}
-
-bool MachThread::SetPC(uint64_t value) {
- // Set program counter
- return m_arch_ap->SetPC(value);
-}
-
-uint64_t MachThread::GetSP(uint64_t failValue) {
- // Get stack pointer
- return m_arch_ap->GetSP(failValue);
-}
-
-nub_process_t MachThread::ProcessID() const {
- if (m_process)
- return m_process->ProcessID();
- return INVALID_NUB_PROCESS;
-}
-
-void MachThread::Dump(uint32_t index) {
- const char *thread_run_state = NULL;
-
- switch (m_basic_info.run_state) {
- case TH_STATE_RUNNING:
- thread_run_state = "running";
- break; // 1 thread is running normally
- case TH_STATE_STOPPED:
- thread_run_state = "stopped";
- break; // 2 thread is stopped
- case TH_STATE_WAITING:
- thread_run_state = "waiting";
- break; // 3 thread is waiting normally
- case TH_STATE_UNINTERRUPTIBLE:
- thread_run_state = "uninter";
- break; // 4 thread is in an uninterruptible wait
- case TH_STATE_HALTED:
- thread_run_state = "halted ";
- break; // 5 thread is halted at a
- default:
- thread_run_state = "???";
- break;
- }
-
- DNBLogThreaded(
- "[%3u] #%3u tid: 0x%8.8" PRIx64 ", pc: 0x%16.16" PRIx64
- ", sp: 0x%16.16" PRIx64
- ", user: %d.%6.6d, system: %d.%6.6d, cpu: %2d, policy: %2d, run_state: "
- "%2d (%s), flags: %2d, suspend_count: %2d (current %2d), sleep_time: %d",
- index, m_seq_id, m_unique_id, GetPC(INVALID_NUB_ADDRESS),
- GetSP(INVALID_NUB_ADDRESS), m_basic_info.user_time.seconds,
- m_basic_info.user_time.microseconds, m_basic_info.system_time.seconds,
- m_basic_info.system_time.microseconds, m_basic_info.cpu_usage,
- m_basic_info.policy, m_basic_info.run_state, thread_run_state,
- m_basic_info.flags, m_basic_info.suspend_count, m_suspend_count,
- m_basic_info.sleep_time);
- // DumpRegisterState(0);
-}
-
-void MachThread::ThreadWillResume(const DNBThreadResumeAction *thread_action,
- bool others_stopped) {
- if (thread_action->addr != INVALID_NUB_ADDRESS)
- SetPC(thread_action->addr);
-
- SetState(thread_action->state);
- switch (thread_action->state) {
- case eStateStopped:
- case eStateSuspended:
- assert(others_stopped == false);
- Suspend();
- break;
-
- case eStateRunning:
- case eStateStepping:
- Resume(others_stopped);
- break;
- default:
- break;
- }
- m_arch_ap->ThreadWillResume();
- m_stop_exception.Clear();
-}
-
-DNBBreakpoint *MachThread::CurrentBreakpoint() {
- return m_process->Breakpoints().FindByAddress(GetPC());
-}
-
-bool MachThread::ShouldStop(bool &step_more) {
- // See if this thread is at a breakpoint?
- DNBBreakpoint *bp = CurrentBreakpoint();
-
- if (bp) {
- // This thread is sitting at a breakpoint, ask the breakpoint
- // if we should be stopping here.
- return true;
- } else {
- if (m_arch_ap->StepNotComplete()) {
- step_more = true;
- return false;
- }
- // The thread state is used to let us know what the thread was
- // trying to do. MachThread::ThreadWillResume() will set the
- // thread state to various values depending if the thread was
- // the current thread and if it was to be single stepped, or
- // resumed.
- if (GetState() == eStateRunning) {
- // If our state is running, then we should continue as we are in
- // the process of stepping over a breakpoint.
- return false;
- } else {
- // Stop if we have any kind of valid exception for this
- // thread.
- if (GetStopException().IsValid())
- return true;
- }
- }
- return false;
-}
-bool MachThread::IsStepping() { return GetState() == eStateStepping; }
-
-bool MachThread::ThreadDidStop() {
- // This thread has existed prior to resuming under debug nub control,
- // and has just been stopped. Do any cleanup that needs to be done
- // after running.
-
- // The thread state and breakpoint will still have the same values
- // as they had prior to resuming the thread, so it makes it easy to check
- // if we were trying to step a thread, or we tried to resume while being
- // at a breakpoint.
-
- // When this method gets called, the process state is still in the
- // state it was in while running so we can act accordingly.
- m_arch_ap->ThreadDidStop();
-
- // We may have suspended this thread so the primary thread could step
- // without worrying about race conditions, so lets restore our suspend
- // count.
- RestoreSuspendCountAfterStop();
-
- // Update the basic information for a thread
- MachThread::GetBasicInfo(m_mach_port_number, &m_basic_info);
-
- if (m_basic_info.suspend_count > 0)
- SetState(eStateSuspended);
- else
- SetState(eStateStopped);
- return true;
-}
-
-bool MachThread::NotifyException(MachException::Data &exc) {
- // Allow the arch specific protocol to process (MachException::Data &)exc
- // first before possible reassignment of m_stop_exception with exc.
- // See also MachThread::GetStopException().
- bool handled = m_arch_ap->NotifyException(exc);
-
- if (m_stop_exception.IsValid()) {
- // We may have more than one exception for a thread, but we need to
- // only remember the one that we will say is the reason we stopped.
- // We may have been single stepping and also gotten a signal exception,
- // so just remember the most pertinent one.
- if (m_stop_exception.IsBreakpoint())
- m_stop_exception = exc;
- } else {
- m_stop_exception = exc;
- }
-
- return handled;
-}
-
-nub_state_t MachThread::GetState() {
- // If any other threads access this we will need a mutex for it
- PTHREAD_MUTEX_LOCKER(locker, m_state_mutex);
- return m_state;
-}
-
-void MachThread::SetState(nub_state_t state) {
- PTHREAD_MUTEX_LOCKER(locker, m_state_mutex);
- m_state = state;
- DNBLogThreadedIf(LOG_THREAD,
- "MachThread::SetState ( %s ) for tid = 0x%8.8" PRIx64 "",
- DNBStateAsString(state), m_unique_id);
-}
-
-nub_size_t MachThread::GetNumRegistersInSet(nub_size_t regSet) const {
- if (regSet < m_num_reg_sets)
- return m_reg_sets[regSet].num_registers;
- return 0;
-}
-
-const char *MachThread::GetRegisterSetName(nub_size_t regSet) const {
- if (regSet < m_num_reg_sets)
- return m_reg_sets[regSet].name;
- return NULL;
-}
-
-const DNBRegisterInfo *MachThread::GetRegisterInfo(nub_size_t regSet,
- nub_size_t regIndex) const {
- if (regSet < m_num_reg_sets)
- if (regIndex < m_reg_sets[regSet].num_registers)
- return &m_reg_sets[regSet].registers[regIndex];
- return NULL;
-}
-void MachThread::DumpRegisterState(nub_size_t regSet) {
- if (regSet == REGISTER_SET_ALL) {
- for (regSet = 1; regSet < m_num_reg_sets; regSet++)
- DumpRegisterState(regSet);
- } else {
- if (m_arch_ap->RegisterSetStateIsValid((int)regSet)) {
- const size_t numRegisters = GetNumRegistersInSet(regSet);
- uint32_t regIndex = 0;
- DNBRegisterValueClass reg;
- for (regIndex = 0; regIndex < numRegisters; ++regIndex) {
- if (m_arch_ap->GetRegisterValue((uint32_t)regSet, regIndex, &reg)) {
- reg.Dump(NULL, NULL);
- }
- }
- } else {
- DNBLog("%s: registers are not currently valid.",
- GetRegisterSetName(regSet));
- }
- }
-}
-
-const DNBRegisterSetInfo *
-MachThread::GetRegisterSetInfo(nub_size_t *num_reg_sets) const {
- *num_reg_sets = m_num_reg_sets;
- return &m_reg_sets[0];
-}
-
-bool MachThread::GetRegisterValue(uint32_t set, uint32_t reg,
- DNBRegisterValue *value) {
- return m_arch_ap->GetRegisterValue(set, reg, value);
-}
-
-bool MachThread::SetRegisterValue(uint32_t set, uint32_t reg,
- const DNBRegisterValue *value) {
- return m_arch_ap->SetRegisterValue(set, reg, value);
-}
-
-nub_size_t MachThread::GetRegisterContext(void *buf, nub_size_t buf_len) {
- return m_arch_ap->GetRegisterContext(buf, buf_len);
-}
-
-nub_size_t MachThread::SetRegisterContext(const void *buf, nub_size_t buf_len) {
- return m_arch_ap->SetRegisterContext(buf, buf_len);
-}
-
-uint32_t MachThread::SaveRegisterState() {
- return m_arch_ap->SaveRegisterState();
-}
-bool MachThread::RestoreRegisterState(uint32_t save_id) {
- return m_arch_ap->RestoreRegisterState(save_id);
-}
-
-uint32_t MachThread::EnableHardwareBreakpoint(const DNBBreakpoint *bp) {
- if (bp != NULL && bp->IsBreakpoint())
- return m_arch_ap->EnableHardwareBreakpoint(bp->Address(), bp->ByteSize());
- return INVALID_NUB_HW_INDEX;
-}
-
-uint32_t MachThread::EnableHardwareWatchpoint(const DNBBreakpoint *wp,
- bool also_set_on_task) {
- if (wp != NULL && wp->IsWatchpoint())
- return m_arch_ap->EnableHardwareWatchpoint(
- wp->Address(), wp->ByteSize(), wp->WatchpointRead(),
- wp->WatchpointWrite(), also_set_on_task);
- return INVALID_NUB_HW_INDEX;
-}
-
-bool MachThread::RollbackTransForHWP() {
- return m_arch_ap->RollbackTransForHWP();
-}
-
-bool MachThread::FinishTransForHWP() { return m_arch_ap->FinishTransForHWP(); }
-
-bool MachThread::DisableHardwareBreakpoint(const DNBBreakpoint *bp) {
- if (bp != NULL && bp->IsHardware())
- return m_arch_ap->DisableHardwareBreakpoint(bp->GetHardwareIndex());
- return false;
-}
-
-bool MachThread::DisableHardwareWatchpoint(const DNBBreakpoint *wp,
- bool also_set_on_task) {
- if (wp != NULL && wp->IsHardware())
- return m_arch_ap->DisableHardwareWatchpoint(wp->GetHardwareIndex(),
- also_set_on_task);
- return false;
-}
-
-uint32_t MachThread::NumSupportedHardwareWatchpoints() const {
- return m_arch_ap->NumSupportedHardwareWatchpoints();
-}
-
-bool MachThread::GetIdentifierInfo() {
- // Don't try to get the thread info once and cache it for the life of the
- // thread. It changes over time, for instance
- // if the thread name changes, then the thread_handle also changes... So you
- // have to refetch it every time.
- mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
- kern_return_t kret = ::thread_info(m_mach_port_number, THREAD_IDENTIFIER_INFO,
- (thread_info_t)&m_ident_info, &count);
- return kret == KERN_SUCCESS;
-
- return false;
-}
-
-const char *MachThread::GetName() {
- if (GetIdentifierInfo()) {
- int len = ::proc_pidinfo(m_process->ProcessID(), PROC_PIDTHREADINFO,
- m_ident_info.thread_handle, &m_proc_threadinfo,
- sizeof(m_proc_threadinfo));
-
- if (len && m_proc_threadinfo.pth_name[0])
- return m_proc_threadinfo.pth_name;
- }
- return NULL;
-}
-
-uint64_t
-MachThread::GetGloballyUniqueThreadIDForMachPortID(thread_t mach_port_id) {
- kern_return_t kr;
- thread_identifier_info_data_t tident;
- mach_msg_type_number_t tident_count = THREAD_IDENTIFIER_INFO_COUNT;
- kr = thread_info(mach_port_id, THREAD_IDENTIFIER_INFO, (thread_info_t)&tident,
- &tident_count);
- if (kr != KERN_SUCCESS) {
- return mach_port_id;
- }
- return tident.thread_id;
-}
-
-nub_addr_t MachThread::GetPThreadT() {
- nub_addr_t pthread_t_value = INVALID_NUB_ADDRESS;
- if (MachPortNumberIsValid(m_mach_port_number)) {
- kern_return_t kr;
- thread_identifier_info_data_t tident;
- mach_msg_type_number_t tident_count = THREAD_IDENTIFIER_INFO_COUNT;
- kr = thread_info(m_mach_port_number, THREAD_IDENTIFIER_INFO,
- (thread_info_t)&tident, &tident_count);
- if (kr == KERN_SUCCESS) {
- // Dereference thread_handle to get the pthread_t value for this thread.
- if (m_is_64_bit) {
- uint64_t addr;
- if (m_process->ReadMemory(tident.thread_handle, 8, &addr) == 8) {
- if (addr != 0) {
- pthread_t_value = addr;
- }
- }
- } else {
- uint32_t addr;
- if (m_process->ReadMemory(tident.thread_handle, 4, &addr) == 4) {
- if (addr != 0) {
- pthread_t_value = addr;
- }
- }
- }
- }
- }
- return pthread_t_value;
-}
-
-// Return this thread's TSD (Thread Specific Data) address.
-// This is computed based on this thread's pthread_t value.
-//
-// We compute the TSD from the pthread_t by one of two methods.
-//
-// If plo_pthread_tsd_base_offset is non-zero, this is a simple offset that we
-// add to
-// the pthread_t to get the TSD base address.
-//
-// Else we read a pointer from memory at pthread_t +
-// plo_pthread_tsd_base_address_offset and
-// that gives us the TSD address.
-//
-// These plo_pthread_tsd_base values must be read out of libpthread by lldb &
-// provided to debugserver.
-
-nub_addr_t
-MachThread::GetTSDAddressForThread(uint64_t plo_pthread_tsd_base_address_offset,
- uint64_t plo_pthread_tsd_base_offset,
- uint64_t plo_pthread_tsd_entry_size) {
- nub_addr_t tsd_addr = INVALID_NUB_ADDRESS;
- nub_addr_t pthread_t_value = GetPThreadT();
- if (plo_pthread_tsd_base_offset != 0 &&
- plo_pthread_tsd_base_offset != INVALID_NUB_ADDRESS) {
- tsd_addr = pthread_t_value + plo_pthread_tsd_base_offset;
- } else {
- if (plo_pthread_tsd_entry_size == 4) {
- uint32_t addr = 0;
- if (m_process->ReadMemory(pthread_t_value +
- plo_pthread_tsd_base_address_offset,
- 4, &addr) == 4) {
- if (addr != 0) {
- tsd_addr = addr;
- }
- }
- }
- if (plo_pthread_tsd_entry_size == 4) {
- uint64_t addr = 0;
- if (m_process->ReadMemory(pthread_t_value +
- plo_pthread_tsd_base_address_offset,
- 8, &addr) == 8) {
- if (addr != 0) {
- tsd_addr = addr;
- }
- }
- }
- }
- return tsd_addr;
-}
-
-nub_addr_t MachThread::GetDispatchQueueT() {
- nub_addr_t dispatch_queue_t_value = INVALID_NUB_ADDRESS;
- if (MachPortNumberIsValid(m_mach_port_number)) {
- kern_return_t kr;
- thread_identifier_info_data_t tident;
- mach_msg_type_number_t tident_count = THREAD_IDENTIFIER_INFO_COUNT;
- kr = thread_info(m_mach_port_number, THREAD_IDENTIFIER_INFO,
- (thread_info_t)&tident, &tident_count);
- if (kr == KERN_SUCCESS && tident.dispatch_qaddr != 0 &&
- tident.dispatch_qaddr != INVALID_NUB_ADDRESS) {
- // Dereference dispatch_qaddr to get the dispatch_queue_t value for this
- // thread's queue, if any.
- if (m_is_64_bit) {
- uint64_t addr;
- if (m_process->ReadMemory(tident.dispatch_qaddr, 8, &addr) == 8) {
- if (addr != 0)
- dispatch_queue_t_value = addr;
- }
- } else {
- uint32_t addr;
- if (m_process->ReadMemory(tident.dispatch_qaddr, 4, &addr) == 4) {
- if (addr != 0)
- dispatch_queue_t_value = addr;
- }
- }
- }
- }
- return dispatch_queue_t_value;
-}
-
-ThreadInfo::QoS MachThread::GetRequestedQoS(nub_addr_t tsd,
- uint64_t dti_qos_class_index) {
- ThreadInfo::QoS qos_value;
- if (MachPortNumberIsValid(m_mach_port_number) &&
- m_pthread_qos_class_decode != nullptr) {
- uint64_t pthread_priority_value = 0;
- if (m_is_64_bit) {
- uint64_t pri;
- if (m_process->ReadMemory(tsd + (dti_qos_class_index * 8), 8, &pri) ==
- 8) {
- pthread_priority_value = pri;
- }
- } else {
- uint32_t pri;
- if (m_process->ReadMemory(tsd + (dti_qos_class_index * 4), 4, &pri) ==
- 4) {
- pthread_priority_value = pri;
- }
- }
-
- uint32_t requested_qos =
- m_pthread_qos_class_decode(pthread_priority_value, NULL, NULL);
-
- switch (requested_qos) {
- // These constants from <pthread/qos.h>
- case 0x21:
- qos_value.enum_value = requested_qos;
- qos_value.constant_name = "QOS_CLASS_USER_INTERACTIVE";
- qos_value.printable_name = "User Interactive";
- break;
- case 0x19:
- qos_value.enum_value = requested_qos;
- qos_value.constant_name = "QOS_CLASS_USER_INITIATED";
- qos_value.printable_name = "User Initiated";
- break;
- case 0x15:
- qos_value.enum_value = requested_qos;
- qos_value.constant_name = "QOS_CLASS_DEFAULT";
- qos_value.printable_name = "Default";
- break;
- case 0x11:
- qos_value.enum_value = requested_qos;
- qos_value.constant_name = "QOS_CLASS_UTILITY";
- qos_value.printable_name = "Utility";
- break;
- case 0x09:
- qos_value.enum_value = requested_qos;
- qos_value.constant_name = "QOS_CLASS_BACKGROUND";
- qos_value.printable_name = "Background";
- break;
- case 0x00:
- qos_value.enum_value = requested_qos;
- qos_value.constant_name = "QOS_CLASS_UNSPECIFIED";
- qos_value.printable_name = "Unspecified";
- break;
- }
- }
- return qos_value;
-}
diff --git a/tools/debugserver/source/MacOSX/MachThread.h b/tools/debugserver/source/MacOSX/MachThread.h
deleted file mode 100644
index a98d8aa2b05c..000000000000
--- a/tools/debugserver/source/MacOSX/MachThread.h
+++ /dev/null
@@ -1,170 +0,0 @@
-//===-- MachThread.h --------------------------------------------*- 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/19/07.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __MachThread_h__
-#define __MachThread_h__
-
-#include <string>
-#include <vector>
-
-#include <libproc.h>
-#include <mach/mach.h>
-#include <pthread.h>
-#include <sys/signal.h>
-
-#include "DNBArch.h"
-#include "DNBRegisterInfo.h"
-#include "MachException.h"
-#include "PThreadCondition.h"
-#include "PThreadMutex.h"
-
-#include "ThreadInfo.h"
-
-class DNBBreakpoint;
-class MachProcess;
-class MachThreadList;
-
-class MachThread {
-public:
- MachThread(MachProcess *process, bool is_64_bit,
- uint64_t unique_thread_id = 0, thread_t mach_port_number = 0);
- ~MachThread();
-
- MachProcess *Process() { return m_process; }
- const MachProcess *Process() const { return m_process; }
- nub_process_t ProcessID() const;
- void Dump(uint32_t index);
- uint64_t ThreadID() const { return m_unique_id; }
- thread_t MachPortNumber() const { return m_mach_port_number; }
- thread_t InferiorThreadID() const;
-
- uint32_t SequenceID() const { return m_seq_id; }
- static bool ThreadIDIsValid(
- uint64_t thread); // The 64-bit system-wide unique thread identifier
- static bool MachPortNumberIsValid(thread_t thread); // The mach port # for
- // this thread in
- // debugserver namespace
- void Resume(bool others_stopped);
- void Suspend();
- bool SetSuspendCountBeforeResume(bool others_stopped);
- bool RestoreSuspendCountAfterStop();
-
- bool GetRegisterState(int flavor, bool force);
- bool SetRegisterState(int flavor);
- uint64_t
- GetPC(uint64_t failValue = INVALID_NUB_ADDRESS); // Get program counter
- bool SetPC(uint64_t value); // Set program counter
- uint64_t GetSP(uint64_t failValue = INVALID_NUB_ADDRESS); // Get stack pointer
-
- DNBBreakpoint *CurrentBreakpoint();
- uint32_t EnableHardwareBreakpoint(const DNBBreakpoint *breakpoint);
- uint32_t EnableHardwareWatchpoint(const DNBBreakpoint *watchpoint,
- bool also_set_on_task);
- bool DisableHardwareBreakpoint(const DNBBreakpoint *breakpoint);
- bool DisableHardwareWatchpoint(const DNBBreakpoint *watchpoint,
- bool also_set_on_task);
- uint32_t NumSupportedHardwareWatchpoints() const;
- bool RollbackTransForHWP();
- bool FinishTransForHWP();
-
- nub_state_t GetState();
- void SetState(nub_state_t state);
-
- void ThreadWillResume(const DNBThreadResumeAction *thread_action,
- bool others_stopped = false);
- bool ShouldStop(bool &step_more);
- bool IsStepping();
- bool ThreadDidStop();
- bool NotifyException(MachException::Data &exc);
- const MachException::Data &GetStopException() { return m_stop_exception; }
-
- nub_size_t GetNumRegistersInSet(nub_size_t regSet) const;
- const char *GetRegisterSetName(nub_size_t regSet) const;
- const DNBRegisterInfo *GetRegisterInfo(nub_size_t regSet,
- nub_size_t regIndex) const;
- void DumpRegisterState(nub_size_t regSet);
- const DNBRegisterSetInfo *GetRegisterSetInfo(nub_size_t *num_reg_sets) const;
- bool GetRegisterValue(uint32_t reg_set_idx, uint32_t reg_idx,
- DNBRegisterValue *reg_value);
- bool SetRegisterValue(uint32_t reg_set_idx, uint32_t reg_idx,
- const DNBRegisterValue *reg_value);
- nub_size_t GetRegisterContext(void *buf, nub_size_t buf_len);
- nub_size_t SetRegisterContext(const void *buf, nub_size_t buf_len);
- uint32_t SaveRegisterState();
- bool RestoreRegisterState(uint32_t save_id);
-
- void NotifyBreakpointChanged(const DNBBreakpoint *bp) {}
-
- bool IsUserReady();
- struct thread_basic_info *GetBasicInfo();
- const char *GetBasicInfoAsString() const;
- const char *GetName();
-
- DNBArchProtocol *GetArchProtocol() { return m_arch_ap.get(); }
-
- ThreadInfo::QoS GetRequestedQoS(nub_addr_t tsd, uint64_t dti_qos_class_index);
- nub_addr_t GetPThreadT();
- nub_addr_t GetDispatchQueueT();
- nub_addr_t
- GetTSDAddressForThread(uint64_t plo_pthread_tsd_base_address_offset,
- uint64_t plo_pthread_tsd_base_offset,
- uint64_t plo_pthread_tsd_entry_size);
-
- static uint64_t GetGloballyUniqueThreadIDForMachPortID(thread_t mach_port_id);
-
-protected:
- static bool GetBasicInfo(thread_t threadID,
- struct thread_basic_info *basic_info);
-
- bool GetIdentifierInfo();
-
- // const char *
- // GetDispatchQueueName();
- //
- MachProcess *m_process; // The process that owns this thread
- uint64_t m_unique_id; // The globally unique ID for this thread (nub_thread_t)
- thread_t m_mach_port_number; // The mach port # for this thread in debugserver
- // namesp.
- uint32_t m_seq_id; // A Sequential ID that increments with each new thread
- nub_state_t m_state; // The state of our process
- PThreadMutex m_state_mutex; // Multithreaded protection for m_state
- struct thread_basic_info m_basic_info; // Basic information for a thread used
- // to see if a thread is valid
- int32_t m_suspend_count; // The current suspend count > 0 means we have
- // suspended m_suspendCount times,
- // < 0 means we have resumed it m_suspendCount
- // times.
- MachException::Data m_stop_exception; // The best exception that describes why
- // this thread is stopped
- std::unique_ptr<DNBArchProtocol>
- m_arch_ap; // Arch specific information for register state and more
- const DNBRegisterSetInfo
- *m_reg_sets; // Register set information for this thread
- nub_size_t m_num_reg_sets;
- thread_identifier_info_data_t m_ident_info;
- struct proc_threadinfo m_proc_threadinfo;
- std::string m_dispatch_queue_name;
- bool m_is_64_bit;
-
- // qos_class_t _pthread_qos_class_decode(pthread_priority_t priority, int *,
- // unsigned long *);
- unsigned int (*m_pthread_qos_class_decode)(unsigned long priority, int *,
- unsigned long *);
-
-private:
- friend class MachThreadList;
-};
-
-typedef std::shared_ptr<MachThread> MachThreadSP;
-
-#endif
diff --git a/tools/debugserver/source/MacOSX/MachThreadList.cpp b/tools/debugserver/source/MacOSX/MachThreadList.cpp
deleted file mode 100644
index 05e9627b591b..000000000000
--- a/tools/debugserver/source/MacOSX/MachThreadList.cpp
+++ /dev/null
@@ -1,582 +0,0 @@
-//===-- MachThreadList.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/19/07.
-//
-//===----------------------------------------------------------------------===//
-
-#include "MachThreadList.h"
-
-#include <inttypes.h>
-#include <sys/sysctl.h>
-
-#include "DNBLog.h"
-#include "DNBThreadResumeActions.h"
-#include "MachProcess.h"
-
-MachThreadList::MachThreadList()
- : m_threads(), m_threads_mutex(PTHREAD_MUTEX_RECURSIVE),
- m_is_64_bit(false) {}
-
-MachThreadList::~MachThreadList() {}
-
-nub_state_t MachThreadList::GetState(nub_thread_t tid) {
- MachThreadSP thread_sp(GetThreadByID(tid));
- if (thread_sp)
- return thread_sp->GetState();
- return eStateInvalid;
-}
-
-const char *MachThreadList::GetName(nub_thread_t tid) {
- MachThreadSP thread_sp(GetThreadByID(tid));
- if (thread_sp)
- return thread_sp->GetName();
- return NULL;
-}
-
-ThreadInfo::QoS MachThreadList::GetRequestedQoS(nub_thread_t tid,
- nub_addr_t tsd,
- uint64_t dti_qos_class_index) {
- MachThreadSP thread_sp(GetThreadByID(tid));
- if (thread_sp)
- return thread_sp->GetRequestedQoS(tsd, dti_qos_class_index);
- return ThreadInfo::QoS();
-}
-
-nub_addr_t MachThreadList::GetPThreadT(nub_thread_t tid) {
- MachThreadSP thread_sp(GetThreadByID(tid));
- if (thread_sp)
- return thread_sp->GetPThreadT();
- return INVALID_NUB_ADDRESS;
-}
-
-nub_addr_t MachThreadList::GetDispatchQueueT(nub_thread_t tid) {
- MachThreadSP thread_sp(GetThreadByID(tid));
- if (thread_sp)
- return thread_sp->GetDispatchQueueT();
- return INVALID_NUB_ADDRESS;
-}
-
-nub_addr_t MachThreadList::GetTSDAddressForThread(
- nub_thread_t tid, uint64_t plo_pthread_tsd_base_address_offset,
- uint64_t plo_pthread_tsd_base_offset, uint64_t plo_pthread_tsd_entry_size) {
- MachThreadSP thread_sp(GetThreadByID(tid));
- if (thread_sp)
- return thread_sp->GetTSDAddressForThread(
- plo_pthread_tsd_base_address_offset, plo_pthread_tsd_base_offset,
- plo_pthread_tsd_entry_size);
- return INVALID_NUB_ADDRESS;
-}
-
-nub_thread_t MachThreadList::SetCurrentThread(nub_thread_t tid) {
- MachThreadSP thread_sp(GetThreadByID(tid));
- if (thread_sp) {
- m_current_thread = thread_sp;
- return tid;
- }
- return INVALID_NUB_THREAD;
-}
-
-bool MachThreadList::GetThreadStoppedReason(
- nub_thread_t tid, struct DNBThreadStopInfo *stop_info) const {
- MachThreadSP thread_sp(GetThreadByID(tid));
- if (thread_sp)
- return thread_sp->GetStopException().GetStopInfo(stop_info);
- return false;
-}
-
-bool MachThreadList::GetIdentifierInfo(
- nub_thread_t tid, thread_identifier_info_data_t *ident_info) {
- thread_t mach_port_number = GetMachPortNumberByThreadID(tid);
-
- mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
- return ::thread_info(mach_port_number, THREAD_IDENTIFIER_INFO,
- (thread_info_t)ident_info, &count) == KERN_SUCCESS;
-}
-
-void MachThreadList::DumpThreadStoppedReason(nub_thread_t tid) const {
- MachThreadSP thread_sp(GetThreadByID(tid));
- if (thread_sp)
- thread_sp->GetStopException().DumpStopReason();
-}
-
-const char *MachThreadList::GetThreadInfo(nub_thread_t tid) const {
- MachThreadSP thread_sp(GetThreadByID(tid));
- if (thread_sp)
- return thread_sp->GetBasicInfoAsString();
- return NULL;
-}
-
-MachThreadSP MachThreadList::GetThreadByID(nub_thread_t tid) const {
- PTHREAD_MUTEX_LOCKER(locker, m_threads_mutex);
- MachThreadSP thread_sp;
- const size_t num_threads = m_threads.size();
- for (size_t idx = 0; idx < num_threads; ++idx) {
- if (m_threads[idx]->ThreadID() == tid) {
- thread_sp = m_threads[idx];
- break;
- }
- }
- return thread_sp;
-}
-
-MachThreadSP
-MachThreadList::GetThreadByMachPortNumber(thread_t mach_port_number) const {
- PTHREAD_MUTEX_LOCKER(locker, m_threads_mutex);
- MachThreadSP thread_sp;
- const size_t num_threads = m_threads.size();
- for (size_t idx = 0; idx < num_threads; ++idx) {
- if (m_threads[idx]->MachPortNumber() == mach_port_number) {
- thread_sp = m_threads[idx];
- break;
- }
- }
- return thread_sp;
-}
-
-nub_thread_t
-MachThreadList::GetThreadIDByMachPortNumber(thread_t mach_port_number) const {
- PTHREAD_MUTEX_LOCKER(locker, m_threads_mutex);
- MachThreadSP thread_sp;
- const size_t num_threads = m_threads.size();
- for (size_t idx = 0; idx < num_threads; ++idx) {
- if (m_threads[idx]->MachPortNumber() == mach_port_number) {
- return m_threads[idx]->ThreadID();
- }
- }
- return INVALID_NUB_THREAD;
-}
-
-thread_t MachThreadList::GetMachPortNumberByThreadID(
- nub_thread_t globally_unique_id) const {
- PTHREAD_MUTEX_LOCKER(locker, m_threads_mutex);
- MachThreadSP thread_sp;
- const size_t num_threads = m_threads.size();
- for (size_t idx = 0; idx < num_threads; ++idx) {
- if (m_threads[idx]->ThreadID() == globally_unique_id) {
- return m_threads[idx]->MachPortNumber();
- }
- }
- return 0;
-}
-
-bool MachThreadList::GetRegisterValue(nub_thread_t tid, uint32_t set,
- uint32_t reg,
- DNBRegisterValue *reg_value) const {
- MachThreadSP thread_sp(GetThreadByID(tid));
- if (thread_sp)
- return thread_sp->GetRegisterValue(set, reg, reg_value);
-
- return false;
-}
-
-bool MachThreadList::SetRegisterValue(nub_thread_t tid, uint32_t set,
- uint32_t reg,
- const DNBRegisterValue *reg_value) const {
- MachThreadSP thread_sp(GetThreadByID(tid));
- if (thread_sp)
- return thread_sp->SetRegisterValue(set, reg, reg_value);
-
- return false;
-}
-
-nub_size_t MachThreadList::GetRegisterContext(nub_thread_t tid, void *buf,
- size_t buf_len) {
- MachThreadSP thread_sp(GetThreadByID(tid));
- if (thread_sp)
- return thread_sp->GetRegisterContext(buf, buf_len);
- return 0;
-}
-
-nub_size_t MachThreadList::SetRegisterContext(nub_thread_t tid, const void *buf,
- size_t buf_len) {
- MachThreadSP thread_sp(GetThreadByID(tid));
- if (thread_sp)
- return thread_sp->SetRegisterContext(buf, buf_len);
- return 0;
-}
-
-uint32_t MachThreadList::SaveRegisterState(nub_thread_t tid) {
- MachThreadSP thread_sp(GetThreadByID(tid));
- if (thread_sp)
- return thread_sp->SaveRegisterState();
- return 0;
-}
-
-bool MachThreadList::RestoreRegisterState(nub_thread_t tid, uint32_t save_id) {
- MachThreadSP thread_sp(GetThreadByID(tid));
- if (thread_sp)
- return thread_sp->RestoreRegisterState(save_id);
- return 0;
-}
-
-nub_size_t MachThreadList::NumThreads() const {
- PTHREAD_MUTEX_LOCKER(locker, m_threads_mutex);
- return m_threads.size();
-}
-
-nub_thread_t MachThreadList::ThreadIDAtIndex(nub_size_t idx) const {
- PTHREAD_MUTEX_LOCKER(locker, m_threads_mutex);
- if (idx < m_threads.size())
- return m_threads[idx]->ThreadID();
- return INVALID_NUB_THREAD;
-}
-
-nub_thread_t MachThreadList::CurrentThreadID() {
- MachThreadSP thread_sp;
- CurrentThread(thread_sp);
- if (thread_sp.get())
- return thread_sp->ThreadID();
- return INVALID_NUB_THREAD;
-}
-
-bool MachThreadList::NotifyException(MachException::Data &exc) {
- MachThreadSP thread_sp(GetThreadByMachPortNumber(exc.thread_port));
- if (thread_sp) {
- thread_sp->NotifyException(exc);
- return true;
- }
- return false;
-}
-
-void MachThreadList::Clear() {
- PTHREAD_MUTEX_LOCKER(locker, m_threads_mutex);
- m_threads.clear();
-}
-
-uint32_t
-MachThreadList::UpdateThreadList(MachProcess *process, bool update,
- MachThreadList::collection *new_threads) {
- // locker will keep a mutex locked until it goes out of scope
- 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 (process->StopCount() == 0) {
- int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, process->ProcessID()};
- struct kinfo_proc processInfo;
- size_t bufsize = sizeof(processInfo);
- if (sysctl(mib, (unsigned)(sizeof(mib) / sizeof(int)), &processInfo,
- &bufsize, NULL, 0) == 0 &&
- bufsize > 0) {
- if (processInfo.kp_proc.p_flag & P_LP64)
- m_is_64_bit = true;
- }
-#if defined(__i386__) || defined(__x86_64__)
- if (m_is_64_bit)
- DNBArchProtocol::SetArchitecture(CPU_TYPE_X86_64);
- else
- DNBArchProtocol::SetArchitecture(CPU_TYPE_I386);
-#elif defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
- if (m_is_64_bit)
- DNBArchProtocol::SetArchitecture(CPU_TYPE_ARM64);
- else
- DNBArchProtocol::SetArchitecture(CPU_TYPE_ARM);
-#endif
- }
-
- if (m_threads.empty() || update) {
- thread_array_t thread_list = NULL;
- mach_msg_type_number_t thread_list_count = 0;
- task_t task = process->Task().TaskPort();
- DNBError err(::task_threads(task, &thread_list, &thread_list_count),
- DNBError::MachKernel);
-
- if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail())
- err.LogThreaded("::task_threads ( task = 0x%4.4x, thread_list => %p, "
- "thread_list_count => %u )",
- task, thread_list, thread_list_count);
-
- if (err.Status() == KERN_SUCCESS && thread_list_count > 0) {
- MachThreadList::collection currThreads;
- size_t idx;
- // Iterator through the current thread list and see which threads
- // we already have in our list (keep them), which ones we don't
- // (add them), and which ones are not around anymore (remove them).
- for (idx = 0; idx < thread_list_count; ++idx) {
- const thread_t mach_port_num = thread_list[idx];
-
- uint64_t unique_thread_id =
- MachThread::GetGloballyUniqueThreadIDForMachPortID(mach_port_num);
- MachThreadSP thread_sp(GetThreadByID(unique_thread_id));
- if (thread_sp) {
- // Keep the existing thread class
- currThreads.push_back(thread_sp);
- } else {
- // We don't have this thread, lets add it.
- thread_sp.reset(new MachThread(process, m_is_64_bit, unique_thread_id,
- mach_port_num));
-
- // Add the new thread regardless of its is user ready state...
- // Make sure the thread is ready to be displayed and shown to users
- // before we add this thread to our list...
- if (thread_sp->IsUserReady()) {
- if (new_threads)
- new_threads->push_back(thread_sp);
-
- currThreads.push_back(thread_sp);
- }
- }
- }
-
- m_threads.swap(currThreads);
- m_current_thread.reset();
-
- // Free the vm memory given to us by ::task_threads()
- vm_size_t thread_list_size =
- (vm_size_t)(thread_list_count * sizeof(thread_t));
- ::vm_deallocate(::mach_task_self(), (vm_address_t)thread_list,
- thread_list_size);
- }
- }
- return static_cast<uint32_t>(m_threads.size());
-}
-
-void MachThreadList::CurrentThread(MachThreadSP &thread_sp) {
- // locker will keep a mutex locked until it goes out of scope
- PTHREAD_MUTEX_LOCKER(locker, m_threads_mutex);
- if (m_current_thread.get() == NULL) {
- // Figure out which thread is going to be our current thread.
- // This is currently done by finding the first thread in the list
- // that has a valid exception.
- const size_t num_threads = m_threads.size();
- for (uint32_t idx = 0; idx < num_threads; ++idx) {
- if (m_threads[idx]->GetStopException().IsValid()) {
- m_current_thread = m_threads[idx];
- break;
- }
- }
- }
- thread_sp = m_current_thread;
-}
-
-void MachThreadList::Dump() const {
- PTHREAD_MUTEX_LOCKER(locker, m_threads_mutex);
- const size_t num_threads = m_threads.size();
- for (uint32_t idx = 0; idx < num_threads; ++idx) {
- m_threads[idx]->Dump(idx);
- }
-}
-
-void MachThreadList::ProcessWillResume(
- MachProcess *process, const DNBThreadResumeActions &thread_actions) {
- PTHREAD_MUTEX_LOCKER(locker, m_threads_mutex);
-
- // Update our thread list, because sometimes libdispatch or the kernel
- // will spawn threads while a task is suspended.
- MachThreadList::collection new_threads;
-
- // First figure out if we were planning on running only one thread, and if so
- // force that thread to resume.
- bool run_one_thread;
- nub_thread_t solo_thread = INVALID_NUB_THREAD;
- if (thread_actions.GetSize() > 0 &&
- thread_actions.NumActionsWithState(eStateStepping) +
- thread_actions.NumActionsWithState(eStateRunning) ==
- 1) {
- run_one_thread = true;
- const DNBThreadResumeAction *action_ptr = thread_actions.GetFirst();
- size_t num_actions = thread_actions.GetSize();
- for (size_t i = 0; i < num_actions; i++, action_ptr++) {
- if (action_ptr->state == eStateStepping ||
- action_ptr->state == eStateRunning) {
- solo_thread = action_ptr->tid;
- break;
- }
- }
- } else
- run_one_thread = false;
-
- UpdateThreadList(process, true, &new_threads);
-
- DNBThreadResumeAction resume_new_threads = {-1U, eStateRunning, 0,
- INVALID_NUB_ADDRESS};
- // If we are planning to run only one thread, any new threads should be
- // suspended.
- if (run_one_thread)
- resume_new_threads.state = eStateSuspended;
-
- const size_t num_new_threads = new_threads.size();
- const size_t num_threads = m_threads.size();
- for (uint32_t idx = 0; idx < num_threads; ++idx) {
- MachThread *thread = m_threads[idx].get();
- bool handled = false;
- for (uint32_t new_idx = 0; new_idx < num_new_threads; ++new_idx) {
- if (thread == new_threads[new_idx].get()) {
- thread->ThreadWillResume(&resume_new_threads);
- handled = true;
- break;
- }
- }
-
- if (!handled) {
- const DNBThreadResumeAction *thread_action =
- thread_actions.GetActionForThread(thread->ThreadID(), true);
- // There must always be a thread action for every thread.
- assert(thread_action);
- bool others_stopped = false;
- if (solo_thread == thread->ThreadID())
- others_stopped = true;
- thread->ThreadWillResume(thread_action, others_stopped);
- }
- }
-
- if (new_threads.size()) {
- for (uint32_t idx = 0; idx < num_new_threads; ++idx) {
- DNBLogThreadedIf(
- LOG_THREAD, "MachThreadList::ProcessWillResume (pid = %4.4x) "
- "stop-id=%u, resuming newly discovered thread: "
- "0x%8.8" PRIx64 ", thread-is-user-ready=%i)",
- process->ProcessID(), process->StopCount(),
- new_threads[idx]->ThreadID(), new_threads[idx]->IsUserReady());
- }
- }
-}
-
-uint32_t MachThreadList::ProcessDidStop(MachProcess *process) {
- PTHREAD_MUTEX_LOCKER(locker, m_threads_mutex);
- // Update our thread list
- const uint32_t num_threads = UpdateThreadList(process, true);
- for (uint32_t idx = 0; idx < num_threads; ++idx) {
- m_threads[idx]->ThreadDidStop();
- }
- return num_threads;
-}
-
-//----------------------------------------------------------------------
-// Check each thread in our thread list to see if we should notify our
-// client of the current halt in execution.
-//
-// Breakpoints can have callback functions associated with them than
-// can return true to stop, or false to continue executing the inferior.
-//
-// RETURNS
-// true if we should stop and notify our clients
-// false if we should resume our child process and skip notification
-//----------------------------------------------------------------------
-bool MachThreadList::ShouldStop(bool &step_more) {
- PTHREAD_MUTEX_LOCKER(locker, m_threads_mutex);
- uint32_t should_stop = false;
- const size_t num_threads = m_threads.size();
- for (uint32_t idx = 0; !should_stop && idx < num_threads; ++idx) {
- should_stop = m_threads[idx]->ShouldStop(step_more);
- }
- return should_stop;
-}
-
-void MachThreadList::NotifyBreakpointChanged(const DNBBreakpoint *bp) {
- PTHREAD_MUTEX_LOCKER(locker, m_threads_mutex);
- const size_t num_threads = m_threads.size();
- for (uint32_t idx = 0; idx < num_threads; ++idx) {
- m_threads[idx]->NotifyBreakpointChanged(bp);
- }
-}
-
-uint32_t
-MachThreadList::EnableHardwareBreakpoint(const DNBBreakpoint *bp) const {
- if (bp != NULL) {
- const size_t num_threads = m_threads.size();
- for (uint32_t idx = 0; idx < num_threads; ++idx)
- m_threads[idx]->EnableHardwareBreakpoint(bp);
- }
- return INVALID_NUB_HW_INDEX;
-}
-
-bool MachThreadList::DisableHardwareBreakpoint(const DNBBreakpoint *bp) const {
- if (bp != NULL) {
- const size_t num_threads = m_threads.size();
- for (uint32_t idx = 0; idx < num_threads; ++idx)
- m_threads[idx]->DisableHardwareBreakpoint(bp);
- }
- return false;
-}
-
-// DNBWatchpointSet() -> MachProcess::CreateWatchpoint() ->
-// MachProcess::EnableWatchpoint()
-// -> MachThreadList::EnableHardwareWatchpoint().
-uint32_t
-MachThreadList::EnableHardwareWatchpoint(const DNBBreakpoint *wp) const {
- uint32_t hw_index = INVALID_NUB_HW_INDEX;
- if (wp != NULL) {
- PTHREAD_MUTEX_LOCKER(locker, m_threads_mutex);
- const size_t num_threads = m_threads.size();
- // On Mac OS X we have to prime the control registers for new threads. We
- // do this
- // using the control register data for the first thread, for lack of a
- // better way of choosing.
- bool also_set_on_task = true;
- for (uint32_t idx = 0; idx < num_threads; ++idx) {
- if ((hw_index = m_threads[idx]->EnableHardwareWatchpoint(
- wp, also_set_on_task)) == INVALID_NUB_HW_INDEX) {
- // We know that idx failed for some reason. Let's rollback the
- // transaction for [0, idx).
- for (uint32_t i = 0; i < idx; ++i)
- m_threads[i]->RollbackTransForHWP();
- return INVALID_NUB_HW_INDEX;
- }
- also_set_on_task = false;
- }
- // Notify each thread to commit the pending transaction.
- for (uint32_t idx = 0; idx < num_threads; ++idx)
- m_threads[idx]->FinishTransForHWP();
- }
- return hw_index;
-}
-
-bool MachThreadList::DisableHardwareWatchpoint(const DNBBreakpoint *wp) const {
- if (wp != NULL) {
- PTHREAD_MUTEX_LOCKER(locker, m_threads_mutex);
- const size_t num_threads = m_threads.size();
-
- // On Mac OS X we have to prime the control registers for new threads. We
- // do this
- // using the control register data for the first thread, for lack of a
- // better way of choosing.
- bool also_set_on_task = true;
- for (uint32_t idx = 0; idx < num_threads; ++idx) {
- if (!m_threads[idx]->DisableHardwareWatchpoint(wp, also_set_on_task)) {
- // We know that idx failed for some reason. Let's rollback the
- // transaction for [0, idx).
- for (uint32_t i = 0; i < idx; ++i)
- m_threads[i]->RollbackTransForHWP();
- return false;
- }
- also_set_on_task = false;
- }
- // Notify each thread to commit the pending transaction.
- for (uint32_t idx = 0; idx < num_threads; ++idx)
- m_threads[idx]->FinishTransForHWP();
-
- return true;
- }
- return false;
-}
-
-uint32_t MachThreadList::NumSupportedHardwareWatchpoints() const {
- PTHREAD_MUTEX_LOCKER(locker, m_threads_mutex);
- const size_t num_threads = m_threads.size();
- // Use an arbitrary thread to retrieve the number of supported hardware
- // watchpoints.
- if (num_threads)
- return m_threads[0]->NumSupportedHardwareWatchpoints();
- return 0;
-}
-
-uint32_t MachThreadList::GetThreadIndexForThreadStoppedWithSignal(
- const int signo) const {
- PTHREAD_MUTEX_LOCKER(locker, m_threads_mutex);
- uint32_t should_stop = false;
- const size_t num_threads = m_threads.size();
- for (uint32_t idx = 0; !should_stop && idx < num_threads; ++idx) {
- if (m_threads[idx]->GetStopException().SoftSignal() == signo)
- return idx;
- }
- return UINT32_MAX;
-}
diff --git a/tools/debugserver/source/MacOSX/MachThreadList.h b/tools/debugserver/source/MacOSX/MachThreadList.h
deleted file mode 100644
index bcef695edf87..000000000000
--- a/tools/debugserver/source/MacOSX/MachThreadList.h
+++ /dev/null
@@ -1,97 +0,0 @@
-//===-- MachThreadList.h ----------------------------------------*- 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/19/07.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __MachThreadList_h__
-#define __MachThreadList_h__
-
-#include "MachThread.h"
-#include "ThreadInfo.h"
-
-class DNBThreadResumeActions;
-
-class MachThreadList {
-public:
- MachThreadList();
- ~MachThreadList();
-
- void Clear();
- void Dump() const;
- bool GetRegisterValue(nub_thread_t tid, uint32_t set, uint32_t reg,
- DNBRegisterValue *reg_value) const;
- bool SetRegisterValue(nub_thread_t tid, uint32_t set, uint32_t reg,
- const DNBRegisterValue *reg_value) const;
- nub_size_t GetRegisterContext(nub_thread_t tid, void *buf, size_t buf_len);
- nub_size_t SetRegisterContext(nub_thread_t tid, const void *buf,
- size_t buf_len);
- uint32_t SaveRegisterState(nub_thread_t tid);
- bool RestoreRegisterState(nub_thread_t tid, uint32_t save_id);
- const char *GetThreadInfo(nub_thread_t tid) const;
- void ProcessWillResume(MachProcess *process,
- const DNBThreadResumeActions &thread_actions);
- uint32_t ProcessDidStop(MachProcess *process);
- bool NotifyException(MachException::Data &exc);
- bool ShouldStop(bool &step_more);
- const char *GetName(nub_thread_t tid);
- nub_state_t GetState(nub_thread_t tid);
- nub_thread_t SetCurrentThread(nub_thread_t tid);
-
- ThreadInfo::QoS GetRequestedQoS(nub_thread_t tid, nub_addr_t tsd,
- uint64_t dti_qos_class_index);
- nub_addr_t GetPThreadT(nub_thread_t tid);
- nub_addr_t GetDispatchQueueT(nub_thread_t tid);
- nub_addr_t
- GetTSDAddressForThread(nub_thread_t tid,
- uint64_t plo_pthread_tsd_base_address_offset,
- uint64_t plo_pthread_tsd_base_offset,
- uint64_t plo_pthread_tsd_entry_size);
-
- bool GetThreadStoppedReason(nub_thread_t tid,
- struct DNBThreadStopInfo *stop_info) const;
- void DumpThreadStoppedReason(nub_thread_t tid) const;
- bool GetIdentifierInfo(nub_thread_t tid,
- thread_identifier_info_data_t *ident_info);
- nub_size_t NumThreads() const;
- nub_thread_t ThreadIDAtIndex(nub_size_t idx) const;
- nub_thread_t CurrentThreadID();
- void CurrentThread(MachThreadSP &threadSP);
- void NotifyBreakpointChanged(const DNBBreakpoint *bp);
- uint32_t EnableHardwareBreakpoint(const DNBBreakpoint *bp) const;
- bool DisableHardwareBreakpoint(const DNBBreakpoint *bp) const;
- uint32_t EnableHardwareWatchpoint(const DNBBreakpoint *wp) const;
- bool DisableHardwareWatchpoint(const DNBBreakpoint *wp) const;
- uint32_t NumSupportedHardwareWatchpoints() const;
-
- uint32_t GetThreadIndexForThreadStoppedWithSignal(const int signo) const;
-
- MachThreadSP GetThreadByID(nub_thread_t tid) const;
-
- MachThreadSP GetThreadByMachPortNumber(thread_t mach_port_number) const;
- nub_thread_t GetThreadIDByMachPortNumber(thread_t mach_port_number) const;
- thread_t GetMachPortNumberByThreadID(nub_thread_t globally_unique_id) const;
-
-protected:
- typedef std::vector<MachThreadSP> collection;
- typedef collection::iterator iterator;
- typedef collection::const_iterator const_iterator;
-
- uint32_t UpdateThreadList(MachProcess *process, bool update,
- collection *num_threads = NULL);
- // const_iterator FindThreadByID (thread_t tid) const;
-
- collection m_threads;
- mutable PThreadMutex m_threads_mutex;
- MachThreadSP m_current_thread;
- bool m_is_64_bit;
-};
-
-#endif // #ifndef __MachThreadList_h__
diff --git a/tools/debugserver/source/MacOSX/MachVMMemory.cpp b/tools/debugserver/source/MacOSX/MachVMMemory.cpp
deleted file mode 100644
index 754fb82dba3e..000000000000
--- a/tools/debugserver/source/MacOSX/MachVMMemory.cpp
+++ /dev/null
@@ -1,297 +0,0 @@
-//===-- MachVMMemory.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/26/07.
-//
-//===----------------------------------------------------------------------===//
-
-#include "MachVMMemory.h"
-#include "DNBLog.h"
-#include "MachVMRegion.h"
-#include <dlfcn.h>
-#include <mach/mach_vm.h>
-#include <mach/shared_region.h>
-#include <sys/sysctl.h>
-
-#if defined(WITH_FBS) || defined(WITH_BKS)
-extern "C" {
-#import <sys/kern_memorystatus.h>
-}
-#endif
-
-static const vm_size_t kInvalidPageSize = ~0;
-
-MachVMMemory::MachVMMemory() : m_page_size(kInvalidPageSize), m_err(0) {}
-
-MachVMMemory::~MachVMMemory() {}
-
-nub_size_t MachVMMemory::PageSize(task_t task) {
- if (m_page_size == kInvalidPageSize) {
-#if defined(TASK_VM_INFO) && TASK_VM_INFO >= 22
- if (task != TASK_NULL) {
- kern_return_t kr;
- mach_msg_type_number_t info_count = TASK_VM_INFO_COUNT;
- task_vm_info_data_t vm_info;
- kr = task_info(task, TASK_VM_INFO, (task_info_t)&vm_info, &info_count);
- if (kr == KERN_SUCCESS) {
- DNBLogThreadedIf(
- LOG_TASK,
- "MachVMMemory::PageSize task_info returned page size of 0x%x",
- (int)vm_info.page_size);
- m_page_size = vm_info.page_size;
- return m_page_size;
- } else {
- DNBLogThreadedIf(LOG_TASK, "MachVMMemory::PageSize task_info call "
- "failed to get page size, TASK_VM_INFO %d, "
- "TASK_VM_INFO_COUNT %d, kern return %d",
- TASK_VM_INFO, TASK_VM_INFO_COUNT, kr);
- }
- }
-#endif
- m_err = ::host_page_size(::mach_host_self(), &m_page_size);
- if (m_err.Fail())
- m_page_size = 0;
- }
- return m_page_size;
-}
-
-nub_size_t MachVMMemory::MaxBytesLeftInPage(task_t task, nub_addr_t addr,
- nub_size_t count) {
- const nub_size_t page_size = PageSize(task);
- if (page_size > 0) {
- nub_size_t page_offset = (addr % page_size);
- nub_size_t bytes_left_in_page = page_size - page_offset;
- if (count > bytes_left_in_page)
- count = bytes_left_in_page;
- }
- return count;
-}
-
-nub_bool_t MachVMMemory::GetMemoryRegionInfo(task_t task, nub_addr_t address,
- DNBRegionInfo *region_info) {
- MachVMRegion vmRegion(task);
-
- if (vmRegion.GetRegionForAddress(address)) {
- region_info->addr = vmRegion.StartAddress();
- region_info->size = vmRegion.GetByteSize();
- region_info->permissions = vmRegion.GetDNBPermissions();
- } else {
- region_info->addr = address;
- region_info->size = 0;
- if (vmRegion.GetError().Success()) {
- // vmRegion.GetRegionForAddress() return false, indicating that "address"
- // wasn't in a valid region, but the "vmRegion" info was successfully
- // read from the task which means the info describes the next valid
- // region from which we can infer the size of this invalid region
- mach_vm_address_t start_addr = vmRegion.StartAddress();
- if (address < start_addr)
- region_info->size = start_addr - address;
- }
- // If we can't get any info about the size from the next region it means
- // we asked about an address that was past all mappings, so the size
- // of this region will take up all remaining address space.
- if (region_info->size == 0)
- region_info->size = INVALID_NUB_ADDRESS - region_info->addr;
-
- // Not readable, writeable or executable
- region_info->permissions = 0;
- }
- return true;
-}
-
-static uint64_t GetPhysicalMemory() {
- // This doesn't change often at all. No need to poll each time.
- static uint64_t physical_memory = 0;
- static bool calculated = false;
- if (calculated)
- return physical_memory;
-
- size_t len = sizeof(physical_memory);
- sysctlbyname("hw.memsize", &physical_memory, &len, NULL, 0);
-
- calculated = true;
- return physical_memory;
-}
-
-nub_bool_t MachVMMemory::GetMemoryProfile(
- DNBProfileDataScanType scanType, task_t task, struct task_basic_info ti,
- cpu_type_t cputype, nub_process_t pid, vm_statistics64_data_t &vminfo,
- uint64_t &physical_memory, uint64_t &anonymous,
- uint64_t &phys_footprint, uint64_t &memory_cap)
-{
- if (scanType & eProfileHostMemory)
- physical_memory = GetPhysicalMemory();
-
- if (scanType & eProfileMemory) {
- static mach_port_t localHost = mach_host_self();
- mach_msg_type_number_t count = HOST_VM_INFO64_COUNT;
- host_statistics64(localHost, HOST_VM_INFO64, (host_info64_t)&vminfo,
- &count);
-
- kern_return_t kr;
- mach_msg_type_number_t info_count;
- task_vm_info_data_t vm_info;
-
- info_count = TASK_VM_INFO_COUNT;
- kr = task_info(task, TASK_VM_INFO_PURGEABLE, (task_info_t)&vm_info, &info_count);
- if (kr == KERN_SUCCESS) {
- if (scanType & eProfileMemoryAnonymous) {
- anonymous = vm_info.internal + vm_info.compressed - vm_info.purgeable_volatile_pmap;
- }
-
- phys_footprint = vm_info.phys_footprint;
- }
- }
-
-#if defined(WITH_FBS) || defined(WITH_BKS)
- if (scanType & eProfileMemoryCap) {
- memorystatus_memlimit_properties_t memlimit_properties;
- memset(&memlimit_properties, 0, sizeof(memlimit_properties));
- if (memorystatus_control(MEMORYSTATUS_CMD_GET_MEMLIMIT_PROPERTIES, pid, 0, &memlimit_properties, sizeof(memlimit_properties)) == 0) {
- memory_cap = memlimit_properties.memlimit_active;
- }
- }
-#endif
-
- return true;
-}
-
-nub_size_t MachVMMemory::Read(task_t task, nub_addr_t address, void *data,
- nub_size_t data_count) {
- if (data == NULL || data_count == 0)
- return 0;
-
- nub_size_t total_bytes_read = 0;
- nub_addr_t curr_addr = address;
- uint8_t *curr_data = (uint8_t *)data;
- while (total_bytes_read < data_count) {
- mach_vm_size_t curr_size =
- MaxBytesLeftInPage(task, curr_addr, data_count - total_bytes_read);
- mach_msg_type_number_t curr_bytes_read = 0;
- vm_offset_t vm_memory = 0;
- m_err = ::mach_vm_read(task, curr_addr, curr_size, &vm_memory,
- &curr_bytes_read);
-
- if (DNBLogCheckLogBit(LOG_MEMORY))
- m_err.LogThreaded("::mach_vm_read ( task = 0x%4.4x, addr = 0x%8.8llx, "
- "size = %llu, data => %8.8p, dataCnt => %i )",
- task, (uint64_t)curr_addr, (uint64_t)curr_size,
- vm_memory, curr_bytes_read);
-
- if (m_err.Success()) {
- if (curr_bytes_read != curr_size) {
- if (DNBLogCheckLogBit(LOG_MEMORY))
- m_err.LogThreaded(
- "::mach_vm_read ( task = 0x%4.4x, addr = 0x%8.8llx, size = %llu, "
- "data => %8.8p, dataCnt=>%i ) only read %u of %llu bytes",
- task, (uint64_t)curr_addr, (uint64_t)curr_size, vm_memory,
- curr_bytes_read, curr_bytes_read, (uint64_t)curr_size);
- }
- ::memcpy(curr_data, (void *)vm_memory, curr_bytes_read);
- ::vm_deallocate(mach_task_self(), vm_memory, curr_bytes_read);
- total_bytes_read += curr_bytes_read;
- curr_addr += curr_bytes_read;
- curr_data += curr_bytes_read;
- } else {
- break;
- }
- }
- return total_bytes_read;
-}
-
-nub_size_t MachVMMemory::Write(task_t task, nub_addr_t address,
- const void *data, nub_size_t data_count) {
- MachVMRegion vmRegion(task);
-
- nub_size_t total_bytes_written = 0;
- nub_addr_t curr_addr = address;
- const uint8_t *curr_data = (const uint8_t *)data;
-
- while (total_bytes_written < data_count) {
- if (vmRegion.GetRegionForAddress(curr_addr)) {
- mach_vm_size_t curr_data_count = data_count - total_bytes_written;
- mach_vm_size_t region_bytes_left = vmRegion.BytesRemaining(curr_addr);
- if (region_bytes_left == 0) {
- break;
- }
- if (curr_data_count > region_bytes_left)
- curr_data_count = region_bytes_left;
-
- if (vmRegion.SetProtections(curr_addr, curr_data_count,
- VM_PROT_READ | VM_PROT_WRITE)) {
- nub_size_t bytes_written =
- WriteRegion(task, curr_addr, curr_data, curr_data_count);
- if (bytes_written <= 0) {
- // Status should have already be posted by WriteRegion...
- break;
- } else {
- total_bytes_written += bytes_written;
- curr_addr += bytes_written;
- curr_data += bytes_written;
- }
- } else {
- DNBLogThreadedIf(
- LOG_MEMORY_PROTECTIONS, "Failed to set read/write protections on "
- "region for address: [0x%8.8llx-0x%8.8llx)",
- (uint64_t)curr_addr, (uint64_t)(curr_addr + curr_data_count));
- break;
- }
- } else {
- DNBLogThreadedIf(LOG_MEMORY_PROTECTIONS,
- "Failed to get region for address: 0x%8.8llx",
- (uint64_t)address);
- break;
- }
- }
-
- return total_bytes_written;
-}
-
-nub_size_t MachVMMemory::WriteRegion(task_t task, const nub_addr_t address,
- const void *data,
- const nub_size_t data_count) {
- if (data == NULL || data_count == 0)
- return 0;
-
- nub_size_t total_bytes_written = 0;
- nub_addr_t curr_addr = address;
- const uint8_t *curr_data = (const uint8_t *)data;
- while (total_bytes_written < data_count) {
- mach_msg_type_number_t curr_data_count =
- static_cast<mach_msg_type_number_t>(MaxBytesLeftInPage(
- task, curr_addr, data_count - total_bytes_written));
- m_err =
- ::mach_vm_write(task, curr_addr, (pointer_t)curr_data, curr_data_count);
- if (DNBLogCheckLogBit(LOG_MEMORY) || m_err.Fail())
- m_err.LogThreaded("::mach_vm_write ( task = 0x%4.4x, addr = 0x%8.8llx, "
- "data = %8.8p, dataCnt = %u )",
- task, (uint64_t)curr_addr, curr_data, curr_data_count);
-
-#if !defined(__i386__) && !defined(__x86_64__)
- vm_machine_attribute_val_t mattr_value = MATTR_VAL_CACHE_FLUSH;
-
- m_err = ::vm_machine_attribute(task, curr_addr, curr_data_count,
- MATTR_CACHE, &mattr_value);
- if (DNBLogCheckLogBit(LOG_MEMORY) || m_err.Fail())
- m_err.LogThreaded("::vm_machine_attribute ( task = 0x%4.4x, addr = "
- "0x%8.8llx, size = %u, attr = MATTR_CACHE, mattr_value "
- "=> MATTR_VAL_CACHE_FLUSH )",
- task, (uint64_t)curr_addr, curr_data_count);
-#endif
-
- if (m_err.Success()) {
- total_bytes_written += curr_data_count;
- curr_addr += curr_data_count;
- curr_data += curr_data_count;
- } else {
- break;
- }
- }
- return total_bytes_written;
-}
diff --git a/tools/debugserver/source/MacOSX/MachVMMemory.h b/tools/debugserver/source/MacOSX/MachVMMemory.h
deleted file mode 100644
index 513b69ee709f..000000000000
--- a/tools/debugserver/source/MacOSX/MachVMMemory.h
+++ /dev/null
@@ -1,48 +0,0 @@
-//===-- MachVMMemory.h ------------------------------------------*- 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/26/07.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __MachVMMemory_h__
-#define __MachVMMemory_h__
-
-#include "DNBDefs.h"
-#include "DNBError.h"
-#include <mach/mach.h>
-
-class MachVMMemory {
-public:
- MachVMMemory();
- ~MachVMMemory();
- nub_size_t Read(task_t task, nub_addr_t address, void *data,
- nub_size_t data_count);
- nub_size_t Write(task_t task, nub_addr_t address, const void *data,
- nub_size_t data_count);
- nub_size_t PageSize(task_t task);
- nub_bool_t GetMemoryRegionInfo(task_t task, nub_addr_t address,
- DNBRegionInfo *region_info);
- nub_bool_t GetMemoryProfile(DNBProfileDataScanType scanType, task_t task,
- struct task_basic_info ti, cpu_type_t cputype,
- nub_process_t pid, vm_statistics64_data_t &vminfo,
- uint64_t &physical_memory, uint64_t &anonymous,
- uint64_t &phys_footprint, uint64_t &memory_cap);
-
-protected:
- nub_size_t MaxBytesLeftInPage(task_t task, nub_addr_t addr, nub_size_t count);
-
- nub_size_t WriteRegion(task_t task, const nub_addr_t address,
- const void *data, const nub_size_t data_count);
-
- vm_size_t m_page_size;
- DNBError m_err;
-};
-
-#endif // #ifndef __MachVMMemory_h__
diff --git a/tools/debugserver/source/MacOSX/MachVMRegion.cpp b/tools/debugserver/source/MacOSX/MachVMRegion.cpp
deleted file mode 100644
index 172fc7867b57..000000000000
--- a/tools/debugserver/source/MacOSX/MachVMRegion.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-//===-- MachVMRegion.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/26/07.
-//
-//===----------------------------------------------------------------------===//
-
-#include "MachVMRegion.h"
-#include "DNBLog.h"
-#include <assert.h>
-#include <mach/mach_vm.h>
-
-MachVMRegion::MachVMRegion(task_t task)
- : m_task(task), m_addr(INVALID_NUB_ADDRESS), m_err(),
- m_start(INVALID_NUB_ADDRESS), m_size(0), m_depth(-1),
- m_curr_protection(0), m_protection_addr(INVALID_NUB_ADDRESS),
- m_protection_size(0) {
- memset(&m_data, 0, sizeof(m_data));
-}
-
-MachVMRegion::~MachVMRegion() {
- // Restore any original protections and clear our vars
- Clear();
-}
-
-void MachVMRegion::Clear() {
- RestoreProtections();
- m_addr = INVALID_NUB_ADDRESS;
- m_err.Clear();
- m_start = INVALID_NUB_ADDRESS;
- m_size = 0;
- m_depth = -1;
- memset(&m_data, 0, sizeof(m_data));
- m_curr_protection = 0;
- m_protection_addr = INVALID_NUB_ADDRESS;
- m_protection_size = 0;
-}
-
-bool MachVMRegion::SetProtections(mach_vm_address_t addr, mach_vm_size_t size,
- vm_prot_t prot) {
- if (ContainsAddress(addr)) {
- mach_vm_size_t prot_size = size;
- mach_vm_address_t end_addr = EndAddress();
- if (prot_size > (end_addr - addr))
- prot_size = end_addr - addr;
-
- if (prot_size > 0) {
- if (prot == (m_curr_protection & VM_PROT_ALL)) {
- DNBLogThreadedIf(LOG_MEMORY_PROTECTIONS | LOG_VERBOSE,
- "MachVMRegion::%s: protections (%u) already "
- "sufficient for task 0x%4.4x at address 0x%8.8llx) ",
- __FUNCTION__, prot, m_task, (uint64_t)addr);
- // Protections are already set as requested...
- return true;
- } else {
- m_err = ::mach_vm_protect(m_task, addr, prot_size, 0, prot);
- if (DNBLogCheckLogBit(LOG_MEMORY_PROTECTIONS))
- m_err.LogThreaded("::mach_vm_protect ( task = 0x%4.4x, addr = "
- "0x%8.8llx, size = %llu, set_max = %i, prot = %u )",
- m_task, (uint64_t)addr, (uint64_t)prot_size, 0,
- prot);
- if (m_err.Fail()) {
- // Try again with the ability to create a copy on write region
- m_err = ::mach_vm_protect(m_task, addr, prot_size, 0,
- prot | VM_PROT_COPY);
- if (DNBLogCheckLogBit(LOG_MEMORY_PROTECTIONS) || m_err.Fail())
- m_err.LogThreaded("::mach_vm_protect ( task = 0x%4.4x, addr = "
- "0x%8.8llx, size = %llu, set_max = %i, prot = %u "
- ")",
- m_task, (uint64_t)addr, (uint64_t)prot_size, 0,
- prot | VM_PROT_COPY);
- }
- if (m_err.Success()) {
- m_curr_protection = prot;
- m_protection_addr = addr;
- m_protection_size = prot_size;
- return true;
- }
- }
- } else {
- DNBLogThreadedIf(LOG_MEMORY_PROTECTIONS | LOG_VERBOSE,
- "%s: Zero size for task 0x%4.4x at address 0x%8.8llx) ",
- __FUNCTION__, m_task, (uint64_t)addr);
- }
- }
- return false;
-}
-
-bool MachVMRegion::RestoreProtections() {
- if (m_curr_protection != m_data.protection && m_protection_size > 0) {
- m_err = ::mach_vm_protect(m_task, m_protection_addr, m_protection_size, 0,
- m_data.protection);
- if (DNBLogCheckLogBit(LOG_MEMORY_PROTECTIONS) || m_err.Fail())
- m_err.LogThreaded("::mach_vm_protect ( task = 0x%4.4x, addr = 0x%8.8llx, "
- "size = %llu, set_max = %i, prot = %u )",
- m_task, (uint64_t)m_protection_addr,
- (uint64_t)m_protection_size, 0, m_data.protection);
- if (m_err.Success()) {
- m_protection_size = 0;
- m_protection_addr = INVALID_NUB_ADDRESS;
- m_curr_protection = m_data.protection;
- return true;
- }
- } else {
- m_err.Clear();
- return true;
- }
-
- return false;
-}
-
-bool MachVMRegion::GetRegionForAddress(nub_addr_t addr) {
- // Restore any original protections and clear our vars
- Clear();
- m_err.Clear();
- m_addr = addr;
- m_start = addr;
- m_depth = 1024;
- mach_msg_type_number_t info_size = kRegionInfoSize;
- assert(sizeof(info_size) == 4);
- m_err =
- ::mach_vm_region_recurse(m_task, &m_start, &m_size, &m_depth,
- (vm_region_recurse_info_t)&m_data, &info_size);
-
- const bool failed = m_err.Fail();
- const bool log_protections = DNBLogCheckLogBit(LOG_MEMORY_PROTECTIONS);
-
- if (log_protections || failed)
- m_err.LogThreaded("::mach_vm_region_recurse ( task = 0x%4.4x, address => "
- "0x%8.8llx, size => %llu, nesting_depth => %d, info => "
- "%p, infoCnt => %d) addr = 0x%8.8llx ",
- m_task, (uint64_t)m_start, (uint64_t)m_size, m_depth,
- &m_data, info_size, (uint64_t)addr);
-
- if (failed)
- return false;
- if (log_protections) {
- DNBLogThreaded("info = { prot = %u, "
- "max_prot = %u, "
- "inheritance = 0x%8.8x, "
- "offset = 0x%8.8llx, "
- "user_tag = 0x%8.8x, "
- "ref_count = %u, "
- "shadow_depth = %u, "
- "ext_pager = %u, "
- "share_mode = %u, "
- "is_submap = %d, "
- "behavior = %d, "
- "object_id = 0x%8.8x, "
- "user_wired_count = 0x%4.4x }",
- m_data.protection, m_data.max_protection, m_data.inheritance,
- (uint64_t)m_data.offset, m_data.user_tag, m_data.ref_count,
- m_data.shadow_depth, m_data.external_pager,
- m_data.share_mode, m_data.is_submap, m_data.behavior,
- m_data.object_id, m_data.user_wired_count);
- }
- m_curr_protection = m_data.protection;
-
- // We make a request for an address and got no error back, but this
- // doesn't mean that "addr" is in the range. The data in this object will
- // be valid though, so you could see where the next region begins. So we
- // return false, yet leave "m_err" with a successfull return code.
- return !((addr < m_start) || (addr >= (m_start + m_size)));
-}
-
-uint32_t MachVMRegion::GetDNBPermissions() const {
- if (m_addr == INVALID_NUB_ADDRESS || m_start == INVALID_NUB_ADDRESS ||
- m_size == 0)
- return 0;
- uint32_t dnb_permissions = 0;
-
- if ((m_data.protection & VM_PROT_READ) == VM_PROT_READ)
- dnb_permissions |= eMemoryPermissionsReadable;
- if ((m_data.protection & VM_PROT_WRITE) == VM_PROT_WRITE)
- dnb_permissions |= eMemoryPermissionsWritable;
- if ((m_data.protection & VM_PROT_EXECUTE) == VM_PROT_EXECUTE)
- dnb_permissions |= eMemoryPermissionsExecutable;
- return dnb_permissions;
-}
diff --git a/tools/debugserver/source/MacOSX/MachVMRegion.h b/tools/debugserver/source/MacOSX/MachVMRegion.h
deleted file mode 100644
index 758112d236d7..000000000000
--- a/tools/debugserver/source/MacOSX/MachVMRegion.h
+++ /dev/null
@@ -1,73 +0,0 @@
-//===-- MachVMRegion.h ------------------------------------------*- 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/26/07.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __MachVMRegion_h__
-#define __MachVMRegion_h__
-
-#include "DNBDefs.h"
-#include "DNBError.h"
-#include <mach/mach.h>
-
-class MachVMRegion {
-public:
- MachVMRegion(task_t task);
- ~MachVMRegion();
-
- void Clear();
- mach_vm_address_t StartAddress() const { return m_start; }
- mach_vm_address_t EndAddress() const { return m_start + m_size; }
- mach_vm_size_t GetByteSize() const { return m_size; }
- mach_vm_address_t BytesRemaining(mach_vm_address_t addr) const {
- if (ContainsAddress(addr))
- return m_size - (addr - m_start);
- else
- return 0;
- }
- bool ContainsAddress(mach_vm_address_t addr) const {
- return addr >= StartAddress() && addr < EndAddress();
- }
-
- bool SetProtections(mach_vm_address_t addr, mach_vm_size_t size,
- vm_prot_t prot);
- bool RestoreProtections();
- bool GetRegionForAddress(nub_addr_t addr);
-
- uint32_t GetDNBPermissions() const;
-
- const DNBError &GetError() { return m_err; }
-
-protected:
-#if defined(VM_REGION_SUBMAP_SHORT_INFO_COUNT_64)
- typedef vm_region_submap_short_info_data_64_t RegionInfo;
- enum { kRegionInfoSize = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64 };
-#else
- typedef vm_region_submap_info_data_64_t RegionInfo;
- enum { kRegionInfoSize = VM_REGION_SUBMAP_INFO_COUNT_64 };
-#endif
-
- task_t m_task;
- mach_vm_address_t m_addr;
- DNBError m_err;
- mach_vm_address_t m_start;
- mach_vm_size_t m_size;
- natural_t m_depth;
- RegionInfo m_data;
- vm_prot_t m_curr_protection; // The current, possibly modified protections.
- // Original value is saved in m_data.protections.
- mach_vm_address_t
- m_protection_addr; // The start address at which protections were changed
- mach_vm_size_t
- m_protection_size; // The size of memory that had its protections changed
-};
-
-#endif // #ifndef __MachVMRegion_h__
diff --git a/tools/debugserver/source/MacOSX/OsLogger.cpp b/tools/debugserver/source/MacOSX/OsLogger.cpp
deleted file mode 100644
index 40aeec73f0aa..000000000000
--- a/tools/debugserver/source/MacOSX/OsLogger.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-//===-- OsLogger.cpp --------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "OsLogger.h"
-#include <Availability.h>
-
-#if (LLDB_USE_OS_LOG) && (__MAC_OS_X_VERSION_MAX_ALLOWED >= 101200)
-
-#include <os/log.h>
-
-#include "DNBDefs.h"
-#include "DNBLog.h"
-
-#define LLDB_OS_LOG_MAX_BUFFER_LENGTH 256
-
-namespace {
-//----------------------------------------------------------------------
-// Darwin os_log logging callback that can be registered with
-// DNBLogSetLogCallback
-//----------------------------------------------------------------------
-void DarwinLogCallback(void *baton, uint32_t flags, const char *format,
- va_list args) {
- if (format == nullptr)
- return;
-
- static os_log_t g_logger;
- if (!g_logger) {
- g_logger = os_log_create("com.apple.dt.lldb", "debugserver");
- if (!g_logger)
- return;
- }
-
- os_log_type_t log_type;
- if (flags & DNBLOG_FLAG_FATAL)
- log_type = OS_LOG_TYPE_FAULT;
- else if (flags & DNBLOG_FLAG_ERROR)
- log_type = OS_LOG_TYPE_ERROR;
- else if (flags & DNBLOG_FLAG_WARNING)
- log_type = OS_LOG_TYPE_DEFAULT;
- else if (flags & DNBLOG_FLAG_VERBOSE)
- log_type = OS_LOG_TYPE_DEBUG;
- else
- log_type = OS_LOG_TYPE_DEFAULT;
-
- // This code is unfortunate. os_log* only takes static strings, but
- // our current log API isn't set up to make use of that style.
- char buffer[LLDB_OS_LOG_MAX_BUFFER_LENGTH];
- vsnprintf(buffer, sizeof(buffer), format, args);
- os_log_with_type(g_logger, log_type, "%{public}s", buffer);
-}
-}
-
-DNBCallbackLog OsLogger::GetLogFunction() { return DarwinLogCallback; }
-
-#else
-
-DNBCallbackLog OsLogger::GetLogFunction() { return nullptr; }
-
-#endif
-
diff --git a/tools/debugserver/source/MacOSX/OsLogger.h b/tools/debugserver/source/MacOSX/OsLogger.h
deleted file mode 100644
index 9afdcb974d9a..000000000000
--- a/tools/debugserver/source/MacOSX/OsLogger.h
+++ /dev/null
@@ -1,20 +0,0 @@
-//===-- OsLogger.h ----------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef OsLogger_h
-#define OsLogger_h
-
-#include "DNBDefs.h"
-
-class OsLogger {
-public:
- static DNBCallbackLog GetLogFunction();
-};
-
-#endif /* OsLogger_h */
diff --git a/tools/debugserver/source/MacOSX/ThreadInfo.h b/tools/debugserver/source/MacOSX/ThreadInfo.h
deleted file mode 100644
index e9773caf9ea3..000000000000
--- a/tools/debugserver/source/MacOSX/ThreadInfo.h
+++ /dev/null
@@ -1,26 +0,0 @@
-//===-- ThreadInfo.h -----------------------------------------------*- C++
-//-*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __ThreadInfo_h__
-#define __ThreadInfo_h__
-
-namespace ThreadInfo {
-
-class QoS {
-public:
- QoS() : constant_name(), printable_name(), enum_value(UINT32_MAX) {}
- bool IsValid() { return enum_value != UINT32_MAX; }
- std::string constant_name;
- std::string printable_name;
- uint32_t enum_value;
-};
-};
-
-#endif // __ThreadInfo_h__
diff --git a/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp b/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp
deleted file mode 100644
index 2841ddb11081..000000000000
--- a/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp
+++ /dev/null
@@ -1,2194 +0,0 @@
-//===-- DNBArchImpl.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__) || defined(__aarch64__)
-
-#include "MacOSX/arm/DNBArchImpl.h"
-#include "ARM_DWARF_Registers.h"
-#include "ARM_ehframe_Registers.h"
-#include "DNB.h"
-#include "DNBBreakpoint.h"
-#include "DNBLog.h"
-#include "DNBRegisterInfo.h"
-#include "MacOSX/MachProcess.h"
-#include "MacOSX/MachThread.h"
-
-#include <inttypes.h>
-#include <sys/sysctl.h>
-
-// BCR address match type
-#define BCR_M_IMVA_MATCH ((uint32_t)(0u << 21))
-#define BCR_M_CONTEXT_ID_MATCH ((uint32_t)(1u << 21))
-#define BCR_M_IMVA_MISMATCH ((uint32_t)(2u << 21))
-#define BCR_M_RESERVED ((uint32_t)(3u << 21))
-
-// Link a BVR/BCR or WVR/WCR pair to another
-#define E_ENABLE_LINKING ((uint32_t)(1u << 20))
-
-// Byte Address Select
-#define BAS_IMVA_PLUS_0 ((uint32_t)(1u << 5))
-#define BAS_IMVA_PLUS_1 ((uint32_t)(1u << 6))
-#define BAS_IMVA_PLUS_2 ((uint32_t)(1u << 7))
-#define BAS_IMVA_PLUS_3 ((uint32_t)(1u << 8))
-#define BAS_IMVA_0_1 ((uint32_t)(3u << 5))
-#define BAS_IMVA_2_3 ((uint32_t)(3u << 7))
-#define BAS_IMVA_ALL ((uint32_t)(0xfu << 5))
-
-// 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 BCR_ENABLE ((uint32_t)(1u))
-#define WCR_ENABLE ((uint32_t)(1u))
-
-// Watchpoint load/store
-#define WCR_LOAD ((uint32_t)(1u << 3))
-#define WCR_STORE ((uint32_t)(1u << 4))
-
-// Definitions for the Debug Status and Control Register fields:
-// [5:2] => Method of debug entry
-//#define WATCHPOINT_OCCURRED ((uint32_t)(2u))
-// I'm seeing this, instead.
-#define WATCHPOINT_OCCURRED ((uint32_t)(10u))
-
-// 0xE120BE70
-static const uint8_t g_arm_breakpoint_opcode[] = {0x70, 0xBE, 0x20, 0xE1};
-static const uint8_t g_thumb_breakpoint_opcode[] = {0x70, 0xBE};
-
-// 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
-#define PC_REG 15
-#define PC_REGLIST_BIT 0x8000
-
-// ARM conditions
-#define COND_EQ 0x0
-#define COND_NE 0x1
-#define COND_CS 0x2
-#define COND_HS 0x2
-#define COND_CC 0x3
-#define COND_LO 0x3
-#define COND_MI 0x4
-#define COND_PL 0x5
-#define COND_VS 0x6
-#define COND_VC 0x7
-#define COND_HI 0x8
-#define COND_LS 0x9
-#define COND_GE 0xA
-#define COND_LT 0xB
-#define COND_GT 0xC
-#define COND_LE 0xD
-#define COND_AL 0xE
-#define COND_UNCOND 0xF
-
-#define MASK_CPSR_T (1u << 5)
-#define MASK_CPSR_J (1u << 24)
-
-#define MNEMONIC_STRING_SIZE 32
-#define OPERAND_STRING_SIZE 128
-
-// Returns true if the first 16 bit opcode of a thumb instruction indicates
-// the instruction will be a 32 bit thumb opcode
-static bool IsThumb32Opcode(uint16_t opcode) {
- if (((opcode & 0xE000) == 0xE000) && (opcode & 0x1800))
- return true;
- return false;
-}
-
-void DNBArchMachARM::Initialize() {
- DNBArchPluginInfo arch_plugin_info = {
- CPU_TYPE_ARM, DNBArchMachARM::Create, DNBArchMachARM::GetRegisterSetInfo,
- DNBArchMachARM::SoftwareBreakpointOpcode};
-
- // Register this arch plug-in with the main protocol class
- DNBArchProtocol::RegisterArchPlugin(arch_plugin_info);
-}
-
-DNBArchProtocol *DNBArchMachARM::Create(MachThread *thread) {
- DNBArchMachARM *obj = new DNBArchMachARM(thread);
- return obj;
-}
-
-const uint8_t *DNBArchMachARM::SoftwareBreakpointOpcode(nub_size_t byte_size) {
- switch (byte_size) {
- case 2:
- return g_thumb_breakpoint_opcode;
- case 4:
- return g_arm_breakpoint_opcode;
- }
- return NULL;
-}
-
-uint32_t DNBArchMachARM::GetCPUType() { return CPU_TYPE_ARM; }
-
-uint64_t DNBArchMachARM::GetPC(uint64_t failValue) {
- // Get program counter
- if (GetGPRState(false) == KERN_SUCCESS)
- return m_state.context.gpr.__pc;
- return failValue;
-}
-
-kern_return_t DNBArchMachARM::SetPC(uint64_t value) {
- // Get program counter
- kern_return_t err = GetGPRState(false);
- if (err == KERN_SUCCESS) {
- m_state.context.gpr.__pc = (uint32_t)value;
- err = SetGPRState();
- }
- return err == KERN_SUCCESS;
-}
-
-uint64_t DNBArchMachARM::GetSP(uint64_t failValue) {
- // Get stack pointer
- if (GetGPRState(false) == KERN_SUCCESS)
- return m_state.context.gpr.__sp;
- return failValue;
-}
-
-kern_return_t DNBArchMachARM::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 = ARM_THREAD_STATE_COUNT;
- kern_return_t kret =
- ::thread_get_state(m_thread->MachPortNumber(), ARM_THREAD_STATE,
- (thread_state_t)&m_state.context.gpr, &count);
- uint32_t *r = &m_state.context.gpr.__r[0];
- DNBLogThreadedIf(
- LOG_THREAD, "thread_get_state(0x%4.4x, %u, &gpr, %u) => 0x%8.8x (count = "
- "%u) regs r0=%8.8x r1=%8.8x r2=%8.8x r3=%8.8x r4=%8.8x "
- "r5=%8.8x r6=%8.8x r7=%8.8x r8=%8.8x r9=%8.8x r10=%8.8x "
- "r11=%8.8x s12=%8.8x sp=%8.8x lr=%8.8x pc=%8.8x cpsr=%8.8x",
- m_thread->MachPortNumber(), ARM_THREAD_STATE, ARM_THREAD_STATE_COUNT,
- kret, count, r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9],
- r[10], r[11], r[12], r[13], r[14], r[15], r[16]);
- m_state.SetError(set, Read, kret);
- return kret;
-}
-
-kern_return_t DNBArchMachARM::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;
-
- kern_return_t kret;
-
-#if defined(__arm64__) || defined(__aarch64__)
- // Read the registers from our thread
- mach_msg_type_number_t count = ARM_NEON_STATE_COUNT;
- kret = ::thread_get_state(m_thread->MachPortNumber(), ARM_NEON_STATE,
- (thread_state_t)&m_state.context.vfp, &count);
- if (DNBLogEnabledForAny(LOG_THREAD)) {
- 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 fpsr = 0x%8.8x"
- "\n fpcr = 0x%8.8x\n\n",
- m_thread->MachPortNumber(), ARM_NEON_STATE, ARM_NEON_STATE_COUNT, 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],
- m_state.context.vfp.__fpsr, m_state.context.vfp.__fpcr);
- }
-#else
- // Read the registers from our thread
- mach_msg_type_number_t count = ARM_VFP_STATE_COUNT;
- kret = ::thread_get_state(m_thread->MachPortNumber(), ARM_VFP_STATE,
- (thread_state_t)&m_state.context.vfp, &count);
-
- if (DNBLogEnabledForAny(LOG_THREAD)) {
- uint32_t *r = &m_state.context.vfp.__r[0];
- DNBLogThreaded(
- "thread_get_state(0x%4.4x, %u, &gpr, %u) => 0x%8.8x (count => %u)",
- m_thread->MachPortNumber(), ARM_THREAD_STATE, ARM_THREAD_STATE_COUNT,
- kret, count);
- DNBLogThreaded(" s0=%8.8x s1=%8.8x s2=%8.8x s3=%8.8x s4=%8.8x "
- "s5=%8.8x s6=%8.8x s7=%8.8x",
- r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7]);
- DNBLogThreaded(" s8=%8.8x s9=%8.8x s10=%8.8x s11=%8.8x s12=%8.8x "
- "s13=%8.8x s14=%8.8x s15=%8.8x",
- r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15]);
- DNBLogThreaded(" s16=%8.8x s17=%8.8x s18=%8.8x s19=%8.8x s20=%8.8x "
- "s21=%8.8x s22=%8.8x s23=%8.8x",
- r[16], r[17], r[18], r[19], r[20], r[21], r[22], r[23]);
- DNBLogThreaded(" s24=%8.8x s25=%8.8x s26=%8.8x s27=%8.8x s28=%8.8x "
- "s29=%8.8x s30=%8.8x s31=%8.8x",
- r[24], r[25], r[26], r[27], r[28], r[29], r[30], r[31]);
- DNBLogThreaded(" s32=%8.8x s33=%8.8x s34=%8.8x s35=%8.8x s36=%8.8x "
- "s37=%8.8x s38=%8.8x s39=%8.8x",
- r[32], r[33], r[34], r[35], r[36], r[37], r[38], r[39]);
- DNBLogThreaded(" s40=%8.8x s41=%8.8x s42=%8.8x s43=%8.8x s44=%8.8x "
- "s45=%8.8x s46=%8.8x s47=%8.8x",
- r[40], r[41], r[42], r[43], r[44], r[45], r[46], r[47]);
- DNBLogThreaded(" s48=%8.8x s49=%8.8x s50=%8.8x s51=%8.8x s52=%8.8x "
- "s53=%8.8x s54=%8.8x s55=%8.8x",
- r[48], r[49], r[50], r[51], r[52], r[53], r[54], r[55]);
- DNBLogThreaded(" s56=%8.8x s57=%8.8x s58=%8.8x s59=%8.8x s60=%8.8x "
- "s61=%8.8x s62=%8.8x s63=%8.8x fpscr=%8.8x",
- r[56], r[57], r[58], r[59], r[60], r[61], r[62], r[63],
- r[64]);
- }
-
-#endif
- m_state.SetError(set, Read, kret);
- return kret;
-}
-
-kern_return_t DNBArchMachARM::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 = ARM_EXCEPTION_STATE_COUNT;
- kern_return_t kret =
- ::thread_get_state(m_thread->MachPortNumber(), ARM_EXCEPTION_STATE,
- (thread_state_t)&m_state.context.exc, &count);
- m_state.SetError(set, Read, kret);
- return kret;
-}
-
-static void DumpDBGState(const DNBArchMachARM::DBG &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 DNBArchMachARM::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
-#if defined(ARM_DEBUG_STATE32) && (defined(__arm64__) || defined(__aarch64__))
- 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;
-}
-
-kern_return_t DNBArchMachARM::SetGPRState() {
- int set = e_regSetGPR;
- kern_return_t kret = ::thread_set_state(
- m_thread->MachPortNumber(), ARM_THREAD_STATE,
- (thread_state_t)&m_state.context.gpr, ARM_THREAD_STATE_COUNT);
- 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 DNBArchMachARM::SetVFPState() {
- int set = e_regSetVFP;
- kern_return_t kret;
- mach_msg_type_number_t count;
-
-#if defined(__arm64__) || defined(__aarch64__)
- count = ARM_NEON_STATE_COUNT;
- kret = ::thread_set_state(m_thread->MachPortNumber(), ARM_NEON_STATE,
- (thread_state_t)&m_state.context.vfp, count);
-#else
- count = ARM_VFP_STATE_COUNT;
- kret = ::thread_set_state(m_thread->MachPortNumber(), ARM_VFP_STATE,
- (thread_state_t)&m_state.context.vfp, count);
-#endif
-
-#if defined(__arm64__) || defined(__aarch64__)
- if (DNBLogEnabledForAny(LOG_THREAD)) {
- DNBLogThreaded(
- "thread_set_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 fpsr = 0x%8.8x"
- "\n fpcr = 0x%8.8x\n\n",
- m_thread->MachPortNumber(), ARM_NEON_STATE, ARM_NEON_STATE_COUNT, 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],
- m_state.context.vfp.__fpsr, m_state.context.vfp.__fpcr);
- }
-#else
- if (DNBLogEnabledForAny(LOG_THREAD)) {
- uint32_t *r = &m_state.context.vfp.__r[0];
- DNBLogThreaded(
- "thread_get_state(0x%4.4x, %u, &gpr, %u) => 0x%8.8x (count => %u)",
- m_thread->MachPortNumber(), ARM_THREAD_STATE, ARM_THREAD_STATE_COUNT,
- kret, count);
- DNBLogThreaded(" s0=%8.8x s1=%8.8x s2=%8.8x s3=%8.8x s4=%8.8x "
- "s5=%8.8x s6=%8.8x s7=%8.8x",
- r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7]);
- DNBLogThreaded(" s8=%8.8x s9=%8.8x s10=%8.8x s11=%8.8x s12=%8.8x "
- "s13=%8.8x s14=%8.8x s15=%8.8x",
- r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15]);
- DNBLogThreaded(" s16=%8.8x s17=%8.8x s18=%8.8x s19=%8.8x s20=%8.8x "
- "s21=%8.8x s22=%8.8x s23=%8.8x",
- r[16], r[17], r[18], r[19], r[20], r[21], r[22], r[23]);
- DNBLogThreaded(" s24=%8.8x s25=%8.8x s26=%8.8x s27=%8.8x s28=%8.8x "
- "s29=%8.8x s30=%8.8x s31=%8.8x",
- r[24], r[25], r[26], r[27], r[28], r[29], r[30], r[31]);
- DNBLogThreaded(" s32=%8.8x s33=%8.8x s34=%8.8x s35=%8.8x s36=%8.8x "
- "s37=%8.8x s38=%8.8x s39=%8.8x",
- r[32], r[33], r[34], r[35], r[36], r[37], r[38], r[39]);
- DNBLogThreaded(" s40=%8.8x s41=%8.8x s42=%8.8x s43=%8.8x s44=%8.8x "
- "s45=%8.8x s46=%8.8x s47=%8.8x",
- r[40], r[41], r[42], r[43], r[44], r[45], r[46], r[47]);
- DNBLogThreaded(" s48=%8.8x s49=%8.8x s50=%8.8x s51=%8.8x s52=%8.8x "
- "s53=%8.8x s54=%8.8x s55=%8.8x",
- r[48], r[49], r[50], r[51], r[52], r[53], r[54], r[55]);
- DNBLogThreaded(" s56=%8.8x s57=%8.8x s58=%8.8x s59=%8.8x s60=%8.8x "
- "s61=%8.8x s62=%8.8x s63=%8.8x fpscr=%8.8x",
- r[56], r[57], r[58], r[59], r[60], r[61], r[62], r[63],
- r[64]);
- }
-#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
- return kret; // Return the error code
-}
-
-kern_return_t DNBArchMachARM::SetEXCState() {
- int set = e_regSetEXC;
- kern_return_t kret = ::thread_set_state(
- m_thread->MachPortNumber(), ARM_EXCEPTION_STATE,
- (thread_state_t)&m_state.context.exc, ARM_EXCEPTION_STATE_COUNT);
- 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 DNBArchMachARM::SetDBGState(bool also_set_on_task) {
- int set = e_regSetDBG;
-#if defined(ARM_DEBUG_STATE32) && (defined(__arm64__) || defined(__aarch64__))
- 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) {
- kern_return_t task_kret = ::task_set_state(
- m_thread->Process()->Task().TaskPort(), ARM_DEBUG_STATE,
- (thread_state_t)&m_state.dbg, ARM_DEBUG_STATE_COUNT);
- 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
- return kret; // Return the error code
-}
-
-void DNBArchMachARM::ThreadWillResume() {
- // Do we need to step this thread? If so, let the mach thread tell us so.
- if (m_thread->IsStepping()) {
- // This is the primary thread, let the arch do anything it needs
- if (NumSupportedHardwareBreakpoints() > 0) {
- if (EnableHardwareSingleStep(true) != KERN_SUCCESS) {
- DNBLogThreaded("DNBArchMachARM::ThreadWillResume() failed to enable "
- "hardware single step");
- }
- }
- }
-
- // 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 DNBArchMachARM::ThreadDidStop() {
- bool success = true;
-
- m_state.InvalidateRegisterSetState(e_regSetALL);
-
- 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()) {
- 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;
-}
-
-bool DNBArchMachARM::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);
- 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 DNBArchMachARM::StepNotComplete() {
- if (m_hw_single_chained_step_addr != INVALID_NUB_ADDRESS) {
- kern_return_t kret = KERN_INVALID_ARGUMENT;
- kret = GetGPRState(false);
- if (kret == KERN_SUCCESS) {
- if (m_state.context.gpr.__pc == m_hw_single_chained_step_addr) {
- DNBLogThreadedIf(LOG_STEP, "Need to step some more at 0x%8.8llx",
- (uint64_t)m_hw_single_chained_step_addr);
- return true;
- }
- }
- }
-
- m_hw_single_chained_step_addr = INVALID_NUB_ADDRESS;
- return false;
-}
-
-// Set the single step bit in the processor status register.
-kern_return_t DNBArchMachARM::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.Status();
- }
-
- err = GetDBGState(false);
-
- if (err.Fail()) {
- err.LogThreaded("%s: failed to read the DBG registers", __FUNCTION__);
- return err.Status();
- }
-
-// 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__) || defined(__aarch64__)
- 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) {
- m_hw_single_chained_step_addr = INVALID_NUB_ADDRESS;
-
- // Save our previous state
- m_dbg_save = m_state.dbg;
- // Set a breakpoint that will stop when the PC doesn't match the current
- // one!
- m_state.dbg.__bvr[i] =
- m_state.context.gpr.__pc &
- 0xFFFFFFFCu; // Set the current PC as the breakpoint address
- m_state.dbg.__bcr[i] = BCR_M_IMVA_MISMATCH | // Stop on address mismatch
- S_USER | // Stop only in user mode
- BCR_ENABLE; // Enable this breakpoint
- if (m_state.context.gpr.__cpsr & 0x20) {
- // Thumb breakpoint
- if (m_state.context.gpr.__pc & 2)
- m_state.dbg.__bcr[i] |= BAS_IMVA_2_3;
- else
- m_state.dbg.__bcr[i] |= BAS_IMVA_0_1;
-
- uint16_t opcode;
- if (sizeof(opcode) ==
- m_thread->Process()->Task().ReadMemory(m_state.context.gpr.__pc,
- sizeof(opcode), &opcode)) {
- if (IsThumb32Opcode(opcode)) {
- // 32 bit thumb opcode...
- if (m_state.context.gpr.__pc & 2) {
- // We can't take care of a 32 bit thumb instruction single step
- // with just IVA mismatching. We will need to chain an extra
- // hardware single step in order to complete this single step...
- m_hw_single_chained_step_addr = m_state.context.gpr.__pc + 2;
- } else {
- // Extend the number of bits to ignore for the mismatch
- m_state.dbg.__bcr[i] |= BAS_IMVA_ALL;
- }
- }
- }
- } else {
- // ARM breakpoint
- m_state.dbg.__bcr[i] |= BAS_IMVA_ALL; // Stop when any address bits change
- }
-
- DNBLogThreadedIf(LOG_STEP, "%s: BVR%u=0x%8.8x BCR%u=0x%8.8x", __FUNCTION__,
- i, m_state.dbg.__bvr[i], i, m_state.dbg.__bcr[i]);
-
- for (uint32_t j = i + 1; j < 16; ++j) {
- // Disable all others
- m_state.dbg.__bvr[j] = 0;
- m_state.dbg.__bcr[j] = 0;
- }
- } else {
- // Just restore the state we had before we did single stepping
- m_state.dbg = m_dbg_save;
- }
-#endif
-
- 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 uint32_t bits(uint32_t value, uint32_t msbit, uint32_t lsbit) {
- assert(msbit >= lsbit);
- uint32_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
-}
-
-bool DNBArchMachARM::ConditionPassed(uint8_t condition, uint32_t cpsr) {
- uint32_t cpsr_n = bit(cpsr, 31); // Negative condition code flag
- uint32_t cpsr_z = bit(cpsr, 30); // Zero condition code flag
- uint32_t cpsr_c = bit(cpsr, 29); // Carry condition code flag
- uint32_t cpsr_v = bit(cpsr, 28); // Overflow condition code flag
-
- switch (condition) {
- case COND_EQ: // (0x0)
- if (cpsr_z == 1)
- return true;
- break;
- case COND_NE: // (0x1)
- if (cpsr_z == 0)
- return true;
- break;
- case COND_CS: // (0x2)
- if (cpsr_c == 1)
- return true;
- break;
- case COND_CC: // (0x3)
- if (cpsr_c == 0)
- return true;
- break;
- case COND_MI: // (0x4)
- if (cpsr_n == 1)
- return true;
- break;
- case COND_PL: // (0x5)
- if (cpsr_n == 0)
- return true;
- break;
- case COND_VS: // (0x6)
- if (cpsr_v == 1)
- return true;
- break;
- case COND_VC: // (0x7)
- if (cpsr_v == 0)
- return true;
- break;
- case COND_HI: // (0x8)
- if ((cpsr_c == 1) && (cpsr_z == 0))
- return true;
- break;
- case COND_LS: // (0x9)
- if ((cpsr_c == 0) || (cpsr_z == 1))
- return true;
- break;
- case COND_GE: // (0xA)
- if (cpsr_n == cpsr_v)
- return true;
- break;
- case COND_LT: // (0xB)
- if (cpsr_n != cpsr_v)
- return true;
- break;
- case COND_GT: // (0xC)
- if ((cpsr_z == 0) && (cpsr_n == cpsr_v))
- return true;
- break;
- case COND_LE: // (0xD)
- if ((cpsr_z == 1) || (cpsr_n != cpsr_v))
- return true;
- break;
- default:
- return true;
- break;
- }
-
- return false;
-}
-
-uint32_t DNBArchMachARM::NumSupportedHardwareBreakpoints() {
- // Set the init value to something that will let us know that we need to
- // autodetect how many breakpoints are supported dynamically...
- static uint32_t g_num_supported_hw_breakpoints = UINT_MAX;
- if (g_num_supported_hw_breakpoints == UINT_MAX) {
- // Set this to zero in case we can't tell if there are any HW breakpoints
- g_num_supported_hw_breakpoints = 0;
-
- size_t len;
- uint32_t n = 0;
- len = sizeof(n);
- if (::sysctlbyname("hw.optional.breakpoint", &n, &len, NULL, 0) == 0) {
- g_num_supported_hw_breakpoints = n;
- DNBLogThreadedIf(LOG_THREAD, "hw.optional.breakpoint=%u", n);
- } else {
-#if !defined(__arm64__) && !defined(__aarch64__)
- // 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
- // cases using a field in a sysctl. For now we are using "hw.cpusubtype"
- // field to distinguish CPU architectures. This is a hack until we can
- // get <rdar://problem/6372672> fixed, at which point we will switch to
- // using a different sysctl string that will tell us how many BRPs
- // are available to us directly without having to read DBGDIDR.
- uint32_t register_DBGDIDR;
-
- asm("mrc p14, 0, %0, c0, c0, 0" : "=r"(register_DBGDIDR));
- uint32_t numBRPs = bits(register_DBGDIDR, 27, 24);
- // Zero is reserved for the BRP count, so don't increment it if it is zero
- if (numBRPs > 0)
- numBRPs++;
- DNBLogThreadedIf(LOG_THREAD, "DBGDIDR=0x%8.8x (number BRP pairs = %u)",
- register_DBGDIDR, numBRPs);
-
- if (numBRPs > 0) {
- uint32_t cpusubtype;
- len = sizeof(cpusubtype);
- // TODO: remove this hack and change to using hw.optional.xx when
- // implmented
- if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0) {
- DNBLogThreadedIf(LOG_THREAD, "hw.cpusubtype=%d", cpusubtype);
- if (cpusubtype == CPU_SUBTYPE_ARM_V7)
- DNBLogThreadedIf(LOG_THREAD, "Hardware breakpoints disabled for "
- "armv7 (rdar://problem/6372672)");
- else
- g_num_supported_hw_breakpoints = numBRPs;
- }
- }
-#endif
- }
- }
- return g_num_supported_hw_breakpoints;
-}
-
-uint32_t DNBArchMachARM::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 {
-#if !defined(__arm64__) && !defined(__aarch64__)
- // 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
- // cases using a field in a sysctl. For now we are using "hw.cpusubtype"
- // field to distinguish CPU architectures. This is a hack until we can
- // get <rdar://problem/6372672> fixed, at which point we will switch to
- // using a different sysctl string that will tell us how many WRPs
- // are available to us directly without having to read DBGDIDR.
-
- uint32_t register_DBGDIDR;
- asm("mrc p14, 0, %0, c0, c0, 0" : "=r"(register_DBGDIDR));
- uint32_t numWRPs = bits(register_DBGDIDR, 31, 28) + 1;
- DNBLogThreadedIf(LOG_THREAD, "DBGDIDR=0x%8.8x (number WRP pairs = %u)",
- register_DBGDIDR, numWRPs);
-
- if (numWRPs > 0) {
- uint32_t cpusubtype;
- size_t len;
- len = sizeof(cpusubtype);
- // TODO: remove this hack and change to using hw.optional.xx when
- // implmented
- if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0) {
- DNBLogThreadedIf(LOG_THREAD, "hw.cpusubtype=0x%d", cpusubtype);
-
- if (cpusubtype == CPU_SUBTYPE_ARM_V7)
- DNBLogThreadedIf(LOG_THREAD, "Hardware watchpoints disabled for "
- "armv7 (rdar://problem/6372672)");
- else
- g_num_supported_hw_watchpoints = numWRPs;
- }
- }
-#endif
- }
- }
- return g_num_supported_hw_watchpoints;
-}
-
-uint32_t DNBArchMachARM::EnableHardwareBreakpoint(nub_addr_t addr,
- nub_size_t size) {
- // Make sure our address isn't bogus
- if (addr & 1)
- return INVALID_NUB_HW_INDEX;
-
- kern_return_t kret = GetDBGState(false);
-
- if (kret == KERN_SUCCESS) {
- const uint32_t num_hw_breakpoints = NumSupportedHardwareBreakpoints();
- uint32_t i;
- for (i = 0; i < num_hw_breakpoints; ++i) {
- if ((m_state.dbg.__bcr[i] & BCR_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_breakpoints) {
- // Make sure bits 1:0 are clear in our address
- m_state.dbg.__bvr[i] = addr & ~((nub_addr_t)3);
-
- if (size == 2 || addr & 2) {
- uint32_t byte_addr_select = (addr & 2) ? BAS_IMVA_2_3 : BAS_IMVA_0_1;
-
- // We have a thumb breakpoint
- // We have an ARM breakpoint
- m_state.dbg.__bcr[i] =
- BCR_M_IMVA_MATCH | // Stop on address mismatch
- byte_addr_select | // Set the correct byte address select so we only
- // trigger on the correct opcode
- S_USER | // Which modes should this breakpoint stop in?
- BCR_ENABLE; // Enable this hardware breakpoint
- DNBLogThreadedIf(LOG_BREAKPOINTS,
- "DNBArchMachARM::EnableHardwareBreakpoint( addr = "
- "0x%8.8llx, size = %llu ) - BVR%u/BCR%u = 0x%8.8x / "
- "0x%8.8x (Thumb)",
- (uint64_t)addr, (uint64_t)size, i, i,
- m_state.dbg.__bvr[i], m_state.dbg.__bcr[i]);
- } else if (size == 4) {
- // We have an ARM breakpoint
- m_state.dbg.__bcr[i] =
- BCR_M_IMVA_MATCH | // Stop on address mismatch
- BAS_IMVA_ALL | // Stop on any of the four bytes following the IMVA
- S_USER | // Which modes should this breakpoint stop in?
- BCR_ENABLE; // Enable this hardware breakpoint
- DNBLogThreadedIf(LOG_BREAKPOINTS,
- "DNBArchMachARM::EnableHardwareBreakpoint( addr = "
- "0x%8.8llx, size = %llu ) - BVR%u/BCR%u = 0x%8.8x / "
- "0x%8.8x (ARM)",
- (uint64_t)addr, (uint64_t)size, i, i,
- m_state.dbg.__bvr[i], m_state.dbg.__bcr[i]);
- }
-
- kret = SetDBGState(false);
- DNBLogThreadedIf(LOG_BREAKPOINTS, "DNBArchMachARM::"
- "EnableHardwareBreakpoint() "
- "SetDBGState() => 0x%8.8x.",
- kret);
-
- if (kret == KERN_SUCCESS)
- return i;
- } else {
- DNBLogThreadedIf(LOG_BREAKPOINTS,
- "DNBArchMachARM::EnableHardwareBreakpoint(addr = "
- "0x%8.8llx, size = %llu) => all hardware breakpoint "
- "resources are being used.",
- (uint64_t)addr, (uint64_t)size);
- }
- }
-
- return INVALID_NUB_HW_INDEX;
-}
-
-bool DNBArchMachARM::DisableHardwareBreakpoint(uint32_t hw_index) {
- kern_return_t kret = GetDBGState(false);
-
- const uint32_t num_hw_points = NumSupportedHardwareBreakpoints();
- if (kret == KERN_SUCCESS) {
- if (hw_index < num_hw_points) {
- m_state.dbg.__bcr[hw_index] = 0;
- DNBLogThreadedIf(LOG_BREAKPOINTS, "DNBArchMachARM::SetHardwareBreakpoint("
- " %u ) - BVR%u = 0x%8.8x BCR%u = "
- "0x%8.8x",
- hw_index, hw_index, m_state.dbg.__bvr[hw_index],
- hw_index, m_state.dbg.__bcr[hw_index]);
-
- kret = SetDBGState(false);
-
- if (kret == KERN_SUCCESS)
- return true;
- }
- }
- return false;
-}
-
-// 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__) || defined(__aarch64__)
-#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) {
-
- DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::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;
-
-// 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(
- 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);
- 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(true);
-
- 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, "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);
-
- DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::"
- "EnableHardwareWatchpoint() "
- "SetDBGState() => 0x%8.8x.",
- kret);
-
- if (kret == KERN_SUCCESS)
- return i;
- } else {
- DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::"
- "EnableHardwareWatchpoint(): All "
- "hardware resources (%u) are in use.",
- num_hw_watchpoints);
- }
- }
- return INVALID_NUB_HW_INDEX;
-}
-
-bool 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;
-
- 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, "DNBArchMachARM::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 DNBArchMachARM::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 DNBArchMachARM::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.__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, (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);
-}
-
-// Returns -1 if the trailing bit patterns are not one of:
-// { 0b???1, 0b??10, 0b?100, 0b1000 }.
-static inline int32_t LowestBitSet(uint32_t val) {
- for (unsigned i = 0; i < 4; ++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 DNBArchMachARM::GetHardwareWatchpointHit(nub_addr_t &addr) {
- // Read the debug state
- kern_return_t kret = GetDBGState(true);
- // DumpDBGState(m_state.dbg);
- DNBLogThreadedIf(
- LOG_WATCHPOINTS,
- "DNBArchMachARM::GetHardwareWatchpointHit() GetDBGState() => 0x%8.8x.",
- kret);
- 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;
- uint32_t i, num = NumSupportedHardwareWatchpoints();
- for (i = 0; i < num; ++i) {
- nub_addr_t wp_addr = GetWatchAddress(debug_state, i);
- DNBLogThreadedIf(LOG_WATCHPOINTS, "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)
- 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 DNBArchMachARM::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 DNBArchMachARM::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 DNBArchMachARM::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], 31, 0);
-}
-
-//----------------------------------------------------------------------
-// Register information definitions for 32 bit ARMV7.
-//----------------------------------------------------------------------
-enum gpr_regnums {
- gpr_r0 = 0,
- gpr_r1,
- gpr_r2,
- gpr_r3,
- gpr_r4,
- gpr_r5,
- gpr_r6,
- gpr_r7,
- gpr_r8,
- gpr_r9,
- gpr_r10,
- gpr_r11,
- gpr_r12,
- gpr_sp,
- gpr_lr,
- gpr_pc,
- gpr_cpsr
-};
-
-enum {
- vfp_s0 = 0,
- 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,
- 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,
- vfp_q0,
- vfp_q1,
- vfp_q2,
- vfp_q3,
- vfp_q4,
- vfp_q5,
- vfp_q6,
- vfp_q7,
- vfp_q8,
- vfp_q9,
- vfp_q10,
- vfp_q11,
- vfp_q12,
- vfp_q13,
- vfp_q14,
- vfp_q15,
-#if defined(__arm64__) || defined(__aarch64__)
- vfp_fpsr,
- vfp_fpcr,
-#else
- vfp_fpscr
-#endif
-};
-
-enum {
- exc_exception,
- exc_fsr,
- exc_far,
-};
-
-#define GPR_OFFSET_IDX(idx) (offsetof(DNBArchMachARM::GPR, __r[idx]))
-#define GPR_OFFSET_NAME(reg) (offsetof(DNBArchMachARM::GPR, __##reg))
-
-#define EXC_OFFSET(reg) \
- (offsetof(DNBArchMachARM::EXC, __##reg) + \
- offsetof(DNBArchMachARM::Context, exc))
-
-// 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, 4, GPR_OFFSET_IDX(idx), \
- ehframe_##reg, dwarf_##reg, gen, INVALID_NUB_REGNUM, NULL, NULL \
- }
-#define DEFINE_GPR_NAME(reg, alt, gen, inval) \
- { \
- e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, 4, GPR_OFFSET_NAME(reg), \
- ehframe_##reg, dwarf_##reg, gen, INVALID_NUB_REGNUM, NULL, inval \
- }
-
-// In case we are debugging to a debug target that the ability to
-// change into the protected modes with folded registers (ABT, IRQ,
-// FIQ, SYS, USR, etc..), we should invalidate r8-r14 if the CPSR
-// gets modified.
-
-const char *g_invalidate_cpsr[] = {"r8", "r9", "r10", "r11",
- "r12", "sp", "lr", NULL};
-
-// General purpose registers
-const DNBRegisterInfo DNBArchMachARM::g_gpr_registers[] = {
- DEFINE_GPR_IDX(0, r0, "arg1", GENERIC_REGNUM_ARG1),
- DEFINE_GPR_IDX(1, r1, "arg2", GENERIC_REGNUM_ARG2),
- DEFINE_GPR_IDX(2, r2, "arg3", GENERIC_REGNUM_ARG3),
- DEFINE_GPR_IDX(3, r3, "arg4", GENERIC_REGNUM_ARG4),
- DEFINE_GPR_IDX(4, r4, NULL, INVALID_NUB_REGNUM),
- DEFINE_GPR_IDX(5, r5, NULL, INVALID_NUB_REGNUM),
- DEFINE_GPR_IDX(6, r6, NULL, INVALID_NUB_REGNUM),
- DEFINE_GPR_IDX(7, r7, "fp", GENERIC_REGNUM_FP),
- DEFINE_GPR_IDX(8, r8, NULL, INVALID_NUB_REGNUM),
- DEFINE_GPR_IDX(9, r9, NULL, INVALID_NUB_REGNUM),
- DEFINE_GPR_IDX(10, r10, NULL, INVALID_NUB_REGNUM),
- DEFINE_GPR_IDX(11, r11, NULL, INVALID_NUB_REGNUM),
- DEFINE_GPR_IDX(12, r12, NULL, INVALID_NUB_REGNUM),
- DEFINE_GPR_NAME(sp, "r13", GENERIC_REGNUM_SP, NULL),
- DEFINE_GPR_NAME(lr, "r14", GENERIC_REGNUM_RA, NULL),
- DEFINE_GPR_NAME(pc, "r15", GENERIC_REGNUM_PC, NULL),
- DEFINE_GPR_NAME(cpsr, "flags", GENERIC_REGNUM_FLAGS, g_invalidate_cpsr)};
-
-const char *g_contained_q0[]{"q0", NULL};
-const char *g_contained_q1[]{"q1", NULL};
-const char *g_contained_q2[]{"q2", NULL};
-const char *g_contained_q3[]{"q3", NULL};
-const char *g_contained_q4[]{"q4", NULL};
-const char *g_contained_q5[]{"q5", NULL};
-const char *g_contained_q6[]{"q6", NULL};
-const char *g_contained_q7[]{"q7", NULL};
-const char *g_contained_q8[]{"q8", NULL};
-const char *g_contained_q9[]{"q9", NULL};
-const char *g_contained_q10[]{"q10", NULL};
-const char *g_contained_q11[]{"q11", NULL};
-const char *g_contained_q12[]{"q12", NULL};
-const char *g_contained_q13[]{"q13", NULL};
-const char *g_contained_q14[]{"q14", NULL};
-const char *g_contained_q15[]{"q15", NULL};
-
-const char *g_invalidate_q0[]{"q0", "d0", "d1", "s0", "s1", "s2", "s3", NULL};
-const char *g_invalidate_q1[]{"q1", "d2", "d3", "s4", "s5", "s6", "s7", NULL};
-const char *g_invalidate_q2[]{"q2", "d4", "d5", "s8", "s9", "s10", "s11", NULL};
-const char *g_invalidate_q3[]{"q3", "d6", "d7", "s12",
- "s13", "s14", "s15", NULL};
-const char *g_invalidate_q4[]{"q4", "d8", "d9", "s16",
- "s17", "s18", "s19", NULL};
-const char *g_invalidate_q5[]{"q5", "d10", "d11", "s20",
- "s21", "s22", "s23", NULL};
-const char *g_invalidate_q6[]{"q6", "d12", "d13", "s24",
- "s25", "s26", "s27", NULL};
-const char *g_invalidate_q7[]{"q7", "d14", "d15", "s28",
- "s29", "s30", "s31", NULL};
-const char *g_invalidate_q8[]{"q8", "d16", "d17", NULL};
-const char *g_invalidate_q9[]{"q9", "d18", "d19", NULL};
-const char *g_invalidate_q10[]{"q10", "d20", "d21", NULL};
-const char *g_invalidate_q11[]{"q11", "d22", "d23", NULL};
-const char *g_invalidate_q12[]{"q12", "d24", "d25", NULL};
-const char *g_invalidate_q13[]{"q13", "d26", "d27", NULL};
-const char *g_invalidate_q14[]{"q14", "d28", "d29", NULL};
-const char *g_invalidate_q15[]{"q15", "d30", "d31", NULL};
-
-#define VFP_S_OFFSET_IDX(idx) \
- (((idx) % 4) * 4) // offset into q reg: 0, 4, 8, 12
-#define VFP_D_OFFSET_IDX(idx) (((idx) % 2) * 8) // offset into q reg: 0, 8
-#define VFP_Q_OFFSET_IDX(idx) (VFP_S_OFFSET_IDX((idx)*4))
-
-#define VFP_OFFSET_NAME(reg) \
- (offsetof(DNBArchMachARM::FPU, __##reg) + \
- offsetof(DNBArchMachARM::Context, vfp))
-
-#define FLOAT_FORMAT Float
-
-#define DEFINE_VFP_S_IDX(idx) \
- e_regSetVFP, vfp_s##idx, "s" #idx, NULL, IEEE754, FLOAT_FORMAT, 4, \
- VFP_S_OFFSET_IDX(idx), INVALID_NUB_REGNUM, dwarf_s##idx, \
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM
-#define DEFINE_VFP_D_IDX(idx) \
- e_regSetVFP, vfp_d##idx, "d" #idx, NULL, IEEE754, FLOAT_FORMAT, 8, \
- VFP_D_OFFSET_IDX(idx), INVALID_NUB_REGNUM, dwarf_d##idx, \
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM
-#define DEFINE_VFP_Q_IDX(idx) \
- e_regSetVFP, vfp_q##idx, "q" #idx, NULL, Vector, VectorOfUInt8, 16, \
- VFP_Q_OFFSET_IDX(idx), INVALID_NUB_REGNUM, dwarf_q##idx, \
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM
-
-// Floating point registers
-const DNBRegisterInfo DNBArchMachARM::g_vfp_registers[] = {
- {DEFINE_VFP_S_IDX(0), g_contained_q0, g_invalidate_q0},
- {DEFINE_VFP_S_IDX(1), g_contained_q0, g_invalidate_q0},
- {DEFINE_VFP_S_IDX(2), g_contained_q0, g_invalidate_q0},
- {DEFINE_VFP_S_IDX(3), g_contained_q0, g_invalidate_q0},
- {DEFINE_VFP_S_IDX(4), g_contained_q1, g_invalidate_q1},
- {DEFINE_VFP_S_IDX(5), g_contained_q1, g_invalidate_q1},
- {DEFINE_VFP_S_IDX(6), g_contained_q1, g_invalidate_q1},
- {DEFINE_VFP_S_IDX(7), g_contained_q1, g_invalidate_q1},
- {DEFINE_VFP_S_IDX(8), g_contained_q2, g_invalidate_q2},
- {DEFINE_VFP_S_IDX(9), g_contained_q2, g_invalidate_q2},
- {DEFINE_VFP_S_IDX(10), g_contained_q2, g_invalidate_q2},
- {DEFINE_VFP_S_IDX(11), g_contained_q2, g_invalidate_q2},
- {DEFINE_VFP_S_IDX(12), g_contained_q3, g_invalidate_q3},
- {DEFINE_VFP_S_IDX(13), g_contained_q3, g_invalidate_q3},
- {DEFINE_VFP_S_IDX(14), g_contained_q3, g_invalidate_q3},
- {DEFINE_VFP_S_IDX(15), g_contained_q3, g_invalidate_q3},
- {DEFINE_VFP_S_IDX(16), g_contained_q4, g_invalidate_q4},
- {DEFINE_VFP_S_IDX(17), g_contained_q4, g_invalidate_q4},
- {DEFINE_VFP_S_IDX(18), g_contained_q4, g_invalidate_q4},
- {DEFINE_VFP_S_IDX(19), g_contained_q4, g_invalidate_q4},
- {DEFINE_VFP_S_IDX(20), g_contained_q5, g_invalidate_q5},
- {DEFINE_VFP_S_IDX(21), g_contained_q5, g_invalidate_q5},
- {DEFINE_VFP_S_IDX(22), g_contained_q5, g_invalidate_q5},
- {DEFINE_VFP_S_IDX(23), g_contained_q5, g_invalidate_q5},
- {DEFINE_VFP_S_IDX(24), g_contained_q6, g_invalidate_q6},
- {DEFINE_VFP_S_IDX(25), g_contained_q6, g_invalidate_q6},
- {DEFINE_VFP_S_IDX(26), g_contained_q6, g_invalidate_q6},
- {DEFINE_VFP_S_IDX(27), g_contained_q6, g_invalidate_q6},
- {DEFINE_VFP_S_IDX(28), g_contained_q7, g_invalidate_q7},
- {DEFINE_VFP_S_IDX(29), g_contained_q7, g_invalidate_q7},
- {DEFINE_VFP_S_IDX(30), g_contained_q7, g_invalidate_q7},
- {DEFINE_VFP_S_IDX(31), g_contained_q7, g_invalidate_q7},
-
- {DEFINE_VFP_D_IDX(0), g_contained_q0, g_invalidate_q0},
- {DEFINE_VFP_D_IDX(1), g_contained_q0, g_invalidate_q0},
- {DEFINE_VFP_D_IDX(2), g_contained_q1, g_invalidate_q1},
- {DEFINE_VFP_D_IDX(3), g_contained_q1, g_invalidate_q1},
- {DEFINE_VFP_D_IDX(4), g_contained_q2, g_invalidate_q2},
- {DEFINE_VFP_D_IDX(5), g_contained_q2, g_invalidate_q2},
- {DEFINE_VFP_D_IDX(6), g_contained_q3, g_invalidate_q3},
- {DEFINE_VFP_D_IDX(7), g_contained_q3, g_invalidate_q3},
- {DEFINE_VFP_D_IDX(8), g_contained_q4, g_invalidate_q4},
- {DEFINE_VFP_D_IDX(9), g_contained_q4, g_invalidate_q4},
- {DEFINE_VFP_D_IDX(10), g_contained_q5, g_invalidate_q5},
- {DEFINE_VFP_D_IDX(11), g_contained_q5, g_invalidate_q5},
- {DEFINE_VFP_D_IDX(12), g_contained_q6, g_invalidate_q6},
- {DEFINE_VFP_D_IDX(13), g_contained_q6, g_invalidate_q6},
- {DEFINE_VFP_D_IDX(14), g_contained_q7, g_invalidate_q7},
- {DEFINE_VFP_D_IDX(15), g_contained_q7, g_invalidate_q7},
- {DEFINE_VFP_D_IDX(16), g_contained_q8, g_invalidate_q8},
- {DEFINE_VFP_D_IDX(17), g_contained_q8, g_invalidate_q8},
- {DEFINE_VFP_D_IDX(18), g_contained_q9, g_invalidate_q9},
- {DEFINE_VFP_D_IDX(19), g_contained_q9, g_invalidate_q9},
- {DEFINE_VFP_D_IDX(20), g_contained_q10, g_invalidate_q10},
- {DEFINE_VFP_D_IDX(21), g_contained_q10, g_invalidate_q10},
- {DEFINE_VFP_D_IDX(22), g_contained_q11, g_invalidate_q11},
- {DEFINE_VFP_D_IDX(23), g_contained_q11, g_invalidate_q11},
- {DEFINE_VFP_D_IDX(24), g_contained_q12, g_invalidate_q12},
- {DEFINE_VFP_D_IDX(25), g_contained_q12, g_invalidate_q12},
- {DEFINE_VFP_D_IDX(26), g_contained_q13, g_invalidate_q13},
- {DEFINE_VFP_D_IDX(27), g_contained_q13, g_invalidate_q13},
- {DEFINE_VFP_D_IDX(28), g_contained_q14, g_invalidate_q14},
- {DEFINE_VFP_D_IDX(29), g_contained_q14, g_invalidate_q14},
- {DEFINE_VFP_D_IDX(30), g_contained_q15, g_invalidate_q15},
- {DEFINE_VFP_D_IDX(31), g_contained_q15, g_invalidate_q15},
-
- {DEFINE_VFP_Q_IDX(0), NULL, g_invalidate_q0},
- {DEFINE_VFP_Q_IDX(1), NULL, g_invalidate_q1},
- {DEFINE_VFP_Q_IDX(2), NULL, g_invalidate_q2},
- {DEFINE_VFP_Q_IDX(3), NULL, g_invalidate_q3},
- {DEFINE_VFP_Q_IDX(4), NULL, g_invalidate_q4},
- {DEFINE_VFP_Q_IDX(5), NULL, g_invalidate_q5},
- {DEFINE_VFP_Q_IDX(6), NULL, g_invalidate_q6},
- {DEFINE_VFP_Q_IDX(7), NULL, g_invalidate_q7},
- {DEFINE_VFP_Q_IDX(8), NULL, g_invalidate_q8},
- {DEFINE_VFP_Q_IDX(9), NULL, g_invalidate_q9},
- {DEFINE_VFP_Q_IDX(10), NULL, g_invalidate_q10},
- {DEFINE_VFP_Q_IDX(11), NULL, g_invalidate_q11},
- {DEFINE_VFP_Q_IDX(12), NULL, g_invalidate_q12},
- {DEFINE_VFP_Q_IDX(13), NULL, g_invalidate_q13},
- {DEFINE_VFP_Q_IDX(14), NULL, g_invalidate_q14},
- {DEFINE_VFP_Q_IDX(15), NULL, g_invalidate_q15},
-
-#if defined(__arm64__) || defined(__aarch64__)
- {e_regSetVFP, vfp_fpsr, "fpsr", NULL, Uint, Hex, 4, VFP_OFFSET_NAME(fpsr),
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, NULL, NULL},
- {e_regSetVFP, vfp_fpcr, "fpcr", NULL, Uint, Hex, 4, VFP_OFFSET_NAME(fpcr),
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, NULL, NULL}
-#else
- {e_regSetVFP, vfp_fpscr, "fpscr", NULL, Uint, Hex, 4,
- VFP_OFFSET_NAME(fpscr), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL}
-#endif
-};
-
-// Exception registers
-
-const DNBRegisterInfo DNBArchMachARM::g_exc_registers[] = {
- {e_regSetVFP, exc_exception, "exception", NULL, Uint, Hex, 4,
- EXC_OFFSET(exception), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM},
- {e_regSetVFP, exc_fsr, "fsr", NULL, Uint, Hex, 4, EXC_OFFSET(fsr),
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM},
- {e_regSetVFP, exc_far, "far", NULL, Uint, Hex, 4, EXC_OFFSET(far),
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM}};
-
-// Number of registers in each register set
-const size_t DNBArchMachARM::k_num_gpr_registers =
- sizeof(g_gpr_registers) / sizeof(DNBRegisterInfo);
-const size_t DNBArchMachARM::k_num_vfp_registers =
- sizeof(g_vfp_registers) / sizeof(DNBRegisterInfo);
-const size_t DNBArchMachARM::k_num_exc_registers =
- sizeof(g_exc_registers) / sizeof(DNBRegisterInfo);
-const size_t DNBArchMachARM::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 DNBArchMachARM::g_reg_sets[] = {
- {"ARM 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 DNBArchMachARM::k_num_register_sets =
- sizeof(g_reg_sets) / sizeof(DNBRegisterSetInfo);
-
-const DNBRegisterSetInfo *
-DNBArchMachARM::GetRegisterSetInfo(nub_size_t *num_reg_sets) {
- *num_reg_sets = k_num_register_sets;
- return g_reg_sets;
-}
-
-bool DNBArchMachARM::GetRegisterValue(uint32_t set, uint32_t reg,
- DNBRegisterValue *value) {
- 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_r7; // is this the right reg?
- 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;
-
- default:
- 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 < k_num_gpr_registers) {
- value->value.uint32 = m_state.context.gpr.__r[reg];
- return true;
- }
- break;
-
- case e_regSetVFP:
- // "reg" is an index into the floating point register set at this point.
- // We need to translate it up so entry 0 in the fp reg set is the same as
- // vfp_s0
- // in the enumerated values for case statement below.
- if (reg >= vfp_s0 && reg <= vfp_s31) {
-#if defined(__arm64__) || defined(__aarch64__)
- uint32_t *s_reg =
- ((uint32_t *)&m_state.context.vfp.__v[0]) + (reg - vfp_s0);
- memcpy(&value->value.v_uint8, s_reg, 4);
-#else
- value->value.uint32 = m_state.context.vfp.__r[reg];
-#endif
- return true;
- } else if (reg >= vfp_d0 && reg <= vfp_d31) {
-#if defined(__arm64__) || defined(__aarch64__)
- uint64_t *d_reg =
- ((uint64_t *)&m_state.context.vfp.__v[0]) + (reg - vfp_d0);
- memcpy(&value->value.v_uint8, d_reg, 8);
-#else
- uint32_t d_reg_idx = reg - vfp_d0;
- uint32_t s_reg_idx = d_reg_idx * 2;
- value->value.v_sint32[0] = m_state.context.vfp.__r[s_reg_idx + 0];
- value->value.v_sint32[1] = m_state.context.vfp.__r[s_reg_idx + 1];
-#endif
- return true;
- } else if (reg >= vfp_q0 && reg <= vfp_q15) {
-#if defined(__arm64__) || defined(__aarch64__)
- memcpy(&value->value.v_uint8,
- (uint8_t *)&m_state.context.vfp.__v[reg - vfp_q0], 16);
-#else
- uint32_t s_reg_idx = (reg - vfp_q0) * 4;
- memcpy(&value->value.v_uint8,
- (uint8_t *)&m_state.context.vfp.__r[s_reg_idx], 16);
-#endif
- return true;
- }
-#if defined(__arm64__) || defined(__aarch64__)
- else if (reg == vfp_fpsr) {
- value->value.uint32 = m_state.context.vfp.__fpsr;
- return true;
- } else if (reg == vfp_fpcr) {
- value->value.uint32 = m_state.context.vfp.__fpcr;
- return true;
- }
-#else
- else if (reg == vfp_fpscr) {
- value->value.uint32 = m_state.context.vfp.__fpscr;
- return true;
- }
-#endif
- break;
-
- case e_regSetEXC:
- if (reg < k_num_exc_registers) {
- value->value.uint32 = (&m_state.context.exc.__exception)[reg];
- return true;
- }
- break;
- }
- }
- return false;
-}
-
-bool DNBArchMachARM::SetRegisterValue(uint32_t set, uint32_t reg,
- const DNBRegisterValue *value) {
- 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_r7;
- 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;
-
- default:
- 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 < k_num_gpr_registers) {
- m_state.context.gpr.__r[reg] = value->value.uint32;
- success = true;
- }
- break;
-
- case e_regSetVFP:
- // "reg" is an index into the floating point register set at this point.
- // We need to translate it up so entry 0 in the fp reg set is the same as
- // vfp_s0
- // in the enumerated values for case statement below.
- if (reg >= vfp_s0 && reg <= vfp_s31) {
-#if defined(__arm64__) || defined(__aarch64__)
- uint32_t *s_reg =
- ((uint32_t *)&m_state.context.vfp.__v[0]) + (reg - vfp_s0);
- memcpy(s_reg, &value->value.v_uint8, 4);
-#else
- m_state.context.vfp.__r[reg] = value->value.uint32;
-#endif
- success = true;
- } else if (reg >= vfp_d0 && reg <= vfp_d31) {
-#if defined(__arm64__) || defined(__aarch64__)
- uint64_t *d_reg =
- ((uint64_t *)&m_state.context.vfp.__v[0]) + (reg - vfp_d0);
- memcpy(d_reg, &value->value.v_uint8, 8);
-#else
- uint32_t d_reg_idx = reg - vfp_d0;
- uint32_t s_reg_idx = d_reg_idx * 2;
- m_state.context.vfp.__r[s_reg_idx + 0] = value->value.v_sint32[0];
- m_state.context.vfp.__r[s_reg_idx + 1] = value->value.v_sint32[1];
-#endif
- success = true;
- } else if (reg >= vfp_q0 && reg <= vfp_q15) {
-#if defined(__arm64__) || defined(__aarch64__)
- memcpy((uint8_t *)&m_state.context.vfp.__v[reg - vfp_q0],
- &value->value.v_uint8, 16);
-#else
- uint32_t s_reg_idx = (reg - vfp_q0) * 4;
- memcpy((uint8_t *)&m_state.context.vfp.__r[s_reg_idx],
- &value->value.v_uint8, 16);
-#endif
- success = true;
- }
-#if defined(__arm64__) || defined(__aarch64__)
- else if (reg == vfp_fpsr) {
- m_state.context.vfp.__fpsr = value->value.uint32;
- success = true;
- } else if (reg == vfp_fpcr) {
- m_state.context.vfp.__fpcr = value->value.uint32;
- success = true;
- }
-#else
- else if (reg == vfp_fpscr) {
- m_state.context.vfp.__fpscr = value->value.uint32;
- success = true;
- }
-#endif
- break;
-
- case e_regSetEXC:
- if (reg < k_num_exc_registers) {
- (&m_state.context.exc.__exception)[reg] = value->value.uint32;
- success = true;
- }
- break;
- }
- }
- if (success)
- return SetRegisterState(set) == KERN_SUCCESS;
- return false;
-}
-
-kern_return_t DNBArchMachARM::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 DNBArchMachARM::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 DNBArchMachARM::RegisterSetStateIsValid(int set) const {
- return m_state.RegsAreValid(set);
-}
-
-nub_size_t DNBArchMachARM::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;
- UNUSED_IF_ASSERT_DISABLED(bytes_written);
- assert(bytes_written == size);
- }
- DNBLogThreadedIf(
- LOG_THREAD,
- "DNBArchMachARM::GetRegisterContext (buf = %p, len = %llu) => %llu", buf,
- (uint64_t)buf_len, (uint64_t)size);
- // Return the size of the register context even if NULL was passed in
- return size;
-}
-
-nub_size_t DNBArchMachARM::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;
- UNUSED_IF_ASSERT_DISABLED(bytes_written);
- assert(bytes_written == size);
-
- if (SetGPRState() | SetVFPState() | SetEXCState())
- return 0;
- }
- DNBLogThreadedIf(
- LOG_THREAD,
- "DNBArchMachARM::SetRegisterContext (buf = %p, len = %llu) => %llu", buf,
- (uint64_t)buf_len, (uint64_t)size);
- return size;
-}
-
-uint32_t DNBArchMachARM::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, "DNBArchMachARM::SaveRegisterState () error: "
- "GPR regs failed to read: %u ",
- kret);
- } else if ((kret = GetVFPState(force)) != KERN_SUCCESS) {
- DNBLogThreadedIf(LOG_THREAD, "DNBArchMachARM::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 DNBArchMachARM::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, "DNBArchMachARM::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, "DNBArchMachARM::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__)
diff --git a/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h b/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h
deleted file mode 100644
index e8622c4ec7eb..000000000000
--- a/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h
+++ /dev/null
@@ -1,275 +0,0 @@
-//===-- DNBArchImpl.h -------------------------------------------*- 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.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __DebugNubArchMachARM_h__
-#define __DebugNubArchMachARM_h__
-
-#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
-
-#include "DNBArch.h"
-
-#include <map>
-
-class MachThread;
-
-class DNBArchMachARM : public DNBArchProtocol {
-public:
- enum { kMaxNumThumbITBreakpoints = 4 };
-
- 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),
- 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));
-#if defined(USE_ARM_DISASSEMBLER_FRAMEWORK)
- ThumbStaticsInit(&m_last_decode_thumb);
-#endif
- }
-
- virtual ~DNBArchMachARM() {}
-
- static void Initialize();
- static const DNBRegisterSetInfo *GetRegisterSetInfo(nub_size_t *num_reg_sets);
-
- virtual bool GetRegisterValue(uint32_t set, uint32_t reg,
- DNBRegisterValue *value);
- virtual bool SetRegisterValue(uint32_t set, uint32_t 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 *SoftwareBreakpointOpcode(nub_size_t byte_size);
- static uint32_t GetCPUType();
-
- virtual uint32_t NumSupportedHardwareBreakpoints();
- virtual uint32_t NumSupportedHardwareWatchpoints();
- virtual uint32_t EnableHardwareBreakpoint(nub_addr_t addr, nub_size_t size);
- 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 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__) || defined(__aarch64__))
- typedef arm_debug_state32_t DBG;
-#else
- typedef arm_debug_state_t DBG;
-#endif
-
-protected:
- kern_return_t EnableHardwareSingleStep(bool enable);
- kern_return_t SetSingleStepSoftwareBreakpoints();
-
- bool ConditionPassed(uint8_t condition, uint32_t cpsr);
-#if defined(USE_ARM_DISASSEMBLER_FRAMEWORK)
- bool ComputeNextPC(nub_addr_t currentPC,
- arm_decoded_instruction_t decodedInstruction,
- bool currentPCIsThumb, nub_addr_t *targetPC);
- arm_error_t DecodeInstructionUsingDisassembler(
- nub_addr_t curr_pc, uint32_t curr_cpsr,
- arm_decoded_instruction_t *decodedInstruction,
- thumb_static_data_t *thumbStaticData, nub_addr_t *next_pc);
- void DecodeITBlockInstructions(nub_addr_t curr_pc);
-#endif
- void EvaluateNextInstructionForSoftwareBreakpointSetup(nub_addr_t currentPC,
- uint32_t cpsr,
- bool currentPCIsThumb,
- nub_addr_t *nextPC,
- bool *nextPCIsThumb);
-
- typedef enum RegisterSetTag {
- e_regSetALL = REGISTER_SET_ALL,
- e_regSetGPR, // ARM_THREAD_STATE
- e_regSetVFP, // ARM_VFP_STATE (ARM_NEON_STATE if defined __arm64__)
- e_regSetEXC, // ARM_EXCEPTION_STATE
- e_regSetDBG, // ARM_DEBUG_STATE (ARM_DEBUG_STATE32 if defined __arm64__)
- kNumRegisterSets
- } RegisterSet;
-
- enum { Read = 0, Write = 1, kNumErrors = 2 };
-
- typedef arm_thread_state_t GPR;
-#if defined(__arm64__) || defined(__aarch64__)
- typedef arm_neon_state_t FPU;
-#else
- typedef arm_vfp_state_t FPU;
-#endif
- typedef arm_exception_state_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;
- DBG 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); }
- 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);
-
- 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;
-
- // 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__)
-#endif // #ifndef __DebugNubArchMachARM_h__
diff --git a/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp b/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp
deleted file mode 100644
index 51bc5aaee5bb..000000000000
--- a/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp
+++ /dev/null
@@ -1,2104 +0,0 @@
-//===-- 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__) || defined(__aarch64__)
-
-#include "MacOSX/arm64/DNBArchImplARM64.h"
-
-#if defined(ARM_THREAD_STATE64_COUNT)
-
-#include "DNB.h"
-#include "DNBBreakpoint.h"
-#include "DNBLog.h"
-#include "DNBRegisterInfo.h"
-#include "MacOSX/MachProcess.h"
-#include "MacOSX/MachThread.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 *
-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__) || defined(__aarch64__)
- 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.Status();
- }
-
- err = GetDBGState(false);
-
- if (err.Fail()) {
- err.LogThreaded("%s: failed to read the DBG registers", __FUNCTION__);
- return err.Status();
- }
-
- 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 definitions 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 {
- debugserver_gpr_x0 = 0,
- debugserver_gpr_x1,
- debugserver_gpr_x2,
- debugserver_gpr_x3,
- debugserver_gpr_x4,
- debugserver_gpr_x5,
- debugserver_gpr_x6,
- debugserver_gpr_x7,
- debugserver_gpr_x8,
- debugserver_gpr_x9,
- debugserver_gpr_x10,
- debugserver_gpr_x11,
- debugserver_gpr_x12,
- debugserver_gpr_x13,
- debugserver_gpr_x14,
- debugserver_gpr_x15,
- debugserver_gpr_x16,
- debugserver_gpr_x17,
- debugserver_gpr_x18,
- debugserver_gpr_x19,
- debugserver_gpr_x20,
- debugserver_gpr_x21,
- debugserver_gpr_x22,
- debugserver_gpr_x23,
- debugserver_gpr_x24,
- debugserver_gpr_x25,
- debugserver_gpr_x26,
- debugserver_gpr_x27,
- debugserver_gpr_x28,
- debugserver_gpr_fp, // x29
- debugserver_gpr_lr, // x30
- debugserver_gpr_sp, // sp aka xsp
- debugserver_gpr_pc,
- debugserver_gpr_cpsr,
- debugserver_vfp_v0,
- debugserver_vfp_v1,
- debugserver_vfp_v2,
- debugserver_vfp_v3,
- debugserver_vfp_v4,
- debugserver_vfp_v5,
- debugserver_vfp_v6,
- debugserver_vfp_v7,
- debugserver_vfp_v8,
- debugserver_vfp_v9,
- debugserver_vfp_v10,
- debugserver_vfp_v11,
- debugserver_vfp_v12,
- debugserver_vfp_v13,
- debugserver_vfp_v14,
- debugserver_vfp_v15,
- debugserver_vfp_v16,
- debugserver_vfp_v17,
- debugserver_vfp_v18,
- debugserver_vfp_v19,
- debugserver_vfp_v20,
- debugserver_vfp_v21,
- debugserver_vfp_v22,
- debugserver_vfp_v23,
- debugserver_vfp_v24,
- debugserver_vfp_v25,
- debugserver_vfp_v26,
- debugserver_vfp_v27,
- debugserver_vfp_v28,
- debugserver_vfp_v29,
- debugserver_vfp_v30,
- debugserver_vfp_v31,
- debugserver_vfp_fpsr,
- debugserver_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, debugserver_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, debugserver_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, "arg7", GENERIC_REGNUM_ARG7),
- DEFINE_GPR_IDX(7, x7, "arg8", GENERIC_REGNUM_ARG8),
- 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 specified 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,
- debugserver_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__) || defined(__aarch64__)
-#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, debugserver_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(uint32_t &set, uint32_t &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(uint32_t set, uint32_t 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__) || defined(__aarch64__)
- 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__) || defined(__aarch64__)
- 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__) || defined(__aarch64__)
- 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__) || defined(__aarch64__)
- 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__) || defined(__aarch64__)
- 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(uint32_t set, uint32_t 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__) || defined(__aarch64__)
- 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__) || defined(__aarch64__)
- 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__) || defined(__aarch64__)
- 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__) || defined(__aarch64__)
- 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__) || defined(__aarch64__)
- 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;
- UNUSED_IF_ASSERT_DISABLED(bytes_written);
- 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;
- UNUSED_IF_ASSERT_DISABLED(bytes_written);
- 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__) || defined (__arm64__) || defined (__aarch64__)
diff --git a/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.h b/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.h
deleted file mode 100644
index cde0abf42d53..000000000000
--- a/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.h
+++ /dev/null
@@ -1,249 +0,0 @@
-//===-- 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__) || defined(__aarch64__)
-
-#include <mach/thread_status.h>
-#include <map>
-
-#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(uint32_t set, uint32_t reg,
- DNBRegisterValue *value);
- virtual bool SetRegisterValue(uint32_t set, uint32_t 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 *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(uint32_t &set, uint32_t &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__
diff --git a/tools/debugserver/source/MacOSX/dbgnub-mig.defs b/tools/debugserver/source/MacOSX/dbgnub-mig.defs
deleted file mode 100644
index cd5be1700704..000000000000
--- a/tools/debugserver/source/MacOSX/dbgnub-mig.defs
+++ /dev/null
@@ -1,5 +0,0 @@
-/*
- * nub.defs
- */
-
-#import <mach/mach_exc.defs>
diff --git a/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp b/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp
deleted file mode 100644
index ba37a328ecf3..000000000000
--- a/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp
+++ /dev/null
@@ -1,2387 +0,0 @@
-//===-- DNBArchImplI386.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(__i386__) || defined(__x86_64__)
-
-#include <sys/cdefs.h>
-
-#include "DNBLog.h"
-#include "MacOSX/i386/DNBArchImplI386.h"
-#include "MachProcess.h"
-#include "MachThread.h"
-
-extern "C" bool CPUHasAVX(); // Defined over in DNBArchImplX86_64.cpp
-extern "C" bool CPUHasAVX512f(); // Defined over in DNBArchImplX86_64.cpp
-#if defined(LLDB_DEBUGSERVER_RELEASE) || defined(LLDB_DEBUGSERVER_DEBUG)
-enum debugState { debugStateUnknown, debugStateOff, debugStateOn };
-
-static debugState sFPUDebugState = debugStateUnknown;
-static debugState sAVXForceState = debugStateUnknown;
-
-static bool DebugFPURegs() {
- if (sFPUDebugState == debugStateUnknown) {
- if (getenv("DNB_DEBUG_FPU_REGS"))
- sFPUDebugState = debugStateOn;
- else
- sFPUDebugState = debugStateOff;
- }
-
- return (sFPUDebugState == debugStateOn);
-}
-
-static bool ForceAVXRegs() {
- if (sFPUDebugState == debugStateUnknown) {
- if (getenv("DNB_DEBUG_X86_FORCE_AVX_REGS"))
- sAVXForceState = debugStateOn;
- else
- sAVXForceState = debugStateOff;
- }
-
- return (sAVXForceState == debugStateOn);
-}
-
-#define DEBUG_FPU_REGS (DebugFPURegs())
-#define FORCE_AVX_REGS (ForceAVXRegs())
-#else
-#define DEBUG_FPU_REGS (0)
-#define FORCE_AVX_REGS (0)
-#endif
-
-enum {
- gpr_eax = 0,
- gpr_ebx = 1,
- gpr_ecx = 2,
- gpr_edx = 3,
- gpr_edi = 4,
- gpr_esi = 5,
- gpr_ebp = 6,
- gpr_esp = 7,
- gpr_ss = 8,
- gpr_eflags = 9,
- gpr_eip = 10,
- gpr_cs = 11,
- gpr_ds = 12,
- gpr_es = 13,
- gpr_fs = 14,
- gpr_gs = 15,
- gpr_ax,
- gpr_bx,
- gpr_cx,
- gpr_dx,
- gpr_di,
- gpr_si,
- gpr_bp,
- gpr_sp,
- gpr_ah,
- gpr_bh,
- gpr_ch,
- gpr_dh,
- gpr_al,
- gpr_bl,
- gpr_cl,
- gpr_dl,
- gpr_dil,
- gpr_sil,
- gpr_bpl,
- gpr_spl,
- k_num_gpr_regs
-};
-
-enum {
- fpu_fcw,
- fpu_fsw,
- fpu_ftw,
- fpu_fop,
- fpu_ip,
- fpu_cs,
- fpu_dp,
- fpu_ds,
- fpu_mxcsr,
- fpu_mxcsrmask,
- fpu_stmm0,
- fpu_stmm1,
- fpu_stmm2,
- fpu_stmm3,
- fpu_stmm4,
- fpu_stmm5,
- fpu_stmm6,
- fpu_stmm7,
- fpu_xmm0,
- fpu_xmm1,
- fpu_xmm2,
- fpu_xmm3,
- fpu_xmm4,
- fpu_xmm5,
- fpu_xmm6,
- fpu_xmm7,
- fpu_ymm0,
- fpu_ymm1,
- fpu_ymm2,
- fpu_ymm3,
- fpu_ymm4,
- fpu_ymm5,
- fpu_ymm6,
- fpu_ymm7,
- fpu_k0,
- fpu_k1,
- fpu_k2,
- fpu_k3,
- fpu_k4,
- fpu_k5,
- fpu_k6,
- fpu_k7,
- fpu_zmm0,
- fpu_zmm1,
- fpu_zmm2,
- fpu_zmm3,
- fpu_zmm4,
- fpu_zmm5,
- fpu_zmm6,
- fpu_zmm7,
- k_num_fpu_regs,
-
- // Aliases
- fpu_fctrl = fpu_fcw,
- fpu_fstat = fpu_fsw,
- fpu_ftag = fpu_ftw,
- fpu_fiseg = fpu_cs,
- fpu_fioff = fpu_ip,
- fpu_foseg = fpu_ds,
- fpu_fooff = fpu_dp
-};
-
-enum {
- exc_trapno,
- exc_err,
- exc_faultvaddr,
- k_num_exc_regs,
-};
-
-enum {
- ehframe_eax = 0,
- ehframe_ecx,
- ehframe_edx,
- ehframe_ebx,
-
- // On i386 Darwin the eh_frame register numbers for ebp and esp are reversed
- // from DWARF.
- // It's due to an ancient compiler bug in the output of the eh_frame.
- // Specifically, on i386 darwin eh_frame, 4 is ebp, 5 is esp.
- // On i386 darwin debug_frame (and debug_info), 4 is esp, 5 is ebp.
- ehframe_ebp,
- ehframe_esp,
- ehframe_esi,
- ehframe_edi,
- ehframe_eip,
- ehframe_eflags
-};
-
-enum {
- dwarf_eax = 0,
- dwarf_ecx,
- dwarf_edx,
- dwarf_ebx,
- dwarf_esp,
- dwarf_ebp,
- dwarf_esi,
- dwarf_edi,
- dwarf_eip,
- dwarf_eflags,
- dwarf_stmm0 = 11,
- dwarf_stmm1,
- dwarf_stmm2,
- dwarf_stmm3,
- dwarf_stmm4,
- dwarf_stmm5,
- dwarf_stmm6,
- dwarf_stmm7,
- dwarf_xmm0 = 21,
- dwarf_xmm1,
- dwarf_xmm2,
- dwarf_xmm3,
- dwarf_xmm4,
- dwarf_xmm5,
- dwarf_xmm6,
- dwarf_xmm7,
- dwarf_ymm0 = dwarf_xmm0,
- dwarf_ymm1 = dwarf_xmm1,
- dwarf_ymm2 = dwarf_xmm2,
- dwarf_ymm3 = dwarf_xmm3,
- dwarf_ymm4 = dwarf_xmm4,
- dwarf_ymm5 = dwarf_xmm5,
- dwarf_ymm6 = dwarf_xmm6,
- dwarf_ymm7 = dwarf_xmm7,
- dwarf_zmm0 = dwarf_xmm0,
- dwarf_zmm1 = dwarf_xmm1,
- dwarf_zmm2 = dwarf_xmm2,
- dwarf_zmm3 = dwarf_xmm3,
- dwarf_zmm4 = dwarf_xmm4,
- dwarf_zmm5 = dwarf_xmm5,
- dwarf_zmm6 = dwarf_xmm6,
- dwarf_zmm7 = dwarf_xmm7,
- dwarf_k0 = 118,
- dwarf_k1,
- dwarf_k2,
- dwarf_k3,
- dwarf_k4,
- dwarf_k5,
- dwarf_k6,
- dwarf_k7,
-};
-
-enum {
- debugserver_eax = 0,
- debugserver_ecx = 1,
- debugserver_edx = 2,
- debugserver_ebx = 3,
- debugserver_esp = 4,
- debugserver_ebp = 5,
- debugserver_esi = 6,
- debugserver_edi = 7,
- debugserver_eip = 8,
- debugserver_eflags = 9,
- debugserver_cs = 10,
- debugserver_ss = 11,
- debugserver_ds = 12,
- debugserver_es = 13,
- debugserver_fs = 14,
- debugserver_gs = 15,
- debugserver_stmm0 = 16,
- debugserver_stmm1 = 17,
- debugserver_stmm2 = 18,
- debugserver_stmm3 = 19,
- debugserver_stmm4 = 20,
- debugserver_stmm5 = 21,
- debugserver_stmm6 = 22,
- debugserver_stmm7 = 23,
- debugserver_fctrl = 24,
- debugserver_fcw = debugserver_fctrl,
- debugserver_fstat = 25,
- debugserver_fsw = debugserver_fstat,
- debugserver_ftag = 26,
- debugserver_ftw = debugserver_ftag,
- debugserver_fiseg = 27,
- debugserver_fpu_cs = debugserver_fiseg,
- debugserver_fioff = 28,
- debugserver_ip = debugserver_fioff,
- debugserver_foseg = 29,
- debugserver_fpu_ds = debugserver_foseg,
- debugserver_fooff = 30,
- debugserver_dp = debugserver_fooff,
- debugserver_fop = 31,
- debugserver_xmm0 = 32,
- debugserver_xmm1 = 33,
- debugserver_xmm2 = 34,
- debugserver_xmm3 = 35,
- debugserver_xmm4 = 36,
- debugserver_xmm5 = 37,
- debugserver_xmm6 = 38,
- debugserver_xmm7 = 39,
- debugserver_mxcsr = 40,
- debugserver_mm0 = 41,
- debugserver_mm1 = 42,
- debugserver_mm2 = 43,
- debugserver_mm3 = 44,
- debugserver_mm4 = 45,
- debugserver_mm5 = 46,
- debugserver_mm6 = 47,
- debugserver_mm7 = 48,
- debugserver_ymm0 = debugserver_xmm0,
- debugserver_ymm1 = debugserver_xmm1,
- debugserver_ymm2 = debugserver_xmm2,
- debugserver_ymm3 = debugserver_xmm3,
- debugserver_ymm4 = debugserver_xmm4,
- debugserver_ymm5 = debugserver_xmm5,
- debugserver_ymm6 = debugserver_xmm6,
- debugserver_ymm7 = debugserver_xmm7,
- debugserver_zmm0 = debugserver_xmm0,
- debugserver_zmm1 = debugserver_xmm1,
- debugserver_zmm2 = debugserver_xmm2,
- debugserver_zmm3 = debugserver_xmm3,
- debugserver_zmm4 = debugserver_xmm4,
- debugserver_zmm5 = debugserver_xmm5,
- debugserver_zmm6 = debugserver_xmm6,
- debugserver_zmm7 = debugserver_xmm7,
- debugserver_k0 = 118,
- debugserver_k1 = 119,
- debugserver_k2 = 120,
- debugserver_k3 = 121,
- debugserver_k4 = 122,
- debugserver_k5 = 123,
- debugserver_k6 = 124,
- debugserver_k7 = 125,
-};
-
-uint64_t DNBArchImplI386::GetPC(uint64_t failValue) {
- // Get program counter
- if (GetGPRState(false) == KERN_SUCCESS)
- return m_state.context.gpr.__eip;
- return failValue;
-}
-
-kern_return_t DNBArchImplI386::SetPC(uint64_t value) {
- // Get program counter
- kern_return_t err = GetGPRState(false);
- if (err == KERN_SUCCESS) {
- m_state.context.gpr.__eip = static_cast<uint32_t>(value);
- err = SetGPRState();
- }
- return err == KERN_SUCCESS;
-}
-
-uint64_t DNBArchImplI386::GetSP(uint64_t failValue) {
- // Get stack pointer
- if (GetGPRState(false) == KERN_SUCCESS)
- return m_state.context.gpr.__esp;
- return failValue;
-}
-
-// Uncomment the value below to verify the values in the debugger.
-//#define DEBUG_GPR_VALUES 1 // DO NOT CHECK IN WITH THIS DEFINE ENABLED
-//#define SET_GPR(reg) m_state.context.gpr.__##reg = gpr_##reg
-
-kern_return_t DNBArchImplI386::GetGPRState(bool force) {
- if (force || m_state.GetError(e_regSetGPR, Read)) {
-#if DEBUG_GPR_VALUES
- SET_GPR(eax);
- SET_GPR(ebx);
- SET_GPR(ecx);
- SET_GPR(edx);
- SET_GPR(edi);
- SET_GPR(esi);
- SET_GPR(ebp);
- SET_GPR(esp);
- SET_GPR(ss);
- SET_GPR(eflags);
- SET_GPR(eip);
- SET_GPR(cs);
- SET_GPR(ds);
- SET_GPR(es);
- SET_GPR(fs);
- SET_GPR(gs);
- m_state.SetError(e_regSetGPR, Read, 0);
-#else
- mach_msg_type_number_t count = e_regSetWordSizeGPR;
- m_state.SetError(
- e_regSetGPR, Read,
- ::thread_get_state(m_thread->MachPortNumber(), __i386_THREAD_STATE,
- (thread_state_t)&m_state.context.gpr, &count));
-#endif
- }
- return m_state.GetError(e_regSetGPR, Read);
-}
-
-// Uncomment the value below to verify the values in the debugger.
-//#define DEBUG_FPU_VALUES 1 // DO NOT CHECK IN WITH THIS DEFINE ENABLED
-
-kern_return_t DNBArchImplI386::GetFPUState(bool force) {
- if (force || m_state.GetError(e_regSetFPU, Read)) {
- if (DEBUG_FPU_REGS) {
-
- m_state.context.fpu.no_avx.__fpu_reserved[0] = -1;
- m_state.context.fpu.no_avx.__fpu_reserved[1] = -1;
- *(uint16_t *)&(m_state.context.fpu.no_avx.__fpu_fcw) = 0x1234;
- *(uint16_t *)&(m_state.context.fpu.no_avx.__fpu_fsw) = 0x5678;
- m_state.context.fpu.no_avx.__fpu_ftw = 1;
- m_state.context.fpu.no_avx.__fpu_rsrv1 = UINT8_MAX;
- m_state.context.fpu.no_avx.__fpu_fop = 2;
- m_state.context.fpu.no_avx.__fpu_ip = 3;
- m_state.context.fpu.no_avx.__fpu_cs = 4;
- m_state.context.fpu.no_avx.__fpu_rsrv2 = 5;
- m_state.context.fpu.no_avx.__fpu_dp = 6;
- m_state.context.fpu.no_avx.__fpu_ds = 7;
- m_state.context.fpu.no_avx.__fpu_rsrv3 = UINT16_MAX;
- m_state.context.fpu.no_avx.__fpu_mxcsr = 8;
- m_state.context.fpu.no_avx.__fpu_mxcsrmask = 9;
- for (int i = 0; i < 16; ++i) {
- if (i < 10) {
- m_state.context.fpu.no_avx.__fpu_stmm0.__mmst_reg[i] = 'a';
- m_state.context.fpu.no_avx.__fpu_stmm1.__mmst_reg[i] = 'b';
- m_state.context.fpu.no_avx.__fpu_stmm2.__mmst_reg[i] = 'c';
- m_state.context.fpu.no_avx.__fpu_stmm3.__mmst_reg[i] = 'd';
- m_state.context.fpu.no_avx.__fpu_stmm4.__mmst_reg[i] = 'e';
- m_state.context.fpu.no_avx.__fpu_stmm5.__mmst_reg[i] = 'f';
- m_state.context.fpu.no_avx.__fpu_stmm6.__mmst_reg[i] = 'g';
- m_state.context.fpu.no_avx.__fpu_stmm7.__mmst_reg[i] = 'h';
- } else {
- m_state.context.fpu.no_avx.__fpu_stmm0.__mmst_reg[i] = INT8_MIN;
- m_state.context.fpu.no_avx.__fpu_stmm1.__mmst_reg[i] = INT8_MIN;
- m_state.context.fpu.no_avx.__fpu_stmm2.__mmst_reg[i] = INT8_MIN;
- m_state.context.fpu.no_avx.__fpu_stmm3.__mmst_reg[i] = INT8_MIN;
- m_state.context.fpu.no_avx.__fpu_stmm4.__mmst_reg[i] = INT8_MIN;
- m_state.context.fpu.no_avx.__fpu_stmm5.__mmst_reg[i] = INT8_MIN;
- m_state.context.fpu.no_avx.__fpu_stmm6.__mmst_reg[i] = INT8_MIN;
- m_state.context.fpu.no_avx.__fpu_stmm7.__mmst_reg[i] = INT8_MIN;
- }
-
- m_state.context.fpu.no_avx.__fpu_xmm0.__xmm_reg[i] = '0';
- m_state.context.fpu.no_avx.__fpu_xmm1.__xmm_reg[i] = '1';
- m_state.context.fpu.no_avx.__fpu_xmm2.__xmm_reg[i] = '2';
- m_state.context.fpu.no_avx.__fpu_xmm3.__xmm_reg[i] = '3';
- m_state.context.fpu.no_avx.__fpu_xmm4.__xmm_reg[i] = '4';
- m_state.context.fpu.no_avx.__fpu_xmm5.__xmm_reg[i] = '5';
- m_state.context.fpu.no_avx.__fpu_xmm6.__xmm_reg[i] = '6';
- m_state.context.fpu.no_avx.__fpu_xmm7.__xmm_reg[i] = '7';
- }
- for (int i = 0; i < sizeof(m_state.context.fpu.no_avx.__fpu_rsrv4); ++i)
- m_state.context.fpu.no_avx.__fpu_rsrv4[i] = INT8_MIN;
- m_state.context.fpu.no_avx.__fpu_reserved1 = -1;
-
- if (CPUHasAVX() || FORCE_AVX_REGS) {
- for (int i = 0; i < sizeof(m_state.context.fpu.avx.__avx_reserved1);
- ++i)
- m_state.context.fpu.avx.__avx_reserved1[i] = INT8_MIN;
-
- for (int i = 0; i < 16; ++i) {
- m_state.context.fpu.avx.__fpu_ymmh0.__xmm_reg[i] = '0';
- m_state.context.fpu.avx.__fpu_ymmh1.__xmm_reg[i] = '1';
- m_state.context.fpu.avx.__fpu_ymmh2.__xmm_reg[i] = '2';
- m_state.context.fpu.avx.__fpu_ymmh3.__xmm_reg[i] = '3';
- m_state.context.fpu.avx.__fpu_ymmh4.__xmm_reg[i] = '4';
- m_state.context.fpu.avx.__fpu_ymmh5.__xmm_reg[i] = '5';
- m_state.context.fpu.avx.__fpu_ymmh6.__xmm_reg[i] = '6';
- m_state.context.fpu.avx.__fpu_ymmh7.__xmm_reg[i] = '7';
- }
- }
- if (CPUHasAVX512f() || FORCE_AVX_REGS) {
- for (int i = 0; i < 8; ++i) {
- m_state.context.fpu.avx512f.__fpu_k0.__opmask_reg[i] = '0';
- m_state.context.fpu.avx512f.__fpu_k1.__opmask_reg[i] = '1';
- m_state.context.fpu.avx512f.__fpu_k2.__opmask_reg[i] = '2';
- m_state.context.fpu.avx512f.__fpu_k3.__opmask_reg[i] = '3';
- m_state.context.fpu.avx512f.__fpu_k4.__opmask_reg[i] = '4';
- m_state.context.fpu.avx512f.__fpu_k5.__opmask_reg[i] = '5';
- m_state.context.fpu.avx512f.__fpu_k6.__opmask_reg[i] = '6';
- m_state.context.fpu.avx512f.__fpu_k7.__opmask_reg[i] = '7';
- }
-
- for (int i = 0; i < 32; ++i) {
- m_state.context.fpu.avx512f.__fpu_zmmh0.__ymm_reg[i] = '0';
- m_state.context.fpu.avx512f.__fpu_zmmh1.__ymm_reg[i] = '1';
- m_state.context.fpu.avx512f.__fpu_zmmh2.__ymm_reg[i] = '2';
- m_state.context.fpu.avx512f.__fpu_zmmh3.__ymm_reg[i] = '3';
- m_state.context.fpu.avx512f.__fpu_zmmh4.__ymm_reg[i] = '4';
- m_state.context.fpu.avx512f.__fpu_zmmh5.__ymm_reg[i] = '5';
- m_state.context.fpu.avx512f.__fpu_zmmh6.__ymm_reg[i] = '6';
- m_state.context.fpu.avx512f.__fpu_zmmh7.__ymm_reg[i] = '7';
- }
- }
- m_state.SetError(e_regSetFPU, Read, 0);
- } else {
- mach_msg_type_number_t count = e_regSetWordSizeFPU;
- int flavor = __i386_FLOAT_STATE;
-
- // On a machine with the AVX512 register set, a process only gets a
- // full AVX512 register context after it uses the AVX512 registers;
- // if the process has not yet triggered this change, trying to fetch
- // the AVX512 registers will fail. Fall through to fetching the AVX
- // registers.
- if (CPUHasAVX512f() || FORCE_AVX_REGS) {
- count = e_regSetWordSizeAVX512f;
- flavor = __i386_AVX512F_STATE;
- m_state.SetError(e_regSetFPU, Read,
- ::thread_get_state(m_thread->MachPortNumber(), flavor,
- (thread_state_t)&m_state.context.fpu,
- &count));
- DNBLogThreadedIf(LOG_THREAD,
- "::thread_get_state (0x%4.4x, %u, &fpu, %u => 0x%8.8x",
- m_thread->MachPortNumber(), flavor, (uint32_t)count,
- m_state.GetError(e_regSetFPU, Read));
- if (m_state.GetError(e_regSetFPU, Read) == KERN_SUCCESS)
- return m_state.GetError(e_regSetFPU, Read);
- }
- if (CPUHasAVX()) {
- count = e_regSetWordSizeAVX;
- flavor = __i386_AVX_STATE;
- }
- m_state.SetError(e_regSetFPU, Read,
- ::thread_get_state(m_thread->MachPortNumber(), flavor,
- (thread_state_t)&m_state.context.fpu,
- &count));
- DNBLogThreadedIf(LOG_THREAD,
- "::thread_get_state (0x%4.4x, %u, &fpu, %u => 0x%8.8x",
- m_thread->MachPortNumber(), flavor, (uint32_t)count,
- m_state.GetError(e_regSetFPU, Read));
- }
- }
- return m_state.GetError(e_regSetFPU, Read);
-}
-
-kern_return_t DNBArchImplI386::GetEXCState(bool force) {
- if (force || m_state.GetError(e_regSetEXC, Read)) {
- mach_msg_type_number_t count = e_regSetWordSizeEXC;
- m_state.SetError(
- e_regSetEXC, Read,
- ::thread_get_state(m_thread->MachPortNumber(), __i386_EXCEPTION_STATE,
- (thread_state_t)&m_state.context.exc, &count));
- }
- return m_state.GetError(e_regSetEXC, Read);
-}
-
-kern_return_t DNBArchImplI386::SetGPRState() {
- 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());
-
- m_state.SetError(e_regSetGPR, Write,
- ::thread_set_state(m_thread->MachPortNumber(),
- __i386_THREAD_STATE,
- (thread_state_t)&m_state.context.gpr,
- e_regSetWordSizeGPR));
- return m_state.GetError(e_regSetGPR, Write);
-}
-
-kern_return_t DNBArchImplI386::SetFPUState() {
- if (DEBUG_FPU_REGS) {
- m_state.SetError(e_regSetFPU, Write, 0);
- return m_state.GetError(e_regSetFPU, Write);
- } else {
- int flavor = __i386_FLOAT_STATE;
- mach_msg_type_number_t count = e_regSetWordSizeFPU;
- if (CPUHasAVX512f() || FORCE_AVX_REGS) {
- flavor = __i386_AVX512F_STATE;
- count = e_regSetWordSizeAVX512f;
- } else
- if (CPUHasAVX()) {
- flavor = __i386_AVX_STATE;
- count = e_regSetWordSizeAVX;
- }
-
- m_state.SetError(e_regSetFPU, Write,
- ::thread_set_state(m_thread->MachPortNumber(), flavor,
- (thread_state_t)&m_state.context.fpu,
- count));
- return m_state.GetError(e_regSetFPU, Write);
- }
-}
-
-kern_return_t DNBArchImplI386::SetEXCState() {
- m_state.SetError(e_regSetEXC, Write,
- ::thread_set_state(m_thread->MachPortNumber(),
- __i386_EXCEPTION_STATE,
- (thread_state_t)&m_state.context.exc,
- e_regSetWordSizeEXC));
- return m_state.GetError(e_regSetEXC, Write);
-}
-
-kern_return_t DNBArchImplI386::GetDBGState(bool force) {
- if (force || m_state.GetError(e_regSetDBG, Read)) {
- mach_msg_type_number_t count = e_regSetWordSizeDBG;
- m_state.SetError(
- e_regSetDBG, Read,
- ::thread_get_state(m_thread->MachPortNumber(), __i386_DEBUG_STATE,
- (thread_state_t)&m_state.context.dbg, &count));
- }
- return m_state.GetError(e_regSetDBG, Read);
-}
-
-kern_return_t DNBArchImplI386::SetDBGState(bool also_set_on_task) {
- m_state.SetError(e_regSetDBG, Write,
- ::thread_set_state(m_thread->MachPortNumber(),
- __i386_DEBUG_STATE,
- (thread_state_t)&m_state.context.dbg,
- e_regSetWordSizeDBG));
- if (also_set_on_task) {
- kern_return_t kret = ::task_set_state(
- m_thread->Process()->Task().TaskPort(), __i386_DEBUG_STATE,
- (thread_state_t)&m_state.context.dbg, e_regSetWordSizeDBG);
- if (kret != KERN_SUCCESS)
- DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplI386::SetDBGState failed "
- "to set debug control register state: "
- "0x%8.8x.",
- kret);
- }
- return m_state.GetError(e_regSetDBG, Write);
-}
-
-void DNBArchImplI386::ThreadWillResume() {
- // Do we need to step this thread? If so, let the mach thread tell us so.
- if (m_thread->IsStepping()) {
- // This is the primary thread, let the arch do anything it needs
- EnableHardwareSingleStep(true);
- }
-
- // Reset the debug status register, if necessary, before we resume.
- kern_return_t kret = GetDBGState(false);
- DNBLogThreadedIf(
- LOG_WATCHPOINTS,
- "DNBArchImplI386::ThreadWillResume() GetDBGState() => 0x%8.8x.", kret);
- if (kret != KERN_SUCCESS)
- return;
-
- DBG &debug_state = m_state.context.dbg;
- bool need_reset = false;
- uint32_t i, num = NumSupportedHardwareWatchpoints();
- for (i = 0; i < num; ++i)
- if (IsWatchpointHit(debug_state, i))
- need_reset = true;
-
- if (need_reset) {
- ClearWatchpointHits(debug_state);
- kret = SetDBGState(false);
- DNBLogThreadedIf(
- LOG_WATCHPOINTS,
- "DNBArchImplI386::ThreadWillResume() SetDBGState() => 0x%8.8x.", kret);
- }
-}
-
-bool DNBArchImplI386::ThreadDidStop() {
- bool success = true;
-
- m_state.InvalidateAllRegisterStates();
-
- // 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;
-}
-
-bool DNBArchImplI386::NotifyException(MachException::Data &exc) {
- switch (exc.exc_type) {
- case EXC_BAD_ACCESS:
- break;
- case EXC_BAD_INSTRUCTION:
- break;
- case EXC_ARITHMETIC:
- break;
- case EXC_EMULATION:
- break;
- case EXC_SOFTWARE:
- break;
- case EXC_BREAKPOINT:
- if (exc.exc_data.size() >= 2 && exc.exc_data[0] == 2) {
- // exc_code = EXC_I386_BPT
- //
- nub_addr_t pc = GetPC(INVALID_NUB_ADDRESS);
- if (pc != INVALID_NUB_ADDRESS && pc > 0) {
- pc -= 1;
- // Check for a breakpoint at one byte prior to the current PC value
- // since the PC will be just past the trap.
-
- DNBBreakpoint *bp =
- m_thread->Process()->Breakpoints().FindByAddress(pc);
- if (bp) {
- // Backup the PC for i386 since the trap was taken and the PC
- // is at the address following the single byte trap instruction.
- if (m_state.context.gpr.__eip > 0) {
- m_state.context.gpr.__eip = static_cast<uint32_t>(pc);
- // Write the new PC back out
- SetGPRState();
- }
- }
- return true;
- }
- } else if (exc.exc_data.size() >= 2 && exc.exc_data[0] == 1) {
- // exc_code = EXC_I386_SGL
- //
- // Check whether this corresponds to a watchpoint hit event.
- // If yes, set the exc_sub_code to the data break address.
- nub_addr_t addr = 0;
- uint32_t hw_index = GetHardwareWatchpointHit(addr);
- if (hw_index != INVALID_NUB_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;
- case EXC_SYSCALL:
- break;
- case EXC_MACH_SYSCALL:
- break;
- case EXC_RPC_ALERT:
- break;
- }
- return false;
-}
-
-uint32_t DNBArchImplI386::NumSupportedHardwareWatchpoints() {
- // Available debug address registers: dr0, dr1, dr2, dr3.
- return 4;
-}
-
-static uint32_t size_and_rw_bits(nub_size_t size, bool read, bool write) {
- uint32_t rw;
- if (read) {
- rw = 0x3; // READ or READ/WRITE
- } else if (write) {
- rw = 0x1; // WRITE
- } else {
- assert(0 && "read and write cannot both be false");
- }
-
- switch (size) {
- case 1:
- return rw;
- case 2:
- return (0x1 << 2) | rw;
- case 4:
- return (0x3 << 2) | rw;
- case 8:
- return (0x2 << 2) | rw;
- }
- assert(0 && "invalid size, must be one of 1, 2, 4, or 8");
- return 0;
-}
-
-void DNBArchImplI386::SetWatchpoint(DBG &debug_state, uint32_t hw_index,
- nub_addr_t addr, nub_size_t size, bool read,
- bool write) {
- // Set both dr7 (debug control register) and dri (debug address register).
-
- // dr7{7-0} encodes the local/gloabl enable bits:
- // global enable --. .-- local enable
- // | |
- // v v
- // dr0 -> bits{1-0}
- // dr1 -> bits{3-2}
- // dr2 -> bits{5-4}
- // dr3 -> bits{7-6}
- //
- // dr7{31-16} encodes the rw/len bits:
- // b_x+3, b_x+2, b_x+1, b_x
- // where bits{x+1, x} => rw
- // 0b00: execute, 0b01: write, 0b11: read-or-write, 0b10: io
- // read-or-write (unused)
- // and bits{x+3, x+2} => len
- // 0b00: 1-byte, 0b01: 2-byte, 0b11: 4-byte, 0b10: 8-byte
- //
- // dr0 -> bits{19-16}
- // dr1 -> bits{23-20}
- // dr2 -> bits{27-24}
- // dr3 -> bits{31-28}
- debug_state.__dr7 |=
- (1 << (2 * hw_index) |
- size_and_rw_bits(size, read, write) << (16 + 4 * hw_index));
- uint32_t addr_32 = addr & 0xffffffff;
- switch (hw_index) {
- case 0:
- debug_state.__dr0 = addr_32;
- break;
- case 1:
- debug_state.__dr1 = addr_32;
- break;
- case 2:
- debug_state.__dr2 = addr_32;
- break;
- case 3:
- debug_state.__dr3 = addr_32;
- break;
- default:
- assert(0 &&
- "invalid hardware register index, must be one of 0, 1, 2, or 3");
- }
- return;
-}
-
-void DNBArchImplI386::ClearWatchpoint(DBG &debug_state, uint32_t hw_index) {
- debug_state.__dr7 &= ~(3 << (2 * hw_index));
- switch (hw_index) {
- case 0:
- debug_state.__dr0 = 0;
- break;
- case 1:
- debug_state.__dr1 = 0;
- break;
- case 2:
- debug_state.__dr2 = 0;
- break;
- case 3:
- debug_state.__dr3 = 0;
- break;
- default:
- assert(0 &&
- "invalid hardware register index, must be one of 0, 1, 2, or 3");
- }
- return;
-}
-
-bool DNBArchImplI386::IsWatchpointVacant(const DBG &debug_state,
- uint32_t hw_index) {
- // Check dr7 (debug control register) for local/global enable bits:
- // global enable --. .-- local enable
- // | |
- // v v
- // dr0 -> bits{1-0}
- // dr1 -> bits{3-2}
- // dr2 -> bits{5-4}
- // dr3 -> bits{7-6}
- return (debug_state.__dr7 & (3 << (2 * hw_index))) == 0;
-}
-
-// Resets local copy of debug status register to wait for the next debug
-// exception.
-void DNBArchImplI386::ClearWatchpointHits(DBG &debug_state) {
- // See also IsWatchpointHit().
- debug_state.__dr6 = 0;
- return;
-}
-
-bool DNBArchImplI386::IsWatchpointHit(const DBG &debug_state,
- uint32_t hw_index) {
- // Check dr6 (debug status register) whether a watchpoint hits:
- // is watchpoint hit?
- // |
- // v
- // dr0 -> bits{0}
- // dr1 -> bits{1}
- // dr2 -> bits{2}
- // dr3 -> bits{3}
- return (debug_state.__dr6 & (1 << hw_index));
-}
-
-nub_addr_t DNBArchImplI386::GetWatchAddress(const DBG &debug_state,
- uint32_t hw_index) {
- switch (hw_index) {
- case 0:
- return debug_state.__dr0;
- case 1:
- return debug_state.__dr1;
- case 2:
- return debug_state.__dr2;
- case 3:
- return debug_state.__dr3;
- }
- assert(0 && "invalid hardware register index, must be one of 0, 1, 2, or 3");
- return 0;
-}
-
-bool DNBArchImplI386::StartTransForHWP() {
- if (m_2pc_trans_state != Trans_Done && m_2pc_trans_state != Trans_Rolled_Back)
- DNBLogError("%s inconsistent state detected, expected %d or %d, got: %d",
- __FUNCTION__, Trans_Done, Trans_Rolled_Back, m_2pc_trans_state);
- m_2pc_dbg_checkpoint = m_state.context.dbg;
- m_2pc_trans_state = Trans_Pending;
- return true;
-}
-bool DNBArchImplI386::RollbackTransForHWP() {
- m_state.context.dbg = m_2pc_dbg_checkpoint;
- if (m_2pc_trans_state != Trans_Pending)
- DNBLogError("%s inconsistent state detected, expected %d, got: %d",
- __FUNCTION__, Trans_Pending, m_2pc_trans_state);
- m_2pc_trans_state = Trans_Rolled_Back;
- kern_return_t kret = SetDBGState(false);
- DNBLogThreadedIf(
- LOG_WATCHPOINTS,
- "DNBArchImplI386::RollbackTransForHWP() SetDBGState() => 0x%8.8x.", kret);
-
- return kret == KERN_SUCCESS;
-}
-bool DNBArchImplI386::FinishTransForHWP() {
- m_2pc_trans_state = Trans_Done;
- return true;
-}
-DNBArchImplI386::DBG DNBArchImplI386::GetDBGCheckpoint() {
- return m_2pc_dbg_checkpoint;
-}
-
-uint32_t DNBArchImplI386::EnableHardwareWatchpoint(nub_addr_t addr,
- nub_size_t size, bool read,
- bool write,
- bool also_set_on_task) {
- DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplI386::EnableHardwareWatchpoint("
- "addr = 0x%llx, size = %llu, read = %u, "
- "write = %u)",
- (uint64_t)addr, (uint64_t)size, read, write);
-
- const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
-
- // Can only watch 1, 2, 4, or 8 bytes.
- if (!(size == 1 || size == 2 || size == 4 || size == 8))
- return INVALID_NUB_HW_INDEX;
-
- // We must watch for either read or write
- if (!read && !write)
- return INVALID_NUB_HW_INDEX;
-
- // 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;
-
- DBG &debug_state = m_state.context.dbg;
- for (i = 0; i < num_hw_watchpoints; ++i) {
- if (IsWatchpointVacant(debug_state, i))
- break;
- }
-
- // See if we found an available hw breakpoint slot above
- if (i < num_hw_watchpoints) {
- StartTransForHWP();
-
- // Modify our local copy of the debug state, first.
- SetWatchpoint(debug_state, i, addr, size, read, write);
- // Now set the watch point in the inferior.
- kret = SetDBGState(also_set_on_task);
- DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplI386::"
- "EnableHardwareWatchpoint() "
- "SetDBGState() => 0x%8.8x.",
- kret);
-
- if (kret == KERN_SUCCESS)
- return i;
- else // Revert to the previous debug state voluntarily. The transaction
- // coordinator knows that we have failed.
- m_state.context.dbg = GetDBGCheckpoint();
- } else {
- DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplI386::"
- "EnableHardwareWatchpoint(): All "
- "hardware resources (%u) are in use.",
- num_hw_watchpoints);
- }
- }
- return INVALID_NUB_HW_INDEX;
-}
-
-bool DNBArchImplI386::DisableHardwareWatchpoint(uint32_t hw_index,
- bool also_set_on_task) {
- kern_return_t kret = GetDBGState(false);
-
- const uint32_t num_hw_points = NumSupportedHardwareWatchpoints();
- if (kret == KERN_SUCCESS) {
- DBG &debug_state = m_state.context.dbg;
- if (hw_index < num_hw_points &&
- !IsWatchpointVacant(debug_state, hw_index)) {
- StartTransForHWP();
-
- // Modify our local copy of the debug state, first.
- ClearWatchpoint(debug_state, hw_index);
- // Now disable the watch point in the inferior.
- kret = SetDBGState(also_set_on_task);
- DNBLogThreadedIf(LOG_WATCHPOINTS,
- "DNBArchImplI386::DisableHardwareWatchpoint( %u )",
- hw_index);
-
- if (kret == KERN_SUCCESS)
- return true;
- else // Revert to the previous debug state voluntarily. The transaction
- // coordinator knows that we have failed.
- m_state.context.dbg = GetDBGCheckpoint();
- }
- }
- return false;
-}
-
-// Iterate through the debug status register; return the index of the first hit.
-uint32_t DNBArchImplI386::GetHardwareWatchpointHit(nub_addr_t &addr) {
- // Read the debug state
- kern_return_t kret = GetDBGState(true);
- DNBLogThreadedIf(
- LOG_WATCHPOINTS,
- "DNBArchImplI386::GetHardwareWatchpointHit() GetDBGState() => 0x%8.8x.",
- kret);
- if (kret == KERN_SUCCESS) {
- DBG &debug_state = m_state.context.dbg;
- uint32_t i, num = NumSupportedHardwareWatchpoints();
- for (i = 0; i < num; ++i) {
- if (IsWatchpointHit(debug_state, i)) {
- addr = GetWatchAddress(debug_state, i);
- DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplI386::"
- "GetHardwareWatchpointHit() found => "
- "%u (addr = 0x%llx).",
- i, (uint64_t)addr);
- return i;
- }
- }
- }
- return INVALID_NUB_HW_INDEX;
-}
-
-// Set the single step bit in the processor status register.
-kern_return_t DNBArchImplI386::EnableHardwareSingleStep(bool enable) {
- if (GetGPRState(false) == KERN_SUCCESS) {
- const uint32_t trace_bit = 0x100u;
- if (enable)
- m_state.context.gpr.__eflags |= trace_bit;
- else
- m_state.context.gpr.__eflags &= ~trace_bit;
- return SetGPRState();
- }
- return m_state.GetError(e_regSetGPR, Read);
-}
-
-//----------------------------------------------------------------------
-// Register information definitions
-//----------------------------------------------------------------------
-
-#define DEFINE_GPR_PSEUDO_16(reg16, reg32) \
- { \
- e_regSetGPR, gpr_##reg16, #reg16, NULL, Uint, Hex, 2, 0, \
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, \
- INVALID_NUB_REGNUM, g_contained_##reg32, g_invalidate_##reg32 \
- }
-#define DEFINE_GPR_PSEUDO_8H(reg8, reg32) \
- { \
- e_regSetGPR, gpr_##reg8, #reg8, NULL, Uint, Hex, 1, 1, INVALID_NUB_REGNUM, \
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, \
- g_contained_##reg32, g_invalidate_##reg32 \
- }
-#define DEFINE_GPR_PSEUDO_8L(reg8, reg32) \
- { \
- e_regSetGPR, gpr_##reg8, #reg8, NULL, Uint, Hex, 1, 0, INVALID_NUB_REGNUM, \
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, \
- g_contained_##reg32, g_invalidate_##reg32 \
- }
-
-#define GPR_OFFSET(reg) (offsetof(DNBArchImplI386::GPR, __##reg))
-#define FPU_OFFSET(reg) \
- (offsetof(DNBArchImplI386::FPU, __fpu_##reg) + \
- offsetof(DNBArchImplI386::Context, fpu.no_avx))
-#define AVX_OFFSET(reg) \
- (offsetof(DNBArchImplI386::AVX, __fpu_##reg) + \
- offsetof(DNBArchImplI386::Context, fpu.avx))
-#define AVX512F_OFFSET(reg) \
- (offsetof(DNBArchImplI386::AVX512F, __fpu_##reg) + \
- offsetof(DNBArchImplI386::Context, fpu.avx512f))
-#define EXC_OFFSET(reg) \
- (offsetof(DNBArchImplI386::EXC, __##reg) + \
- offsetof(DNBArchImplI386::Context, exc))
-
-#define GPR_SIZE(reg) (sizeof(((DNBArchImplI386::GPR *)NULL)->__##reg))
-#define FPU_SIZE_UINT(reg) (sizeof(((DNBArchImplI386::FPU *)NULL)->__fpu_##reg))
-#define FPU_SIZE_MMST(reg) \
- (sizeof(((DNBArchImplI386::FPU *)NULL)->__fpu_##reg.__mmst_reg))
-#define FPU_SIZE_XMM(reg) \
- (sizeof(((DNBArchImplI386::FPU *)NULL)->__fpu_##reg.__xmm_reg))
-#define FPU_SIZE_YMM(reg) (32)
-#define FPU_SIZE_ZMM(reg) (64)
-#define EXC_SIZE(reg) (sizeof(((DNBArchImplI386::EXC *)NULL)->__##reg))
-
-// This does not accurately identify the location of ymm0...7 in
-// Context.fpu.avx. That is because there is a bunch of padding
-// in Context.fpu.avx that we don't need. Offset macros lay out
-// the register state that Debugserver transmits to the debugger
-// -- not to interpret the thread_get_state info.
-#define AVX_OFFSET_YMM(n) (AVX_OFFSET(xmm7) + FPU_SIZE_XMM(xmm7) + (32 * n))
-
-// TODO: Test this and come back.
-#define AVX512F_OFFSET_ZMM(n) (AVX_OFFSET_YMM(7) + FPU_SIZE_XMM(xmm7) + (64 * n))
-
-// 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.
-
-const char *g_contained_eax[] = {"eax", NULL};
-const char *g_contained_ebx[] = {"ebx", NULL};
-const char *g_contained_ecx[] = {"ecx", NULL};
-const char *g_contained_edx[] = {"edx", NULL};
-const char *g_contained_edi[] = {"edi", NULL};
-const char *g_contained_esi[] = {"esi", NULL};
-const char *g_contained_ebp[] = {"ebp", NULL};
-const char *g_contained_esp[] = {"esp", NULL};
-
-const char *g_invalidate_eax[] = {"eax", "ax", "ah", "al", NULL};
-const char *g_invalidate_ebx[] = {"ebx", "bx", "bh", "bl", NULL};
-const char *g_invalidate_ecx[] = {"ecx", "cx", "ch", "cl", NULL};
-const char *g_invalidate_edx[] = {"edx", "dx", "dh", "dl", NULL};
-const char *g_invalidate_edi[] = {"edi", "di", "dil", NULL};
-const char *g_invalidate_esi[] = {"esi", "si", "sil", NULL};
-const char *g_invalidate_ebp[] = {"ebp", "bp", "bpl", NULL};
-const char *g_invalidate_esp[] = {"esp", "sp", "spl", NULL};
-
-// General purpose registers for 64 bit
-const DNBRegisterInfo DNBArchImplI386::g_gpr_registers[] = {
- {e_regSetGPR, gpr_eax, "eax", NULL, Uint, Hex, GPR_SIZE(eax),
- GPR_OFFSET(eax), ehframe_eax, dwarf_eax, INVALID_NUB_REGNUM,
- debugserver_eax, NULL, g_invalidate_eax},
- {e_regSetGPR, gpr_ebx, "ebx", NULL, Uint, Hex, GPR_SIZE(ebx),
- GPR_OFFSET(ebx), ehframe_ebx, dwarf_ebx, INVALID_NUB_REGNUM,
- debugserver_ebx, NULL, g_invalidate_ebx},
- {e_regSetGPR, gpr_ecx, "ecx", NULL, Uint, Hex, GPR_SIZE(ecx),
- GPR_OFFSET(ecx), ehframe_ecx, dwarf_ecx, INVALID_NUB_REGNUM,
- debugserver_ecx, NULL, g_invalidate_ecx},
- {e_regSetGPR, gpr_edx, "edx", NULL, Uint, Hex, GPR_SIZE(edx),
- GPR_OFFSET(edx), ehframe_edx, dwarf_edx, INVALID_NUB_REGNUM,
- debugserver_edx, NULL, g_invalidate_edx},
- {e_regSetGPR, gpr_edi, "edi", NULL, Uint, Hex, GPR_SIZE(edi),
- GPR_OFFSET(edi), ehframe_edi, dwarf_edi, INVALID_NUB_REGNUM,
- debugserver_edi, NULL, g_invalidate_edi},
- {e_regSetGPR, gpr_esi, "esi", NULL, Uint, Hex, GPR_SIZE(esi),
- GPR_OFFSET(esi), ehframe_esi, dwarf_esi, INVALID_NUB_REGNUM,
- debugserver_esi, NULL, g_invalidate_esi},
- {e_regSetGPR, gpr_ebp, "ebp", "fp", Uint, Hex, GPR_SIZE(ebp),
- GPR_OFFSET(ebp), ehframe_ebp, dwarf_ebp, GENERIC_REGNUM_FP,
- debugserver_ebp, NULL, g_invalidate_ebp},
- {e_regSetGPR, gpr_esp, "esp", "sp", Uint, Hex, GPR_SIZE(esp),
- GPR_OFFSET(esp), ehframe_esp, dwarf_esp, GENERIC_REGNUM_SP,
- debugserver_esp, NULL, g_invalidate_esp},
- {e_regSetGPR, gpr_ss, "ss", NULL, Uint, Hex, GPR_SIZE(ss), GPR_OFFSET(ss),
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, debugserver_ss,
- NULL, NULL},
- {e_regSetGPR, gpr_eflags, "eflags", "flags", Uint, Hex, GPR_SIZE(eflags),
- GPR_OFFSET(eflags), ehframe_eflags, dwarf_eflags, GENERIC_REGNUM_FLAGS,
- debugserver_eflags, NULL, NULL},
- {e_regSetGPR, gpr_eip, "eip", "pc", Uint, Hex, GPR_SIZE(eip),
- GPR_OFFSET(eip), ehframe_eip, dwarf_eip, GENERIC_REGNUM_PC,
- debugserver_eip, NULL, NULL},
- {e_regSetGPR, gpr_cs, "cs", NULL, Uint, Hex, GPR_SIZE(cs), GPR_OFFSET(cs),
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, debugserver_cs,
- NULL, NULL},
- {e_regSetGPR, gpr_ds, "ds", NULL, Uint, Hex, GPR_SIZE(ds), GPR_OFFSET(ds),
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, debugserver_ds,
- NULL, NULL},
- {e_regSetGPR, gpr_es, "es", NULL, Uint, Hex, GPR_SIZE(es), GPR_OFFSET(es),
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, debugserver_es,
- NULL, NULL},
- {e_regSetGPR, gpr_fs, "fs", NULL, Uint, Hex, GPR_SIZE(fs), GPR_OFFSET(fs),
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, debugserver_fs,
- NULL, NULL},
- {e_regSetGPR, gpr_gs, "gs", NULL, Uint, Hex, GPR_SIZE(gs), GPR_OFFSET(gs),
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, debugserver_gs,
- NULL, NULL},
- DEFINE_GPR_PSEUDO_16(ax, eax),
- DEFINE_GPR_PSEUDO_16(bx, ebx),
- DEFINE_GPR_PSEUDO_16(cx, ecx),
- DEFINE_GPR_PSEUDO_16(dx, edx),
- DEFINE_GPR_PSEUDO_16(di, edi),
- DEFINE_GPR_PSEUDO_16(si, esi),
- DEFINE_GPR_PSEUDO_16(bp, ebp),
- DEFINE_GPR_PSEUDO_16(sp, esp),
- DEFINE_GPR_PSEUDO_8H(ah, eax),
- DEFINE_GPR_PSEUDO_8H(bh, ebx),
- DEFINE_GPR_PSEUDO_8H(ch, ecx),
- DEFINE_GPR_PSEUDO_8H(dh, edx),
- DEFINE_GPR_PSEUDO_8L(al, eax),
- DEFINE_GPR_PSEUDO_8L(bl, ebx),
- DEFINE_GPR_PSEUDO_8L(cl, ecx),
- DEFINE_GPR_PSEUDO_8L(dl, edx),
- DEFINE_GPR_PSEUDO_8L(dil, edi),
- DEFINE_GPR_PSEUDO_8L(sil, esi),
- DEFINE_GPR_PSEUDO_8L(bpl, ebp),
- DEFINE_GPR_PSEUDO_8L(spl, esp)};
-
-const DNBRegisterInfo DNBArchImplI386::g_fpu_registers_no_avx[] = {
- {e_regSetFPU, fpu_fcw, "fctrl", NULL, Uint, Hex, FPU_SIZE_UINT(fcw),
- FPU_OFFSET(fcw), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL},
- {e_regSetFPU, fpu_fsw, "fstat", NULL, Uint, Hex, FPU_SIZE_UINT(fsw),
- FPU_OFFSET(fsw), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL},
- {e_regSetFPU, fpu_ftw, "ftag", NULL, Uint, Hex, 2 /* sizeof __fpu_ftw + sizeof __fpu_rsrv1 */,
- FPU_OFFSET(ftw), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL},
- {e_regSetFPU, fpu_fop, "fop", NULL, Uint, Hex, FPU_SIZE_UINT(fop),
- FPU_OFFSET(fop), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL},
- {e_regSetFPU, fpu_ip, "fioff", NULL, Uint, Hex, FPU_SIZE_UINT(ip),
- FPU_OFFSET(ip), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, NULL, NULL},
- {e_regSetFPU, fpu_cs, "fiseg", NULL, Uint, Hex, FPU_SIZE_UINT(cs),
- FPU_OFFSET(cs), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, NULL, NULL},
- {e_regSetFPU, fpu_dp, "fooff", NULL, Uint, Hex, FPU_SIZE_UINT(dp),
- FPU_OFFSET(dp), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, NULL, NULL},
- {e_regSetFPU, fpu_ds, "foseg", NULL, Uint, Hex, FPU_SIZE_UINT(ds),
- FPU_OFFSET(ds), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, NULL, NULL},
- {e_regSetFPU, fpu_mxcsr, "mxcsr", NULL, Uint, Hex, FPU_SIZE_UINT(mxcsr),
- FPU_OFFSET(mxcsr), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL},
- {e_regSetFPU, fpu_mxcsrmask, "mxcsrmask", NULL, Uint, Hex,
- FPU_SIZE_UINT(mxcsrmask), FPU_OFFSET(mxcsrmask), INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL},
-
- {e_regSetFPU, fpu_stmm0, "stmm0", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm0), FPU_OFFSET(stmm0), INVALID_NUB_REGNUM, dwarf_stmm0,
- INVALID_NUB_REGNUM, debugserver_stmm0, NULL, NULL},
- {e_regSetFPU, fpu_stmm1, "stmm1", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm1), FPU_OFFSET(stmm1), INVALID_NUB_REGNUM, dwarf_stmm1,
- INVALID_NUB_REGNUM, debugserver_stmm1, NULL, NULL},
- {e_regSetFPU, fpu_stmm2, "stmm2", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm2), FPU_OFFSET(stmm2), INVALID_NUB_REGNUM, dwarf_stmm2,
- INVALID_NUB_REGNUM, debugserver_stmm2, NULL, NULL},
- {e_regSetFPU, fpu_stmm3, "stmm3", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm3), FPU_OFFSET(stmm3), INVALID_NUB_REGNUM, dwarf_stmm3,
- INVALID_NUB_REGNUM, debugserver_stmm3, NULL, NULL},
- {e_regSetFPU, fpu_stmm4, "stmm4", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm4), FPU_OFFSET(stmm4), INVALID_NUB_REGNUM, dwarf_stmm4,
- INVALID_NUB_REGNUM, debugserver_stmm4, NULL, NULL},
- {e_regSetFPU, fpu_stmm5, "stmm5", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm5), FPU_OFFSET(stmm5), INVALID_NUB_REGNUM, dwarf_stmm5,
- INVALID_NUB_REGNUM, debugserver_stmm5, NULL, NULL},
- {e_regSetFPU, fpu_stmm6, "stmm6", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm6), FPU_OFFSET(stmm6), INVALID_NUB_REGNUM, dwarf_stmm6,
- INVALID_NUB_REGNUM, debugserver_stmm6, NULL, NULL},
- {e_regSetFPU, fpu_stmm7, "stmm7", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm7), FPU_OFFSET(stmm7), INVALID_NUB_REGNUM, dwarf_stmm7,
- INVALID_NUB_REGNUM, debugserver_stmm7, NULL, NULL},
-
- {e_regSetFPU, fpu_xmm0, "xmm0", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm0), FPU_OFFSET(xmm0), INVALID_NUB_REGNUM, dwarf_xmm0,
- INVALID_NUB_REGNUM, debugserver_xmm0, NULL, NULL},
- {e_regSetFPU, fpu_xmm1, "xmm1", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm1), FPU_OFFSET(xmm1), INVALID_NUB_REGNUM, dwarf_xmm1,
- INVALID_NUB_REGNUM, debugserver_xmm1, NULL, NULL},
- {e_regSetFPU, fpu_xmm2, "xmm2", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm2), FPU_OFFSET(xmm2), INVALID_NUB_REGNUM, dwarf_xmm2,
- INVALID_NUB_REGNUM, debugserver_xmm2, NULL, NULL},
- {e_regSetFPU, fpu_xmm3, "xmm3", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm3), FPU_OFFSET(xmm3), INVALID_NUB_REGNUM, dwarf_xmm3,
- INVALID_NUB_REGNUM, debugserver_xmm3, NULL, NULL},
- {e_regSetFPU, fpu_xmm4, "xmm4", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm4), FPU_OFFSET(xmm4), INVALID_NUB_REGNUM, dwarf_xmm4,
- INVALID_NUB_REGNUM, debugserver_xmm4, NULL, NULL},
- {e_regSetFPU, fpu_xmm5, "xmm5", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm5), FPU_OFFSET(xmm5), INVALID_NUB_REGNUM, dwarf_xmm5,
- INVALID_NUB_REGNUM, debugserver_xmm5, NULL, NULL},
- {e_regSetFPU, fpu_xmm6, "xmm6", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm6), FPU_OFFSET(xmm6), INVALID_NUB_REGNUM, dwarf_xmm6,
- INVALID_NUB_REGNUM, debugserver_xmm6, NULL, NULL},
- {e_regSetFPU, fpu_xmm7, "xmm7", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm7), FPU_OFFSET(xmm7), INVALID_NUB_REGNUM, dwarf_xmm7,
- INVALID_NUB_REGNUM, debugserver_xmm7, NULL, NULL}};
-
-static const char *g_contained_ymm0[] = {"ymm0", NULL};
-static const char *g_contained_ymm1[] = {"ymm1", NULL};
-static const char *g_contained_ymm2[] = {"ymm2", NULL};
-static const char *g_contained_ymm3[] = {"ymm3", NULL};
-static const char *g_contained_ymm4[] = {"ymm4", NULL};
-static const char *g_contained_ymm5[] = {"ymm5", NULL};
-static const char *g_contained_ymm6[] = {"ymm6", NULL};
-static const char *g_contained_ymm7[] = {"ymm7", NULL};
-
-const DNBRegisterInfo DNBArchImplI386::g_fpu_registers_avx[] = {
- {e_regSetFPU, fpu_fcw, "fctrl", NULL, Uint, Hex, FPU_SIZE_UINT(fcw),
- AVX_OFFSET(fcw), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL},
- {e_regSetFPU, fpu_fsw, "fstat", NULL, Uint, Hex, FPU_SIZE_UINT(fsw),
- AVX_OFFSET(fsw), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL},
- {e_regSetFPU, fpu_ftw, "ftag", NULL, Uint, Hex, 2 /* sizeof __fpu_ftw + sizeof __fpu_rsrv1 */,
- AVX_OFFSET(ftw), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL},
- {e_regSetFPU, fpu_fop, "fop", NULL, Uint, Hex, FPU_SIZE_UINT(fop),
- AVX_OFFSET(fop), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL},
- {e_regSetFPU, fpu_ip, "fioff", NULL, Uint, Hex, FPU_SIZE_UINT(ip),
- AVX_OFFSET(ip), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, NULL, NULL},
- {e_regSetFPU, fpu_cs, "fiseg", NULL, Uint, Hex, FPU_SIZE_UINT(cs),
- AVX_OFFSET(cs), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, NULL, NULL},
- {e_regSetFPU, fpu_dp, "fooff", NULL, Uint, Hex, FPU_SIZE_UINT(dp),
- AVX_OFFSET(dp), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, NULL, NULL},
- {e_regSetFPU, fpu_ds, "foseg", NULL, Uint, Hex, FPU_SIZE_UINT(ds),
- AVX_OFFSET(ds), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, NULL, NULL},
- {e_regSetFPU, fpu_mxcsr, "mxcsr", NULL, Uint, Hex, FPU_SIZE_UINT(mxcsr),
- AVX_OFFSET(mxcsr), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL},
- {e_regSetFPU, fpu_mxcsrmask, "mxcsrmask", NULL, Uint, Hex,
- FPU_SIZE_UINT(mxcsrmask), AVX_OFFSET(mxcsrmask), INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL},
-
- {e_regSetFPU, fpu_stmm0, "stmm0", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm0), AVX_OFFSET(stmm0), INVALID_NUB_REGNUM, dwarf_stmm0,
- INVALID_NUB_REGNUM, debugserver_stmm0, NULL, NULL},
- {e_regSetFPU, fpu_stmm1, "stmm1", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm1), AVX_OFFSET(stmm1), INVALID_NUB_REGNUM, dwarf_stmm1,
- INVALID_NUB_REGNUM, debugserver_stmm1, NULL, NULL},
- {e_regSetFPU, fpu_stmm2, "stmm2", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm2), AVX_OFFSET(stmm2), INVALID_NUB_REGNUM, dwarf_stmm2,
- INVALID_NUB_REGNUM, debugserver_stmm2, NULL, NULL},
- {e_regSetFPU, fpu_stmm3, "stmm3", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm3), AVX_OFFSET(stmm3), INVALID_NUB_REGNUM, dwarf_stmm3,
- INVALID_NUB_REGNUM, debugserver_stmm3, NULL, NULL},
- {e_regSetFPU, fpu_stmm4, "stmm4", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm4), AVX_OFFSET(stmm4), INVALID_NUB_REGNUM, dwarf_stmm4,
- INVALID_NUB_REGNUM, debugserver_stmm4, NULL, NULL},
- {e_regSetFPU, fpu_stmm5, "stmm5", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm5), AVX_OFFSET(stmm5), INVALID_NUB_REGNUM, dwarf_stmm5,
- INVALID_NUB_REGNUM, debugserver_stmm5, NULL, NULL},
- {e_regSetFPU, fpu_stmm6, "stmm6", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm6), AVX_OFFSET(stmm6), INVALID_NUB_REGNUM, dwarf_stmm6,
- INVALID_NUB_REGNUM, debugserver_stmm6, NULL, NULL},
- {e_regSetFPU, fpu_stmm7, "stmm7", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm7), AVX_OFFSET(stmm7), INVALID_NUB_REGNUM, dwarf_stmm7,
- INVALID_NUB_REGNUM, debugserver_stmm7, NULL, NULL},
-
- {e_regSetFPU, fpu_ymm0, "ymm0", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_YMM(ymm0), AVX_OFFSET_YMM(0), INVALID_NUB_REGNUM, dwarf_ymm0,
- INVALID_NUB_REGNUM, debugserver_ymm0, NULL, NULL},
- {e_regSetFPU, fpu_ymm1, "ymm1", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_YMM(ymm1), AVX_OFFSET_YMM(1), INVALID_NUB_REGNUM, dwarf_ymm1,
- INVALID_NUB_REGNUM, debugserver_ymm1, NULL, NULL},
- {e_regSetFPU, fpu_ymm2, "ymm2", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_YMM(ymm2), AVX_OFFSET_YMM(2), INVALID_NUB_REGNUM, dwarf_ymm2,
- INVALID_NUB_REGNUM, debugserver_ymm2, NULL, NULL},
- {e_regSetFPU, fpu_ymm3, "ymm3", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_YMM(ymm3), AVX_OFFSET_YMM(3), INVALID_NUB_REGNUM, dwarf_ymm3,
- INVALID_NUB_REGNUM, debugserver_ymm3, NULL, NULL},
- {e_regSetFPU, fpu_ymm4, "ymm4", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_YMM(ymm4), AVX_OFFSET_YMM(4), INVALID_NUB_REGNUM, dwarf_ymm4,
- INVALID_NUB_REGNUM, debugserver_ymm4, NULL, NULL},
- {e_regSetFPU, fpu_ymm5, "ymm5", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_YMM(ymm5), AVX_OFFSET_YMM(5), INVALID_NUB_REGNUM, dwarf_ymm5,
- INVALID_NUB_REGNUM, debugserver_ymm5, NULL, NULL},
- {e_regSetFPU, fpu_ymm6, "ymm6", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_YMM(ymm6), AVX_OFFSET_YMM(6), INVALID_NUB_REGNUM, dwarf_ymm6,
- INVALID_NUB_REGNUM, debugserver_ymm6, NULL, NULL},
- {e_regSetFPU, fpu_ymm7, "ymm7", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_YMM(ymm7), AVX_OFFSET_YMM(7), INVALID_NUB_REGNUM, dwarf_ymm7,
- INVALID_NUB_REGNUM, debugserver_ymm7, NULL, NULL},
-
- {e_regSetFPU, fpu_xmm0, "xmm0", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm0), 0, INVALID_NUB_REGNUM, dwarf_xmm0, INVALID_NUB_REGNUM,
- debugserver_xmm0, g_contained_ymm0, NULL},
- {e_regSetFPU, fpu_xmm1, "xmm1", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm1), 0, INVALID_NUB_REGNUM, dwarf_xmm1, INVALID_NUB_REGNUM,
- debugserver_xmm1, g_contained_ymm1, NULL},
- {e_regSetFPU, fpu_xmm2, "xmm2", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm2), 0, INVALID_NUB_REGNUM, dwarf_xmm2, INVALID_NUB_REGNUM,
- debugserver_xmm2, g_contained_ymm2, NULL},
- {e_regSetFPU, fpu_xmm3, "xmm3", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm3), 0, INVALID_NUB_REGNUM, dwarf_xmm3, INVALID_NUB_REGNUM,
- debugserver_xmm3, g_contained_ymm3, NULL},
- {e_regSetFPU, fpu_xmm4, "xmm4", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm4), 0, INVALID_NUB_REGNUM, dwarf_xmm4, INVALID_NUB_REGNUM,
- debugserver_xmm4, g_contained_ymm4, NULL},
- {e_regSetFPU, fpu_xmm5, "xmm5", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm5), 0, INVALID_NUB_REGNUM, dwarf_xmm5, INVALID_NUB_REGNUM,
- debugserver_xmm5, g_contained_ymm5, NULL},
- {e_regSetFPU, fpu_xmm6, "xmm6", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm6), 0, INVALID_NUB_REGNUM, dwarf_xmm6, INVALID_NUB_REGNUM,
- debugserver_xmm6, g_contained_ymm6, NULL},
- {e_regSetFPU, fpu_xmm7, "xmm7", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm7), 0, INVALID_NUB_REGNUM, dwarf_xmm7, INVALID_NUB_REGNUM,
- debugserver_xmm7, g_contained_ymm7, NULL},
-
-};
-
-
-#define STR(s) #s
-
-#define ZMM_REG_DEF(reg) \
- { \
- e_regSetFPU, fpu_zmm##reg, STR(zmm##reg), NULL, Vector, VectorOfUInt8, \
- FPU_SIZE_ZMM(zmm##reg), AVX512F_OFFSET_ZMM(reg), INVALID_NUB_REGNUM, \
- dwarf_zmm##reg, INVALID_NUB_REGNUM, debugserver_zmm##reg, NULL, NULL \
- }
-
-#define YMM_REG_ALIAS(reg) \
- { \
- e_regSetFPU, fpu_ymm##reg, STR(ymm##reg), NULL, Vector, VectorOfUInt8, \
- FPU_SIZE_YMM(ymm##reg), 0, INVALID_NUB_REGNUM, dwarf_ymm##reg, \
- INVALID_NUB_REGNUM, debugserver_ymm##reg, g_contained_zmm##reg, NULL \
- }
-
-#define XMM_REG_ALIAS(reg) \
- { \
- e_regSetFPU, fpu_xmm##reg, STR(xmm##reg), NULL, Vector, VectorOfUInt8, \
- FPU_SIZE_XMM(xmm##reg), 0, INVALID_NUB_REGNUM, dwarf_xmm##reg, \
- INVALID_NUB_REGNUM, debugserver_xmm##reg, g_contained_zmm##reg, NULL \
- }
-
-#define AVX512_K_REG_DEF(reg) \
- { \
- e_regSetFPU, fpu_k##reg, STR(k##reg), NULL, Vector, VectorOfUInt8, 8, \
- AVX512F_OFFSET(k##reg), dwarf_k##reg, dwarf_k##reg, -1U, \
- debugserver_k##reg, NULL, NULL \
- }
-
-static const char *g_contained_zmm0[] = {"zmm0", NULL};
-static const char *g_contained_zmm1[] = {"zmm1", NULL};
-static const char *g_contained_zmm2[] = {"zmm2", NULL};
-static const char *g_contained_zmm3[] = {"zmm3", NULL};
-static const char *g_contained_zmm4[] = {"zmm4", NULL};
-static const char *g_contained_zmm5[] = {"zmm5", NULL};
-static const char *g_contained_zmm6[] = {"zmm6", NULL};
-static const char *g_contained_zmm7[] = {"zmm7", NULL};
-
-const DNBRegisterInfo DNBArchImplI386::g_fpu_registers_avx512f[] = {
- {e_regSetFPU, fpu_fcw, "fctrl", NULL, Uint, Hex, FPU_SIZE_UINT(fcw),
- AVX_OFFSET(fcw), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL},
- {e_regSetFPU, fpu_fsw, "fstat", NULL, Uint, Hex, FPU_SIZE_UINT(fsw),
- AVX_OFFSET(fsw), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL},
- {e_regSetFPU, fpu_ftw, "ftag", NULL, Uint, Hex, 2 /* sizeof __fpu_ftw + sizeof __fpu_rsrv1 */,
- FPU_OFFSET(ftw), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL},
- {e_regSetFPU, fpu_fop, "fop", NULL, Uint, Hex, FPU_SIZE_UINT(fop),
- AVX_OFFSET(fop), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL},
- {e_regSetFPU, fpu_ip, "fioff", NULL, Uint, Hex, FPU_SIZE_UINT(ip),
- AVX_OFFSET(ip), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, NULL, NULL},
- {e_regSetFPU, fpu_cs, "fiseg", NULL, Uint, Hex, FPU_SIZE_UINT(cs),
- AVX_OFFSET(cs), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, NULL, NULL},
- {e_regSetFPU, fpu_dp, "fooff", NULL, Uint, Hex, FPU_SIZE_UINT(dp),
- AVX_OFFSET(dp), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, NULL, NULL},
- {e_regSetFPU, fpu_ds, "foseg", NULL, Uint, Hex, FPU_SIZE_UINT(ds),
- AVX_OFFSET(ds), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, NULL, NULL},
- {e_regSetFPU, fpu_mxcsr, "mxcsr", NULL, Uint, Hex, FPU_SIZE_UINT(mxcsr),
- AVX_OFFSET(mxcsr), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL},
- {e_regSetFPU, fpu_mxcsrmask, "mxcsrmask", NULL, Uint, Hex,
- FPU_SIZE_UINT(mxcsrmask), AVX_OFFSET(mxcsrmask), INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL},
-
- {e_regSetFPU, fpu_stmm0, "stmm0", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm0), AVX_OFFSET(stmm0), INVALID_NUB_REGNUM, dwarf_stmm0,
- INVALID_NUB_REGNUM, debugserver_stmm0, NULL, NULL},
- {e_regSetFPU, fpu_stmm1, "stmm1", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm1), AVX_OFFSET(stmm1), INVALID_NUB_REGNUM, dwarf_stmm1,
- INVALID_NUB_REGNUM, debugserver_stmm1, NULL, NULL},
- {e_regSetFPU, fpu_stmm2, "stmm2", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm2), AVX_OFFSET(stmm2), INVALID_NUB_REGNUM, dwarf_stmm2,
- INVALID_NUB_REGNUM, debugserver_stmm2, NULL, NULL},
- {e_regSetFPU, fpu_stmm3, "stmm3", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm3), AVX_OFFSET(stmm3), INVALID_NUB_REGNUM, dwarf_stmm3,
- INVALID_NUB_REGNUM, debugserver_stmm3, NULL, NULL},
- {e_regSetFPU, fpu_stmm4, "stmm4", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm4), AVX_OFFSET(stmm4), INVALID_NUB_REGNUM, dwarf_stmm4,
- INVALID_NUB_REGNUM, debugserver_stmm4, NULL, NULL},
- {e_regSetFPU, fpu_stmm5, "stmm5", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm5), AVX_OFFSET(stmm5), INVALID_NUB_REGNUM, dwarf_stmm5,
- INVALID_NUB_REGNUM, debugserver_stmm5, NULL, NULL},
- {e_regSetFPU, fpu_stmm6, "stmm6", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm6), AVX_OFFSET(stmm6), INVALID_NUB_REGNUM, dwarf_stmm6,
- INVALID_NUB_REGNUM, debugserver_stmm6, NULL, NULL},
- {e_regSetFPU, fpu_stmm7, "stmm7", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm7), AVX_OFFSET(stmm7), INVALID_NUB_REGNUM, dwarf_stmm7,
- INVALID_NUB_REGNUM, debugserver_stmm7, NULL, NULL},
-
- AVX512_K_REG_DEF(0),
- AVX512_K_REG_DEF(1),
- AVX512_K_REG_DEF(2),
- AVX512_K_REG_DEF(3),
- AVX512_K_REG_DEF(4),
- AVX512_K_REG_DEF(5),
- AVX512_K_REG_DEF(6),
- AVX512_K_REG_DEF(7),
-
- ZMM_REG_DEF(0),
- ZMM_REG_DEF(1),
- ZMM_REG_DEF(2),
- ZMM_REG_DEF(3),
- ZMM_REG_DEF(4),
- ZMM_REG_DEF(5),
- ZMM_REG_DEF(6),
- ZMM_REG_DEF(7),
-
- YMM_REG_ALIAS(0),
- YMM_REG_ALIAS(1),
- YMM_REG_ALIAS(2),
- YMM_REG_ALIAS(3),
- YMM_REG_ALIAS(4),
- YMM_REG_ALIAS(5),
- YMM_REG_ALIAS(6),
- YMM_REG_ALIAS(7),
-
- XMM_REG_ALIAS(0),
- XMM_REG_ALIAS(1),
- XMM_REG_ALIAS(2),
- XMM_REG_ALIAS(3),
- XMM_REG_ALIAS(4),
- XMM_REG_ALIAS(5),
- XMM_REG_ALIAS(6),
- XMM_REG_ALIAS(7)
-
-};
-
-const DNBRegisterInfo DNBArchImplI386::g_exc_registers[] = {
- {e_regSetEXC, exc_trapno, "trapno", NULL, Uint, Hex, EXC_SIZE(trapno),
- EXC_OFFSET(trapno), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL},
- {e_regSetEXC, exc_err, "err", NULL, Uint, Hex, EXC_SIZE(err),
- EXC_OFFSET(err), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL},
- {e_regSetEXC, exc_faultvaddr, "faultvaddr", NULL, Uint, Hex,
- EXC_SIZE(faultvaddr), EXC_OFFSET(faultvaddr), INVALID_NUB_REGNUM,
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL}};
-
-// Number of registers in each register set
-const size_t DNBArchImplI386::k_num_gpr_registers =
- sizeof(g_gpr_registers) / sizeof(DNBRegisterInfo);
-const size_t DNBArchImplI386::k_num_fpu_registers_no_avx =
- sizeof(g_fpu_registers_no_avx) / sizeof(DNBRegisterInfo);
-const size_t DNBArchImplI386::k_num_fpu_registers_avx =
- sizeof(g_fpu_registers_avx) / sizeof(DNBRegisterInfo);
-const size_t DNBArchImplI386::k_num_fpu_registers_avx512f =
- sizeof(g_fpu_registers_avx512f) / sizeof(DNBRegisterInfo);
-const size_t DNBArchImplI386::k_num_exc_registers =
- sizeof(g_exc_registers) / sizeof(DNBRegisterInfo);
-const size_t DNBArchImplI386::k_num_all_registers_no_avx =
- k_num_gpr_registers + k_num_fpu_registers_no_avx + k_num_exc_registers;
-const size_t DNBArchImplI386::k_num_all_registers_avx =
- k_num_gpr_registers + k_num_fpu_registers_avx + k_num_exc_registers;
-const size_t DNBArchImplI386::k_num_all_registers_avx512f =
- k_num_gpr_registers + k_num_fpu_registers_avx512f + 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 DNBArchImplI386::g_reg_sets_no_avx[] = {
- {"i386 Registers", NULL, k_num_all_registers_no_avx},
- {"General Purpose Registers", g_gpr_registers, k_num_gpr_registers},
- {"Floating Point Registers", g_fpu_registers_no_avx,
- k_num_fpu_registers_no_avx},
- {"Exception State Registers", g_exc_registers, k_num_exc_registers}};
-
-const DNBRegisterSetInfo DNBArchImplI386::g_reg_sets_avx[] = {
- {"i386 Registers", NULL, k_num_all_registers_avx},
- {"General Purpose Registers", g_gpr_registers, k_num_gpr_registers},
- {"Floating Point Registers", g_fpu_registers_avx, k_num_fpu_registers_avx},
- {"Exception State Registers", g_exc_registers, k_num_exc_registers}};
-
-const DNBRegisterSetInfo DNBArchImplI386::g_reg_sets_avx512f[] = {
- {"i386 Registers", NULL, k_num_all_registers_avx512f},
- {"General Purpose Registers", g_gpr_registers, k_num_gpr_registers},
- {"Floating Point Registers", g_fpu_registers_avx512f,
- k_num_fpu_registers_avx512f},
- {"Exception State Registers", g_exc_registers, k_num_exc_registers}};
-
-// Total number of register sets for this architecture
-const size_t DNBArchImplI386::k_num_register_sets =
- sizeof(g_reg_sets_avx) / sizeof(DNBRegisterSetInfo);
-
-DNBArchProtocol *DNBArchImplI386::Create(MachThread *thread) {
- DNBArchImplI386 *obj = new DNBArchImplI386(thread);
- return obj;
-}
-
-const uint8_t *DNBArchImplI386::SoftwareBreakpointOpcode(nub_size_t byte_size) {
- static const uint8_t g_breakpoint_opcode[] = {0xCC};
- if (byte_size == 1)
- return g_breakpoint_opcode;
- return NULL;
-}
-
-const DNBRegisterSetInfo *
-DNBArchImplI386::GetRegisterSetInfo(nub_size_t *num_reg_sets) {
- *num_reg_sets = k_num_register_sets;
- if (CPUHasAVX512f() || FORCE_AVX_REGS)
- return g_reg_sets_avx512f;
- if (CPUHasAVX())
- return g_reg_sets_avx;
- else
- return g_reg_sets_no_avx;
-}
-
-void DNBArchImplI386::Initialize() {
- DNBArchPluginInfo arch_plugin_info = {
- CPU_TYPE_I386, DNBArchImplI386::Create,
- DNBArchImplI386::GetRegisterSetInfo,
- DNBArchImplI386::SoftwareBreakpointOpcode};
-
- // Register this arch plug-in with the main protocol class
- DNBArchProtocol::RegisterArchPlugin(arch_plugin_info);
-}
-
-bool DNBArchImplI386::GetRegisterValue(uint32_t set, uint32_t reg,
- DNBRegisterValue *value) {
- if (set == REGISTER_SET_GENERIC) {
- switch (reg) {
- case GENERIC_REGNUM_PC: // Program Counter
- set = e_regSetGPR;
- reg = gpr_eip;
- break;
-
- case GENERIC_REGNUM_SP: // Stack Pointer
- set = e_regSetGPR;
- reg = gpr_esp;
- break;
-
- case GENERIC_REGNUM_FP: // Frame Pointer
- set = e_regSetGPR;
- reg = gpr_ebp;
- break;
-
- case GENERIC_REGNUM_FLAGS: // Processor flags register
- set = e_regSetGPR;
- reg = gpr_eflags;
- break;
-
- case GENERIC_REGNUM_RA: // Return Address
- default:
- 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 < k_num_gpr_registers) {
- value->value.uint32 = ((uint32_t *)(&m_state.context.gpr))[reg];
- return true;
- }
- break;
-
- case e_regSetFPU:
- if (reg > fpu_xmm7 && !(CPUHasAVX() || FORCE_AVX_REGS))
- return false;
- if (reg > fpu_ymm7 && !(CPUHasAVX512f() || FORCE_AVX_REGS))
- return false;
- switch (reg) {
- case fpu_fcw:
- value->value.uint16 =
- *((uint16_t *)(&m_state.context.fpu.no_avx.__fpu_fcw));
- return true;
- case fpu_fsw:
- value->value.uint16 =
- *((uint16_t *)(&m_state.context.fpu.no_avx.__fpu_fsw));
- return true;
- case fpu_ftw:
- memcpy (&value->value.uint16, &m_state.context.fpu.no_avx.__fpu_ftw, 2);
- return true;
- case fpu_fop:
- value->value.uint16 = m_state.context.fpu.no_avx.__fpu_fop;
- return true;
- case fpu_ip:
- value->value.uint32 = m_state.context.fpu.no_avx.__fpu_ip;
- return true;
- case fpu_cs:
- value->value.uint16 = m_state.context.fpu.no_avx.__fpu_cs;
- return true;
- case fpu_dp:
- value->value.uint32 = m_state.context.fpu.no_avx.__fpu_dp;
- return true;
- case fpu_ds:
- value->value.uint16 = m_state.context.fpu.no_avx.__fpu_ds;
- return true;
- case fpu_mxcsr:
- value->value.uint32 = m_state.context.fpu.no_avx.__fpu_mxcsr;
- return true;
- case fpu_mxcsrmask:
- value->value.uint32 = m_state.context.fpu.no_avx.__fpu_mxcsrmask;
- return true;
-
- case fpu_stmm0:
- memcpy(&value->value.uint8,
- m_state.context.fpu.no_avx.__fpu_stmm0.__mmst_reg, 10);
- return true;
- case fpu_stmm1:
- memcpy(&value->value.uint8,
- m_state.context.fpu.no_avx.__fpu_stmm1.__mmst_reg, 10);
- return true;
- case fpu_stmm2:
- memcpy(&value->value.uint8,
- m_state.context.fpu.no_avx.__fpu_stmm2.__mmst_reg, 10);
- return true;
- case fpu_stmm3:
- memcpy(&value->value.uint8,
- m_state.context.fpu.no_avx.__fpu_stmm3.__mmst_reg, 10);
- return true;
- case fpu_stmm4:
- memcpy(&value->value.uint8,
- m_state.context.fpu.no_avx.__fpu_stmm4.__mmst_reg, 10);
- return true;
- case fpu_stmm5:
- memcpy(&value->value.uint8,
- m_state.context.fpu.no_avx.__fpu_stmm5.__mmst_reg, 10);
- return true;
- case fpu_stmm6:
- memcpy(&value->value.uint8,
- m_state.context.fpu.no_avx.__fpu_stmm6.__mmst_reg, 10);
- return true;
- case fpu_stmm7:
- memcpy(&value->value.uint8,
- m_state.context.fpu.no_avx.__fpu_stmm7.__mmst_reg, 10);
- return true;
-
- case fpu_xmm0:
- memcpy(&value->value.uint8,
- m_state.context.fpu.no_avx.__fpu_xmm0.__xmm_reg, 16);
- return true;
- case fpu_xmm1:
- memcpy(&value->value.uint8,
- m_state.context.fpu.no_avx.__fpu_xmm1.__xmm_reg, 16);
- return true;
- case fpu_xmm2:
- memcpy(&value->value.uint8,
- m_state.context.fpu.no_avx.__fpu_xmm2.__xmm_reg, 16);
- return true;
- case fpu_xmm3:
- memcpy(&value->value.uint8,
- m_state.context.fpu.no_avx.__fpu_xmm3.__xmm_reg, 16);
- return true;
- case fpu_xmm4:
- memcpy(&value->value.uint8,
- m_state.context.fpu.no_avx.__fpu_xmm4.__xmm_reg, 16);
- return true;
- case fpu_xmm5:
- memcpy(&value->value.uint8,
- m_state.context.fpu.no_avx.__fpu_xmm5.__xmm_reg, 16);
- return true;
- case fpu_xmm6:
- memcpy(&value->value.uint8,
- m_state.context.fpu.no_avx.__fpu_xmm6.__xmm_reg, 16);
- return true;
- case fpu_xmm7:
- memcpy(&value->value.uint8,
- m_state.context.fpu.no_avx.__fpu_xmm7.__xmm_reg, 16);
- return true;
-
-#define MEMCPY_YMM(n) \
- memcpy(&value->value.uint8, m_state.context.fpu.avx.__fpu_xmm##n.__xmm_reg, \
- 16); \
- memcpy((&value->value.uint8) + 16, \
- m_state.context.fpu.avx.__fpu_ymmh##n.__xmm_reg, 16);
- case fpu_ymm0:
- MEMCPY_YMM(0);
- return true;
- case fpu_ymm1:
- MEMCPY_YMM(1);
- return true;
- case fpu_ymm2:
- MEMCPY_YMM(2);
- return true;
- case fpu_ymm3:
- MEMCPY_YMM(3);
- return true;
- case fpu_ymm4:
- MEMCPY_YMM(4);
- return true;
- case fpu_ymm5:
- MEMCPY_YMM(5);
- return true;
- case fpu_ymm6:
- MEMCPY_YMM(6);
- return true;
- case fpu_ymm7:
- MEMCPY_YMM(7);
- return true;
-#undef MEMCPY_YMM
-
- case fpu_k0:
- case fpu_k1:
- case fpu_k2:
- case fpu_k3:
- case fpu_k4:
- case fpu_k5:
- case fpu_k6:
- case fpu_k7:
- memcpy((&value->value.uint8),
- &m_state.context.fpu.avx512f.__fpu_k0 + (reg - fpu_k0), 8);
- return true;
- case fpu_zmm0:
- case fpu_zmm1:
- case fpu_zmm2:
- case fpu_zmm3:
- case fpu_zmm4:
- case fpu_zmm5:
- case fpu_zmm6:
- case fpu_zmm7:
- memcpy(&value->value.uint8,
- &m_state.context.fpu.avx512f.__fpu_xmm0 + (reg - fpu_zmm0), 16);
- memcpy(&value->value.uint8 + 16,
- &m_state.context.fpu.avx512f.__fpu_ymmh0 + (reg - fpu_zmm0), 16);
- memcpy(&value->value.uint8 + 32,
- &m_state.context.fpu.avx512f.__fpu_zmmh0 + (reg - fpu_zmm0), 32);
- return true;
- }
- break;
-
- case e_regSetEXC:
- if (reg < k_num_exc_registers) {
- value->value.uint32 = (&m_state.context.exc.__trapno)[reg];
- return true;
- }
- break;
- }
- }
- return false;
-}
-
-bool DNBArchImplI386::SetRegisterValue(uint32_t set, uint32_t reg,
- const DNBRegisterValue *value) {
- if (set == REGISTER_SET_GENERIC) {
- switch (reg) {
- case GENERIC_REGNUM_PC: // Program Counter
- set = e_regSetGPR;
- reg = gpr_eip;
- break;
-
- case GENERIC_REGNUM_SP: // Stack Pointer
- set = e_regSetGPR;
- reg = gpr_esp;
- break;
-
- case GENERIC_REGNUM_FP: // Frame Pointer
- set = e_regSetGPR;
- reg = gpr_ebp;
- break;
-
- case GENERIC_REGNUM_FLAGS: // Processor flags register
- set = e_regSetGPR;
- reg = gpr_eflags;
- break;
-
- case GENERIC_REGNUM_RA: // Return Address
- default:
- 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 < k_num_gpr_registers) {
- ((uint32_t *)(&m_state.context.gpr))[reg] = value->value.uint32;
- success = true;
- }
- break;
-
- case e_regSetFPU:
- if (reg > fpu_xmm7 && !(CPUHasAVX() || FORCE_AVX_REGS))
- return false;
- if (reg > fpu_ymm7 && !(CPUHasAVX512f() || FORCE_AVX_REGS))
- return false;
- switch (reg) {
- case fpu_fcw:
- *((uint16_t *)(&m_state.context.fpu.no_avx.__fpu_fcw)) =
- value->value.uint16;
- success = true;
- break;
- case fpu_fsw:
- *((uint16_t *)(&m_state.context.fpu.no_avx.__fpu_fsw)) =
- value->value.uint16;
- success = true;
- break;
- case fpu_ftw:
- memcpy (&m_state.context.fpu.no_avx.__fpu_ftw, &value->value.uint16, 2);
- success = true;
- break;
- case fpu_fop:
- m_state.context.fpu.no_avx.__fpu_fop = value->value.uint16;
- success = true;
- break;
- case fpu_ip:
- m_state.context.fpu.no_avx.__fpu_ip = value->value.uint32;
- success = true;
- break;
- case fpu_cs:
- m_state.context.fpu.no_avx.__fpu_cs = value->value.uint16;
- success = true;
- break;
- case fpu_dp:
- m_state.context.fpu.no_avx.__fpu_dp = value->value.uint32;
- success = true;
- break;
- case fpu_ds:
- m_state.context.fpu.no_avx.__fpu_ds = value->value.uint16;
- success = true;
- break;
- case fpu_mxcsr:
- m_state.context.fpu.no_avx.__fpu_mxcsr = value->value.uint32;
- success = true;
- break;
- case fpu_mxcsrmask:
- m_state.context.fpu.no_avx.__fpu_mxcsrmask = value->value.uint32;
- success = true;
- break;
-
- case fpu_stmm0:
- memcpy(m_state.context.fpu.no_avx.__fpu_stmm0.__mmst_reg,
- &value->value.uint8, 10);
- success = true;
- break;
- case fpu_stmm1:
- memcpy(m_state.context.fpu.no_avx.__fpu_stmm1.__mmst_reg,
- &value->value.uint8, 10);
- success = true;
- break;
- case fpu_stmm2:
- memcpy(m_state.context.fpu.no_avx.__fpu_stmm2.__mmst_reg,
- &value->value.uint8, 10);
- success = true;
- break;
- case fpu_stmm3:
- memcpy(m_state.context.fpu.no_avx.__fpu_stmm3.__mmst_reg,
- &value->value.uint8, 10);
- success = true;
- break;
- case fpu_stmm4:
- memcpy(m_state.context.fpu.no_avx.__fpu_stmm4.__mmst_reg,
- &value->value.uint8, 10);
- success = true;
- break;
- case fpu_stmm5:
- memcpy(m_state.context.fpu.no_avx.__fpu_stmm5.__mmst_reg,
- &value->value.uint8, 10);
- success = true;
- break;
- case fpu_stmm6:
- memcpy(m_state.context.fpu.no_avx.__fpu_stmm6.__mmst_reg,
- &value->value.uint8, 10);
- success = true;
- break;
- case fpu_stmm7:
- memcpy(m_state.context.fpu.no_avx.__fpu_stmm7.__mmst_reg,
- &value->value.uint8, 10);
- success = true;
- break;
-
- case fpu_xmm0:
- memcpy(m_state.context.fpu.no_avx.__fpu_xmm0.__xmm_reg,
- &value->value.uint8, 16);
- success = true;
- break;
- case fpu_xmm1:
- memcpy(m_state.context.fpu.no_avx.__fpu_xmm1.__xmm_reg,
- &value->value.uint8, 16);
- success = true;
- break;
- case fpu_xmm2:
- memcpy(m_state.context.fpu.no_avx.__fpu_xmm2.__xmm_reg,
- &value->value.uint8, 16);
- success = true;
- break;
- case fpu_xmm3:
- memcpy(m_state.context.fpu.no_avx.__fpu_xmm3.__xmm_reg,
- &value->value.uint8, 16);
- success = true;
- break;
- case fpu_xmm4:
- memcpy(m_state.context.fpu.no_avx.__fpu_xmm4.__xmm_reg,
- &value->value.uint8, 16);
- success = true;
- break;
- case fpu_xmm5:
- memcpy(m_state.context.fpu.no_avx.__fpu_xmm5.__xmm_reg,
- &value->value.uint8, 16);
- success = true;
- break;
- case fpu_xmm6:
- memcpy(m_state.context.fpu.no_avx.__fpu_xmm6.__xmm_reg,
- &value->value.uint8, 16);
- success = true;
- break;
- case fpu_xmm7:
- memcpy(m_state.context.fpu.no_avx.__fpu_xmm7.__xmm_reg,
- &value->value.uint8, 16);
- success = true;
- break;
-
-#define MEMCPY_YMM(n) \
- memcpy(m_state.context.fpu.avx.__fpu_xmm##n.__xmm_reg, &value->value.uint8, \
- 16); \
- memcpy(m_state.context.fpu.avx.__fpu_ymmh##n.__xmm_reg, \
- (&value->value.uint8) + 16, 16);
- case fpu_ymm0:
- MEMCPY_YMM(0);
- return true;
- case fpu_ymm1:
- MEMCPY_YMM(1);
- return true;
- case fpu_ymm2:
- MEMCPY_YMM(2);
- return true;
- case fpu_ymm3:
- MEMCPY_YMM(3);
- return true;
- case fpu_ymm4:
- MEMCPY_YMM(4);
- return true;
- case fpu_ymm5:
- MEMCPY_YMM(5);
- return true;
- case fpu_ymm6:
- MEMCPY_YMM(6);
- return true;
- case fpu_ymm7:
- MEMCPY_YMM(7);
- return true;
-#undef MEMCPY_YMM
-
- case fpu_k0:
- case fpu_k1:
- case fpu_k2:
- case fpu_k3:
- case fpu_k4:
- case fpu_k5:
- case fpu_k6:
- case fpu_k7:
- memcpy(&m_state.context.fpu.avx512f.__fpu_k0 + (reg - fpu_k0),
- &value->value.uint8, 8);
- return true;
- case fpu_zmm0:
- case fpu_zmm1:
- case fpu_zmm2:
- case fpu_zmm3:
- case fpu_zmm4:
- case fpu_zmm5:
- case fpu_zmm6:
- case fpu_zmm7:
- memcpy(&m_state.context.fpu.avx512f.__fpu_xmm0 + (reg - fpu_zmm0),
- &value->value.uint8, 16);
- memcpy(&m_state.context.fpu.avx512f.__fpu_ymmh0 + (reg - fpu_zmm0),
- &value->value.uint8 + 16, 16);
- memcpy(&m_state.context.fpu.avx512f.__fpu_zmmh0 + (reg - fpu_zmm0),
- &value->value.uint8 + 32, 32);
- return true;
- }
- break;
-
- case e_regSetEXC:
- if (reg < k_num_exc_registers) {
- (&m_state.context.exc.__trapno)[reg] = value->value.uint32;
- success = true;
- }
- break;
- }
- }
-
- if (success)
- return SetRegisterState(set) == KERN_SUCCESS;
- return false;
-}
-
-uint32_t DNBArchImplI386::GetRegisterContextSize() {
- static uint32_t g_cached_size = 0;
- if (g_cached_size == 0) {
- if(CPUHasAVX512f() || FORCE_AVX_REGS) {
- for (size_t i = 0; i < k_num_fpu_registers_avx512f; ++i) {
- if (g_fpu_registers_avx512f[i].value_regs == NULL)
- g_cached_size += g_fpu_registers_avx512f[i].size;
- }
- } else
- if (CPUHasAVX()) {
- for (size_t i = 0; i < k_num_fpu_registers_avx; ++i) {
- if (g_fpu_registers_avx[i].value_regs == NULL)
- g_cached_size += g_fpu_registers_avx[i].size;
- }
- } else {
- for (size_t i = 0; i < k_num_fpu_registers_no_avx; ++i) {
- if (g_fpu_registers_no_avx[i].value_regs == NULL)
- g_cached_size += g_fpu_registers_no_avx[i].size;
- }
- }
- DNBLogThreaded("DNBArchImplX86_64::GetRegisterContextSize() - GPR = %zu, "
- "FPU = %u, EXC = %zu",
- sizeof(GPR), g_cached_size, sizeof(EXC));
- g_cached_size += sizeof(GPR);
- g_cached_size += sizeof(EXC);
- DNBLogThreaded(
- "DNBArchImplX86_64::GetRegisterContextSize() - GPR + FPU + EXC = %u",
- g_cached_size);
- }
- return g_cached_size;
-}
-
-nub_size_t DNBArchImplI386::GetRegisterContext(void *buf, nub_size_t buf_len) {
- uint32_t size = GetRegisterContextSize();
-
- if (buf && buf_len) {
- if (size > buf_len)
- size = static_cast<uint32_t>(buf_len);
-
- bool force = false;
- kern_return_t kret;
- if ((kret = GetGPRState(force)) != KERN_SUCCESS) {
- DNBLogThreadedIf(LOG_THREAD, "DNBArchImplI386::GetRegisterContext (buf = "
- "%p, len = %llu) error: GPR regs failed to "
- "read: %u ",
- buf, (uint64_t)buf_len, kret);
- size = 0;
- } else if ((kret = GetFPUState(force)) != KERN_SUCCESS) {
- DNBLogThreadedIf(
- LOG_THREAD, "DNBArchImplI386::GetRegisterContext (buf = %p, len = "
- "%llu) error: %s regs failed to read: %u",
- buf, (uint64_t)buf_len, CPUHasAVX() ? "AVX" : "FPU", kret);
- size = 0;
- } else if ((kret = GetEXCState(force)) != KERN_SUCCESS) {
- DNBLogThreadedIf(LOG_THREAD, "DNBArchImplI386::GetRegisterContext (buf = "
- "%p, len = %llu) error: EXC regs failed to "
- "read: %u",
- buf, (uint64_t)buf_len, kret);
- size = 0;
- } else {
- uint8_t *p = (uint8_t *)buf;
- // Copy the GPR registers
- memcpy(p, &m_state.context.gpr, sizeof(GPR));
- p += sizeof(GPR);
-
- // Walk around the gaps in the FPU regs
- memcpy(p, &m_state.context.fpu.no_avx.__fpu_fcw, 5);
- p += 5;
- memcpy(p, &m_state.context.fpu.no_avx.__fpu_fop, 8);
- p += 8;
- memcpy(p, &m_state.context.fpu.no_avx.__fpu_dp, 6);
- p += 6;
- memcpy(p, &m_state.context.fpu.no_avx.__fpu_mxcsr, 8);
- p += 8;
-
- // Work around the padding between the stmm registers as they are 16
- // byte structs with 10 bytes of the value in each
- for (size_t i = 0; i < 8; ++i) {
- memcpy(p, &m_state.context.fpu.no_avx.__fpu_stmm0 + i, 10);
- p += 10;
- }
-
- if (CPUHasAVX512f() || FORCE_AVX_REGS) {
- for (size_t i = 0; i < 8; ++i) {
- memcpy(p, &m_state.context.fpu.avx512f.__fpu_k0 + i, 8);
- p += 8;
- }
- }
-
- if (CPUHasAVX() || FORCE_AVX_REGS) {
- // Interleave the XMM and YMMH registers to make the YMM registers
- for (size_t i = 0; i < 8; ++i) {
- memcpy(p, &m_state.context.fpu.avx.__fpu_xmm0 + i, 16);
- p += 16;
- memcpy(p, &m_state.context.fpu.avx.__fpu_ymmh0 + i, 16);
- p += 16;
- }
- if(CPUHasAVX512f() || FORCE_AVX_REGS) {
- for (size_t i = 0; i < 8; ++i) {
- memcpy(p, &m_state.context.fpu.avx512f.__fpu_zmmh0 + i, 32);
- p += 32;
- }
- }
- } else {
- // Copy the XMM registers in a single block
- memcpy(p, &m_state.context.fpu.no_avx.__fpu_xmm0, 8 * 16);
- p += 8 * 16;
- }
-
- // Copy the exception registers
- memcpy(p, &m_state.context.exc, sizeof(EXC));
- p += sizeof(EXC);
-
- // make sure we end up with exactly what we think we should have
- size_t bytes_written = p - (uint8_t *)buf;
- UNUSED_IF_ASSERT_DISABLED(bytes_written);
- assert(bytes_written == size);
- }
- }
- DNBLogThreadedIf(
- LOG_THREAD,
- "DNBArchImplI386::GetRegisterContext (buf = %p, len = %llu) => %llu", buf,
- (uint64_t)buf_len, (uint64_t)size);
- // Return the size of the register context even if NULL was passed in
- return size;
-}
-
-nub_size_t DNBArchImplI386::SetRegisterContext(const void *buf,
- nub_size_t buf_len) {
- nub_size_t size = sizeof(m_state.context);
- if (buf == NULL || buf_len == 0)
- size = 0;
-
- if (size) {
- if (size > buf_len)
- size = buf_len;
-
- const uint8_t *p = (const uint8_t *)buf;
- // Copy the GPR registers
- memcpy(&m_state.context.gpr, p, sizeof(GPR));
- p += sizeof(GPR);
-
- // Copy fcw through mxcsrmask as there is no padding
- memcpy(&m_state.context.fpu.no_avx.__fpu_fcw, p, 5);
- p += 5;
- memcpy(&m_state.context.fpu.no_avx.__fpu_fop, p, 8);
- p += 8;
- memcpy(&m_state.context.fpu.no_avx.__fpu_dp, p, 6);
- p += 6;
- memcpy(&m_state.context.fpu.no_avx.__fpu_mxcsr, p, 8);
- p += 8;
-
- // Work around the padding between the stmm registers as they are 16
- // byte structs with 10 bytes of the value in each
- for (size_t i = 0; i < 8; ++i) {
- memcpy(&m_state.context.fpu.no_avx.__fpu_stmm0 + i, p, 10);
- p += 10;
- }
-
- if(CPUHasAVX512f() || FORCE_AVX_REGS) {
- for (size_t i = 0; i < 8; ++i) {
- memcpy(&m_state.context.fpu.avx512f.__fpu_k0 + i, p, 8);
- p += 8;
- }
- }
-
- if (CPUHasAVX() || FORCE_AVX_REGS) {
- // Interleave the XMM and YMMH registers to make the YMM registers
- for (size_t i = 0; i < 8; ++i) {
- memcpy(&m_state.context.fpu.avx.__fpu_xmm0 + i, p, 16);
- p += 16;
- memcpy(&m_state.context.fpu.avx.__fpu_ymmh0 + i, p, 16);
- p += 16;
- }
-
- if(CPUHasAVX512f() || FORCE_AVX_REGS) {
- for (size_t i = 0; i < 8; ++i) {
- memcpy(&m_state.context.fpu.avx512f.__fpu_zmmh0 + i, p, 32);
- p += 32;
- }
- }
- } else {
- // Copy the XMM registers in a single block
- memcpy(&m_state.context.fpu.no_avx.__fpu_xmm0, p, 8 * 16);
- p += 8 * 16;
- }
-
- // Copy the exception registers
- memcpy(&m_state.context.exc, p, sizeof(EXC));
- p += sizeof(EXC);
-
- // make sure we end up with exactly what we think we should have
- size_t bytes_written = p - (const uint8_t *)buf;
- UNUSED_IF_ASSERT_DISABLED(bytes_written);
- assert(bytes_written == size);
- kern_return_t kret;
- if ((kret = SetGPRState()) != KERN_SUCCESS)
- DNBLogThreadedIf(LOG_THREAD, "DNBArchImplI386::SetRegisterContext (buf = "
- "%p, len = %llu) error: GPR regs failed to "
- "write: %u",
- buf, (uint64_t)buf_len, kret);
- if ((kret = SetFPUState()) != KERN_SUCCESS)
- DNBLogThreadedIf(
- LOG_THREAD, "DNBArchImplI386::SetRegisterContext (buf = %p, len = "
- "%llu) error: %s regs failed to write: %u",
- buf, (uint64_t)buf_len, CPUHasAVX() ? "AVX" : "FPU", kret);
- if ((kret = SetEXCState()) != KERN_SUCCESS)
- DNBLogThreadedIf(LOG_THREAD, "DNBArchImplI386::SetRegisterContext (buf = "
- "%p, len = %llu) error: EXP regs failed to "
- "write: %u",
- buf, (uint64_t)buf_len, kret);
- }
- DNBLogThreadedIf(
- LOG_THREAD,
- "DNBArchImplI386::SetRegisterContext (buf = %p, len = %llu) => %llu", buf,
- (uint64_t)buf_len, (uint64_t)size);
- return size;
-}
-
-uint32_t DNBArchImplI386::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());
-
- bool force = true;
-
- if ((kret = GetGPRState(force)) != KERN_SUCCESS) {
- DNBLogThreadedIf(LOG_THREAD, "DNBArchImplI386::SaveRegisterState () error: "
- "GPR regs failed to read: %u ",
- kret);
- } else if ((kret = GetFPUState(force)) != KERN_SUCCESS) {
- DNBLogThreadedIf(LOG_THREAD, "DNBArchImplI386::SaveRegisterState () error: "
- "%s regs failed to read: %u",
- CPUHasAVX() ? "AVX" : "FPU", kret);
- } else {
- const uint32_t save_id = GetNextRegisterStateSaveID();
- m_saved_register_states[save_id] = m_state.context;
- return save_id;
- }
- return 0;
-}
-bool DNBArchImplI386::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.fpu = pos->second.fpu;
- m_state.context.exc = pos->second.exc;
- m_state.SetError(e_regSetGPR, Read, 0);
- m_state.SetError(e_regSetFPU, Read, 0);
- m_state.SetError(e_regSetEXC, Read, 0);
- kern_return_t kret;
- bool success = true;
- if ((kret = SetGPRState()) != KERN_SUCCESS) {
- DNBLogThreadedIf(LOG_THREAD, "DNBArchImplI386::RestoreRegisterState "
- "(save_id = %u) error: GPR regs failed to "
- "write: %u",
- save_id, kret);
- success = false;
- } else if ((kret = SetFPUState()) != KERN_SUCCESS) {
- DNBLogThreadedIf(LOG_THREAD, "DNBArchImplI386::RestoreRegisterState "
- "(save_id = %u) error: %s regs failed to "
- "write: %u",
- save_id, CPUHasAVX() ? "AVX" : "FPU", kret);
- success = false;
- }
- m_saved_register_states.erase(pos);
- return success;
- }
- return false;
-}
-
-kern_return_t DNBArchImplI386::GetRegisterState(int set, bool force) {
- switch (set) {
- case e_regSetALL:
- return GetGPRState(force) | GetFPUState(force) | GetEXCState(force);
- case e_regSetGPR:
- return GetGPRState(force);
- case e_regSetFPU:
- return GetFPUState(force);
- case e_regSetEXC:
- return GetEXCState(force);
- default:
- break;
- }
- return KERN_INVALID_ARGUMENT;
-}
-
-kern_return_t DNBArchImplI386::SetRegisterState(int set) {
- // Make sure we have a valid context to set.
- if (RegisterSetStateIsValid(set)) {
- switch (set) {
- case e_regSetALL:
- return SetGPRState() | SetFPUState() | SetEXCState();
- case e_regSetGPR:
- return SetGPRState();
- case e_regSetFPU:
- return SetFPUState();
- case e_regSetEXC:
- return SetEXCState();
- default:
- break;
- }
- }
- return KERN_INVALID_ARGUMENT;
-}
-
-bool DNBArchImplI386::RegisterSetStateIsValid(int set) const {
- return m_state.RegsAreValid(set);
-}
-
-#endif // #if defined (__i386__)
diff --git a/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h b/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h
deleted file mode 100644
index ce56a540e092..000000000000
--- a/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h
+++ /dev/null
@@ -1,239 +0,0 @@
-//===-- DNBArchImplI386.h ---------------------------------------*- 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.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __DNBArchImplI386_h__
-#define __DNBArchImplI386_h__
-
-#if defined(__i386__) || defined(__x86_64__)
-
-#include "DNBArch.h"
-#include "MachRegisterStatesI386.h"
-
-#include <map>
-
-class MachThread;
-
-class DNBArchImplI386 : public DNBArchProtocol {
-public:
- DNBArchImplI386(MachThread *thread)
- : DNBArchProtocol(), m_thread(thread), m_state(), m_2pc_dbg_checkpoint(),
- m_2pc_trans_state(Trans_Done), m_saved_register_states() {}
- virtual ~DNBArchImplI386() {}
-
- static void Initialize();
-
- virtual bool GetRegisterValue(uint32_t set, uint32_t reg,
- DNBRegisterValue *value);
- virtual bool SetRegisterValue(uint32_t set, uint32_t 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);
-
- 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 uint32_t GetHardwareWatchpointHit(nub_addr_t &addr);
-
-protected:
- kern_return_t EnableHardwareSingleStep(bool enable);
-
- typedef __i386_thread_state_t GPR;
- typedef __i386_float_state_t FPU;
- typedef __i386_exception_state_t EXC;
- typedef __i386_avx_state_t AVX;
- typedef __i386_debug_state_t DBG;
-
- static const DNBRegisterInfo g_gpr_registers[];
- static const DNBRegisterInfo g_fpu_registers_no_avx[];
- static const DNBRegisterInfo g_fpu_registers_avx[];
- static const DNBRegisterInfo g_exc_registers[];
- static const DNBRegisterSetInfo g_reg_sets_no_avx[];
- static const DNBRegisterSetInfo g_reg_sets_avx[];
- static const size_t k_num_gpr_registers;
- static const size_t k_num_fpu_registers_no_avx;
- static const size_t k_num_fpu_registers_avx;
- static const size_t k_num_exc_registers;
- static const size_t k_num_all_registers_no_avx;
- static const size_t k_num_all_registers_avx;
- static const size_t k_num_register_sets;
-
- typedef __i386_avx512f_state_t AVX512F;
- static const DNBRegisterInfo g_fpu_registers_avx512f[];
- static const DNBRegisterSetInfo g_reg_sets_avx512f[];
- static const size_t k_num_fpu_registers_avx512f;
- static const size_t k_num_all_registers_avx512f;
-
- typedef enum RegisterSetTag {
- e_regSetALL = REGISTER_SET_ALL,
- e_regSetGPR,
- e_regSetFPU,
- e_regSetEXC,
- e_regSetDBG,
- kNumRegisterSets
- } RegisterSet;
-
- typedef enum RegisterSetWordSizeTag {
- e_regSetWordSizeGPR = sizeof(GPR) / sizeof(int),
- e_regSetWordSizeFPU = sizeof(FPU) / sizeof(int),
- e_regSetWordSizeEXC = sizeof(EXC) / sizeof(int),
- e_regSetWordSizeAVX = sizeof(AVX) / sizeof(int),
- e_regSetWordSizeAVX512f = sizeof(AVX512F) / sizeof(int),
- e_regSetWordSizeDBG = sizeof(DBG) / sizeof(int)
- } RegisterSetWordSize;
-
- enum { Read = 0, Write = 1, kNumErrors = 2 };
-
- struct Context {
- GPR gpr;
- union {
- FPU no_avx;
- AVX avx;
- AVX512F avx512f;
- } fpu;
- EXC exc;
- DBG dbg;
- };
-
- struct State {
- Context context;
- kern_return_t gpr_errs[2]; // Read/Write errors
- kern_return_t fpu_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;
- fpu_errs[i] = -1;
- exc_errs[i] = -1;
- dbg_errs[i] = -1;
- }
- }
- void InvalidateAllRegisterStates() { SetError(e_regSetALL, Read, -1); }
- kern_return_t 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 e_regSetALL:
- return gpr_errs[err_idx] | fpu_errs[err_idx] | exc_errs[err_idx];
- case e_regSetGPR:
- return gpr_errs[err_idx];
- case e_regSetFPU:
- return fpu_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 flavor, uint32_t err_idx, kern_return_t err) {
- if (err_idx < kNumErrors) {
- switch (flavor) {
- case e_regSetALL:
- gpr_errs[err_idx] = fpu_errs[err_idx] = exc_errs[err_idx] =
- dbg_errs[err_idx] = err;
- return true;
-
- case e_regSetGPR:
- gpr_errs[err_idx] = err;
- return true;
-
- case e_regSetFPU:
- fpu_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 flavor) const {
- return GetError(flavor, Read) == KERN_SUCCESS;
- }
- };
-
- kern_return_t GetGPRState(bool force);
- kern_return_t GetFPUState(bool force);
- kern_return_t GetEXCState(bool force);
- kern_return_t GetDBGState(bool force);
-
- kern_return_t SetGPRState();
- kern_return_t SetFPUState();
- kern_return_t SetEXCState();
- kern_return_t SetDBGState(bool also_set_on_task);
-
- static DNBArchProtocol *Create(MachThread *thread);
-
- static const uint8_t *SoftwareBreakpointOpcode(nub_size_t byte_size);
-
- static const DNBRegisterSetInfo *GetRegisterSetInfo(nub_size_t *num_reg_sets);
-
- static uint32_t GetRegisterContextSize();
-
- // Helper functions for watchpoint manipulations.
- static void SetWatchpoint(DBG &debug_state, uint32_t hw_index,
- nub_addr_t addr, nub_size_t size, bool read,
- bool write);
- static void ClearWatchpoint(DBG &debug_state, uint32_t hw_index);
- static bool IsWatchpointVacant(const DBG &debug_state, uint32_t hw_index);
- static void ClearWatchpointHits(DBG &debug_state);
- static bool IsWatchpointHit(const DBG &debug_state, uint32_t hw_index);
- static nub_addr_t GetWatchAddress(const DBG &debug_state, uint32_t hw_index);
-
- virtual bool StartTransForHWP();
- virtual bool RollbackTransForHWP();
- virtual bool FinishTransForHWP();
- DBG GetDBGCheckpoint();
-
- MachThread *m_thread;
- State m_state;
- DBG m_2pc_dbg_checkpoint;
- uint32_t m_2pc_trans_state; // Is transaction of DBG state change: Pedning
- // (0), Done (1), or Rolled Back (2)?
- typedef std::map<uint32_t, Context> SaveRegisterStates;
- SaveRegisterStates m_saved_register_states;
-};
-
-#endif // #if defined (__i386__) || defined (__x86_64__)
-#endif // #ifndef __DNBArchImplI386_h__
diff --git a/tools/debugserver/source/MacOSX/i386/MachRegisterStatesI386.h b/tools/debugserver/source/MacOSX/i386/MachRegisterStatesI386.h
deleted file mode 100644
index e51ecfd24bef..000000000000
--- a/tools/debugserver/source/MacOSX/i386/MachRegisterStatesI386.h
+++ /dev/null
@@ -1,242 +0,0 @@
-//===-- MachRegisterStatesI386.h --------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Created by Sean Callanan on 3/16/11.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __MachRegisterStatesI386_h__
-#define __MachRegisterStatesI386_h__
-
-#include <inttypes.h>
-
-#define __i386_THREAD_STATE 1
-#define __i386_FLOAT_STATE 2
-#define __i386_EXCEPTION_STATE 3
-#define __i386_DEBUG_STATE 10
-#define __i386_AVX_STATE 16
-#define __i386_AVX512F_STATE 19
-
-typedef struct {
- uint32_t __eax;
- uint32_t __ebx;
- uint32_t __ecx;
- uint32_t __edx;
- uint32_t __edi;
- uint32_t __esi;
- uint32_t __ebp;
- uint32_t __esp;
- uint32_t __ss;
- uint32_t __eflags;
- uint32_t __eip;
- uint32_t __cs;
- uint32_t __ds;
- uint32_t __es;
- uint32_t __fs;
- uint32_t __gs;
-} __i386_thread_state_t;
-
-typedef struct {
- uint16_t __invalid : 1;
- uint16_t __denorm : 1;
- uint16_t __zdiv : 1;
- uint16_t __ovrfl : 1;
- uint16_t __undfl : 1;
- uint16_t __precis : 1;
- uint16_t __PAD1 : 2;
- uint16_t __pc : 2;
- uint16_t __rc : 2;
- uint16_t __PAD2 : 1;
- uint16_t __PAD3 : 3;
-} __i386_fp_control_t;
-
-typedef struct {
- uint16_t __invalid : 1;
- uint16_t __denorm : 1;
- uint16_t __zdiv : 1;
- uint16_t __ovrfl : 1;
- uint16_t __undfl : 1;
- uint16_t __precis : 1;
- uint16_t __stkflt : 1;
- uint16_t __errsumm : 1;
- uint16_t __c0 : 1;
- uint16_t __c1 : 1;
- uint16_t __c2 : 1;
- uint16_t __tos : 3;
- uint16_t __c3 : 1;
- uint16_t __busy : 1;
-} __i386_fp_status_t;
-
-typedef struct {
- uint8_t __mmst_reg[10];
- uint8_t __mmst_rsrv[6];
-} __i386_mmst_reg;
-
-typedef struct { uint8_t __xmm_reg[16]; } __i386_xmm_reg;
-
-typedef struct {
- uint32_t __fpu_reserved[2];
- __i386_fp_control_t __fpu_fcw;
- __i386_fp_status_t __fpu_fsw;
- uint8_t __fpu_ftw;
- uint8_t __fpu_rsrv1;
- uint16_t __fpu_fop;
- uint32_t __fpu_ip;
- uint16_t __fpu_cs;
- uint16_t __fpu_rsrv2;
- uint32_t __fpu_dp;
- uint16_t __fpu_ds;
- uint16_t __fpu_rsrv3;
- uint32_t __fpu_mxcsr;
- uint32_t __fpu_mxcsrmask;
- __i386_mmst_reg __fpu_stmm0;
- __i386_mmst_reg __fpu_stmm1;
- __i386_mmst_reg __fpu_stmm2;
- __i386_mmst_reg __fpu_stmm3;
- __i386_mmst_reg __fpu_stmm4;
- __i386_mmst_reg __fpu_stmm5;
- __i386_mmst_reg __fpu_stmm6;
- __i386_mmst_reg __fpu_stmm7;
- __i386_xmm_reg __fpu_xmm0;
- __i386_xmm_reg __fpu_xmm1;
- __i386_xmm_reg __fpu_xmm2;
- __i386_xmm_reg __fpu_xmm3;
- __i386_xmm_reg __fpu_xmm4;
- __i386_xmm_reg __fpu_xmm5;
- __i386_xmm_reg __fpu_xmm6;
- __i386_xmm_reg __fpu_xmm7;
- uint8_t __fpu_rsrv4[14 * 16];
- uint32_t __fpu_reserved1;
-} __i386_float_state_t;
-
-typedef struct {
- uint32_t __fpu_reserved[2];
- __i386_fp_control_t __fpu_fcw;
- __i386_fp_status_t __fpu_fsw;
- uint8_t __fpu_ftw;
- uint8_t __fpu_rsrv1;
- uint16_t __fpu_fop;
- uint32_t __fpu_ip;
- uint16_t __fpu_cs;
- uint16_t __fpu_rsrv2;
- uint32_t __fpu_dp;
- uint16_t __fpu_ds;
- uint16_t __fpu_rsrv3;
- uint32_t __fpu_mxcsr;
- uint32_t __fpu_mxcsrmask;
- __i386_mmst_reg __fpu_stmm0;
- __i386_mmst_reg __fpu_stmm1;
- __i386_mmst_reg __fpu_stmm2;
- __i386_mmst_reg __fpu_stmm3;
- __i386_mmst_reg __fpu_stmm4;
- __i386_mmst_reg __fpu_stmm5;
- __i386_mmst_reg __fpu_stmm6;
- __i386_mmst_reg __fpu_stmm7;
- __i386_xmm_reg __fpu_xmm0;
- __i386_xmm_reg __fpu_xmm1;
- __i386_xmm_reg __fpu_xmm2;
- __i386_xmm_reg __fpu_xmm3;
- __i386_xmm_reg __fpu_xmm4;
- __i386_xmm_reg __fpu_xmm5;
- __i386_xmm_reg __fpu_xmm6;
- __i386_xmm_reg __fpu_xmm7;
- uint8_t __fpu_rsrv4[14 * 16];
- uint32_t __fpu_reserved1;
- uint8_t __avx_reserved1[64];
- __i386_xmm_reg __fpu_ymmh0;
- __i386_xmm_reg __fpu_ymmh1;
- __i386_xmm_reg __fpu_ymmh2;
- __i386_xmm_reg __fpu_ymmh3;
- __i386_xmm_reg __fpu_ymmh4;
- __i386_xmm_reg __fpu_ymmh5;
- __i386_xmm_reg __fpu_ymmh6;
- __i386_xmm_reg __fpu_ymmh7;
-} __i386_avx_state_t;
-
-typedef struct { uint8_t __ymm_reg[32]; } __i386_ymm_reg;
-typedef struct { uint8_t __opmask_reg[8]; } __i386_opmask_reg;
-
-typedef struct {
- uint32_t __fpu_reserved[2];
- __i386_fp_control_t __fpu_fcw;
- __i386_fp_status_t __fpu_fsw;
- uint8_t __fpu_ftw;
- uint8_t __fpu_rsrv1;
- uint16_t __fpu_fop;
- uint32_t __fpu_ip;
- uint16_t __fpu_cs;
- uint16_t __fpu_rsrv2;
- uint32_t __fpu_dp;
- uint16_t __fpu_ds;
- uint16_t __fpu_rsrv3;
- uint32_t __fpu_mxcsr;
- uint32_t __fpu_mxcsrmask;
- __i386_mmst_reg __fpu_stmm0;
- __i386_mmst_reg __fpu_stmm1;
- __i386_mmst_reg __fpu_stmm2;
- __i386_mmst_reg __fpu_stmm3;
- __i386_mmst_reg __fpu_stmm4;
- __i386_mmst_reg __fpu_stmm5;
- __i386_mmst_reg __fpu_stmm6;
- __i386_mmst_reg __fpu_stmm7;
- __i386_xmm_reg __fpu_xmm0;
- __i386_xmm_reg __fpu_xmm1;
- __i386_xmm_reg __fpu_xmm2;
- __i386_xmm_reg __fpu_xmm3;
- __i386_xmm_reg __fpu_xmm4;
- __i386_xmm_reg __fpu_xmm5;
- __i386_xmm_reg __fpu_xmm6;
- __i386_xmm_reg __fpu_xmm7;
- uint8_t __fpu_rsrv4[14 * 16];
- uint32_t __fpu_reserved1;
- uint8_t __avx_reserved1[64];
- __i386_xmm_reg __fpu_ymmh0;
- __i386_xmm_reg __fpu_ymmh1;
- __i386_xmm_reg __fpu_ymmh2;
- __i386_xmm_reg __fpu_ymmh3;
- __i386_xmm_reg __fpu_ymmh4;
- __i386_xmm_reg __fpu_ymmh5;
- __i386_xmm_reg __fpu_ymmh6;
- __i386_xmm_reg __fpu_ymmh7;
- __i386_opmask_reg __fpu_k0;
- __i386_opmask_reg __fpu_k1;
- __i386_opmask_reg __fpu_k2;
- __i386_opmask_reg __fpu_k3;
- __i386_opmask_reg __fpu_k4;
- __i386_opmask_reg __fpu_k5;
- __i386_opmask_reg __fpu_k6;
- __i386_opmask_reg __fpu_k7;
- __i386_ymm_reg __fpu_zmmh0;
- __i386_ymm_reg __fpu_zmmh1;
- __i386_ymm_reg __fpu_zmmh2;
- __i386_ymm_reg __fpu_zmmh3;
- __i386_ymm_reg __fpu_zmmh4;
- __i386_ymm_reg __fpu_zmmh5;
- __i386_ymm_reg __fpu_zmmh6;
- __i386_ymm_reg __fpu_zmmh7;
-} __i386_avx512f_state_t;
-
-typedef struct {
- uint32_t __trapno;
- uint32_t __err;
- uint32_t __faultvaddr;
-} __i386_exception_state_t;
-
-typedef struct {
- uint32_t __dr0;
- uint32_t __dr1;
- uint32_t __dr2;
- uint32_t __dr3;
- uint32_t __dr4;
- uint32_t __dr5;
- uint32_t __dr6;
- uint32_t __dr7;
-} __i386_debug_state_t;
-
-#endif
diff --git a/tools/debugserver/source/MacOSX/ppc/DNBArchImpl.cpp b/tools/debugserver/source/MacOSX/ppc/DNBArchImpl.cpp
deleted file mode 100644
index 1653287430ad..000000000000
--- a/tools/debugserver/source/MacOSX/ppc/DNBArchImpl.cpp
+++ /dev/null
@@ -1,492 +0,0 @@
-//===-- DNBArchImpl.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(__powerpc__) || defined(__ppc__) || defined(__ppc64__)
-
-#if __DARWIN_UNIX03
-#define PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(reg) __##reg
-#else
-#define PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(reg) reg
-#endif
-
-#include "MacOSX/ppc/DNBArchImpl.h"
-#include "DNBBreakpoint.h"
-#include "DNBLog.h"
-#include "DNBRegisterInfo.h"
-#include "MacOSX/MachThread.h"
-
-static const uint8_t g_breakpoint_opcode[] = {0x7F, 0xC0, 0x00, 0x08};
-
-const uint8_t *DNBArchMachPPC::SoftwareBreakpointOpcode(nub_size_t size) {
- if (size == 4)
- return g_breakpoint_opcode;
- return NULL;
-}
-
-uint32_t DNBArchMachPPC::GetCPUType() { return CPU_TYPE_POWERPC; }
-
-uint64_t DNBArchMachPPC::GetPC(uint64_t failValue) {
- // Get program counter
- if (GetGPRState(false) == KERN_SUCCESS)
- return m_state.gpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(srr0);
- return failValue;
-}
-
-kern_return_t DNBArchMachPPC::SetPC(uint64_t value) {
- // Get program counter
- kern_return_t err = GetGPRState(false);
- if (err == KERN_SUCCESS) {
- m_state.gpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(srr0) = value;
- err = SetGPRState();
- }
- return err == KERN_SUCCESS;
-}
-
-uint64_t DNBArchMachPPC::GetSP(uint64_t failValue) {
- // Get stack pointer
- if (GetGPRState(false) == KERN_SUCCESS)
- return m_state.gpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(r1);
- return failValue;
-}
-
-kern_return_t DNBArchMachPPC::GetGPRState(bool force) {
- if (force || m_state.GetError(e_regSetGPR, Read)) {
- mach_msg_type_number_t count = e_regSetWordSizeGPR;
- m_state.SetError(e_regSetGPR, Read,
- ::thread_get_state(m_thread->MachPortNumber(), e_regSetGPR,
- (thread_state_t)&m_state.gpr, &count));
- }
- return m_state.GetError(e_regSetGPR, Read);
-}
-
-kern_return_t DNBArchMachPPC::GetFPRState(bool force) {
- if (force || m_state.GetError(e_regSetFPR, Read)) {
- mach_msg_type_number_t count = e_regSetWordSizeFPR;
- m_state.SetError(e_regSetFPR, Read,
- ::thread_get_state(m_thread->MachPortNumber(), e_regSetFPR,
- (thread_state_t)&m_state.fpr, &count));
- }
- return m_state.GetError(e_regSetFPR, Read);
-}
-
-kern_return_t DNBArchMachPPC::GetEXCState(bool force) {
- if (force || m_state.GetError(e_regSetEXC, Read)) {
- mach_msg_type_number_t count = e_regSetWordSizeEXC;
- m_state.SetError(e_regSetEXC, Read,
- ::thread_get_state(m_thread->MachPortNumber(), e_regSetEXC,
- (thread_state_t)&m_state.exc, &count));
- }
- return m_state.GetError(e_regSetEXC, Read);
-}
-
-kern_return_t DNBArchMachPPC::GetVECState(bool force) {
- if (force || m_state.GetError(e_regSetVEC, Read)) {
- mach_msg_type_number_t count = e_regSetWordSizeVEC;
- m_state.SetError(e_regSetVEC, Read,
- ::thread_get_state(m_thread->MachPortNumber(), e_regSetVEC,
- (thread_state_t)&m_state.vec, &count));
- }
- return m_state.GetError(e_regSetVEC, Read);
-}
-
-kern_return_t DNBArchMachPPC::SetGPRState() {
- m_state.SetError(e_regSetGPR, Write,
- ::thread_set_state(m_thread->MachPortNumber(), e_regSetGPR,
- (thread_state_t)&m_state.gpr,
- e_regSetWordSizeGPR));
- return m_state.GetError(e_regSetGPR, Write);
-}
-
-kern_return_t DNBArchMachPPC::SetFPRState() {
- m_state.SetError(e_regSetFPR, Write,
- ::thread_set_state(m_thread->MachPortNumber(), e_regSetFPR,
- (thread_state_t)&m_state.fpr,
- e_regSetWordSizeFPR));
- return m_state.GetError(e_regSetFPR, Write);
-}
-
-kern_return_t DNBArchMachPPC::SetEXCState() {
- m_state.SetError(e_regSetEXC, Write,
- ::thread_set_state(m_thread->MachPortNumber(), e_regSetEXC,
- (thread_state_t)&m_state.exc,
- e_regSetWordSizeEXC));
- return m_state.GetError(e_regSetEXC, Write);
-}
-
-kern_return_t DNBArchMachPPC::SetVECState() {
- m_state.SetError(e_regSetVEC, Write,
- ::thread_set_state(m_thread->MachPortNumber(), e_regSetVEC,
- (thread_state_t)&m_state.vec,
- e_regSetWordSizeVEC));
- return m_state.GetError(e_regSetVEC, Write);
-}
-
-bool DNBArchMachPPC::ThreadWillResume() {
- bool success = true;
-
- // Do we need to step this thread? If so, let the mach thread tell us so.
- if (m_thread->IsStepping()) {
- // This is the primary thread, let the arch do anything it needs
- success = EnableHardwareSingleStep(true) == KERN_SUCCESS;
- }
- return success;
-}
-
-bool DNBArchMachPPC::ThreadDidStop() {
- bool success = true;
-
- m_state.InvalidateAllRegisterStates();
-
- // 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 DNBArchMachPPC::EnableHardwareSingleStep(bool enable) {
- DNBLogThreadedIf(LOG_STEP,
- "DNBArchMachPPC::EnableHardwareSingleStep( enable = %d )",
- enable);
- if (GetGPRState(false) == KERN_SUCCESS) {
- const uint32_t trace_bit = 0x400;
- if (enable)
- m_state.gpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(srr1) |= trace_bit;
- else
- m_state.gpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(srr1) &= ~trace_bit;
- return SetGPRState();
- }
- return m_state.GetError(e_regSetGPR, Read);
-}
-
-//----------------------------------------------------------------------
-// Register information definitions for 32 bit PowerPC.
-//----------------------------------------------------------------------
-
-enum gpr_regnums {
- e_regNumGPR_srr0,
- e_regNumGPR_srr1,
- e_regNumGPR_r0,
- e_regNumGPR_r1,
- e_regNumGPR_r2,
- e_regNumGPR_r3,
- e_regNumGPR_r4,
- e_regNumGPR_r5,
- e_regNumGPR_r6,
- e_regNumGPR_r7,
- e_regNumGPR_r8,
- e_regNumGPR_r9,
- e_regNumGPR_r10,
- e_regNumGPR_r11,
- e_regNumGPR_r12,
- e_regNumGPR_r13,
- e_regNumGPR_r14,
- e_regNumGPR_r15,
- e_regNumGPR_r16,
- e_regNumGPR_r17,
- e_regNumGPR_r18,
- e_regNumGPR_r19,
- e_regNumGPR_r20,
- e_regNumGPR_r21,
- e_regNumGPR_r22,
- e_regNumGPR_r23,
- e_regNumGPR_r24,
- e_regNumGPR_r25,
- e_regNumGPR_r26,
- e_regNumGPR_r27,
- e_regNumGPR_r28,
- e_regNumGPR_r29,
- e_regNumGPR_r30,
- e_regNumGPR_r31,
- e_regNumGPR_cr,
- e_regNumGPR_xer,
- e_regNumGPR_lr,
- e_regNumGPR_ctr,
- e_regNumGPR_mq,
- e_regNumGPR_vrsave
-};
-
-// General purpose registers
-static DNBRegisterInfo g_gpr_registers[] = {
- {"srr0", Uint, 4, Hex}, {"srr1", Uint, 4, Hex}, {"r0", Uint, 4, Hex},
- {"r1", Uint, 4, Hex}, {"r2", Uint, 4, Hex}, {"r3", Uint, 4, Hex},
- {"r4", Uint, 4, Hex}, {"r5", Uint, 4, Hex}, {"r6", Uint, 4, Hex},
- {"r7", Uint, 4, Hex}, {"r8", Uint, 4, Hex}, {"r9", Uint, 4, Hex},
- {"r10", Uint, 4, Hex}, {"r11", Uint, 4, Hex}, {"r12", Uint, 4, Hex},
- {"r13", Uint, 4, Hex}, {"r14", Uint, 4, Hex}, {"r15", Uint, 4, Hex},
- {"r16", Uint, 4, Hex}, {"r17", Uint, 4, Hex}, {"r18", Uint, 4, Hex},
- {"r19", Uint, 4, Hex}, {"r20", Uint, 4, Hex}, {"r21", Uint, 4, Hex},
- {"r22", Uint, 4, Hex}, {"r23", Uint, 4, Hex}, {"r24", Uint, 4, Hex},
- {"r25", Uint, 4, Hex}, {"r26", Uint, 4, Hex}, {"r27", Uint, 4, Hex},
- {"r28", Uint, 4, Hex}, {"r29", Uint, 4, Hex}, {"r30", Uint, 4, Hex},
- {"r31", Uint, 4, Hex}, {"cr", Uint, 4, Hex}, {"xer", Uint, 4, Hex},
- {"lr", Uint, 4, Hex}, {"ctr", Uint, 4, Hex}, {"mq", Uint, 4, Hex},
- {"vrsave", Uint, 4, Hex},
-};
-
-// Floating point registers
-static DNBRegisterInfo g_fpr_registers[] = {
- {"fp0", IEEE754, 8, Float}, {"fp1", IEEE754, 8, Float},
- {"fp2", IEEE754, 8, Float}, {"fp3", IEEE754, 8, Float},
- {"fp4", IEEE754, 8, Float}, {"fp5", IEEE754, 8, Float},
- {"fp6", IEEE754, 8, Float}, {"fp7", IEEE754, 8, Float},
- {"fp8", IEEE754, 8, Float}, {"fp9", IEEE754, 8, Float},
- {"fp10", IEEE754, 8, Float}, {"fp11", IEEE754, 8, Float},
- {"fp12", IEEE754, 8, Float}, {"fp13", IEEE754, 8, Float},
- {"fp14", IEEE754, 8, Float}, {"fp15", IEEE754, 8, Float},
- {"fp16", IEEE754, 8, Float}, {"fp17", IEEE754, 8, Float},
- {"fp18", IEEE754, 8, Float}, {"fp19", IEEE754, 8, Float},
- {"fp20", IEEE754, 8, Float}, {"fp21", IEEE754, 8, Float},
- {"fp22", IEEE754, 8, Float}, {"fp23", IEEE754, 8, Float},
- {"fp24", IEEE754, 8, Float}, {"fp25", IEEE754, 8, Float},
- {"fp26", IEEE754, 8, Float}, {"fp27", IEEE754, 8, Float},
- {"fp28", IEEE754, 8, Float}, {"fp29", IEEE754, 8, Float},
- {"fp30", IEEE754, 8, Float}, {"fp31", IEEE754, 8, Float},
- {"fpscr", Uint, 4, Hex}};
-
-// Exception registers
-
-static DNBRegisterInfo g_exc_registers[] = {{"dar", Uint, 4, Hex},
- {"dsisr", Uint, 4, Hex},
- {"exception", Uint, 4, Hex}};
-
-// Altivec registers
-static DNBRegisterInfo g_vec_registers[] = {
- {"vr0", Vector, 16, VectorOfFloat32},
- {"vr1", Vector, 16, VectorOfFloat32},
- {"vr2", Vector, 16, VectorOfFloat32},
- {"vr3", Vector, 16, VectorOfFloat32},
- {"vr4", Vector, 16, VectorOfFloat32},
- {"vr5", Vector, 16, VectorOfFloat32},
- {"vr6", Vector, 16, VectorOfFloat32},
- {"vr7", Vector, 16, VectorOfFloat32},
- {"vr8", Vector, 16, VectorOfFloat32},
- {"vr9", Vector, 16, VectorOfFloat32},
- {"vr10", Vector, 16, VectorOfFloat32},
- {"vr11", Vector, 16, VectorOfFloat32},
- {"vr12", Vector, 16, VectorOfFloat32},
- {"vr13", Vector, 16, VectorOfFloat32},
- {"vr14", Vector, 16, VectorOfFloat32},
- {"vr15", Vector, 16, VectorOfFloat32},
- {"vr16", Vector, 16, VectorOfFloat32},
- {"vr17", Vector, 16, VectorOfFloat32},
- {"vr18", Vector, 16, VectorOfFloat32},
- {"vr19", Vector, 16, VectorOfFloat32},
- {"vr20", Vector, 16, VectorOfFloat32},
- {"vr21", Vector, 16, VectorOfFloat32},
- {"vr22", Vector, 16, VectorOfFloat32},
- {"vr23", Vector, 16, VectorOfFloat32},
- {"vr24", Vector, 16, VectorOfFloat32},
- {"vr25", Vector, 16, VectorOfFloat32},
- {"vr26", Vector, 16, VectorOfFloat32},
- {"vr27", Vector, 16, VectorOfFloat32},
- {"vr28", Vector, 16, VectorOfFloat32},
- {"vr29", Vector, 16, VectorOfFloat32},
- {"vr30", Vector, 16, VectorOfFloat32},
- {"vr31", Vector, 16, VectorOfFloat32},
- {"vscr", Uint, 16, Hex},
- {"vrvalid", Uint, 4, Hex}};
-
-// Number of registers in each register set
-const size_t k_num_gpr_registers =
- sizeof(g_gpr_registers) / sizeof(DNBRegisterInfo);
-const size_t k_num_fpr_registers =
- sizeof(g_fpr_registers) / sizeof(DNBRegisterInfo);
-const size_t k_num_exc_registers =
- sizeof(g_exc_registers) / sizeof(DNBRegisterInfo);
-const size_t k_num_vec_registers =
- sizeof(g_vec_registers) / sizeof(DNBRegisterInfo);
-// Total number of registers for this architecture
-const size_t k_num_ppc_registers = k_num_gpr_registers + k_num_fpr_registers +
- k_num_exc_registers + k_num_vec_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.
-//----------------------------------------------------------------------
-static const DNBRegisterSetInfo g_reg_sets[] = {
- {"PowerPC Registers", NULL, k_num_ppc_registers},
- {"General Purpose Registers", g_gpr_registers, k_num_gpr_registers},
- {"Floating Point Registers", g_fpr_registers, k_num_fpr_registers},
- {"Exception State Registers", g_exc_registers, k_num_exc_registers},
- {"Altivec Registers", g_vec_registers, k_num_vec_registers}};
-// Total number of register sets for this architecture
-const size_t k_num_register_sets =
- sizeof(g_reg_sets) / sizeof(DNBRegisterSetInfo);
-
-const DNBRegisterSetInfo *
-DNBArchMachPPC::GetRegisterSetInfo(nub_size_t *num_reg_sets) const {
- *num_reg_sets = k_num_register_sets;
- return g_reg_sets;
-}
-
-bool DNBArchMachPPC::GetRegisterValue(uint32_t set, uint32_t reg,
- DNBRegisterValue *value) const {
- if (set == REGISTER_SET_GENERIC) {
- switch (reg) {
- case GENERIC_REGNUM_PC: // Program Counter
- set = e_regSetGPR;
- reg = e_regNumGPR_srr0;
- break;
-
- case GENERIC_REGNUM_SP: // Stack Pointer
- set = e_regSetGPR;
- reg = e_regNumGPR_r1;
- break;
-
- case GENERIC_REGNUM_FP: // Frame Pointer
- // Return false for now instead of returning r30 as gcc 3.x would
- // use a variety of registers for the FP and it takes inspecting
- // the stack to make sure there is a frame pointer before we can
- // determine the FP.
- return false;
-
- case GENERIC_REGNUM_RA: // Return Address
- set = e_regSetGPR;
- reg = e_regNumGPR_lr;
- break;
-
- case GENERIC_REGNUM_FLAGS: // Processor flags register
- set = e_regSetGPR;
- reg = e_regNumGPR_srr1;
- break;
-
- default:
- return false;
- }
- }
-
- if (!m_state.RegsAreValid(set))
- return false;
-
- const DNBRegisterInfo *regInfo = m_thread->GetRegisterInfo(set, reg);
- if (regInfo) {
- value->info = *regInfo;
- switch (set) {
- case e_regSetGPR:
- if (reg < k_num_gpr_registers) {
- value->value.uint32 =
- (&m_state.gpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(srr0))[reg];
- return true;
- }
- break;
-
- case e_regSetFPR:
- if (reg < 32) {
- value->value.float64 =
- m_state.fpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(fpregs)[reg];
- return true;
- } else if (reg == 32) {
- value->value.uint32 =
- m_state.fpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(fpscr);
- return true;
- }
- break;
-
- case e_regSetEXC:
- if (reg < k_num_exc_registers) {
- value->value.uint32 =
- (&m_state.exc.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(dar))[reg];
- return true;
- }
- break;
-
- case e_regSetVEC:
- if (reg < k_num_vec_registers) {
- if (reg < 33) // FP0 - FP31 and VSCR
- {
- // Copy all 4 uint32 values for this vector register
- value->value.v_uint32[0] =
- m_state.vec.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(save_vr)[reg]
- [0];
- value->value.v_uint32[1] =
- m_state.vec.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(save_vr)[reg]
- [1];
- value->value.v_uint32[2] =
- m_state.vec.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(save_vr)[reg]
- [2];
- value->value.v_uint32[3] =
- m_state.vec.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(save_vr)[reg]
- [3];
- return true;
- } else if (reg == 34) // VRVALID
- {
- value->value.uint32 =
- m_state.vec.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(save_vrvalid);
- return true;
- }
- }
- break;
- }
- }
- return false;
-}
-
-kern_return_t DNBArchMachPPC::GetRegisterState(int set, bool force) {
- switch (set) {
- case e_regSetALL:
- return GetGPRState(force) | GetFPRState(force) | GetEXCState(force) |
- GetVECState(force);
- case e_regSetGPR:
- return GetGPRState(force);
- case e_regSetFPR:
- return GetFPRState(force);
- case e_regSetEXC:
- return GetEXCState(force);
- case e_regSetVEC:
- return GetVECState(force);
- default:
- break;
- }
- return KERN_INVALID_ARGUMENT;
-}
-
-kern_return_t DNBArchMachPPC::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() | SetFPRState() | SetEXCState() | SetVECState();
- case e_regSetGPR:
- return SetGPRState();
- case e_regSetFPR:
- return SetFPRState();
- case e_regSetEXC:
- return SetEXCState();
- case e_regSetVEC:
- return SetVECState();
- default:
- break;
- }
- return KERN_INVALID_ARGUMENT;
-}
-
-bool DNBArchMachPPC::RegisterSetStateIsValid(int set) const {
- return m_state.RegsAreValid(set);
-}
-
-#endif // #if defined (__powerpc__) || defined (__ppc__) || defined (__ppc64__)
diff --git a/tools/debugserver/source/MacOSX/ppc/DNBArchImpl.h b/tools/debugserver/source/MacOSX/ppc/DNBArchImpl.h
deleted file mode 100644
index 8aed9fc0f80a..000000000000
--- a/tools/debugserver/source/MacOSX/ppc/DNBArchImpl.h
+++ /dev/null
@@ -1,160 +0,0 @@
-//===-- DNBArchImpl.h -------------------------------------------*- 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.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __DebugNubArchMachPPC_h__
-#define __DebugNubArchMachPPC_h__
-
-#if defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__)
-
-#include "DNBArch.h"
-
-class MachThread;
-
-class DNBArchMachPPC : public DNBArchProtocol {
-public:
- DNBArchMachPPC(MachThread *thread) : m_thread(thread), m_state() {}
-
- virtual ~DNBArchMachPPC() {}
-
- virtual const DNBRegisterSetInfo *
- GetRegisterSetInfo(nub_size_t *num_reg_sets) const;
- virtual bool GetRegisterValue(uint32_t set, uint32_t reg,
- DNBRegisterValue *value) const;
- 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 bool ThreadWillResume();
- virtual bool ThreadDidStop();
-
- static const uint8_t *SoftwareBreakpointOpcode(nub_size_t byte_size);
- static uint32_t GetCPUType();
-
-protected:
- kern_return_t EnableHardwareSingleStep(bool enable);
-
- typedef enum RegisterSetTag {
- e_regSetALL = REGISTER_SET_ALL,
- e_regSetGPR,
- e_regSetFPR,
- e_regSetEXC,
- e_regSetVEC,
- kNumRegisterSets
- } RegisterSet;
-
- typedef enum RegisterSetWordSizeTag {
- e_regSetWordSizeGPR = PPC_THREAD_STATE_COUNT,
- e_regSetWordSizeFPR = PPC_FLOAT_STATE_COUNT,
- e_regSetWordSizeEXC = PPC_EXCEPTION_STATE_COUNT,
- e_regSetWordSizeVEC = PPC_VECTOR_STATE_COUNT
- } RegisterSetWordSize;
-
- enum { Read = 0, Write = 1, kNumErrors = 2 };
-
- struct State {
- ppc_thread_state_t gpr;
- ppc_float_state_t fpr;
- ppc_exception_state_t exc;
- ppc_vector_state_t vec;
- kern_return_t gpr_errs[2]; // Read/Write errors
- kern_return_t fpr_errs[2]; // Read/Write errors
- kern_return_t exc_errs[2]; // Read/Write errors
- kern_return_t vec_errs[2]; // Read/Write errors
-
- State() {
- uint32_t i;
- for (i = 0; i < kNumErrors; i++) {
- gpr_errs[i] = -1;
- fpr_errs[i] = -1;
- exc_errs[i] = -1;
- vec_errs[i] = -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] | fpr_errs[err_idx] | exc_errs[err_idx] |
- vec_errs[err_idx];
- case e_regSetGPR:
- return gpr_errs[err_idx];
- case e_regSetFPR:
- return fpr_errs[err_idx];
- case e_regSetEXC:
- return exc_errs[err_idx];
- case e_regSetVEC:
- return vec_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] = fpr_errs[err_idx] = exc_errs[err_idx] =
- vec_errs[err_idx] = err;
- return true;
-
- case e_regSetGPR:
- gpr_errs[err_idx] = err;
- return true;
-
- case e_regSetFPR:
- fpr_errs[err_idx] = err;
- return true;
-
- case e_regSetEXC:
- exc_errs[err_idx] = err;
- return true;
-
- case e_regSetVEC:
- vec_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 GetFPRState(bool force);
- kern_return_t GetEXCState(bool force);
- kern_return_t GetVECState(bool force);
-
- kern_return_t SetGPRState();
- kern_return_t SetFPRState();
- kern_return_t SetEXCState();
- kern_return_t SetVECState();
-
-protected:
- MachThread *m_thread;
- State m_state;
-};
-
-#endif // #if defined (__powerpc__) || defined (__ppc__) || defined (__ppc64__)
-#endif // #ifndef __DebugNubArchMachPPC_h__
diff --git a/tools/debugserver/source/MacOSX/stack_logging.h b/tools/debugserver/source/MacOSX/stack_logging.h
deleted file mode 100644
index 5209e38a08ea..000000000000
--- a/tools/debugserver/source/MacOSX/stack_logging.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (c) 1999-2007 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#ifndef malloc_history_test_stack_logging_h
-#define malloc_history_test_stack_logging_h
-
-#import <malloc/malloc.h>
-
-#define stack_logging_type_free 0
-#define stack_logging_type_generic \
- 1 /* anything that is not allocation/deallocation */
-#define stack_logging_type_alloc 2 /* malloc, realloc, etc... */
-#define stack_logging_type_dealloc 4 /* free, realloc, etc... */
-
-// Following flags are absorbed by stack_logging_log_stack()
-#define stack_logging_flag_zone 8 /* NSZoneMalloc, etc... */
-#define stack_logging_flag_calloc 16 /* multiply arguments to get the size */
-#define stack_logging_flag_object \
- 32 /* NSAllocateObject(Class, extraBytes, zone) */
-#define stack_logging_flag_cleared 64 /* for NewEmptyHandle */
-#define stack_logging_flag_handle 128 /* for Handle (de-)allocation routines \
- */
-#define stack_logging_flag_set_handle_size \
- 256 /* (Handle, newSize) treated specially */
-
-/* Macro used to disguise addresses so that leak finding can work */
-#define STACK_LOGGING_DISGUISE(address) \
- ((address) ^ 0x00005555) /* nicely idempotent */
-
-extern "C" int
- stack_logging_enable_logging; /* when clear, no logging takes place */
-extern "C" int stack_logging_dontcompact; /* default is to compact; when set
- does not compact alloc/free logs;
- useful for tracing history */
-
-extern "C" void stack_logging_log_stack(unsigned type, unsigned arg1,
- unsigned arg2, unsigned arg3,
- unsigned result,
- unsigned num_hot_to_skip);
-/* This is the old log-to-memory logger, which is now deprecated. It remains
- * for compatibility with performance tools that haven't been updated to
- * disk_stack_logging_log_stack() yet. */
-
-extern "C" void
-__disk_stack_logging_log_stack(uint32_t type_flags, uintptr_t zone_ptr,
- uintptr_t size, uintptr_t ptr_arg,
- uintptr_t return_val, uint32_t num_hot_to_skip);
-/* Fits as the malloc_logger; logs malloc/free/realloc events and can log custom
- * events if called directly */
-
-/* 64-bit-aware stack log access. */
-typedef struct {
- uint32_t type_flags;
- uint64_t stack_identifier;
- uint64_t argument;
- mach_vm_address_t address;
-} mach_stack_logging_record_t;
-
-extern "C" kern_return_t
-__mach_stack_logging_get_frames(task_t task, mach_vm_address_t address,
- mach_vm_address_t *stack_frames_buffer,
- uint32_t max_stack_frames, uint32_t *count);
-/* Gets the last allocation record (malloc, realloc, or free) about address */
-
-extern "C" kern_return_t __mach_stack_logging_enumerate_records(
- task_t task, mach_vm_address_t address,
- void enumerator(mach_stack_logging_record_t, void *), void *context);
-/* Applies enumerator to all records involving address sending context as
- * enumerator's second parameter; if !address, applies enumerator to all records
- */
-
-extern "C" kern_return_t __mach_stack_logging_frames_for_uniqued_stack(
- task_t task, uint64_t stack_identifier,
- mach_vm_address_t *stack_frames_buffer, uint32_t max_stack_frames,
- uint32_t *count);
-/* Given a uniqued_stack fills stack_frames_buffer */
-
-#pragma mark -
-#pragma mark Legacy
-
-/* The following is the old 32-bit-only, in-process-memory stack logging. This
- * is deprecated and clients should move to the above 64-bit-aware disk stack
- * logging SPI. */
-
-typedef struct {
- unsigned type;
- unsigned uniqued_stack;
- unsigned argument;
- unsigned address; /* disguised, to avoid confusing leaks */
-} stack_logging_record_t;
-
-typedef struct {
- unsigned overall_num_bytes;
- unsigned num_records;
- unsigned lock; /* 0 means OK to lock; used for inter-process locking */
- unsigned *uniquing_table; /* allocated using vm_allocate() */
- /* hashtable organized as (PC, uniqued parent)
- Only the second half of the table is active
- To enable us to grow dynamically */
- unsigned uniquing_table_num_pages; /* number of pages of the table */
- unsigned extra_retain_count; /* not used by stack_logging_log_stack */
- unsigned filler[2]; /* align to cache lines for better performance */
- stack_logging_record_t records[0]; /* records follow here */
-} stack_logging_record_list_t;
-
-extern "C" stack_logging_record_list_t *stack_logging_the_record_list;
-/* This is the global variable containing all logs */
-
-extern "C" kern_return_t
-stack_logging_get_frames(task_t task, memory_reader_t reader,
- vm_address_t address,
- vm_address_t *stack_frames_buffer,
- unsigned max_stack_frames, unsigned *num_frames);
-/* Gets the last record in stack_logging_the_record_list about address */
-
-#define STACK_LOGGING_ENUMERATION_PROVIDED \
- 1 // temporary to avoid dependencies between projects
-
-extern "C" kern_return_t stack_logging_enumerate_records(
- task_t task, memory_reader_t reader, vm_address_t address,
- void enumerator(stack_logging_record_t, void *), void *context);
-/* Gets all the records about address;
- If !address, gets all records */
-
-extern "C" kern_return_t stack_logging_frames_for_uniqued_stack(
- task_t task, memory_reader_t reader, unsigned uniqued_stack,
- vm_address_t *stack_frames_buffer, unsigned max_stack_frames,
- unsigned *num_frames);
-/* Given a uniqued_stack fills stack_frames_buffer */
-
-extern "C" void thread_stack_pcs(vm_address_t *buffer, unsigned max,
- unsigned *num);
-/* Convenience to fill buffer with the PCs of the frames, starting with the hot
- frames;
- num: returned number of frames
- */
-
-#endif
diff --git a/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp b/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
deleted file mode 100644
index 2f8ed32fa5d0..000000000000
--- a/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
+++ /dev/null
@@ -1,2890 +0,0 @@
-//===-- DNBArchImplX86_64.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(__i386__) || defined(__x86_64__)
-
-#include <sys/cdefs.h>
-#include <sys/sysctl.h>
-#include <sys/types.h>
-
-#include "DNBLog.h"
-#include "MacOSX/x86_64/DNBArchImplX86_64.h"
-#include "MachProcess.h"
-#include "MachThread.h"
-#include <mach/mach.h>
-#include <stdlib.h>
-
-#if defined(LLDB_DEBUGSERVER_RELEASE) || defined(LLDB_DEBUGSERVER_DEBUG)
-enum debugState { debugStateUnknown, debugStateOff, debugStateOn };
-
-static debugState sFPUDebugState = debugStateUnknown;
-static debugState sAVXForceState = debugStateUnknown;
-
-static bool DebugFPURegs() {
- if (sFPUDebugState == debugStateUnknown) {
- if (getenv("DNB_DEBUG_FPU_REGS"))
- sFPUDebugState = debugStateOn;
- else
- sFPUDebugState = debugStateOff;
- }
-
- return (sFPUDebugState == debugStateOn);
-}
-
-static bool ForceAVXRegs() {
- if (sFPUDebugState == debugStateUnknown) {
- if (getenv("DNB_DEBUG_X86_FORCE_AVX_REGS"))
- sAVXForceState = debugStateOn;
- else
- sAVXForceState = debugStateOff;
- }
-
- return (sAVXForceState == debugStateOn);
-}
-
-#define DEBUG_FPU_REGS (DebugFPURegs())
-#define FORCE_AVX_REGS (ForceAVXRegs())
-#else
-#define DEBUG_FPU_REGS (0)
-#define FORCE_AVX_REGS (0)
-#endif
-
-bool DetectHardwareFeature(const char *feature) {
- int answer = 0;
- size_t answer_size = sizeof(answer);
- int error = ::sysctlbyname(feature, &answer, &answer_size, NULL, 0);
- return error == 0 && answer != 0;
-}
-
-enum AVXPresence { eAVXUnknown = -1, eAVXNotPresent = 0, eAVXPresent = 1 };
-
-bool LogAVXAndReturn(AVXPresence has_avx, int err, const char * os_ver) {
- DNBLogThreadedIf(LOG_THREAD,
- "CPUHasAVX(): g_has_avx = %i (err = %i, os_ver = %s)",
- has_avx, err, os_ver);
- return (has_avx == eAVXPresent);
-}
-
-extern "C" bool CPUHasAVX() {
- static AVXPresence g_has_avx = eAVXUnknown;
- if (g_has_avx != eAVXUnknown)
- return LogAVXAndReturn(g_has_avx, 0, "");
-
- g_has_avx = eAVXNotPresent;
-
- // OS X 10.7.3 and earlier have a bug in thread_get_state that truncated the
- // size of the return. To work around this we have to disable AVX debugging
- // on hosts prior to 10.7.3 (<rdar://problem/10122874>).
- int mib[2];
- char buffer[1024];
- size_t length = sizeof(buffer);
- mib[0] = CTL_KERN;
- mib[1] = KERN_OSVERSION;
-
- // KERN_OSVERSION returns the build number which is a number signifying the
- // major version, a capitol letter signifying the minor version, and numbers
- // signifying the build (ex: on 10.12.3, the returned value is 16D32).
- int err = ::sysctl(mib, 2, &buffer, &length, NULL, 0);
- if (err != 0)
- return LogAVXAndReturn(g_has_avx, err, "");
-
- size_t first_letter = 0;
- for (; first_letter < length; ++first_letter) {
- // This is looking for the first uppercase letter
- if (isupper(buffer[first_letter]))
- break;
- }
- char letter = buffer[first_letter];
- buffer[first_letter] = '\0';
- auto major_ver = strtoull(buffer, NULL, 0);
- buffer[first_letter] = letter;
-
- // In this check we're looking to see that our major and minor version numer
- // was >= 11E, which is the 10.7.4 release.
- if (major_ver < 11 || (major_ver == 11 && letter < 'E'))
- return LogAVXAndReturn(g_has_avx, err, buffer);
- if (DetectHardwareFeature("hw.optional.avx1_0"))
- g_has_avx = eAVXPresent;
-
- return LogAVXAndReturn(g_has_avx, err, buffer);
-}
-
-extern "C" bool CPUHasAVX512f() {
- static AVXPresence g_has_avx512f = eAVXUnknown;
- if (g_has_avx512f != eAVXUnknown)
- return g_has_avx512f == eAVXPresent;
-
- g_has_avx512f = DetectHardwareFeature("hw.optional.avx512f") ? eAVXPresent
- : eAVXNotPresent;
-
- return (g_has_avx512f == eAVXPresent);
-}
-
-uint64_t DNBArchImplX86_64::GetPC(uint64_t failValue) {
- // Get program counter
- if (GetGPRState(false) == KERN_SUCCESS)
- return m_state.context.gpr.__rip;
- return failValue;
-}
-
-kern_return_t DNBArchImplX86_64::SetPC(uint64_t value) {
- // Get program counter
- kern_return_t err = GetGPRState(false);
- if (err == KERN_SUCCESS) {
- m_state.context.gpr.__rip = value;
- err = SetGPRState();
- }
- return err == KERN_SUCCESS;
-}
-
-uint64_t DNBArchImplX86_64::GetSP(uint64_t failValue) {
- // Get stack pointer
- if (GetGPRState(false) == KERN_SUCCESS)
- return m_state.context.gpr.__rsp;
- return failValue;
-}
-
-// Uncomment the value below to verify the values in the debugger.
-//#define DEBUG_GPR_VALUES 1 // DO NOT CHECK IN WITH THIS DEFINE ENABLED
-
-kern_return_t DNBArchImplX86_64::GetGPRState(bool force) {
- if (force || m_state.GetError(e_regSetGPR, Read)) {
-#if DEBUG_GPR_VALUES
- m_state.context.gpr.__rax = ('a' << 8) + 'x';
- m_state.context.gpr.__rbx = ('b' << 8) + 'x';
- m_state.context.gpr.__rcx = ('c' << 8) + 'x';
- m_state.context.gpr.__rdx = ('d' << 8) + 'x';
- m_state.context.gpr.__rdi = ('d' << 8) + 'i';
- m_state.context.gpr.__rsi = ('s' << 8) + 'i';
- m_state.context.gpr.__rbp = ('b' << 8) + 'p';
- m_state.context.gpr.__rsp = ('s' << 8) + 'p';
- m_state.context.gpr.__r8 = ('r' << 8) + '8';
- m_state.context.gpr.__r9 = ('r' << 8) + '9';
- m_state.context.gpr.__r10 = ('r' << 8) + 'a';
- m_state.context.gpr.__r11 = ('r' << 8) + 'b';
- m_state.context.gpr.__r12 = ('r' << 8) + 'c';
- m_state.context.gpr.__r13 = ('r' << 8) + 'd';
- m_state.context.gpr.__r14 = ('r' << 8) + 'e';
- m_state.context.gpr.__r15 = ('r' << 8) + 'f';
- m_state.context.gpr.__rip = ('i' << 8) + 'p';
- m_state.context.gpr.__rflags = ('f' << 8) + 'l';
- m_state.context.gpr.__cs = ('c' << 8) + 's';
- m_state.context.gpr.__fs = ('f' << 8) + 's';
- m_state.context.gpr.__gs = ('g' << 8) + 's';
- m_state.SetError(e_regSetGPR, Read, 0);
-#else
- mach_msg_type_number_t count = e_regSetWordSizeGPR;
- m_state.SetError(
- e_regSetGPR, Read,
- ::thread_get_state(m_thread->MachPortNumber(), __x86_64_THREAD_STATE,
- (thread_state_t)&m_state.context.gpr, &count));
- DNBLogThreadedIf(
- LOG_THREAD,
- "::thread_get_state (0x%4.4x, %u, &gpr, %u) => 0x%8.8x"
- "\n\trax = %16.16llx rbx = %16.16llx rcx = %16.16llx rdx = %16.16llx"
- "\n\trdi = %16.16llx rsi = %16.16llx rbp = %16.16llx rsp = %16.16llx"
- "\n\t r8 = %16.16llx r9 = %16.16llx r10 = %16.16llx r11 = %16.16llx"
- "\n\tr12 = %16.16llx r13 = %16.16llx r14 = %16.16llx r15 = %16.16llx"
- "\n\trip = %16.16llx"
- "\n\tflg = %16.16llx cs = %16.16llx fs = %16.16llx gs = %16.16llx",
- m_thread->MachPortNumber(), x86_THREAD_STATE64,
- x86_THREAD_STATE64_COUNT, m_state.GetError(e_regSetGPR, Read),
- m_state.context.gpr.__rax, m_state.context.gpr.__rbx,
- m_state.context.gpr.__rcx, m_state.context.gpr.__rdx,
- m_state.context.gpr.__rdi, m_state.context.gpr.__rsi,
- m_state.context.gpr.__rbp, m_state.context.gpr.__rsp,
- m_state.context.gpr.__r8, m_state.context.gpr.__r9,
- m_state.context.gpr.__r10, m_state.context.gpr.__r11,
- m_state.context.gpr.__r12, m_state.context.gpr.__r13,
- m_state.context.gpr.__r14, m_state.context.gpr.__r15,
- m_state.context.gpr.__rip, m_state.context.gpr.__rflags,
- m_state.context.gpr.__cs, m_state.context.gpr.__fs,
- m_state.context.gpr.__gs);
-
-// DNBLogThreadedIf (LOG_THREAD, "thread_get_state(0x%4.4x, %u, &gpr, %u)
-// => 0x%8.8x"
-// "\n\trax = %16.16llx"
-// "\n\trbx = %16.16llx"
-// "\n\trcx = %16.16llx"
-// "\n\trdx = %16.16llx"
-// "\n\trdi = %16.16llx"
-// "\n\trsi = %16.16llx"
-// "\n\trbp = %16.16llx"
-// "\n\trsp = %16.16llx"
-// "\n\t r8 = %16.16llx"
-// "\n\t r9 = %16.16llx"
-// "\n\tr10 = %16.16llx"
-// "\n\tr11 = %16.16llx"
-// "\n\tr12 = %16.16llx"
-// "\n\tr13 = %16.16llx"
-// "\n\tr14 = %16.16llx"
-// "\n\tr15 = %16.16llx"
-// "\n\trip = %16.16llx"
-// "\n\tflg = %16.16llx"
-// "\n\t cs = %16.16llx"
-// "\n\t fs = %16.16llx"
-// "\n\t gs = %16.16llx",
-// m_thread->MachPortNumber(),
-// x86_THREAD_STATE64,
-// x86_THREAD_STATE64_COUNT,
-// m_state.GetError(e_regSetGPR, Read),
-// m_state.context.gpr.__rax,
-// m_state.context.gpr.__rbx,
-// m_state.context.gpr.__rcx,
-// m_state.context.gpr.__rdx,
-// m_state.context.gpr.__rdi,
-// m_state.context.gpr.__rsi,
-// m_state.context.gpr.__rbp,
-// m_state.context.gpr.__rsp,
-// m_state.context.gpr.__r8,
-// m_state.context.gpr.__r9,
-// m_state.context.gpr.__r10,
-// m_state.context.gpr.__r11,
-// m_state.context.gpr.__r12,
-// m_state.context.gpr.__r13,
-// m_state.context.gpr.__r14,
-// m_state.context.gpr.__r15,
-// m_state.context.gpr.__rip,
-// m_state.context.gpr.__rflags,
-// m_state.context.gpr.__cs,
-// m_state.context.gpr.__fs,
-// m_state.context.gpr.__gs);
-#endif
- }
- return m_state.GetError(e_regSetGPR, Read);
-}
-
-// Uncomment the value below to verify the values in the debugger.
-//#define DEBUG_FPU_REGS 1 // DO NOT CHECK IN WITH THIS DEFINE ENABLED
-
-kern_return_t DNBArchImplX86_64::GetFPUState(bool force) {
- if (force || m_state.GetError(e_regSetFPU, Read)) {
- if (DEBUG_FPU_REGS) {
- m_state.context.fpu.no_avx.__fpu_reserved[0] = -1;
- m_state.context.fpu.no_avx.__fpu_reserved[1] = -1;
- *(uint16_t *)&(m_state.context.fpu.no_avx.__fpu_fcw) = 0x1234;
- *(uint16_t *)&(m_state.context.fpu.no_avx.__fpu_fsw) = 0x5678;
- m_state.context.fpu.no_avx.__fpu_ftw = 1;
- m_state.context.fpu.no_avx.__fpu_rsrv1 = UINT8_MAX;
- m_state.context.fpu.no_avx.__fpu_fop = 2;
- m_state.context.fpu.no_avx.__fpu_ip = 3;
- m_state.context.fpu.no_avx.__fpu_cs = 4;
- m_state.context.fpu.no_avx.__fpu_rsrv2 = 5;
- m_state.context.fpu.no_avx.__fpu_dp = 6;
- m_state.context.fpu.no_avx.__fpu_ds = 7;
- m_state.context.fpu.no_avx.__fpu_rsrv3 = UINT16_MAX;
- m_state.context.fpu.no_avx.__fpu_mxcsr = 8;
- m_state.context.fpu.no_avx.__fpu_mxcsrmask = 9;
- for (int i = 0; i < 16; ++i) {
- if (i < 10) {
- m_state.context.fpu.no_avx.__fpu_stmm0.__mmst_reg[i] = 'a';
- m_state.context.fpu.no_avx.__fpu_stmm1.__mmst_reg[i] = 'b';
- m_state.context.fpu.no_avx.__fpu_stmm2.__mmst_reg[i] = 'c';
- m_state.context.fpu.no_avx.__fpu_stmm3.__mmst_reg[i] = 'd';
- m_state.context.fpu.no_avx.__fpu_stmm4.__mmst_reg[i] = 'e';
- m_state.context.fpu.no_avx.__fpu_stmm5.__mmst_reg[i] = 'f';
- m_state.context.fpu.no_avx.__fpu_stmm6.__mmst_reg[i] = 'g';
- m_state.context.fpu.no_avx.__fpu_stmm7.__mmst_reg[i] = 'h';
- } else {
- m_state.context.fpu.no_avx.__fpu_stmm0.__mmst_reg[i] = INT8_MIN;
- m_state.context.fpu.no_avx.__fpu_stmm1.__mmst_reg[i] = INT8_MIN;
- m_state.context.fpu.no_avx.__fpu_stmm2.__mmst_reg[i] = INT8_MIN;
- m_state.context.fpu.no_avx.__fpu_stmm3.__mmst_reg[i] = INT8_MIN;
- m_state.context.fpu.no_avx.__fpu_stmm4.__mmst_reg[i] = INT8_MIN;
- m_state.context.fpu.no_avx.__fpu_stmm5.__mmst_reg[i] = INT8_MIN;
- m_state.context.fpu.no_avx.__fpu_stmm6.__mmst_reg[i] = INT8_MIN;
- m_state.context.fpu.no_avx.__fpu_stmm7.__mmst_reg[i] = INT8_MIN;
- }
-
- m_state.context.fpu.no_avx.__fpu_xmm0.__xmm_reg[i] = '0';
- m_state.context.fpu.no_avx.__fpu_xmm1.__xmm_reg[i] = '1';
- m_state.context.fpu.no_avx.__fpu_xmm2.__xmm_reg[i] = '2';
- m_state.context.fpu.no_avx.__fpu_xmm3.__xmm_reg[i] = '3';
- m_state.context.fpu.no_avx.__fpu_xmm4.__xmm_reg[i] = '4';
- m_state.context.fpu.no_avx.__fpu_xmm5.__xmm_reg[i] = '5';
- m_state.context.fpu.no_avx.__fpu_xmm6.__xmm_reg[i] = '6';
- m_state.context.fpu.no_avx.__fpu_xmm7.__xmm_reg[i] = '7';
- m_state.context.fpu.no_avx.__fpu_xmm8.__xmm_reg[i] = '8';
- m_state.context.fpu.no_avx.__fpu_xmm9.__xmm_reg[i] = '9';
- m_state.context.fpu.no_avx.__fpu_xmm10.__xmm_reg[i] = 'A';
- m_state.context.fpu.no_avx.__fpu_xmm11.__xmm_reg[i] = 'B';
- m_state.context.fpu.no_avx.__fpu_xmm12.__xmm_reg[i] = 'C';
- m_state.context.fpu.no_avx.__fpu_xmm13.__xmm_reg[i] = 'D';
- m_state.context.fpu.no_avx.__fpu_xmm14.__xmm_reg[i] = 'E';
- m_state.context.fpu.no_avx.__fpu_xmm15.__xmm_reg[i] = 'F';
- }
- for (int i = 0; i < sizeof(m_state.context.fpu.no_avx.__fpu_rsrv4); ++i)
- m_state.context.fpu.no_avx.__fpu_rsrv4[i] = INT8_MIN;
- m_state.context.fpu.no_avx.__fpu_reserved1 = -1;
-
- if (CPUHasAVX() || FORCE_AVX_REGS) {
- for (int i = 0; i < 16; ++i) {
- m_state.context.fpu.avx.__fpu_ymmh0.__xmm_reg[i] = '0' + i;
- m_state.context.fpu.avx.__fpu_ymmh1.__xmm_reg[i] = '1' + i;
- m_state.context.fpu.avx.__fpu_ymmh2.__xmm_reg[i] = '2' + i;
- m_state.context.fpu.avx.__fpu_ymmh3.__xmm_reg[i] = '3' + i;
- m_state.context.fpu.avx.__fpu_ymmh4.__xmm_reg[i] = '4' + i;
- m_state.context.fpu.avx.__fpu_ymmh5.__xmm_reg[i] = '5' + i;
- m_state.context.fpu.avx.__fpu_ymmh6.__xmm_reg[i] = '6' + i;
- m_state.context.fpu.avx.__fpu_ymmh7.__xmm_reg[i] = '7' + i;
- m_state.context.fpu.avx.__fpu_ymmh8.__xmm_reg[i] = '8' + i;
- m_state.context.fpu.avx.__fpu_ymmh9.__xmm_reg[i] = '9' + i;
- m_state.context.fpu.avx.__fpu_ymmh10.__xmm_reg[i] = 'A' + i;
- m_state.context.fpu.avx.__fpu_ymmh11.__xmm_reg[i] = 'B' + i;
- m_state.context.fpu.avx.__fpu_ymmh12.__xmm_reg[i] = 'C' + i;
- m_state.context.fpu.avx.__fpu_ymmh13.__xmm_reg[i] = 'D' + i;
- m_state.context.fpu.avx.__fpu_ymmh14.__xmm_reg[i] = 'E' + i;
- m_state.context.fpu.avx.__fpu_ymmh15.__xmm_reg[i] = 'F' + i;
- }
- for (int i = 0; i < sizeof(m_state.context.fpu.avx.__avx_reserved1); ++i)
- m_state.context.fpu.avx.__avx_reserved1[i] = INT8_MIN;
- }
- if (CPUHasAVX512f() || FORCE_AVX_REGS) {
- for (int i = 0; i < 8; ++i) {
- m_state.context.fpu.avx512f.__fpu_k0.__opmask_reg[i] = '0';
- m_state.context.fpu.avx512f.__fpu_k1.__opmask_reg[i] = '1';
- m_state.context.fpu.avx512f.__fpu_k2.__opmask_reg[i] = '2';
- m_state.context.fpu.avx512f.__fpu_k3.__opmask_reg[i] = '3';
- m_state.context.fpu.avx512f.__fpu_k4.__opmask_reg[i] = '4';
- m_state.context.fpu.avx512f.__fpu_k5.__opmask_reg[i] = '5';
- m_state.context.fpu.avx512f.__fpu_k6.__opmask_reg[i] = '6';
- m_state.context.fpu.avx512f.__fpu_k7.__opmask_reg[i] = '7';
- }
-
- for (int i = 0; i < 32; ++i) {
- m_state.context.fpu.avx512f.__fpu_zmmh0.__ymm_reg[i] = '0';
- m_state.context.fpu.avx512f.__fpu_zmmh1.__ymm_reg[i] = '1';
- m_state.context.fpu.avx512f.__fpu_zmmh2.__ymm_reg[i] = '2';
- m_state.context.fpu.avx512f.__fpu_zmmh3.__ymm_reg[i] = '3';
- m_state.context.fpu.avx512f.__fpu_zmmh4.__ymm_reg[i] = '4';
- m_state.context.fpu.avx512f.__fpu_zmmh5.__ymm_reg[i] = '5';
- m_state.context.fpu.avx512f.__fpu_zmmh6.__ymm_reg[i] = '6';
- m_state.context.fpu.avx512f.__fpu_zmmh7.__ymm_reg[i] = '7';
- m_state.context.fpu.avx512f.__fpu_zmmh8.__ymm_reg[i] = '8';
- m_state.context.fpu.avx512f.__fpu_zmmh9.__ymm_reg[i] = '9';
- m_state.context.fpu.avx512f.__fpu_zmmh10.__ymm_reg[i] = 'A';
- m_state.context.fpu.avx512f.__fpu_zmmh11.__ymm_reg[i] = 'B';
- m_state.context.fpu.avx512f.__fpu_zmmh12.__ymm_reg[i] = 'C';
- m_state.context.fpu.avx512f.__fpu_zmmh13.__ymm_reg[i] = 'D';
- m_state.context.fpu.avx512f.__fpu_zmmh14.__ymm_reg[i] = 'E';
- m_state.context.fpu.avx512f.__fpu_zmmh15.__ymm_reg[i] = 'F';
- }
- for (int i = 0; i < 64; ++i) {
- m_state.context.fpu.avx512f.__fpu_zmm16.__zmm_reg[i] = 'G';
- m_state.context.fpu.avx512f.__fpu_zmm17.__zmm_reg[i] = 'H';
- m_state.context.fpu.avx512f.__fpu_zmm18.__zmm_reg[i] = 'I';
- m_state.context.fpu.avx512f.__fpu_zmm19.__zmm_reg[i] = 'J';
- m_state.context.fpu.avx512f.__fpu_zmm20.__zmm_reg[i] = 'K';
- m_state.context.fpu.avx512f.__fpu_zmm21.__zmm_reg[i] = 'L';
- m_state.context.fpu.avx512f.__fpu_zmm22.__zmm_reg[i] = 'M';
- m_state.context.fpu.avx512f.__fpu_zmm23.__zmm_reg[i] = 'N';
- m_state.context.fpu.avx512f.__fpu_zmm24.__zmm_reg[i] = 'O';
- m_state.context.fpu.avx512f.__fpu_zmm25.__zmm_reg[i] = 'P';
- m_state.context.fpu.avx512f.__fpu_zmm26.__zmm_reg[i] = 'Q';
- m_state.context.fpu.avx512f.__fpu_zmm27.__zmm_reg[i] = 'R';
- m_state.context.fpu.avx512f.__fpu_zmm28.__zmm_reg[i] = 'S';
- m_state.context.fpu.avx512f.__fpu_zmm29.__zmm_reg[i] = 'T';
- m_state.context.fpu.avx512f.__fpu_zmm30.__zmm_reg[i] = 'U';
- m_state.context.fpu.avx512f.__fpu_zmm31.__zmm_reg[i] = 'V';
- }
- }
- m_state.SetError(e_regSetFPU, Read, 0);
- } else {
- mach_msg_type_number_t count = e_regSetWordSizeFPU;
- int flavor = __x86_64_FLOAT_STATE;
- // On a machine with the AVX512 register set, a process only gets a
- // full AVX512 register context after it uses the AVX512 registers;
- // if the process has not yet triggered this change, trying to fetch
- // the AVX512 registers will fail. Fall through to fetching the AVX
- // registers.
- if (CPUHasAVX512f() || FORCE_AVX_REGS) {
- count = e_regSetWordSizeAVX512f;
- flavor = __x86_64_AVX512F_STATE;
- m_state.SetError(e_regSetFPU, Read,
- ::thread_get_state(m_thread->MachPortNumber(), flavor,
- (thread_state_t)&m_state.context.fpu,
- &count));
- DNBLogThreadedIf(LOG_THREAD,
- "::thread_get_state (0x%4.4x, %u, &fpu, %u => 0x%8.8x",
- m_thread->MachPortNumber(), flavor, (uint32_t)count,
- m_state.GetError(e_regSetFPU, Read));
-
- if (m_state.GetError(e_regSetFPU, Read) == KERN_SUCCESS)
- return m_state.GetError(e_regSetFPU, Read);
- else
- DNBLogThreadedIf(LOG_THREAD,
- "::thread_get_state attempted fetch of avx512 fpu regctx failed, will try fetching avx");
- }
- if (CPUHasAVX() || FORCE_AVX_REGS) {
- count = e_regSetWordSizeAVX;
- flavor = __x86_64_AVX_STATE;
- }
- m_state.SetError(e_regSetFPU, Read,
- ::thread_get_state(m_thread->MachPortNumber(), flavor,
- (thread_state_t)&m_state.context.fpu,
- &count));
- DNBLogThreadedIf(LOG_THREAD,
- "::thread_get_state (0x%4.4x, %u, &fpu, %u => 0x%8.8x",
- m_thread->MachPortNumber(), flavor, (uint32_t)count,
- m_state.GetError(e_regSetFPU, Read));
- }
- }
- return m_state.GetError(e_regSetFPU, Read);
-}
-
-kern_return_t DNBArchImplX86_64::GetEXCState(bool force) {
- if (force || m_state.GetError(e_regSetEXC, Read)) {
- mach_msg_type_number_t count = e_regSetWordSizeEXC;
- m_state.SetError(
- e_regSetEXC, Read,
- ::thread_get_state(m_thread->MachPortNumber(), __x86_64_EXCEPTION_STATE,
- (thread_state_t)&m_state.context.exc, &count));
- }
- return m_state.GetError(e_regSetEXC, Read);
-}
-
-kern_return_t DNBArchImplX86_64::SetGPRState() {
- 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());
-
- m_state.SetError(e_regSetGPR, Write,
- ::thread_set_state(m_thread->MachPortNumber(),
- __x86_64_THREAD_STATE,
- (thread_state_t)&m_state.context.gpr,
- e_regSetWordSizeGPR));
- DNBLogThreadedIf(
- LOG_THREAD,
- "::thread_set_state (0x%4.4x, %u, &gpr, %u) => 0x%8.8x"
- "\n\trax = %16.16llx rbx = %16.16llx rcx = %16.16llx rdx = %16.16llx"
- "\n\trdi = %16.16llx rsi = %16.16llx rbp = %16.16llx rsp = %16.16llx"
- "\n\t r8 = %16.16llx r9 = %16.16llx r10 = %16.16llx r11 = %16.16llx"
- "\n\tr12 = %16.16llx r13 = %16.16llx r14 = %16.16llx r15 = %16.16llx"
- "\n\trip = %16.16llx"
- "\n\tflg = %16.16llx cs = %16.16llx fs = %16.16llx gs = %16.16llx",
- m_thread->MachPortNumber(), __x86_64_THREAD_STATE, e_regSetWordSizeGPR,
- m_state.GetError(e_regSetGPR, Write), m_state.context.gpr.__rax,
- m_state.context.gpr.__rbx, m_state.context.gpr.__rcx,
- m_state.context.gpr.__rdx, m_state.context.gpr.__rdi,
- m_state.context.gpr.__rsi, m_state.context.gpr.__rbp,
- m_state.context.gpr.__rsp, m_state.context.gpr.__r8,
- m_state.context.gpr.__r9, m_state.context.gpr.__r10,
- m_state.context.gpr.__r11, m_state.context.gpr.__r12,
- m_state.context.gpr.__r13, m_state.context.gpr.__r14,
- m_state.context.gpr.__r15, m_state.context.gpr.__rip,
- m_state.context.gpr.__rflags, m_state.context.gpr.__cs,
- m_state.context.gpr.__fs, m_state.context.gpr.__gs);
- return m_state.GetError(e_regSetGPR, Write);
-}
-
-kern_return_t DNBArchImplX86_64::SetFPUState() {
- if (DEBUG_FPU_REGS) {
- m_state.SetError(e_regSetFPU, Write, 0);
- return m_state.GetError(e_regSetFPU, Write);
- } else {
- int flavor = __x86_64_FLOAT_STATE;
- mach_msg_type_number_t count = e_regSetWordSizeFPU;
- if (CPUHasAVX512f() || FORCE_AVX_REGS) {
- count = e_regSetWordSizeAVX512f;
- flavor = __x86_64_AVX512F_STATE;
- m_state.SetError(
- e_regSetFPU, Write,
- ::thread_set_state(m_thread->MachPortNumber(), flavor,
- (thread_state_t)&m_state.context.fpu, count));
- if (m_state.GetError(e_regSetFPU, Write) == KERN_SUCCESS)
- return m_state.GetError(e_regSetFPU, Write);
- else
- DNBLogThreadedIf(LOG_THREAD,
- "::thread_get_state attempted save of avx512 fpu regctx failed, will try saving avx regctx");
- }
-
- if (CPUHasAVX() || FORCE_AVX_REGS) {
- flavor = __x86_64_AVX_STATE;
- count = e_regSetWordSizeAVX;
- }
- m_state.SetError(
- e_regSetFPU, Write,
- ::thread_set_state(m_thread->MachPortNumber(), flavor,
- (thread_state_t)&m_state.context.fpu, count));
- return m_state.GetError(e_regSetFPU, Write);
- }
-}
-
-kern_return_t DNBArchImplX86_64::SetEXCState() {
- m_state.SetError(e_regSetEXC, Write,
- ::thread_set_state(m_thread->MachPortNumber(),
- __x86_64_EXCEPTION_STATE,
- (thread_state_t)&m_state.context.exc,
- e_regSetWordSizeEXC));
- return m_state.GetError(e_regSetEXC, Write);
-}
-
-kern_return_t DNBArchImplX86_64::GetDBGState(bool force) {
- if (force || m_state.GetError(e_regSetDBG, Read)) {
- mach_msg_type_number_t count = e_regSetWordSizeDBG;
- m_state.SetError(
- e_regSetDBG, Read,
- ::thread_get_state(m_thread->MachPortNumber(), __x86_64_DEBUG_STATE,
- (thread_state_t)&m_state.context.dbg, &count));
- }
- return m_state.GetError(e_regSetDBG, Read);
-}
-
-kern_return_t DNBArchImplX86_64::SetDBGState(bool also_set_on_task) {
- m_state.SetError(e_regSetDBG, Write,
- ::thread_set_state(m_thread->MachPortNumber(),
- __x86_64_DEBUG_STATE,
- (thread_state_t)&m_state.context.dbg,
- e_regSetWordSizeDBG));
- if (also_set_on_task) {
- kern_return_t kret = ::task_set_state(
- m_thread->Process()->Task().TaskPort(), __x86_64_DEBUG_STATE,
- (thread_state_t)&m_state.context.dbg, e_regSetWordSizeDBG);
- if (kret != KERN_SUCCESS)
- DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::SetDBGState failed "
- "to set debug control register state: "
- "0x%8.8x.",
- kret);
- }
- return m_state.GetError(e_regSetDBG, Write);
-}
-
-void DNBArchImplX86_64::ThreadWillResume() {
- // Do we need to step this thread? If so, let the mach thread tell us so.
- if (m_thread->IsStepping()) {
- // This is the primary thread, let the arch do anything it needs
- EnableHardwareSingleStep(true);
- }
-
- // Reset the debug status register, if necessary, before we resume.
- kern_return_t kret = GetDBGState(false);
- DNBLogThreadedIf(
- LOG_WATCHPOINTS,
- "DNBArchImplX86_64::ThreadWillResume() GetDBGState() => 0x%8.8x.", kret);
- if (kret != KERN_SUCCESS)
- return;
-
- DBG &debug_state = m_state.context.dbg;
- bool need_reset = false;
- uint32_t i, num = NumSupportedHardwareWatchpoints();
- for (i = 0; i < num; ++i)
- if (IsWatchpointHit(debug_state, i))
- need_reset = true;
-
- if (need_reset) {
- ClearWatchpointHits(debug_state);
- kret = SetDBGState(false);
- DNBLogThreadedIf(
- LOG_WATCHPOINTS,
- "DNBArchImplX86_64::ThreadWillResume() SetDBGState() => 0x%8.8x.",
- kret);
- }
-}
-
-bool DNBArchImplX86_64::ThreadDidStop() {
- bool success = true;
-
- m_state.InvalidateAllRegisterStates();
-
- // 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;
-}
-
-bool DNBArchImplX86_64::NotifyException(MachException::Data &exc) {
- switch (exc.exc_type) {
- case EXC_BAD_ACCESS:
- break;
- case EXC_BAD_INSTRUCTION:
- break;
- case EXC_ARITHMETIC:
- break;
- case EXC_EMULATION:
- break;
- case EXC_SOFTWARE:
- break;
- case EXC_BREAKPOINT:
- if (exc.exc_data.size() >= 2 && exc.exc_data[0] == 2) {
- // exc_code = EXC_I386_BPT
- //
- nub_addr_t pc = GetPC(INVALID_NUB_ADDRESS);
- if (pc != INVALID_NUB_ADDRESS && pc > 0) {
- pc -= 1;
- // Check for a breakpoint at one byte prior to the current PC value
- // since the PC will be just past the trap.
-
- DNBBreakpoint *bp =
- m_thread->Process()->Breakpoints().FindByAddress(pc);
- if (bp) {
- // Backup the PC for i386 since the trap was taken and the PC
- // is at the address following the single byte trap instruction.
- if (m_state.context.gpr.__rip > 0) {
- m_state.context.gpr.__rip = pc;
- // Write the new PC back out
- SetGPRState();
- }
- }
- return true;
- }
- } else if (exc.exc_data.size() >= 2 && exc.exc_data[0] == 1) {
- // exc_code = EXC_I386_SGL
- //
- // Check whether this corresponds to a watchpoint hit event.
- // If yes, set the exc_sub_code to the data break address.
- nub_addr_t addr = 0;
- uint32_t hw_index = GetHardwareWatchpointHit(addr);
- if (hw_index != INVALID_NUB_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;
- case EXC_SYSCALL:
- break;
- case EXC_MACH_SYSCALL:
- break;
- case EXC_RPC_ALERT:
- break;
- }
- return false;
-}
-
-uint32_t DNBArchImplX86_64::NumSupportedHardwareWatchpoints() {
- // Available debug address registers: dr0, dr1, dr2, dr3.
- return 4;
-}
-
-static uint32_t size_and_rw_bits(nub_size_t size, bool read, bool write) {
- uint32_t rw;
- if (read) {
- rw = 0x3; // READ or READ/WRITE
- } else if (write) {
- rw = 0x1; // WRITE
- } else {
- assert(0 && "read and write cannot both be false");
- }
-
- switch (size) {
- case 1:
- return rw;
- case 2:
- return (0x1 << 2) | rw;
- case 4:
- return (0x3 << 2) | rw;
- case 8:
- return (0x2 << 2) | rw;
- }
- assert(0 && "invalid size, must be one of 1, 2, 4, or 8");
- return 0;
-}
-void DNBArchImplX86_64::SetWatchpoint(DBG &debug_state, uint32_t hw_index,
- nub_addr_t addr, nub_size_t size,
- bool read, bool write) {
- // Set both dr7 (debug control register) and dri (debug address register).
-
- // dr7{7-0} encodes the local/gloabl enable bits:
- // global enable --. .-- local enable
- // | |
- // v v
- // dr0 -> bits{1-0}
- // dr1 -> bits{3-2}
- // dr2 -> bits{5-4}
- // dr3 -> bits{7-6}
- //
- // dr7{31-16} encodes the rw/len bits:
- // b_x+3, b_x+2, b_x+1, b_x
- // where bits{x+1, x} => rw
- // 0b00: execute, 0b01: write, 0b11: read-or-write, 0b10: io
- // read-or-write (unused)
- // and bits{x+3, x+2} => len
- // 0b00: 1-byte, 0b01: 2-byte, 0b11: 4-byte, 0b10: 8-byte
- //
- // dr0 -> bits{19-16}
- // dr1 -> bits{23-20}
- // dr2 -> bits{27-24}
- // dr3 -> bits{31-28}
- debug_state.__dr7 |=
- (1 << (2 * hw_index) |
- size_and_rw_bits(size, read, write) << (16 + 4 * hw_index));
- switch (hw_index) {
- case 0:
- debug_state.__dr0 = addr;
- break;
- case 1:
- debug_state.__dr1 = addr;
- break;
- case 2:
- debug_state.__dr2 = addr;
- break;
- case 3:
- debug_state.__dr3 = addr;
- break;
- default:
- assert(0 &&
- "invalid hardware register index, must be one of 0, 1, 2, or 3");
- }
- return;
-}
-
-void DNBArchImplX86_64::ClearWatchpoint(DBG &debug_state, uint32_t hw_index) {
- debug_state.__dr7 &= ~(3 << (2 * hw_index));
- switch (hw_index) {
- case 0:
- debug_state.__dr0 = 0;
- break;
- case 1:
- debug_state.__dr1 = 0;
- break;
- case 2:
- debug_state.__dr2 = 0;
- break;
- case 3:
- debug_state.__dr3 = 0;
- break;
- default:
- assert(0 &&
- "invalid hardware register index, must be one of 0, 1, 2, or 3");
- }
- return;
-}
-
-bool DNBArchImplX86_64::IsWatchpointVacant(const DBG &debug_state,
- uint32_t hw_index) {
- // Check dr7 (debug control register) for local/global enable bits:
- // global enable --. .-- local enable
- // | |
- // v v
- // dr0 -> bits{1-0}
- // dr1 -> bits{3-2}
- // dr2 -> bits{5-4}
- // dr3 -> bits{7-6}
- return (debug_state.__dr7 & (3 << (2 * hw_index))) == 0;
-}
-
-// Resets local copy of debug status register to wait for the next debug
-// exception.
-void DNBArchImplX86_64::ClearWatchpointHits(DBG &debug_state) {
- // See also IsWatchpointHit().
- debug_state.__dr6 = 0;
- return;
-}
-
-bool DNBArchImplX86_64::IsWatchpointHit(const DBG &debug_state,
- uint32_t hw_index) {
- // Check dr6 (debug status register) whether a watchpoint hits:
- // is watchpoint hit?
- // |
- // v
- // dr0 -> bits{0}
- // dr1 -> bits{1}
- // dr2 -> bits{2}
- // dr3 -> bits{3}
- return (debug_state.__dr6 & (1 << hw_index));
-}
-
-nub_addr_t DNBArchImplX86_64::GetWatchAddress(const DBG &debug_state,
- uint32_t hw_index) {
- switch (hw_index) {
- case 0:
- return debug_state.__dr0;
- case 1:
- return debug_state.__dr1;
- case 2:
- return debug_state.__dr2;
- case 3:
- return debug_state.__dr3;
- }
- assert(0 && "invalid hardware register index, must be one of 0, 1, 2, or 3");
- return 0;
-}
-
-bool DNBArchImplX86_64::StartTransForHWP() {
- if (m_2pc_trans_state != Trans_Done && m_2pc_trans_state != Trans_Rolled_Back)
- DNBLogError("%s inconsistent state detected, expected %d or %d, got: %d",
- __FUNCTION__, Trans_Done, Trans_Rolled_Back, m_2pc_trans_state);
- m_2pc_dbg_checkpoint = m_state.context.dbg;
- m_2pc_trans_state = Trans_Pending;
- return true;
-}
-bool DNBArchImplX86_64::RollbackTransForHWP() {
- m_state.context.dbg = m_2pc_dbg_checkpoint;
- if (m_2pc_trans_state != Trans_Pending)
- DNBLogError("%s inconsistent state detected, expected %d, got: %d",
- __FUNCTION__, Trans_Pending, m_2pc_trans_state);
- m_2pc_trans_state = Trans_Rolled_Back;
- kern_return_t kret = SetDBGState(false);
- DNBLogThreadedIf(
- LOG_WATCHPOINTS,
- "DNBArchImplX86_64::RollbackTransForHWP() SetDBGState() => 0x%8.8x.",
- kret);
-
- return kret == KERN_SUCCESS;
-}
-bool DNBArchImplX86_64::FinishTransForHWP() {
- m_2pc_trans_state = Trans_Done;
- return true;
-}
-DNBArchImplX86_64::DBG DNBArchImplX86_64::GetDBGCheckpoint() {
- return m_2pc_dbg_checkpoint;
-}
-
-uint32_t DNBArchImplX86_64::EnableHardwareWatchpoint(nub_addr_t addr,
- nub_size_t size, bool read,
- bool write,
- bool also_set_on_task) {
- DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::"
- "EnableHardwareWatchpoint(addr = 0x%llx, "
- "size = %llu, read = %u, write = %u)",
- (uint64_t)addr, (uint64_t)size, read, write);
-
- const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
-
- // Can only watch 1, 2, 4, or 8 bytes.
- if (!(size == 1 || size == 2 || size == 4 || size == 8))
- return INVALID_NUB_HW_INDEX;
-
- // We must watch for either read or write
- if (!read && !write)
- return INVALID_NUB_HW_INDEX;
-
- // 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;
-
- DBG &debug_state = m_state.context.dbg;
- for (i = 0; i < num_hw_watchpoints; ++i) {
- if (IsWatchpointVacant(debug_state, i))
- break;
- }
-
- // See if we found an available hw breakpoint slot above
- if (i < num_hw_watchpoints) {
- StartTransForHWP();
-
- // Modify our local copy of the debug state, first.
- SetWatchpoint(debug_state, i, addr, size, read, write);
- // Now set the watch point in the inferior.
- kret = SetDBGState(also_set_on_task);
- DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::"
- "EnableHardwareWatchpoint() "
- "SetDBGState() => 0x%8.8x.",
- kret);
-
- if (kret == KERN_SUCCESS)
- return i;
- else // Revert to the previous debug state voluntarily. The transaction
- // coordinator knows that we have failed.
- m_state.context.dbg = GetDBGCheckpoint();
- } else {
- DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::"
- "EnableHardwareWatchpoint(): All "
- "hardware resources (%u) are in use.",
- num_hw_watchpoints);
- }
- }
- return INVALID_NUB_HW_INDEX;
-}
-
-bool DNBArchImplX86_64::DisableHardwareWatchpoint(uint32_t hw_index,
- bool also_set_on_task) {
- kern_return_t kret = GetDBGState(false);
-
- const uint32_t num_hw_points = NumSupportedHardwareWatchpoints();
- if (kret == KERN_SUCCESS) {
- DBG &debug_state = m_state.context.dbg;
- if (hw_index < num_hw_points &&
- !IsWatchpointVacant(debug_state, hw_index)) {
- StartTransForHWP();
-
- // Modify our local copy of the debug state, first.
- ClearWatchpoint(debug_state, hw_index);
- // Now disable the watch point in the inferior.
- kret = SetDBGState(also_set_on_task);
- DNBLogThreadedIf(LOG_WATCHPOINTS,
- "DNBArchImplX86_64::DisableHardwareWatchpoint( %u )",
- hw_index);
-
- if (kret == KERN_SUCCESS)
- return true;
- else // Revert to the previous debug state voluntarily. The transaction
- // coordinator knows that we have failed.
- m_state.context.dbg = GetDBGCheckpoint();
- }
- }
- return false;
-}
-
-// Iterate through the debug status register; return the index of the first hit.
-uint32_t DNBArchImplX86_64::GetHardwareWatchpointHit(nub_addr_t &addr) {
- // Read the debug state
- kern_return_t kret = GetDBGState(true);
- DNBLogThreadedIf(
- LOG_WATCHPOINTS,
- "DNBArchImplX86_64::GetHardwareWatchpointHit() GetDBGState() => 0x%8.8x.",
- kret);
- if (kret == KERN_SUCCESS) {
- DBG &debug_state = m_state.context.dbg;
- uint32_t i, num = NumSupportedHardwareWatchpoints();
- for (i = 0; i < num; ++i) {
- if (IsWatchpointHit(debug_state, i)) {
- addr = GetWatchAddress(debug_state, i);
- DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::"
- "GetHardwareWatchpointHit() found => "
- "%u (addr = 0x%llx).",
- i, (uint64_t)addr);
- return i;
- }
- }
- }
- return INVALID_NUB_HW_INDEX;
-}
-
-// Set the single step bit in the processor status register.
-kern_return_t DNBArchImplX86_64::EnableHardwareSingleStep(bool enable) {
- if (GetGPRState(false) == KERN_SUCCESS) {
- const uint32_t trace_bit = 0x100u;
- if (enable)
- m_state.context.gpr.__rflags |= trace_bit;
- else
- m_state.context.gpr.__rflags &= ~trace_bit;
- return SetGPRState();
- }
- return m_state.GetError(e_regSetGPR, Read);
-}
-
-//----------------------------------------------------------------------
-// Register information definitions
-//----------------------------------------------------------------------
-
-enum {
- gpr_rax = 0,
- gpr_rbx,
- gpr_rcx,
- gpr_rdx,
- gpr_rdi,
- gpr_rsi,
- gpr_rbp,
- gpr_rsp,
- gpr_r8,
- gpr_r9,
- gpr_r10,
- gpr_r11,
- gpr_r12,
- gpr_r13,
- gpr_r14,
- gpr_r15,
- gpr_rip,
- gpr_rflags,
- gpr_cs,
- gpr_fs,
- gpr_gs,
- gpr_eax,
- gpr_ebx,
- gpr_ecx,
- gpr_edx,
- gpr_edi,
- gpr_esi,
- gpr_ebp,
- gpr_esp,
- gpr_r8d, // Low 32 bits or r8
- gpr_r9d, // Low 32 bits or r9
- gpr_r10d, // Low 32 bits or r10
- gpr_r11d, // Low 32 bits or r11
- gpr_r12d, // Low 32 bits or r12
- gpr_r13d, // Low 32 bits or r13
- gpr_r14d, // Low 32 bits or r14
- gpr_r15d, // Low 32 bits or r15
- gpr_ax,
- gpr_bx,
- gpr_cx,
- gpr_dx,
- gpr_di,
- gpr_si,
- gpr_bp,
- gpr_sp,
- gpr_r8w, // Low 16 bits or r8
- gpr_r9w, // Low 16 bits or r9
- gpr_r10w, // Low 16 bits or r10
- gpr_r11w, // Low 16 bits or r11
- gpr_r12w, // Low 16 bits or r12
- gpr_r13w, // Low 16 bits or r13
- gpr_r14w, // Low 16 bits or r14
- gpr_r15w, // Low 16 bits or r15
- gpr_ah,
- gpr_bh,
- gpr_ch,
- gpr_dh,
- gpr_al,
- gpr_bl,
- gpr_cl,
- gpr_dl,
- gpr_dil,
- gpr_sil,
- gpr_bpl,
- gpr_spl,
- gpr_r8l, // Low 8 bits or r8
- gpr_r9l, // Low 8 bits or r9
- gpr_r10l, // Low 8 bits or r10
- gpr_r11l, // Low 8 bits or r11
- gpr_r12l, // Low 8 bits or r12
- gpr_r13l, // Low 8 bits or r13
- gpr_r14l, // Low 8 bits or r14
- gpr_r15l, // Low 8 bits or r15
- k_num_gpr_regs
-};
-
-enum {
- fpu_fcw,
- fpu_fsw,
- fpu_ftw,
- fpu_fop,
- fpu_ip,
- fpu_cs,
- fpu_dp,
- fpu_ds,
- fpu_mxcsr,
- fpu_mxcsrmask,
- fpu_stmm0,
- fpu_stmm1,
- fpu_stmm2,
- fpu_stmm3,
- fpu_stmm4,
- fpu_stmm5,
- fpu_stmm6,
- fpu_stmm7,
- fpu_xmm0,
- fpu_xmm1,
- fpu_xmm2,
- fpu_xmm3,
- fpu_xmm4,
- fpu_xmm5,
- fpu_xmm6,
- fpu_xmm7,
- fpu_xmm8,
- fpu_xmm9,
- fpu_xmm10,
- fpu_xmm11,
- fpu_xmm12,
- fpu_xmm13,
- fpu_xmm14,
- fpu_xmm15,
- fpu_ymm0,
- fpu_ymm1,
- fpu_ymm2,
- fpu_ymm3,
- fpu_ymm4,
- fpu_ymm5,
- fpu_ymm6,
- fpu_ymm7,
- fpu_ymm8,
- fpu_ymm9,
- fpu_ymm10,
- fpu_ymm11,
- fpu_ymm12,
- fpu_ymm13,
- fpu_ymm14,
- fpu_ymm15,
- fpu_k0,
- fpu_k1,
- fpu_k2,
- fpu_k3,
- fpu_k4,
- fpu_k5,
- fpu_k6,
- fpu_k7,
- fpu_zmm0,
- fpu_zmm1,
- fpu_zmm2,
- fpu_zmm3,
- fpu_zmm4,
- fpu_zmm5,
- fpu_zmm6,
- fpu_zmm7,
- fpu_zmm8,
- fpu_zmm9,
- fpu_zmm10,
- fpu_zmm11,
- fpu_zmm12,
- fpu_zmm13,
- fpu_zmm14,
- fpu_zmm15,
- fpu_zmm16,
- fpu_zmm17,
- fpu_zmm18,
- fpu_zmm19,
- fpu_zmm20,
- fpu_zmm21,
- fpu_zmm22,
- fpu_zmm23,
- fpu_zmm24,
- fpu_zmm25,
- fpu_zmm26,
- fpu_zmm27,
- fpu_zmm28,
- fpu_zmm29,
- fpu_zmm30,
- fpu_zmm31,
- k_num_fpu_regs,
-
- // Aliases
- fpu_fctrl = fpu_fcw,
- fpu_fstat = fpu_fsw,
- fpu_ftag = fpu_ftw,
- fpu_fiseg = fpu_cs,
- fpu_fioff = fpu_ip,
- fpu_foseg = fpu_ds,
- fpu_fooff = fpu_dp
-};
-
-enum {
- exc_trapno,
- exc_err,
- exc_faultvaddr,
- k_num_exc_regs,
-};
-
-enum ehframe_dwarf_regnums {
- ehframe_dwarf_rax = 0,
- ehframe_dwarf_rdx = 1,
- ehframe_dwarf_rcx = 2,
- ehframe_dwarf_rbx = 3,
- ehframe_dwarf_rsi = 4,
- ehframe_dwarf_rdi = 5,
- ehframe_dwarf_rbp = 6,
- ehframe_dwarf_rsp = 7,
- ehframe_dwarf_r8,
- ehframe_dwarf_r9,
- ehframe_dwarf_r10,
- ehframe_dwarf_r11,
- ehframe_dwarf_r12,
- ehframe_dwarf_r13,
- ehframe_dwarf_r14,
- ehframe_dwarf_r15,
- ehframe_dwarf_rip,
- ehframe_dwarf_xmm0,
- ehframe_dwarf_xmm1,
- ehframe_dwarf_xmm2,
- ehframe_dwarf_xmm3,
- ehframe_dwarf_xmm4,
- ehframe_dwarf_xmm5,
- ehframe_dwarf_xmm6,
- ehframe_dwarf_xmm7,
- ehframe_dwarf_xmm8,
- ehframe_dwarf_xmm9,
- ehframe_dwarf_xmm10,
- ehframe_dwarf_xmm11,
- ehframe_dwarf_xmm12,
- ehframe_dwarf_xmm13,
- ehframe_dwarf_xmm14,
- ehframe_dwarf_xmm15,
- ehframe_dwarf_stmm0,
- ehframe_dwarf_stmm1,
- ehframe_dwarf_stmm2,
- ehframe_dwarf_stmm3,
- ehframe_dwarf_stmm4,
- ehframe_dwarf_stmm5,
- ehframe_dwarf_stmm6,
- ehframe_dwarf_stmm7,
- ehframe_dwarf_ymm0 = ehframe_dwarf_xmm0,
- ehframe_dwarf_ymm1 = ehframe_dwarf_xmm1,
- ehframe_dwarf_ymm2 = ehframe_dwarf_xmm2,
- ehframe_dwarf_ymm3 = ehframe_dwarf_xmm3,
- ehframe_dwarf_ymm4 = ehframe_dwarf_xmm4,
- ehframe_dwarf_ymm5 = ehframe_dwarf_xmm5,
- ehframe_dwarf_ymm6 = ehframe_dwarf_xmm6,
- ehframe_dwarf_ymm7 = ehframe_dwarf_xmm7,
- ehframe_dwarf_ymm8 = ehframe_dwarf_xmm8,
- ehframe_dwarf_ymm9 = ehframe_dwarf_xmm9,
- ehframe_dwarf_ymm10 = ehframe_dwarf_xmm10,
- ehframe_dwarf_ymm11 = ehframe_dwarf_xmm11,
- ehframe_dwarf_ymm12 = ehframe_dwarf_xmm12,
- ehframe_dwarf_ymm13 = ehframe_dwarf_xmm13,
- ehframe_dwarf_ymm14 = ehframe_dwarf_xmm14,
- ehframe_dwarf_ymm15 = ehframe_dwarf_xmm15,
- ehframe_dwarf_zmm0 = ehframe_dwarf_xmm0,
- ehframe_dwarf_zmm1 = ehframe_dwarf_xmm1,
- ehframe_dwarf_zmm2 = ehframe_dwarf_xmm2,
- ehframe_dwarf_zmm3 = ehframe_dwarf_xmm3,
- ehframe_dwarf_zmm4 = ehframe_dwarf_xmm4,
- ehframe_dwarf_zmm5 = ehframe_dwarf_xmm5,
- ehframe_dwarf_zmm6 = ehframe_dwarf_xmm6,
- ehframe_dwarf_zmm7 = ehframe_dwarf_xmm7,
- ehframe_dwarf_zmm8 = ehframe_dwarf_xmm8,
- ehframe_dwarf_zmm9 = ehframe_dwarf_xmm9,
- ehframe_dwarf_zmm10 = ehframe_dwarf_xmm10,
- ehframe_dwarf_zmm11 = ehframe_dwarf_xmm11,
- ehframe_dwarf_zmm12 = ehframe_dwarf_xmm12,
- ehframe_dwarf_zmm13 = ehframe_dwarf_xmm13,
- ehframe_dwarf_zmm14 = ehframe_dwarf_xmm14,
- ehframe_dwarf_zmm15 = ehframe_dwarf_xmm15,
- ehframe_dwarf_zmm16 = 67,
- ehframe_dwarf_zmm17,
- ehframe_dwarf_zmm18,
- ehframe_dwarf_zmm19,
- ehframe_dwarf_zmm20,
- ehframe_dwarf_zmm21,
- ehframe_dwarf_zmm22,
- ehframe_dwarf_zmm23,
- ehframe_dwarf_zmm24,
- ehframe_dwarf_zmm25,
- ehframe_dwarf_zmm26,
- ehframe_dwarf_zmm27,
- ehframe_dwarf_zmm28,
- ehframe_dwarf_zmm29,
- ehframe_dwarf_zmm30,
- ehframe_dwarf_zmm31,
- ehframe_dwarf_k0 = 118,
- ehframe_dwarf_k1,
- ehframe_dwarf_k2,
- ehframe_dwarf_k3,
- ehframe_dwarf_k4,
- ehframe_dwarf_k5,
- ehframe_dwarf_k6,
- ehframe_dwarf_k7,
-};
-
-enum debugserver_regnums {
- debugserver_rax = 0,
- debugserver_rbx = 1,
- debugserver_rcx = 2,
- debugserver_rdx = 3,
- debugserver_rsi = 4,
- debugserver_rdi = 5,
- debugserver_rbp = 6,
- debugserver_rsp = 7,
- debugserver_r8 = 8,
- debugserver_r9 = 9,
- debugserver_r10 = 10,
- debugserver_r11 = 11,
- debugserver_r12 = 12,
- debugserver_r13 = 13,
- debugserver_r14 = 14,
- debugserver_r15 = 15,
- debugserver_rip = 16,
- debugserver_rflags = 17,
- debugserver_cs = 18,
- debugserver_ss = 19,
- debugserver_ds = 20,
- debugserver_es = 21,
- debugserver_fs = 22,
- debugserver_gs = 23,
- debugserver_stmm0 = 24,
- debugserver_stmm1 = 25,
- debugserver_stmm2 = 26,
- debugserver_stmm3 = 27,
- debugserver_stmm4 = 28,
- debugserver_stmm5 = 29,
- debugserver_stmm6 = 30,
- debugserver_stmm7 = 31,
- debugserver_fctrl = 32,
- debugserver_fcw = debugserver_fctrl,
- debugserver_fstat = 33,
- debugserver_fsw = debugserver_fstat,
- debugserver_ftag = 34,
- debugserver_ftw = debugserver_ftag,
- debugserver_fiseg = 35,
- debugserver_fpu_cs = debugserver_fiseg,
- debugserver_fioff = 36,
- debugserver_ip = debugserver_fioff,
- debugserver_foseg = 37,
- debugserver_fpu_ds = debugserver_foseg,
- debugserver_fooff = 38,
- debugserver_dp = debugserver_fooff,
- debugserver_fop = 39,
- debugserver_xmm0 = 40,
- debugserver_xmm1 = 41,
- debugserver_xmm2 = 42,
- debugserver_xmm3 = 43,
- debugserver_xmm4 = 44,
- debugserver_xmm5 = 45,
- debugserver_xmm6 = 46,
- debugserver_xmm7 = 47,
- debugserver_xmm8 = 48,
- debugserver_xmm9 = 49,
- debugserver_xmm10 = 50,
- debugserver_xmm11 = 51,
- debugserver_xmm12 = 52,
- debugserver_xmm13 = 53,
- debugserver_xmm14 = 54,
- debugserver_xmm15 = 55,
- debugserver_mxcsr = 56,
- debugserver_ymm0 = debugserver_xmm0,
- debugserver_ymm1 = debugserver_xmm1,
- debugserver_ymm2 = debugserver_xmm2,
- debugserver_ymm3 = debugserver_xmm3,
- debugserver_ymm4 = debugserver_xmm4,
- debugserver_ymm5 = debugserver_xmm5,
- debugserver_ymm6 = debugserver_xmm6,
- debugserver_ymm7 = debugserver_xmm7,
- debugserver_ymm8 = debugserver_xmm8,
- debugserver_ymm9 = debugserver_xmm9,
- debugserver_ymm10 = debugserver_xmm10,
- debugserver_ymm11 = debugserver_xmm11,
- debugserver_ymm12 = debugserver_xmm12,
- debugserver_ymm13 = debugserver_xmm13,
- debugserver_ymm14 = debugserver_xmm14,
- debugserver_ymm15 = debugserver_xmm15,
- debugserver_zmm0 = debugserver_xmm0,
- debugserver_zmm1 = debugserver_xmm1,
- debugserver_zmm2 = debugserver_xmm2,
- debugserver_zmm3 = debugserver_xmm3,
- debugserver_zmm4 = debugserver_xmm4,
- debugserver_zmm5 = debugserver_xmm5,
- debugserver_zmm6 = debugserver_xmm6,
- debugserver_zmm7 = debugserver_xmm7,
- debugserver_zmm8 = debugserver_xmm8,
- debugserver_zmm9 = debugserver_xmm9,
- debugserver_zmm10 = debugserver_xmm10,
- debugserver_zmm11 = debugserver_xmm11,
- debugserver_zmm12 = debugserver_xmm12,
- debugserver_zmm13 = debugserver_xmm13,
- debugserver_zmm14 = debugserver_xmm14,
- debugserver_zmm15 = debugserver_xmm15,
- debugserver_zmm16 = 67,
- debugserver_zmm17 = 68,
- debugserver_zmm18 = 69,
- debugserver_zmm19 = 70,
- debugserver_zmm20 = 71,
- debugserver_zmm21 = 72,
- debugserver_zmm22 = 73,
- debugserver_zmm23 = 74,
- debugserver_zmm24 = 75,
- debugserver_zmm25 = 76,
- debugserver_zmm26 = 77,
- debugserver_zmm27 = 78,
- debugserver_zmm28 = 79,
- debugserver_zmm29 = 80,
- debugserver_zmm30 = 81,
- debugserver_zmm31 = 82,
- debugserver_k0 = 118,
- debugserver_k1 = 119,
- debugserver_k2 = 120,
- debugserver_k3 = 121,
- debugserver_k4 = 122,
- debugserver_k5 = 123,
- debugserver_k6 = 124,
- debugserver_k7 = 125,
-};
-
-#define GPR_OFFSET(reg) (offsetof(DNBArchImplX86_64::GPR, __##reg))
-#define FPU_OFFSET(reg) \
- (offsetof(DNBArchImplX86_64::FPU, __fpu_##reg) + \
- offsetof(DNBArchImplX86_64::Context, fpu.no_avx))
-#define AVX_OFFSET(reg) \
- (offsetof(DNBArchImplX86_64::AVX, __fpu_##reg) + \
- offsetof(DNBArchImplX86_64::Context, fpu.avx))
-#define AVX512F_OFFSET(reg) \
- (offsetof(DNBArchImplX86_64::AVX512F, __fpu_##reg) + \
- offsetof(DNBArchImplX86_64::Context, fpu.avx512f))
-#define EXC_OFFSET(reg) \
- (offsetof(DNBArchImplX86_64::EXC, __##reg) + \
- offsetof(DNBArchImplX86_64::Context, exc))
-#define AVX_OFFSET_YMM(n) (AVX_OFFSET(ymmh0) + (32 * n))
-#define AVX512F_OFFSET_ZMM(n) (AVX512F_OFFSET(zmmh0) + (64 * n))
-
-#define GPR_SIZE(reg) (sizeof(((DNBArchImplX86_64::GPR *)NULL)->__##reg))
-#define FPU_SIZE_UINT(reg) \
- (sizeof(((DNBArchImplX86_64::FPU *)NULL)->__fpu_##reg))
-#define FPU_SIZE_MMST(reg) \
- (sizeof(((DNBArchImplX86_64::FPU *)NULL)->__fpu_##reg.__mmst_reg))
-#define FPU_SIZE_XMM(reg) \
- (sizeof(((DNBArchImplX86_64::FPU *)NULL)->__fpu_##reg.__xmm_reg))
-#define FPU_SIZE_YMM(reg) (32)
-#define FPU_SIZE_ZMM(reg) (64)
-#define EXC_SIZE(reg) (sizeof(((DNBArchImplX86_64::EXC *)NULL)->__##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(reg) \
- { \
- e_regSetGPR, gpr_##reg, #reg, NULL, Uint, Hex, GPR_SIZE(reg), \
- GPR_OFFSET(reg), ehframe_dwarf_##reg, ehframe_dwarf_##reg, \
- INVALID_NUB_REGNUM, debugserver_##reg, NULL, g_invalidate_##reg \
- }
-#define DEFINE_GPR_ALT(reg, alt, gen) \
- { \
- e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, GPR_SIZE(reg), \
- GPR_OFFSET(reg), ehframe_dwarf_##reg, ehframe_dwarf_##reg, gen, \
- debugserver_##reg, NULL, g_invalidate_##reg \
- }
-#define DEFINE_GPR_ALT2(reg, alt) \
- { \
- e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, GPR_SIZE(reg), \
- GPR_OFFSET(reg), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, \
- INVALID_NUB_REGNUM, debugserver_##reg, NULL, NULL \
- }
-#define DEFINE_GPR_ALT3(reg, alt, gen) \
- { \
- e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, GPR_SIZE(reg), \
- GPR_OFFSET(reg), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, gen, \
- debugserver_##reg, NULL, NULL \
- }
-#define DEFINE_GPR_ALT4(reg, alt, gen) \
- { \
- e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, GPR_SIZE(reg), \
- GPR_OFFSET(reg), ehframe_dwarf_##reg, ehframe_dwarf_##reg, gen, \
- debugserver_##reg, NULL, NULL \
- }
-
-#define DEFINE_GPR_PSEUDO_32(reg32, reg64) \
- { \
- e_regSetGPR, gpr_##reg32, #reg32, NULL, Uint, Hex, 4, 0, \
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, \
- INVALID_NUB_REGNUM, g_contained_##reg64, g_invalidate_##reg64 \
- }
-#define DEFINE_GPR_PSEUDO_16(reg16, reg64) \
- { \
- e_regSetGPR, gpr_##reg16, #reg16, NULL, Uint, Hex, 2, 0, \
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, \
- INVALID_NUB_REGNUM, g_contained_##reg64, g_invalidate_##reg64 \
- }
-#define DEFINE_GPR_PSEUDO_8H(reg8, reg64) \
- { \
- e_regSetGPR, gpr_##reg8, #reg8, NULL, Uint, Hex, 1, 1, INVALID_NUB_REGNUM, \
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, \
- g_contained_##reg64, g_invalidate_##reg64 \
- }
-#define DEFINE_GPR_PSEUDO_8L(reg8, reg64) \
- { \
- e_regSetGPR, gpr_##reg8, #reg8, NULL, Uint, Hex, 1, 0, INVALID_NUB_REGNUM, \
- INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, \
- g_contained_##reg64, g_invalidate_##reg64 \
- }
-
-// General purpose registers for 64 bit
-
-const char *g_contained_rax[] = {"rax", NULL};
-const char *g_contained_rbx[] = {"rbx", NULL};
-const char *g_contained_rcx[] = {"rcx", NULL};
-const char *g_contained_rdx[] = {"rdx", NULL};
-const char *g_contained_rdi[] = {"rdi", NULL};
-const char *g_contained_rsi[] = {"rsi", NULL};
-const char *g_contained_rbp[] = {"rbp", NULL};
-const char *g_contained_rsp[] = {"rsp", NULL};
-const char *g_contained_r8[] = {"r8", NULL};
-const char *g_contained_r9[] = {"r9", NULL};
-const char *g_contained_r10[] = {"r10", NULL};
-const char *g_contained_r11[] = {"r11", NULL};
-const char *g_contained_r12[] = {"r12", NULL};
-const char *g_contained_r13[] = {"r13", NULL};
-const char *g_contained_r14[] = {"r14", NULL};
-const char *g_contained_r15[] = {"r15", NULL};
-
-const char *g_invalidate_rax[] = {"rax", "eax", "ax", "ah", "al", NULL};
-const char *g_invalidate_rbx[] = {"rbx", "ebx", "bx", "bh", "bl", NULL};
-const char *g_invalidate_rcx[] = {"rcx", "ecx", "cx", "ch", "cl", NULL};
-const char *g_invalidate_rdx[] = {"rdx", "edx", "dx", "dh", "dl", NULL};
-const char *g_invalidate_rdi[] = {"rdi", "edi", "di", "dil", NULL};
-const char *g_invalidate_rsi[] = {"rsi", "esi", "si", "sil", NULL};
-const char *g_invalidate_rbp[] = {"rbp", "ebp", "bp", "bpl", NULL};
-const char *g_invalidate_rsp[] = {"rsp", "esp", "sp", "spl", NULL};
-const char *g_invalidate_r8[] = {"r8", "r8d", "r8w", "r8l", NULL};
-const char *g_invalidate_r9[] = {"r9", "r9d", "r9w", "r9l", NULL};
-const char *g_invalidate_r10[] = {"r10", "r10d", "r10w", "r10l", NULL};
-const char *g_invalidate_r11[] = {"r11", "r11d", "r11w", "r11l", NULL};
-const char *g_invalidate_r12[] = {"r12", "r12d", "r12w", "r12l", NULL};
-const char *g_invalidate_r13[] = {"r13", "r13d", "r13w", "r13l", NULL};
-const char *g_invalidate_r14[] = {"r14", "r14d", "r14w", "r14l", NULL};
-const char *g_invalidate_r15[] = {"r15", "r15d", "r15w", "r15l", NULL};
-
-const DNBRegisterInfo DNBArchImplX86_64::g_gpr_registers[] = {
- DEFINE_GPR(rax),
- DEFINE_GPR(rbx),
- DEFINE_GPR_ALT(rcx, "arg4", GENERIC_REGNUM_ARG4),
- DEFINE_GPR_ALT(rdx, "arg3", GENERIC_REGNUM_ARG3),
- DEFINE_GPR_ALT(rdi, "arg1", GENERIC_REGNUM_ARG1),
- DEFINE_GPR_ALT(rsi, "arg2", GENERIC_REGNUM_ARG2),
- DEFINE_GPR_ALT(rbp, "fp", GENERIC_REGNUM_FP),
- DEFINE_GPR_ALT(rsp, "sp", GENERIC_REGNUM_SP),
- DEFINE_GPR_ALT(r8, "arg5", GENERIC_REGNUM_ARG5),
- DEFINE_GPR_ALT(r9, "arg6", GENERIC_REGNUM_ARG6),
- DEFINE_GPR(r10),
- DEFINE_GPR(r11),
- DEFINE_GPR(r12),
- DEFINE_GPR(r13),
- DEFINE_GPR(r14),
- DEFINE_GPR(r15),
- DEFINE_GPR_ALT4(rip, "pc", GENERIC_REGNUM_PC),
- DEFINE_GPR_ALT3(rflags, "flags", GENERIC_REGNUM_FLAGS),
- DEFINE_GPR_ALT2(cs, NULL),
- DEFINE_GPR_ALT2(fs, NULL),
- DEFINE_GPR_ALT2(gs, NULL),
- DEFINE_GPR_PSEUDO_32(eax, rax),
- DEFINE_GPR_PSEUDO_32(ebx, rbx),
- DEFINE_GPR_PSEUDO_32(ecx, rcx),
- DEFINE_GPR_PSEUDO_32(edx, rdx),
- DEFINE_GPR_PSEUDO_32(edi, rdi),
- DEFINE_GPR_PSEUDO_32(esi, rsi),
- DEFINE_GPR_PSEUDO_32(ebp, rbp),
- DEFINE_GPR_PSEUDO_32(esp, rsp),
- DEFINE_GPR_PSEUDO_32(r8d, r8),
- DEFINE_GPR_PSEUDO_32(r9d, r9),
- DEFINE_GPR_PSEUDO_32(r10d, r10),
- DEFINE_GPR_PSEUDO_32(r11d, r11),
- DEFINE_GPR_PSEUDO_32(r12d, r12),
- DEFINE_GPR_PSEUDO_32(r13d, r13),
- DEFINE_GPR_PSEUDO_32(r14d, r14),
- DEFINE_GPR_PSEUDO_32(r15d, r15),
- DEFINE_GPR_PSEUDO_16(ax, rax),
- DEFINE_GPR_PSEUDO_16(bx, rbx),
- DEFINE_GPR_PSEUDO_16(cx, rcx),
- DEFINE_GPR_PSEUDO_16(dx, rdx),
- DEFINE_GPR_PSEUDO_16(di, rdi),
- DEFINE_GPR_PSEUDO_16(si, rsi),
- DEFINE_GPR_PSEUDO_16(bp, rbp),
- DEFINE_GPR_PSEUDO_16(sp, rsp),
- DEFINE_GPR_PSEUDO_16(r8w, r8),
- DEFINE_GPR_PSEUDO_16(r9w, r9),
- DEFINE_GPR_PSEUDO_16(r10w, r10),
- DEFINE_GPR_PSEUDO_16(r11w, r11),
- DEFINE_GPR_PSEUDO_16(r12w, r12),
- DEFINE_GPR_PSEUDO_16(r13w, r13),
- DEFINE_GPR_PSEUDO_16(r14w, r14),
- DEFINE_GPR_PSEUDO_16(r15w, r15),
- DEFINE_GPR_PSEUDO_8H(ah, rax),
- DEFINE_GPR_PSEUDO_8H(bh, rbx),
- DEFINE_GPR_PSEUDO_8H(ch, rcx),
- DEFINE_GPR_PSEUDO_8H(dh, rdx),
- DEFINE_GPR_PSEUDO_8L(al, rax),
- DEFINE_GPR_PSEUDO_8L(bl, rbx),
- DEFINE_GPR_PSEUDO_8L(cl, rcx),
- DEFINE_GPR_PSEUDO_8L(dl, rdx),
- DEFINE_GPR_PSEUDO_8L(dil, rdi),
- DEFINE_GPR_PSEUDO_8L(sil, rsi),
- DEFINE_GPR_PSEUDO_8L(bpl, rbp),
- DEFINE_GPR_PSEUDO_8L(spl, rsp),
- DEFINE_GPR_PSEUDO_8L(r8l, r8),
- DEFINE_GPR_PSEUDO_8L(r9l, r9),
- DEFINE_GPR_PSEUDO_8L(r10l, r10),
- DEFINE_GPR_PSEUDO_8L(r11l, r11),
- DEFINE_GPR_PSEUDO_8L(r12l, r12),
- DEFINE_GPR_PSEUDO_8L(r13l, r13),
- DEFINE_GPR_PSEUDO_8L(r14l, r14),
- DEFINE_GPR_PSEUDO_8L(r15l, r15)};
-
-// Floating point registers 64 bit
-const DNBRegisterInfo DNBArchImplX86_64::g_fpu_registers_no_avx[] = {
- {e_regSetFPU, fpu_fcw, "fctrl", NULL, Uint, Hex, FPU_SIZE_UINT(fcw),
- FPU_OFFSET(fcw), -1U, -1U, -1U, -1U, NULL, NULL},
- {e_regSetFPU, fpu_fsw, "fstat", NULL, Uint, Hex, FPU_SIZE_UINT(fsw),
- FPU_OFFSET(fsw), -1U, -1U, -1U, -1U, NULL, NULL},
- {e_regSetFPU, fpu_ftw, "ftag", NULL, Uint, Hex, 2 /* sizeof __fpu_ftw + sizeof __fpu_rsrv1 */,
- FPU_OFFSET(ftw), -1U, -1U, -1U, -1U, NULL, NULL},
- {e_regSetFPU, fpu_fop, "fop", NULL, Uint, Hex, FPU_SIZE_UINT(fop),
- FPU_OFFSET(fop), -1U, -1U, -1U, -1U, NULL, NULL},
- {e_regSetFPU, fpu_ip, "fioff", NULL, Uint, Hex, FPU_SIZE_UINT(ip),
- FPU_OFFSET(ip), -1U, -1U, -1U, -1U, NULL, NULL},
- {e_regSetFPU, fpu_cs, "fiseg", NULL, Uint, Hex, FPU_SIZE_UINT(cs),
- FPU_OFFSET(cs), -1U, -1U, -1U, -1U, NULL, NULL},
- {e_regSetFPU, fpu_dp, "fooff", NULL, Uint, Hex, FPU_SIZE_UINT(dp),
- FPU_OFFSET(dp), -1U, -1U, -1U, -1U, NULL, NULL},
- {e_regSetFPU, fpu_ds, "foseg", NULL, Uint, Hex, FPU_SIZE_UINT(ds),
- FPU_OFFSET(ds), -1U, -1U, -1U, -1U, NULL, NULL},
- {e_regSetFPU, fpu_mxcsr, "mxcsr", NULL, Uint, Hex, FPU_SIZE_UINT(mxcsr),
- FPU_OFFSET(mxcsr), -1U, -1U, -1U, -1U, NULL, NULL},
- {e_regSetFPU, fpu_mxcsrmask, "mxcsrmask", NULL, Uint, Hex,
- FPU_SIZE_UINT(mxcsrmask), FPU_OFFSET(mxcsrmask), -1U, -1U, -1U, -1U, NULL,
- NULL},
-
- {e_regSetFPU, fpu_stmm0, "stmm0", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm0), FPU_OFFSET(stmm0), ehframe_dwarf_stmm0,
- ehframe_dwarf_stmm0, -1U, debugserver_stmm0, NULL, NULL},
- {e_regSetFPU, fpu_stmm1, "stmm1", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm1), FPU_OFFSET(stmm1), ehframe_dwarf_stmm1,
- ehframe_dwarf_stmm1, -1U, debugserver_stmm1, NULL, NULL},
- {e_regSetFPU, fpu_stmm2, "stmm2", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm2), FPU_OFFSET(stmm2), ehframe_dwarf_stmm2,
- ehframe_dwarf_stmm2, -1U, debugserver_stmm2, NULL, NULL},
- {e_regSetFPU, fpu_stmm3, "stmm3", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm3), FPU_OFFSET(stmm3), ehframe_dwarf_stmm3,
- ehframe_dwarf_stmm3, -1U, debugserver_stmm3, NULL, NULL},
- {e_regSetFPU, fpu_stmm4, "stmm4", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm4), FPU_OFFSET(stmm4), ehframe_dwarf_stmm4,
- ehframe_dwarf_stmm4, -1U, debugserver_stmm4, NULL, NULL},
- {e_regSetFPU, fpu_stmm5, "stmm5", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm5), FPU_OFFSET(stmm5), ehframe_dwarf_stmm5,
- ehframe_dwarf_stmm5, -1U, debugserver_stmm5, NULL, NULL},
- {e_regSetFPU, fpu_stmm6, "stmm6", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm6), FPU_OFFSET(stmm6), ehframe_dwarf_stmm6,
- ehframe_dwarf_stmm6, -1U, debugserver_stmm6, NULL, NULL},
- {e_regSetFPU, fpu_stmm7, "stmm7", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm7), FPU_OFFSET(stmm7), ehframe_dwarf_stmm7,
- ehframe_dwarf_stmm7, -1U, debugserver_stmm7, NULL, NULL},
-
- {e_regSetFPU, fpu_xmm0, "xmm0", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm0), FPU_OFFSET(xmm0), ehframe_dwarf_xmm0,
- ehframe_dwarf_xmm0, -1U, debugserver_xmm0, NULL, NULL},
- {e_regSetFPU, fpu_xmm1, "xmm1", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm1), FPU_OFFSET(xmm1), ehframe_dwarf_xmm1,
- ehframe_dwarf_xmm1, -1U, debugserver_xmm1, NULL, NULL},
- {e_regSetFPU, fpu_xmm2, "xmm2", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm2), FPU_OFFSET(xmm2), ehframe_dwarf_xmm2,
- ehframe_dwarf_xmm2, -1U, debugserver_xmm2, NULL, NULL},
- {e_regSetFPU, fpu_xmm3, "xmm3", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm3), FPU_OFFSET(xmm3), ehframe_dwarf_xmm3,
- ehframe_dwarf_xmm3, -1U, debugserver_xmm3, NULL, NULL},
- {e_regSetFPU, fpu_xmm4, "xmm4", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm4), FPU_OFFSET(xmm4), ehframe_dwarf_xmm4,
- ehframe_dwarf_xmm4, -1U, debugserver_xmm4, NULL, NULL},
- {e_regSetFPU, fpu_xmm5, "xmm5", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm5), FPU_OFFSET(xmm5), ehframe_dwarf_xmm5,
- ehframe_dwarf_xmm5, -1U, debugserver_xmm5, NULL, NULL},
- {e_regSetFPU, fpu_xmm6, "xmm6", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm6), FPU_OFFSET(xmm6), ehframe_dwarf_xmm6,
- ehframe_dwarf_xmm6, -1U, debugserver_xmm6, NULL, NULL},
- {e_regSetFPU, fpu_xmm7, "xmm7", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm7), FPU_OFFSET(xmm7), ehframe_dwarf_xmm7,
- ehframe_dwarf_xmm7, -1U, debugserver_xmm7, NULL, NULL},
- {e_regSetFPU, fpu_xmm8, "xmm8", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm8), FPU_OFFSET(xmm8), ehframe_dwarf_xmm8,
- ehframe_dwarf_xmm8, -1U, debugserver_xmm8, NULL, NULL},
- {e_regSetFPU, fpu_xmm9, "xmm9", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm9), FPU_OFFSET(xmm9), ehframe_dwarf_xmm9,
- ehframe_dwarf_xmm9, -1U, debugserver_xmm9, NULL, NULL},
- {e_regSetFPU, fpu_xmm10, "xmm10", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm10), FPU_OFFSET(xmm10), ehframe_dwarf_xmm10,
- ehframe_dwarf_xmm10, -1U, debugserver_xmm10, NULL, NULL},
- {e_regSetFPU, fpu_xmm11, "xmm11", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm11), FPU_OFFSET(xmm11), ehframe_dwarf_xmm11,
- ehframe_dwarf_xmm11, -1U, debugserver_xmm11, NULL, NULL},
- {e_regSetFPU, fpu_xmm12, "xmm12", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm12), FPU_OFFSET(xmm12), ehframe_dwarf_xmm12,
- ehframe_dwarf_xmm12, -1U, debugserver_xmm12, NULL, NULL},
- {e_regSetFPU, fpu_xmm13, "xmm13", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm13), FPU_OFFSET(xmm13), ehframe_dwarf_xmm13,
- ehframe_dwarf_xmm13, -1U, debugserver_xmm13, NULL, NULL},
- {e_regSetFPU, fpu_xmm14, "xmm14", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm14), FPU_OFFSET(xmm14), ehframe_dwarf_xmm14,
- ehframe_dwarf_xmm14, -1U, debugserver_xmm14, NULL, NULL},
- {e_regSetFPU, fpu_xmm15, "xmm15", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm15), FPU_OFFSET(xmm15), ehframe_dwarf_xmm15,
- ehframe_dwarf_xmm15, -1U, debugserver_xmm15, NULL, NULL},
-};
-
-static const char *g_contained_ymm0[] = {"ymm0", NULL};
-static const char *g_contained_ymm1[] = {"ymm1", NULL};
-static const char *g_contained_ymm2[] = {"ymm2", NULL};
-static const char *g_contained_ymm3[] = {"ymm3", NULL};
-static const char *g_contained_ymm4[] = {"ymm4", NULL};
-static const char *g_contained_ymm5[] = {"ymm5", NULL};
-static const char *g_contained_ymm6[] = {"ymm6", NULL};
-static const char *g_contained_ymm7[] = {"ymm7", NULL};
-static const char *g_contained_ymm8[] = {"ymm8", NULL};
-static const char *g_contained_ymm9[] = {"ymm9", NULL};
-static const char *g_contained_ymm10[] = {"ymm10", NULL};
-static const char *g_contained_ymm11[] = {"ymm11", NULL};
-static const char *g_contained_ymm12[] = {"ymm12", NULL};
-static const char *g_contained_ymm13[] = {"ymm13", NULL};
-static const char *g_contained_ymm14[] = {"ymm14", NULL};
-static const char *g_contained_ymm15[] = {"ymm15", NULL};
-
-const DNBRegisterInfo DNBArchImplX86_64::g_fpu_registers_avx[] = {
- {e_regSetFPU, fpu_fcw, "fctrl", NULL, Uint, Hex, FPU_SIZE_UINT(fcw),
- AVX_OFFSET(fcw), -1U, -1U, -1U, -1U, NULL, NULL},
- {e_regSetFPU, fpu_fsw, "fstat", NULL, Uint, Hex, FPU_SIZE_UINT(fsw),
- AVX_OFFSET(fsw), -1U, -1U, -1U, -1U, NULL, NULL},
- {e_regSetFPU, fpu_ftw, "ftag", NULL, Uint, Hex, 2 /* sizeof __fpu_ftw + sizeof __fpu_rsrv1 */,
- AVX_OFFSET(ftw), -1U, -1U, -1U, -1U, NULL, NULL},
- {e_regSetFPU, fpu_fop, "fop", NULL, Uint, Hex, FPU_SIZE_UINT(fop),
- AVX_OFFSET(fop), -1U, -1U, -1U, -1U, NULL, NULL},
- {e_regSetFPU, fpu_ip, "fioff", NULL, Uint, Hex, FPU_SIZE_UINT(ip),
- AVX_OFFSET(ip), -1U, -1U, -1U, -1U, NULL, NULL},
- {e_regSetFPU, fpu_cs, "fiseg", NULL, Uint, Hex, FPU_SIZE_UINT(cs),
- AVX_OFFSET(cs), -1U, -1U, -1U, -1U, NULL, NULL},
- {e_regSetFPU, fpu_dp, "fooff", NULL, Uint, Hex, FPU_SIZE_UINT(dp),
- AVX_OFFSET(dp), -1U, -1U, -1U, -1U, NULL, NULL},
- {e_regSetFPU, fpu_ds, "foseg", NULL, Uint, Hex, FPU_SIZE_UINT(ds),
- AVX_OFFSET(ds), -1U, -1U, -1U, -1U, NULL, NULL},
- {e_regSetFPU, fpu_mxcsr, "mxcsr", NULL, Uint, Hex, FPU_SIZE_UINT(mxcsr),
- AVX_OFFSET(mxcsr), -1U, -1U, -1U, -1U, NULL, NULL},
- {e_regSetFPU, fpu_mxcsrmask, "mxcsrmask", NULL, Uint, Hex,
- FPU_SIZE_UINT(mxcsrmask), AVX_OFFSET(mxcsrmask), -1U, -1U, -1U, -1U, NULL,
- NULL},
-
- {e_regSetFPU, fpu_stmm0, "stmm0", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm0), AVX_OFFSET(stmm0), ehframe_dwarf_stmm0,
- ehframe_dwarf_stmm0, -1U, debugserver_stmm0, NULL, NULL},
- {e_regSetFPU, fpu_stmm1, "stmm1", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm1), AVX_OFFSET(stmm1), ehframe_dwarf_stmm1,
- ehframe_dwarf_stmm1, -1U, debugserver_stmm1, NULL, NULL},
- {e_regSetFPU, fpu_stmm2, "stmm2", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm2), AVX_OFFSET(stmm2), ehframe_dwarf_stmm2,
- ehframe_dwarf_stmm2, -1U, debugserver_stmm2, NULL, NULL},
- {e_regSetFPU, fpu_stmm3, "stmm3", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm3), AVX_OFFSET(stmm3), ehframe_dwarf_stmm3,
- ehframe_dwarf_stmm3, -1U, debugserver_stmm3, NULL, NULL},
- {e_regSetFPU, fpu_stmm4, "stmm4", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm4), AVX_OFFSET(stmm4), ehframe_dwarf_stmm4,
- ehframe_dwarf_stmm4, -1U, debugserver_stmm4, NULL, NULL},
- {e_regSetFPU, fpu_stmm5, "stmm5", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm5), AVX_OFFSET(stmm5), ehframe_dwarf_stmm5,
- ehframe_dwarf_stmm5, -1U, debugserver_stmm5, NULL, NULL},
- {e_regSetFPU, fpu_stmm6, "stmm6", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm6), AVX_OFFSET(stmm6), ehframe_dwarf_stmm6,
- ehframe_dwarf_stmm6, -1U, debugserver_stmm6, NULL, NULL},
- {e_regSetFPU, fpu_stmm7, "stmm7", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm7), AVX_OFFSET(stmm7), ehframe_dwarf_stmm7,
- ehframe_dwarf_stmm7, -1U, debugserver_stmm7, NULL, NULL},
-
- {e_regSetFPU, fpu_ymm0, "ymm0", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_YMM(ymm0), AVX_OFFSET_YMM(0), ehframe_dwarf_ymm0,
- ehframe_dwarf_ymm0, -1U, debugserver_ymm0, NULL, NULL},
- {e_regSetFPU, fpu_ymm1, "ymm1", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_YMM(ymm1), AVX_OFFSET_YMM(1), ehframe_dwarf_ymm1,
- ehframe_dwarf_ymm1, -1U, debugserver_ymm1, NULL, NULL},
- {e_regSetFPU, fpu_ymm2, "ymm2", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_YMM(ymm2), AVX_OFFSET_YMM(2), ehframe_dwarf_ymm2,
- ehframe_dwarf_ymm2, -1U, debugserver_ymm2, NULL, NULL},
- {e_regSetFPU, fpu_ymm3, "ymm3", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_YMM(ymm3), AVX_OFFSET_YMM(3), ehframe_dwarf_ymm3,
- ehframe_dwarf_ymm3, -1U, debugserver_ymm3, NULL, NULL},
- {e_regSetFPU, fpu_ymm4, "ymm4", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_YMM(ymm4), AVX_OFFSET_YMM(4), ehframe_dwarf_ymm4,
- ehframe_dwarf_ymm4, -1U, debugserver_ymm4, NULL, NULL},
- {e_regSetFPU, fpu_ymm5, "ymm5", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_YMM(ymm5), AVX_OFFSET_YMM(5), ehframe_dwarf_ymm5,
- ehframe_dwarf_ymm5, -1U, debugserver_ymm5, NULL, NULL},
- {e_regSetFPU, fpu_ymm6, "ymm6", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_YMM(ymm6), AVX_OFFSET_YMM(6), ehframe_dwarf_ymm6,
- ehframe_dwarf_ymm6, -1U, debugserver_ymm6, NULL, NULL},
- {e_regSetFPU, fpu_ymm7, "ymm7", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_YMM(ymm7), AVX_OFFSET_YMM(7), ehframe_dwarf_ymm7,
- ehframe_dwarf_ymm7, -1U, debugserver_ymm7, NULL, NULL},
- {e_regSetFPU, fpu_ymm8, "ymm8", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_YMM(ymm8), AVX_OFFSET_YMM(8), ehframe_dwarf_ymm8,
- ehframe_dwarf_ymm8, -1U, debugserver_ymm8, NULL, NULL},
- {e_regSetFPU, fpu_ymm9, "ymm9", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_YMM(ymm9), AVX_OFFSET_YMM(9), ehframe_dwarf_ymm9,
- ehframe_dwarf_ymm9, -1U, debugserver_ymm9, NULL, NULL},
- {e_regSetFPU, fpu_ymm10, "ymm10", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_YMM(ymm10), AVX_OFFSET_YMM(10), ehframe_dwarf_ymm10,
- ehframe_dwarf_ymm10, -1U, debugserver_ymm10, NULL, NULL},
- {e_regSetFPU, fpu_ymm11, "ymm11", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_YMM(ymm11), AVX_OFFSET_YMM(11), ehframe_dwarf_ymm11,
- ehframe_dwarf_ymm11, -1U, debugserver_ymm11, NULL, NULL},
- {e_regSetFPU, fpu_ymm12, "ymm12", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_YMM(ymm12), AVX_OFFSET_YMM(12), ehframe_dwarf_ymm12,
- ehframe_dwarf_ymm12, -1U, debugserver_ymm12, NULL, NULL},
- {e_regSetFPU, fpu_ymm13, "ymm13", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_YMM(ymm13), AVX_OFFSET_YMM(13), ehframe_dwarf_ymm13,
- ehframe_dwarf_ymm13, -1U, debugserver_ymm13, NULL, NULL},
- {e_regSetFPU, fpu_ymm14, "ymm14", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_YMM(ymm14), AVX_OFFSET_YMM(14), ehframe_dwarf_ymm14,
- ehframe_dwarf_ymm14, -1U, debugserver_ymm14, NULL, NULL},
- {e_regSetFPU, fpu_ymm15, "ymm15", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_YMM(ymm15), AVX_OFFSET_YMM(15), ehframe_dwarf_ymm15,
- ehframe_dwarf_ymm15, -1U, debugserver_ymm15, NULL, NULL},
-
- {e_regSetFPU, fpu_xmm0, "xmm0", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm0), 0, ehframe_dwarf_xmm0, ehframe_dwarf_xmm0, -1U,
- debugserver_xmm0, g_contained_ymm0, NULL},
- {e_regSetFPU, fpu_xmm1, "xmm1", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm1), 0, ehframe_dwarf_xmm1, ehframe_dwarf_xmm1, -1U,
- debugserver_xmm1, g_contained_ymm1, NULL},
- {e_regSetFPU, fpu_xmm2, "xmm2", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm2), 0, ehframe_dwarf_xmm2, ehframe_dwarf_xmm2, -1U,
- debugserver_xmm2, g_contained_ymm2, NULL},
- {e_regSetFPU, fpu_xmm3, "xmm3", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm3), 0, ehframe_dwarf_xmm3, ehframe_dwarf_xmm3, -1U,
- debugserver_xmm3, g_contained_ymm3, NULL},
- {e_regSetFPU, fpu_xmm4, "xmm4", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm4), 0, ehframe_dwarf_xmm4, ehframe_dwarf_xmm4, -1U,
- debugserver_xmm4, g_contained_ymm4, NULL},
- {e_regSetFPU, fpu_xmm5, "xmm5", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm5), 0, ehframe_dwarf_xmm5, ehframe_dwarf_xmm5, -1U,
- debugserver_xmm5, g_contained_ymm5, NULL},
- {e_regSetFPU, fpu_xmm6, "xmm6", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm6), 0, ehframe_dwarf_xmm6, ehframe_dwarf_xmm6, -1U,
- debugserver_xmm6, g_contained_ymm6, NULL},
- {e_regSetFPU, fpu_xmm7, "xmm7", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm7), 0, ehframe_dwarf_xmm7, ehframe_dwarf_xmm7, -1U,
- debugserver_xmm7, g_contained_ymm7, NULL},
- {e_regSetFPU, fpu_xmm8, "xmm8", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm8), 0, ehframe_dwarf_xmm8, ehframe_dwarf_xmm8, -1U,
- debugserver_xmm8, g_contained_ymm8, NULL},
- {e_regSetFPU, fpu_xmm9, "xmm9", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm9), 0, ehframe_dwarf_xmm9, ehframe_dwarf_xmm9, -1U,
- debugserver_xmm9, g_contained_ymm9, NULL},
- {e_regSetFPU, fpu_xmm10, "xmm10", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm10), 0, ehframe_dwarf_xmm10, ehframe_dwarf_xmm10, -1U,
- debugserver_xmm10, g_contained_ymm10, NULL},
- {e_regSetFPU, fpu_xmm11, "xmm11", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm11), 0, ehframe_dwarf_xmm11, ehframe_dwarf_xmm11, -1U,
- debugserver_xmm11, g_contained_ymm11, NULL},
- {e_regSetFPU, fpu_xmm12, "xmm12", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm12), 0, ehframe_dwarf_xmm12, ehframe_dwarf_xmm12, -1U,
- debugserver_xmm12, g_contained_ymm12, NULL},
- {e_regSetFPU, fpu_xmm13, "xmm13", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm13), 0, ehframe_dwarf_xmm13, ehframe_dwarf_xmm13, -1U,
- debugserver_xmm13, g_contained_ymm13, NULL},
- {e_regSetFPU, fpu_xmm14, "xmm14", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm14), 0, ehframe_dwarf_xmm14, ehframe_dwarf_xmm14, -1U,
- debugserver_xmm14, g_contained_ymm14, NULL},
- {e_regSetFPU, fpu_xmm15, "xmm15", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_XMM(xmm15), 0, ehframe_dwarf_xmm15, ehframe_dwarf_xmm15, -1U,
- debugserver_xmm15, g_contained_ymm15, NULL}
-
-};
-
-static const char *g_contained_zmm0[] = {"zmm0", NULL};
-static const char *g_contained_zmm1[] = {"zmm1", NULL};
-static const char *g_contained_zmm2[] = {"zmm2", NULL};
-static const char *g_contained_zmm3[] = {"zmm3", NULL};
-static const char *g_contained_zmm4[] = {"zmm4", NULL};
-static const char *g_contained_zmm5[] = {"zmm5", NULL};
-static const char *g_contained_zmm6[] = {"zmm6", NULL};
-static const char *g_contained_zmm7[] = {"zmm7", NULL};
-static const char *g_contained_zmm8[] = {"zmm8", NULL};
-static const char *g_contained_zmm9[] = {"zmm9", NULL};
-static const char *g_contained_zmm10[] = {"zmm10", NULL};
-static const char *g_contained_zmm11[] = {"zmm11", NULL};
-static const char *g_contained_zmm12[] = {"zmm12", NULL};
-static const char *g_contained_zmm13[] = {"zmm13", NULL};
-static const char *g_contained_zmm14[] = {"zmm14", NULL};
-static const char *g_contained_zmm15[] = {"zmm15", NULL};
-
-#define STR(s) #s
-
-#define ZMM_REG_DEF(reg) \
- { \
- e_regSetFPU, fpu_zmm##reg, STR(zmm##reg), NULL, Vector, VectorOfUInt8, \
- FPU_SIZE_ZMM(zmm##reg), AVX512F_OFFSET_ZMM(reg), \
- ehframe_dwarf_zmm##reg, ehframe_dwarf_zmm##reg, -1U, \
- debugserver_zmm##reg, NULL, NULL \
- }
-
-#define YMM_REG_ALIAS(reg) \
- { \
- e_regSetFPU, fpu_ymm##reg, STR(ymm##reg), NULL, Vector, VectorOfUInt8, \
- FPU_SIZE_YMM(ymm##reg), 0, ehframe_dwarf_ymm##reg, \
- ehframe_dwarf_ymm##reg, -1U, debugserver_ymm##reg, \
- g_contained_zmm##reg, NULL \
- }
-
-#define XMM_REG_ALIAS(reg) \
- { \
- e_regSetFPU, fpu_xmm##reg, STR(xmm##reg), NULL, Vector, VectorOfUInt8, \
- FPU_SIZE_XMM(xmm##reg), 0, ehframe_dwarf_xmm##reg, \
- ehframe_dwarf_xmm##reg, -1U, debugserver_xmm##reg, \
- g_contained_zmm##reg, NULL \
- }
-
-#define AVX512_K_REG_DEF(reg) \
- { \
- e_regSetFPU, fpu_k##reg, STR(k##reg), NULL, Vector, VectorOfUInt8, 8, \
- AVX512F_OFFSET(k##reg), ehframe_dwarf_k##reg, ehframe_dwarf_k##reg, \
- -1U, debugserver_k##reg, NULL, NULL \
- }
-
-const DNBRegisterInfo DNBArchImplX86_64::g_fpu_registers_avx512f[] = {
- {e_regSetFPU, fpu_fcw, "fctrl", NULL, Uint, Hex, FPU_SIZE_UINT(fcw),
- AVX_OFFSET(fcw), -1U, -1U, -1U, -1U, NULL, NULL},
- {e_regSetFPU, fpu_fsw, "fstat", NULL, Uint, Hex, FPU_SIZE_UINT(fsw),
- AVX_OFFSET(fsw), -1U, -1U, -1U, -1U, NULL, NULL},
- {e_regSetFPU, fpu_ftw, "ftag", NULL, Uint, Hex, 2 /* sizeof __fpu_ftw + sizeof __fpu_rsrv1 */,
- AVX_OFFSET(ftw), -1U, -1U, -1U, -1U, NULL, NULL},
- {e_regSetFPU, fpu_fop, "fop", NULL, Uint, Hex, FPU_SIZE_UINT(fop),
- AVX_OFFSET(fop), -1U, -1U, -1U, -1U, NULL, NULL},
- {e_regSetFPU, fpu_ip, "fioff", NULL, Uint, Hex, FPU_SIZE_UINT(ip),
- AVX_OFFSET(ip), -1U, -1U, -1U, -1U, NULL, NULL},
- {e_regSetFPU, fpu_cs, "fiseg", NULL, Uint, Hex, FPU_SIZE_UINT(cs),
- AVX_OFFSET(cs), -1U, -1U, -1U, -1U, NULL, NULL},
- {e_regSetFPU, fpu_dp, "fooff", NULL, Uint, Hex, FPU_SIZE_UINT(dp),
- AVX_OFFSET(dp), -1U, -1U, -1U, -1U, NULL, NULL},
- {e_regSetFPU, fpu_ds, "foseg", NULL, Uint, Hex, FPU_SIZE_UINT(ds),
- AVX_OFFSET(ds), -1U, -1U, -1U, -1U, NULL, NULL},
- {e_regSetFPU, fpu_mxcsr, "mxcsr", NULL, Uint, Hex, FPU_SIZE_UINT(mxcsr),
- AVX_OFFSET(mxcsr), -1U, -1U, -1U, -1U, NULL, NULL},
- {e_regSetFPU, fpu_mxcsrmask, "mxcsrmask", NULL, Uint, Hex,
- FPU_SIZE_UINT(mxcsrmask), AVX_OFFSET(mxcsrmask), -1U, -1U, -1U, -1U, NULL,
- NULL},
-
- {e_regSetFPU, fpu_stmm0, "stmm0", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm0), AVX_OFFSET(stmm0), ehframe_dwarf_stmm0,
- ehframe_dwarf_stmm0, -1U, debugserver_stmm0, NULL, NULL},
- {e_regSetFPU, fpu_stmm1, "stmm1", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm1), AVX_OFFSET(stmm1), ehframe_dwarf_stmm1,
- ehframe_dwarf_stmm1, -1U, debugserver_stmm1, NULL, NULL},
- {e_regSetFPU, fpu_stmm2, "stmm2", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm2), AVX_OFFSET(stmm2), ehframe_dwarf_stmm2,
- ehframe_dwarf_stmm2, -1U, debugserver_stmm2, NULL, NULL},
- {e_regSetFPU, fpu_stmm3, "stmm3", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm3), AVX_OFFSET(stmm3), ehframe_dwarf_stmm3,
- ehframe_dwarf_stmm3, -1U, debugserver_stmm3, NULL, NULL},
- {e_regSetFPU, fpu_stmm4, "stmm4", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm4), AVX_OFFSET(stmm4), ehframe_dwarf_stmm4,
- ehframe_dwarf_stmm4, -1U, debugserver_stmm4, NULL, NULL},
- {e_regSetFPU, fpu_stmm5, "stmm5", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm5), AVX_OFFSET(stmm5), ehframe_dwarf_stmm5,
- ehframe_dwarf_stmm5, -1U, debugserver_stmm5, NULL, NULL},
- {e_regSetFPU, fpu_stmm6, "stmm6", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm6), AVX_OFFSET(stmm6), ehframe_dwarf_stmm6,
- ehframe_dwarf_stmm6, -1U, debugserver_stmm6, NULL, NULL},
- {e_regSetFPU, fpu_stmm7, "stmm7", NULL, Vector, VectorOfUInt8,
- FPU_SIZE_MMST(stmm7), AVX_OFFSET(stmm7), ehframe_dwarf_stmm7,
- ehframe_dwarf_stmm7, -1U, debugserver_stmm7, NULL, NULL},
-
- AVX512_K_REG_DEF(0),
- AVX512_K_REG_DEF(1),
- AVX512_K_REG_DEF(2),
- AVX512_K_REG_DEF(3),
- AVX512_K_REG_DEF(4),
- AVX512_K_REG_DEF(5),
- AVX512_K_REG_DEF(6),
- AVX512_K_REG_DEF(7),
-
- ZMM_REG_DEF(0),
- ZMM_REG_DEF(1),
- ZMM_REG_DEF(2),
- ZMM_REG_DEF(3),
- ZMM_REG_DEF(4),
- ZMM_REG_DEF(5),
- ZMM_REG_DEF(6),
- ZMM_REG_DEF(7),
- ZMM_REG_DEF(8),
- ZMM_REG_DEF(9),
- ZMM_REG_DEF(10),
- ZMM_REG_DEF(11),
- ZMM_REG_DEF(12),
- ZMM_REG_DEF(13),
- ZMM_REG_DEF(14),
- ZMM_REG_DEF(15),
- ZMM_REG_DEF(16),
- ZMM_REG_DEF(17),
- ZMM_REG_DEF(18),
- ZMM_REG_DEF(19),
- ZMM_REG_DEF(20),
- ZMM_REG_DEF(21),
- ZMM_REG_DEF(22),
- ZMM_REG_DEF(23),
- ZMM_REG_DEF(24),
- ZMM_REG_DEF(25),
- ZMM_REG_DEF(26),
- ZMM_REG_DEF(27),
- ZMM_REG_DEF(28),
- ZMM_REG_DEF(29),
- ZMM_REG_DEF(30),
- ZMM_REG_DEF(31),
-
- YMM_REG_ALIAS(0),
- YMM_REG_ALIAS(1),
- YMM_REG_ALIAS(2),
- YMM_REG_ALIAS(3),
- YMM_REG_ALIAS(4),
- YMM_REG_ALIAS(5),
- YMM_REG_ALIAS(6),
- YMM_REG_ALIAS(7),
- YMM_REG_ALIAS(8),
- YMM_REG_ALIAS(9),
- YMM_REG_ALIAS(10),
- YMM_REG_ALIAS(11),
- YMM_REG_ALIAS(12),
- YMM_REG_ALIAS(13),
- YMM_REG_ALIAS(14),
- YMM_REG_ALIAS(15),
-
- XMM_REG_ALIAS(0),
- XMM_REG_ALIAS(1),
- XMM_REG_ALIAS(2),
- XMM_REG_ALIAS(3),
- XMM_REG_ALIAS(4),
- XMM_REG_ALIAS(5),
- XMM_REG_ALIAS(6),
- XMM_REG_ALIAS(7),
- XMM_REG_ALIAS(8),
- XMM_REG_ALIAS(9),
- XMM_REG_ALIAS(10),
- XMM_REG_ALIAS(11),
- XMM_REG_ALIAS(12),
- XMM_REG_ALIAS(13),
- XMM_REG_ALIAS(14),
- XMM_REG_ALIAS(15),
-
-};
-
-
-// Exception registers
-
-const DNBRegisterInfo DNBArchImplX86_64::g_exc_registers[] = {
- {e_regSetEXC, exc_trapno, "trapno", NULL, Uint, Hex, EXC_SIZE(trapno),
- EXC_OFFSET(trapno), -1U, -1U, -1U, -1U, NULL, NULL},
- {e_regSetEXC, exc_err, "err", NULL, Uint, Hex, EXC_SIZE(err),
- EXC_OFFSET(err), -1U, -1U, -1U, -1U, NULL, NULL},
- {e_regSetEXC, exc_faultvaddr, "faultvaddr", NULL, Uint, Hex,
- EXC_SIZE(faultvaddr), EXC_OFFSET(faultvaddr), -1U, -1U, -1U, -1U, NULL,
- NULL}};
-
-// Number of registers in each register set
-const size_t DNBArchImplX86_64::k_num_gpr_registers =
- sizeof(g_gpr_registers) / sizeof(DNBRegisterInfo);
-const size_t DNBArchImplX86_64::k_num_fpu_registers_no_avx =
- sizeof(g_fpu_registers_no_avx) / sizeof(DNBRegisterInfo);
-const size_t DNBArchImplX86_64::k_num_fpu_registers_avx =
- sizeof(g_fpu_registers_avx) / sizeof(DNBRegisterInfo);
-const size_t DNBArchImplX86_64::k_num_exc_registers =
- sizeof(g_exc_registers) / sizeof(DNBRegisterInfo);
-const size_t DNBArchImplX86_64::k_num_all_registers_no_avx =
- k_num_gpr_registers + k_num_fpu_registers_no_avx + k_num_exc_registers;
-const size_t DNBArchImplX86_64::k_num_all_registers_avx =
- k_num_gpr_registers + k_num_fpu_registers_avx + k_num_exc_registers;
-const size_t DNBArchImplX86_64::k_num_fpu_registers_avx512f =
- sizeof(g_fpu_registers_avx512f) / sizeof(DNBRegisterInfo);
-const size_t DNBArchImplX86_64::k_num_all_registers_avx512f =
- k_num_gpr_registers + k_num_fpu_registers_avx512f + 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 DNBArchImplX86_64::g_reg_sets_no_avx[] = {
- {"x86_64 Registers", NULL, k_num_all_registers_no_avx},
- {"General Purpose Registers", g_gpr_registers, k_num_gpr_registers},
- {"Floating Point Registers", g_fpu_registers_no_avx,
- k_num_fpu_registers_no_avx},
- {"Exception State Registers", g_exc_registers, k_num_exc_registers}};
-
-const DNBRegisterSetInfo DNBArchImplX86_64::g_reg_sets_avx[] = {
- {"x86_64 Registers", NULL, k_num_all_registers_avx},
- {"General Purpose Registers", g_gpr_registers, k_num_gpr_registers},
- {"Floating Point Registers", g_fpu_registers_avx, k_num_fpu_registers_avx},
- {"Exception State Registers", g_exc_registers, k_num_exc_registers}};
-
-const DNBRegisterSetInfo DNBArchImplX86_64::g_reg_sets_avx512f[] = {
- {"x86_64 Registers", NULL, k_num_all_registers_avx},
- {"General Purpose Registers", g_gpr_registers, k_num_gpr_registers},
- {"Floating Point Registers", g_fpu_registers_avx512f,
- k_num_fpu_registers_avx512f},
- {"Exception State Registers", g_exc_registers, k_num_exc_registers}};
-
-// Total number of register sets for this architecture
-const size_t DNBArchImplX86_64::k_num_register_sets =
- sizeof(g_reg_sets_avx) / sizeof(DNBRegisterSetInfo);
-
-DNBArchProtocol *DNBArchImplX86_64::Create(MachThread *thread) {
- DNBArchImplX86_64 *obj = new DNBArchImplX86_64(thread);
- return obj;
-}
-
-const uint8_t *
-DNBArchImplX86_64::SoftwareBreakpointOpcode(nub_size_t byte_size) {
- static const uint8_t g_breakpoint_opcode[] = {0xCC};
- if (byte_size == 1)
- return g_breakpoint_opcode;
- return NULL;
-}
-
-const DNBRegisterSetInfo *
-DNBArchImplX86_64::GetRegisterSetInfo(nub_size_t *num_reg_sets) {
- *num_reg_sets = k_num_register_sets;
-
- if (CPUHasAVX512f() || FORCE_AVX_REGS)
- return g_reg_sets_avx512f;
- if (CPUHasAVX() || FORCE_AVX_REGS)
- return g_reg_sets_avx;
- else
- return g_reg_sets_no_avx;
-}
-
-void DNBArchImplX86_64::Initialize() {
- DNBArchPluginInfo arch_plugin_info = {
- CPU_TYPE_X86_64, DNBArchImplX86_64::Create,
- DNBArchImplX86_64::GetRegisterSetInfo,
- DNBArchImplX86_64::SoftwareBreakpointOpcode};
-
- // Register this arch plug-in with the main protocol class
- DNBArchProtocol::RegisterArchPlugin(arch_plugin_info);
-}
-
-bool DNBArchImplX86_64::GetRegisterValue(uint32_t set, uint32_t reg,
- DNBRegisterValue *value) {
- if (set == REGISTER_SET_GENERIC) {
- switch (reg) {
- case GENERIC_REGNUM_PC: // Program Counter
- set = e_regSetGPR;
- reg = gpr_rip;
- break;
-
- case GENERIC_REGNUM_SP: // Stack Pointer
- set = e_regSetGPR;
- reg = gpr_rsp;
- break;
-
- case GENERIC_REGNUM_FP: // Frame Pointer
- set = e_regSetGPR;
- reg = gpr_rbp;
- break;
-
- case GENERIC_REGNUM_FLAGS: // Processor flags register
- set = e_regSetGPR;
- reg = gpr_rflags;
- break;
-
- case GENERIC_REGNUM_RA: // Return Address
- default:
- 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 < k_num_gpr_registers) {
- value->value.uint64 = ((uint64_t *)(&m_state.context.gpr))[reg];
- return true;
- }
- break;
-
- case e_regSetFPU:
- if (reg > fpu_xmm15 && !(CPUHasAVX() || FORCE_AVX_REGS))
- return false;
- if (reg > fpu_ymm15 && !(CPUHasAVX512f() || FORCE_AVX_REGS))
- return false;
- switch (reg) {
-
- case fpu_fcw:
- value->value.uint16 =
- *((uint16_t *)(&m_state.context.fpu.no_avx.__fpu_fcw));
- return true;
- case fpu_fsw:
- value->value.uint16 =
- *((uint16_t *)(&m_state.context.fpu.no_avx.__fpu_fsw));
- return true;
- case fpu_ftw:
- memcpy (&value->value.uint16, &m_state.context.fpu.no_avx.__fpu_ftw, 2);
- return true;
- case fpu_fop:
- value->value.uint16 = m_state.context.fpu.no_avx.__fpu_fop;
- return true;
- case fpu_ip:
- value->value.uint32 = m_state.context.fpu.no_avx.__fpu_ip;
- return true;
- case fpu_cs:
- value->value.uint16 = m_state.context.fpu.no_avx.__fpu_cs;
- return true;
- case fpu_dp:
- value->value.uint32 = m_state.context.fpu.no_avx.__fpu_dp;
- return true;
- case fpu_ds:
- value->value.uint16 = m_state.context.fpu.no_avx.__fpu_ds;
- return true;
- case fpu_mxcsr:
- value->value.uint32 = m_state.context.fpu.no_avx.__fpu_mxcsr;
- return true;
- case fpu_mxcsrmask:
- value->value.uint32 = m_state.context.fpu.no_avx.__fpu_mxcsrmask;
- return true;
-
- case fpu_stmm0:
- case fpu_stmm1:
- case fpu_stmm2:
- case fpu_stmm3:
- case fpu_stmm4:
- case fpu_stmm5:
- case fpu_stmm6:
- case fpu_stmm7:
- memcpy(&value->value.uint8,
- &m_state.context.fpu.no_avx.__fpu_stmm0 + (reg - fpu_stmm0), 10);
- return true;
-
- case fpu_xmm0:
- case fpu_xmm1:
- case fpu_xmm2:
- case fpu_xmm3:
- case fpu_xmm4:
- case fpu_xmm5:
- case fpu_xmm6:
- case fpu_xmm7:
- case fpu_xmm8:
- case fpu_xmm9:
- case fpu_xmm10:
- case fpu_xmm11:
- case fpu_xmm12:
- case fpu_xmm13:
- case fpu_xmm14:
- case fpu_xmm15:
- memcpy(&value->value.uint8,
- &m_state.context.fpu.no_avx.__fpu_xmm0 + (reg - fpu_xmm0), 16);
- return true;
-
- case fpu_ymm0:
- case fpu_ymm1:
- case fpu_ymm2:
- case fpu_ymm3:
- case fpu_ymm4:
- case fpu_ymm5:
- case fpu_ymm6:
- case fpu_ymm7:
- case fpu_ymm8:
- case fpu_ymm9:
- case fpu_ymm10:
- case fpu_ymm11:
- case fpu_ymm12:
- case fpu_ymm13:
- case fpu_ymm14:
- case fpu_ymm15:
- memcpy(&value->value.uint8,
- &m_state.context.fpu.avx.__fpu_xmm0 + (reg - fpu_ymm0), 16);
- memcpy((&value->value.uint8) + 16,
- &m_state.context.fpu.avx.__fpu_ymmh0 + (reg - fpu_ymm0), 16);
- return true;
- case fpu_k0:
- case fpu_k1:
- case fpu_k2:
- case fpu_k3:
- case fpu_k4:
- case fpu_k5:
- case fpu_k6:
- case fpu_k7:
- memcpy((&value->value.uint8),
- &m_state.context.fpu.avx512f.__fpu_k0 + (reg - fpu_k0), 8);
- return true;
- case fpu_zmm0:
- case fpu_zmm1:
- case fpu_zmm2:
- case fpu_zmm3:
- case fpu_zmm4:
- case fpu_zmm5:
- case fpu_zmm6:
- case fpu_zmm7:
- case fpu_zmm8:
- case fpu_zmm9:
- case fpu_zmm10:
- case fpu_zmm11:
- case fpu_zmm12:
- case fpu_zmm13:
- case fpu_zmm14:
- case fpu_zmm15:
- memcpy(&value->value.uint8,
- &m_state.context.fpu.avx512f.__fpu_xmm0 + (reg - fpu_zmm0), 16);
- memcpy((&value->value.uint8) + 16,
- &m_state.context.fpu.avx512f.__fpu_ymmh0 + (reg - fpu_zmm0), 16);
- memcpy((&value->value.uint8) + 32,
- &m_state.context.fpu.avx512f.__fpu_zmmh0 + (reg - fpu_zmm0), 32);
- return true;
- case fpu_zmm16:
- case fpu_zmm17:
- case fpu_zmm18:
- case fpu_zmm19:
- case fpu_zmm20:
- case fpu_zmm21:
- case fpu_zmm22:
- case fpu_zmm23:
- case fpu_zmm24:
- case fpu_zmm25:
- case fpu_zmm26:
- case fpu_zmm27:
- case fpu_zmm28:
- case fpu_zmm29:
- case fpu_zmm30:
- case fpu_zmm31:
- memcpy(&value->value.uint8,
- &m_state.context.fpu.avx512f.__fpu_zmm16 + (reg - fpu_zmm16), 64);
- return true;
- }
- break;
-
- case e_regSetEXC:
- switch (reg) {
- case exc_trapno:
- value->value.uint32 = m_state.context.exc.__trapno;
- return true;
- case exc_err:
- value->value.uint32 = m_state.context.exc.__err;
- return true;
- case exc_faultvaddr:
- value->value.uint64 = m_state.context.exc.__faultvaddr;
- return true;
- }
- break;
- }
- }
- return false;
-}
-
-bool DNBArchImplX86_64::SetRegisterValue(uint32_t set, uint32_t reg,
- const DNBRegisterValue *value) {
- if (set == REGISTER_SET_GENERIC) {
- switch (reg) {
- case GENERIC_REGNUM_PC: // Program Counter
- set = e_regSetGPR;
- reg = gpr_rip;
- break;
-
- case GENERIC_REGNUM_SP: // Stack Pointer
- set = e_regSetGPR;
- reg = gpr_rsp;
- break;
-
- case GENERIC_REGNUM_FP: // Frame Pointer
- set = e_regSetGPR;
- reg = gpr_rbp;
- break;
-
- case GENERIC_REGNUM_FLAGS: // Processor flags register
- set = e_regSetGPR;
- reg = gpr_rflags;
- break;
-
- case GENERIC_REGNUM_RA: // Return Address
- default:
- 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 < k_num_gpr_registers) {
- ((uint64_t *)(&m_state.context.gpr))[reg] = value->value.uint64;
- success = true;
- }
- break;
- if (reg > fpu_xmm15 && !(CPUHasAVX() || FORCE_AVX_REGS))
- return false;
- if (reg > fpu_ymm15 && !(CPUHasAVX512f() || FORCE_AVX_REGS))
- return false;
- case e_regSetFPU:
- switch (reg) {
- case fpu_fcw:
- *((uint16_t *)(&m_state.context.fpu.no_avx.__fpu_fcw)) =
- value->value.uint16;
- success = true;
- break;
- case fpu_fsw:
- *((uint16_t *)(&m_state.context.fpu.no_avx.__fpu_fsw)) =
- value->value.uint16;
- success = true;
- break;
- case fpu_ftw:
- memcpy (&m_state.context.fpu.no_avx.__fpu_ftw, &value->value.uint8, 2);
- success = true;
- break;
- case fpu_fop:
- m_state.context.fpu.no_avx.__fpu_fop = value->value.uint16;
- success = true;
- break;
- case fpu_ip:
- m_state.context.fpu.no_avx.__fpu_ip = value->value.uint32;
- success = true;
- break;
- case fpu_cs:
- m_state.context.fpu.no_avx.__fpu_cs = value->value.uint16;
- success = true;
- break;
- case fpu_dp:
- m_state.context.fpu.no_avx.__fpu_dp = value->value.uint32;
- success = true;
- break;
- case fpu_ds:
- m_state.context.fpu.no_avx.__fpu_ds = value->value.uint16;
- success = true;
- break;
- case fpu_mxcsr:
- m_state.context.fpu.no_avx.__fpu_mxcsr = value->value.uint32;
- success = true;
- break;
- case fpu_mxcsrmask:
- m_state.context.fpu.no_avx.__fpu_mxcsrmask = value->value.uint32;
- success = true;
- break;
-
- case fpu_stmm0:
- case fpu_stmm1:
- case fpu_stmm2:
- case fpu_stmm3:
- case fpu_stmm4:
- case fpu_stmm5:
- case fpu_stmm6:
- case fpu_stmm7:
- memcpy(&m_state.context.fpu.no_avx.__fpu_stmm0 + (reg - fpu_stmm0),
- &value->value.uint8, 10);
- success = true;
- break;
-
- case fpu_xmm0:
- case fpu_xmm1:
- case fpu_xmm2:
- case fpu_xmm3:
- case fpu_xmm4:
- case fpu_xmm5:
- case fpu_xmm6:
- case fpu_xmm7:
- case fpu_xmm8:
- case fpu_xmm9:
- case fpu_xmm10:
- case fpu_xmm11:
- case fpu_xmm12:
- case fpu_xmm13:
- case fpu_xmm14:
- case fpu_xmm15:
- memcpy(&m_state.context.fpu.no_avx.__fpu_xmm0 + (reg - fpu_xmm0),
- &value->value.uint8, 16);
- success = true;
- break;
-
- case fpu_ymm0:
- case fpu_ymm1:
- case fpu_ymm2:
- case fpu_ymm3:
- case fpu_ymm4:
- case fpu_ymm5:
- case fpu_ymm6:
- case fpu_ymm7:
- case fpu_ymm8:
- case fpu_ymm9:
- case fpu_ymm10:
- case fpu_ymm11:
- case fpu_ymm12:
- case fpu_ymm13:
- case fpu_ymm14:
- case fpu_ymm15:
- memcpy(&m_state.context.fpu.avx.__fpu_xmm0 + (reg - fpu_ymm0),
- &value->value.uint8, 16);
- memcpy(&m_state.context.fpu.avx.__fpu_ymmh0 + (reg - fpu_ymm0),
- (&value->value.uint8) + 16, 16);
- return true;
- case fpu_k0:
- case fpu_k1:
- case fpu_k2:
- case fpu_k3:
- case fpu_k4:
- case fpu_k5:
- case fpu_k6:
- case fpu_k7:
- memcpy(&m_state.context.fpu.avx512f.__fpu_k0 + (reg - fpu_k0),
- &value->value.uint8, 8);
- return true;
- case fpu_zmm0:
- case fpu_zmm1:
- case fpu_zmm2:
- case fpu_zmm3:
- case fpu_zmm4:
- case fpu_zmm5:
- case fpu_zmm6:
- case fpu_zmm7:
- case fpu_zmm8:
- case fpu_zmm9:
- case fpu_zmm10:
- case fpu_zmm11:
- case fpu_zmm12:
- case fpu_zmm13:
- case fpu_zmm14:
- case fpu_zmm15:
- memcpy(&m_state.context.fpu.avx512f.__fpu_xmm0 + (reg - fpu_zmm0),
- &value->value.uint8, 16);
- memcpy(&m_state.context.fpu.avx512f.__fpu_ymmh0 + (reg - fpu_zmm0),
- &value->value.uint8 + 16, 16);
- memcpy(&m_state.context.fpu.avx512f.__fpu_zmmh0 + (reg - fpu_zmm0),
- &value->value.uint8 + 32, 32);
- return true;
- case fpu_zmm16:
- case fpu_zmm17:
- case fpu_zmm18:
- case fpu_zmm19:
- case fpu_zmm20:
- case fpu_zmm21:
- case fpu_zmm22:
- case fpu_zmm23:
- case fpu_zmm24:
- case fpu_zmm25:
- case fpu_zmm26:
- case fpu_zmm27:
- case fpu_zmm28:
- case fpu_zmm29:
- case fpu_zmm30:
- case fpu_zmm31:
- memcpy(&m_state.context.fpu.avx512f.__fpu_zmm16 + (reg - fpu_zmm16),
- &value->value.uint8, 64);
- return true;
- }
- break;
-
- case e_regSetEXC:
- switch (reg) {
- case exc_trapno:
- m_state.context.exc.__trapno = value->value.uint32;
- success = true;
- break;
- case exc_err:
- m_state.context.exc.__err = value->value.uint32;
- success = true;
- break;
- case exc_faultvaddr:
- m_state.context.exc.__faultvaddr = value->value.uint64;
- success = true;
- break;
- }
- break;
- }
- }
-
- if (success)
- return SetRegisterState(set) == KERN_SUCCESS;
- return false;
-}
-
-uint32_t DNBArchImplX86_64::GetRegisterContextSize() {
- static uint32_t g_cached_size = 0;
- if (g_cached_size == 0) {
- if (CPUHasAVX512f() || FORCE_AVX_REGS) {
- for (size_t i = 0; i < k_num_fpu_registers_avx512f; ++i) {
- if (g_fpu_registers_avx512f[i].value_regs == NULL)
- g_cached_size += g_fpu_registers_avx512f[i].size;
- }
- } else if (CPUHasAVX() || FORCE_AVX_REGS) {
- for (size_t i = 0; i < k_num_fpu_registers_avx; ++i) {
- if (g_fpu_registers_avx[i].value_regs == NULL)
- g_cached_size += g_fpu_registers_avx[i].size;
- }
- } else {
- for (size_t i = 0; i < k_num_fpu_registers_no_avx; ++i) {
- if (g_fpu_registers_no_avx[i].value_regs == NULL)
- g_cached_size += g_fpu_registers_no_avx[i].size;
- }
- }
- DNBLogThreaded("DNBArchImplX86_64::GetRegisterContextSize() - GPR = %zu, "
- "FPU = %u, EXC = %zu",
- sizeof(GPR), g_cached_size, sizeof(EXC));
- g_cached_size += sizeof(GPR);
- g_cached_size += sizeof(EXC);
- DNBLogThreaded(
- "DNBArchImplX86_64::GetRegisterContextSize() - GPR + FPU + EXC = %u",
- g_cached_size);
- }
- return g_cached_size;
-}
-
-nub_size_t DNBArchImplX86_64::GetRegisterContext(void *buf,
- nub_size_t buf_len) {
- uint32_t size = GetRegisterContextSize();
-
- if (buf && buf_len) {
- bool force = false;
- kern_return_t kret;
-
- if ((kret = GetGPRState(force)) != KERN_SUCCESS) {
- DNBLogThreadedIf(LOG_THREAD, "DNBArchImplX86_64::GetRegisterContext (buf "
- "= %p, len = %llu) error: GPR regs failed "
- "to read: %u ",
- buf, (uint64_t)buf_len, kret);
- size = 0;
- } else if ((kret = GetFPUState(force)) != KERN_SUCCESS) {
- DNBLogThreadedIf(
- LOG_THREAD, "DNBArchImplX86_64::GetRegisterContext (buf = %p, len = "
- "%llu) error: %s regs failed to read: %u",
- buf, (uint64_t)buf_len, CPUHasAVX() ? "AVX" : "FPU", kret);
- size = 0;
- } else if ((kret = GetEXCState(force)) != KERN_SUCCESS) {
- DNBLogThreadedIf(LOG_THREAD, "DNBArchImplX86_64::GetRegisterContext (buf "
- "= %p, len = %llu) error: EXC regs failed "
- "to read: %u",
- buf, (uint64_t)buf_len, kret);
- size = 0;
- } else {
- uint8_t *p = (uint8_t *)buf;
- // Copy the GPR registers
- memcpy(p, &m_state.context.gpr, sizeof(GPR));
- p += sizeof(GPR);
-
- // Walk around the gaps in the FPU regs
- memcpy(p, &m_state.context.fpu.no_avx.__fpu_fcw, 5);
- // We read 5 bytes, but we skip 6 to account for __fpu_rsrv1
- // to match the g_fpu_registers_* tables.
- p += 6;
- memcpy(p, &m_state.context.fpu.no_avx.__fpu_fop, 8);
- p += 8;
- memcpy(p, &m_state.context.fpu.no_avx.__fpu_dp, 6);
- p += 6;
- memcpy(p, &m_state.context.fpu.no_avx.__fpu_mxcsr, 8);
- p += 8;
-
- // Work around the padding between the stmm registers as they are 16
- // byte structs with 10 bytes of the value in each
- for (size_t i = 0; i < 8; ++i) {
- memcpy(p, &m_state.context.fpu.no_avx.__fpu_stmm0 + i, 10);
- p += 10;
- }
-
- if(CPUHasAVX512f() || FORCE_AVX_REGS) {
- for (size_t i = 0; i < 8; ++i) {
- memcpy(p, &m_state.context.fpu.avx512f.__fpu_k0 + i, 8);
- p += 8;
- }
- }
-
- if (CPUHasAVX() || FORCE_AVX_REGS) {
- // Interleave the XMM and YMMH registers to make the YMM registers
- for (size_t i = 0; i < 16; ++i) {
- memcpy(p, &m_state.context.fpu.avx.__fpu_xmm0 + i, 16);
- p += 16;
- memcpy(p, &m_state.context.fpu.avx.__fpu_ymmh0 + i, 16);
- p += 16;
- }
- if(CPUHasAVX512f() || FORCE_AVX_REGS) {
- for (size_t i = 0; i < 16; ++i) {
- memcpy(p, &m_state.context.fpu.avx512f.__fpu_zmmh0 + i, 32);
- p += 32;
- }
- for (size_t i = 0; i < 16; ++i) {
- memcpy(p, &m_state.context.fpu.avx512f.__fpu_zmm16 + i, 64);
- p += 64;
- }
- }
- } else {
- // Copy the XMM registers in a single block
- memcpy(p, &m_state.context.fpu.no_avx.__fpu_xmm0, 16 * 16);
- p += 16 * 16;
- }
-
- // Copy the exception registers
- memcpy(p, &m_state.context.exc, sizeof(EXC));
- p += sizeof(EXC);
-
- // make sure we end up with exactly what we think we should have
- size_t bytes_written = p - (uint8_t *)buf;
- UNUSED_IF_ASSERT_DISABLED(bytes_written);
- assert(bytes_written == size);
- }
- }
-
- DNBLogThreadedIf(
- LOG_THREAD,
- "DNBArchImplX86_64::GetRegisterContext (buf = %p, len = %llu) => %u", buf,
- (uint64_t)buf_len, size);
- // Return the size of the register context even if NULL was passed in
- return size;
-}
-
-nub_size_t DNBArchImplX86_64::SetRegisterContext(const void *buf,
- nub_size_t buf_len) {
- uint32_t size = GetRegisterContextSize();
- if (buf == NULL || buf_len == 0)
- size = 0;
-
- if (size) {
- if (size > buf_len)
- size = static_cast<uint32_t>(buf_len);
-
- const uint8_t *p = (const uint8_t *)buf;
- // Copy the GPR registers
- memcpy(&m_state.context.gpr, p, sizeof(GPR));
- p += sizeof(GPR);
-
- // Copy fcw through mxcsrmask as there is no padding
- memcpy(&m_state.context.fpu.no_avx.__fpu_fcw, p, 5);
- // We wrote 5 bytes, but we skip 6 to account for __fpu_rsrv1
- // to match the g_fpu_registers_* tables.
- p += 6;
- memcpy(&m_state.context.fpu.no_avx.__fpu_fop, p, 8);
- p += 8;
- memcpy(&m_state.context.fpu.no_avx.__fpu_dp, p, 6);
- p += 6;
- memcpy(&m_state.context.fpu.no_avx.__fpu_mxcsr, p, 8);
- p += 8;
-
- // Work around the padding between the stmm registers as they are 16
- // byte structs with 10 bytes of the value in each
- for (size_t i = 0; i < 8; ++i) {
- memcpy(&m_state.context.fpu.no_avx.__fpu_stmm0 + i, p, 10);
- p += 10;
- }
-
- if(CPUHasAVX512f() || FORCE_AVX_REGS) {
- for (size_t i = 0; i < 8; ++i) {
- memcpy(&m_state.context.fpu.avx512f.__fpu_k0 + i, p, 8);
- p += 8;
- }
- }
-
- if (CPUHasAVX() || FORCE_AVX_REGS) {
- // Interleave the XMM and YMMH registers to make the YMM registers
- for (size_t i = 0; i < 16; ++i) {
- memcpy(&m_state.context.fpu.avx.__fpu_xmm0 + i, p, 16);
- p += 16;
- memcpy(&m_state.context.fpu.avx.__fpu_ymmh0 + i, p, 16);
- p += 16;
- }
- if(CPUHasAVX512f() || FORCE_AVX_REGS) {
- for (size_t i = 0; i < 16; ++i) {
- memcpy(&m_state.context.fpu.avx512f.__fpu_zmmh0 + i, p, 32);
- p += 32;
- }
- for (size_t i = 0; i < 16; ++i) {
- memcpy(&m_state.context.fpu.avx512f.__fpu_zmm16 + i, p, 64);
- p += 64;
- }
- }
- } else {
- // Copy the XMM registers in a single block
- memcpy(&m_state.context.fpu.no_avx.__fpu_xmm0, p, 16 * 16);
- p += 16 * 16;
- }
-
- // Copy the exception registers
- memcpy(&m_state.context.exc, p, sizeof(EXC));
- p += sizeof(EXC);
-
- // make sure we end up with exactly what we think we should have
- size_t bytes_written = p - (const uint8_t *)buf;
- UNUSED_IF_ASSERT_DISABLED(bytes_written);
- assert(bytes_written == size);
-
- kern_return_t kret;
- if ((kret = SetGPRState()) != KERN_SUCCESS)
- DNBLogThreadedIf(LOG_THREAD, "DNBArchImplX86_64::SetRegisterContext (buf "
- "= %p, len = %llu) error: GPR regs failed "
- "to write: %u",
- buf, (uint64_t)buf_len, kret);
- if ((kret = SetFPUState()) != KERN_SUCCESS)
- DNBLogThreadedIf(
- LOG_THREAD, "DNBArchImplX86_64::SetRegisterContext (buf = %p, len = "
- "%llu) error: %s regs failed to write: %u",
- buf, (uint64_t)buf_len, CPUHasAVX() ? "AVX" : "FPU", kret);
- if ((kret = SetEXCState()) != KERN_SUCCESS)
- DNBLogThreadedIf(LOG_THREAD, "DNBArchImplX86_64::SetRegisterContext (buf "
- "= %p, len = %llu) error: EXP regs failed "
- "to write: %u",
- buf, (uint64_t)buf_len, kret);
- }
- DNBLogThreadedIf(
- LOG_THREAD,
- "DNBArchImplX86_64::SetRegisterContext (buf = %p, len = %llu) => %llu",
- buf, (uint64_t)buf_len, (uint64_t)size);
- return size;
-}
-
-uint32_t DNBArchImplX86_64::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, "DNBArchImplX86_64::SaveRegisterState () "
- "error: GPR regs failed to read: %u ",
- kret);
- } else if ((kret = GetFPUState(force)) != KERN_SUCCESS) {
- DNBLogThreadedIf(LOG_THREAD, "DNBArchImplX86_64::SaveRegisterState () "
- "error: %s regs failed to read: %u",
- CPUHasAVX() ? "AVX" : "FPU", kret);
- } else {
- const uint32_t save_id = GetNextRegisterStateSaveID();
- m_saved_register_states[save_id] = m_state.context;
- return save_id;
- }
- return 0;
-}
-bool DNBArchImplX86_64::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.fpu = pos->second.fpu;
- m_state.SetError(e_regSetGPR, Read, 0);
- m_state.SetError(e_regSetFPU, Read, 0);
- kern_return_t kret;
- bool success = true;
- if ((kret = SetGPRState()) != KERN_SUCCESS) {
- DNBLogThreadedIf(LOG_THREAD, "DNBArchImplX86_64::RestoreRegisterState "
- "(save_id = %u) error: GPR regs failed to "
- "write: %u",
- save_id, kret);
- success = false;
- } else if ((kret = SetFPUState()) != KERN_SUCCESS) {
- DNBLogThreadedIf(LOG_THREAD, "DNBArchImplX86_64::RestoreRegisterState "
- "(save_id = %u) error: %s regs failed to "
- "write: %u",
- save_id, CPUHasAVX() ? "AVX" : "FPU", kret);
- success = false;
- }
- m_saved_register_states.erase(pos);
- return success;
- }
- return false;
-}
-
-kern_return_t DNBArchImplX86_64::GetRegisterState(int set, bool force) {
- switch (set) {
- case e_regSetALL:
- return GetGPRState(force) | GetFPUState(force) | GetEXCState(force);
- case e_regSetGPR:
- return GetGPRState(force);
- case e_regSetFPU:
- return GetFPUState(force);
- case e_regSetEXC:
- return GetEXCState(force);
- default:
- break;
- }
- return KERN_INVALID_ARGUMENT;
-}
-
-kern_return_t DNBArchImplX86_64::SetRegisterState(int set) {
- // Make sure we have a valid context to set.
- if (RegisterSetStateIsValid(set)) {
- switch (set) {
- case e_regSetALL:
- return SetGPRState() | SetFPUState() | SetEXCState();
- case e_regSetGPR:
- return SetGPRState();
- case e_regSetFPU:
- return SetFPUState();
- case e_regSetEXC:
- return SetEXCState();
- default:
- break;
- }
- }
- return KERN_INVALID_ARGUMENT;
-}
-
-bool DNBArchImplX86_64::RegisterSetStateIsValid(int set) const {
- return m_state.RegsAreValid(set);
-}
-
-#endif // #if defined (__i386__) || defined (__x86_64__)
diff --git a/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h b/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h
deleted file mode 100644
index ef2ba1ee09a6..000000000000
--- a/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h
+++ /dev/null
@@ -1,242 +0,0 @@
-//===-- DNBArchImplX86_64.h -------------------------------------*- 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.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __DNBArchImplX86_64_h__
-#define __DNBArchImplX86_64_h__
-
-#if defined(__i386__) || defined(__x86_64__)
-#include "DNBArch.h"
-#include "MachRegisterStatesX86_64.h"
-
-#include <map>
-
-class MachThread;
-
-class DNBArchImplX86_64 : public DNBArchProtocol {
-public:
- DNBArchImplX86_64(MachThread *thread)
- : DNBArchProtocol(), m_thread(thread), m_state(), m_2pc_dbg_checkpoint(),
- m_2pc_trans_state(Trans_Done), m_saved_register_states() {}
- virtual ~DNBArchImplX86_64() {}
-
- static void Initialize();
-
- virtual bool GetRegisterValue(uint32_t set, uint32_t reg,
- DNBRegisterValue *value);
- virtual bool SetRegisterValue(uint32_t set, uint32_t 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);
-
- 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 uint32_t GetHardwareWatchpointHit(nub_addr_t &addr);
-
-protected:
- kern_return_t EnableHardwareSingleStep(bool enable);
-
- typedef __x86_64_thread_state_t GPR;
- typedef __x86_64_float_state_t FPU;
- typedef __x86_64_exception_state_t EXC;
- typedef __x86_64_avx_state_t AVX;
- typedef __x86_64_debug_state_t DBG;
-
- static const DNBRegisterInfo g_gpr_registers[];
- static const DNBRegisterInfo g_fpu_registers_no_avx[];
- static const DNBRegisterInfo g_fpu_registers_avx[];
- static const DNBRegisterInfo g_exc_registers[];
- static const DNBRegisterSetInfo g_reg_sets_no_avx[];
- static const DNBRegisterSetInfo g_reg_sets_avx[];
- static const size_t k_num_gpr_registers;
- static const size_t k_num_fpu_registers_no_avx;
- static const size_t k_num_fpu_registers_avx;
- static const size_t k_num_exc_registers;
- static const size_t k_num_all_registers_no_avx;
- static const size_t k_num_all_registers_avx;
- static const size_t k_num_register_sets;
-
- typedef __x86_64_avx512f_state_t AVX512F;
- static const DNBRegisterInfo g_fpu_registers_avx512f[];
- static const DNBRegisterSetInfo g_reg_sets_avx512f[];
- static const size_t k_num_fpu_registers_avx512f;
- static const size_t k_num_all_registers_avx512f;
-
- typedef enum RegisterSetTag {
- e_regSetALL = REGISTER_SET_ALL,
- e_regSetGPR,
- e_regSetFPU,
- e_regSetEXC,
- e_regSetDBG,
- kNumRegisterSets
- } RegisterSet;
-
- typedef enum RegisterSetWordSizeTag {
- e_regSetWordSizeGPR = sizeof(GPR) / sizeof(int),
- e_regSetWordSizeFPU = sizeof(FPU) / sizeof(int),
- e_regSetWordSizeEXC = sizeof(EXC) / sizeof(int),
- e_regSetWordSizeAVX = sizeof(AVX) / sizeof(int),
- e_regSetWordSizeAVX512f = sizeof(AVX512F) / sizeof(int),
- e_regSetWordSizeDBG = sizeof(DBG) / sizeof(int)
- } RegisterSetWordSize;
-
- enum { Read = 0, Write = 1, kNumErrors = 2 };
-
- struct Context {
- GPR gpr;
- union {
- FPU no_avx;
- AVX avx;
- AVX512F avx512f;
- } fpu;
- EXC exc;
- DBG dbg;
- };
-
- struct State {
- Context context;
- kern_return_t gpr_errs[2]; // Read/Write errors
- kern_return_t fpu_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;
- fpu_errs[i] = -1;
- exc_errs[i] = -1;
- dbg_errs[i] = -1;
- }
- }
-
- void InvalidateAllRegisterStates() { SetError(e_regSetALL, Read, -1); }
-
- kern_return_t 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 e_regSetALL:
- return gpr_errs[err_idx] | fpu_errs[err_idx] | exc_errs[err_idx];
- case e_regSetGPR:
- return gpr_errs[err_idx];
- case e_regSetFPU:
- return fpu_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 flavor, uint32_t err_idx, kern_return_t err) {
- if (err_idx < kNumErrors) {
- switch (flavor) {
- case e_regSetALL:
- gpr_errs[err_idx] = fpu_errs[err_idx] = exc_errs[err_idx] =
- dbg_errs[err_idx] = err;
- return true;
-
- case e_regSetGPR:
- gpr_errs[err_idx] = err;
- return true;
-
- case e_regSetFPU:
- fpu_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 flavor) const {
- return GetError(flavor, Read) == KERN_SUCCESS;
- }
- };
-
- kern_return_t GetGPRState(bool force);
- kern_return_t GetFPUState(bool force);
- kern_return_t GetEXCState(bool force);
- kern_return_t GetDBGState(bool force);
-
- kern_return_t SetGPRState();
- kern_return_t SetFPUState();
- kern_return_t SetEXCState();
- kern_return_t SetDBGState(bool also_set_on_task);
-
- static DNBArchProtocol *Create(MachThread *thread);
-
- static const uint8_t *SoftwareBreakpointOpcode(nub_size_t byte_size);
-
- static const DNBRegisterSetInfo *GetRegisterSetInfo(nub_size_t *num_reg_sets);
-
- static uint32_t GetRegisterContextSize();
-
- // Helper functions for watchpoint manipulations.
- static void SetWatchpoint(DBG &debug_state, uint32_t hw_index,
- nub_addr_t addr, nub_size_t size, bool read,
- bool write);
- static void ClearWatchpoint(DBG &debug_state, uint32_t hw_index);
- static bool IsWatchpointVacant(const DBG &debug_state, uint32_t hw_index);
- static void ClearWatchpointHits(DBG &debug_state);
- static bool IsWatchpointHit(const DBG &debug_state, uint32_t hw_index);
- static nub_addr_t GetWatchAddress(const DBG &debug_state, uint32_t hw_index);
-
- virtual bool StartTransForHWP();
- virtual bool RollbackTransForHWP();
- virtual bool FinishTransForHWP();
- DBG GetDBGCheckpoint();
-
- MachThread *m_thread;
- State m_state;
- DBG m_2pc_dbg_checkpoint;
- uint32_t m_2pc_trans_state; // Is transaction of DBG state change: Pedning
- // (0), Done (1), or Rolled Back (2)?
- typedef std::map<uint32_t, Context> SaveRegisterStates;
- SaveRegisterStates m_saved_register_states;
-};
-
-#endif // #if defined (__i386__) || defined (__x86_64__)
-#endif // #ifndef __DNBArchImplX86_64_h__
diff --git a/tools/debugserver/source/MacOSX/x86_64/MachRegisterStatesX86_64.h b/tools/debugserver/source/MacOSX/x86_64/MachRegisterStatesX86_64.h
deleted file mode 100644
index fcb648dac59e..000000000000
--- a/tools/debugserver/source/MacOSX/x86_64/MachRegisterStatesX86_64.h
+++ /dev/null
@@ -1,314 +0,0 @@
-//===-- MachRegisterStatesX86_64.h --------------------------------*- C++
-//-*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Created by Sean Callanan on 3/16/11.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __MachRegisterStatesX86_64_h__
-#define __MachRegisterStatesX86_64_h__
-
-#include <inttypes.h>
-
-#define __x86_64_THREAD_STATE 4
-#define __x86_64_FLOAT_STATE 5
-#define __x86_64_EXCEPTION_STATE 6
-#define __x86_64_DEBUG_STATE 11
-#define __x86_64_AVX_STATE 17
-#define __x86_64_AVX512F_STATE 20
-
-typedef struct {
- uint64_t __rax;
- uint64_t __rbx;
- uint64_t __rcx;
- uint64_t __rdx;
- uint64_t __rdi;
- uint64_t __rsi;
- uint64_t __rbp;
- uint64_t __rsp;
- uint64_t __r8;
- uint64_t __r9;
- uint64_t __r10;
- uint64_t __r11;
- uint64_t __r12;
- uint64_t __r13;
- uint64_t __r14;
- uint64_t __r15;
- uint64_t __rip;
- uint64_t __rflags;
- uint64_t __cs;
- uint64_t __fs;
- uint64_t __gs;
-} __x86_64_thread_state_t;
-
-typedef struct {
- uint16_t __invalid : 1;
- uint16_t __denorm : 1;
- uint16_t __zdiv : 1;
- uint16_t __ovrfl : 1;
- uint16_t __undfl : 1;
- uint16_t __precis : 1;
- uint16_t __PAD1 : 2;
- uint16_t __pc : 2;
- uint16_t __rc : 2;
- uint16_t __PAD2 : 1;
- uint16_t __PAD3 : 3;
-} __x86_64_fp_control_t;
-
-typedef struct {
- uint16_t __invalid : 1;
- uint16_t __denorm : 1;
- uint16_t __zdiv : 1;
- uint16_t __ovrfl : 1;
- uint16_t __undfl : 1;
- uint16_t __precis : 1;
- uint16_t __stkflt : 1;
- uint16_t __errsumm : 1;
- uint16_t __c0 : 1;
- uint16_t __c1 : 1;
- uint16_t __c2 : 1;
- uint16_t __tos : 3;
- uint16_t __c3 : 1;
- uint16_t __busy : 1;
-} __x86_64_fp_status_t;
-
-typedef struct {
- uint8_t __mmst_reg[10];
- uint8_t __mmst_rsrv[6];
-} __x86_64_mmst_reg;
-
-typedef struct { uint8_t __xmm_reg[16]; } __x86_64_xmm_reg;
-
-typedef struct {
- uint32_t __fpu_reserved[2];
- __x86_64_fp_control_t __fpu_fcw;
- __x86_64_fp_status_t __fpu_fsw;
- uint8_t __fpu_ftw;
- uint8_t __fpu_rsrv1;
- uint16_t __fpu_fop;
- uint32_t __fpu_ip;
- uint16_t __fpu_cs;
- uint16_t __fpu_rsrv2;
- uint32_t __fpu_dp;
- uint16_t __fpu_ds;
- uint16_t __fpu_rsrv3;
- uint32_t __fpu_mxcsr;
- uint32_t __fpu_mxcsrmask;
- __x86_64_mmst_reg __fpu_stmm0;
- __x86_64_mmst_reg __fpu_stmm1;
- __x86_64_mmst_reg __fpu_stmm2;
- __x86_64_mmst_reg __fpu_stmm3;
- __x86_64_mmst_reg __fpu_stmm4;
- __x86_64_mmst_reg __fpu_stmm5;
- __x86_64_mmst_reg __fpu_stmm6;
- __x86_64_mmst_reg __fpu_stmm7;
- __x86_64_xmm_reg __fpu_xmm0;
- __x86_64_xmm_reg __fpu_xmm1;
- __x86_64_xmm_reg __fpu_xmm2;
- __x86_64_xmm_reg __fpu_xmm3;
- __x86_64_xmm_reg __fpu_xmm4;
- __x86_64_xmm_reg __fpu_xmm5;
- __x86_64_xmm_reg __fpu_xmm6;
- __x86_64_xmm_reg __fpu_xmm7;
- __x86_64_xmm_reg __fpu_xmm8;
- __x86_64_xmm_reg __fpu_xmm9;
- __x86_64_xmm_reg __fpu_xmm10;
- __x86_64_xmm_reg __fpu_xmm11;
- __x86_64_xmm_reg __fpu_xmm12;
- __x86_64_xmm_reg __fpu_xmm13;
- __x86_64_xmm_reg __fpu_xmm14;
- __x86_64_xmm_reg __fpu_xmm15;
- uint8_t __fpu_rsrv4[6 * 16];
- uint32_t __fpu_reserved1;
-} __x86_64_float_state_t;
-
-typedef struct {
- uint32_t __fpu_reserved[2];
- __x86_64_fp_control_t __fpu_fcw;
- __x86_64_fp_status_t __fpu_fsw;
- uint8_t __fpu_ftw;
- uint8_t __fpu_rsrv1;
- uint16_t __fpu_fop;
- uint32_t __fpu_ip;
- uint16_t __fpu_cs;
- uint16_t __fpu_rsrv2;
- uint32_t __fpu_dp;
- uint16_t __fpu_ds;
- uint16_t __fpu_rsrv3;
- uint32_t __fpu_mxcsr;
- uint32_t __fpu_mxcsrmask;
- __x86_64_mmst_reg __fpu_stmm0;
- __x86_64_mmst_reg __fpu_stmm1;
- __x86_64_mmst_reg __fpu_stmm2;
- __x86_64_mmst_reg __fpu_stmm3;
- __x86_64_mmst_reg __fpu_stmm4;
- __x86_64_mmst_reg __fpu_stmm5;
- __x86_64_mmst_reg __fpu_stmm6;
- __x86_64_mmst_reg __fpu_stmm7;
- __x86_64_xmm_reg __fpu_xmm0;
- __x86_64_xmm_reg __fpu_xmm1;
- __x86_64_xmm_reg __fpu_xmm2;
- __x86_64_xmm_reg __fpu_xmm3;
- __x86_64_xmm_reg __fpu_xmm4;
- __x86_64_xmm_reg __fpu_xmm5;
- __x86_64_xmm_reg __fpu_xmm6;
- __x86_64_xmm_reg __fpu_xmm7;
- __x86_64_xmm_reg __fpu_xmm8;
- __x86_64_xmm_reg __fpu_xmm9;
- __x86_64_xmm_reg __fpu_xmm10;
- __x86_64_xmm_reg __fpu_xmm11;
- __x86_64_xmm_reg __fpu_xmm12;
- __x86_64_xmm_reg __fpu_xmm13;
- __x86_64_xmm_reg __fpu_xmm14;
- __x86_64_xmm_reg __fpu_xmm15;
- uint8_t __fpu_rsrv4[6 * 16];
- uint32_t __fpu_reserved1;
- uint8_t __avx_reserved1[64];
- __x86_64_xmm_reg __fpu_ymmh0;
- __x86_64_xmm_reg __fpu_ymmh1;
- __x86_64_xmm_reg __fpu_ymmh2;
- __x86_64_xmm_reg __fpu_ymmh3;
- __x86_64_xmm_reg __fpu_ymmh4;
- __x86_64_xmm_reg __fpu_ymmh5;
- __x86_64_xmm_reg __fpu_ymmh6;
- __x86_64_xmm_reg __fpu_ymmh7;
- __x86_64_xmm_reg __fpu_ymmh8;
- __x86_64_xmm_reg __fpu_ymmh9;
- __x86_64_xmm_reg __fpu_ymmh10;
- __x86_64_xmm_reg __fpu_ymmh11;
- __x86_64_xmm_reg __fpu_ymmh12;
- __x86_64_xmm_reg __fpu_ymmh13;
- __x86_64_xmm_reg __fpu_ymmh14;
- __x86_64_xmm_reg __fpu_ymmh15;
-} __x86_64_avx_state_t;
-
-typedef struct { uint8_t __ymm_reg[32]; } __x86_64_ymm_reg;
-typedef struct { uint8_t __zmm_reg[64]; } __x86_64_zmm_reg;
-typedef struct { uint8_t __opmask_reg[8]; } __x86_64_opmask_reg;
-
-typedef struct {
- uint32_t __fpu_reserved[2];
- __x86_64_fp_control_t __fpu_fcw;
- __x86_64_fp_status_t __fpu_fsw;
- uint8_t __fpu_ftw;
- uint8_t __fpu_rsrv1;
- uint16_t __fpu_fop;
- uint32_t __fpu_ip;
- uint16_t __fpu_cs;
- uint16_t __fpu_rsrv2;
- uint32_t __fpu_dp;
- uint16_t __fpu_ds;
- uint16_t __fpu_rsrv3;
- uint32_t __fpu_mxcsr;
- uint32_t __fpu_mxcsrmask;
- __x86_64_mmst_reg __fpu_stmm0;
- __x86_64_mmst_reg __fpu_stmm1;
- __x86_64_mmst_reg __fpu_stmm2;
- __x86_64_mmst_reg __fpu_stmm3;
- __x86_64_mmst_reg __fpu_stmm4;
- __x86_64_mmst_reg __fpu_stmm5;
- __x86_64_mmst_reg __fpu_stmm6;
- __x86_64_mmst_reg __fpu_stmm7;
- __x86_64_xmm_reg __fpu_xmm0;
- __x86_64_xmm_reg __fpu_xmm1;
- __x86_64_xmm_reg __fpu_xmm2;
- __x86_64_xmm_reg __fpu_xmm3;
- __x86_64_xmm_reg __fpu_xmm4;
- __x86_64_xmm_reg __fpu_xmm5;
- __x86_64_xmm_reg __fpu_xmm6;
- __x86_64_xmm_reg __fpu_xmm7;
- __x86_64_xmm_reg __fpu_xmm8;
- __x86_64_xmm_reg __fpu_xmm9;
- __x86_64_xmm_reg __fpu_xmm10;
- __x86_64_xmm_reg __fpu_xmm11;
- __x86_64_xmm_reg __fpu_xmm12;
- __x86_64_xmm_reg __fpu_xmm13;
- __x86_64_xmm_reg __fpu_xmm14;
- __x86_64_xmm_reg __fpu_xmm15;
- uint8_t __fpu_rsrv4[6 * 16];
- uint32_t __fpu_reserved1;
- uint8_t __avx_reserved1[64];
- __x86_64_xmm_reg __fpu_ymmh0;
- __x86_64_xmm_reg __fpu_ymmh1;
- __x86_64_xmm_reg __fpu_ymmh2;
- __x86_64_xmm_reg __fpu_ymmh3;
- __x86_64_xmm_reg __fpu_ymmh4;
- __x86_64_xmm_reg __fpu_ymmh5;
- __x86_64_xmm_reg __fpu_ymmh6;
- __x86_64_xmm_reg __fpu_ymmh7;
- __x86_64_xmm_reg __fpu_ymmh8;
- __x86_64_xmm_reg __fpu_ymmh9;
- __x86_64_xmm_reg __fpu_ymmh10;
- __x86_64_xmm_reg __fpu_ymmh11;
- __x86_64_xmm_reg __fpu_ymmh12;
- __x86_64_xmm_reg __fpu_ymmh13;
- __x86_64_xmm_reg __fpu_ymmh14;
- __x86_64_xmm_reg __fpu_ymmh15;
- __x86_64_opmask_reg __fpu_k0;
- __x86_64_opmask_reg __fpu_k1;
- __x86_64_opmask_reg __fpu_k2;
- __x86_64_opmask_reg __fpu_k3;
- __x86_64_opmask_reg __fpu_k4;
- __x86_64_opmask_reg __fpu_k5;
- __x86_64_opmask_reg __fpu_k6;
- __x86_64_opmask_reg __fpu_k7;
- __x86_64_ymm_reg __fpu_zmmh0;
- __x86_64_ymm_reg __fpu_zmmh1;
- __x86_64_ymm_reg __fpu_zmmh2;
- __x86_64_ymm_reg __fpu_zmmh3;
- __x86_64_ymm_reg __fpu_zmmh4;
- __x86_64_ymm_reg __fpu_zmmh5;
- __x86_64_ymm_reg __fpu_zmmh6;
- __x86_64_ymm_reg __fpu_zmmh7;
- __x86_64_ymm_reg __fpu_zmmh8;
- __x86_64_ymm_reg __fpu_zmmh9;
- __x86_64_ymm_reg __fpu_zmmh10;
- __x86_64_ymm_reg __fpu_zmmh11;
- __x86_64_ymm_reg __fpu_zmmh12;
- __x86_64_ymm_reg __fpu_zmmh13;
- __x86_64_ymm_reg __fpu_zmmh14;
- __x86_64_ymm_reg __fpu_zmmh15;
- __x86_64_zmm_reg __fpu_zmm16;
- __x86_64_zmm_reg __fpu_zmm17;
- __x86_64_zmm_reg __fpu_zmm18;
- __x86_64_zmm_reg __fpu_zmm19;
- __x86_64_zmm_reg __fpu_zmm20;
- __x86_64_zmm_reg __fpu_zmm21;
- __x86_64_zmm_reg __fpu_zmm22;
- __x86_64_zmm_reg __fpu_zmm23;
- __x86_64_zmm_reg __fpu_zmm24;
- __x86_64_zmm_reg __fpu_zmm25;
- __x86_64_zmm_reg __fpu_zmm26;
- __x86_64_zmm_reg __fpu_zmm27;
- __x86_64_zmm_reg __fpu_zmm28;
- __x86_64_zmm_reg __fpu_zmm29;
- __x86_64_zmm_reg __fpu_zmm30;
- __x86_64_zmm_reg __fpu_zmm31;
-
-} __x86_64_avx512f_state_t;
-
-typedef struct {
- uint32_t __trapno;
- uint32_t __err;
- uint64_t __faultvaddr;
-} __x86_64_exception_state_t;
-
-typedef struct {
- uint64_t __dr0;
- uint64_t __dr1;
- uint64_t __dr2;
- uint64_t __dr3;
- uint64_t __dr4;
- uint64_t __dr5;
- uint64_t __dr6;
- uint64_t __dr7;
-} __x86_64_debug_state_t;
-
-#endif
diff --git a/tools/debugserver/source/PThreadCondition.h b/tools/debugserver/source/PThreadCondition.h
deleted file mode 100644
index 9cd64bf24723..000000000000
--- a/tools/debugserver/source/PThreadCondition.h
+++ /dev/null
@@ -1,35 +0,0 @@
-//===-- PThreadCondition.h --------------------------------------*- 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/16/07.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __PThreadCondition_h__
-#define __PThreadCondition_h__
-
-#include <pthread.h>
-
-class PThreadCondition {
-public:
- PThreadCondition() { ::pthread_cond_init(&m_condition, NULL); }
-
- ~PThreadCondition() { ::pthread_cond_destroy(&m_condition); }
-
- pthread_cond_t *Condition() { return &m_condition; }
-
- int Broadcast() { return ::pthread_cond_broadcast(&m_condition); }
-
- int Signal() { return ::pthread_cond_signal(&m_condition); }
-
-protected:
- pthread_cond_t m_condition;
-};
-
-#endif
diff --git a/tools/debugserver/source/PThreadEvent.cpp b/tools/debugserver/source/PThreadEvent.cpp
deleted file mode 100644
index 1b0900ca7107..000000000000
--- a/tools/debugserver/source/PThreadEvent.cpp
+++ /dev/null
@@ -1,200 +0,0 @@
-//===-- PThreadEvent.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/16/07.
-//
-//===----------------------------------------------------------------------===//
-
-#include "PThreadEvent.h"
-#include "DNBLog.h"
-#include "errno.h"
-
-PThreadEvent::PThreadEvent(uint32_t bits, uint32_t validBits)
- : m_mutex(), m_set_condition(), m_reset_condition(), m_bits(bits),
- m_validBits(validBits), m_reset_ack_mask(0) {
- // DNBLogThreadedIf(LOG_EVENTS, "%p PThreadEvent::%s (0x%8.8x, 0x%8.8x)",
- // this, __FUNCTION__, bits, validBits);
-}
-
-PThreadEvent::~PThreadEvent() {
- // DNBLogThreadedIf(LOG_EVENTS, "%p %s", this, LLVM_PRETTY_FUNCTION);
-}
-
-uint32_t PThreadEvent::NewEventBit() {
- // DNBLogThreadedIf(LOG_EVENTS, "%p %s", this, LLVM_PRETTY_FUNCTION);
- PTHREAD_MUTEX_LOCKER(locker, m_mutex);
- uint32_t mask = 1;
- while (mask & m_validBits)
- mask <<= 1;
- m_validBits |= mask;
- return mask;
-}
-
-void PThreadEvent::FreeEventBits(const uint32_t mask) {
- // DNBLogThreadedIf(LOG_EVENTS, "%p PThreadEvent::%s (0x%8.8x)", this,
- // __FUNCTION__, mask);
- if (mask) {
- PTHREAD_MUTEX_LOCKER(locker, m_mutex);
- m_bits &= ~mask;
- m_validBits &= ~mask;
- }
-}
-
-uint32_t PThreadEvent::GetEventBits() const {
- // DNBLogThreadedIf(LOG_EVENTS, "%p %s", this, LLVM_PRETTY_FUNCTION);
- PTHREAD_MUTEX_LOCKER(locker, m_mutex);
- uint32_t bits = m_bits;
- return bits;
-}
-
-// Replace the event bits with a new bitmask value
-void PThreadEvent::ReplaceEventBits(const uint32_t bits) {
- // DNBLogThreadedIf(LOG_EVENTS, "%p PThreadEvent::%s (0x%8.8x)", this,
- // __FUNCTION__, bits);
- PTHREAD_MUTEX_LOCKER(locker, m_mutex);
- // Make sure we have some bits and that they aren't already set...
- if (m_bits != bits) {
- // Figure out which bits are changing
- uint32_t changed_bits = m_bits ^ bits;
- // Set the new bit values
- m_bits = bits;
- // If any new bits are set, then broadcast
- if (changed_bits & m_bits)
- m_set_condition.Broadcast();
- }
-}
-
-// Set one or more event bits and broadcast if any new event bits get set
-// that weren't already set.
-
-void PThreadEvent::SetEvents(const uint32_t mask) {
- // DNBLogThreadedIf(LOG_EVENTS, "%p PThreadEvent::%s (0x%8.8x)", this,
- // __FUNCTION__, mask);
- // Make sure we have some bits to set
- if (mask) {
- PTHREAD_MUTEX_LOCKER(locker, m_mutex);
- // Save the old event bit state so we can tell if things change
- uint32_t old = m_bits;
- // Set the all event bits that are set in 'mask'
- m_bits |= mask;
- // Broadcast only if any extra bits got set.
- if (old != m_bits)
- m_set_condition.Broadcast();
- }
-}
-
-// Reset one or more event bits
-void PThreadEvent::ResetEvents(const uint32_t mask) {
- // DNBLogThreadedIf(LOG_EVENTS, "%p PThreadEvent::%s (0x%8.8x)", this,
- // __FUNCTION__, mask);
- if (mask) {
- PTHREAD_MUTEX_LOCKER(locker, m_mutex);
-
- // Save the old event bit state so we can tell if things change
- uint32_t old = m_bits;
- // Clear the all event bits that are set in 'mask'
- m_bits &= ~mask;
- // Broadcast only if any extra bits got reset.
- if (old != m_bits)
- m_reset_condition.Broadcast();
- }
-}
-
-//----------------------------------------------------------------------
-// Wait until 'timeout_abstime' for any events that are set in
-// 'mask'. If 'timeout_abstime' is NULL, then wait forever.
-//----------------------------------------------------------------------
-uint32_t
-PThreadEvent::WaitForSetEvents(const uint32_t mask,
- const struct timespec *timeout_abstime) const {
- // DNBLogThreadedIf(LOG_EVENTS, "%p PThreadEvent::%s (0x%8.8x, %p)", this,
- // __FUNCTION__, mask, timeout_abstime);
- int err = 0;
- // pthread_cond_timedwait() or pthread_cond_wait() will atomically
- // unlock the mutex and wait for the condition to be set. When either
- // function returns, they will re-lock the mutex. We use an auto lock/unlock
- // class (PThreadMutex::Locker) to allow us to return at any point in this
- // function and not have to worry about unlocking the mutex.
- PTHREAD_MUTEX_LOCKER(locker, m_mutex);
- do {
- // Check our predicate (event bits) in case any are already set
- if (mask & m_bits) {
- uint32_t bits_set = mask & m_bits;
- // Our PThreadMutex::Locker will automatically unlock our mutex
- return bits_set;
- }
- if (timeout_abstime) {
- // Wait for condition to get broadcast, or for a timeout. If we get
- // a timeout we will drop out of the do loop and return false which
- // is what we want.
- err = ::pthread_cond_timedwait(m_set_condition.Condition(),
- m_mutex.Mutex(), timeout_abstime);
- // Retest our predicate in case of a race condition right at the end
- // of the timeout.
- if (err == ETIMEDOUT) {
- uint32_t bits_set = mask & m_bits;
- return bits_set;
- }
- } else {
- // Wait for condition to get broadcast. The only error this function
- // should return is if
- err = ::pthread_cond_wait(m_set_condition.Condition(), m_mutex.Mutex());
- }
- } while (err == 0);
- return 0;
-}
-
-//----------------------------------------------------------------------
-// Wait until 'timeout_abstime' for any events in 'mask' to reset.
-// If 'timeout_abstime' is NULL, then wait forever.
-//----------------------------------------------------------------------
-uint32_t PThreadEvent::WaitForEventsToReset(
- const uint32_t mask, const struct timespec *timeout_abstime) const {
- // DNBLogThreadedIf(LOG_EVENTS, "%p PThreadEvent::%s (0x%8.8x, %p)", this,
- // __FUNCTION__, mask, timeout_abstime);
- int err = 0;
- // pthread_cond_timedwait() or pthread_cond_wait() will atomically
- // unlock the mutex and wait for the condition to be set. When either
- // function returns, they will re-lock the mutex. We use an auto lock/unlock
- // class (PThreadMutex::Locker) to allow us to return at any point in this
- // function and not have to worry about unlocking the mutex.
- PTHREAD_MUTEX_LOCKER(locker, m_mutex);
- do {
- // Check our predicate (event bits) each time through this do loop
- if ((mask & m_bits) == 0) {
- // All the bits requested have been reset, return zero indicating
- // which bits from the mask were still set (none of them)
- return 0;
- }
- if (timeout_abstime) {
- // Wait for condition to get broadcast, or for a timeout. If we get
- // a timeout we will drop out of the do loop and return false which
- // is what we want.
- err = ::pthread_cond_timedwait(m_reset_condition.Condition(),
- m_mutex.Mutex(), timeout_abstime);
- } else {
- // Wait for condition to get broadcast. The only error this function
- // should return is if
- err = ::pthread_cond_wait(m_reset_condition.Condition(), m_mutex.Mutex());
- }
- } while (err == 0);
- // Return a mask indicating which bits (if any) were still set
- return mask & m_bits;
-}
-
-uint32_t
-PThreadEvent::WaitForResetAck(const uint32_t mask,
- const struct timespec *timeout_abstime) const {
- if (mask & m_reset_ack_mask) {
- // DNBLogThreadedIf(LOG_EVENTS, "%p PThreadEvent::%s (0x%8.8x, %p)", this,
- // __FUNCTION__, mask, timeout_abstime);
- return WaitForEventsToReset(mask & m_reset_ack_mask, timeout_abstime);
- }
- return 0;
-}
diff --git a/tools/debugserver/source/PThreadEvent.h b/tools/debugserver/source/PThreadEvent.h
deleted file mode 100644
index fbcd4593352b..000000000000
--- a/tools/debugserver/source/PThreadEvent.h
+++ /dev/null
@@ -1,64 +0,0 @@
-//===-- PThreadEvent.h ------------------------------------------*- 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/16/07.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __PThreadEvent_h__
-#define __PThreadEvent_h__
-#include "PThreadCondition.h"
-#include "PThreadMutex.h"
-#include <stdint.h>
-#include <time.h>
-
-class PThreadEvent {
-public:
- PThreadEvent(uint32_t bits = 0, uint32_t validBits = 0);
- ~PThreadEvent();
-
- uint32_t NewEventBit();
- void FreeEventBits(const uint32_t mask);
-
- void ReplaceEventBits(const uint32_t bits);
- uint32_t GetEventBits() const;
- void SetEvents(const uint32_t mask);
- void ResetEvents(const uint32_t mask);
- // Wait for events to be set or reset. These functions take an optional
- // timeout value. If timeout is NULL an infinite timeout will be used.
- uint32_t
- WaitForSetEvents(const uint32_t mask,
- const struct timespec *timeout_abstime = NULL) const;
- uint32_t
- WaitForEventsToReset(const uint32_t mask,
- const struct timespec *timeout_abstime = NULL) const;
-
- uint32_t GetResetAckMask() const { return m_reset_ack_mask; }
- uint32_t SetResetAckMask(uint32_t mask) { return m_reset_ack_mask = mask; }
- uint32_t WaitForResetAck(const uint32_t mask,
- const struct timespec *timeout_abstime = NULL) const;
-
-protected:
- //----------------------------------------------------------------------
- // pthread condition and mutex variable to control access and allow
- // blocking between the main thread and the spotlight index thread.
- //----------------------------------------------------------------------
- mutable PThreadMutex m_mutex;
- mutable PThreadCondition m_set_condition;
- mutable PThreadCondition m_reset_condition;
- uint32_t m_bits;
- uint32_t m_validBits;
- uint32_t m_reset_ack_mask;
-
-private:
- PThreadEvent(const PThreadEvent &); // Outlaw copy constructor
- PThreadEvent &operator=(const PThreadEvent &rhs);
-};
-
-#endif // #ifndef __PThreadEvent_h__
diff --git a/tools/debugserver/source/PThreadMutex.cpp b/tools/debugserver/source/PThreadMutex.cpp
deleted file mode 100644
index 0e9132e380bf..000000000000
--- a/tools/debugserver/source/PThreadMutex.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-//===-- PThreadMutex.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 12/9/08.
-//
-//===----------------------------------------------------------------------===//
-
-#include "PThreadMutex.h"
-
-#include "DNBTimer.h"
-
-#if defined(DEBUG_PTHREAD_MUTEX_DEADLOCKS)
-
-PThreadMutex::Locker::Locker(PThreadMutex &m, const char *function,
- const char *file, const int line)
- : m_pMutex(m.Mutex()), m_function(function), m_file(file), m_line(line),
- m_lock_time(0) {
- Lock();
-}
-
-PThreadMutex::Locker::Locker(PThreadMutex *m, const char *function,
- const char *file, const int line)
- : m_pMutex(m ? m->Mutex() : NULL), m_function(function), m_file(file),
- m_line(line), m_lock_time(0) {
- Lock();
-}
-
-PThreadMutex::Locker::Locker(pthread_mutex_t *mutex, const char *function,
- const char *file, const int line)
- : m_pMutex(mutex), m_function(function), m_file(file), m_line(line),
- m_lock_time(0) {
- Lock();
-}
-
-PThreadMutex::Locker::~Locker() { Unlock(); }
-
-void PThreadMutex::Locker::Lock() {
- if (m_pMutex) {
- m_lock_time = DNBTimer::GetTimeOfDay();
- if (::pthread_mutex_trylock(m_pMutex) != 0) {
- fprintf(stdout, "::pthread_mutex_trylock (%8.8p) mutex is locked "
- "(function %s in %s:%i), waiting...\n",
- m_pMutex, m_function, m_file, m_line);
- ::pthread_mutex_lock(m_pMutex);
- fprintf(stdout, "::pthread_mutex_lock (%8.8p) succeeded after %6llu "
- "usecs (function %s in %s:%i)\n",
- m_pMutex, DNBTimer::GetTimeOfDay() - m_lock_time, m_function,
- m_file, m_line);
- }
- }
-}
-
-void PThreadMutex::Locker::Unlock() {
- fprintf(stdout, "::pthread_mutex_unlock (%8.8p) had lock for %6llu usecs in "
- "%s in %s:%i\n",
- m_pMutex, DNBTimer::GetTimeOfDay() - m_lock_time, m_function, m_file,
- m_line);
- ::pthread_mutex_unlock(m_pMutex);
-}
-
-#endif
diff --git a/tools/debugserver/source/PThreadMutex.h b/tools/debugserver/source/PThreadMutex.h
deleted file mode 100644
index c6ec293c5e59..000000000000
--- a/tools/debugserver/source/PThreadMutex.h
+++ /dev/null
@@ -1,120 +0,0 @@
-//===-- PThreadMutex.h ------------------------------------------*- 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/16/07.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __PThreadMutex_h__
-#define __PThreadMutex_h__
-
-#include <assert.h>
-#include <pthread.h>
-#include <stdint.h>
-
-//#define DEBUG_PTHREAD_MUTEX_DEADLOCKS 1
-
-#if defined(DEBUG_PTHREAD_MUTEX_DEADLOCKS)
-#define PTHREAD_MUTEX_LOCKER(var, mutex) \
- PThreadMutex::Locker var(mutex, __FUNCTION__, __FILE__, __LINE__)
-
-#else
-#define PTHREAD_MUTEX_LOCKER(var, mutex) PThreadMutex::Locker var(mutex)
-#endif
-
-class PThreadMutex {
-public:
- class Locker {
- public:
-#if defined(DEBUG_PTHREAD_MUTEX_DEADLOCKS)
-
- Locker(PThreadMutex &m, const char *function, const char *file, int line);
- Locker(PThreadMutex *m, const char *function, const char *file, int line);
- Locker(pthread_mutex_t *mutex, const char *function, const char *file,
- int line);
- ~Locker();
- void Lock();
- void Unlock();
-
-#else
- Locker(PThreadMutex &m) : m_pMutex(m.Mutex()) { Lock(); }
-
- Locker(PThreadMutex *m) : m_pMutex(m ? m->Mutex() : NULL) { Lock(); }
-
- Locker(pthread_mutex_t *mutex) : m_pMutex(mutex) { Lock(); }
-
- void Lock() {
- if (m_pMutex)
- ::pthread_mutex_lock(m_pMutex);
- }
-
- void Unlock() {
- if (m_pMutex)
- ::pthread_mutex_unlock(m_pMutex);
- }
-
- ~Locker() { Unlock(); }
-
-#endif
-
- // unlock any the current mutex and lock the new one if it is valid
- void Reset(pthread_mutex_t *pMutex = NULL) {
- Unlock();
- m_pMutex = pMutex;
- Lock();
- }
- pthread_mutex_t *m_pMutex;
-#if defined(DEBUG_PTHREAD_MUTEX_DEADLOCKS)
- const char *m_function;
- const char *m_file;
- int m_line;
- uint64_t m_lock_time;
-#endif
- };
-
- PThreadMutex() {
- int err;
- err = ::pthread_mutex_init(&m_mutex, NULL);
- assert(err == 0);
- }
-
- PThreadMutex(int type) {
- int err;
- ::pthread_mutexattr_t attr;
- err = ::pthread_mutexattr_init(&attr);
- assert(err == 0);
- err = ::pthread_mutexattr_settype(&attr, type);
- assert(err == 0);
- err = ::pthread_mutex_init(&m_mutex, &attr);
- assert(err == 0);
- err = ::pthread_mutexattr_destroy(&attr);
- assert(err == 0);
- }
-
- ~PThreadMutex() {
- int err;
- err = ::pthread_mutex_destroy(&m_mutex);
- if (err != 0) {
- err = Unlock();
- if (err == 0)
- ::pthread_mutex_destroy(&m_mutex);
- }
- }
-
- pthread_mutex_t *Mutex() { return &m_mutex; }
-
- int Lock() { return ::pthread_mutex_lock(&m_mutex); }
-
- int Unlock() { return ::pthread_mutex_unlock(&m_mutex); }
-
-protected:
- pthread_mutex_t m_mutex;
-};
-
-#endif
diff --git a/tools/debugserver/source/PseudoTerminal.cpp b/tools/debugserver/source/PseudoTerminal.cpp
deleted file mode 100644
index 892574a61dcf..000000000000
--- a/tools/debugserver/source/PseudoTerminal.cpp
+++ /dev/null
@@ -1,196 +0,0 @@
-//===-- PseudoTerminal.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 1/8/08.
-//
-//===----------------------------------------------------------------------===//
-
-#include "PseudoTerminal.h"
-#include <stdlib.h>
-#include <sys/ioctl.h>
-#include <unistd.h>
-
-//----------------------------------------------------------------------
-// PseudoTerminal constructor
-//----------------------------------------------------------------------
-PseudoTerminal::PseudoTerminal()
- : m_master_fd(invalid_fd), m_slave_fd(invalid_fd) {}
-
-//----------------------------------------------------------------------
-// Destructor
-// The master and slave file descriptors will get closed if they are
-// valid. Call the ReleaseMasterFD()/ReleaseSlaveFD() member functions
-// to release any file descriptors that are needed beyond the lifespan
-// of this object.
-//----------------------------------------------------------------------
-PseudoTerminal::~PseudoTerminal() {
- CloseMaster();
- CloseSlave();
-}
-
-//----------------------------------------------------------------------
-// Close the master file descriptor if it is valid.
-//----------------------------------------------------------------------
-void PseudoTerminal::CloseMaster() {
- if (m_master_fd > 0) {
- ::close(m_master_fd);
- m_master_fd = invalid_fd;
- }
-}
-
-//----------------------------------------------------------------------
-// Close the slave file descriptor if it is valid.
-//----------------------------------------------------------------------
-void PseudoTerminal::CloseSlave() {
- if (m_slave_fd > 0) {
- ::close(m_slave_fd);
- m_slave_fd = invalid_fd;
- }
-}
-
-//----------------------------------------------------------------------
-// Open the first available pseudo terminal with OFLAG as the
-// permissions. The file descriptor is store in the m_master_fd member
-// variable and can be accessed via the MasterFD() or ReleaseMasterFD()
-// accessors.
-//
-// Suggested value for oflag is O_RDWR|O_NOCTTY
-//
-// RETURNS:
-// Zero when successful, non-zero indicating an error occurred.
-//----------------------------------------------------------------------
-PseudoTerminal::Status PseudoTerminal::OpenFirstAvailableMaster(int oflag) {
- // Open the master side of a pseudo terminal
- m_master_fd = ::posix_openpt(oflag);
- if (m_master_fd < 0) {
- return err_posix_openpt_failed;
- }
-
- // Grant access to the slave pseudo terminal
- if (::grantpt(m_master_fd) < 0) {
- CloseMaster();
- return err_grantpt_failed;
- }
-
- // Clear the lock flag on the slave pseudo terminal
- if (::unlockpt(m_master_fd) < 0) {
- CloseMaster();
- return err_unlockpt_failed;
- }
-
- return success;
-}
-
-//----------------------------------------------------------------------
-// Open the slave pseudo terminal for the current master pseudo
-// terminal. A master pseudo terminal should already be valid prior to
-// calling this function (see PseudoTerminal::OpenFirstAvailableMaster()).
-// The file descriptor is stored in the m_slave_fd member variable and
-// can be accessed via the SlaveFD() or ReleaseSlaveFD() accessors.
-//
-// RETURNS:
-// Zero when successful, non-zero indicating an error occurred.
-//----------------------------------------------------------------------
-PseudoTerminal::Status PseudoTerminal::OpenSlave(int oflag) {
- CloseSlave();
-
- // Open the master side of a pseudo terminal
- const char *slave_name = SlaveName();
-
- if (slave_name == NULL)
- return err_ptsname_failed;
-
- m_slave_fd = ::open(slave_name, oflag);
-
- if (m_slave_fd < 0)
- return err_open_slave_failed;
-
- return success;
-}
-
-//----------------------------------------------------------------------
-// Get the name of the slave pseudo terminal. A master pseudo terminal
-// should already be valid prior to calling this function (see
-// PseudoTerminal::OpenFirstAvailableMaster()).
-//
-// RETURNS:
-// NULL if no valid master pseudo terminal or if ptsname() fails.
-// The name of the slave pseudo terminal as a NULL terminated C string
-// that comes from static memory, so a copy of the string should be
-// made as subsequent calls can change this value.
-//----------------------------------------------------------------------
-const char *PseudoTerminal::SlaveName() const {
- if (m_master_fd < 0)
- return NULL;
- return ::ptsname(m_master_fd);
-}
-
-//----------------------------------------------------------------------
-// Fork a child process that and have its stdio routed to a pseudo
-// terminal.
-//
-// In the parent process when a valid pid is returned, the master file
-// descriptor can be used as a read/write access to stdio of the
-// child process.
-//
-// In the child process the stdin/stdout/stderr will already be routed
-// to the slave pseudo terminal and the master file descriptor will be
-// closed as it is no longer needed by the child process.
-//
-// This class will close the file descriptors for the master/slave
-// when the destructor is called, so be sure to call ReleaseMasterFD()
-// or ReleaseSlaveFD() if any file descriptors are going to be used
-// past the lifespan of this object.
-//
-// RETURNS:
-// in the parent process: the pid of the child, or -1 if fork fails
-// in the child process: zero
-//----------------------------------------------------------------------
-
-pid_t PseudoTerminal::Fork(PseudoTerminal::Status &error) {
- pid_t pid = invalid_pid;
- error = OpenFirstAvailableMaster(O_RDWR | O_NOCTTY);
-
- if (error == 0) {
- // Successfully opened our master pseudo terminal
-
- pid = ::fork();
- if (pid < 0) {
- // Fork failed
- error = err_fork_failed;
- } else if (pid == 0) {
- // Child Process
- ::setsid();
-
- error = OpenSlave(O_RDWR);
- if (error == 0) {
- // Successfully opened slave
- // We are done with the master in the child process so lets close it
- CloseMaster();
-
-#if defined(TIOCSCTTY)
- // Acquire the controlling terminal
- if (::ioctl(m_slave_fd, TIOCSCTTY, (char *)0) < 0)
- error = err_failed_to_acquire_controlling_terminal;
-#endif
- // Duplicate all stdio file descriptors to the slave pseudo terminal
- if (::dup2(m_slave_fd, STDIN_FILENO) != STDIN_FILENO)
- error = error ? error : err_dup2_failed_on_stdin;
- if (::dup2(m_slave_fd, STDOUT_FILENO) != STDOUT_FILENO)
- error = error ? error : err_dup2_failed_on_stdout;
- if (::dup2(m_slave_fd, STDERR_FILENO) != STDERR_FILENO)
- error = error ? error : err_dup2_failed_on_stderr;
- }
- } else {
- // Parent Process
- // Do nothing and let the pid get returned!
- }
- }
- return pid;
-}
diff --git a/tools/debugserver/source/PseudoTerminal.h b/tools/debugserver/source/PseudoTerminal.h
deleted file mode 100644
index f6b71f8909a6..000000000000
--- a/tools/debugserver/source/PseudoTerminal.h
+++ /dev/null
@@ -1,87 +0,0 @@
-//===-- PseudoTerminal.h ----------------------------------------*- 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 1/8/08.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __PseudoTerminal_h__
-#define __PseudoTerminal_h__
-
-#include <fcntl.h>
-#include <string>
-#include <termios.h>
-
-class PseudoTerminal {
-public:
- enum { invalid_fd = -1, invalid_pid = -1 };
-
- enum Status {
- success = 0,
- err_posix_openpt_failed = -2,
- err_grantpt_failed = -3,
- err_unlockpt_failed = -4,
- err_ptsname_failed = -5,
- err_open_slave_failed = -6,
- err_fork_failed = -7,
- err_setsid_failed = -8,
- err_failed_to_acquire_controlling_terminal = -9,
- err_dup2_failed_on_stdin = -10,
- err_dup2_failed_on_stdout = -11,
- err_dup2_failed_on_stderr = -12
- };
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- PseudoTerminal();
- ~PseudoTerminal();
-
- void CloseMaster();
- void CloseSlave();
- Status OpenFirstAvailableMaster(int oflag);
- Status OpenSlave(int oflag);
- int MasterFD() const { return m_master_fd; }
- int SlaveFD() const { return m_slave_fd; }
- int ReleaseMasterFD() {
- // Release ownership of the master pseudo terminal file
- // descriptor without closing it. (the destructor for this
- // class will close it otherwise!)
- int fd = m_master_fd;
- m_master_fd = invalid_fd;
- return fd;
- }
- int ReleaseSlaveFD() {
- // Release ownership of the slave pseudo terminal file
- // descriptor without closing it (the destructor for this
- // class will close it otherwise!)
- int fd = m_slave_fd;
- m_slave_fd = invalid_fd;
- return fd;
- }
-
- const char *SlaveName() const;
-
- pid_t Fork(Status &error);
-
-protected:
- //------------------------------------------------------------------
- // Classes that inherit from PseudoTerminal can see and modify these
- //------------------------------------------------------------------
- int m_master_fd;
- int m_slave_fd;
-
-private:
- //------------------------------------------------------------------
- // Outlaw copy and assignment constructors
- //------------------------------------------------------------------
- PseudoTerminal(const PseudoTerminal &rhs);
- PseudoTerminal &operator=(const PseudoTerminal &rhs);
-};
-
-#endif // #ifndef __PseudoTerminal_h__
diff --git a/tools/debugserver/source/RNBContext.cpp b/tools/debugserver/source/RNBContext.cpp
deleted file mode 100644
index c86511c6e226..000000000000
--- a/tools/debugserver/source/RNBContext.cpp
+++ /dev/null
@@ -1,297 +0,0 @@
-//===-- RNBContext.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 12/12/07.
-//
-//===----------------------------------------------------------------------===//
-
-#include "RNBContext.h"
-
-#include <sstream>
-#include <sys/stat.h>
-
-#if defined(__APPLE__)
-#include <pthread.h>
-#include <sched.h>
-#endif
-
-#include "CFString.h"
-#include "DNB.h"
-#include "DNBLog.h"
-#include "RNBRemote.h"
-
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-RNBContext::~RNBContext() { SetProcessID(INVALID_NUB_PROCESS); }
-
-//----------------------------------------------------------------------
-// RNBContext constructor
-//----------------------------------------------------------------------
-
-const char *RNBContext::EnvironmentAtIndex(size_t index) {
- if (index < m_env_vec.size())
- return m_env_vec[index].c_str();
- else
- return NULL;
-}
-
-static std::string GetEnvironmentKey(const std::string &env) {
- std::string key = env.substr(0, env.find('='));
- if (!key.empty() && key.back() == '=')
- key.pop_back();
- return key;
-}
-
-void RNBContext::PushEnvironmentIfNeeded(const char *arg) {
- if (!arg)
- return;
- std::string arg_key = GetEnvironmentKey(arg);
-
- for (const std::string &entry: m_env_vec) {
- if (arg_key == GetEnvironmentKey(entry))
- return;
- }
- m_env_vec.push_back(arg);
-}
-
-const char *RNBContext::ArgumentAtIndex(size_t index) {
- if (index < m_arg_vec.size())
- return m_arg_vec[index].c_str();
- else
- return NULL;
-}
-
-bool RNBContext::SetWorkingDirectory(const char *path) {
- struct stat working_directory_stat;
- if (::stat(path, &working_directory_stat) != 0) {
- m_working_directory.clear();
- return false;
- }
- m_working_directory.assign(path);
- return true;
-}
-
-void RNBContext::SetProcessID(nub_process_t pid) {
- // Delete and events we created
- if (m_pid != INVALID_NUB_PROCESS) {
- StopProcessStatusThread();
- // Unregister this context as a client of the process's events.
- }
- // Assign our new process ID
- m_pid = pid;
-
- if (pid != INVALID_NUB_PROCESS) {
- StartProcessStatusThread();
- }
-}
-
-void RNBContext::StartProcessStatusThread() {
- DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s called", __FUNCTION__);
- if ((m_events.GetEventBits() & event_proc_thread_running) == 0) {
- int err = ::pthread_create(&m_pid_pthread, NULL,
- ThreadFunctionProcessStatus, this);
- if (err == 0) {
- // Our thread was successfully kicked off, wait for it to
- // set the started event so we can safely continue
- m_events.WaitForSetEvents(event_proc_thread_running);
- DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s thread got started!",
- __FUNCTION__);
- } else {
- DNBLogThreadedIf(LOG_RNB_PROC,
- "RNBContext::%s thread failed to start: err = %i",
- __FUNCTION__, err);
- m_events.ResetEvents(event_proc_thread_running);
- m_events.SetEvents(event_proc_thread_exiting);
- }
- }
-}
-
-void RNBContext::StopProcessStatusThread() {
- DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s called", __FUNCTION__);
- if ((m_events.GetEventBits() & event_proc_thread_running) ==
- event_proc_thread_running) {
- struct timespec timeout_abstime;
- DNBTimer::OffsetTimeOfDay(&timeout_abstime, 2, 0);
- // Wait for 2 seconds for the rx thread to exit
- if (m_events.WaitForSetEvents(RNBContext::event_proc_thread_exiting,
- &timeout_abstime) ==
- RNBContext::event_proc_thread_exiting) {
- DNBLogThreadedIf(LOG_RNB_PROC,
- "RNBContext::%s thread stopped as requeseted",
- __FUNCTION__);
- } else {
- DNBLogThreadedIf(LOG_RNB_PROC,
- "RNBContext::%s thread did not stop in 2 seconds...",
- __FUNCTION__);
- // Kill the RX thread???
- }
- }
-}
-
-//----------------------------------------------------------------------
-// This thread's sole purpose is to watch for any status changes in the
-// child process.
-//----------------------------------------------------------------------
-void *RNBContext::ThreadFunctionProcessStatus(void *arg) {
- RNBRemoteSP remoteSP(g_remoteSP);
- RNBRemote *remote = remoteSP.get();
- if (remote == NULL)
- return NULL;
- RNBContext &ctx = remote->Context();
-
- nub_process_t pid = ctx.ProcessID();
- DNBLogThreadedIf(LOG_RNB_PROC,
- "RNBContext::%s (arg=%p, pid=%4.4x): thread starting...",
- __FUNCTION__, arg, pid);
- ctx.Events().SetEvents(RNBContext::event_proc_thread_running);
-
-#if defined(__APPLE__)
- pthread_setname_np("child process status watcher thread");
-#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
- struct sched_param thread_param;
- int thread_sched_policy;
- if (pthread_getschedparam(pthread_self(), &thread_sched_policy,
- &thread_param) == 0) {
- thread_param.sched_priority = 47;
- pthread_setschedparam(pthread_self(), thread_sched_policy, &thread_param);
- }
-#endif
-#endif
-
- bool done = false;
- while (!done) {
- DNBLogThreadedIf(LOG_RNB_PROC,
- "RNBContext::%s calling DNBProcessWaitForEvent(pid, "
- "eEventProcessRunningStateChanged | "
- "eEventProcessStoppedStateChanged | eEventStdioAvailable "
- "| eEventProfileDataAvailable, true)...",
- __FUNCTION__);
- nub_event_t pid_status_event = DNBProcessWaitForEvents(
- pid,
- eEventProcessRunningStateChanged | eEventProcessStoppedStateChanged |
- eEventStdioAvailable | eEventProfileDataAvailable,
- true, NULL);
- DNBLogThreadedIf(LOG_RNB_PROC,
- "RNBContext::%s calling DNBProcessWaitForEvent(pid, "
- "eEventProcessRunningStateChanged | "
- "eEventProcessStoppedStateChanged | eEventStdioAvailable "
- "| eEventProfileDataAvailable, true) => 0x%8.8x",
- __FUNCTION__, pid_status_event);
-
- if (pid_status_event == 0) {
- DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s (pid=%4.4x) got ZERO back "
- "from DNBProcessWaitForEvent....",
- __FUNCTION__, pid);
- // done = true;
- } else {
- if (pid_status_event & eEventStdioAvailable) {
- DNBLogThreadedIf(
- LOG_RNB_PROC,
- "RNBContext::%s (pid=%4.4x) got stdio available event....",
- __FUNCTION__, pid);
- ctx.Events().SetEvents(RNBContext::event_proc_stdio_available);
- // Wait for the main thread to consume this notification if it requested
- // we wait for it
- ctx.Events().WaitForResetAck(RNBContext::event_proc_stdio_available);
- }
-
- if (pid_status_event & eEventProfileDataAvailable) {
- DNBLogThreadedIf(
- LOG_RNB_PROC,
- "RNBContext::%s (pid=%4.4x) got profile data event....",
- __FUNCTION__, pid);
- ctx.Events().SetEvents(RNBContext::event_proc_profile_data);
- // Wait for the main thread to consume this notification if it requested
- // we wait for it
- ctx.Events().WaitForResetAck(RNBContext::event_proc_profile_data);
- }
-
- if (pid_status_event & (eEventProcessRunningStateChanged |
- eEventProcessStoppedStateChanged)) {
- nub_state_t pid_state = DNBProcessGetState(pid);
- DNBLogThreadedIf(
- LOG_RNB_PROC,
- "RNBContext::%s (pid=%4.4x) got process state change: %s",
- __FUNCTION__, pid, DNBStateAsString(pid_state));
-
- // Let the main thread know there is a process state change to see
- ctx.Events().SetEvents(RNBContext::event_proc_state_changed);
- // Wait for the main thread to consume this notification if it requested
- // we wait for it
- ctx.Events().WaitForResetAck(RNBContext::event_proc_state_changed);
-
- switch (pid_state) {
- case eStateStopped:
- break;
-
- case eStateInvalid:
- case eStateExited:
- case eStateDetached:
- done = true;
- break;
- default:
- break;
- }
- }
-
- // Reset any events that we consumed.
- DNBProcessResetEvents(pid, pid_status_event);
- }
- }
- DNBLogThreadedIf(LOG_RNB_PROC,
- "RNBContext::%s (arg=%p, pid=%4.4x): thread exiting...",
- __FUNCTION__, arg, pid);
- ctx.Events().ResetEvents(event_proc_thread_running);
- ctx.Events().SetEvents(event_proc_thread_exiting);
- return NULL;
-}
-
-const char *RNBContext::EventsAsString(nub_event_t events, std::string &s) {
- s.clear();
- if (events & event_proc_state_changed)
- s += "proc_state_changed ";
- if (events & event_proc_thread_running)
- s += "proc_thread_running ";
- if (events & event_proc_thread_exiting)
- s += "proc_thread_exiting ";
- if (events & event_proc_stdio_available)
- s += "proc_stdio_available ";
- if (events & event_proc_profile_data)
- s += "proc_profile_data ";
- if (events & event_darwin_log_data_available)
- s += "darwin_log_data_available ";
- if (events & event_read_packet_available)
- s += "read_packet_available ";
- if (events & event_read_thread_running)
- s += "read_thread_running ";
- if (events & event_read_thread_running)
- s += "read_thread_running ";
- return s.c_str();
-}
-
-const char *RNBContext::LaunchStatusAsString(std::string &s) {
- s.clear();
-
- const char *err_str = m_launch_status.AsString();
- if (err_str)
- s = err_str;
- else {
- char error_num_str[64];
- snprintf(error_num_str, sizeof(error_num_str), "%u",
- m_launch_status.Status());
- s = error_num_str;
- }
- return s.c_str();
-}
-
-bool RNBContext::ProcessStateRunning() const {
- nub_state_t pid_state = DNBProcessGetState(m_pid);
- return pid_state == eStateRunning || pid_state == eStateStepping;
-}
diff --git a/tools/debugserver/source/RNBContext.h b/tools/debugserver/source/RNBContext.h
deleted file mode 100644
index 0c649ae41007..000000000000
--- a/tools/debugserver/source/RNBContext.h
+++ /dev/null
@@ -1,164 +0,0 @@
-//===-- RNBContext.h --------------------------------------------*- 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 12/12/07.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __RNBContext_h__
-#define __RNBContext_h__
-
-#include "DNBError.h"
-#include "PThreadEvent.h"
-#include "RNBDefs.h"
-#include <string>
-#include <vector>
-
-class RNBContext {
-public:
- enum {
- event_proc_state_changed = 0x001,
- event_proc_thread_running = 0x002, // Sticky
- event_proc_thread_exiting = 0x004,
- event_proc_stdio_available = 0x008,
- event_proc_profile_data = 0x010,
- event_read_packet_available = 0x020,
- event_read_thread_running = 0x040, // Sticky
- event_read_thread_exiting = 0x080,
- event_darwin_log_data_available = 0x100,
-
- normal_event_bits = event_proc_state_changed | event_proc_thread_exiting |
- event_proc_stdio_available | event_proc_profile_data |
- event_read_packet_available |
- event_read_thread_exiting |
- event_darwin_log_data_available,
-
- sticky_event_bits = event_proc_thread_running | event_read_thread_running,
-
- all_event_bits = sticky_event_bits | normal_event_bits
- } event_t;
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- RNBContext()
- : m_pid(INVALID_NUB_PROCESS), m_pid_stop_count(0),
- m_events(0, all_event_bits), m_pid_pthread(), m_launch_status(),
- m_arg_vec(), m_env_vec(), m_detach_on_error(false) {}
-
- virtual ~RNBContext();
-
- nub_process_t ProcessID() const { return m_pid; }
- bool HasValidProcessID() const { return m_pid != INVALID_NUB_PROCESS; }
- void SetProcessID(nub_process_t pid);
- nub_size_t GetProcessStopCount() const { return m_pid_stop_count; }
- bool SetProcessStopCount(nub_size_t count) {
- // Returns true if this class' notion of the PID state changed
- if (m_pid_stop_count == count)
- return false; // Didn't change
- m_pid_stop_count = count;
- return true; // The stop count has changed.
- }
-
- bool ProcessStateRunning() const;
- PThreadEvent &Events() { return m_events; }
- nub_event_t AllEventBits() const { return all_event_bits; }
- nub_event_t NormalEventBits() const { return normal_event_bits; }
- nub_event_t StickyEventBits() const { return sticky_event_bits; }
- const char *EventsAsString(nub_event_t events, std::string &s);
-
- size_t ArgumentCount() const { return m_arg_vec.size(); }
- const char *ArgumentAtIndex(size_t index);
- void PushArgument(const char *arg) {
- if (arg)
- m_arg_vec.push_back(arg);
- }
- void ClearArgv() { m_arg_vec.erase(m_arg_vec.begin(), m_arg_vec.end()); }
-
- size_t EnvironmentCount() const { return m_env_vec.size(); }
- const char *EnvironmentAtIndex(size_t index);
- void PushEnvironment(const char *arg) {
- if (arg)
- m_env_vec.push_back(arg);
- }
- void PushEnvironmentIfNeeded(const char *arg);
- void ClearEnvironment() {
- m_env_vec.erase(m_env_vec.begin(), m_env_vec.end());
- }
- DNBError &LaunchStatus() { return m_launch_status; }
- const char *LaunchStatusAsString(std::string &s);
- nub_launch_flavor_t LaunchFlavor() const { return m_launch_flavor; }
- void SetLaunchFlavor(nub_launch_flavor_t flavor) { m_launch_flavor = flavor; }
-
- const char *GetWorkingDirectory() const {
- if (!m_working_directory.empty())
- return m_working_directory.c_str();
- return NULL;
- }
-
- bool SetWorkingDirectory(const char *path);
-
- std::string &GetSTDIN() { return m_stdin; }
- std::string &GetSTDOUT() { return m_stdout; }
- std::string &GetSTDERR() { return m_stderr; }
- std::string &GetWorkingDir() { return m_working_dir; }
-
- const char *GetSTDINPath() {
- return m_stdin.empty() ? NULL : m_stdin.c_str();
- }
- 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; }
-
-protected:
- //------------------------------------------------------------------
- // Classes that inherit from RNBContext can see and modify these
- //------------------------------------------------------------------
- nub_process_t m_pid;
- std::string m_stdin;
- std::string m_stdout;
- std::string m_stderr;
- std::string m_working_dir;
- nub_size_t m_pid_stop_count;
- PThreadEvent m_events; // Threaded events that we can wait for
- pthread_t m_pid_pthread;
- nub_launch_flavor_t m_launch_flavor; // How to launch our inferior process
- DNBError
- m_launch_status; // This holds the status from the last launch attempt.
- 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();
- void StopProcessStatusThread();
- static void *ThreadFunctionProcessStatus(void *arg);
-
-private:
- //------------------------------------------------------------------
- // Outlaw copy and assignment operators
- //------------------------------------------------------------------
- RNBContext(const RNBContext &rhs);
- RNBContext &operator=(const RNBContext &rhs);
-};
-
-#endif // #ifndef __RNBContext_h__
diff --git a/tools/debugserver/source/RNBDefs.h b/tools/debugserver/source/RNBDefs.h
deleted file mode 100644
index 5714099f5fcd..000000000000
--- a/tools/debugserver/source/RNBDefs.h
+++ /dev/null
@@ -1,99 +0,0 @@
-//===-- RNBDefs.h -----------------------------------------------*- 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 12/14/07.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __RNBDefs_h__
-#define __RNBDefs_h__
-
-#include "DNBDefs.h"
-#include <memory>
-
-#define CONCAT2(a, b) a##b
-#define CONCAT(a, b) CONCAT2(a, b)
-#define STRINGIZE2(x) #x
-#define STRINGIZE(x) STRINGIZE2(x)
-
-#if !defined(DEBUGSERVER_PROGRAM_SYMBOL)
-#define DEBUGSERVER_PROGRAM_SYMBOL debugserver
-#endif
-
-#if !defined(DEBUGSERVER_PROGRAM_NAME)
-#define DEBUGSERVER_PROGRAM_NAME STRINGIZE(DEBUGSERVER_PROGRAM_SYMBOL)
-#endif
-
-#ifndef DEBUGSERVER_VERSION_NUM
-extern "C" const unsigned char CONCAT(DEBUGSERVER_PROGRAM_SYMBOL,
- VersionString)[];
-#define DEBUGSERVER_VERSION_NUM \
- CONCAT(DEBUGSERVER_PROGRAM_SYMBOL, VersionNumber)
-#endif
-
-#ifndef DEBUGSERVER_VERSION_STR
-extern "C" const double CONCAT(DEBUGSERVER_PROGRAM_SYMBOL, VersionNumber);
-#define DEBUGSERVER_VERSION_STR \
- CONCAT(DEBUGSERVER_PROGRAM_SYMBOL, VersionString)
-#endif
-
-#if defined(__i386__)
-
-#define RNB_ARCH "i386"
-
-#elif defined(__x86_64__)
-
-#define RNB_ARCH "x86_64"
-
-#elif defined(__ppc64__)
-
-#define RNB_ARCH "ppc64"
-
-#elif defined(__powerpc__) || defined(__ppc__)
-
-#define RNB_ARCH "ppc"
-
-#elif defined(__arm64__) || defined(__aarch64__)
-
-#define RNB_ARCH "arm64"
-
-#elif defined(__arm__)
-
-#define RNB_ARCH "armv7"
-
-#else
-
-#error undefined architecture
-
-#endif
-
-class RNBRemote;
-typedef std::shared_ptr<RNBRemote> RNBRemoteSP;
-
-typedef enum { rnb_success = 0, rnb_err = 1, rnb_not_connected = 2 } rnb_err_t;
-
-// Log bits
-// reserve low bits for DNB
-#define LOG_RNB_MINIMAL \
- ((LOG_LO_USER) << 0) // Minimal logging (min verbosity)
-#define LOG_RNB_MEDIUM \
- ((LOG_LO_USER) << 1) // Medium logging (med verbosity)
-#define LOG_RNB_MAX ((LOG_LO_USER) << 2) // Max logging (max verbosity)
-#define LOG_RNB_COMM ((LOG_LO_USER) << 3) // Log communications (RNBSocket)
-#define LOG_RNB_REMOTE ((LOG_LO_USER) << 4) // Log remote (RNBRemote)
-#define LOG_RNB_EVENTS \
- ((LOG_LO_USER) << 5) // Log events (PThreadEvents)
-#define LOG_RNB_PROC ((LOG_LO_USER) << 6) // Log process state (Process thread)
-#define LOG_RNB_PACKETS ((LOG_LO_USER) << 7) // Log gdb remote packets
-#define LOG_RNB_ALL (~((LOG_LO_USER)-1))
-#define LOG_RNB_DEFAULT (LOG_RNB_ALL)
-
-extern RNBRemoteSP g_remoteSP;
-
-#endif // #ifndef __RNBDefs_h__
diff --git a/tools/debugserver/source/RNBRemote.cpp b/tools/debugserver/source/RNBRemote.cpp
deleted file mode 100644
index f611ec0d2199..000000000000
--- a/tools/debugserver/source/RNBRemote.cpp
+++ /dev/null
@@ -1,6256 +0,0 @@
-//===-- RNBRemote.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 12/12/07.
-//
-//===----------------------------------------------------------------------===//
-
-#include "RNBRemote.h"
-
-#include <errno.h>
-#include <mach-o/loader.h>
-#include <mach/exception_types.h>
-#include <signal.h>
-#include <sys/stat.h>
-#include <sys/sysctl.h>
-#include <unistd.h>
-
-#if defined(__APPLE__)
-#include <pthread.h>
-#include <sched.h>
-#endif
-
-#include "DNB.h"
-#include "DNBDataRef.h"
-#include "DNBLog.h"
-#include "DNBThreadResumeActions.h"
-#include "DarwinLogCollector.h"
-#include "DarwinLogEvent.h"
-#include "JSON.h"
-#include "JSONGenerator.h"
-#include "JSONGenerator.h"
-#include "MacOSX/Genealogy.h"
-#include "OsLogger.h"
-#include "RNBContext.h"
-#include "RNBServices.h"
-#include "RNBSocket.h"
-#include "StdStringExtractor.h"
-
-#include <compression.h>
-
-#include <TargetConditionals.h>
-#include <iomanip>
-#include <sstream>
-#include <unordered_set>
-
-//----------------------------------------------------------------------
-// constants
-//----------------------------------------------------------------------
-
-static const std::string OS_LOG_EVENTS_KEY_NAME("events");
-static const std::string JSON_ASYNC_TYPE_KEY_NAME("type");
-static const DarwinLogEventVector::size_type DARWIN_LOG_MAX_EVENTS_PER_PACKET =
- 10;
-
-//----------------------------------------------------------------------
-// std::iostream formatting macros
-//----------------------------------------------------------------------
-#define RAW_HEXBASE std::setfill('0') << std::hex << std::right
-#define HEXBASE '0' << 'x' << RAW_HEXBASE
-#define RAWHEX8(x) RAW_HEXBASE << std::setw(2) << ((uint32_t)((uint8_t)x))
-#define RAWHEX16 RAW_HEXBASE << std::setw(4)
-#define RAWHEX32 RAW_HEXBASE << std::setw(8)
-#define RAWHEX64 RAW_HEXBASE << std::setw(16)
-#define HEX8(x) HEXBASE << std::setw(2) << ((uint32_t)(x))
-#define HEX16 HEXBASE << std::setw(4)
-#define HEX32 HEXBASE << std::setw(8)
-#define HEX64 HEXBASE << std::setw(16)
-#define RAW_HEX(x) RAW_HEXBASE << std::setw(sizeof(x) * 2) << (x)
-#define HEX(x) HEXBASE << std::setw(sizeof(x) * 2) << (x)
-#define RAWHEX_SIZE(x, sz) RAW_HEXBASE << std::setw((sz)) << (x)
-#define HEX_SIZE(x, sz) HEXBASE << std::setw((sz)) << (x)
-#define STRING_WIDTH(w) std::setfill(' ') << std::setw(w)
-#define LEFT_STRING_WIDTH(s, w) \
- std::left << std::setfill(' ') << std::setw(w) << (s) << std::right
-#define DECIMAL std::dec << std::setfill(' ')
-#define DECIMAL_WIDTH(w) DECIMAL << std::setw(w)
-#define FLOAT(n, d) \
- std::setfill(' ') << std::setw((n) + (d) + 1) << std::setprecision(d) \
- << std::showpoint << std::fixed
-#define INDENT_WITH_SPACES(iword_idx) \
- std::setfill(' ') << std::setw((iword_idx)) << ""
-#define INDENT_WITH_TABS(iword_idx) \
- std::setfill('\t') << std::setw((iword_idx)) << ""
-// Class to handle communications via gdb remote protocol.
-
-//----------------------------------------------------------------------
-// Prototypes
-//----------------------------------------------------------------------
-
-static std::string binary_encode_string(const std::string &s);
-
-//----------------------------------------------------------------------
-// Decode a single hex character and return the hex value as a number or
-// -1 if "ch" is not a hex character.
-//----------------------------------------------------------------------
-static inline int xdigit_to_sint(char ch) {
- if (ch >= 'a' && ch <= 'f')
- return 10 + ch - 'a';
- if (ch >= 'A' && ch <= 'F')
- return 10 + ch - 'A';
- if (ch >= '0' && ch <= '9')
- return ch - '0';
- return -1;
-}
-
-//----------------------------------------------------------------------
-// Decode a single hex ASCII byte. Return -1 on failure, a value 0-255
-// on success.
-//----------------------------------------------------------------------
-static inline int decoded_hex_ascii_char(const char *p) {
- const int hi_nibble = xdigit_to_sint(p[0]);
- if (hi_nibble == -1)
- return -1;
- const int lo_nibble = xdigit_to_sint(p[1]);
- if (lo_nibble == -1)
- return -1;
- return (uint8_t)((hi_nibble << 4) + lo_nibble);
-}
-
-//----------------------------------------------------------------------
-// Decode a hex ASCII string back into a string
-//----------------------------------------------------------------------
-static std::string decode_hex_ascii_string(const char *p,
- uint32_t max_length = UINT32_MAX) {
- std::string arg;
- if (p) {
- for (const char *c = p; ((c - p) / 2) < max_length; c += 2) {
- int ch = decoded_hex_ascii_char(c);
- if (ch == -1)
- break;
- else
- arg.push_back(ch);
- }
- }
- return arg;
-}
-
-uint64_t decode_uint64(const char *p, int base, char **end = nullptr,
- uint64_t fail_value = 0) {
- nub_addr_t addr = strtoull(p, end, 16);
- if (addr == 0 && errno != 0)
- return fail_value;
- return addr;
-}
-
-extern void ASLLogCallback(void *baton, uint32_t flags, const char *format,
- va_list args);
-
-#if defined(__APPLE__) && \
- (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101000)
-// from System.framework/Versions/B/PrivateHeaders/sys/codesign.h
-extern "C" {
-#define CS_OPS_STATUS 0 /* return status */
-#define CS_RESTRICT 0x0000800 /* tell dyld to treat restricted */
-int csops(pid_t pid, unsigned int ops, void *useraddr, size_t usersize);
-
-// from rootless.h
-bool rootless_allows_task_for_pid(pid_t pid);
-
-// from sys/csr.h
-typedef uint32_t csr_config_t;
-#define CSR_ALLOW_TASK_FOR_PID (1 << 2)
-int csr_check(csr_config_t mask);
-}
-#endif
-
-RNBRemote::RNBRemote()
- : m_ctx(), m_comm(), m_arch(), m_continue_thread(-1), m_thread(-1),
- m_mutex(), m_dispatch_queue_offsets(),
- m_dispatch_queue_offsets_addr(INVALID_NUB_ADDRESS),
- m_qSymbol_index(UINT32_MAX), m_packets_recvd(0), m_packets(),
- m_rx_packets(), m_rx_partial_data(), m_rx_pthread(0),
- m_max_payload_size(DEFAULT_GDB_REMOTE_PROTOCOL_BUFSIZE - 4),
- m_extended_mode(false), m_noack_mode(false),
- m_thread_suffix_supported(false), m_list_threads_in_stop_reply(false),
- m_compression_minsize(384), m_enable_compression_next_send_packet(false),
- m_compression_mode(compression_types::none) {
- DNBLogThreadedIf(LOG_RNB_REMOTE, "%s", __PRETTY_FUNCTION__);
- CreatePacketTable();
-}
-
-RNBRemote::~RNBRemote() {
- DNBLogThreadedIf(LOG_RNB_REMOTE, "%s", __PRETTY_FUNCTION__);
- StopReadRemoteDataThread();
-}
-
-void RNBRemote::CreatePacketTable() {
- // Step required to add new packets:
- // 1 - Add new enumeration to RNBRemote::PacketEnum
- // 2 - Create the RNBRemote::HandlePacket_ function if a new function is
- // needed
- // 3 - Register the Packet definition with any needed callbacks in this
- // function
- // - If no response is needed for a command, then use NULL for the
- // normal callback
- // - If the packet is not supported while the target is running, use
- // NULL for the async callback
- // 4 - If the packet is a standard packet (starts with a '$' character
- // followed by the payload and then '#' and checksum, then you are done
- // else go on to step 5
- // 5 - if the packet is a fixed length packet:
- // - modify the switch statement for the first character in the payload
- // in RNBRemote::CommDataReceived so it doesn't reject the new packet
- // type as invalid
- // - modify the switch statement for the first character in the payload
- // in RNBRemote::GetPacketPayload and make sure the payload of the
- // packet
- // is returned correctly
-
- std::vector<Packet> &t = m_packets;
- t.push_back(Packet(ack, NULL, NULL, "+", "ACK"));
- t.push_back(Packet(nack, NULL, NULL, "-", "!ACK"));
- t.push_back(Packet(read_memory, &RNBRemote::HandlePacket_m, NULL, "m",
- "Read memory"));
- t.push_back(Packet(read_register, &RNBRemote::HandlePacket_p, NULL, "p",
- "Read one register"));
- t.push_back(Packet(read_general_regs, &RNBRemote::HandlePacket_g, NULL, "g",
- "Read registers"));
- t.push_back(Packet(write_memory, &RNBRemote::HandlePacket_M, NULL, "M",
- "Write memory"));
- t.push_back(Packet(write_register, &RNBRemote::HandlePacket_P, NULL, "P",
- "Write one register"));
- t.push_back(Packet(write_general_regs, &RNBRemote::HandlePacket_G, NULL, "G",
- "Write registers"));
- t.push_back(Packet(insert_mem_bp, &RNBRemote::HandlePacket_z, NULL, "Z0",
- "Insert memory breakpoint"));
- t.push_back(Packet(remove_mem_bp, &RNBRemote::HandlePacket_z, NULL, "z0",
- "Remove memory breakpoint"));
- t.push_back(Packet(single_step, &RNBRemote::HandlePacket_s, NULL, "s",
- "Single step"));
- t.push_back(Packet(cont, &RNBRemote::HandlePacket_c, NULL, "c", "continue"));
- t.push_back(Packet(single_step_with_sig, &RNBRemote::HandlePacket_S, NULL,
- "S", "Single step with signal"));
- t.push_back(
- Packet(set_thread, &RNBRemote::HandlePacket_H, NULL, "H", "Set thread"));
- t.push_back(Packet(halt, &RNBRemote::HandlePacket_last_signal,
- &RNBRemote::HandlePacket_stop_process, "\x03", "^C"));
- // t.push_back (Packet (use_extended_mode,
- // &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "!", "Use extended mode"));
- t.push_back(Packet(why_halted, &RNBRemote::HandlePacket_last_signal, NULL,
- "?", "Why did target halt"));
- t.push_back(
- Packet(set_argv, &RNBRemote::HandlePacket_A, NULL, "A", "Set argv"));
- // t.push_back (Packet (set_bp,
- // &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "B", "Set/clear
- // breakpoint"));
- t.push_back(Packet(continue_with_sig, &RNBRemote::HandlePacket_C, NULL, "C",
- "Continue with signal"));
- t.push_back(Packet(detach, &RNBRemote::HandlePacket_D, NULL, "D",
- "Detach gdb from remote system"));
- // t.push_back (Packet (step_inferior_one_cycle,
- // &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "i", "Step inferior by one
- // clock cycle"));
- // t.push_back (Packet (signal_and_step_inf_one_cycle,
- // &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "I", "Signal inferior, then
- // step one clock cycle"));
- t.push_back(Packet(kill, &RNBRemote::HandlePacket_k, NULL, "k", "Kill"));
- // t.push_back (Packet (restart,
- // &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "R", "Restart inferior"));
- // t.push_back (Packet (search_mem_backwards,
- // &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "t", "Search memory
- // backwards"));
- t.push_back(Packet(thread_alive_p, &RNBRemote::HandlePacket_T, NULL, "T",
- "Is thread alive"));
- t.push_back(Packet(query_supported_features,
- &RNBRemote::HandlePacket_qSupported, NULL, "qSupported",
- "Query about supported features"));
- t.push_back(Packet(vattach, &RNBRemote::HandlePacket_v, NULL, "vAttach",
- "Attach to a new process"));
- t.push_back(Packet(vattachwait, &RNBRemote::HandlePacket_v, NULL,
- "vAttachWait",
- "Wait for a process to start up then attach to it"));
- t.push_back(Packet(vattachorwait, &RNBRemote::HandlePacket_v, NULL,
- "vAttachOrWait", "Attach to the process or if it doesn't "
- "exist, wait for the process to start up "
- "then attach to it"));
- t.push_back(Packet(vattachname, &RNBRemote::HandlePacket_v, NULL,
- "vAttachName", "Attach to an existing process by name"));
- t.push_back(Packet(vcont_list_actions, &RNBRemote::HandlePacket_v, NULL,
- "vCont;", "Verbose resume with thread actions"));
- t.push_back(Packet(vcont_list_actions, &RNBRemote::HandlePacket_v, NULL,
- "vCont?",
- "List valid continue-with-thread-actions actions"));
- t.push_back(Packet(read_data_from_memory, &RNBRemote::HandlePacket_x, NULL,
- "x", "Read data from memory"));
- t.push_back(Packet(write_data_to_memory, &RNBRemote::HandlePacket_X, NULL,
- "X", "Write data to memory"));
- // t.push_back (Packet (insert_hardware_bp,
- // &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "Z1", "Insert hardware
- // breakpoint"));
- // t.push_back (Packet (remove_hardware_bp,
- // &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "z1", "Remove hardware
- // breakpoint"));
- t.push_back(Packet(insert_write_watch_bp, &RNBRemote::HandlePacket_z, NULL,
- "Z2", "Insert write watchpoint"));
- t.push_back(Packet(remove_write_watch_bp, &RNBRemote::HandlePacket_z, NULL,
- "z2", "Remove write watchpoint"));
- t.push_back(Packet(insert_read_watch_bp, &RNBRemote::HandlePacket_z, NULL,
- "Z3", "Insert read watchpoint"));
- t.push_back(Packet(remove_read_watch_bp, &RNBRemote::HandlePacket_z, NULL,
- "z3", "Remove read watchpoint"));
- t.push_back(Packet(insert_access_watch_bp, &RNBRemote::HandlePacket_z, NULL,
- "Z4", "Insert access watchpoint"));
- t.push_back(Packet(remove_access_watch_bp, &RNBRemote::HandlePacket_z, NULL,
- "z4", "Remove access watchpoint"));
- t.push_back(Packet(query_monitor, &RNBRemote::HandlePacket_qRcmd, NULL,
- "qRcmd", "Monitor command"));
- t.push_back(Packet(query_current_thread_id, &RNBRemote::HandlePacket_qC, NULL,
- "qC", "Query current thread ID"));
- t.push_back(Packet(query_echo, &RNBRemote::HandlePacket_qEcho, NULL, "qEcho:",
- "Echo the packet back to allow the debugger to sync up "
- "with this server"));
- t.push_back(Packet(query_get_pid, &RNBRemote::HandlePacket_qGetPid, NULL,
- "qGetPid", "Query process id"));
- t.push_back(Packet(query_thread_ids_first,
- &RNBRemote::HandlePacket_qThreadInfo, NULL, "qfThreadInfo",
- "Get list of active threads (first req)"));
- t.push_back(Packet(query_thread_ids_subsequent,
- &RNBRemote::HandlePacket_qThreadInfo, NULL, "qsThreadInfo",
- "Get list of active threads (subsequent req)"));
- // APPLE LOCAL: qThreadStopInfo
- // syntax: qThreadStopInfoTTTT
- // TTTT is hex thread ID
- t.push_back(Packet(query_thread_stop_info,
- &RNBRemote::HandlePacket_qThreadStopInfo, NULL,
- "qThreadStopInfo",
- "Get detailed info on why the specified thread stopped"));
- t.push_back(Packet(query_thread_extra_info,
- &RNBRemote::HandlePacket_qThreadExtraInfo, NULL,
- "qThreadExtraInfo", "Get printable status of a thread"));
- // t.push_back (Packet (query_image_offsets,
- // &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "qOffsets", "Report offset
- // of loaded program"));
- t.push_back(Packet(
- query_launch_success, &RNBRemote::HandlePacket_qLaunchSuccess, NULL,
- "qLaunchSuccess", "Report the success or failure of the launch attempt"));
- t.push_back(
- Packet(query_register_info, &RNBRemote::HandlePacket_qRegisterInfo, NULL,
- "qRegisterInfo",
- "Dynamically discover remote register context information."));
- t.push_back(Packet(
- query_shlib_notify_info_addr, &RNBRemote::HandlePacket_qShlibInfoAddr,
- NULL, "qShlibInfoAddr", "Returns the address that contains info needed "
- "for getting shared library notifications"));
- t.push_back(Packet(query_step_packet_supported,
- &RNBRemote::HandlePacket_qStepPacketSupported, NULL,
- "qStepPacketSupported",
- "Replys with OK if the 's' packet is supported."));
- t.push_back(
- Packet(query_vattachorwait_supported,
- &RNBRemote::HandlePacket_qVAttachOrWaitSupported, NULL,
- "qVAttachOrWaitSupported",
- "Replys with OK if the 'vAttachOrWait' packet is supported."));
- t.push_back(
- Packet(query_sync_thread_state_supported,
- &RNBRemote::HandlePacket_qSyncThreadStateSupported, NULL,
- "qSyncThreadStateSupported",
- "Replys with OK if the 'QSyncThreadState:' packet is supported."));
- t.push_back(Packet(
- query_host_info, &RNBRemote::HandlePacket_qHostInfo, NULL, "qHostInfo",
- "Replies with multiple 'key:value;' tuples appended to each other."));
- t.push_back(Packet(
- query_gdb_server_version, &RNBRemote::HandlePacket_qGDBServerVersion,
- NULL, "qGDBServerVersion",
- "Replies with multiple 'key:value;' tuples appended to each other."));
- t.push_back(Packet(
- query_process_info, &RNBRemote::HandlePacket_qProcessInfo, NULL,
- "qProcessInfo",
- "Replies with multiple 'key:value;' tuples appended to each other."));
- t.push_back(Packet(
- query_symbol_lookup, &RNBRemote::HandlePacket_qSymbol, NULL, "qSymbol:",
- "Notify that host debugger is ready to do symbol lookups"));
- t.push_back(Packet(json_query_thread_extended_info,
- &RNBRemote::HandlePacket_jThreadExtendedInfo, NULL,
- "jThreadExtendedInfo",
- "Replies with JSON data of thread extended information."));
- t.push_back(Packet(json_query_get_loaded_dynamic_libraries_infos,
- &RNBRemote::HandlePacket_jGetLoadedDynamicLibrariesInfos,
- NULL, "jGetLoadedDynamicLibrariesInfos",
- "Replies with JSON data of all the shared libraries "
- "loaded in this process."));
- t.push_back(
- Packet(json_query_threads_info, &RNBRemote::HandlePacket_jThreadsInfo,
- NULL, "jThreadsInfo",
- "Replies with JSON data with information about all threads."));
- t.push_back(Packet(json_query_get_shared_cache_info,
- &RNBRemote::HandlePacket_jGetSharedCacheInfo, NULL,
- "jGetSharedCacheInfo", "Replies with JSON data about the "
- "location and uuid of the shared "
- "cache in the inferior process."));
- t.push_back(Packet(start_noack_mode, &RNBRemote::HandlePacket_QStartNoAckMode,
- NULL, "QStartNoAckMode",
- "Request that " DEBUGSERVER_PROGRAM_NAME
- " stop acking remote protocol packets"));
- t.push_back(Packet(prefix_reg_packets_with_tid,
- &RNBRemote::HandlePacket_QThreadSuffixSupported, NULL,
- "QThreadSuffixSupported",
- "Check if thread specific packets (register packets 'g', "
- "'G', 'p', and 'P') support having the thread ID appended "
- "to the end of the command"));
- t.push_back(Packet(set_logging_mode, &RNBRemote::HandlePacket_QSetLogging,
- NULL, "QSetLogging:", "Check if register packets ('g', "
- "'G', 'p', and 'P' support having "
- "the thread ID prefix"));
- t.push_back(Packet(
- set_max_packet_size, &RNBRemote::HandlePacket_QSetMaxPacketSize, NULL,
- "QSetMaxPacketSize:",
- "Tell " DEBUGSERVER_PROGRAM_NAME " the max sized packet gdb can handle"));
- t.push_back(Packet(
- set_max_payload_size, &RNBRemote::HandlePacket_QSetMaxPayloadSize, NULL,
- "QSetMaxPayloadSize:", "Tell " DEBUGSERVER_PROGRAM_NAME
- " the max sized payload gdb can handle"));
- t.push_back(
- Packet(set_environment_variable, &RNBRemote::HandlePacket_QEnvironment,
- NULL, "QEnvironment:",
- "Add an environment variable to the inferior's environment"));
- t.push_back(
- Packet(set_environment_variable_hex,
- &RNBRemote::HandlePacket_QEnvironmentHexEncoded, NULL,
- "QEnvironmentHexEncoded:",
- "Add an environment variable to the inferior's environment"));
- t.push_back(Packet(set_launch_arch, &RNBRemote::HandlePacket_QLaunchArch,
- NULL, "QLaunchArch:", "Set the architecture to use when "
- "launching a process for hosts that "
- "can run multiple architecture "
- "slices from universal files."));
- t.push_back(Packet(set_disable_aslr, &RNBRemote::HandlePacket_QSetDisableASLR,
- NULL, "QSetDisableASLR:",
- "Set whether to disable ASLR when launching the process "
- "with the set argv ('A') packet"));
- t.push_back(Packet(set_stdin, &RNBRemote::HandlePacket_QSetSTDIO, NULL,
- "QSetSTDIN:", "Set the standard input for a process to be "
- "launched with the 'A' packet"));
- t.push_back(Packet(set_stdout, &RNBRemote::HandlePacket_QSetSTDIO, NULL,
- "QSetSTDOUT:", "Set the standard output for a process to "
- "be launched with the 'A' packet"));
- t.push_back(Packet(set_stderr, &RNBRemote::HandlePacket_QSetSTDIO, NULL,
- "QSetSTDERR:", "Set the standard error for a process to "
- "be launched with the 'A' packet"));
- t.push_back(Packet(set_working_dir, &RNBRemote::HandlePacket_QSetWorkingDir,
- NULL, "QSetWorkingDir:", "Set the working directory for a "
- "process to be launched with the "
- "'A' packet"));
- t.push_back(Packet(set_list_threads_in_stop_reply,
- &RNBRemote::HandlePacket_QListThreadsInStopReply, NULL,
- "QListThreadsInStopReply",
- "Set if the 'threads' key should be added to the stop "
- "reply packets with a list of all thread IDs."));
- t.push_back(Packet(
- sync_thread_state, &RNBRemote::HandlePacket_QSyncThreadState, NULL,
- "QSyncThreadState:", "Do whatever is necessary to make sure 'thread' is "
- "in a safe state to call functions on."));
- // t.push_back (Packet (pass_signals_to_inferior,
- // &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "QPassSignals:", "Specify
- // which signals are passed to the inferior"));
- t.push_back(Packet(allocate_memory, &RNBRemote::HandlePacket_AllocateMemory,
- NULL, "_M", "Allocate memory in the inferior process."));
- t.push_back(Packet(deallocate_memory,
- &RNBRemote::HandlePacket_DeallocateMemory, NULL, "_m",
- "Deallocate memory in the inferior process."));
- t.push_back(Packet(
- save_register_state, &RNBRemote::HandlePacket_SaveRegisterState, NULL,
- "QSaveRegisterState", "Save the register state for the current thread "
- "and return a decimal save ID."));
- t.push_back(Packet(restore_register_state,
- &RNBRemote::HandlePacket_RestoreRegisterState, NULL,
- "QRestoreRegisterState:",
- "Restore the register state given a save ID previously "
- "returned from a call to QSaveRegisterState."));
- t.push_back(Packet(
- memory_region_info, &RNBRemote::HandlePacket_MemoryRegionInfo, NULL,
- "qMemoryRegionInfo", "Return size and attributes of a memory region that "
- "contains the given address"));
- 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(enable_compression,
- &RNBRemote::HandlePacket_QEnableCompression, NULL,
- "QEnableCompression:",
- "Enable compression for the remainder of the connection"));
- 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(set_detach_on_error, &RNBRemote::HandlePacket_QSetDetachOnError,
- NULL, "QSetDetachOnError:",
- "Set whether debugserver will detach (1) or kill (0) from the "
- "process it is controlling if it loses connection to lldb."));
- t.push_back(Packet(
- speed_test, &RNBRemote::HandlePacket_qSpeedTest, NULL, "qSpeedTest:",
- "Test the maximum speed at which packet can be sent/received."));
- t.push_back(Packet(query_transfer, &RNBRemote::HandlePacket_qXfer, NULL,
- "qXfer:", "Support the qXfer packet."));
- t.push_back(
- Packet(query_supported_async_json_packets,
- &RNBRemote::HandlePacket_qStructuredDataPlugins, NULL,
- "qStructuredDataPlugins",
- "Query for the structured data plugins supported by the remote."));
- t.push_back(
- Packet(configure_darwin_log, &RNBRemote::HandlePacket_QConfigureDarwinLog,
- NULL, "QConfigureDarwinLog:",
- "Configure the DarwinLog structured data plugin support."));
-}
-
-void RNBRemote::FlushSTDIO() {
- if (m_ctx.HasValidProcessID()) {
- nub_process_t pid = m_ctx.ProcessID();
- char buf[256];
- nub_size_t count;
- do {
- count = DNBProcessGetAvailableSTDOUT(pid, buf, sizeof(buf));
- if (count > 0) {
- SendSTDOUTPacket(buf, count);
- }
- } while (count > 0);
-
- do {
- count = DNBProcessGetAvailableSTDERR(pid, buf, sizeof(buf));
- if (count > 0) {
- SendSTDERRPacket(buf, count);
- }
- } while (count > 0);
- }
-}
-
-void RNBRemote::SendAsyncProfileData() {
- if (m_ctx.HasValidProcessID()) {
- nub_process_t pid = m_ctx.ProcessID();
- char buf[1024];
- nub_size_t count;
- do {
- count = DNBProcessGetAvailableProfileData(pid, buf, sizeof(buf));
- if (count > 0) {
- SendAsyncProfileDataPacket(buf, count);
- }
- } while (count > 0);
- }
-}
-
-void RNBRemote::SendAsyncDarwinLogData() {
- DNBLogThreadedIf(LOG_DARWIN_LOG, "RNBRemote::%s(): enter", __FUNCTION__);
-
- if (!m_ctx.HasValidProcessID()) {
- DNBLogThreadedIf(LOG_DARWIN_LOG, "RNBRemote::%s(): ignoring due to"
- "invalid process id",
- __FUNCTION__);
- return;
- }
-
- nub_process_t pid = m_ctx.ProcessID();
- DarwinLogEventVector::size_type entry_count = 0;
-
- // NOTE: the current looping structure here does nothing
- // to guarantee that we can send off async packets faster
- // than we generate them. It will keep sending as long
- // as there's data to send.
- do {
- DarwinLogEventVector events = DNBProcessGetAvailableDarwinLogEvents(pid);
- entry_count = events.size();
-
- DNBLogThreadedIf(LOG_DARWIN_LOG, "RNBRemote::%s(): outer loop enter",
- __FUNCTION__);
-
- for (DarwinLogEventVector::size_type base_entry = 0;
- base_entry < entry_count;
- base_entry += DARWIN_LOG_MAX_EVENTS_PER_PACKET) {
- DNBLogThreadedIf(LOG_DARWIN_LOG, "RNBRemote::%s(): inner loop enter",
- __FUNCTION__);
-
- // We limit the total number of entries we pack
- // into a single JSON async packet just so it
- // doesn't get too large.
- JSONGenerator::Dictionary async_dictionary;
-
- // Specify the type of the JSON async data we're sending.
- async_dictionary.AddStringItem(JSON_ASYNC_TYPE_KEY_NAME, "DarwinLog");
-
- // Create an array entry in the dictionary to hold all
- // the events going in this packet.
- JSONGenerator::ArraySP events_array(new JSONGenerator::Array());
- async_dictionary.AddItem(OS_LOG_EVENTS_KEY_NAME, events_array);
-
- // We bundle up to DARWIN_LOG_MAX_EVENTS_PER_PACKET events in
- // a single packet.
- const auto inner_loop_bound =
- std::min(base_entry + DARWIN_LOG_MAX_EVENTS_PER_PACKET, entry_count);
- for (DarwinLogEventVector::size_type i = base_entry; i < inner_loop_bound;
- ++i) {
- DNBLogThreadedIf(LOG_DARWIN_LOG, "RNBRemote::%s(): adding "
- "entry index %lu to the JSON packet",
- __FUNCTION__, i);
- events_array->AddItem(events[i]);
- }
-
- // Send off the packet.
- DNBLogThreadedIf(LOG_DARWIN_LOG, "RNBRemote::%s(): sending JSON "
- "packet, %lu entries remain",
- __FUNCTION__, entry_count - inner_loop_bound);
- SendAsyncJSONPacket(async_dictionary);
- }
-
- DNBLogThreadedIf(LOG_DARWIN_LOG, "RNBRemote::%s(): outer loop exit",
- __FUNCTION__);
-
- } while (entry_count > 0);
-
- DNBLogThreadedIf(LOG_DARWIN_LOG, "RNBRemote::%s(): exit",
- __PRETTY_FUNCTION__);
-}
-
-rnb_err_t RNBRemote::SendHexEncodedBytePacket(const char *header,
- const void *buf, size_t buf_len,
- const char *footer) {
- std::ostringstream packet_sstrm;
- // Append the header cstr if there was one
- if (header && header[0])
- packet_sstrm << header;
- nub_size_t i;
- const uint8_t *ubuf8 = (const uint8_t *)buf;
- for (i = 0; i < buf_len; i++) {
- packet_sstrm << RAWHEX8(ubuf8[i]);
- }
- // Append the footer cstr if there was one
- if (footer && footer[0])
- packet_sstrm << footer;
-
- return SendPacket(packet_sstrm.str());
-}
-
-rnb_err_t RNBRemote::SendSTDOUTPacket(char *buf, nub_size_t buf_size) {
- if (buf_size == 0)
- return rnb_success;
- return SendHexEncodedBytePacket("O", buf, buf_size, NULL);
-}
-
-rnb_err_t RNBRemote::SendSTDERRPacket(char *buf, nub_size_t buf_size) {
- if (buf_size == 0)
- return rnb_success;
- return SendHexEncodedBytePacket("O", buf, buf_size, NULL);
-}
-
-// This makes use of asynchronous bit 'A' in the gdb remote protocol.
-rnb_err_t RNBRemote::SendAsyncProfileDataPacket(char *buf,
- nub_size_t buf_size) {
- if (buf_size == 0)
- return rnb_success;
-
- std::string packet("A");
- packet.append(buf, buf_size);
- return SendPacket(packet);
-}
-
-rnb_err_t
-RNBRemote::SendAsyncJSONPacket(const JSONGenerator::Dictionary &dictionary) {
- std::ostringstream stream;
- // We're choosing something that is easy to spot if we somehow get one
- // of these coming out at the wrong time (i.e. when the remote side
- // is not waiting for a process control completion response).
- stream << "JSON-async:";
- dictionary.Dump(stream);
- const std::string payload = binary_encode_string(stream.str());
- return SendPacket(payload);
-}
-
-// Given a std::string packet contents to send, possibly encode/compress it.
-// If compression is enabled, the returned std::string will be in one of two
-// forms:
-//
-// N<original packet contents uncompressed>
-// C<size of original decompressed packet>:<packet compressed with the
-// requested compression scheme>
-//
-// If compression is not requested, the original packet contents are returned
-
-std::string RNBRemote::CompressString(const std::string &orig) {
- std::string compressed;
- compression_types compression_type = GetCompressionType();
- if (compression_type != compression_types::none) {
- bool compress_this_packet = false;
-
- if (orig.size() > m_compression_minsize) {
- compress_this_packet = true;
- }
-
- if (compress_this_packet) {
- const size_t encoded_data_buf_size = orig.size() + 128;
- std::vector<uint8_t> encoded_data(encoded_data_buf_size);
- size_t compressed_size = 0;
-
- // Allocate a scratch buffer for libcompression the first
- // time we see a different compression type; reuse it in
- // all compression_encode_buffer calls so it doesn't need
- // to allocate / free its own scratch buffer each time.
- // This buffer will only be freed when compression type
- // changes; otherwise it will persist until debugserver
- // exit.
-
- static compression_types g_libcompress_scratchbuf_type = compression_types::none;
- static void *g_libcompress_scratchbuf = nullptr;
-
- if (g_libcompress_scratchbuf_type != compression_type) {
- if (g_libcompress_scratchbuf) {
- free (g_libcompress_scratchbuf);
- g_libcompress_scratchbuf = nullptr;
- }
- size_t scratchbuf_size = 0;
- switch (compression_type) {
- case compression_types::lz4:
- scratchbuf_size = compression_encode_scratch_buffer_size (COMPRESSION_LZ4_RAW);
- break;
- case compression_types::zlib_deflate:
- scratchbuf_size = compression_encode_scratch_buffer_size (COMPRESSION_ZLIB);
- break;
- case compression_types::lzma:
- scratchbuf_size = compression_encode_scratch_buffer_size (COMPRESSION_LZMA);
- break;
- case compression_types::lzfse:
- scratchbuf_size = compression_encode_scratch_buffer_size (COMPRESSION_LZFSE);
- break;
- default:
- break;
- }
- if (scratchbuf_size > 0) {
- g_libcompress_scratchbuf = (void*) malloc (scratchbuf_size);
- g_libcompress_scratchbuf_type = compression_type;
- }
- }
-
- if (compression_type == compression_types::lz4) {
- compressed_size = compression_encode_buffer(
- encoded_data.data(), encoded_data_buf_size,
- (const uint8_t *)orig.c_str(), orig.size(),
- g_libcompress_scratchbuf,
- COMPRESSION_LZ4_RAW);
- }
- if (compression_type == compression_types::zlib_deflate) {
- compressed_size = compression_encode_buffer(
- encoded_data.data(), encoded_data_buf_size,
- (const uint8_t *)orig.c_str(), orig.size(),
- g_libcompress_scratchbuf,
- COMPRESSION_ZLIB);
- }
- if (compression_type == compression_types::lzma) {
- compressed_size = compression_encode_buffer(
- encoded_data.data(), encoded_data_buf_size,
- (const uint8_t *)orig.c_str(), orig.size(),
- g_libcompress_scratchbuf,
- COMPRESSION_LZMA);
- }
- if (compression_type == compression_types::lzfse) {
- compressed_size = compression_encode_buffer(
- encoded_data.data(), encoded_data_buf_size,
- (const uint8_t *)orig.c_str(), orig.size(),
- g_libcompress_scratchbuf,
- COMPRESSION_LZFSE);
- }
-
- if (compressed_size > 0) {
- compressed.clear();
- compressed.reserve(compressed_size);
- compressed = "C";
- char numbuf[16];
- snprintf(numbuf, sizeof(numbuf), "%zu:", orig.size());
- numbuf[sizeof(numbuf) - 1] = '\0';
- compressed.append(numbuf);
-
- for (size_t i = 0; i < compressed_size; i++) {
- uint8_t byte = encoded_data[i];
- if (byte == '#' || byte == '$' || byte == '}' || byte == '*' ||
- byte == '\0') {
- compressed.push_back(0x7d);
- compressed.push_back(byte ^ 0x20);
- } else {
- compressed.push_back(byte);
- }
- }
- } else {
- compressed = "N" + orig;
- }
- } else {
- compressed = "N" + orig;
- }
- } else {
- compressed = orig;
- }
-
- return compressed;
-}
-
-rnb_err_t RNBRemote::SendPacket(const std::string &s) {
- DNBLogThreadedIf(LOG_RNB_MAX, "%8d RNBRemote::%s (%s) called",
- (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true),
- __FUNCTION__, s.c_str());
-
- std::string s_compressed = CompressString(s);
-
- std::string sendpacket = "$" + s_compressed + "#";
- int cksum = 0;
- char hexbuf[5];
-
- if (m_noack_mode) {
- sendpacket += "00";
- } else {
- for (size_t i = 0; i != s_compressed.size(); ++i)
- cksum += s_compressed[i];
- snprintf(hexbuf, sizeof hexbuf, "%02x", cksum & 0xff);
- sendpacket += hexbuf;
- }
-
- rnb_err_t err = m_comm.Write(sendpacket.c_str(), sendpacket.size());
- if (err != rnb_success)
- return err;
-
- if (m_noack_mode)
- return rnb_success;
-
- std::string reply;
- RNBRemote::Packet packet;
- err = GetPacket(reply, packet, true);
-
- if (err != rnb_success) {
- DNBLogThreadedIf(LOG_RNB_REMOTE,
- "%8d RNBRemote::%s (%s) got error trying to get reply...",
- (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true),
- __FUNCTION__, sendpacket.c_str());
- return err;
- }
-
- DNBLogThreadedIf(LOG_RNB_MAX, "%8d RNBRemote::%s (%s) got reply: '%s'",
- (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true),
- __FUNCTION__, sendpacket.c_str(), reply.c_str());
-
- if (packet.type == ack)
- return rnb_success;
-
- // Should we try to resend the packet at this layer?
- // if (packet.command == nack)
- return rnb_err;
-}
-
-/* Get a packet via gdb remote protocol.
- Strip off the prefix/suffix, verify the checksum to make sure
- a valid packet was received, send an ACK if they match. */
-
-rnb_err_t RNBRemote::GetPacketPayload(std::string &return_packet) {
- // DNBLogThreadedIf (LOG_RNB_MAX, "%8u RNBRemote::%s called",
- // (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
-
- PThreadMutex::Locker locker(m_mutex);
- if (m_rx_packets.empty()) {
- // Only reset the remote command available event if we have no more packets
- m_ctx.Events().ResetEvents(RNBContext::event_read_packet_available);
- // DNBLogThreadedIf (LOG_RNB_MAX, "%8u RNBRemote::%s error: no packets
- // available...", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true),
- // __FUNCTION__);
- return rnb_err;
- }
-
- // DNBLogThreadedIf (LOG_RNB_MAX, "%8u RNBRemote::%s has %u queued packets",
- // (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__,
- // m_rx_packets.size());
- return_packet.swap(m_rx_packets.front());
- m_rx_packets.pop_front();
- locker.Reset(); // Release our lock on the mutex
-
- if (m_rx_packets.empty()) {
- // Reset the remote command available event if we have no more packets
- m_ctx.Events().ResetEvents(RNBContext::event_read_packet_available);
- }
-
- // DNBLogThreadedIf (LOG_RNB_MEDIUM, "%8u RNBRemote::%s: '%s'",
- // (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__,
- // return_packet.c_str());
-
- switch (return_packet[0]) {
- case '+':
- case '-':
- case '\x03':
- break;
-
- case '$': {
- long packet_checksum = 0;
- if (!m_noack_mode) {
- for (size_t i = return_packet.size() - 2; i < return_packet.size(); ++i) {
- char checksum_char = tolower(return_packet[i]);
- if (!isxdigit(checksum_char)) {
- m_comm.Write("-", 1);
- DNBLogThreadedIf(LOG_RNB_REMOTE, "%8u RNBRemote::%s error: packet "
- "with invalid checksum characters: "
- "%s",
- (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true),
- __FUNCTION__, return_packet.c_str());
- return rnb_err;
- }
- }
- packet_checksum =
- strtol(&return_packet[return_packet.size() - 2], NULL, 16);
- }
-
- return_packet.erase(0, 1); // Strip the leading '$'
- return_packet.erase(return_packet.size() - 3); // Strip the #XX checksum
-
- if (!m_noack_mode) {
- // Compute the checksum
- int computed_checksum = 0;
- for (std::string::iterator it = return_packet.begin();
- it != return_packet.end(); ++it) {
- computed_checksum += *it;
- }
-
- if (packet_checksum == (computed_checksum & 0xff)) {
- // DNBLogThreadedIf (LOG_RNB_MEDIUM, "%8u RNBRemote::%s sending ACK for
- // '%s'", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true),
- // __FUNCTION__, return_packet.c_str());
- m_comm.Write("+", 1);
- } else {
- DNBLogThreadedIf(
- LOG_RNB_MEDIUM, "%8u RNBRemote::%s sending ACK for '%s' (error: "
- "packet checksum mismatch (0x%2.2lx != 0x%2.2x))",
- (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__,
- return_packet.c_str(), packet_checksum, computed_checksum);
- m_comm.Write("-", 1);
- return rnb_err;
- }
- }
- } break;
-
- default:
- DNBLogThreadedIf(LOG_RNB_REMOTE,
- "%8u RNBRemote::%s tossing unexpected packet???? %s",
- (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true),
- __FUNCTION__, return_packet.c_str());
- if (!m_noack_mode)
- m_comm.Write("-", 1);
- return rnb_err;
- }
-
- return rnb_success;
-}
-
-rnb_err_t RNBRemote::HandlePacket_UNIMPLEMENTED(const char *p) {
- DNBLogThreadedIf(LOG_RNB_MAX, "%8u RNBRemote::%s(\"%s\")",
- (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true),
- __FUNCTION__, p ? p : "NULL");
- return SendPacket("");
-}
-
-rnb_err_t RNBRemote::HandlePacket_ILLFORMED(const char *file, int line,
- const char *p,
- const char *description) {
- DNBLogThreadedIf(LOG_RNB_PACKETS, "%8u %s:%i ILLFORMED: '%s' (%s)",
- (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), file,
- line, __FUNCTION__, p);
- return SendPacket("E03");
-}
-
-rnb_err_t RNBRemote::GetPacket(std::string &packet_payload,
- RNBRemote::Packet &packet_info, bool wait) {
- std::string payload;
- rnb_err_t err = GetPacketPayload(payload);
- if (err != rnb_success) {
- PThreadEvent &events = m_ctx.Events();
- nub_event_t set_events = events.GetEventBits();
- // TODO: add timeout version of GetPacket?? We would then need to pass
- // that timeout value along to DNBProcessTimedWaitForEvent.
- if (!wait || ((set_events & RNBContext::event_read_thread_running) == 0))
- return err;
-
- const nub_event_t events_to_wait_for =
- RNBContext::event_read_packet_available |
- RNBContext::event_read_thread_exiting;
-
- while ((set_events = events.WaitForSetEvents(events_to_wait_for)) != 0) {
- if (set_events & RNBContext::event_read_packet_available) {
- // Try the queue again now that we got an event
- err = GetPacketPayload(payload);
- if (err == rnb_success)
- break;
- }
-
- if (set_events & RNBContext::event_read_thread_exiting)
- err = rnb_not_connected;
-
- if (err == rnb_not_connected)
- return err;
- }
- while (err == rnb_err)
- ;
-
- if (set_events == 0)
- err = rnb_not_connected;
- }
-
- if (err == rnb_success) {
- Packet::iterator it;
- for (it = m_packets.begin(); it != m_packets.end(); ++it) {
- if (payload.compare(0, it->abbrev.size(), it->abbrev) == 0)
- break;
- }
-
- // A packet we don't have an entry for. This can happen when we
- // get a packet that we don't know about or support. We just reply
- // accordingly and go on.
- if (it == m_packets.end()) {
- DNBLogThreadedIf(LOG_RNB_PACKETS, "unimplemented packet: '%s'",
- payload.c_str());
- HandlePacket_UNIMPLEMENTED(payload.c_str());
- return rnb_err;
- } else {
- packet_info = *it;
- packet_payload = payload;
- }
- }
- return err;
-}
-
-rnb_err_t RNBRemote::HandleAsyncPacket(PacketEnum *type) {
- DNBLogThreadedIf(LOG_RNB_REMOTE, "%8u RNBRemote::%s",
- (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true),
- __FUNCTION__);
- static DNBTimer g_packetTimer(true);
- rnb_err_t err = rnb_err;
- std::string packet_data;
- RNBRemote::Packet packet_info;
- err = GetPacket(packet_data, packet_info, false);
-
- if (err == rnb_success) {
- if (!packet_data.empty() && isprint(packet_data[0]))
- DNBLogThreadedIf(LOG_RNB_REMOTE | LOG_RNB_PACKETS,
- "HandleAsyncPacket (\"%s\");", packet_data.c_str());
- else
- DNBLogThreadedIf(LOG_RNB_REMOTE | LOG_RNB_PACKETS,
- "HandleAsyncPacket (%s);",
- packet_info.printable_name.c_str());
-
- HandlePacketCallback packet_callback = packet_info.async;
- if (packet_callback != NULL) {
- if (type != NULL)
- *type = packet_info.type;
- return (this->*packet_callback)(packet_data.c_str());
- }
- }
-
- return err;
-}
-
-rnb_err_t RNBRemote::HandleReceivedPacket(PacketEnum *type) {
- static DNBTimer g_packetTimer(true);
-
- // DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s",
- // (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
- rnb_err_t err = rnb_err;
- std::string packet_data;
- RNBRemote::Packet packet_info;
- err = GetPacket(packet_data, packet_info, false);
-
- if (err == rnb_success) {
- DNBLogThreadedIf(LOG_RNB_REMOTE, "HandleReceivedPacket (\"%s\");",
- packet_data.c_str());
- HandlePacketCallback packet_callback = packet_info.normal;
- if (packet_callback != NULL) {
- if (type != NULL)
- *type = packet_info.type;
- return (this->*packet_callback)(packet_data.c_str());
- } else {
- // Do not fall through to end of this function, if we have valid
- // packet_info and it has a NULL callback, then we need to respect
- // that it may not want any response or anything to be done.
- return err;
- }
- }
- return rnb_err;
-}
-
-void RNBRemote::CommDataReceived(const std::string &new_data) {
- // DNBLogThreadedIf (LOG_RNB_REMOTE, "%8d RNBRemote::%s called",
- // (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
- {
- // Put the packet data into the buffer in a thread safe fashion
- PThreadMutex::Locker locker(m_mutex);
-
- std::string data;
- // See if we have any left over data from a previous call to this
- // function?
- if (!m_rx_partial_data.empty()) {
- // We do, so lets start with that data
- data.swap(m_rx_partial_data);
- }
- // Append the new incoming data
- data += new_data;
-
- // Parse up the packets into gdb remote packets
- size_t idx = 0;
- const size_t data_size = data.size();
-
- while (idx < data_size) {
- // end_idx must be one past the last valid packet byte. Start
- // it off with an invalid value that is the same as the current
- // index.
- size_t end_idx = idx;
-
- switch (data[idx]) {
- case '+': // Look for ack
- case '-': // Look for cancel
- case '\x03': // ^C to halt target
- end_idx = idx + 1; // The command is one byte long...
- break;
-
- case '$':
- // Look for a standard gdb packet?
- end_idx = data.find('#', idx + 1);
- if (end_idx == std::string::npos || end_idx + 3 > data_size) {
- end_idx = std::string::npos;
- } else {
- // Add two for the checksum bytes and 1 to point to the
- // byte just past the end of this packet
- end_idx += 3;
- }
- break;
-
- default:
- break;
- }
-
- if (end_idx == std::string::npos) {
- // Not all data may be here for the packet yet, save it for
- // next time through this function.
- m_rx_partial_data += data.substr(idx);
- // DNBLogThreadedIf (LOG_RNB_MAX, "%8d RNBRemote::%s saving data for
- // later[%u, npos):
- // '%s'",(uint32_t)m_comm.Timer().ElapsedMicroSeconds(true),
- // __FUNCTION__, idx, m_rx_partial_data.c_str());
- idx = end_idx;
- } else if (idx < end_idx) {
- m_packets_recvd++;
- // Hack to get rid of initial '+' ACK???
- if (m_packets_recvd == 1 && (end_idx == idx + 1) && data[idx] == '+') {
- // DNBLogThreadedIf (LOG_RNB_REMOTE, "%8d RNBRemote::%s throwing first
- // ACK away....[%u, npos):
- // '+'",(uint32_t)m_comm.Timer().ElapsedMicroSeconds(true),
- // __FUNCTION__, idx);
- } else {
- // We have a valid packet...
- m_rx_packets.push_back(data.substr(idx, end_idx - idx));
- DNBLogThreadedIf(LOG_RNB_PACKETS, "getpkt: %s",
- m_rx_packets.back().c_str());
- }
- idx = end_idx;
- } else {
- DNBLogThreadedIf(LOG_RNB_MAX,
- "%8d RNBRemote::%s tossing junk byte at %c",
- (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true),
- __FUNCTION__, data[idx]);
- idx = idx + 1;
- }
- }
- }
-
- if (!m_rx_packets.empty()) {
- // Let the main thread know we have received a packet
-
- // DNBLogThreadedIf (LOG_RNB_EVENTS, "%8d RNBRemote::%s called
- // events.SetEvent(RNBContext::event_read_packet_available)",
- // (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
- PThreadEvent &events = m_ctx.Events();
- events.SetEvents(RNBContext::event_read_packet_available);
- }
-}
-
-rnb_err_t RNBRemote::GetCommData() {
- // DNBLogThreadedIf (LOG_RNB_REMOTE, "%8d RNBRemote::%s called",
- // (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
- std::string comm_data;
- rnb_err_t err = m_comm.Read(comm_data);
- if (err == rnb_success) {
- if (!comm_data.empty())
- CommDataReceived(comm_data);
- }
- return err;
-}
-
-void RNBRemote::StartReadRemoteDataThread() {
- DNBLogThreadedIf(LOG_RNB_REMOTE, "%8u RNBRemote::%s called",
- (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true),
- __FUNCTION__);
- PThreadEvent &events = m_ctx.Events();
- if ((events.GetEventBits() & RNBContext::event_read_thread_running) == 0) {
- events.ResetEvents(RNBContext::event_read_thread_exiting);
- int err = ::pthread_create(&m_rx_pthread, NULL,
- ThreadFunctionReadRemoteData, this);
- if (err == 0) {
- // Our thread was successfully kicked off, wait for it to
- // set the started event so we can safely continue
- events.WaitForSetEvents(RNBContext::event_read_thread_running);
- } else {
- events.ResetEvents(RNBContext::event_read_thread_running);
- events.SetEvents(RNBContext::event_read_thread_exiting);
- }
- }
-}
-
-void RNBRemote::StopReadRemoteDataThread() {
- DNBLogThreadedIf(LOG_RNB_REMOTE, "%8u RNBRemote::%s called",
- (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true),
- __FUNCTION__);
- PThreadEvent &events = m_ctx.Events();
- if ((events.GetEventBits() & RNBContext::event_read_thread_running) ==
- RNBContext::event_read_thread_running) {
- m_comm.Disconnect(true);
- struct timespec timeout_abstime;
- DNBTimer::OffsetTimeOfDay(&timeout_abstime, 2, 0);
-
- // Wait for 2 seconds for the remote data thread to exit
- if (events.WaitForSetEvents(RNBContext::event_read_thread_exiting,
- &timeout_abstime) == 0) {
- // Kill the remote data thread???
- }
- }
-}
-
-void *RNBRemote::ThreadFunctionReadRemoteData(void *arg) {
- // Keep a shared pointer reference so this doesn't go away on us before the
- // thread is killed.
- DNBLogThreadedIf(LOG_RNB_REMOTE, "RNBRemote::%s (%p): thread starting...",
- __FUNCTION__, arg);
- RNBRemoteSP remoteSP(g_remoteSP);
- if (remoteSP.get() != NULL) {
-
-#if defined(__APPLE__)
- pthread_setname_np("read gdb-remote packets thread");
-#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
- struct sched_param thread_param;
- int thread_sched_policy;
- if (pthread_getschedparam(pthread_self(), &thread_sched_policy,
- &thread_param) == 0) {
- thread_param.sched_priority = 47;
- pthread_setschedparam(pthread_self(), thread_sched_policy, &thread_param);
- }
-#endif
-#endif
-
- RNBRemote *remote = remoteSP.get();
- PThreadEvent &events = remote->Context().Events();
- events.SetEvents(RNBContext::event_read_thread_running);
- // START: main receive remote command thread loop
- bool done = false;
- while (!done) {
- rnb_err_t err = remote->GetCommData();
-
- switch (err) {
- case rnb_success:
- break;
-
- case rnb_err:
- DNBLogThreadedIf(LOG_RNB_REMOTE,
- "RNBSocket::GetCommData returned error %u", err);
- done = true;
- break;
-
- case rnb_not_connected:
- DNBLogThreadedIf(LOG_RNB_REMOTE,
- "RNBSocket::GetCommData returned not connected...");
- done = true;
- break;
- }
- }
- // START: main receive remote command thread loop
- events.ResetEvents(RNBContext::event_read_thread_running);
- events.SetEvents(RNBContext::event_read_thread_exiting);
- }
- DNBLogThreadedIf(LOG_RNB_REMOTE, "RNBRemote::%s (%p): thread exiting...",
- __FUNCTION__, arg);
- return NULL;
-}
-
-// If we fail to get back a valid CPU type for the remote process,
-// make a best guess for the CPU type based on the currently running
-// debugserver binary -- the debugger may not handle the case of an
-// un-specified process CPU type correctly.
-
-static cpu_type_t best_guess_cpu_type() {
-#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
- if (sizeof(char *) == 8) {
- return CPU_TYPE_ARM64;
- } else {
- return CPU_TYPE_ARM;
- }
-#elif defined(__i386__) || defined(__x86_64__)
- if (sizeof(char *) == 8) {
- return CPU_TYPE_X86_64;
- } else {
- return CPU_TYPE_I386;
- }
-#endif
- return 0;
-}
-
-/* Read the bytes in STR which are GDB Remote Protocol binary encoded bytes
- (8-bit bytes).
- This encoding uses 0x7d ('}') as an escape character for
- 0x7d ('}'), 0x23 ('#'), 0x24 ('$'), 0x2a ('*').
- LEN is the number of bytes to be processed. If a character is escaped,
- it is 2 characters for LEN. A LEN of -1 means decode-until-nul-byte
- (end of string). */
-
-std::vector<uint8_t> decode_binary_data(const char *str, size_t len) {
- std::vector<uint8_t> bytes;
- if (len == 0) {
- return bytes;
- }
- if (len == (size_t)-1)
- len = strlen(str);
-
- while (len--) {
- unsigned char c = *str++;
- if (c == 0x7d && len > 0) {
- len--;
- c = *str++ ^ 0x20;
- }
- bytes.push_back(c);
- }
- return bytes;
-}
-
-// Quote any meta characters in a std::string as per the binary
-// packet convention in the gdb-remote protocol.
-
-static std::string binary_encode_string(const std::string &s) {
- std::string output;
- const size_t s_size = s.size();
- const char *s_chars = s.c_str();
-
- for (size_t i = 0; i < s_size; i++) {
- unsigned char ch = *(s_chars + i);
- if (ch == '#' || ch == '$' || ch == '}' || ch == '*') {
- output.push_back('}'); // 0x7d
- output.push_back(ch ^ 0x20);
- } else {
- output.push_back(ch);
- }
- }
- return output;
-}
-
-// If the value side of a key-value pair in JSON is a string,
-// and that string has a " character in it, the " character must
-// be escaped.
-
-std::string json_string_quote_metachars(const std::string &s) {
- if (s.find('"') == std::string::npos)
- return s;
-
- std::string output;
- const size_t s_size = s.size();
- const char *s_chars = s.c_str();
- for (size_t i = 0; i < s_size; i++) {
- unsigned char ch = *(s_chars + i);
- if (ch == '"') {
- output.push_back('\\');
- }
- output.push_back(ch);
- }
- return output;
-}
-
-typedef struct register_map_entry {
- uint32_t debugserver_regnum; // debugserver register number
- uint32_t offset; // Offset in bytes into the register context data with no
- // padding between register values
- DNBRegisterInfo nub_info; // debugnub register info
- std::vector<uint32_t> value_regnums;
- std::vector<uint32_t> invalidate_regnums;
-} register_map_entry_t;
-
-// If the notion of registers differs from what is handed out by the
-// architecture, then flavors can be defined here.
-
-static std::vector<register_map_entry_t> g_dynamic_register_map;
-static register_map_entry_t *g_reg_entries = NULL;
-static size_t g_num_reg_entries = 0;
-
-void RNBRemote::Initialize() { DNBInitialize(); }
-
-bool RNBRemote::InitializeRegisters(bool force) {
- pid_t pid = m_ctx.ProcessID();
- if (pid == INVALID_NUB_PROCESS)
- return false;
-
- DNBLogThreadedIf(
- LOG_RNB_PROC,
- "RNBRemote::%s() getting native registers from DNB interface",
- __FUNCTION__);
- // Discover the registers by querying the DNB interface and letting it
- // state the registers that it would like to export. This allows the
- // registers to be discovered using multiple qRegisterInfo calls to get
- // all register information after the architecture for the process is
- // determined.
- if (force) {
- g_dynamic_register_map.clear();
- g_reg_entries = NULL;
- g_num_reg_entries = 0;
- }
-
- if (g_dynamic_register_map.empty()) {
- nub_size_t num_reg_sets = 0;
- const DNBRegisterSetInfo *reg_sets = DNBGetRegisterSetInfo(&num_reg_sets);
-
- assert(num_reg_sets > 0 && reg_sets != NULL);
-
- uint32_t regnum = 0;
- uint32_t reg_data_offset = 0;
- typedef std::map<std::string, uint32_t> NameToRegNum;
- NameToRegNum name_to_regnum;
- for (nub_size_t set = 0; set < num_reg_sets; ++set) {
- if (reg_sets[set].registers == NULL)
- continue;
-
- for (uint32_t reg = 0; reg < reg_sets[set].num_registers; ++reg) {
- register_map_entry_t reg_entry = {
- regnum++, // register number starts at zero and goes up with no gaps
- reg_data_offset, // Offset into register context data, no gaps
- // between registers
- reg_sets[set].registers[reg], // DNBRegisterInfo
- {},
- {},
- };
-
- name_to_regnum[reg_entry.nub_info.name] = reg_entry.debugserver_regnum;
-
- if (reg_entry.nub_info.value_regs == NULL) {
- reg_data_offset += reg_entry.nub_info.size;
- }
-
- g_dynamic_register_map.push_back(reg_entry);
- }
- }
-
- // Now we must find any registers whose values are in other registers and
- // fix up
- // the offsets since we removed all gaps...
- for (auto &reg_entry : g_dynamic_register_map) {
- if (reg_entry.nub_info.value_regs) {
- uint32_t new_offset = UINT32_MAX;
- for (size_t i = 0; reg_entry.nub_info.value_regs[i] != NULL; ++i) {
- const char *name = reg_entry.nub_info.value_regs[i];
- auto pos = name_to_regnum.find(name);
- if (pos != name_to_regnum.end()) {
- regnum = pos->second;
- reg_entry.value_regnums.push_back(regnum);
- if (regnum < g_dynamic_register_map.size()) {
- // The offset for value_regs registers is the offset within the
- // register with the lowest offset
- const uint32_t reg_offset =
- g_dynamic_register_map[regnum].offset +
- reg_entry.nub_info.offset;
- if (new_offset > reg_offset)
- new_offset = reg_offset;
- }
- }
- }
-
- if (new_offset != UINT32_MAX) {
- reg_entry.offset = new_offset;
- } else {
- DNBLogThreaded("no offset was calculated entry for register %s",
- reg_entry.nub_info.name);
- reg_entry.offset = UINT32_MAX;
- }
- }
-
- if (reg_entry.nub_info.update_regs) {
- for (size_t i = 0; reg_entry.nub_info.update_regs[i] != NULL; ++i) {
- const char *name = reg_entry.nub_info.update_regs[i];
- auto pos = name_to_regnum.find(name);
- if (pos != name_to_regnum.end()) {
- regnum = pos->second;
- reg_entry.invalidate_regnums.push_back(regnum);
- }
- }
- }
- }
-
- // for (auto &reg_entry: g_dynamic_register_map)
- // {
- // DNBLogThreaded("%4i: size = %3u, pseudo = %i, name = %s",
- // reg_entry.offset,
- // reg_entry.nub_info.size,
- // reg_entry.nub_info.value_regs != NULL,
- // reg_entry.nub_info.name);
- // }
-
- g_reg_entries = g_dynamic_register_map.data();
- g_num_reg_entries = g_dynamic_register_map.size();
- }
- return true;
-}
-
-/* The inferior has stopped executing; send a packet
- to gdb to let it know. */
-
-void RNBRemote::NotifyThatProcessStopped(void) {
- RNBRemote::HandlePacket_last_signal(NULL);
- return;
-}
-
-/* 'A arglen,argnum,arg,...'
- Update the inferior context CTX with the program name and arg
- list.
- The documentation for this packet is underwhelming but my best reading
- of this is that it is a series of (len, position #, arg)'s, one for
- each argument with "arg" hex encoded (two 0-9a-f chars?).
- Why we need BOTH a "len" and a hex encoded "arg" is beyond me - either
- is sufficient to get around the "," position separator escape issue.
-
- e.g. our best guess for a valid 'A' packet for "gdb -q a.out" is
-
- 6,0,676462,4,1,2d71,10,2,612e6f7574
-
- Note that "argnum" and "arglen" are numbers in base 10. Again, that's
- not documented either way but I'm assuming it's so. */
-
-rnb_err_t RNBRemote::HandlePacket_A(const char *p) {
- if (p == NULL || *p == '\0') {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "Null packet for 'A' pkt");
- }
- p++;
- if (*p == '\0' || !isdigit(*p)) {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "arglen not specified on 'A' pkt");
- }
-
- /* I promise I don't modify it anywhere in this function. strtoul()'s
- 2nd arg has to be non-const which makes it problematic to step
- through the string easily. */
- char *buf = const_cast<char *>(p);
-
- RNBContext &ctx = Context();
-
- while (*buf != '\0') {
- unsigned long arglen, argnum;
- std::string arg;
- char *c;
-
- errno = 0;
- arglen = strtoul(buf, &c, 10);
- if (errno != 0 && arglen == 0) {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "arglen not a number on 'A' pkt");
- }
- if (*c != ',') {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "arglen not followed by comma on 'A' pkt");
- }
- buf = c + 1;
-
- errno = 0;
- argnum = strtoul(buf, &c, 10);
- if (errno != 0 && argnum == 0) {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "argnum not a number on 'A' pkt");
- }
- if (*c != ',') {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "arglen not followed by comma on 'A' pkt");
- }
- buf = c + 1;
-
- c = buf;
- buf = buf + arglen;
- while (c < buf && *c != '\0' && c + 1 < buf && *(c + 1) != '\0') {
- char smallbuf[3];
- smallbuf[0] = *c;
- smallbuf[1] = *(c + 1);
- smallbuf[2] = '\0';
-
- errno = 0;
- int ch = static_cast<int>(strtoul(smallbuf, NULL, 16));
- if (errno != 0 && ch == 0) {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "non-hex char in arg on 'A' pkt");
- }
-
- arg.push_back(ch);
- c += 2;
- }
-
- ctx.PushArgument(arg.c_str());
- if (*buf == ',')
- buf++;
- }
- SendPacket("OK");
-
- return rnb_success;
-}
-
-/* 'H c t'
- Set the thread for subsequent actions; 'c' for step/continue ops,
- 'g' for other ops. -1 means all threads, 0 means any thread. */
-
-rnb_err_t RNBRemote::HandlePacket_H(const char *p) {
- p++; // skip 'H'
- if (*p != 'c' && *p != 'g') {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "Missing 'c' or 'g' type in H packet");
- }
-
- if (!m_ctx.HasValidProcessID()) {
- // We allow gdb to connect to a server that hasn't started running
- // the target yet. gdb still wants to ask questions about it and
- // freaks out if it gets an error. So just return OK here.
- }
-
- errno = 0;
- nub_thread_t tid = strtoul(p + 1, NULL, 16);
- if (errno != 0 && tid == 0) {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "Invalid thread number in H packet");
- }
- if (*p == 'c')
- SetContinueThread(tid);
- if (*p == 'g')
- SetCurrentThread(tid);
-
- return SendPacket("OK");
-}
-
-rnb_err_t RNBRemote::HandlePacket_qLaunchSuccess(const char *p) {
- if (m_ctx.HasValidProcessID() || m_ctx.LaunchStatus().Status() == 0)
- return SendPacket("OK");
- std::ostringstream ret_str;
- std::string status_str;
- ret_str << "E" << m_ctx.LaunchStatusAsString(status_str);
-
- return SendPacket(ret_str.str());
-}
-
-rnb_err_t RNBRemote::HandlePacket_qShlibInfoAddr(const char *p) {
- if (m_ctx.HasValidProcessID()) {
- nub_addr_t shlib_info_addr =
- DNBProcessGetSharedLibraryInfoAddress(m_ctx.ProcessID());
- if (shlib_info_addr != INVALID_NUB_ADDRESS) {
- std::ostringstream ostrm;
- ostrm << RAW_HEXBASE << shlib_info_addr;
- return SendPacket(ostrm.str());
- }
- }
- return SendPacket("E44");
-}
-
-rnb_err_t RNBRemote::HandlePacket_qStepPacketSupported(const char *p) {
- // Normally the "s" packet is mandatory, yet in gdb when using ARM, they
- // get around the need for this packet by implementing software single
- // stepping from gdb. Current versions of debugserver do support the "s"
- // packet, yet some older versions do not. We need a way to tell if this
- // packet is supported so we can disable software single stepping in gdb
- // for remote targets (so the "s" packet will get used).
- return SendPacket("OK");
-}
-
-rnb_err_t RNBRemote::HandlePacket_qSyncThreadStateSupported(const char *p) {
- // We support attachOrWait meaning attach if the process exists, otherwise
- // wait to attach.
- return SendPacket("OK");
-}
-
-rnb_err_t RNBRemote::HandlePacket_qVAttachOrWaitSupported(const char *p) {
- // We support attachOrWait meaning attach if the process exists, otherwise
- // wait to attach.
- return SendPacket("OK");
-}
-
-rnb_err_t RNBRemote::HandlePacket_qThreadStopInfo(const char *p) {
- p += strlen("qThreadStopInfo");
- nub_thread_t tid = strtoul(p, 0, 16);
- return SendStopReplyPacketForThread(tid);
-}
-
-rnb_err_t RNBRemote::HandlePacket_qThreadInfo(const char *p) {
- // We allow gdb to connect to a server that hasn't started running
- // the target yet. gdb still wants to ask questions about it and
- // freaks out if it gets an error. So just return OK here.
- nub_process_t pid = m_ctx.ProcessID();
- if (pid == INVALID_NUB_PROCESS)
- return SendPacket("OK");
-
- // Only "qfThreadInfo" and "qsThreadInfo" get into this function so
- // we only need to check the second byte to tell which is which
- if (p[1] == 'f') {
- nub_size_t numthreads = DNBProcessGetNumThreads(pid);
- std::ostringstream ostrm;
- ostrm << "m";
- bool first = true;
- for (nub_size_t i = 0; i < numthreads; ++i) {
- if (first)
- first = false;
- else
- ostrm << ",";
- nub_thread_t th = DNBProcessGetThreadAtIndex(pid, i);
- ostrm << std::hex << th;
- }
- return SendPacket(ostrm.str());
- } else {
- return SendPacket("l");
- }
-}
-
-rnb_err_t RNBRemote::HandlePacket_qThreadExtraInfo(const char *p) {
- // We allow gdb to connect to a server that hasn't started running
- // the target yet. gdb still wants to ask questions about it and
- // freaks out if it gets an error. So just return OK here.
- nub_process_t pid = m_ctx.ProcessID();
- if (pid == INVALID_NUB_PROCESS)
- return SendPacket("OK");
-
- /* This is supposed to return a string like 'Runnable' or
- 'Blocked on Mutex'.
- The returned string is formatted like the "A" packet - a
- sequence of letters encoded in as 2-hex-chars-per-letter. */
- p += strlen("qThreadExtraInfo");
- if (*p++ != ',')
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "Illformed qThreadExtraInfo packet");
- errno = 0;
- nub_thread_t tid = strtoul(p, NULL, 16);
- if (errno != 0 && tid == 0) {
- return HandlePacket_ILLFORMED(
- __FILE__, __LINE__, p,
- "Invalid thread number in qThreadExtraInfo packet");
- }
-
- const char *threadInfo = DNBThreadGetInfo(pid, tid);
- if (threadInfo != NULL && threadInfo[0]) {
- return SendHexEncodedBytePacket(NULL, threadInfo, strlen(threadInfo), NULL);
- } else {
- // "OK" == 4f6b
- // Return "OK" as a ASCII hex byte stream if things go wrong
- return SendPacket("4f6b");
- }
-
- return SendPacket("");
-}
-
-const char *k_space_delimiters = " \t";
-static void skip_spaces(std::string &line) {
- if (!line.empty()) {
- size_t space_pos = line.find_first_not_of(k_space_delimiters);
- if (space_pos > 0)
- line.erase(0, space_pos);
- }
-}
-
-static std::string get_identifier(std::string &line) {
- std::string word;
- skip_spaces(line);
- const size_t line_size = line.size();
- size_t end_pos;
- for (end_pos = 0; end_pos < line_size; ++end_pos) {
- if (end_pos == 0) {
- if (isalpha(line[end_pos]) || line[end_pos] == '_')
- continue;
- } else if (isalnum(line[end_pos]) || line[end_pos] == '_')
- continue;
- break;
- }
- word.assign(line, 0, end_pos);
- line.erase(0, end_pos);
- return word;
-}
-
-static std::string get_operator(std::string &line) {
- std::string op;
- skip_spaces(line);
- if (!line.empty()) {
- if (line[0] == '=') {
- op = '=';
- line.erase(0, 1);
- }
- }
- return op;
-}
-
-static std::string get_value(std::string &line) {
- std::string value;
- skip_spaces(line);
- if (!line.empty()) {
- value.swap(line);
- }
- return value;
-}
-
-extern void FileLogCallback(void *baton, uint32_t flags, const char *format,
- va_list args);
-extern void ASLLogCallback(void *baton, uint32_t flags, const char *format,
- va_list args);
-
-rnb_err_t RNBRemote::HandlePacket_qRcmd(const char *p) {
- const char *c = p + strlen("qRcmd,");
- std::string line;
- while (c[0] && c[1]) {
- char smallbuf[3] = {c[0], c[1], '\0'};
- errno = 0;
- int ch = static_cast<int>(strtoul(smallbuf, NULL, 16));
- if (errno != 0 && ch == 0)
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "non-hex char in payload of qRcmd packet");
- line.push_back(ch);
- c += 2;
- }
- if (*c == '\0') {
- std::string command = get_identifier(line);
- if (command == "set") {
- std::string variable = get_identifier(line);
- std::string op = get_operator(line);
- std::string value = get_value(line);
- if (variable == "logfile") {
- FILE *log_file = fopen(value.c_str(), "w");
- if (log_file) {
- DNBLogSetLogCallback(FileLogCallback, log_file);
- return SendPacket("OK");
- }
- return SendPacket("E71");
- } else if (variable == "logmask") {
- char *end;
- errno = 0;
- uint32_t logmask =
- static_cast<uint32_t>(strtoul(value.c_str(), &end, 0));
- if (errno == 0 && end && *end == '\0') {
- DNBLogSetLogMask(logmask);
- if (!DNBLogGetLogCallback())
- DNBLogSetLogCallback(ASLLogCallback, NULL);
- return SendPacket("OK");
- }
- errno = 0;
- logmask = static_cast<uint32_t>(strtoul(value.c_str(), &end, 16));
- if (errno == 0 && end && *end == '\0') {
- DNBLogSetLogMask(logmask);
- return SendPacket("OK");
- }
- return SendPacket("E72");
- }
- return SendPacket("E70");
- }
- return SendPacket("E69");
- }
- return SendPacket("E73");
-}
-
-rnb_err_t RNBRemote::HandlePacket_qC(const char *p) {
- nub_thread_t tid;
- std::ostringstream rep;
- // If we haven't run the process yet, we tell the debugger the
- // pid is 0. That way it can know to tell use to run later on.
- if (!m_ctx.HasValidProcessID())
- tid = 0;
- else {
- // Grab the current thread.
- tid = DNBProcessGetCurrentThread(m_ctx.ProcessID());
- // Make sure we set the current thread so g and p packets return
- // the data the gdb will expect.
- SetCurrentThread(tid);
- }
- rep << "QC" << std::hex << tid;
- return SendPacket(rep.str());
-}
-
-rnb_err_t RNBRemote::HandlePacket_qEcho(const char *p) {
- // Just send the exact same packet back that we received to
- // synchronize the response packets after a previous packet
- // timed out. This allows the debugger to get back on track
- // with responses after a packet timeout.
- return SendPacket(p);
-}
-
-rnb_err_t RNBRemote::HandlePacket_qGetPid(const char *p) {
- nub_process_t pid;
- std::ostringstream rep;
- // If we haven't run the process yet, we tell the debugger the
- // pid is 0. That way it can know to tell use to run later on.
- if (m_ctx.HasValidProcessID())
- pid = m_ctx.ProcessID();
- else
- pid = 0;
- rep << std::hex << pid;
- return SendPacket(rep.str());
-}
-
-rnb_err_t RNBRemote::HandlePacket_qRegisterInfo(const char *p) {
- if (g_num_reg_entries == 0)
- InitializeRegisters();
-
- p += strlen("qRegisterInfo");
-
- nub_size_t num_reg_sets = 0;
- const DNBRegisterSetInfo *reg_set_info = DNBGetRegisterSetInfo(&num_reg_sets);
- uint32_t reg_num = static_cast<uint32_t>(strtoul(p, 0, 16));
-
- if (reg_num < g_num_reg_entries) {
- const register_map_entry_t *reg_entry = &g_reg_entries[reg_num];
- std::ostringstream ostrm;
- if (reg_entry->nub_info.name)
- ostrm << "name:" << reg_entry->nub_info.name << ';';
- if (reg_entry->nub_info.alt)
- ostrm << "alt-name:" << reg_entry->nub_info.alt << ';';
-
- ostrm << "bitsize:" << std::dec << reg_entry->nub_info.size * 8 << ';';
- ostrm << "offset:" << std::dec << reg_entry->offset << ';';
-
- switch (reg_entry->nub_info.type) {
- case Uint:
- ostrm << "encoding:uint;";
- break;
- case Sint:
- ostrm << "encoding:sint;";
- break;
- case IEEE754:
- ostrm << "encoding:ieee754;";
- break;
- case Vector:
- ostrm << "encoding:vector;";
- break;
- }
-
- switch (reg_entry->nub_info.format) {
- case Binary:
- ostrm << "format:binary;";
- break;
- case Decimal:
- ostrm << "format:decimal;";
- break;
- case Hex:
- ostrm << "format:hex;";
- break;
- case Float:
- ostrm << "format:float;";
- break;
- case VectorOfSInt8:
- ostrm << "format:vector-sint8;";
- break;
- case VectorOfUInt8:
- ostrm << "format:vector-uint8;";
- break;
- case VectorOfSInt16:
- ostrm << "format:vector-sint16;";
- break;
- case VectorOfUInt16:
- ostrm << "format:vector-uint16;";
- break;
- case VectorOfSInt32:
- ostrm << "format:vector-sint32;";
- break;
- case VectorOfUInt32:
- ostrm << "format:vector-uint32;";
- break;
- case VectorOfFloat32:
- ostrm << "format:vector-float32;";
- break;
- case VectorOfUInt128:
- ostrm << "format:vector-uint128;";
- break;
- };
-
- if (reg_set_info && reg_entry->nub_info.set < num_reg_sets)
- ostrm << "set:" << reg_set_info[reg_entry->nub_info.set].name << ';';
-
- if (reg_entry->nub_info.reg_ehframe != INVALID_NUB_REGNUM)
- ostrm << "ehframe:" << std::dec << reg_entry->nub_info.reg_ehframe << ';';
-
- if (reg_entry->nub_info.reg_dwarf != INVALID_NUB_REGNUM)
- ostrm << "dwarf:" << std::dec << reg_entry->nub_info.reg_dwarf << ';';
-
- switch (reg_entry->nub_info.reg_generic) {
- case GENERIC_REGNUM_FP:
- ostrm << "generic:fp;";
- break;
- case GENERIC_REGNUM_PC:
- ostrm << "generic:pc;";
- break;
- case GENERIC_REGNUM_SP:
- ostrm << "generic:sp;";
- break;
- case GENERIC_REGNUM_RA:
- ostrm << "generic:ra;";
- break;
- case GENERIC_REGNUM_FLAGS:
- ostrm << "generic:flags;";
- break;
- case GENERIC_REGNUM_ARG1:
- ostrm << "generic:arg1;";
- break;
- case GENERIC_REGNUM_ARG2:
- ostrm << "generic:arg2;";
- break;
- case GENERIC_REGNUM_ARG3:
- ostrm << "generic:arg3;";
- break;
- case GENERIC_REGNUM_ARG4:
- ostrm << "generic:arg4;";
- break;
- case GENERIC_REGNUM_ARG5:
- ostrm << "generic:arg5;";
- break;
- case GENERIC_REGNUM_ARG6:
- ostrm << "generic:arg6;";
- break;
- case GENERIC_REGNUM_ARG7:
- ostrm << "generic:arg7;";
- break;
- case GENERIC_REGNUM_ARG8:
- ostrm << "generic:arg8;";
- break;
- default:
- break;
- }
-
- if (!reg_entry->value_regnums.empty()) {
- ostrm << "container-regs:";
- for (size_t i = 0, n = reg_entry->value_regnums.size(); i < n; ++i) {
- if (i > 0)
- ostrm << ',';
- ostrm << RAW_HEXBASE << reg_entry->value_regnums[i];
- }
- ostrm << ';';
- }
-
- if (!reg_entry->invalidate_regnums.empty()) {
- ostrm << "invalidate-regs:";
- for (size_t i = 0, n = reg_entry->invalidate_regnums.size(); i < n; ++i) {
- if (i > 0)
- ostrm << ',';
- ostrm << RAW_HEXBASE << reg_entry->invalidate_regnums[i];
- }
- ostrm << ';';
- }
-
- return SendPacket(ostrm.str());
- }
- return SendPacket("E45");
-}
-
-/* This expects a packet formatted like
-
- QSetLogging:bitmask=LOG_ALL|LOG_RNB_REMOTE;
-
- with the "QSetLogging:" already removed from the start. Maybe in the
- future this packet will include other keyvalue pairs like
-
- QSetLogging:bitmask=LOG_ALL;mode=asl;
- */
-
-rnb_err_t set_logging(const char *p) {
- int bitmask = 0;
- while (p && *p != '\0') {
- if (strncmp(p, "bitmask=", sizeof("bitmask=") - 1) == 0) {
- p += sizeof("bitmask=") - 1;
- while (p && *p != '\0' && *p != ';') {
- if (*p == '|')
- p++;
-
- // to regenerate the LOG_ entries (not including the LOG_RNB entries)
- // $ for logname in `grep '^#define LOG_' DNBDefs.h | egrep -v
- // 'LOG_HI|LOG_LO' | awk '{print $2}'`
- // do
- // echo " else if (strncmp (p, \"$logname\", sizeof
- // (\"$logname\") - 1) == 0)"
- // echo " {"
- // echo " p += sizeof (\"$logname\") - 1;"
- // echo " bitmask |= $logname;"
- // echo " }"
- // done
- if (strncmp(p, "LOG_VERBOSE", sizeof("LOG_VERBOSE") - 1) == 0) {
- p += sizeof("LOG_VERBOSE") - 1;
- bitmask |= LOG_VERBOSE;
- } else if (strncmp(p, "LOG_PROCESS", sizeof("LOG_PROCESS") - 1) == 0) {
- p += sizeof("LOG_PROCESS") - 1;
- bitmask |= LOG_PROCESS;
- } else if (strncmp(p, "LOG_THREAD", sizeof("LOG_THREAD") - 1) == 0) {
- p += sizeof("LOG_THREAD") - 1;
- bitmask |= LOG_THREAD;
- } else if (strncmp(p, "LOG_EXCEPTIONS", sizeof("LOG_EXCEPTIONS") - 1) ==
- 0) {
- p += sizeof("LOG_EXCEPTIONS") - 1;
- bitmask |= LOG_EXCEPTIONS;
- } else if (strncmp(p, "LOG_SHLIB", sizeof("LOG_SHLIB") - 1) == 0) {
- p += sizeof("LOG_SHLIB") - 1;
- bitmask |= LOG_SHLIB;
- } else if (strncmp(p, "LOG_MEMORY", sizeof("LOG_MEMORY") - 1) == 0) {
- p += sizeof("LOG_MEMORY") - 1;
- bitmask |= LOG_MEMORY;
- } else if (strncmp(p, "LOG_MEMORY_DATA_SHORT",
- sizeof("LOG_MEMORY_DATA_SHORT") - 1) == 0) {
- p += sizeof("LOG_MEMORY_DATA_SHORT") - 1;
- bitmask |= LOG_MEMORY_DATA_SHORT;
- } else if (strncmp(p, "LOG_MEMORY_DATA_LONG",
- sizeof("LOG_MEMORY_DATA_LONG") - 1) == 0) {
- p += sizeof("LOG_MEMORY_DATA_LONG") - 1;
- bitmask |= LOG_MEMORY_DATA_LONG;
- } else if (strncmp(p, "LOG_MEMORY_PROTECTIONS",
- sizeof("LOG_MEMORY_PROTECTIONS") - 1) == 0) {
- p += sizeof("LOG_MEMORY_PROTECTIONS") - 1;
- bitmask |= LOG_MEMORY_PROTECTIONS;
- } else if (strncmp(p, "LOG_BREAKPOINTS",
- sizeof("LOG_BREAKPOINTS") - 1) == 0) {
- p += sizeof("LOG_BREAKPOINTS") - 1;
- bitmask |= LOG_BREAKPOINTS;
- } else if (strncmp(p, "LOG_EVENTS", sizeof("LOG_EVENTS") - 1) == 0) {
- p += sizeof("LOG_EVENTS") - 1;
- bitmask |= LOG_EVENTS;
- } else if (strncmp(p, "LOG_WATCHPOINTS",
- sizeof("LOG_WATCHPOINTS") - 1) == 0) {
- p += sizeof("LOG_WATCHPOINTS") - 1;
- bitmask |= LOG_WATCHPOINTS;
- } else if (strncmp(p, "LOG_STEP", sizeof("LOG_STEP") - 1) == 0) {
- p += sizeof("LOG_STEP") - 1;
- bitmask |= LOG_STEP;
- } else if (strncmp(p, "LOG_TASK", sizeof("LOG_TASK") - 1) == 0) {
- p += sizeof("LOG_TASK") - 1;
- bitmask |= LOG_TASK;
- } else if (strncmp(p, "LOG_ALL", sizeof("LOG_ALL") - 1) == 0) {
- p += sizeof("LOG_ALL") - 1;
- bitmask |= LOG_ALL;
- } else if (strncmp(p, "LOG_DEFAULT", sizeof("LOG_DEFAULT") - 1) == 0) {
- p += sizeof("LOG_DEFAULT") - 1;
- bitmask |= LOG_DEFAULT;
- }
- // end of auto-generated entries
-
- else if (strncmp(p, "LOG_NONE", sizeof("LOG_NONE") - 1) == 0) {
- p += sizeof("LOG_NONE") - 1;
- bitmask = 0;
- } else if (strncmp(p, "LOG_RNB_MINIMAL",
- sizeof("LOG_RNB_MINIMAL") - 1) == 0) {
- p += sizeof("LOG_RNB_MINIMAL") - 1;
- bitmask |= LOG_RNB_MINIMAL;
- } else if (strncmp(p, "LOG_RNB_MEDIUM", sizeof("LOG_RNB_MEDIUM") - 1) ==
- 0) {
- p += sizeof("LOG_RNB_MEDIUM") - 1;
- bitmask |= LOG_RNB_MEDIUM;
- } else if (strncmp(p, "LOG_RNB_MAX", sizeof("LOG_RNB_MAX") - 1) == 0) {
- p += sizeof("LOG_RNB_MAX") - 1;
- bitmask |= LOG_RNB_MAX;
- } else if (strncmp(p, "LOG_RNB_COMM", sizeof("LOG_RNB_COMM") - 1) ==
- 0) {
- p += sizeof("LOG_RNB_COMM") - 1;
- bitmask |= LOG_RNB_COMM;
- } else if (strncmp(p, "LOG_RNB_REMOTE", sizeof("LOG_RNB_REMOTE") - 1) ==
- 0) {
- p += sizeof("LOG_RNB_REMOTE") - 1;
- bitmask |= LOG_RNB_REMOTE;
- } else if (strncmp(p, "LOG_RNB_EVENTS", sizeof("LOG_RNB_EVENTS") - 1) ==
- 0) {
- p += sizeof("LOG_RNB_EVENTS") - 1;
- bitmask |= LOG_RNB_EVENTS;
- } else if (strncmp(p, "LOG_RNB_PROC", sizeof("LOG_RNB_PROC") - 1) ==
- 0) {
- p += sizeof("LOG_RNB_PROC") - 1;
- bitmask |= LOG_RNB_PROC;
- } else if (strncmp(p, "LOG_RNB_PACKETS",
- sizeof("LOG_RNB_PACKETS") - 1) == 0) {
- p += sizeof("LOG_RNB_PACKETS") - 1;
- bitmask |= LOG_RNB_PACKETS;
- } else if (strncmp(p, "LOG_RNB_ALL", sizeof("LOG_RNB_ALL") - 1) == 0) {
- p += sizeof("LOG_RNB_ALL") - 1;
- bitmask |= LOG_RNB_ALL;
- } else if (strncmp(p, "LOG_RNB_DEFAULT",
- sizeof("LOG_RNB_DEFAULT") - 1) == 0) {
- p += sizeof("LOG_RNB_DEFAULT") - 1;
- bitmask |= LOG_RNB_DEFAULT;
- } else if (strncmp(p, "LOG_DARWIN_LOG", sizeof("LOG_DARWIN_LOG") - 1) ==
- 0) {
- p += sizeof("LOG_DARWIN_LOG") - 1;
- bitmask |= LOG_DARWIN_LOG;
- } else if (strncmp(p, "LOG_RNB_NONE", sizeof("LOG_RNB_NONE") - 1) ==
- 0) {
- p += sizeof("LOG_RNB_NONE") - 1;
- bitmask = 0;
- } else {
- /* Unrecognized logging bit; ignore it. */
- const char *c = strchr(p, '|');
- if (c) {
- p = c;
- } else {
- c = strchr(p, ';');
- if (c) {
- p = c;
- } else {
- // Improperly terminated word; just go to end of str
- p = strchr(p, '\0');
- }
- }
- }
- }
- // Did we get a properly formatted logging bitmask?
- if (p && *p == ';') {
- // Enable DNB logging.
- // Use the existing log callback if one was already configured.
- if (!DNBLogGetLogCallback()) {
- // Use the os_log()-based logger if available; otherwise,
- // fallback to ASL.
- auto log_callback = OsLogger::GetLogFunction();
- if (log_callback)
- DNBLogSetLogCallback(log_callback, nullptr);
- else
- DNBLogSetLogCallback(ASLLogCallback, nullptr);
- }
-
- // Update logging to use the configured log channel bitmask.
- DNBLogSetLogMask(bitmask);
- p++;
- }
- }
-// We're not going to support logging to a file for now. All logging
-// goes through ASL or the previously arranged log callback.
-#if 0
- else if (strncmp (p, "mode=", sizeof ("mode=") - 1) == 0)
- {
- p += sizeof ("mode=") - 1;
- if (strncmp (p, "asl;", sizeof ("asl;") - 1) == 0)
- {
- DNBLogToASL ();
- p += sizeof ("asl;") - 1;
- }
- else if (strncmp (p, "file;", sizeof ("file;") - 1) == 0)
- {
- DNBLogToFile ();
- p += sizeof ("file;") - 1;
- }
- else
- {
- // Ignore unknown argument
- const char *c = strchr (p, ';');
- if (c)
- p = c + 1;
- else
- p = strchr (p, '\0');
- }
- }
- else if (strncmp (p, "filename=", sizeof ("filename=") - 1) == 0)
- {
- p += sizeof ("filename=") - 1;
- const char *c = strchr (p, ';');
- if (c == NULL)
- {
- c = strchr (p, '\0');
- continue;
- }
- char *fn = (char *) alloca (c - p + 1);
- strlcpy (fn, p, c - p);
- fn[c - p] = '\0';
-
- // A file name of "asl" is special and is another way to indicate
- // that logging should be done via ASL, not by file.
- if (strcmp (fn, "asl") == 0)
- {
- DNBLogToASL ();
- }
- else
- {
- FILE *f = fopen (fn, "w");
- if (f)
- {
- DNBLogSetLogFile (f);
- DNBEnableLogging (f, DNBLogGetLogMask ());
- DNBLogToFile ();
- }
- }
- p = c + 1;
- }
-#endif /* #if 0 to enforce ASL logging only. */
- else {
- // Ignore unknown argument
- const char *c = strchr(p, ';');
- if (c)
- p = c + 1;
- else
- p = strchr(p, '\0');
- }
- }
-
- return rnb_success;
-}
-
-rnb_err_t RNBRemote::HandlePacket_QThreadSuffixSupported(const char *p) {
- m_thread_suffix_supported = true;
- return SendPacket("OK");
-}
-
-rnb_err_t RNBRemote::HandlePacket_QStartNoAckMode(const char *p) {
- // Send the OK packet first so the correct checksum is appended...
- rnb_err_t result = SendPacket("OK");
- m_noack_mode = true;
- return result;
-}
-
-rnb_err_t RNBRemote::HandlePacket_QSetLogging(const char *p) {
- p += sizeof("QSetLogging:") - 1;
- rnb_err_t result = set_logging(p);
- if (result == rnb_success)
- return SendPacket("OK");
- else
- return SendPacket("E35");
-}
-
-rnb_err_t RNBRemote::HandlePacket_QSetDisableASLR(const char *p) {
- extern int g_disable_aslr;
- p += sizeof("QSetDisableASLR:") - 1;
- switch (*p) {
- case '0':
- g_disable_aslr = 0;
- break;
- case '1':
- g_disable_aslr = 1;
- break;
- default:
- return SendPacket("E56");
- }
- return SendPacket("OK");
-}
-
-rnb_err_t RNBRemote::HandlePacket_QSetSTDIO(const char *p) {
- // Only set stdin/out/err if we don't already have a process
- if (!m_ctx.HasValidProcessID()) {
- bool success = false;
- // Check the seventh character since the packet will be one of:
- // QSetSTDIN
- // QSetSTDOUT
- // QSetSTDERR
- StdStringExtractor packet(p);
- packet.SetFilePos(7);
- char ch = packet.GetChar();
- while (packet.GetChar() != ':')
- /* Do nothing. */;
-
- switch (ch) {
- case 'I': // STDIN
- packet.GetHexByteString(m_ctx.GetSTDIN());
- success = !m_ctx.GetSTDIN().empty();
- break;
-
- case 'O': // STDOUT
- packet.GetHexByteString(m_ctx.GetSTDOUT());
- success = !m_ctx.GetSTDOUT().empty();
- break;
-
- case 'E': // STDERR
- packet.GetHexByteString(m_ctx.GetSTDERR());
- success = !m_ctx.GetSTDERR().empty();
- break;
-
- default:
- break;
- }
- if (success)
- return SendPacket("OK");
- return SendPacket("E57");
- }
- return SendPacket("E58");
-}
-
-rnb_err_t RNBRemote::HandlePacket_QSetWorkingDir(const char *p) {
- // Only set the working directory if we don't already have a process
- if (!m_ctx.HasValidProcessID()) {
- StdStringExtractor packet(p += sizeof("QSetWorkingDir:") - 1);
- if (packet.GetHexByteString(m_ctx.GetWorkingDir())) {
- struct stat working_dir_stat;
- if (::stat(m_ctx.GetWorkingDirPath(), &working_dir_stat) == -1) {
- m_ctx.GetWorkingDir().clear();
- return SendPacket("E61"); // Working directory doesn't exist...
- } else if ((working_dir_stat.st_mode & S_IFMT) == S_IFDIR) {
- return SendPacket("OK");
- } else {
- m_ctx.GetWorkingDir().clear();
- return SendPacket("E62"); // Working directory isn't a directory...
- }
- }
- return SendPacket("E59"); // Invalid path
- }
- return SendPacket(
- "E60"); // Already had a process, too late to set working dir
-}
-
-rnb_err_t RNBRemote::HandlePacket_QSyncThreadState(const char *p) {
- if (!m_ctx.HasValidProcessID()) {
- // We allow gdb to connect to a server that hasn't started running
- // the target yet. gdb still wants to ask questions about it and
- // freaks out if it gets an error. So just return OK here.
- return SendPacket("OK");
- }
-
- errno = 0;
- p += strlen("QSyncThreadState:");
- nub_thread_t tid = strtoul(p, NULL, 16);
- if (errno != 0 && tid == 0) {
- return HandlePacket_ILLFORMED(
- __FILE__, __LINE__, p,
- "Invalid thread number in QSyncThreadState packet");
- }
- if (DNBProcessSyncThreadState(m_ctx.ProcessID(), tid))
- return SendPacket("OK");
- else
- return SendPacket("E61");
-}
-
-rnb_err_t RNBRemote::HandlePacket_QSetDetachOnError(const char *p) {
- p += sizeof("QSetDetachOnError:") - 1;
- bool should_detach = true;
- switch (*p) {
- case '0':
- should_detach = false;
- break;
- case '1':
- should_detach = true;
- break;
- default:
- return HandlePacket_ILLFORMED(
- __FILE__, __LINE__, p,
- "Invalid value for QSetDetachOnError - should be 0 or 1");
- break;
- }
-
- m_ctx.SetDetachOnError(should_detach);
- return SendPacket("OK");
-}
-
-rnb_err_t RNBRemote::HandlePacket_qStructuredDataPlugins(const char *p) {
- // We'll return a JSON array of supported packet types.
- // The type is significant. For each of the supported
- // packet types that have been enabled, there will be a
- // 'J' async packet sent to the client with payload data.
- // This payload data will be a JSON dictionary, and the
- // top level dictionary will contain a string field with
- // its value set to the relevant packet type from this list.
- JSONGenerator::Array supported_json_packets;
-
- // Check for DarwinLog (libtrace os_log/activity support).
- if (DarwinLogCollector::IsSupported())
- supported_json_packets.AddItem(
- JSONGenerator::StringSP(new JSONGenerator::String("DarwinLog")));
-
- // Send back the array.
- std::ostringstream stream;
- supported_json_packets.Dump(stream);
- return SendPacket(stream.str());
-}
-
-rnb_err_t RNBRemote::HandlePacket_QConfigureDarwinLog(const char *p) {
- if (!DarwinLogCollector::IsSupported()) {
- // We should never have been given this request.
- return SendPacket("E89");
- }
-
- // Ensure we have a process. We expect a separate configure request for
- // each process launched/attached.
- const nub_process_t pid = m_ctx.ProcessID();
- if (pid == INVALID_NUB_PROCESS)
- return SendPacket("E94");
-
- // Get the configuration dictionary.
- p += strlen("QConfigureDarwinLog:");
-
- // The configuration dictionary is binary encoded.
- std::vector<uint8_t> unescaped_config_data = decode_binary_data(p, -1);
- std::string unescaped_config_string((const char *)&unescaped_config_data[0],
- unescaped_config_data.size());
- DNBLogThreadedIf(LOG_DARWIN_LOG, "DarwinLog: received config data: \"%s\"",
- unescaped_config_string.c_str());
- auto configuration_sp =
- JSONParser(unescaped_config_string.c_str()).ParseJSONValue();
- if (!configuration_sp) {
- // Malformed request - we require configuration data
- // indicating whether we're enabling or disabling.
- return SendPacket("E90");
- }
-
- if (!JSONObject::classof(configuration_sp.get())) {
- // Configuration data is not of the right type.
- return SendPacket("E91");
- }
- JSONObject &config_dict = *static_cast<JSONObject *>(configuration_sp.get());
-
- // Check if we're enabling or disabling.
- auto enabled_sp = config_dict.GetObject("enabled");
- if (!enabled_sp) {
- // Missing required "enabled" field.
- return SendPacket("E92");
- }
- if (!JSONTrue::classof(enabled_sp.get()) &&
- !JSONFalse::classof(enabled_sp.get())) {
- // Should be a boolean type, but wasn't.
- return SendPacket("E93");
- }
- const bool enabling = JSONTrue::classof(enabled_sp.get());
-
- // TODO - handle other configuration parameters here.
-
- // Shut down any active activity stream for the process.
- DarwinLogCollector::CancelStreamForProcess(pid);
-
- if (enabling) {
- // Look up the procecess.
- if (!DarwinLogCollector::StartCollectingForProcess(pid, config_dict))
- return SendPacket("E95");
- }
-
- return SendPacket("OK");
-}
-
-rnb_err_t RNBRemote::HandlePacket_QListThreadsInStopReply(const char *p) {
- // If this packet is received, it allows us to send an extra key/value
- // pair in the stop reply packets where we will list all of the thread IDs
- // separated by commas:
- //
- // "threads:10a,10b,10c;"
- //
- // This will get included in the stop reply packet as something like:
- //
- // "T11thread:10a;00:00000000;01:00010203:threads:10a,10b,10c;"
- //
- // This can save two packets on each stop: qfThreadInfo/qsThreadInfo and
- // speed things up a bit.
- //
- // Send the OK packet first so the correct checksum is appended...
- rnb_err_t result = SendPacket("OK");
- m_list_threads_in_stop_reply = true;
-
- return result;
-}
-
-rnb_err_t RNBRemote::HandlePacket_QSetMaxPayloadSize(const char *p) {
- /* The number of characters in a packet payload that gdb is
- prepared to accept. The packet-start char, packet-end char,
- 2 checksum chars and terminating null character are not included
- in this size. */
- p += sizeof("QSetMaxPayloadSize:") - 1;
- errno = 0;
- uint32_t size = static_cast<uint32_t>(strtoul(p, NULL, 16));
- if (errno != 0 && size == 0) {
- return HandlePacket_ILLFORMED(
- __FILE__, __LINE__, p, "Invalid length in QSetMaxPayloadSize packet");
- }
- m_max_payload_size = size;
- return SendPacket("OK");
-}
-
-rnb_err_t RNBRemote::HandlePacket_QSetMaxPacketSize(const char *p) {
- /* This tells us the largest packet that gdb can handle.
- i.e. the size of gdb's packet-reading buffer.
- QSetMaxPayloadSize is preferred because it is less ambiguous. */
- p += sizeof("QSetMaxPacketSize:") - 1;
- errno = 0;
- uint32_t size = static_cast<uint32_t>(strtoul(p, NULL, 16));
- if (errno != 0 && size == 0) {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "Invalid length in QSetMaxPacketSize packet");
- }
- m_max_payload_size = size - 5;
- return SendPacket("OK");
-}
-
-rnb_err_t RNBRemote::HandlePacket_QEnvironment(const char *p) {
- /* This sets the environment for the target program. The packet is of the
- form:
-
- QEnvironment:VARIABLE=VALUE
-
- */
-
- DNBLogThreadedIf(
- LOG_RNB_REMOTE, "%8u RNBRemote::%s Handling QEnvironment: \"%s\"",
- (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p);
-
- p += sizeof("QEnvironment:") - 1;
- RNBContext &ctx = Context();
-
- ctx.PushEnvironment(p);
- return SendPacket("OK");
-}
-
-rnb_err_t RNBRemote::HandlePacket_QEnvironmentHexEncoded(const char *p) {
- /* This sets the environment for the target program. The packet is of the
- form:
-
- QEnvironmentHexEncoded:VARIABLE=VALUE
-
- The VARIABLE=VALUE part is sent hex-encoded so characters like '#' with
- special
- meaning in the remote protocol won't break it.
- */
-
- DNBLogThreadedIf(LOG_RNB_REMOTE,
- "%8u RNBRemote::%s Handling QEnvironmentHexEncoded: \"%s\"",
- (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true),
- __FUNCTION__, p);
-
- p += sizeof("QEnvironmentHexEncoded:") - 1;
-
- std::string arg;
- const char *c;
- c = p;
- while (*c != '\0') {
- if (*(c + 1) == '\0') {
- return HandlePacket_ILLFORMED(
- __FILE__, __LINE__, p,
- "non-hex char in arg on 'QEnvironmentHexEncoded' pkt");
- }
- char smallbuf[3];
- smallbuf[0] = *c;
- smallbuf[1] = *(c + 1);
- smallbuf[2] = '\0';
- errno = 0;
- int ch = static_cast<int>(strtoul(smallbuf, NULL, 16));
- if (errno != 0 && ch == 0) {
- return HandlePacket_ILLFORMED(
- __FILE__, __LINE__, p,
- "non-hex char in arg on 'QEnvironmentHexEncoded' pkt");
- }
- arg.push_back(ch);
- c += 2;
- }
-
- RNBContext &ctx = Context();
- if (arg.length() > 0)
- ctx.PushEnvironment(arg.c_str());
-
- return SendPacket("OK");
-}
-
-rnb_err_t RNBRemote::HandlePacket_QLaunchArch(const char *p) {
- p += sizeof("QLaunchArch:") - 1;
- if (DNBSetArchitecture(p))
- return SendPacket("OK");
- 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 void *buf, size_t buf_size,
- bool swap) {
- int i;
- const uint8_t *p = (const uint8_t *)buf;
- if (swap) {
- for (i = static_cast<int>(buf_size) - 1; i >= 0; i--)
- ostrm << RAWHEX8(p[i]);
- } else {
- for (size_t i = 0; i < buf_size; i++)
- ostrm << RAWHEX8(p[i]);
- }
-}
-
-void append_hexified_string(std::ostream &ostrm, const std::string &string) {
- size_t string_size = string.size();
- const char *string_buf = string.c_str();
- for (size_t i = 0; i < string_size; i++) {
- ostrm << RAWHEX8(*(string_buf + i));
- }
-}
-
-void register_value_in_hex_fixed_width(std::ostream &ostrm, nub_process_t pid,
- nub_thread_t tid,
- const register_map_entry_t *reg,
- const DNBRegisterValue *reg_value_ptr) {
- if (reg != NULL) {
- DNBRegisterValue reg_value;
- if (reg_value_ptr == NULL) {
- if (DNBThreadGetRegisterValueByID(pid, tid, reg->nub_info.set,
- reg->nub_info.reg, &reg_value))
- reg_value_ptr = &reg_value;
- }
-
- if (reg_value_ptr) {
- append_hex_value(ostrm, reg_value_ptr->value.v_uint8, reg->nub_info.size,
- false);
- } else {
- // If we fail to read a register value, check if it has a default
- // fail value. If it does, return this instead in case some of
- // the registers are not available on the current system.
- if (reg->nub_info.size > 0) {
- std::basic_string<uint8_t> zeros(reg->nub_info.size, '\0');
- append_hex_value(ostrm, zeros.data(), zeros.size(), false);
- }
- }
- }
-}
-
-void debugserver_regnum_with_fixed_width_hex_register_value(
- std::ostream &ostrm, nub_process_t pid, nub_thread_t tid,
- const register_map_entry_t *reg, const DNBRegisterValue *reg_value_ptr) {
- // Output the register number as 'NN:VVVVVVVV;' where NN is a 2 bytes HEX
- // gdb register number, and VVVVVVVV is the correct number of hex bytes
- // as ASCII for the register value.
- if (reg != NULL) {
- ostrm << RAWHEX8(reg->debugserver_regnum) << ':';
- register_value_in_hex_fixed_width(ostrm, pid, tid, reg, reg_value_ptr);
- ostrm << ';';
- }
-}
-
-void RNBRemote::DispatchQueueOffsets::GetThreadQueueInfo(
- nub_process_t pid, nub_addr_t dispatch_qaddr, nub_addr_t &dispatch_queue_t,
- std::string &queue_name, uint64_t &queue_width,
- uint64_t &queue_serialnum) const {
- queue_name.clear();
- queue_width = 0;
- queue_serialnum = 0;
-
- if (IsValid() && dispatch_qaddr != INVALID_NUB_ADDRESS &&
- dispatch_qaddr != 0) {
- dispatch_queue_t = DNBProcessMemoryReadPointer(pid, dispatch_qaddr);
- if (dispatch_queue_t) {
- queue_width = DNBProcessMemoryReadInteger(
- pid, dispatch_queue_t + dqo_width, dqo_width_size, 0);
- queue_serialnum = DNBProcessMemoryReadInteger(
- pid, dispatch_queue_t + dqo_serialnum, dqo_serialnum_size, 0);
-
- if (dqo_version >= 4) {
- // libdispatch versions 4+, pointer to dispatch name is in the
- // queue structure.
- nub_addr_t pointer_to_label_address = dispatch_queue_t + dqo_label;
- nub_addr_t label_addr =
- DNBProcessMemoryReadPointer(pid, pointer_to_label_address);
- if (label_addr)
- queue_name = DNBProcessMemoryReadCString(pid, label_addr);
- } else {
- // libdispatch versions 1-3, dispatch name is a fixed width char array
- // in the queue structure.
- queue_name = DNBProcessMemoryReadCStringFixed(
- pid, dispatch_queue_t + dqo_label, dqo_label_size);
- }
- }
- }
-}
-
-struct StackMemory {
- uint8_t bytes[2 * sizeof(nub_addr_t)];
- nub_size_t length;
-};
-typedef std::map<nub_addr_t, StackMemory> StackMemoryMap;
-
-static void ReadStackMemory(nub_process_t pid, nub_thread_t tid,
- StackMemoryMap &stack_mmap,
- uint32_t backtrace_limit = 256) {
- DNBRegisterValue reg_value;
- if (DNBThreadGetRegisterValueByID(pid, tid, REGISTER_SET_GENERIC,
- GENERIC_REGNUM_FP, &reg_value)) {
- uint32_t frame_count = 0;
- uint64_t fp = 0;
- if (reg_value.info.size == 4)
- fp = reg_value.value.uint32;
- else
- fp = reg_value.value.uint64;
- while (fp != 0) {
- // Make sure we never recurse more than 256 times so we don't recurse too
- // far or
- // store up too much memory in the expedited cache
- if (++frame_count > backtrace_limit)
- break;
-
- const nub_size_t read_size = reg_value.info.size * 2;
- StackMemory stack_memory;
- stack_memory.length = read_size;
- if (DNBProcessMemoryRead(pid, fp, read_size, stack_memory.bytes) !=
- read_size)
- break;
- // Make sure we don't try to put the same stack memory in more than once
- if (stack_mmap.find(fp) != stack_mmap.end())
- break;
- // Put the entry into the cache
- stack_mmap[fp] = stack_memory;
- // Dereference the frame pointer to get to the previous frame pointer
- if (reg_value.info.size == 4)
- fp = ((uint32_t *)stack_memory.bytes)[0];
- else
- fp = ((uint64_t *)stack_memory.bytes)[0];
- }
- }
-}
-
-rnb_err_t RNBRemote::SendStopReplyPacketForThread(nub_thread_t tid) {
- const nub_process_t pid = m_ctx.ProcessID();
- if (pid == INVALID_NUB_PROCESS)
- return SendPacket("E50");
-
- struct DNBThreadStopInfo tid_stop_info;
-
- /* Fill the remaining space in this packet with as many registers
- as we can stuff in there. */
-
- if (DNBThreadGetStopReason(pid, tid, &tid_stop_info)) {
- const bool did_exec = tid_stop_info.reason == eStopTypeExec;
- if (did_exec) {
- RNBRemote::InitializeRegisters(true);
-
- // Reset any symbols that need resetting when we exec
- m_dispatch_queue_offsets_addr = INVALID_NUB_ADDRESS;
- m_dispatch_queue_offsets.Clear();
- }
-
- std::ostringstream ostrm;
- // Output the T packet with the thread
- ostrm << 'T';
- int signum = tid_stop_info.details.signal.signo;
- DNBLogThreadedIf(
- LOG_RNB_PROC, "%8d %s got signal signo = %u, exc_type = %u",
- (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__,
- signum, tid_stop_info.details.exception.type);
-
- // Translate any mach exceptions to gdb versions, unless they are
- // common exceptions like a breakpoint or a soft signal.
- switch (tid_stop_info.details.exception.type) {
- default:
- signum = 0;
- break;
- case EXC_BREAKPOINT:
- signum = SIGTRAP;
- break;
- case EXC_BAD_ACCESS:
- signum = TARGET_EXC_BAD_ACCESS;
- break;
- case EXC_BAD_INSTRUCTION:
- signum = TARGET_EXC_BAD_INSTRUCTION;
- break;
- case EXC_ARITHMETIC:
- signum = TARGET_EXC_ARITHMETIC;
- break;
- case EXC_EMULATION:
- signum = TARGET_EXC_EMULATION;
- break;
- case EXC_SOFTWARE:
- if (tid_stop_info.details.exception.data_count == 2 &&
- tid_stop_info.details.exception.data[0] == EXC_SOFT_SIGNAL)
- signum = static_cast<int>(tid_stop_info.details.exception.data[1]);
- else
- signum = TARGET_EXC_SOFTWARE;
- break;
- }
-
- ostrm << RAWHEX8(signum & 0xff);
-
- ostrm << std::hex << "thread:" << tid << ';';
-
- const char *thread_name = DNBThreadGetName(pid, tid);
- if (thread_name && thread_name[0]) {
- size_t thread_name_len = strlen(thread_name);
-
- if (::strcspn(thread_name, "$#+-;:") == thread_name_len)
- ostrm << std::hex << "name:" << thread_name << ';';
- else {
- // the thread name contains special chars, send as hex bytes
- ostrm << std::hex << "hexname:";
- const uint8_t *u_thread_name = (const uint8_t *)thread_name;
- for (size_t i = 0; i < thread_name_len; i++)
- ostrm << RAWHEX8(u_thread_name[i]);
- ostrm << ';';
- }
- }
-
- // If a 'QListThreadsInStopReply' was sent to enable this feature, we
- // will send all thread IDs back in the "threads" key whose value is
- // a list of hex thread IDs separated by commas:
- // "threads:10a,10b,10c;"
- // This will save the debugger from having to send a pair of qfThreadInfo
- // and qsThreadInfo packets, but it also might take a lot of room in the
- // stop reply packet, so it must be enabled only on systems where there
- // are no limits on packet lengths.
- if (m_list_threads_in_stop_reply) {
- const nub_size_t numthreads = DNBProcessGetNumThreads(pid);
- if (numthreads > 0) {
- std::vector<uint64_t> pc_values;
- ostrm << std::hex << "threads:";
- for (nub_size_t i = 0; i < numthreads; ++i) {
- nub_thread_t th = DNBProcessGetThreadAtIndex(pid, i);
- if (i > 0)
- ostrm << ',';
- ostrm << std::hex << th;
- DNBRegisterValue pc_regval;
- if (DNBThreadGetRegisterValueByID(pid, th, REGISTER_SET_GENERIC,
- GENERIC_REGNUM_PC, &pc_regval)) {
- uint64_t pc = INVALID_NUB_ADDRESS;
- if (pc_regval.value.uint64 != INVALID_NUB_ADDRESS) {
- if (pc_regval.info.size == 4) {
- pc = pc_regval.value.uint32;
- } else if (pc_regval.info.size == 8) {
- pc = pc_regval.value.uint64;
- }
- if (pc != INVALID_NUB_ADDRESS) {
- pc_values.push_back(pc);
- }
- }
- }
- }
- ostrm << ';';
-
- // If we failed to get any of the thread pc values, the size of our
- // vector will not
- // be the same as the # of threads. Don't provide any expedited thread
- // pc values in
- // that case. This should not happen.
- if (pc_values.size() == numthreads) {
- ostrm << std::hex << "thread-pcs:";
- for (nub_size_t i = 0; i < numthreads; ++i) {
- if (i > 0)
- ostrm << ',';
- ostrm << std::hex << pc_values[i];
- }
- ostrm << ';';
- }
- }
-
- // Include JSON info that describes the stop reason for any threads
- // that actually have stop reasons. We use the new "jstopinfo" key
- // whose values is hex ascii JSON that contains the thread IDs
- // thread stop info only for threads that have stop reasons. Only send
- // this if we have more than one thread otherwise this packet has all
- // the info it needs.
- if (numthreads > 1) {
- const bool threads_with_valid_stop_info_only = true;
- JSONGenerator::ObjectSP threads_info_sp =
- GetJSONThreadsInfo(threads_with_valid_stop_info_only);
- if (threads_info_sp) {
- ostrm << std::hex << "jstopinfo:";
- std::ostringstream json_strm;
- threads_info_sp->Dump(json_strm);
- append_hexified_string(ostrm, json_strm.str());
- ostrm << ';';
- }
- }
- }
-
- if (g_num_reg_entries == 0)
- InitializeRegisters();
-
- if (g_reg_entries != NULL) {
- DNBRegisterValue reg_value;
- for (uint32_t reg = 0; reg < g_num_reg_entries; reg++) {
- // Expedite all registers in the first register set that aren't
- // contained in other registers
- if (g_reg_entries[reg].nub_info.set == 1 &&
- g_reg_entries[reg].nub_info.value_regs == NULL) {
- if (!DNBThreadGetRegisterValueByID(
- pid, tid, g_reg_entries[reg].nub_info.set,
- g_reg_entries[reg].nub_info.reg, &reg_value))
- continue;
-
- debugserver_regnum_with_fixed_width_hex_register_value(
- ostrm, pid, tid, &g_reg_entries[reg], &reg_value);
- }
- }
- }
-
- if (did_exec) {
- ostrm << "reason:exec;";
- } else if (tid_stop_info.details.exception.type) {
- ostrm << "metype:" << std::hex << tid_stop_info.details.exception.type
- << ';';
- ostrm << "mecount:" << std::hex
- << tid_stop_info.details.exception.data_count << ';';
- for (nub_size_t i = 0; i < tid_stop_info.details.exception.data_count;
- ++i)
- ostrm << "medata:" << std::hex
- << tid_stop_info.details.exception.data[i] << ';';
- }
-
- // Add expedited stack memory so stack backtracing doesn't need to read
- // anything from the
- // frame pointer chain.
- StackMemoryMap stack_mmap;
- ReadStackMemory(pid, tid, stack_mmap, 2);
- if (!stack_mmap.empty()) {
- for (const auto &stack_memory : stack_mmap) {
- ostrm << "memory:" << HEXBASE << stack_memory.first << '=';
- append_hex_value(ostrm, stack_memory.second.bytes,
- stack_memory.second.length, false);
- ostrm << ';';
- }
- }
-
- return SendPacket(ostrm.str());
- }
- return SendPacket("E51");
-}
-
-/* '?'
- The stop reply packet - tell gdb what the status of the inferior is.
- Often called the questionmark_packet. */
-
-rnb_err_t RNBRemote::HandlePacket_last_signal(const char *unused) {
- if (!m_ctx.HasValidProcessID()) {
- // Inferior is not yet specified/running
- return SendPacket("E02");
- }
-
- nub_process_t pid = m_ctx.ProcessID();
- nub_state_t pid_state = DNBProcessGetState(pid);
-
- switch (pid_state) {
- case eStateAttaching:
- case eStateLaunching:
- case eStateRunning:
- case eStateStepping:
- case eStateDetached:
- return rnb_success; // Ignore
-
- case eStateSuspended:
- case eStateStopped:
- case eStateCrashed: {
- nub_thread_t tid = DNBProcessGetCurrentThread(pid);
- // Make sure we set the current thread so g and p packets return
- // the data the gdb will expect.
- SetCurrentThread(tid);
-
- SendStopReplyPacketForThread(tid);
- } break;
-
- case eStateInvalid:
- case eStateUnloaded:
- case eStateExited: {
- char pid_exited_packet[16] = "";
- int pid_status = 0;
- // Process exited with exit status
- if (!DNBProcessGetExitStatus(pid, &pid_status))
- pid_status = 0;
-
- if (pid_status) {
- if (WIFEXITED(pid_status))
- snprintf(pid_exited_packet, sizeof(pid_exited_packet), "W%02x",
- WEXITSTATUS(pid_status));
- else if (WIFSIGNALED(pid_status))
- snprintf(pid_exited_packet, sizeof(pid_exited_packet), "X%02x",
- WEXITSTATUS(pid_status));
- else if (WIFSTOPPED(pid_status))
- snprintf(pid_exited_packet, sizeof(pid_exited_packet), "S%02x",
- WSTOPSIG(pid_status));
- }
-
- // If we have an empty exit packet, lets fill one in to be safe.
- if (!pid_exited_packet[0]) {
- strlcpy(pid_exited_packet, "W00", sizeof(pid_exited_packet) - 1);
- pid_exited_packet[sizeof(pid_exited_packet) - 1] = '\0';
- }
-
- 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;
- }
- return rnb_success;
-}
-
-rnb_err_t RNBRemote::HandlePacket_M(const char *p) {
- if (p == NULL || p[0] == '\0' || strlen(p) < 3) {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, "Too short M packet");
- }
-
- char *c;
- p++;
- errno = 0;
- nub_addr_t addr = strtoull(p, &c, 16);
- if (errno != 0 && addr == 0) {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "Invalid address in M packet");
- }
- if (*c != ',') {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "Comma sep missing in M packet");
- }
-
- /* Advance 'p' to the length part of the packet. */
- p += (c - p) + 1;
-
- errno = 0;
- unsigned long length = strtoul(p, &c, 16);
- if (errno != 0 && length == 0) {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "Invalid length in M packet");
- }
- if (length == 0) {
- return SendPacket("OK");
- }
-
- if (*c != ':') {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "Missing colon in M packet");
- }
- /* Advance 'p' to the data part of the packet. */
- p += (c - p) + 1;
-
- size_t datalen = strlen(p);
- if (datalen & 0x1) {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "Uneven # of hex chars for data in M packet");
- }
- if (datalen == 0) {
- return SendPacket("OK");
- }
-
- uint8_t *buf = (uint8_t *)alloca(datalen / 2);
- uint8_t *i = buf;
-
- while (*p != '\0' && *(p + 1) != '\0') {
- char hexbuf[3];
- hexbuf[0] = *p;
- hexbuf[1] = *(p + 1);
- hexbuf[2] = '\0';
- errno = 0;
- uint8_t byte = strtoul(hexbuf, NULL, 16);
- if (errno != 0 && byte == 0) {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "Invalid hex byte in M packet");
- }
- *i++ = byte;
- p += 2;
- }
-
- nub_size_t wrote =
- DNBProcessMemoryWrite(m_ctx.ProcessID(), addr, length, buf);
- if (wrote != length)
- return SendPacket("E09");
- else
- return SendPacket("OK");
-}
-
-rnb_err_t RNBRemote::HandlePacket_m(const char *p) {
- if (p == NULL || p[0] == '\0' || strlen(p) < 3) {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, "Too short m packet");
- }
-
- char *c;
- p++;
- errno = 0;
- nub_addr_t addr = strtoull(p, &c, 16);
- if (errno != 0 && addr == 0) {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "Invalid address in m packet");
- }
- if (*c != ',') {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "Comma sep missing in m packet");
- }
-
- /* Advance 'p' to the length part of the packet. */
- p += (c - p) + 1;
-
- errno = 0;
- auto length = strtoul(p, NULL, 16);
- if (errno != 0 && length == 0) {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "Invalid length in m packet");
- }
- if (length == 0) {
- return SendPacket("");
- }
-
- std::string buf(length, '\0');
- if (buf.empty()) {
- return SendPacket("E78");
- }
- nub_size_t bytes_read =
- DNBProcessMemoryRead(m_ctx.ProcessID(), addr, buf.size(), &buf[0]);
- if (bytes_read == 0) {
- return SendPacket("E08");
- }
-
- // "The reply may contain fewer bytes than requested if the server was able
- // to read only part of the region of memory."
- length = bytes_read;
-
- std::ostringstream ostrm;
- for (unsigned long i = 0; i < length; i++)
- ostrm << RAWHEX8(buf[i]);
- return SendPacket(ostrm.str());
-}
-
-// Read memory, sent it up as binary data.
-// Usage: xADDR,LEN
-// ADDR and LEN are both base 16.
-
-// Responds with 'OK' for zero-length request
-// or
-//
-// DATA
-//
-// where DATA is the binary data payload.
-
-rnb_err_t RNBRemote::HandlePacket_x(const char *p) {
- if (p == NULL || p[0] == '\0' || strlen(p) < 3) {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, "Too short X packet");
- }
-
- char *c;
- p++;
- errno = 0;
- nub_addr_t addr = strtoull(p, &c, 16);
- if (errno != 0) {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "Invalid address in X packet");
- }
- if (*c != ',') {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "Comma sep missing in X packet");
- }
-
- /* Advance 'p' to the number of bytes to be read. */
- p += (c - p) + 1;
-
- errno = 0;
- auto length = strtoul(p, NULL, 16);
- if (errno != 0) {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "Invalid length in x packet");
- }
-
- // zero length read means this is a test of whether that packet is implemented
- // or not.
- if (length == 0) {
- return SendPacket("OK");
- }
-
- std::vector<uint8_t> buf(length);
-
- if (buf.capacity() != length) {
- return SendPacket("E79");
- }
- nub_size_t bytes_read =
- DNBProcessMemoryRead(m_ctx.ProcessID(), addr, buf.size(), &buf[0]);
- if (bytes_read == 0) {
- return SendPacket("E80");
- }
-
- std::vector<uint8_t> buf_quoted;
- buf_quoted.reserve(bytes_read + 30);
- for (nub_size_t i = 0; i < bytes_read; i++) {
- if (buf[i] == '#' || buf[i] == '$' || buf[i] == '}' || buf[i] == '*') {
- buf_quoted.push_back(0x7d);
- buf_quoted.push_back(buf[i] ^ 0x20);
- } else {
- buf_quoted.push_back(buf[i]);
- }
- }
- length = buf_quoted.size();
-
- std::ostringstream ostrm;
- for (unsigned long i = 0; i < length; i++)
- ostrm << buf_quoted[i];
-
- return SendPacket(ostrm.str());
-}
-
-rnb_err_t RNBRemote::HandlePacket_X(const char *p) {
- if (p == NULL || p[0] == '\0' || strlen(p) < 3) {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, "Too short X packet");
- }
-
- char *c;
- p++;
- errno = 0;
- nub_addr_t addr = strtoull(p, &c, 16);
- if (errno != 0 && addr == 0) {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "Invalid address in X packet");
- }
- if (*c != ',') {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "Comma sep missing in X packet");
- }
-
- /* Advance 'p' to the length part of the packet. NB this is the length of the
- packet
- including any escaped chars. The data payload may be a little bit smaller
- after
- decoding. */
- p += (c - p) + 1;
-
- errno = 0;
- auto length = strtoul(p, NULL, 16);
- if (errno != 0 && length == 0) {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "Invalid length in X packet");
- }
-
- // I think gdb sends a zero length write request to test whether this
- // packet is accepted.
- if (length == 0) {
- return SendPacket("OK");
- }
-
- std::vector<uint8_t> data = decode_binary_data(c, -1);
- std::vector<uint8_t>::const_iterator it;
- uint8_t *buf = (uint8_t *)alloca(data.size());
- uint8_t *i = buf;
- for (it = data.begin(); it != data.end(); ++it) {
- *i++ = *it;
- }
-
- nub_size_t wrote =
- DNBProcessMemoryWrite(m_ctx.ProcessID(), addr, data.size(), buf);
- if (wrote != data.size())
- return SendPacket("E08");
- return SendPacket("OK");
-}
-
-/* 'g' -- read registers
- Get the contents of the registers for the current thread,
- send them to gdb.
- Should the setting of the Hg packet determine which thread's registers
- are returned? */
-
-rnb_err_t RNBRemote::HandlePacket_g(const char *p) {
- std::ostringstream ostrm;
- if (!m_ctx.HasValidProcessID()) {
- return SendPacket("E11");
- }
-
- if (g_num_reg_entries == 0)
- InitializeRegisters();
-
- nub_process_t pid = m_ctx.ProcessID();
- nub_thread_t tid = ExtractThreadIDFromThreadSuffix(p + 1);
- if (tid == INVALID_NUB_THREAD)
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "No thread specified in p packet");
-
- // Get the register context size first by calling with NULL buffer
- nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0);
- if (reg_ctx_size) {
- // Now allocate enough space for the entire register context
- std::vector<uint8_t> reg_ctx;
- reg_ctx.resize(reg_ctx_size);
- // Now read the register context
- reg_ctx_size =
- DNBThreadGetRegisterContext(pid, tid, &reg_ctx[0], reg_ctx.size());
- if (reg_ctx_size) {
- append_hex_value(ostrm, reg_ctx.data(), reg_ctx.size(), false);
- return SendPacket(ostrm.str());
- }
- }
- return SendPacket("E74");
-}
-
-/* 'G XXX...' -- write registers
- How is the thread for these specified, beyond "the current thread"?
- Does gdb actually use the Hg packet to set this? */
-
-rnb_err_t RNBRemote::HandlePacket_G(const char *p) {
- if (!m_ctx.HasValidProcessID()) {
- return SendPacket("E11");
- }
-
- if (g_num_reg_entries == 0)
- InitializeRegisters();
-
- StdStringExtractor packet(p);
- packet.SetFilePos(1); // Skip the 'G'
-
- nub_process_t pid = m_ctx.ProcessID();
- nub_thread_t tid = ExtractThreadIDFromThreadSuffix(p);
- if (tid == INVALID_NUB_THREAD)
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "No thread specified in p packet");
-
- // Get the register context size first by calling with NULL buffer
- nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0);
- if (reg_ctx_size) {
- // Now allocate enough space for the entire register context
- std::vector<uint8_t> reg_ctx;
- reg_ctx.resize(reg_ctx_size);
-
- const nub_size_t bytes_extracted =
- packet.GetHexBytes(&reg_ctx[0], reg_ctx.size(), 0xcc);
- if (bytes_extracted == reg_ctx.size()) {
- // Now write the register context
- reg_ctx_size =
- DNBThreadSetRegisterContext(pid, tid, reg_ctx.data(), reg_ctx.size());
- if (reg_ctx_size == reg_ctx.size())
- return SendPacket("OK");
- else
- return SendPacket("E55");
- } else {
- DNBLogError("RNBRemote::HandlePacket_G(%s): extracted %llu of %llu "
- "bytes, size mismatch\n",
- p, (uint64_t)bytes_extracted, (uint64_t)reg_ctx_size);
- return SendPacket("E64");
- }
- }
- return SendPacket("E65");
-}
-
-static bool RNBRemoteShouldCancelCallback(void *not_used) {
- RNBRemoteSP remoteSP(g_remoteSP);
- if (remoteSP.get() != NULL) {
- RNBRemote *remote = remoteSP.get();
- return !remote->Comm().IsConnected();
- }
- return true;
-}
-
-// FORMAT: _MXXXXXX,PPP
-// XXXXXX: big endian hex chars
-// PPP: permissions can be any combo of r w x chars
-//
-// RESPONSE: XXXXXX
-// XXXXXX: hex address of the newly allocated memory
-// EXX: error code
-//
-// EXAMPLES:
-// _M123000,rw
-// _M123000,rwx
-// _M123000,xw
-
-rnb_err_t RNBRemote::HandlePacket_AllocateMemory(const char *p) {
- StdStringExtractor packet(p);
- packet.SetFilePos(2); // Skip the "_M"
-
- nub_addr_t size = packet.GetHexMaxU64(StdStringExtractor::BigEndian, 0);
- if (size != 0) {
- if (packet.GetChar() == ',') {
- uint32_t permissions = 0;
- char ch;
- bool success = true;
- while (success && (ch = packet.GetChar()) != '\0') {
- switch (ch) {
- case 'r':
- permissions |= eMemoryPermissionsReadable;
- break;
- case 'w':
- permissions |= eMemoryPermissionsWritable;
- break;
- case 'x':
- permissions |= eMemoryPermissionsExecutable;
- break;
- default:
- success = false;
- break;
- }
- }
-
- if (success) {
- nub_addr_t addr =
- DNBProcessMemoryAllocate(m_ctx.ProcessID(), size, permissions);
- if (addr != INVALID_NUB_ADDRESS) {
- std::ostringstream ostrm;
- ostrm << RAW_HEXBASE << addr;
- return SendPacket(ostrm.str());
- }
- }
- }
- }
- return SendPacket("E53");
-}
-
-// FORMAT: _mXXXXXX
-// XXXXXX: address that was previously allocated
-//
-// RESPONSE: XXXXXX
-// OK: address was deallocated
-// EXX: error code
-//
-// EXAMPLES:
-// _m123000
-
-rnb_err_t RNBRemote::HandlePacket_DeallocateMemory(const char *p) {
- StdStringExtractor packet(p);
- packet.SetFilePos(2); // Skip the "_m"
- nub_addr_t addr =
- packet.GetHexMaxU64(StdStringExtractor::BigEndian, INVALID_NUB_ADDRESS);
-
- if (addr != INVALID_NUB_ADDRESS) {
- if (DNBProcessMemoryDeallocate(m_ctx.ProcessID(), addr))
- return SendPacket("OK");
- }
- return SendPacket("E54");
-}
-
-// FORMAT: QSaveRegisterState;thread:TTTT; (when thread suffix is supported)
-// FORMAT: QSaveRegisterState (when thread suffix is NOT
-// supported)
-// TTTT: thread ID in hex
-//
-// RESPONSE:
-// SAVEID: Where SAVEID is a decimal number that represents the save ID
-// that can be passed back into a "QRestoreRegisterState" packet
-// EXX: error code
-//
-// EXAMPLES:
-// QSaveRegisterState;thread:1E34; (when thread suffix is supported)
-// QSaveRegisterState (when thread suffix is NOT
-// supported)
-
-rnb_err_t RNBRemote::HandlePacket_SaveRegisterState(const char *p) {
- nub_process_t pid = m_ctx.ProcessID();
- nub_thread_t tid = ExtractThreadIDFromThreadSuffix(p);
- if (tid == INVALID_NUB_THREAD) {
- if (m_thread_suffix_supported)
- return HandlePacket_ILLFORMED(
- __FILE__, __LINE__, p,
- "No thread specified in QSaveRegisterState packet");
- else
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "No thread was is set with the Hg packet");
- }
-
- // Get the register context size first by calling with NULL buffer
- const uint32_t save_id = DNBThreadSaveRegisterState(pid, tid);
- if (save_id != 0) {
- char response[64];
- snprintf(response, sizeof(response), "%u", save_id);
- return SendPacket(response);
- } else {
- return SendPacket("E75");
- }
-}
-// FORMAT: QRestoreRegisterState:SAVEID;thread:TTTT; (when thread suffix is
-// supported)
-// FORMAT: QRestoreRegisterState:SAVEID (when thread suffix is NOT
-// supported)
-// TTTT: thread ID in hex
-// SAVEID: a decimal number that represents the save ID that was
-// returned from a call to "QSaveRegisterState"
-//
-// RESPONSE:
-// OK: successfully restored registers for the specified thread
-// EXX: error code
-//
-// EXAMPLES:
-// QRestoreRegisterState:1;thread:1E34; (when thread suffix is
-// supported)
-// QRestoreRegisterState:1 (when thread suffix is NOT
-// supported)
-
-rnb_err_t RNBRemote::HandlePacket_RestoreRegisterState(const char *p) {
- nub_process_t pid = m_ctx.ProcessID();
- nub_thread_t tid = ExtractThreadIDFromThreadSuffix(p);
- if (tid == INVALID_NUB_THREAD) {
- if (m_thread_suffix_supported)
- return HandlePacket_ILLFORMED(
- __FILE__, __LINE__, p,
- "No thread specified in QSaveRegisterState packet");
- else
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "No thread was is set with the Hg packet");
- }
-
- StdStringExtractor packet(p);
- packet.SetFilePos(
- strlen("QRestoreRegisterState:")); // Skip the "QRestoreRegisterState:"
- const uint32_t save_id = packet.GetU32(0);
-
- if (save_id != 0) {
- // Get the register context size first by calling with NULL buffer
- if (DNBThreadRestoreRegisterState(pid, tid, save_id))
- return SendPacket("OK");
- else
- return SendPacket("E77");
- }
- return SendPacket("E76");
-}
-
-static bool GetProcessNameFrom_vAttach(const char *&p,
- std::string &attach_name) {
- bool return_val = true;
- while (*p != '\0') {
- char smallbuf[3];
- smallbuf[0] = *p;
- smallbuf[1] = *(p + 1);
- smallbuf[2] = '\0';
-
- errno = 0;
- int ch = static_cast<int>(strtoul(smallbuf, NULL, 16));
- if (errno != 0 && ch == 0) {
- return_val = false;
- break;
- }
-
- attach_name.push_back(ch);
- p += 2;
- }
- return return_val;
-}
-
-rnb_err_t RNBRemote::HandlePacket_qSupported(const char *p) {
- uint32_t max_packet_size = 128 * 1024; // 128KBytes is a reasonable max packet
- // size--debugger can always use less
- char buf[256];
- snprintf(buf, sizeof(buf), "qXfer:features:read+;PacketSize=%x;qEcho+",
- max_packet_size);
-
- bool enable_compression = false;
- (void)enable_compression;
-
-#if (defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1) \
- || (defined (TARGET_OS_IOS) && TARGET_OS_IOS == 1) \
- || (defined (TARGET_OS_TV) && TARGET_OS_TV == 1) \
- || (defined (TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1)
- enable_compression = true;
-#endif
-
- if (enable_compression) {
- strcat(buf, ";SupportedCompressions=lzfse,zlib-deflate,lz4,lzma;"
- "DefaultCompressionMinSize=");
- char numbuf[16];
- snprintf(numbuf, sizeof(numbuf), "%zu", m_compression_minsize);
- numbuf[sizeof(numbuf) - 1] = '\0';
- strcat(buf, numbuf);
- }
-
- return SendPacket(buf);
-}
-
-/*
- vAttach;pid
-
- Attach to a new process with the specified process ID. pid is a hexadecimal
- integer
- identifying the process. If the stub is currently controlling a process, it is
- killed. The attached process is stopped.This packet is only available in
- extended
- mode (see extended mode).
-
- Reply:
- "ENN" for an error
- "Any Stop Reply Packet" for success
- */
-
-rnb_err_t RNBRemote::HandlePacket_v(const char *p) {
- if (strcmp(p, "vCont;c") == 0) {
- // Simple continue
- return RNBRemote::HandlePacket_c("c");
- } else if (strcmp(p, "vCont;s") == 0) {
- // Simple step
- return RNBRemote::HandlePacket_s("s");
- } else if (strstr(p, "vCont") == p) {
- DNBThreadResumeActions thread_actions;
- char *c = const_cast<char *>(p += strlen("vCont"));
- char *c_end = c + strlen(c);
- if (*c == '?')
- return SendPacket("vCont;c;C;s;S");
-
- while (c < c_end && *c == ';') {
- ++c; // Skip the semi-colon
- DNBThreadResumeAction thread_action;
- thread_action.tid = INVALID_NUB_THREAD;
- thread_action.state = eStateInvalid;
- thread_action.signal = 0;
- thread_action.addr = INVALID_NUB_ADDRESS;
-
- char action = *c++;
-
- switch (action) {
- case 'C':
- errno = 0;
- thread_action.signal = static_cast<int>(strtoul(c, &c, 16));
- if (errno != 0)
- return HandlePacket_ILLFORMED(
- __FILE__, __LINE__, p, "Could not parse signal in vCont packet");
- // Fall through to next case...
- [[clang::fallthrough]];
- case 'c':
- // Continue
- thread_action.state = eStateRunning;
- break;
-
- case 'S':
- errno = 0;
- thread_action.signal = static_cast<int>(strtoul(c, &c, 16));
- if (errno != 0)
- return HandlePacket_ILLFORMED(
- __FILE__, __LINE__, p, "Could not parse signal in vCont packet");
- // Fall through to next case...
- [[clang::fallthrough]];
- case 's':
- // Step
- thread_action.state = eStateStepping;
- break;
-
- default:
- HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "Unsupported action in vCont packet");
- break;
- }
- if (*c == ':') {
- errno = 0;
- thread_action.tid = strtoul(++c, &c, 16);
- if (errno != 0)
- return HandlePacket_ILLFORMED(
- __FILE__, __LINE__, p,
- "Could not parse thread number in vCont packet");
- }
-
- thread_actions.Append(thread_action);
- }
-
- // If a default action for all other threads wasn't mentioned
- // then we should stop the threads
- thread_actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0);
- DNBProcessResume(m_ctx.ProcessID(), thread_actions.GetFirst(),
- thread_actions.GetSize());
- return rnb_success;
- } else if (strstr(p, "vAttach") == p) {
- nub_process_t attach_pid =
- INVALID_NUB_PROCESS; // attach_pid will be set to 0 if the attach fails
- nub_process_t pid_attaching_to =
- INVALID_NUB_PROCESS; // pid_attaching_to is the original pid specified
- char err_str[1024] = {'\0'};
- std::string attach_name;
-
- if (strstr(p, "vAttachWait;") == p) {
- p += strlen("vAttachWait;");
- if (!GetProcessNameFrom_vAttach(p, attach_name)) {
- return HandlePacket_ILLFORMED(
- __FILE__, __LINE__, p, "non-hex char in arg on 'vAttachWait' pkt");
- }
- const bool ignore_existing = true;
- attach_pid = DNBProcessAttachWait(
- attach_name.c_str(), m_ctx.LaunchFlavor(), ignore_existing, NULL,
- 1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback);
-
- } else if (strstr(p, "vAttachOrWait;") == p) {
- p += strlen("vAttachOrWait;");
- if (!GetProcessNameFrom_vAttach(p, attach_name)) {
- return HandlePacket_ILLFORMED(
- __FILE__, __LINE__, p,
- "non-hex char in arg on 'vAttachOrWait' pkt");
- }
- const bool ignore_existing = false;
- attach_pid = DNBProcessAttachWait(
- attach_name.c_str(), m_ctx.LaunchFlavor(), ignore_existing, NULL,
- 1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback);
- } else if (strstr(p, "vAttachName;") == p) {
- p += strlen("vAttachName;");
- if (!GetProcessNameFrom_vAttach(p, attach_name)) {
- return HandlePacket_ILLFORMED(
- __FILE__, __LINE__, p, "non-hex char in arg on 'vAttachName' pkt");
- }
-
- attach_pid = DNBProcessAttachByName(attach_name.c_str(), NULL, err_str,
- sizeof(err_str));
-
- } else if (strstr(p, "vAttach;") == p) {
- p += strlen("vAttach;");
- char *end = NULL;
- pid_attaching_to = static_cast<int>(
- strtoul(p, &end, 16)); // PID will be in hex, so use base 16 to decode
- if (p != end && *end == '\0') {
- // Wait at most 30 second for attach
- struct timespec attach_timeout_abstime;
- DNBTimer::OffsetTimeOfDay(&attach_timeout_abstime, 30, 0);
- attach_pid = DNBProcessAttach(pid_attaching_to, &attach_timeout_abstime,
- err_str, sizeof(err_str));
- }
- } else {
- return HandlePacket_UNIMPLEMENTED(p);
- }
-
- if (attach_pid != INVALID_NUB_PROCESS) {
- if (m_ctx.ProcessID() != attach_pid)
- m_ctx.SetProcessID(attach_pid);
- // Send a stop reply packet to indicate we successfully attached!
- NotifyThatProcessStopped();
- return rnb_success;
- } else {
- m_ctx.LaunchStatus().SetError(-1, DNBError::Generic);
- if (err_str[0])
- m_ctx.LaunchStatus().SetErrorString(err_str);
- else
- m_ctx.LaunchStatus().SetErrorString("attach failed");
-
-#if defined(__APPLE__) && \
- (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101000)
- if (pid_attaching_to == INVALID_NUB_PROCESS && !attach_name.empty()) {
- pid_attaching_to = DNBProcessGetPIDByName(attach_name.c_str());
- }
- if (pid_attaching_to != INVALID_NUB_PROCESS &&
- strcmp(err_str, "No such process") != 0) {
- // csr_check(CSR_ALLOW_TASK_FOR_PID) will be nonzero if System Integrity
- // Protection is in effect.
- if (csr_check(CSR_ALLOW_TASK_FOR_PID) != 0) {
- bool attach_failed_due_to_sip = false;
-
- if (rootless_allows_task_for_pid(pid_attaching_to) == 0) {
- attach_failed_due_to_sip = true;
- }
-
- if (!attach_failed_due_to_sip) {
- int csops_flags = 0;
- int retval = ::csops(pid_attaching_to, CS_OPS_STATUS, &csops_flags,
- sizeof(csops_flags));
- if (retval != -1 && (csops_flags & CS_RESTRICT)) {
- attach_failed_due_to_sip = true;
- }
- }
- if (attach_failed_due_to_sip) {
- SendPacket("E87"); // E87 is the magic value which says that we are
- // not allowed to attach
- DNBLogError("Attach failed because process does not allow "
- "attaching: \"%s\".",
- err_str);
- return rnb_err;
- }
- }
- }
-
-#endif
-
- SendPacket("E01"); // E01 is our magic error value for attach failed.
- DNBLogError("Attach failed: \"%s\".", err_str);
- return rnb_err;
- }
- }
-
- // All other failures come through here
- return HandlePacket_UNIMPLEMENTED(p);
-}
-
-/* 'T XX' -- status of thread
- Check if the specified thread is alive.
- The thread number is in hex? */
-
-rnb_err_t RNBRemote::HandlePacket_T(const char *p) {
- p++;
- if (p == NULL || *p == '\0') {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "No thread specified in T packet");
- }
- if (!m_ctx.HasValidProcessID()) {
- return SendPacket("E15");
- }
- errno = 0;
- nub_thread_t tid = strtoul(p, NULL, 16);
- if (errno != 0 && tid == 0) {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "Could not parse thread number in T packet");
- }
-
- nub_state_t state = DNBThreadGetState(m_ctx.ProcessID(), tid);
- if (state == eStateInvalid || state == eStateExited ||
- state == eStateCrashed) {
- return SendPacket("E16");
- }
-
- return SendPacket("OK");
-}
-
-rnb_err_t RNBRemote::HandlePacket_z(const char *p) {
- if (p == NULL || *p == '\0')
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "No thread specified in z packet");
-
- if (!m_ctx.HasValidProcessID())
- return SendPacket("E15");
-
- char packet_cmd = *p++;
- char break_type = *p++;
-
- if (*p++ != ',')
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "Comma separator missing in z packet");
-
- char *c = NULL;
- nub_process_t pid = m_ctx.ProcessID();
- errno = 0;
- nub_addr_t addr = strtoull(p, &c, 16);
- if (errno != 0 && addr == 0)
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "Invalid address in z packet");
- p = c;
- if (*p++ != ',')
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "Comma separator missing in z packet");
-
- errno = 0;
- auto byte_size = strtoul(p, &c, 16);
- if (errno != 0 && byte_size == 0)
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "Invalid length in z packet");
-
- if (packet_cmd == 'Z') {
- // set
- switch (break_type) {
- case '0': // set software breakpoint
- case '1': // set hardware breakpoint
- {
- // gdb can send multiple Z packets for the same address and
- // these calls must be ref counted.
- bool hardware = (break_type == '1');
-
- if (DNBBreakpointSet(pid, addr, byte_size, hardware)) {
- // We successfully created a breakpoint, now lets full out
- // a ref count structure with the breakID and add it to our
- // map.
- return SendPacket("OK");
- } else {
- // We failed to set the software breakpoint
- return SendPacket("E09");
- }
- } break;
-
- case '2': // set write watchpoint
- case '3': // set read watchpoint
- case '4': // set access watchpoint
- {
- bool hardware = true;
- uint32_t watch_flags = 0;
- if (break_type == '2')
- watch_flags = WATCH_TYPE_WRITE;
- else if (break_type == '3')
- watch_flags = WATCH_TYPE_READ;
- else
- watch_flags = WATCH_TYPE_READ | WATCH_TYPE_WRITE;
-
- if (DNBWatchpointSet(pid, addr, byte_size, watch_flags, hardware)) {
- return SendPacket("OK");
- } else {
- // We failed to set the watchpoint
- return SendPacket("E09");
- }
- } break;
-
- default:
- break;
- }
- } else if (packet_cmd == 'z') {
- // remove
- switch (break_type) {
- case '0': // remove software breakpoint
- case '1': // remove hardware breakpoint
- if (DNBBreakpointClear(pid, addr)) {
- return SendPacket("OK");
- } else {
- return SendPacket("E08");
- }
- break;
-
- case '2': // remove write watchpoint
- case '3': // remove read watchpoint
- case '4': // remove access watchpoint
- if (DNBWatchpointClear(pid, addr)) {
- return SendPacket("OK");
- } else {
- return SendPacket("E08");
- }
- break;
-
- default:
- break;
- }
- }
- return HandlePacket_UNIMPLEMENTED(p);
-}
-
-// Extract the thread number from the thread suffix that might be appended to
-// thread specific packets. This will only be enabled if
-// m_thread_suffix_supported
-// is true.
-nub_thread_t RNBRemote::ExtractThreadIDFromThreadSuffix(const char *p) {
- if (m_thread_suffix_supported) {
- nub_thread_t tid = INVALID_NUB_THREAD;
- if (p) {
- const char *tid_cstr = strstr(p, "thread:");
- if (tid_cstr) {
- tid_cstr += strlen("thread:");
- tid = strtoul(tid_cstr, NULL, 16);
- }
- }
- return tid;
- }
- return GetCurrentThread();
-}
-
-/* 'p XX'
- print the contents of register X */
-
-rnb_err_t RNBRemote::HandlePacket_p(const char *p) {
- if (g_num_reg_entries == 0)
- InitializeRegisters();
-
- if (p == NULL || *p == '\0') {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "No thread specified in p packet");
- }
- if (!m_ctx.HasValidProcessID()) {
- return SendPacket("E15");
- }
- nub_process_t pid = m_ctx.ProcessID();
- errno = 0;
- char *tid_cstr = NULL;
- uint32_t reg = static_cast<uint32_t>(strtoul(p + 1, &tid_cstr, 16));
- if (errno != 0 && reg == 0) {
- return HandlePacket_ILLFORMED(
- __FILE__, __LINE__, p, "Could not parse register number in p packet");
- }
-
- nub_thread_t tid = ExtractThreadIDFromThreadSuffix(tid_cstr);
- if (tid == INVALID_NUB_THREAD)
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "No thread specified in p packet");
-
- const register_map_entry_t *reg_entry;
-
- if (reg < g_num_reg_entries)
- reg_entry = &g_reg_entries[reg];
- else
- reg_entry = NULL;
-
- std::ostringstream ostrm;
- if (reg_entry == NULL) {
- DNBLogError(
- "RNBRemote::HandlePacket_p(%s): unknown register number %u requested\n",
- p, reg);
- ostrm << "00000000";
- } else if (reg_entry->nub_info.reg == (uint32_t)-1) {
- if (reg_entry->nub_info.size > 0) {
- std::basic_string<uint8_t> zeros(reg_entry->nub_info.size, '\0');
- append_hex_value(ostrm, zeros.data(), zeros.size(), false);
- }
- } else {
- register_value_in_hex_fixed_width(ostrm, pid, tid, reg_entry, NULL);
- }
- return SendPacket(ostrm.str());
-}
-
-/* 'Pnn=rrrrr'
- Set register number n to value r.
- n and r are hex strings. */
-
-rnb_err_t RNBRemote::HandlePacket_P(const char *p) {
- if (g_num_reg_entries == 0)
- InitializeRegisters();
-
- if (p == NULL || *p == '\0') {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, "Empty P packet");
- }
- if (!m_ctx.HasValidProcessID()) {
- return SendPacket("E28");
- }
-
- nub_process_t pid = m_ctx.ProcessID();
-
- StdStringExtractor packet(p);
-
- const char cmd_char = packet.GetChar();
- // Register ID is always in big endian
- const uint32_t reg = packet.GetHexMaxU32(false, UINT32_MAX);
- const char equal_char = packet.GetChar();
-
- if (cmd_char != 'P')
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "Improperly formed P packet");
-
- if (reg == UINT32_MAX)
- return SendPacket("E29");
-
- if (equal_char != '=')
- return SendPacket("E30");
-
- const register_map_entry_t *reg_entry;
-
- if (reg >= g_num_reg_entries)
- return SendPacket("E47");
-
- reg_entry = &g_reg_entries[reg];
-
- if (reg_entry->nub_info.set == (uint32_t)-1 &&
- reg_entry->nub_info.reg == (uint32_t)-1) {
- DNBLogError(
- "RNBRemote::HandlePacket_P(%s): unknown register number %u requested\n",
- p, reg);
- return SendPacket("E48");
- }
-
- DNBRegisterValue reg_value;
- reg_value.info = reg_entry->nub_info;
- packet.GetHexBytes(reg_value.value.v_sint8, reg_entry->nub_info.size, 0xcc);
-
- nub_thread_t tid = ExtractThreadIDFromThreadSuffix(p);
- if (tid == INVALID_NUB_THREAD)
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "No thread specified in p packet");
-
- if (!DNBThreadSetRegisterValueByID(pid, tid, reg_entry->nub_info.set,
- reg_entry->nub_info.reg, &reg_value)) {
- return SendPacket("E32");
- }
- return SendPacket("OK");
-}
-
-/* 'c [addr]'
- Continue, optionally from a specified address. */
-
-rnb_err_t RNBRemote::HandlePacket_c(const char *p) {
- const nub_process_t pid = m_ctx.ProcessID();
-
- if (pid == INVALID_NUB_PROCESS)
- return SendPacket("E23");
-
- DNBThreadResumeAction action = {INVALID_NUB_THREAD, eStateRunning, 0,
- INVALID_NUB_ADDRESS};
-
- if (*(p + 1) != '\0') {
- action.tid = GetContinueThread();
- errno = 0;
- action.addr = strtoull(p + 1, NULL, 16);
- if (errno != 0 && action.addr == 0)
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "Could not parse address in c packet");
- }
-
- DNBThreadResumeActions thread_actions;
- thread_actions.Append(action);
- thread_actions.SetDefaultThreadActionIfNeeded(eStateRunning, 0);
- if (!DNBProcessResume(pid, thread_actions.GetFirst(),
- thread_actions.GetSize()))
- return SendPacket("E25");
- // Don't send an "OK" packet; response is the stopped/exited message.
- return rnb_success;
-}
-
-rnb_err_t RNBRemote::HandlePacket_MemoryRegionInfo(const char *p) {
- /* This packet will find memory attributes (e.g. readable, writable,
- executable, stack, jitted code)
- for the memory region containing a given address and return that
- information.
-
- Users of this packet must be prepared for three results:
-
- Region information is returned
- Region information is unavailable for this address because the address
- is in unmapped memory
- Region lookup cannot be performed on this platform or process is not
- yet launched
- This packet isn't implemented
-
- Examples of use:
- qMemoryRegionInfo:3a55140
- start:3a50000,size:100000,permissions:rwx
-
- qMemoryRegionInfo:0
- error:address in unmapped region
-
- qMemoryRegionInfo:3a551140 (on a different platform)
- error:region lookup cannot be performed
-
- qMemoryRegionInfo
- OK // this packet is implemented by the remote nub
- */
-
- p += sizeof("qMemoryRegionInfo") - 1;
- if (*p == '\0')
- return SendPacket("OK");
- if (*p++ != ':')
- return SendPacket("E67");
- if (*p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X'))
- p += 2;
-
- errno = 0;
- uint64_t address = strtoul(p, NULL, 16);
- if (errno != 0 && address == 0) {
- return HandlePacket_ILLFORMED(
- __FILE__, __LINE__, p, "Invalid address in qMemoryRegionInfo packet");
- }
-
- DNBRegionInfo region_info = {0, 0, 0};
- DNBProcessMemoryRegionInfo(m_ctx.ProcessID(), address, &region_info);
- std::ostringstream ostrm;
-
- // start:3a50000,size:100000,permissions:rwx
- ostrm << "start:" << std::hex << region_info.addr << ';';
-
- if (region_info.size > 0)
- ostrm << "size:" << std::hex << region_info.size << ';';
-
- if (region_info.permissions) {
- ostrm << "permissions:";
-
- if (region_info.permissions & eMemoryPermissionsReadable)
- ostrm << 'r';
- if (region_info.permissions & eMemoryPermissionsWritable)
- ostrm << 'w';
- if (region_info.permissions & eMemoryPermissionsExecutable)
- ostrm << 'x';
- ostrm << ';';
- }
- return SendPacket(ostrm.str());
-}
-
-// qGetProfileData;scan_type:0xYYYYYYY
-rnb_err_t RNBRemote::HandlePacket_GetProfileData(const char *p) {
- nub_process_t pid = m_ctx.ProcessID();
- if (pid == INVALID_NUB_PROCESS)
- return SendPacket("OK");
-
- StdStringExtractor packet(p += sizeof("qGetProfileData"));
- DNBProfileDataScanType scan_type = eProfileAll;
- std::string name;
- std::string value;
- while (packet.GetNameColonValue(name, value)) {
- if (name == "scan_type") {
- std::istringstream iss(value);
- uint32_t int_value = 0;
- if (iss >> std::hex >> int_value) {
- scan_type = (DNBProfileDataScanType)int_value;
- }
- }
- }
-
- std::string data = DNBProcessGetProfileData(pid, scan_type);
- if (!data.empty()) {
- return SendPacket(data.c_str());
- } else {
- return SendPacket("OK");
- }
-}
-
-// QSetEnableAsyncProfiling;enable:[0|1]:interval_usec:XXXXXX;scan_type:0xYYYYYYY
-rnb_err_t RNBRemote::HandlePacket_SetEnableAsyncProfiling(const char *p) {
- nub_process_t pid = m_ctx.ProcessID();
- if (pid == INVALID_NUB_PROCESS)
- return SendPacket("OK");
-
- StdStringExtractor packet(p += sizeof("QSetEnableAsyncProfiling"));
- bool enable = false;
- uint64_t interval_usec = 0;
- DNBProfileDataScanType scan_type = eProfileAll;
- std::string name;
- std::string value;
- while (packet.GetNameColonValue(name, value)) {
- if (name == "enable") {
- enable = strtoul(value.c_str(), NULL, 10) > 0;
- } else if (name == "interval_usec") {
- interval_usec = strtoul(value.c_str(), NULL, 10);
- } else if (name == "scan_type") {
- std::istringstream iss(value);
- uint32_t int_value = 0;
- if (iss >> std::hex >> int_value) {
- scan_type = (DNBProfileDataScanType)int_value;
- }
- }
- }
-
- if (interval_usec == 0) {
- enable = 0;
- }
-
- DNBProcessSetEnableAsyncProfiling(pid, enable, interval_usec, scan_type);
- return SendPacket("OK");
-}
-
-// QEnableCompression:type:<COMPRESSION-TYPE>;minsize:<MINIMUM PACKET SIZE TO
-// COMPRESS>;
-//
-// type: must be a type previously reported by the qXfer:features:
-// SupportedCompressions list
-//
-// minsize: is optional; by default the qXfer:features:
-// DefaultCompressionMinSize value is used
-// debugserver may have a better idea of what a good minimum packet size to
-// compress is than lldb.
-
-rnb_err_t RNBRemote::HandlePacket_QEnableCompression(const char *p) {
- p += sizeof("QEnableCompression:") - 1;
-
- size_t new_compression_minsize = m_compression_minsize;
- const char *new_compression_minsize_str = strstr(p, "minsize:");
- if (new_compression_minsize_str) {
- new_compression_minsize_str += strlen("minsize:");
- errno = 0;
- new_compression_minsize = strtoul(new_compression_minsize_str, NULL, 10);
- if (errno != 0 || new_compression_minsize == ULONG_MAX) {
- new_compression_minsize = m_compression_minsize;
- }
- }
-
- if (strstr(p, "type:zlib-deflate;") != nullptr) {
- EnableCompressionNextSendPacket(compression_types::zlib_deflate);
- m_compression_minsize = new_compression_minsize;
- return SendPacket("OK");
- } else if (strstr(p, "type:lz4;") != nullptr) {
- EnableCompressionNextSendPacket(compression_types::lz4);
- m_compression_minsize = new_compression_minsize;
- return SendPacket("OK");
- } else if (strstr(p, "type:lzma;") != nullptr) {
- EnableCompressionNextSendPacket(compression_types::lzma);
- m_compression_minsize = new_compression_minsize;
- return SendPacket("OK");
- } else if (strstr(p, "type:lzfse;") != nullptr) {
- EnableCompressionNextSendPacket(compression_types::lzfse);
- m_compression_minsize = new_compression_minsize;
- return SendPacket("OK");
- }
-
- return SendPacket("E88");
-}
-
-rnb_err_t RNBRemote::HandlePacket_qSpeedTest(const char *p) {
- p += strlen("qSpeedTest:response_size:");
- char *end = NULL;
- errno = 0;
- uint64_t response_size = ::strtoul(p, &end, 16);
- if (errno != 0)
- return HandlePacket_ILLFORMED(
- __FILE__, __LINE__, p,
- "Didn't find response_size value at right offset");
- else if (*end == ';') {
- static char g_data[4 * 1024 * 1024 + 16] = "data:";
- memset(g_data + 5, 'a', response_size);
- g_data[response_size + 5] = '\0';
- return SendPacket(g_data);
- } else {
- return SendPacket("E79");
- }
-}
-
-rnb_err_t RNBRemote::HandlePacket_WatchpointSupportInfo(const char *p) {
- /* This packet simply returns the number of supported hardware watchpoints.
-
- Examples of use:
- qWatchpointSupportInfo:
- num:4
-
- qWatchpointSupportInfo
- OK // this packet is implemented by the remote nub
- */
-
- p += sizeof("qWatchpointSupportInfo") - 1;
- if (*p == '\0')
- return SendPacket("OK");
- if (*p++ != ':')
- return SendPacket("E67");
-
- errno = 0;
- uint32_t num = DNBWatchpointGetNumSupportedHWP(m_ctx.ProcessID());
- std::ostringstream ostrm;
-
- // size:4
- ostrm << "num:" << std::dec << num << ';';
- return SendPacket(ostrm.str());
-}
-
-/* 'C sig [;addr]'
- Resume with signal sig, optionally at address addr. */
-
-rnb_err_t RNBRemote::HandlePacket_C(const char *p) {
- const nub_process_t pid = m_ctx.ProcessID();
-
- if (pid == INVALID_NUB_PROCESS)
- return SendPacket("E36");
-
- DNBThreadResumeAction action = {INVALID_NUB_THREAD, eStateRunning, 0,
- INVALID_NUB_ADDRESS};
- int process_signo = -1;
- if (*(p + 1) != '\0') {
- action.tid = GetContinueThread();
- char *end = NULL;
- errno = 0;
- process_signo = static_cast<int>(strtoul(p + 1, &end, 16));
- if (errno != 0)
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "Could not parse signal in C packet");
- else if (*end == ';') {
- errno = 0;
- action.addr = strtoull(end + 1, NULL, 16);
- if (errno != 0 && action.addr == 0)
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "Could not parse address in C packet");
- }
- }
-
- DNBThreadResumeActions thread_actions;
- thread_actions.Append(action);
- thread_actions.SetDefaultThreadActionIfNeeded(eStateRunning, action.signal);
- if (!DNBProcessSignal(pid, process_signo))
- return SendPacket("E52");
- if (!DNBProcessResume(pid, thread_actions.GetFirst(),
- thread_actions.GetSize()))
- return SendPacket("E38");
- /* Don't send an "OK" packet; response is the stopped/exited message. */
- return rnb_success;
-}
-
-//----------------------------------------------------------------------
-// 'D' packet
-// Detach from gdb.
-//----------------------------------------------------------------------
-rnb_err_t RNBRemote::HandlePacket_D(const char *p) {
- if (m_ctx.HasValidProcessID()) {
- if (DNBProcessDetach(m_ctx.ProcessID()))
- SendPacket("OK");
- else
- SendPacket("E");
- } else {
- SendPacket("E");
- }
- return rnb_success;
-}
-
-/* 'k'
- Kill the inferior process. */
-
-rnb_err_t RNBRemote::HandlePacket_k(const char *p) {
- DNBLog("Got a 'k' packet, killing the inferior process.");
- // No response to should be sent to the kill packet
- if (m_ctx.HasValidProcessID())
- DNBProcessKill(m_ctx.ProcessID());
- SendPacket("X09");
- return rnb_success;
-}
-
-rnb_err_t RNBRemote::HandlePacket_stop_process(const char *p) {
-//#define TEST_EXIT_ON_INTERRUPT // This should only be uncommented to test
-//exiting on interrupt
-#if defined(TEST_EXIT_ON_INTERRUPT)
- rnb_err_t err = HandlePacket_k(p);
- m_comm.Disconnect(true);
- return err;
-#else
- if (!DNBProcessInterrupt(m_ctx.ProcessID())) {
- // If we failed to interrupt the process, then send a stop
- // reply packet as the process was probably already stopped
- DNBLogThreaded("RNBRemote::HandlePacket_stop_process() sending extra stop "
- "reply because DNBProcessInterrupt returned false");
- HandlePacket_last_signal(NULL);
- }
- return rnb_success;
-#endif
-}
-
-/* 's'
- Step the inferior process. */
-
-rnb_err_t RNBRemote::HandlePacket_s(const char *p) {
- const nub_process_t pid = m_ctx.ProcessID();
- if (pid == INVALID_NUB_PROCESS)
- return SendPacket("E32");
-
- // Hardware supported stepping not supported on arm
- nub_thread_t tid = GetContinueThread();
- if (tid == 0 || tid == (nub_thread_t)-1)
- tid = GetCurrentThread();
-
- if (tid == INVALID_NUB_THREAD)
- return SendPacket("E33");
-
- DNBThreadResumeActions thread_actions;
- thread_actions.AppendAction(tid, eStateStepping);
-
- // Make all other threads stop when we are stepping
- thread_actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0);
- if (!DNBProcessResume(pid, thread_actions.GetFirst(),
- thread_actions.GetSize()))
- return SendPacket("E49");
- // Don't send an "OK" packet; response is the stopped/exited message.
- return rnb_success;
-}
-
-/* 'S sig [;addr]'
- Step with signal sig, optionally at address addr. */
-
-rnb_err_t RNBRemote::HandlePacket_S(const char *p) {
- const nub_process_t pid = m_ctx.ProcessID();
- if (pid == INVALID_NUB_PROCESS)
- return SendPacket("E36");
-
- DNBThreadResumeAction action = {INVALID_NUB_THREAD, eStateStepping, 0,
- INVALID_NUB_ADDRESS};
-
- if (*(p + 1) != '\0') {
- char *end = NULL;
- errno = 0;
- action.signal = static_cast<int>(strtoul(p + 1, &end, 16));
- if (errno != 0)
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "Could not parse signal in S packet");
- else if (*end == ';') {
- errno = 0;
- action.addr = strtoull(end + 1, NULL, 16);
- if (errno != 0 && action.addr == 0) {
- return HandlePacket_ILLFORMED(__FILE__, __LINE__, p,
- "Could not parse address in S packet");
- }
- }
- }
-
- action.tid = GetContinueThread();
- if (action.tid == 0 || action.tid == (nub_thread_t)-1)
- return SendPacket("E40");
-
- nub_state_t tstate = DNBThreadGetState(pid, action.tid);
- if (tstate == eStateInvalid || tstate == eStateExited)
- return SendPacket("E37");
-
- DNBThreadResumeActions thread_actions;
- thread_actions.Append(action);
-
- // Make all other threads stop when we are stepping
- thread_actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0);
- if (!DNBProcessResume(pid, thread_actions.GetFirst(),
- thread_actions.GetSize()))
- return SendPacket("E39");
-
- // Don't send an "OK" packet; response is the stopped/exited message.
- return rnb_success;
-}
-
-static const char *GetArchName(const uint32_t cputype,
- const uint32_t cpusubtype) {
- switch (cputype) {
- case CPU_TYPE_ARM:
- switch (cpusubtype) {
- case 5:
- return "armv4";
- case 6:
- return "armv6";
- case 7:
- return "armv5t";
- case 8:
- return "xscale";
- case 9:
- return "armv7";
- case 10:
- return "armv7f";
- case 11:
- return "armv7s";
- case 12:
- return "armv7k";
- case 14:
- return "armv6m";
- case 15:
- return "armv7m";
- case 16:
- return "armv7em";
- default:
- return "arm";
- }
- break;
- case CPU_TYPE_ARM64:
- return "arm64";
- case CPU_TYPE_I386:
- return "i386";
- case CPU_TYPE_X86_64:
- switch (cpusubtype) {
- default:
- return "x86_64";
- case 8:
- return "x86_64h";
- }
- break;
- }
- return NULL;
-}
-
-static bool GetHostCPUType(uint32_t &cputype, uint32_t &cpusubtype,
- uint32_t &is_64_bit_capable, bool &promoted_to_64) {
- static uint32_t g_host_cputype = 0;
- static uint32_t g_host_cpusubtype = 0;
- static uint32_t g_is_64_bit_capable = 0;
- static bool g_promoted_to_64 = false;
-
- if (g_host_cputype == 0) {
- g_promoted_to_64 = false;
- size_t len = sizeof(uint32_t);
- if (::sysctlbyname("hw.cputype", &g_host_cputype, &len, NULL, 0) == 0) {
- len = sizeof(uint32_t);
- if (::sysctlbyname("hw.cpu64bit_capable", &g_is_64_bit_capable, &len,
- NULL, 0) == 0) {
- if (g_is_64_bit_capable && ((g_host_cputype & CPU_ARCH_ABI64) == 0)) {
- g_promoted_to_64 = true;
- g_host_cputype |= CPU_ARCH_ABI64;
- }
- }
- }
-
- len = sizeof(uint32_t);
- if (::sysctlbyname("hw.cpusubtype", &g_host_cpusubtype, &len, NULL, 0) ==
- 0) {
- if (g_promoted_to_64 && g_host_cputype == CPU_TYPE_X86_64 &&
- g_host_cpusubtype == CPU_SUBTYPE_486)
- g_host_cpusubtype = CPU_SUBTYPE_X86_64_ALL;
- }
- }
-
- cputype = g_host_cputype;
- cpusubtype = g_host_cpusubtype;
- is_64_bit_capable = g_is_64_bit_capable;
- promoted_to_64 = g_promoted_to_64;
- return g_host_cputype != 0;
-}
-
-rnb_err_t RNBRemote::HandlePacket_qHostInfo(const char *p) {
- std::ostringstream strm;
-
- uint32_t cputype = 0;
- uint32_t cpusubtype = 0;
- uint32_t is_64_bit_capable = 0;
- bool promoted_to_64 = false;
- if (GetHostCPUType(cputype, cpusubtype, is_64_bit_capable, promoted_to_64)) {
- strm << "cputype:" << std::dec << cputype << ';';
- strm << "cpusubtype:" << std::dec << 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 || cputype == CPU_TYPE_ARM64) {
-#if defined(TARGET_OS_TV) && TARGET_OS_TV == 1
- strm << "ostype:tvos;";
-#elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
- strm << "ostype:watchos;";
-#elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1
- strm << "ostype:bridgeos;";
-#else
- strm << "ostype:ios;";
-#endif
-
- // On armv7 we use "synchronous" watchpoints which means the exception is
- // delivered before the instruction executes.
- strm << "watchpoint_exceptions_received:before;";
- } else {
- strm << "ostype:macosx;";
- strm << "watchpoint_exceptions_received:after;";
- }
- // char ostype[64];
- // len = sizeof(ostype);
- // if (::sysctlbyname("kern.ostype", &ostype, &len, NULL, 0) == 0)
- // {
- // len = strlen(ostype);
- // std::transform (ostype, ostype + len, ostype, tolower);
- // strm << "ostype:" << std::dec << ostype << ';';
- // }
-
- strm << "vendor:apple;";
-
- uint64_t major, minor, patch;
- if (DNBGetOSVersionNumbers(&major, &minor, &patch)) {
- strm << "os_version:" << major << "." << minor;
- if (patch != UINT64_MAX)
- strm << "." << patch;
- strm << ";";
- }
-
-#if defined(__LITTLE_ENDIAN__)
- strm << "endian:little;";
-#elif defined(__BIG_ENDIAN__)
- strm << "endian:big;";
-#elif defined(__PDP_ENDIAN__)
- strm << "endian:pdp;";
-#endif
-
- if (promoted_to_64)
- strm << "ptrsize:8;";
- else
- strm << "ptrsize:" << std::dec << sizeof(void *) << ';';
-
-#if defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
- strm << "default_packet_timeout:10;";
-#endif
-
- return SendPacket(strm.str());
-}
-
-void XMLElementStart(std::ostringstream &s, uint32_t indent, const char *name,
- bool has_attributes) {
- if (indent)
- s << INDENT_WITH_SPACES(indent);
- s << '<' << name;
- if (!has_attributes)
- s << '>' << std::endl;
-}
-
-void XMLElementStartEndAttributes(std::ostringstream &s, bool empty) {
- if (empty)
- s << '/';
- s << '>' << std::endl;
-}
-
-void XMLElementEnd(std::ostringstream &s, uint32_t indent, const char *name) {
- if (indent)
- s << INDENT_WITH_SPACES(indent);
- s << '<' << '/' << name << '>' << std::endl;
-}
-
-void XMLElementWithStringValue(std::ostringstream &s, uint32_t indent,
- const char *name, const char *value,
- bool close = true) {
- if (value) {
- if (indent)
- s << INDENT_WITH_SPACES(indent);
- s << '<' << name << '>' << value;
- if (close)
- XMLElementEnd(s, 0, name);
- }
-}
-
-void XMLElementWithUnsignedValue(std::ostringstream &s, uint32_t indent,
- const char *name, uint64_t value,
- bool close = true) {
- if (indent)
- s << INDENT_WITH_SPACES(indent);
-
- s << '<' << name << '>' << DECIMAL << value;
- if (close)
- XMLElementEnd(s, 0, name);
-}
-
-void XMLAttributeString(std::ostringstream &s, const char *name,
- const char *value, const char *default_value = NULL) {
- if (value) {
- if (default_value && strcmp(value, default_value) == 0)
- return; // No need to emit the attribute because it matches the default
- // value
- s << ' ' << name << "=\"" << value << "\"";
- }
-}
-
-void XMLAttributeUnsignedDecimal(std::ostringstream &s, const char *name,
- uint64_t value) {
- s << ' ' << name << "=\"" << DECIMAL << value << "\"";
-}
-
-void GenerateTargetXMLRegister(std::ostringstream &s, const uint32_t reg_num,
- nub_size_t num_reg_sets,
- const DNBRegisterSetInfo *reg_set_info,
- const register_map_entry_t &reg) {
- const char *default_lldb_encoding = "uint";
- const char *lldb_encoding = default_lldb_encoding;
- const char *gdb_group = "general";
- const char *default_gdb_type = "int";
- const char *gdb_type = default_gdb_type;
- const char *default_lldb_format = "hex";
- const char *lldb_format = default_lldb_format;
- const char *lldb_set = NULL;
-
- switch (reg.nub_info.type) {
- case Uint:
- lldb_encoding = "uint";
- break;
- case Sint:
- lldb_encoding = "sint";
- break;
- case IEEE754:
- lldb_encoding = "ieee754";
- if (reg.nub_info.set > 0)
- gdb_group = "float";
- break;
- case Vector:
- lldb_encoding = "vector";
- if (reg.nub_info.set > 0)
- gdb_group = "vector";
- break;
- }
-
- switch (reg.nub_info.format) {
- case Binary:
- lldb_format = "binary";
- break;
- case Decimal:
- lldb_format = "decimal";
- break;
- case Hex:
- lldb_format = "hex";
- break;
- case Float:
- gdb_type = "float";
- lldb_format = "float";
- break;
- case VectorOfSInt8:
- gdb_type = "float";
- lldb_format = "vector-sint8";
- break;
- case VectorOfUInt8:
- gdb_type = "float";
- lldb_format = "vector-uint8";
- break;
- case VectorOfSInt16:
- gdb_type = "float";
- lldb_format = "vector-sint16";
- break;
- case VectorOfUInt16:
- gdb_type = "float";
- lldb_format = "vector-uint16";
- break;
- case VectorOfSInt32:
- gdb_type = "float";
- lldb_format = "vector-sint32";
- break;
- case VectorOfUInt32:
- gdb_type = "float";
- lldb_format = "vector-uint32";
- break;
- case VectorOfFloat32:
- gdb_type = "float";
- lldb_format = "vector-float32";
- break;
- case VectorOfUInt128:
- gdb_type = "float";
- lldb_format = "vector-uint128";
- break;
- };
- if (reg_set_info && reg.nub_info.set < num_reg_sets)
- lldb_set = reg_set_info[reg.nub_info.set].name;
-
- uint32_t indent = 2;
-
- XMLElementStart(s, indent, "reg", true);
- XMLAttributeString(s, "name", reg.nub_info.name);
- XMLAttributeUnsignedDecimal(s, "regnum", reg_num);
- XMLAttributeUnsignedDecimal(s, "offset", reg.offset);
- XMLAttributeUnsignedDecimal(s, "bitsize", reg.nub_info.size * 8);
- XMLAttributeString(s, "group", gdb_group);
- XMLAttributeString(s, "type", gdb_type, default_gdb_type);
- XMLAttributeString(s, "altname", reg.nub_info.alt);
- XMLAttributeString(s, "encoding", lldb_encoding, default_lldb_encoding);
- XMLAttributeString(s, "format", lldb_format, default_lldb_format);
- XMLAttributeUnsignedDecimal(s, "group_id", reg.nub_info.set);
- if (reg.nub_info.reg_ehframe != INVALID_NUB_REGNUM)
- XMLAttributeUnsignedDecimal(s, "ehframe_regnum", reg.nub_info.reg_ehframe);
- if (reg.nub_info.reg_dwarf != INVALID_NUB_REGNUM)
- XMLAttributeUnsignedDecimal(s, "dwarf_regnum", reg.nub_info.reg_dwarf);
-
- const char *lldb_generic = NULL;
- switch (reg.nub_info.reg_generic) {
- case GENERIC_REGNUM_FP:
- lldb_generic = "fp";
- break;
- case GENERIC_REGNUM_PC:
- lldb_generic = "pc";
- break;
- case GENERIC_REGNUM_SP:
- lldb_generic = "sp";
- break;
- case GENERIC_REGNUM_RA:
- lldb_generic = "ra";
- break;
- case GENERIC_REGNUM_FLAGS:
- lldb_generic = "flags";
- break;
- case GENERIC_REGNUM_ARG1:
- lldb_generic = "arg1";
- break;
- case GENERIC_REGNUM_ARG2:
- lldb_generic = "arg2";
- break;
- case GENERIC_REGNUM_ARG3:
- lldb_generic = "arg3";
- break;
- case GENERIC_REGNUM_ARG4:
- lldb_generic = "arg4";
- break;
- case GENERIC_REGNUM_ARG5:
- lldb_generic = "arg5";
- break;
- case GENERIC_REGNUM_ARG6:
- lldb_generic = "arg6";
- break;
- case GENERIC_REGNUM_ARG7:
- lldb_generic = "arg7";
- break;
- case GENERIC_REGNUM_ARG8:
- lldb_generic = "arg8";
- break;
- default:
- break;
- }
- XMLAttributeString(s, "generic", lldb_generic);
-
- bool empty = reg.value_regnums.empty() && reg.invalidate_regnums.empty();
- if (!empty) {
- if (!reg.value_regnums.empty()) {
- std::ostringstream regnums;
- bool first = true;
- regnums << DECIMAL;
- for (auto regnum : reg.value_regnums) {
- if (!first)
- regnums << ',';
- regnums << regnum;
- first = false;
- }
- XMLAttributeString(s, "value_regnums", regnums.str().c_str());
- }
-
- if (!reg.invalidate_regnums.empty()) {
- std::ostringstream regnums;
- bool first = true;
- regnums << DECIMAL;
- for (auto regnum : reg.invalidate_regnums) {
- if (!first)
- regnums << ',';
- regnums << regnum;
- first = false;
- }
- XMLAttributeString(s, "invalidate_regnums", regnums.str().c_str());
- }
- }
- XMLElementStartEndAttributes(s, true);
-}
-
-void GenerateTargetXMLRegisters(std::ostringstream &s) {
- nub_size_t num_reg_sets = 0;
- const DNBRegisterSetInfo *reg_sets = DNBGetRegisterSetInfo(&num_reg_sets);
-
- uint32_t cputype = DNBGetRegisterCPUType();
- if (cputype) {
- XMLElementStart(s, 0, "feature", true);
- std::ostringstream name_strm;
- name_strm << "com.apple.debugserver." << GetArchName(cputype, 0);
- XMLAttributeString(s, "name", name_strm.str().c_str());
- XMLElementStartEndAttributes(s, false);
- for (uint32_t reg_num = 0; reg_num < g_num_reg_entries; ++reg_num)
- // for (const auto &reg: g_dynamic_register_map)
- {
- GenerateTargetXMLRegister(s, reg_num, num_reg_sets, reg_sets,
- g_reg_entries[reg_num]);
- }
- XMLElementEnd(s, 0, "feature");
-
- if (num_reg_sets > 0) {
- XMLElementStart(s, 0, "groups", false);
- for (uint32_t set = 1; set < num_reg_sets; ++set) {
- XMLElementStart(s, 2, "group", true);
- XMLAttributeUnsignedDecimal(s, "id", set);
- XMLAttributeString(s, "name", reg_sets[set].name);
- XMLElementStartEndAttributes(s, true);
- }
- XMLElementEnd(s, 0, "groups");
- }
- }
-}
-
-static const char *g_target_xml_header = R"(<?xml version="1.0"?>
-<target version="1.0">)";
-
-static const char *g_target_xml_footer = "</target>";
-
-static std::string g_target_xml;
-
-void UpdateTargetXML() {
- std::ostringstream s;
- s << g_target_xml_header << std::endl;
-
- // Set the architecture
- //
- // On raw targets (no OS, vendor info), I've seen replies like
- // <architecture>i386:x86-64</architecture> (for x86_64 systems - from vmware)
- // <architecture>arm</architecture> (for an unspecified arm device - from a Segger JLink)
- // For good interop, I'm not sure what's expected here. e.g. will anyone understand
- // <architecture>x86_64</architecture> ? Or is i386:x86_64 the expected phrasing?
- //
- // s << "<architecture>" << arch "</architecture>" << std::endl;
-
- // Set the OSABI
- // s << "<osabi>abi-name</osabi>"
-
- GenerateTargetXMLRegisters(s);
-
- s << g_target_xml_footer << std::endl;
-
- // Save the XML output in case it gets retrieved in chunks
- g_target_xml = s.str();
-}
-
-rnb_err_t RNBRemote::HandlePacket_qXfer(const char *command) {
- const char *p = command;
- p += strlen("qXfer:");
- const char *sep = strchr(p, ':');
- if (sep) {
- std::string object(p, sep - p); // "auxv", "backtrace", "features", etc
- p = sep + 1;
- sep = strchr(p, ':');
- if (sep) {
- std::string rw(p, sep - p); // "read" or "write"
- p = sep + 1;
- sep = strchr(p, ':');
- if (sep) {
- std::string annex(p, sep - p); // "read" or "write"
-
- p = sep + 1;
- sep = strchr(p, ',');
- if (sep) {
- std::string offset_str(p, sep - p); // read the length as a string
- p = sep + 1;
- std::string length_str(p); // read the offset as a string
- char *end = nullptr;
- const uint64_t offset = strtoul(offset_str.c_str(), &end,
- 16); // convert offset_str to a offset
- if (*end == '\0') {
- const uint64_t length = strtoul(
- length_str.c_str(), &end, 16); // convert length_str to a length
- if (*end == '\0') {
- if (object == "features" && rw == "read" &&
- annex == "target.xml") {
- std::ostringstream xml_out;
-
- if (offset == 0) {
- InitializeRegisters(true);
-
- UpdateTargetXML();
- if (g_target_xml.empty())
- return SendPacket("E83");
-
- if (length > g_target_xml.size()) {
- xml_out << 'l'; // No more data
- xml_out << binary_encode_string(g_target_xml);
- } else {
- xml_out << 'm'; // More data needs to be read with a
- // subsequent call
- xml_out << binary_encode_string(
- std::string(g_target_xml, offset, length));
- }
- } else {
- // Retrieving target XML in chunks
- if (offset < g_target_xml.size()) {
- std::string chunk(g_target_xml, offset, length);
- if (chunk.size() < length)
- xml_out << 'l'; // No more data
- else
- xml_out << 'm'; // More data needs to be read with a
- // subsequent call
- xml_out << binary_encode_string(chunk.data());
- }
- }
- return SendPacket(xml_out.str());
- }
- // Well formed, put not supported
- return HandlePacket_UNIMPLEMENTED(command);
- }
- }
- }
- } else {
- SendPacket("E85");
- }
- } else {
- SendPacket("E86");
- }
- }
- return SendPacket("E82");
-}
-
-rnb_err_t RNBRemote::HandlePacket_qGDBServerVersion(const char *p) {
- std::ostringstream strm;
-
-#if defined(DEBUGSERVER_PROGRAM_NAME)
- strm << "name:" DEBUGSERVER_PROGRAM_NAME ";";
-#else
- strm << "name:debugserver;";
-#endif
- strm << "version:" << DEBUGSERVER_VERSION_NUM << ";";
-
- return SendPacket(strm.str());
-}
-
-// A helper function that retrieves a single integer value from
-// a one-level-deep JSON dictionary of key-value pairs. e.g.
-// jThreadExtendedInfo:{"plo_pthread_tsd_base_address_offset":0,"plo_pthread_tsd_base_offset":224,"plo_pthread_tsd_entry_size":8,"thread":144305}]
-//
-uint64_t get_integer_value_for_key_name_from_json(const char *key,
- const char *json_string) {
- uint64_t retval = INVALID_NUB_ADDRESS;
- std::string key_with_quotes = "\"";
- key_with_quotes += key;
- key_with_quotes += "\"";
- const char *c = strstr(json_string, key_with_quotes.c_str());
- if (c) {
- c += key_with_quotes.size();
-
- while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
- c++;
-
- if (*c == ':') {
- c++;
-
- while (*c != '\0' &&
- (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
- c++;
-
- errno = 0;
- retval = strtoul(c, NULL, 10);
- if (errno != 0) {
- retval = INVALID_NUB_ADDRESS;
- }
- }
- }
- return retval;
-}
-
-// A helper function that retrieves a boolean value from
-// a one-level-deep JSON dictionary of key-value pairs. e.g.
-// jGetLoadedDynamicLibrariesInfos:{"fetch_all_solibs":true}]
-
-// Returns true if it was able to find the key name, and sets the 'value'
-// argument to the value found.
-
-bool get_boolean_value_for_key_name_from_json(const char *key,
- const char *json_string,
- bool &value) {
- std::string key_with_quotes = "\"";
- key_with_quotes += key;
- key_with_quotes += "\"";
- const char *c = strstr(json_string, key_with_quotes.c_str());
- if (c) {
- c += key_with_quotes.size();
-
- while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
- c++;
-
- if (*c == ':') {
- c++;
-
- while (*c != '\0' &&
- (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
- c++;
-
- if (strncmp(c, "true", 4) == 0) {
- value = true;
- return true;
- } else if (strncmp(c, "false", 5) == 0) {
- value = false;
- return true;
- }
- }
- }
- return false;
-}
-
-// A helper function that reads an array of uint64_t's from
-// a one-level-deep JSON dictionary of key-value pairs. e.g.
-// jGetLoadedDynamicLibrariesInfos:{"solib_addrs":[31345823,7768020384,7310483024]}]
-
-// Returns true if it was able to find the key name, false if it did not.
-// "ints" will have all integers found in the array appended to it.
-
-bool get_array_of_ints_value_for_key_name_from_json(
- const char *key, const char *json_string, std::vector<uint64_t> &ints) {
- std::string key_with_quotes = "\"";
- key_with_quotes += key;
- key_with_quotes += "\"";
- const char *c = strstr(json_string, key_with_quotes.c_str());
- if (c) {
- c += key_with_quotes.size();
-
- while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
- c++;
-
- if (*c == ':') {
- c++;
-
- while (*c != '\0' &&
- (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
- c++;
-
- if (*c == '[') {
- c++;
- while (*c != '\0' &&
- (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
- c++;
- while (1) {
- if (!isdigit(*c)) {
- return true;
- }
-
- errno = 0;
- char *endptr;
- uint64_t value = strtoul(c, &endptr, 10);
- if (errno == 0) {
- ints.push_back(value);
- } else {
- break;
- }
- if (endptr == c || endptr == nullptr || *endptr == '\0') {
- break;
- }
- c = endptr;
-
- while (*c != '\0' &&
- (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
- c++;
- if (*c == ',')
- c++;
- while (*c != '\0' &&
- (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
- c++;
- if (*c == ']') {
- return true;
- }
- }
- }
- }
- }
- return false;
-}
-
-JSONGenerator::ObjectSP
-RNBRemote::GetJSONThreadsInfo(bool threads_with_valid_stop_info_only) {
- JSONGenerator::ArraySP threads_array_sp;
- if (m_ctx.HasValidProcessID()) {
- threads_array_sp.reset(new JSONGenerator::Array());
-
- nub_process_t pid = m_ctx.ProcessID();
-
- nub_size_t numthreads = DNBProcessGetNumThreads(pid);
- for (nub_size_t i = 0; i < numthreads; ++i) {
- nub_thread_t tid = DNBProcessGetThreadAtIndex(pid, i);
-
- struct DNBThreadStopInfo tid_stop_info;
-
- const bool stop_info_valid =
- DNBThreadGetStopReason(pid, tid, &tid_stop_info);
-
- // If we are doing stop info only, then we only show threads that have a
- // valid stop reason
- if (threads_with_valid_stop_info_only) {
- if (!stop_info_valid || tid_stop_info.reason == eStopTypeInvalid)
- continue;
- }
-
- JSONGenerator::DictionarySP thread_dict_sp(
- new JSONGenerator::Dictionary());
- thread_dict_sp->AddIntegerItem("tid", tid);
-
- std::string reason_value("none");
-
- if (stop_info_valid) {
- switch (tid_stop_info.reason) {
- case eStopTypeInvalid:
- break;
-
- case eStopTypeSignal:
- if (tid_stop_info.details.signal.signo != 0) {
- thread_dict_sp->AddIntegerItem("signal",
- tid_stop_info.details.signal.signo);
- reason_value = "signal";
- }
- break;
-
- case eStopTypeException:
- if (tid_stop_info.details.exception.type != 0) {
- reason_value = "exception";
- thread_dict_sp->AddIntegerItem(
- "metype", tid_stop_info.details.exception.type);
- JSONGenerator::ArraySP medata_array_sp(new JSONGenerator::Array());
- for (nub_size_t i = 0;
- i < tid_stop_info.details.exception.data_count; ++i) {
- medata_array_sp->AddItem(
- JSONGenerator::IntegerSP(new JSONGenerator::Integer(
- tid_stop_info.details.exception.data[i])));
- }
- thread_dict_sp->AddItem("medata", medata_array_sp);
- }
- break;
-
- case eStopTypeExec:
- reason_value = "exec";
- break;
- }
- }
-
- thread_dict_sp->AddStringItem("reason", reason_value);
-
- if (!threads_with_valid_stop_info_only) {
- const char *thread_name = DNBThreadGetName(pid, tid);
- if (thread_name && thread_name[0])
- thread_dict_sp->AddStringItem("name", thread_name);
-
- thread_identifier_info_data_t thread_ident_info;
- if (DNBThreadGetIdentifierInfo(pid, tid, &thread_ident_info)) {
- if (thread_ident_info.dispatch_qaddr != 0) {
- thread_dict_sp->AddIntegerItem("qaddr",
- thread_ident_info.dispatch_qaddr);
-
- const DispatchQueueOffsets *dispatch_queue_offsets =
- GetDispatchQueueOffsets();
- if (dispatch_queue_offsets) {
- std::string queue_name;
- uint64_t queue_width = 0;
- uint64_t queue_serialnum = 0;
- nub_addr_t dispatch_queue_t = INVALID_NUB_ADDRESS;
- dispatch_queue_offsets->GetThreadQueueInfo(
- pid, thread_ident_info.dispatch_qaddr, dispatch_queue_t,
- queue_name, queue_width, queue_serialnum);
- if (dispatch_queue_t == 0 && queue_name.empty() &&
- queue_serialnum == 0) {
- thread_dict_sp->AddBooleanItem("associated_with_dispatch_queue",
- false);
- } else {
- thread_dict_sp->AddBooleanItem("associated_with_dispatch_queue",
- true);
- }
- if (dispatch_queue_t != INVALID_NUB_ADDRESS &&
- dispatch_queue_t != 0)
- thread_dict_sp->AddIntegerItem("dispatch_queue_t",
- dispatch_queue_t);
- if (!queue_name.empty())
- thread_dict_sp->AddStringItem("qname", queue_name);
- if (queue_width == 1)
- thread_dict_sp->AddStringItem("qkind", "serial");
- else if (queue_width > 1)
- thread_dict_sp->AddStringItem("qkind", "concurrent");
- if (queue_serialnum > 0)
- thread_dict_sp->AddIntegerItem("qserialnum", queue_serialnum);
- }
- }
- }
-
- DNBRegisterValue reg_value;
-
- if (g_reg_entries != NULL) {
- JSONGenerator::DictionarySP registers_dict_sp(
- new JSONGenerator::Dictionary());
-
- for (uint32_t reg = 0; reg < g_num_reg_entries; reg++) {
- // Expedite all registers in the first register set that aren't
- // contained in other registers
- if (g_reg_entries[reg].nub_info.set == 1 &&
- g_reg_entries[reg].nub_info.value_regs == NULL) {
- if (!DNBThreadGetRegisterValueByID(
- pid, tid, g_reg_entries[reg].nub_info.set,
- g_reg_entries[reg].nub_info.reg, &reg_value))
- continue;
-
- std::ostringstream reg_num;
- reg_num << std::dec << g_reg_entries[reg].debugserver_regnum;
- // Encode native byte ordered bytes as hex ascii
- registers_dict_sp->AddBytesAsHexASCIIString(
- reg_num.str(), reg_value.value.v_uint8,
- g_reg_entries[reg].nub_info.size);
- }
- }
- thread_dict_sp->AddItem("registers", registers_dict_sp);
- }
-
- // Add expedited stack memory so stack backtracing doesn't need to read
- // anything from the
- // frame pointer chain.
- StackMemoryMap stack_mmap;
- ReadStackMemory(pid, tid, stack_mmap);
- if (!stack_mmap.empty()) {
- JSONGenerator::ArraySP memory_array_sp(new JSONGenerator::Array());
-
- for (const auto &stack_memory : stack_mmap) {
- JSONGenerator::DictionarySP stack_memory_sp(
- new JSONGenerator::Dictionary());
- stack_memory_sp->AddIntegerItem("address", stack_memory.first);
- stack_memory_sp->AddBytesAsHexASCIIString(
- "bytes", stack_memory.second.bytes, stack_memory.second.length);
- memory_array_sp->AddItem(stack_memory_sp);
- }
- thread_dict_sp->AddItem("memory", memory_array_sp);
- }
- }
-
- threads_array_sp->AddItem(thread_dict_sp);
- }
- }
- return threads_array_sp;
-}
-
-rnb_err_t RNBRemote::HandlePacket_jThreadsInfo(const char *p) {
- JSONGenerator::ObjectSP threads_info_sp;
- std::ostringstream json;
- std::ostringstream reply_strm;
- // If we haven't run the process yet, return an error.
- if (m_ctx.HasValidProcessID()) {
- const bool threads_with_valid_stop_info_only = false;
- JSONGenerator::ObjectSP threads_info_sp =
- GetJSONThreadsInfo(threads_with_valid_stop_info_only);
-
- if (threads_info_sp) {
- std::ostringstream strm;
- threads_info_sp->Dump(strm);
- std::string binary_packet = binary_encode_string(strm.str());
- if (!binary_packet.empty())
- return SendPacket(binary_packet.c_str());
- }
- }
- return SendPacket("E85");
-}
-
-rnb_err_t RNBRemote::HandlePacket_jThreadExtendedInfo(const char *p) {
- nub_process_t pid;
- std::ostringstream json;
- // If we haven't run the process yet, return an error.
- if (!m_ctx.HasValidProcessID()) {
- return SendPacket("E81");
- }
-
- pid = m_ctx.ProcessID();
-
- const char thread_extended_info_str[] = {"jThreadExtendedInfo:{"};
- if (strncmp(p, thread_extended_info_str,
- sizeof(thread_extended_info_str) - 1) == 0) {
- p += strlen(thread_extended_info_str);
-
- uint64_t tid = get_integer_value_for_key_name_from_json("thread", p);
- uint64_t plo_pthread_tsd_base_address_offset =
- get_integer_value_for_key_name_from_json(
- "plo_pthread_tsd_base_address_offset", p);
- uint64_t plo_pthread_tsd_base_offset =
- get_integer_value_for_key_name_from_json("plo_pthread_tsd_base_offset",
- p);
- uint64_t plo_pthread_tsd_entry_size =
- get_integer_value_for_key_name_from_json("plo_pthread_tsd_entry_size",
- p);
- uint64_t dti_qos_class_index =
- get_integer_value_for_key_name_from_json("dti_qos_class_index", p);
-
- if (tid != INVALID_NUB_ADDRESS) {
- nub_addr_t pthread_t_value = DNBGetPThreadT(pid, tid);
-
- uint64_t tsd_address = INVALID_NUB_ADDRESS;
- if (plo_pthread_tsd_entry_size != INVALID_NUB_ADDRESS &&
- plo_pthread_tsd_base_offset != INVALID_NUB_ADDRESS &&
- plo_pthread_tsd_entry_size != INVALID_NUB_ADDRESS) {
- tsd_address = DNBGetTSDAddressForThread(
- pid, tid, plo_pthread_tsd_base_address_offset,
- plo_pthread_tsd_base_offset, plo_pthread_tsd_entry_size);
- }
-
- bool timed_out = false;
- Genealogy::ThreadActivitySP thread_activity_sp;
-
- // If the pthread_t value is invalid, or if we were able to fetch the
- // thread's TSD base
- // and got an invalid value back, then we have a thread in early startup
- // or shutdown and
- // it's possible that gathering the genealogy information for this thread
- // go badly.
- // Ideally fetching this info for a thread in these odd states shouldn't
- // matter - but
- // we've seen some problems with these new SPI and threads in edge-casey
- // states.
-
- double genealogy_fetch_time = 0;
- if (pthread_t_value != INVALID_NUB_ADDRESS &&
- tsd_address != INVALID_NUB_ADDRESS) {
- DNBTimer timer(false);
- thread_activity_sp = DNBGetGenealogyInfoForThread(pid, tid, timed_out);
- genealogy_fetch_time = timer.ElapsedMicroSeconds(false) / 1000000.0;
- }
-
- std::unordered_set<uint32_t>
- process_info_indexes; // an array of the process info #'s seen
-
- json << "{";
-
- bool need_to_print_comma = false;
-
- if (thread_activity_sp && !timed_out) {
- const Genealogy::Activity *activity =
- &thread_activity_sp->current_activity;
- bool need_vouchers_comma_sep = false;
- json << "\"activity_query_timed_out\":false,";
- if (genealogy_fetch_time != 0) {
- // If we append the floating point value with << we'll get it in
- // scientific
- // notation.
- char floating_point_ascii_buffer[64];
- floating_point_ascii_buffer[0] = '\0';
- snprintf(floating_point_ascii_buffer,
- sizeof(floating_point_ascii_buffer), "%f",
- genealogy_fetch_time);
- if (strlen(floating_point_ascii_buffer) > 0) {
- if (need_to_print_comma)
- json << ",";
- need_to_print_comma = true;
- json << "\"activity_query_duration\":"
- << floating_point_ascii_buffer;
- }
- }
- if (activity->activity_id != 0) {
- if (need_to_print_comma)
- json << ",";
- need_to_print_comma = true;
- need_vouchers_comma_sep = true;
- json << "\"activity\":{";
- json << "\"start\":" << activity->activity_start << ",";
- json << "\"id\":" << activity->activity_id << ",";
- json << "\"parent_id\":" << activity->parent_id << ",";
- json << "\"name\":\""
- << json_string_quote_metachars(activity->activity_name) << "\",";
- json << "\"reason\":\""
- << json_string_quote_metachars(activity->reason) << "\"";
- json << "}";
- }
- if (thread_activity_sp->messages.size() > 0) {
- need_to_print_comma = true;
- if (need_vouchers_comma_sep)
- json << ",";
- need_vouchers_comma_sep = true;
- json << "\"trace_messages\":[";
- bool printed_one_message = false;
- for (auto iter = thread_activity_sp->messages.begin();
- iter != thread_activity_sp->messages.end(); ++iter) {
- if (printed_one_message)
- json << ",";
- else
- printed_one_message = true;
- json << "{";
- json << "\"timestamp\":" << iter->timestamp << ",";
- json << "\"activity_id\":" << iter->activity_id << ",";
- json << "\"trace_id\":" << iter->trace_id << ",";
- json << "\"thread\":" << iter->thread << ",";
- json << "\"type\":" << (int)iter->type << ",";
- json << "\"process_info_index\":" << iter->process_info_index
- << ",";
- process_info_indexes.insert(iter->process_info_index);
- json << "\"message\":\""
- << json_string_quote_metachars(iter->message) << "\"";
- json << "}";
- }
- json << "]";
- }
- if (thread_activity_sp->breadcrumbs.size() == 1) {
- need_to_print_comma = true;
- if (need_vouchers_comma_sep)
- json << ",";
- need_vouchers_comma_sep = true;
- json << "\"breadcrumb\":{";
- for (auto iter = thread_activity_sp->breadcrumbs.begin();
- iter != thread_activity_sp->breadcrumbs.end(); ++iter) {
- json << "\"breadcrumb_id\":" << iter->breadcrumb_id << ",";
- json << "\"activity_id\":" << iter->activity_id << ",";
- json << "\"timestamp\":" << iter->timestamp << ",";
- json << "\"name\":\"" << json_string_quote_metachars(iter->name)
- << "\"";
- }
- json << "}";
- }
- if (process_info_indexes.size() > 0) {
- need_to_print_comma = true;
- if (need_vouchers_comma_sep)
- json << ",";
- need_vouchers_comma_sep = true;
- bool printed_one_process_info = false;
- for (auto iter = process_info_indexes.begin();
- iter != process_info_indexes.end(); ++iter) {
- if (printed_one_process_info)
- json << ",";
- Genealogy::ProcessExecutableInfoSP image_info_sp;
- uint32_t idx = *iter;
- image_info_sp = DNBGetGenealogyImageInfo(pid, idx);
- if (image_info_sp) {
- if (!printed_one_process_info) {
- json << "\"process_infos\":[";
- printed_one_process_info = true;
- }
-
- json << "{";
- char uuid_buf[37];
- uuid_unparse_upper(image_info_sp->image_uuid, uuid_buf);
- json << "\"process_info_index\":" << idx << ",";
- json << "\"image_path\":\""
- << json_string_quote_metachars(image_info_sp->image_path)
- << "\",";
- json << "\"image_uuid\":\"" << uuid_buf << "\"";
- json << "}";
- }
- }
- if (printed_one_process_info)
- json << "]";
- }
- } else {
- if (timed_out) {
- if (need_to_print_comma)
- json << ",";
- need_to_print_comma = true;
- json << "\"activity_query_timed_out\":true";
- if (genealogy_fetch_time != 0) {
- // If we append the floating point value with << we'll get it in
- // scientific
- // notation.
- char floating_point_ascii_buffer[64];
- floating_point_ascii_buffer[0] = '\0';
- snprintf(floating_point_ascii_buffer,
- sizeof(floating_point_ascii_buffer), "%f",
- genealogy_fetch_time);
- if (strlen(floating_point_ascii_buffer) > 0) {
- json << ",";
- json << "\"activity_query_duration\":"
- << floating_point_ascii_buffer;
- }
- }
- }
- }
-
- if (tsd_address != INVALID_NUB_ADDRESS) {
- if (need_to_print_comma)
- json << ",";
- need_to_print_comma = true;
- json << "\"tsd_address\":" << tsd_address;
-
- if (dti_qos_class_index != 0 && dti_qos_class_index != UINT64_MAX) {
- ThreadInfo::QoS requested_qos = DNBGetRequestedQoSForThread(
- pid, tid, tsd_address, dti_qos_class_index);
- if (requested_qos.IsValid()) {
- if (need_to_print_comma)
- json << ",";
- need_to_print_comma = true;
- json << "\"requested_qos\":{";
- json << "\"enum_value\":" << requested_qos.enum_value << ",";
- json << "\"constant_name\":\""
- << json_string_quote_metachars(requested_qos.constant_name)
- << "\",";
- json << "\"printable_name\":\""
- << json_string_quote_metachars(requested_qos.printable_name)
- << "\"";
- json << "}";
- }
- }
- }
-
- if (pthread_t_value != INVALID_NUB_ADDRESS) {
- if (need_to_print_comma)
- json << ",";
- need_to_print_comma = true;
- json << "\"pthread_t\":" << pthread_t_value;
- }
-
- nub_addr_t dispatch_queue_t_value = DNBGetDispatchQueueT(pid, tid);
- if (dispatch_queue_t_value != INVALID_NUB_ADDRESS) {
- if (need_to_print_comma)
- json << ",";
- need_to_print_comma = true;
- json << "\"dispatch_queue_t\":" << dispatch_queue_t_value;
- }
-
- json << "}";
- std::string json_quoted = binary_encode_string(json.str());
- return SendPacket(json_quoted);
- }
- }
- return SendPacket("OK");
-}
-
-// This packet may be called in one of three ways:
-//
-// jGetLoadedDynamicLibrariesInfos:{"image_count":40,"image_list_address":4295244704}
-// Look for an array of the old dyld_all_image_infos style of binary infos
-// at the image_list_address.
-// This an array of {void* load_addr, void* mod_date, void* pathname}
-//
-// jGetLoadedDynamicLibrariesInfos:{"fetch_all_solibs":true}
-// Use the new style (macOS 10.12, tvOS 10, iOS 10, watchOS 3) dyld SPI to
-// get a list of all the
-// libraries loaded
-//
-// jGetLoadedDynamicLibrariesInfos:{"solib_addresses":[8382824135,3258302053,830202858503]}
-// Use the new style (macOS 10.12, tvOS 10, iOS 10, watchOS 3) dyld SPI to
-// get the information
-// about the libraries loaded at these addresses.
-//
-rnb_err_t
-RNBRemote::HandlePacket_jGetLoadedDynamicLibrariesInfos(const char *p) {
- nub_process_t pid;
- // If we haven't run the process yet, return an error.
- if (!m_ctx.HasValidProcessID()) {
- return SendPacket("E83");
- }
-
- pid = m_ctx.ProcessID();
-
- const char get_loaded_dynamic_libraries_infos_str[] = {
- "jGetLoadedDynamicLibrariesInfos:{"};
- if (strncmp(p, get_loaded_dynamic_libraries_infos_str,
- sizeof(get_loaded_dynamic_libraries_infos_str) - 1) == 0) {
- p += strlen(get_loaded_dynamic_libraries_infos_str);
-
- JSONGenerator::ObjectSP json_sp;
-
- std::vector<uint64_t> macho_addresses;
- bool fetch_all_solibs = false;
- if (get_boolean_value_for_key_name_from_json("fetch_all_solibs", p,
- fetch_all_solibs) &&
- fetch_all_solibs) {
- json_sp = DNBGetAllLoadedLibrariesInfos(pid);
- } else if (get_array_of_ints_value_for_key_name_from_json(
- "solib_addresses", p, macho_addresses)) {
- json_sp = DNBGetLibrariesInfoForAddresses(pid, macho_addresses);
- } else {
- nub_addr_t image_list_address =
- get_integer_value_for_key_name_from_json("image_list_address", p);
- nub_addr_t image_count =
- get_integer_value_for_key_name_from_json("image_count", p);
-
- if (image_list_address != INVALID_NUB_ADDRESS &&
- image_count != INVALID_NUB_ADDRESS) {
- json_sp = DNBGetLoadedDynamicLibrariesInfos(pid, image_list_address,
- image_count);
- }
- }
-
- if (json_sp.get()) {
- std::ostringstream json_str;
- json_sp->Dump(json_str);
- if (json_str.str().size() > 0) {
- std::string json_str_quoted = binary_encode_string(json_str.str());
- return SendPacket(json_str_quoted.c_str());
- } else {
- SendPacket("E84");
- }
- }
- }
- return SendPacket("OK");
-}
-
-// This packet does not currently take any arguments. So the behavior is
-// jGetSharedCacheInfo:{}
-// send information about the inferior's shared cache
-// jGetSharedCacheInfo:
-// send "OK" to indicate that this packet is supported
-rnb_err_t RNBRemote::HandlePacket_jGetSharedCacheInfo(const char *p) {
- nub_process_t pid;
- // If we haven't run the process yet, return an error.
- if (!m_ctx.HasValidProcessID()) {
- return SendPacket("E85");
- }
-
- pid = m_ctx.ProcessID();
-
- const char get_shared_cache_info_str[] = {"jGetSharedCacheInfo:{"};
- if (strncmp(p, get_shared_cache_info_str,
- sizeof(get_shared_cache_info_str) - 1) == 0) {
- JSONGenerator::ObjectSP json_sp = DNBGetSharedCacheInfo(pid);
-
- if (json_sp.get()) {
- std::ostringstream json_str;
- json_sp->Dump(json_str);
- if (json_str.str().size() > 0) {
- std::string json_str_quoted = binary_encode_string(json_str.str());
- return SendPacket(json_str_quoted.c_str());
- } else {
- SendPacket("E86");
- }
- }
- }
- return SendPacket("OK");
-}
-
-static bool MachHeaderIsMainExecutable(nub_process_t pid, uint32_t addr_size,
- nub_addr_t mach_header_addr,
- mach_header &mh) {
- DNBLogThreadedIf(LOG_RNB_PROC, "GetMachHeaderForMainExecutable(pid = %u, "
- "addr_size = %u, mach_header_addr = "
- "0x%16.16llx)",
- pid, addr_size, mach_header_addr);
- const nub_size_t bytes_read =
- DNBProcessMemoryRead(pid, mach_header_addr, sizeof(mh), &mh);
- if (bytes_read == sizeof(mh)) {
- DNBLogThreadedIf(
- LOG_RNB_PROC, "GetMachHeaderForMainExecutable(pid = %u, addr_size = "
- "%u, mach_header_addr = 0x%16.16llx): mh = {\n magic = "
- "0x%8.8x\n cpu = 0x%8.8x\n sub = 0x%8.8x\n filetype = "
- "%u\n ncmds = %u\n sizeofcmds = 0x%8.8x\n flags = "
- "0x%8.8x }",
- pid, addr_size, mach_header_addr, mh.magic, mh.cputype, mh.cpusubtype,
- mh.filetype, mh.ncmds, mh.sizeofcmds, mh.flags);
- if ((addr_size == 4 && mh.magic == MH_MAGIC) ||
- (addr_size == 8 && mh.magic == MH_MAGIC_64)) {
- if (mh.filetype == MH_EXECUTE) {
- DNBLogThreadedIf(LOG_RNB_PROC, "GetMachHeaderForMainExecutable(pid = "
- "%u, addr_size = %u, mach_header_addr = "
- "0x%16.16llx) -> this is the "
- "executable!!!",
- pid, addr_size, mach_header_addr);
- return true;
- }
- }
- }
- return false;
-}
-
-static nub_addr_t GetMachHeaderForMainExecutable(const nub_process_t pid,
- const uint32_t addr_size,
- mach_header &mh) {
- struct AllImageInfos {
- uint32_t version;
- uint32_t dylib_info_count;
- uint64_t dylib_info_addr;
- };
-
- uint64_t mach_header_addr = 0;
-
- const nub_addr_t shlib_addr = DNBProcessGetSharedLibraryInfoAddress(pid);
- uint8_t bytes[256];
- nub_size_t bytes_read = 0;
- DNBDataRef data(bytes, sizeof(bytes), false);
- DNBDataRef::offset_t offset = 0;
- data.SetPointerSize(addr_size);
-
- //----------------------------------------------------------------------
- // When we are sitting at __dyld_start, the kernel has placed the
- // address of the mach header of the main executable on the stack. If we
- // read the SP and dereference a pointer, we might find the mach header
- // for the executable. We also just make sure there is only 1 thread
- // since if we are at __dyld_start we shouldn't have multiple threads.
- //----------------------------------------------------------------------
- if (DNBProcessGetNumThreads(pid) == 1) {
- nub_thread_t tid = DNBProcessGetThreadAtIndex(pid, 0);
- if (tid != INVALID_NUB_THREAD) {
- DNBRegisterValue sp_value;
- if (DNBThreadGetRegisterValueByID(pid, tid, REGISTER_SET_GENERIC,
- GENERIC_REGNUM_SP, &sp_value)) {
- uint64_t sp =
- addr_size == 8 ? sp_value.value.uint64 : sp_value.value.uint32;
- bytes_read = DNBProcessMemoryRead(pid, sp, addr_size, bytes);
- if (bytes_read == addr_size) {
- offset = 0;
- mach_header_addr = data.GetPointer(&offset);
- if (MachHeaderIsMainExecutable(pid, addr_size, mach_header_addr, mh))
- return mach_header_addr;
- }
- }
- }
- }
-
- //----------------------------------------------------------------------
- // Check the dyld_all_image_info structure for a list of mach header
- // since it is a very easy thing to check
- //----------------------------------------------------------------------
- if (shlib_addr != INVALID_NUB_ADDRESS) {
- bytes_read =
- DNBProcessMemoryRead(pid, shlib_addr, sizeof(AllImageInfos), bytes);
- if (bytes_read > 0) {
- AllImageInfos aii;
- offset = 0;
- aii.version = data.Get32(&offset);
- aii.dylib_info_count = data.Get32(&offset);
- if (aii.dylib_info_count > 0) {
- aii.dylib_info_addr = data.GetPointer(&offset);
- if (aii.dylib_info_addr != 0) {
- const size_t image_info_byte_size = 3 * addr_size;
- for (uint32_t i = 0; i < aii.dylib_info_count; ++i) {
- bytes_read = DNBProcessMemoryRead(pid, aii.dylib_info_addr +
- i * image_info_byte_size,
- image_info_byte_size, bytes);
- if (bytes_read != image_info_byte_size)
- break;
- offset = 0;
- mach_header_addr = data.GetPointer(&offset);
- if (MachHeaderIsMainExecutable(pid, addr_size, mach_header_addr,
- mh))
- return mach_header_addr;
- }
- }
- }
- }
- }
-
- //----------------------------------------------------------------------
- // We failed to find the executable's mach header from the all image
- // infos and by dereferencing the stack pointer. Now we fall back to
- // enumerating the memory regions and looking for regions that are
- // executable.
- //----------------------------------------------------------------------
- DNBRegionInfo region_info;
- mach_header_addr = 0;
- while (DNBProcessMemoryRegionInfo(pid, mach_header_addr, &region_info)) {
- if (region_info.size == 0)
- break;
-
- if (region_info.permissions & eMemoryPermissionsExecutable) {
- DNBLogThreadedIf(
- LOG_RNB_PROC, "[0x%16.16llx - 0x%16.16llx) permissions = %c%c%c: "
- "checking region for executable mach header",
- region_info.addr, region_info.addr + region_info.size,
- (region_info.permissions & eMemoryPermissionsReadable) ? 'r' : '-',
- (region_info.permissions & eMemoryPermissionsWritable) ? 'w' : '-',
- (region_info.permissions & eMemoryPermissionsExecutable) ? 'x' : '-');
- if (MachHeaderIsMainExecutable(pid, addr_size, mach_header_addr, mh))
- return mach_header_addr;
- } else {
- DNBLogThreadedIf(
- LOG_RNB_PROC,
- "[0x%16.16llx - 0x%16.16llx): permissions = %c%c%c: skipping region",
- region_info.addr, region_info.addr + region_info.size,
- (region_info.permissions & eMemoryPermissionsReadable) ? 'r' : '-',
- (region_info.permissions & eMemoryPermissionsWritable) ? 'w' : '-',
- (region_info.permissions & eMemoryPermissionsExecutable) ? 'x' : '-');
- }
- // Set the address to the next mapped region
- mach_header_addr = region_info.addr + region_info.size;
- }
- bzero(&mh, sizeof(mh));
- return INVALID_NUB_ADDRESS;
-}
-
-rnb_err_t RNBRemote::HandlePacket_qSymbol(const char *command) {
- const char *p = command;
- p += strlen("qSymbol:");
- const char *sep = strchr(p, ':');
-
- std::string symbol_name;
- std::string symbol_value_str;
- // Extract the symbol value if there is one
- if (sep > p)
- symbol_value_str.assign(p, sep - p);
- p = sep + 1;
-
- if (*p) {
- // We have a symbol name
- symbol_name = decode_hex_ascii_string(p);
- if (!symbol_value_str.empty()) {
- nub_addr_t symbol_value = decode_uint64(symbol_value_str.c_str(), 16);
- if (symbol_name == "dispatch_queue_offsets")
- m_dispatch_queue_offsets_addr = symbol_value;
- }
- ++m_qSymbol_index;
- } else {
- // No symbol name, set our symbol index to zero so we can
- // read any symbols that we need
- m_qSymbol_index = 0;
- }
-
- symbol_name.clear();
-
- if (m_qSymbol_index == 0) {
- if (m_dispatch_queue_offsets_addr == INVALID_NUB_ADDRESS)
- symbol_name = "dispatch_queue_offsets";
- else
- ++m_qSymbol_index;
- }
-
- // // Lookup next symbol when we have one...
- // if (m_qSymbol_index == 1)
- // {
- // }
-
- if (symbol_name.empty()) {
- // Done with symbol lookups
- return SendPacket("OK");
- } else {
- std::ostringstream reply;
- reply << "qSymbol:";
- for (size_t i = 0; i < symbol_name.size(); ++i)
- reply << RAWHEX8(symbol_name[i]);
- return SendPacket(reply.str().c_str());
- }
-}
-
-// Note that all numeric values returned by qProcessInfo are hex encoded,
-// including the pid and the cpu type.
-
-rnb_err_t RNBRemote::HandlePacket_qProcessInfo(const char *p) {
- nub_process_t pid;
- std::ostringstream rep;
-
- // If we haven't run the process yet, return an error.
- if (!m_ctx.HasValidProcessID())
- return SendPacket("E68");
-
- pid = m_ctx.ProcessID();
-
- rep << "pid:" << std::hex << pid << ';';
-
- int procpid_mib[4];
- procpid_mib[0] = CTL_KERN;
- procpid_mib[1] = KERN_PROC;
- procpid_mib[2] = KERN_PROC_PID;
- procpid_mib[3] = pid;
- struct kinfo_proc proc_kinfo;
- size_t proc_kinfo_size = sizeof(struct kinfo_proc);
-
- if (::sysctl(procpid_mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0) {
- if (proc_kinfo_size > 0) {
- rep << "parent-pid:" << std::hex << proc_kinfo.kp_eproc.e_ppid << ';';
- rep << "real-uid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_ruid
- << ';';
- rep << "real-gid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_rgid
- << ';';
- rep << "effective-uid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_uid
- << ';';
- if (proc_kinfo.kp_eproc.e_ucred.cr_ngroups > 0)
- rep << "effective-gid:" << std::hex
- << proc_kinfo.kp_eproc.e_ucred.cr_groups[0] << ';';
- }
- }
-
- cpu_type_t cputype = DNBProcessGetCPUType(pid);
- if (cputype == 0) {
- DNBLog("Unable to get the process cpu_type, making a best guess.");
- cputype = best_guess_cpu_type();
- }
-
- uint32_t addr_size = 0;
- if (cputype != 0) {
- rep << "cputype:" << std::hex << cputype << ";";
- if (cputype & CPU_ARCH_ABI64)
- addr_size = 8;
- else
- addr_size = 4;
- }
-
- bool host_cpu_is_64bit = false;
- 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 = is64bit_capable != 0;
-
- uint32_t cpusubtype;
- size_t cpusubtype_len = sizeof(cpusubtype);
- if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &cpusubtype_len, NULL, 0) ==
- 0) {
- // If a process is CPU_TYPE_X86, then ignore the cpusubtype that we detected
- // from the host and use CPU_SUBTYPE_I386_ALL because we don't want the
- // CPU_SUBTYPE_X86_ARCH1 or CPU_SUBTYPE_X86_64_H to be used as the cpu
- // subtype
- // for i386...
- if (host_cpu_is_64bit) {
- if (cputype == CPU_TYPE_X86) {
- cpusubtype = 3; // CPU_SUBTYPE_I386_ALL
- } else if (cputype == CPU_TYPE_ARM) {
- // 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.
- cpusubtype = 12; // CPU_SUBTYPE_ARM_V7K
- }
- }
- rep << "cpusubtype:" << std::hex << cpusubtype << ';';
- }
-
- bool os_handled = false;
- if (addr_size > 0) {
- rep << "ptrsize:" << std::dec << addr_size << ';';
-
-#if (defined(__x86_64__) || defined(__i386__))
- // Try and get the OS type by looking at the load commands in the main
- // executable and looking for a LC_VERSION_MIN load command. This is the
- // most reliable way to determine the "ostype" value when on desktop.
-
- mach_header mh;
- nub_addr_t exe_mach_header_addr =
- GetMachHeaderForMainExecutable(pid, addr_size, mh);
- if (exe_mach_header_addr != INVALID_NUB_ADDRESS) {
- uint64_t load_command_addr =
- exe_mach_header_addr +
- ((addr_size == 8) ? sizeof(mach_header_64) : sizeof(mach_header));
- load_command lc;
- for (uint32_t i = 0; i < mh.ncmds && !os_handled; ++i) {
- const nub_size_t bytes_read =
- DNBProcessMemoryRead(pid, load_command_addr, sizeof(lc), &lc);
- (void)bytes_read;
-
- uint32_t major_version, minor_version, patch_version;
- auto *platform = DNBGetDeploymentInfo(pid, lc, load_command_addr,
- major_version, minor_version,
- patch_version);
- if (platform) {
- os_handled = true;
- rep << "ostype:" << platform << ";";
- break;
- }
- load_command_addr = load_command_addr + lc.cmdsize;
- }
- }
-#endif // when compiling this on x86 targets
- }
-
- // If we weren't able to find the OS in a LC_VERSION_MIN load command, try
- // to set it correctly by using the cpu type and other tricks
- if (!os_handled) {
- // 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 || cputype == CPU_TYPE_ARM64) {
-#if defined(TARGET_OS_TV) && TARGET_OS_TV == 1
- rep << "ostype:tvos;";
-#elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
- rep << "ostype:watchos;";
-#elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1
- rep << "ostype:bridgeos;";
-#else
- rep << "ostype:ios;";
-#endif
- } else {
- bool is_ios_simulator = false;
- if (cputype == CPU_TYPE_X86 || cputype == CPU_TYPE_X86_64) {
- // Check for iOS simulator binaries by getting the process argument
- // and environment and checking for SIMULATOR_UDID in the environment
- int proc_args_mib[3] = {CTL_KERN, KERN_PROCARGS2, (int)pid};
-
- uint8_t arg_data[8192];
- size_t arg_data_size = sizeof(arg_data);
- if (::sysctl(proc_args_mib, 3, arg_data, &arg_data_size, NULL, 0) ==
- 0) {
- DNBDataRef data(arg_data, arg_data_size, false);
- DNBDataRef::offset_t offset = 0;
- uint32_t argc = data.Get32(&offset);
- const char *cstr;
-
- cstr = data.GetCStr(&offset);
- if (cstr) {
- // Skip NULLs
- while (1) {
- const char *p = data.PeekCStr(offset);
- if ((p == NULL) || (*p != '\0'))
- break;
- ++offset;
- }
- // Now skip all arguments
- for (uint32_t i = 0; i < argc; ++i) {
- data.GetCStr(&offset);
- }
-
- // Now iterate across all environment variables
- while ((cstr = data.GetCStr(&offset))) {
- if (strncmp(cstr, "SIMULATOR_UDID=", strlen("SIMULATOR_UDID=")) ==
- 0) {
- is_ios_simulator = true;
- break;
- }
- if (cstr[0] == '\0')
- break;
- }
- }
- }
- }
- if (is_ios_simulator) {
-#if defined(TARGET_OS_TV) && TARGET_OS_TV == 1
- rep << "ostype:tvos;";
-#elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
- rep << "ostype:watchos;";
-#elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1
- rep << "ostype:bridgeos;";
-#else
- rep << "ostype:ios;";
-#endif
- } else {
- rep << "ostype:macosx;";
- }
- }
- }
-
- rep << "vendor:apple;";
-
-#if defined(__LITTLE_ENDIAN__)
- rep << "endian:little;";
-#elif defined(__BIG_ENDIAN__)
- rep << "endian:big;";
-#elif defined(__PDP_ENDIAN__)
- rep << "endian:pdp;";
-#endif
-
- if (addr_size == 0) {
-#if (defined(__x86_64__) || defined(__i386__)) && defined(x86_THREAD_STATE)
- nub_thread_t thread = DNBProcessGetCurrentThreadMachPort(pid);
- kern_return_t kr;
- x86_thread_state_t gp_regs;
- mach_msg_type_number_t gp_count = x86_THREAD_STATE_COUNT;
- kr = thread_get_state(static_cast<thread_act_t>(thread), x86_THREAD_STATE,
- (thread_state_t)&gp_regs, &gp_count);
- if (kr == KERN_SUCCESS) {
- if (gp_regs.tsh.flavor == x86_THREAD_STATE64)
- rep << "ptrsize:8;";
- else
- rep << "ptrsize:4;";
- }
-#elif defined(__arm__)
- rep << "ptrsize:4;";
-#elif (defined(__arm64__) || defined(__aarch64__)) && \
- 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());
-}
-
-const RNBRemote::DispatchQueueOffsets *RNBRemote::GetDispatchQueueOffsets() {
- if (!m_dispatch_queue_offsets.IsValid() &&
- m_dispatch_queue_offsets_addr != INVALID_NUB_ADDRESS &&
- m_ctx.HasValidProcessID()) {
- nub_process_t pid = m_ctx.ProcessID();
- nub_size_t bytes_read = DNBProcessMemoryRead(
- pid, m_dispatch_queue_offsets_addr, sizeof(m_dispatch_queue_offsets),
- &m_dispatch_queue_offsets);
- if (bytes_read != sizeof(m_dispatch_queue_offsets))
- m_dispatch_queue_offsets.Clear();
- }
-
- if (m_dispatch_queue_offsets.IsValid())
- return &m_dispatch_queue_offsets;
- else
- return nullptr;
-}
-
-void RNBRemote::EnableCompressionNextSendPacket(compression_types type) {
- m_compression_mode = type;
- m_enable_compression_next_send_packet = true;
-}
-
-compression_types RNBRemote::GetCompressionType() {
- // The first packet we send back to the debugger after a QEnableCompression
- // request
- // should be uncompressed -- so we can indicate whether the compression was
- // enabled
- // or not via OK / Enn returns. After that, all packets sent will be using
- // the
- // compression protocol.
-
- if (m_enable_compression_next_send_packet) {
- // One time, we send back "None" as our compression type
- m_enable_compression_next_send_packet = false;
- return compression_types::none;
- }
- return m_compression_mode;
-}
diff --git a/tools/debugserver/source/RNBRemote.h b/tools/debugserver/source/RNBRemote.h
deleted file mode 100644
index 0c9c9856308a..000000000000
--- a/tools/debugserver/source/RNBRemote.h
+++ /dev/null
@@ -1,433 +0,0 @@
-
-//
-// 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 12/12/07.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __RNBRemote_h__
-#define __RNBRemote_h__
-
-#include "DNB.h"
-#include "PThreadMutex.h"
-#include "RNBContext.h"
-#include "RNBDefs.h"
-#include "RNBSocket.h"
-#include <deque>
-#include <map>
-#include <string>
-#include <vector>
-
-class RNBSocket;
-class RNBContext;
-class PThreadEvents;
-
-enum event_loop_mode { debug_nub, gdb_remote_protocol, done };
-
-enum class compression_types { zlib_deflate, lz4, lzma, lzfse, none };
-
-class RNBRemote {
-public:
- typedef enum {
- invalid_packet = 0,
- ack, // '+'
- nack, // '-'
- halt, // ^C (async halt)
- use_extended_mode, // '!'
- why_halted, // '?'
- set_argv, // 'A'
- set_bp, // 'B'
- cont, // 'c'
- continue_with_sig, // 'C'
- detach, // 'D'
- read_general_regs, // 'g'
- write_general_regs, // 'G'
- set_thread, // 'H'
- step_inferior_one_cycle, // 'i'
- signal_and_step_inf_one_cycle, // 'I'
- kill, // 'k'
- read_memory, // 'm'
- write_memory, // 'M'
- read_register, // 'p'
- write_register, // 'P'
- restart, // 'R'
- single_step, // 's'
- single_step_with_sig, // 'S'
- search_mem_backwards, // 't'
- thread_alive_p, // 'T'
- vattach, // 'vAttach;pid'
- vattachwait, // 'vAttachWait:XX...' where XX is one or more hex encoded
- // process name ASCII bytes
- vattachorwait, // 'vAttachOrWait:XX...' where XX is one or more hex encoded
- // process name ASCII bytes
- vattachname, // 'vAttachName:XX...' where XX is one or more hex encoded
- // process name ASCII bytes
- vcont, // 'vCont'
- vcont_list_actions, // 'vCont?'
- read_data_from_memory, // 'x'
- write_data_to_memory, // 'X'
- insert_mem_bp, // 'Z0'
- remove_mem_bp, // 'z0'
- insert_hardware_bp, // 'Z1'
- remove_hardware_bp, // 'z1'
- insert_write_watch_bp, // 'Z2'
- remove_write_watch_bp, // 'z2'
- insert_read_watch_bp, // 'Z3'
- remove_read_watch_bp, // 'z3'
- insert_access_watch_bp, // 'Z4'
- remove_access_watch_bp, // 'z4'
-
- query_monitor, // 'qRcmd'
- query_current_thread_id, // 'qC'
- query_get_pid, // 'qGetPid'
- query_echo, // 'qEcho'
- query_thread_ids_first, // 'qfThreadInfo'
- query_thread_ids_subsequent, // 'qsThreadInfo'
- query_thread_extra_info, // 'qThreadExtraInfo'
- query_thread_stop_info, // 'qThreadStopInfo'
- query_image_offsets, // 'qOffsets'
- query_symbol_lookup, // 'qSymbol'
- query_launch_success, // 'qLaunchSuccess'
- query_register_info, // 'qRegisterInfo'
- query_shlib_notify_info_addr, // 'qShlibInfoAddr'
- query_step_packet_supported, // 'qStepPacketSupported'
- query_supported_features, // 'qSupported'
- query_vattachorwait_supported, // 'qVAttachOrWaitSupported'
- query_sync_thread_state_supported, // 'QSyncThreadState'
- query_host_info, // 'qHostInfo'
- query_gdb_server_version, // 'qGDBServerVersion'
- query_process_info, // 'qProcessInfo'
- json_query_thread_extended_info, // 'jThreadExtendedInfo'
- json_query_get_loaded_dynamic_libraries_infos, // 'jGetLoadedDynamicLibrariesInfos'
- json_query_threads_info, // 'jThreadsInfo'
- json_query_get_shared_cache_info, // 'jGetSharedCacheInfo'
- pass_signals_to_inferior, // 'QPassSignals'
- start_noack_mode, // 'QStartNoAckMode'
- prefix_reg_packets_with_tid, // 'QPrefixRegisterPacketsWithThreadID
- set_logging_mode, // 'QSetLogging:'
- set_max_packet_size, // 'QSetMaxPacketSize:'
- set_max_payload_size, // 'QSetMaxPayloadSize:'
- set_environment_variable, // 'QEnvironment:'
- set_environment_variable_hex, // 'QEnvironmentHexEncoded:'
- set_launch_arch, // 'QLaunchArch:'
- set_disable_aslr, // 'QSetDisableASLR:'
- set_stdin, // 'QSetSTDIN:'
- set_stdout, // 'QSetSTDOUT:'
- set_stderr, // 'QSetSTDERR:'
- set_working_dir, // 'QSetWorkingDir:'
- set_list_threads_in_stop_reply, // 'QListThreadsInStopReply:'
- sync_thread_state, // 'QSyncThreadState:'
- memory_region_info, // 'qMemoryRegionInfo:'
- get_profile_data, // 'qGetProfileData'
- set_enable_profiling, // 'QSetEnableAsyncProfiling'
- enable_compression, // 'QEnableCompression:'
- 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:'
- set_detach_on_error, // 'QSetDetachOnError:'
- query_transfer, // 'qXfer:'
- query_supported_async_json_packets, // 'QSupportedAsyncJSONPackets'
- configure_darwin_log, // 'ConfigureDarwinLog:'
- unknown_type
- } PacketEnum;
-
- typedef rnb_err_t (RNBRemote::*HandlePacketCallback)(const char *p);
-
- RNBRemote();
- ~RNBRemote();
-
- void Initialize();
-
- bool InitializeRegisters(bool force = false);
-
- rnb_err_t HandleAsyncPacket(PacketEnum *type = NULL);
- rnb_err_t HandleReceivedPacket(PacketEnum *type = NULL);
-
- nub_thread_t GetContinueThread() const { return m_continue_thread; }
-
- void SetContinueThread(nub_thread_t tid) { m_continue_thread = tid; }
-
- nub_thread_t GetCurrentThread() const {
- if (m_thread == 0 || m_thread == (nub_thread_t)-1)
- return DNBProcessGetCurrentThread(m_ctx.ProcessID());
- return m_thread;
- }
-
- void SetCurrentThread(nub_thread_t tid) {
- DNBProcessSetCurrentThread(m_ctx.ProcessID(), tid);
- m_thread = tid;
- }
-
- static void *ThreadFunctionReadRemoteData(void *arg);
- void StartReadRemoteDataThread();
- void StopReadRemoteDataThread();
-
- void NotifyThatProcessStopped(void);
-
- rnb_err_t HandlePacket_A(const char *p);
- rnb_err_t HandlePacket_H(const char *p);
- rnb_err_t HandlePacket_qC(const char *p);
- rnb_err_t HandlePacket_qRcmd(const char *p);
- rnb_err_t HandlePacket_qGetPid(const char *p);
- rnb_err_t HandlePacket_qEcho(const char *p);
- rnb_err_t HandlePacket_qLaunchSuccess(const char *p);
- rnb_err_t HandlePacket_qRegisterInfo(const char *p);
- rnb_err_t HandlePacket_qShlibInfoAddr(const char *p);
- rnb_err_t HandlePacket_qStepPacketSupported(const char *p);
- rnb_err_t HandlePacket_qVAttachOrWaitSupported(const char *p);
- rnb_err_t HandlePacket_qSyncThreadStateSupported(const char *p);
- rnb_err_t HandlePacket_qThreadInfo(const char *p);
- rnb_err_t HandlePacket_jThreadExtendedInfo(const char *p);
- rnb_err_t HandlePacket_jGetLoadedDynamicLibrariesInfos(const char *p);
- rnb_err_t HandlePacket_jThreadsInfo(const char *p);
- rnb_err_t HandlePacket_jGetSharedCacheInfo(const char *p);
- rnb_err_t HandlePacket_qThreadExtraInfo(const char *p);
- rnb_err_t HandlePacket_qThreadStopInfo(const char *p);
- rnb_err_t HandlePacket_qHostInfo(const char *p);
- rnb_err_t HandlePacket_qGDBServerVersion(const char *p);
- rnb_err_t HandlePacket_qProcessInfo(const char *p);
- rnb_err_t HandlePacket_qSymbol(const char *p);
- rnb_err_t HandlePacket_QStartNoAckMode(const char *p);
- rnb_err_t HandlePacket_QThreadSuffixSupported(const char *p);
- rnb_err_t HandlePacket_QSetLogging(const char *p);
- rnb_err_t HandlePacket_QSetDisableASLR(const char *p);
- rnb_err_t HandlePacket_QSetSTDIO(const char *p);
- rnb_err_t HandlePacket_QSetWorkingDir(const char *p);
- rnb_err_t HandlePacket_QSetMaxPayloadSize(const char *p);
- rnb_err_t HandlePacket_QSetMaxPacketSize(const char *p);
- rnb_err_t HandlePacket_QEnvironment(const char *p);
- rnb_err_t HandlePacket_QEnvironmentHexEncoded(const char *p);
- rnb_err_t HandlePacket_QLaunchArch(const char *p);
- 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);
- rnb_err_t HandlePacket_x(const char *p);
- rnb_err_t HandlePacket_X(const char *p);
- rnb_err_t HandlePacket_g(const char *p);
- rnb_err_t HandlePacket_G(const char *p);
- rnb_err_t HandlePacket_z(const char *p);
- rnb_err_t HandlePacket_T(const char *p);
- rnb_err_t HandlePacket_p(const char *p);
- rnb_err_t HandlePacket_P(const char *p);
- rnb_err_t HandlePacket_c(const char *p);
- rnb_err_t HandlePacket_C(const char *p);
- rnb_err_t HandlePacket_D(const char *p);
- rnb_err_t HandlePacket_k(const char *p);
- rnb_err_t HandlePacket_s(const char *p);
- rnb_err_t HandlePacket_S(const char *p);
- rnb_err_t HandlePacket_qSupported(const char *p);
- rnb_err_t HandlePacket_v(const char *p);
- rnb_err_t HandlePacket_UNIMPLEMENTED(const char *p);
- rnb_err_t HandlePacket_ILLFORMED(const char *file, int line, const char *p,
- const char *description);
- rnb_err_t HandlePacket_AllocateMemory(const char *p);
- rnb_err_t HandlePacket_DeallocateMemory(const char *p);
- rnb_err_t HandlePacket_SaveRegisterState(const char *p);
- rnb_err_t HandlePacket_RestoreRegisterState(const char *p);
- rnb_err_t HandlePacket_MemoryRegionInfo(const char *p);
- rnb_err_t HandlePacket_GetProfileData(const char *p);
- rnb_err_t HandlePacket_SetEnableAsyncProfiling(const char *p);
- rnb_err_t HandlePacket_QEnableCompression(const char *p);
- rnb_err_t HandlePacket_WatchpointSupportInfo(const char *p);
- rnb_err_t HandlePacket_qSpeedTest(const char *p);
- rnb_err_t HandlePacket_qXfer(const char *p);
- rnb_err_t HandlePacket_stop_process(const char *p);
- rnb_err_t HandlePacket_QSetDetachOnError(const char *p);
- rnb_err_t HandlePacket_qStructuredDataPlugins(const char *p);
- rnb_err_t HandlePacket_QConfigureDarwinLog(const char *p);
-
- rnb_err_t SendStopReplyPacketForThread(nub_thread_t tid);
- rnb_err_t SendHexEncodedBytePacket(const char *header, const void *buf,
- size_t buf_len, const char *footer);
- rnb_err_t SendSTDOUTPacket(char *buf, nub_size_t buf_size);
- rnb_err_t SendSTDERRPacket(char *buf, nub_size_t buf_size);
- void FlushSTDIO();
- void SendAsyncProfileData();
- rnb_err_t SendAsyncProfileDataPacket(char *buf, nub_size_t buf_size);
- void SendAsyncDarwinLogData();
- rnb_err_t SendAsyncJSONPacket(const JSONGenerator::Dictionary &dictionary);
-
- RNBContext &Context() { return m_ctx; }
- RNBSocket &Comm() { return m_comm; }
-
-private:
- // Outlaw some constructors
- RNBRemote(const RNBRemote &);
-
-protected:
- rnb_err_t GetCommData();
- void CommDataReceived(const std::string &data);
- struct Packet {
- typedef std::vector<Packet> collection;
- typedef collection::iterator iterator;
- typedef collection::const_iterator const_iterator;
- PacketEnum type;
- HandlePacketCallback normal; // Function to call when inferior is halted
- HandlePacketCallback async; // Function to call when inferior is running
- std::string abbrev;
- std::string printable_name;
-
- bool IsPlatformPacket() const {
- switch (type) {
- case set_logging_mode:
- case query_host_info:
- return true;
- default:
- break;
- }
- return false;
- }
- Packet()
- : type(invalid_packet), normal(NULL), async(NULL), abbrev(),
- printable_name() {}
-
- Packet(PacketEnum in_type, HandlePacketCallback in_normal,
- HandlePacketCallback in_async, const char *in_abbrev,
- const char *in_printable_name)
- : type(in_type), normal(in_normal), async(in_async), abbrev(in_abbrev),
- printable_name(in_printable_name) {}
- };
-
- struct DispatchQueueOffsets {
- uint16_t dqo_version;
- uint16_t dqo_label;
- uint16_t dqo_label_size;
- uint16_t dqo_flags;
- uint16_t dqo_flags_size;
- uint16_t dqo_serialnum;
- uint16_t dqo_serialnum_size;
- uint16_t dqo_width;
- uint16_t dqo_width_size;
- uint16_t dqo_running;
- uint16_t dqo_running_size;
- uint16_t dqo_suspend_cnt; // version 5 and later, starting with Mac OS X
- // 10.10/iOS 8
- uint16_t dqo_suspend_cnt_size; // version 5 and later, starting with Mac OS
- // X 10.10/iOS 8
- uint16_t dqo_target_queue; // version 5 and later, starting with Mac OS X
- // 10.10/iOS 8
- uint16_t dqo_target_queue_size; // version 5 and later, starting with Mac OS
- // X 10.10/iOS 8
- uint16_t
- dqo_priority; // version 5 and later, starting with Mac OS X 10.10/iOS 8
- uint16_t dqo_priority_size; // version 5 and later, starting with Mac OS X
- // 10.10/iOS 8
-
- DispatchQueueOffsets() { Clear(); }
-
- void Clear() {
- dqo_version = UINT16_MAX;
- dqo_label = UINT16_MAX;
- dqo_label_size = UINT16_MAX;
- dqo_flags = UINT16_MAX;
- dqo_flags_size = UINT16_MAX;
- dqo_serialnum = UINT16_MAX;
- dqo_serialnum_size = UINT16_MAX;
- dqo_width = UINT16_MAX;
- dqo_width_size = UINT16_MAX;
- dqo_running = UINT16_MAX;
- dqo_running_size = UINT16_MAX;
- dqo_suspend_cnt = UINT16_MAX;
- dqo_suspend_cnt_size = UINT16_MAX;
- dqo_target_queue = UINT16_MAX;
- dqo_target_queue_size = UINT16_MAX;
- dqo_priority = UINT16_MAX;
- dqo_priority_size = UINT16_MAX;
- }
-
- bool IsValid() const { return dqo_version != UINT16_MAX; }
-
- void GetThreadQueueInfo(nub_process_t pid, nub_addr_t dispatch_qaddr,
- nub_addr_t &dispatch_queue_t,
- std::string &queue_name, uint64_t &queue_width,
- uint64_t &queue_serialnum) const;
- };
-
- rnb_err_t GetPacket(std::string &packet_data, RNBRemote::Packet &packet_info,
- bool wait);
- rnb_err_t SendPacket(const std::string &);
- std::string CompressString(const std::string &);
-
- void CreatePacketTable();
- rnb_err_t GetPacketPayload(std::string &);
-
- nub_thread_t ExtractThreadIDFromThreadSuffix(const char *p);
-
- void EnableCompressionNextSendPacket(compression_types);
-
- compression_types GetCompressionType();
-
- const DispatchQueueOffsets *GetDispatchQueueOffsets();
-
- JSONGenerator::ObjectSP
- GetJSONThreadsInfo(bool threads_with_valid_stop_info_only);
-
- RNBContext m_ctx; // process context
- RNBSocket m_comm; // communication port
- std::string m_arch;
- nub_thread_t m_continue_thread; // thread to continue; 0 for any, -1 for all
- nub_thread_t m_thread; // thread for other ops; 0 for any, -1 for all
- PThreadMutex m_mutex; // Mutex that protects
- DispatchQueueOffsets m_dispatch_queue_offsets;
- nub_addr_t m_dispatch_queue_offsets_addr;
- uint32_t m_qSymbol_index;
- uint32_t m_packets_recvd;
- Packet::collection m_packets;
- std::deque<std::string> m_rx_packets;
- std::string m_rx_partial_data; // For packets that may come in more than one
- // batch, anything left over can be left here
- pthread_t m_rx_pthread;
- uint32_t
- m_max_payload_size; // the maximum sized payload we should send to gdb
- bool m_extended_mode; // are we in extended mode?
- bool m_noack_mode; // are we in no-ack mode?
- bool m_thread_suffix_supported; // Set to true if the 'p', 'P', 'g', and 'G'
- // packets should be prefixed with the thread
- // ID and colon:
- // "$pRR;thread:TTTT;" instead of "$pRR"
- // "$PRR=VVVVVVVV;thread:TTTT;" instead of "$PRR=VVVVVVVV"
- // "$g;thread:TTTT" instead of "$g"
- // "$GVVVVVVVVVVVVVV;thread:TTTT;#00 instead of "$GVVVVVVVVVVVVVV"
- bool m_list_threads_in_stop_reply;
-
- size_t m_compression_minsize; // only packets larger than this size will be
- // compressed
- bool m_enable_compression_next_send_packet;
-
- compression_types m_compression_mode;
-};
-
-/* We translate the /usr/include/mach/exception_types.h exception types
- (e.g. EXC_BAD_ACCESS) to the fake BSD signal numbers that gdb uses
- in include/gdb/signals.h (e.g. TARGET_EXC_BAD_ACCESS). These hard
- coded values for TARGET_EXC_BAD_ACCESS et al must match the gdb
- values in its include/gdb/signals.h. */
-
-#define TARGET_EXC_BAD_ACCESS 0x91
-#define TARGET_EXC_BAD_INSTRUCTION 0x92
-#define TARGET_EXC_ARITHMETIC 0x93
-#define TARGET_EXC_EMULATION 0x94
-#define TARGET_EXC_SOFTWARE 0x95
-#define TARGET_EXC_BREAKPOINT 0x96
-
-/* Generally speaking, you can't assume gdb can receive more than 399 bytes
- at a time with a random gdb. This bufsize constant is only specifying
- how many bytes gdb can *receive* from debugserver -- it tells us nothing
- about how many bytes gdb might try to send in a single packet. */
-#define DEFAULT_GDB_REMOTE_PROTOCOL_BUFSIZE 399
-
-#endif // #ifndef __RNBRemote_h__
diff --git a/tools/debugserver/source/RNBServices.cpp b/tools/debugserver/source/RNBServices.cpp
deleted file mode 100644
index 89c4c27da1dd..000000000000
--- a/tools/debugserver/source/RNBServices.cpp
+++ /dev/null
@@ -1,235 +0,0 @@
-//===-- RNBServices.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 Christopher Friesen on 3/21/08.
-//
-//===----------------------------------------------------------------------===//
-
-#include "RNBServices.h"
-
-#include "CFString.h"
-#include "DNBLog.h"
-#include "MacOSX/CFUtils.h"
-#include <CoreFoundation/CoreFoundation.h>
-#include <libproc.h>
-#include <sys/sysctl.h>
-#include <unistd.h>
-#include <vector>
-
-// 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)
-#include <SpringBoardServices/SpringBoardServices.h>
-#endif
-
-// From DNB.cpp
-size_t GetAllInfos(std::vector<struct kinfo_proc> &proc_infos);
-
-int GetProcesses(CFMutableArrayRef plistMutableArray, bool all_users) {
- if (plistMutableArray == NULL)
- return -1;
-
- // Running as root, get all processes
- std::vector<struct kinfo_proc> proc_infos;
- const size_t num_proc_infos = GetAllInfos(proc_infos);
- if (num_proc_infos > 0) {
- const pid_t our_pid = getpid();
- const uid_t our_uid = getuid();
- uint32_t i;
- CFAllocatorRef alloc = kCFAllocatorDefault;
-
- for (i = 0; i < num_proc_infos; i++) {
- struct kinfo_proc &proc_info = proc_infos[i];
-
- bool kinfo_user_matches;
- // Special case, if lldb is being run as root we can attach to anything.
- if (all_users)
- kinfo_user_matches = true;
- else
- kinfo_user_matches = proc_info.kp_eproc.e_pcred.p_ruid == our_uid;
-
- const pid_t pid = proc_info.kp_proc.p_pid;
- // Skip zombie processes and processes with unset status
- if (!kinfo_user_matches || // User is acceptable
- pid == our_pid || // Skip this process
- pid == 0 || // Skip kernel (kernel pid is zero)
- proc_info.kp_proc.p_stat ==
- SZOMB || // Zombies are bad, they like brains...
- proc_info.kp_proc.p_flag & P_TRACED || // Being debugged?
- proc_info.kp_proc.p_flag & P_WEXIT || // Working on exiting?
- proc_info.kp_proc.p_flag &
- P_TRANSLATED) // Skip translated ppc (Rosetta)
- continue;
-
- // Create a new mutable dictionary for each application
- CFReleaser<CFMutableDictionaryRef> appInfoDict(
- ::CFDictionaryCreateMutable(alloc, 0, &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks));
-
- // Get the process id for the app (if there is one)
- const int32_t pid_int32 = pid;
- CFReleaser<CFNumberRef> pidCFNumber(
- ::CFNumberCreate(alloc, kCFNumberSInt32Type, &pid_int32));
- ::CFDictionarySetValue(appInfoDict.get(), DTSERVICES_APP_PID_KEY,
- pidCFNumber.get());
-
- // Set a boolean to indicate if this is the front most
- ::CFDictionarySetValue(appInfoDict.get(), DTSERVICES_APP_FRONTMOST_KEY,
- kCFBooleanFalse);
-
- const char *pid_basename = proc_info.kp_proc.p_comm;
- char proc_path_buf[PATH_MAX];
-
- int return_val = proc_pidpath(pid, proc_path_buf, PATH_MAX);
- if (return_val > 0) {
- // Okay, now search backwards from that to see if there is a
- // slash in the name. Note, even though we got all the args we don't
- // care
- // because the list data is just a bunch of concatenated null terminated
- // strings
- // so strrchr will start from the end of argv0.
-
- pid_basename = strrchr(proc_path_buf, '/');
- if (pid_basename) {
- // Skip the '/'
- ++pid_basename;
- } else {
- // We didn't find a directory delimiter in the process argv[0], just
- // use what was in there
- pid_basename = proc_path_buf;
- }
- CFString cf_pid_path(proc_path_buf);
- if (cf_pid_path.get())
- ::CFDictionarySetValue(appInfoDict.get(), DTSERVICES_APP_PATH_KEY,
- cf_pid_path.get());
- }
-
- if (pid_basename && pid_basename[0]) {
- CFString pid_name(pid_basename);
- ::CFDictionarySetValue(appInfoDict.get(),
- DTSERVICES_APP_DISPLAY_NAME_KEY, pid_name.get());
- }
-
- // Append the application info to the plist array
- ::CFArrayAppendValue(plistMutableArray, appInfoDict.get());
- }
- }
- return 0;
-}
-int ListApplications(std::string &plist, bool opt_runningApps,
- bool opt_debuggable) {
- int result = -1;
-
- CFAllocatorRef alloc = kCFAllocatorDefault;
-
- // Create a mutable array that we can populate. Specify zero so it can be of
- // any size.
- CFReleaser<CFMutableArrayRef> plistMutableArray(
- ::CFArrayCreateMutable(alloc, 0, &kCFTypeArrayCallBacks));
-
- const uid_t our_uid = getuid();
-
-#if defined(WITH_SPRINGBOARD) || defined(WITH_BKS)
-
- if (our_uid == 0) {
- bool all_users = true;
- result = GetProcesses(plistMutableArray.get(), all_users);
- } else {
- CFReleaser<CFStringRef> sbsFrontAppID(
- ::SBSCopyFrontmostApplicationDisplayIdentifier());
- CFReleaser<CFArrayRef> sbsAppIDs(::SBSCopyApplicationDisplayIdentifiers(
- opt_runningApps, opt_debuggable));
-
- // Need to check the return value from SBSCopyApplicationDisplayIdentifiers.
- CFIndex count = sbsAppIDs.get() ? ::CFArrayGetCount(sbsAppIDs.get()) : 0;
- CFIndex i = 0;
- for (i = 0; i < count; i++) {
- CFStringRef displayIdentifier =
- (CFStringRef)::CFArrayGetValueAtIndex(sbsAppIDs.get(), i);
-
- // Create a new mutable dictionary for each application
- CFReleaser<CFMutableDictionaryRef> appInfoDict(
- ::CFDictionaryCreateMutable(alloc, 0, &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks));
-
- // Get the process id for the app (if there is one)
- pid_t pid = INVALID_NUB_PROCESS;
- if (::SBSProcessIDForDisplayIdentifier((CFStringRef)displayIdentifier,
- &pid) == true) {
- CFReleaser<CFNumberRef> pidCFNumber(
- ::CFNumberCreate(alloc, kCFNumberSInt32Type, &pid));
- ::CFDictionarySetValue(appInfoDict.get(), DTSERVICES_APP_PID_KEY,
- pidCFNumber.get());
- }
-
- // Set a boolean to indicate if this is the front most
- if (sbsFrontAppID.get() && displayIdentifier &&
- (::CFStringCompare(sbsFrontAppID.get(), displayIdentifier, 0) ==
- kCFCompareEqualTo))
- ::CFDictionarySetValue(appInfoDict.get(), DTSERVICES_APP_FRONTMOST_KEY,
- kCFBooleanTrue);
- else
- ::CFDictionarySetValue(appInfoDict.get(), DTSERVICES_APP_FRONTMOST_KEY,
- kCFBooleanFalse);
-
- CFReleaser<CFStringRef> executablePath(
- ::SBSCopyExecutablePathForDisplayIdentifier(displayIdentifier));
- if (executablePath.get() != NULL) {
- ::CFDictionarySetValue(appInfoDict.get(), DTSERVICES_APP_PATH_KEY,
- executablePath.get());
- }
-
- CFReleaser<CFStringRef> iconImagePath(
- ::SBSCopyIconImagePathForDisplayIdentifier(displayIdentifier));
- if (iconImagePath.get() != NULL) {
- ::CFDictionarySetValue(appInfoDict.get(), DTSERVICES_APP_ICON_PATH_KEY,
- iconImagePath.get());
- }
-
- CFReleaser<CFStringRef> localizedDisplayName(
- ::SBSCopyLocalizedApplicationNameForDisplayIdentifier(
- displayIdentifier));
- if (localizedDisplayName.get() != NULL) {
- ::CFDictionarySetValue(appInfoDict.get(),
- DTSERVICES_APP_DISPLAY_NAME_KEY,
- localizedDisplayName.get());
- }
-
- // Append the application info to the plist array
- ::CFArrayAppendValue(plistMutableArray.get(), appInfoDict.get());
- }
- }
-#else // #if defined (WITH_SPRINGBOARD) || defined (WITH_BKS)
- // When root, show all processes
- bool all_users = (our_uid == 0);
- GetProcesses(plistMutableArray.get(), all_users);
-#endif
-
- CFReleaser<CFDataRef> plistData(
- ::CFPropertyListCreateXMLData(alloc, plistMutableArray.get()));
-
- // write plist to service port
- if (plistData.get() != NULL) {
- CFIndex size = ::CFDataGetLength(plistData.get());
- const UInt8 *bytes = ::CFDataGetBytePtr(plistData.get());
- if (bytes != NULL && size > 0) {
- plist.assign((const char *)bytes, size);
- return 0; // Success
- } else {
- DNBLogError("empty application property list.");
- result = -2;
- }
- } else {
- DNBLogError("serializing task list.");
- result = -3;
- }
-
- return result;
-}
diff --git a/tools/debugserver/source/RNBServices.h b/tools/debugserver/source/RNBServices.h
deleted file mode 100644
index caa2b0fd199e..000000000000
--- a/tools/debugserver/source/RNBServices.h
+++ /dev/null
@@ -1,29 +0,0 @@
-//===-- RNBServices.h -------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Created by Christopher Friesen on 3/21/08.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __RNBServices_h__
-#define __RNBServices_h__
-
-#include "RNBDefs.h"
-#include <string>
-
-#define DTSERVICES_APP_FRONTMOST_KEY CFSTR("isFrontApp")
-#define DTSERVICES_APP_PATH_KEY CFSTR("executablePath")
-#define DTSERVICES_APP_ICON_PATH_KEY CFSTR("iconPath")
-#define DTSERVICES_APP_DISPLAY_NAME_KEY CFSTR("displayName")
-#define DTSERVICES_APP_PID_KEY CFSTR("pid")
-
-int ListApplications(std::string &plist, bool opt_runningApps,
- bool opt_debuggable);
-
-#endif // __RNBServices_h__
diff --git a/tools/debugserver/source/RNBSocket.cpp b/tools/debugserver/source/RNBSocket.cpp
deleted file mode 100644
index 88136c210acc..000000000000
--- a/tools/debugserver/source/RNBSocket.cpp
+++ /dev/null
@@ -1,392 +0,0 @@
-//===-- RNBSocket.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 12/12/07.
-//
-//===----------------------------------------------------------------------===//
-
-#include "RNBSocket.h"
-#include "DNBError.h"
-#include "DNBLog.h"
-#include <arpa/inet.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <map>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <sys/event.h>
-#include <termios.h>
-#include <vector>
-
-#include "lldb/Host/SocketAddress.h"
-
-#ifdef WITH_LOCKDOWN
-#include "lockdown.h"
-#endif
-
-/* Once we have a RNBSocket object with a port # specified,
- this function is called to wait for an incoming connection.
- This function blocks while waiting for that connection. */
-
-bool ResolveIPV4HostName(const char *hostname, in_addr_t &addr) {
- if (hostname == NULL || hostname[0] == '\0' ||
- strcmp(hostname, "localhost") == 0 ||
- strcmp(hostname, "127.0.0.1") == 0) {
- addr = htonl(INADDR_LOOPBACK);
- return true;
- } else if (strcmp(hostname, "*") == 0) {
- addr = htonl(INADDR_ANY);
- return true;
- } else {
- // See if an IP address was specified as numbers
- int inet_pton_result = ::inet_pton(AF_INET, hostname, &addr);
-
- if (inet_pton_result == 1)
- return true;
-
- struct hostent *host_entry = gethostbyname(hostname);
- if (host_entry) {
- std::string ip_str(
- ::inet_ntoa(*(struct in_addr *)*host_entry->h_addr_list));
- inet_pton_result = ::inet_pton(AF_INET, ip_str.c_str(), &addr);
- if (inet_pton_result == 1)
- return true;
- }
- }
- return false;
-}
-
-rnb_err_t RNBSocket::Listen(const char *listen_host, uint16_t port,
- PortBoundCallback callback,
- const void *callback_baton) {
- // DNBLogThreadedIf(LOG_RNB_COMM, "%8u RNBSocket::%s called",
- // (uint32_t)m_timer.ElapsedMicroSeconds(true), __FUNCTION__);
- // Disconnect without saving errno
- Disconnect(false);
-
- DNBError err;
- int queue_id = kqueue();
- if (queue_id < 0) {
- err.SetError(errno, DNBError::MachKernel);
- err.LogThreaded("error: failed to create kqueue.");
- return rnb_err;
- }
-
- bool any_addr = (strcmp(listen_host, "*") == 0);
-
- // If the user wants to allow connections from any address we should create
- // sockets on all families that can resolve localhost. This will allow us to
- // listen for IPv6 and IPv4 connections from all addresses if those interfaces
- // are available.
- const char *local_addr = any_addr ? "localhost" : listen_host;
-
- std::map<int, lldb_private::SocketAddress> sockets;
- auto addresses = lldb_private::SocketAddress::GetAddressInfo(
- local_addr, NULL, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);
-
- for (auto address : addresses) {
- int sock_fd = ::socket(address.GetFamily(), SOCK_STREAM, IPPROTO_TCP);
- if (sock_fd == -1)
- continue;
-
- SetSocketOption(sock_fd, SOL_SOCKET, SO_REUSEADDR, 1);
-
- lldb_private::SocketAddress bind_address = address;
-
- if(any_addr || !bind_address.IsLocalhost())
- bind_address.SetToAnyAddress(bind_address.GetFamily(), port);
- else
- bind_address.SetPort(port);
-
- int error =
- ::bind(sock_fd, &bind_address.sockaddr(), bind_address.GetLength());
- if (error == -1) {
- ClosePort(sock_fd, false);
- continue;
- }
-
- error = ::listen(sock_fd, 5);
- if (error == -1) {
- ClosePort(sock_fd, false);
- continue;
- }
-
- // We were asked to listen on port zero which means we must now read the
- // actual port that was given to us as port zero is a special code for "find
- // an open port for me". This will only execute on the first socket created,
- // subesquent sockets will reuse this port number.
- if (port == 0) {
- socklen_t sa_len = address.GetLength();
- if (getsockname(sock_fd, &address.sockaddr(), &sa_len) == 0)
- port = address.GetPort();
- }
-
- sockets[sock_fd] = address;
- }
-
- if (sockets.size() == 0) {
- err.SetError(errno, DNBError::POSIX);
- err.LogThreaded("::listen or ::bind failed");
- return rnb_err;
- }
-
- if (callback)
- callback(callback_baton, port);
-
- std::vector<struct kevent> events;
- events.resize(sockets.size());
- int i = 0;
- for (auto socket : sockets) {
- EV_SET(&events[i++], socket.first, EVFILT_READ, EV_ADD, 0, 0, 0);
- }
-
- bool accept_connection = false;
-
- // Loop until we are happy with our connection
- while (!accept_connection) {
-
- struct kevent event_list[4];
- int num_events =
- kevent(queue_id, events.data(), events.size(), event_list, 4, NULL);
-
- if (num_events < 0) {
- err.SetError(errno, DNBError::MachKernel);
- err.LogThreaded("error: kevent() failed.");
- }
-
- for (int i = 0; i < num_events; ++i) {
- auto sock_fd = event_list[i].ident;
- auto socket_pair = sockets.find(sock_fd);
- if (socket_pair == sockets.end())
- continue;
-
- lldb_private::SocketAddress &addr_in = socket_pair->second;
- lldb_private::SocketAddress accept_addr;
- socklen_t sa_len = accept_addr.GetMaxLength();
- m_fd = ::accept(sock_fd, &accept_addr.sockaddr(), &sa_len);
-
- if (m_fd == -1) {
- err.SetError(errno, DNBError::POSIX);
- err.LogThreaded("error: Socket accept failed.");
- }
-
- if (addr_in.IsAnyAddr())
- accept_connection = true;
- else {
- if (accept_addr == addr_in)
- accept_connection = true;
- else {
- ::close(m_fd);
- m_fd = -1;
- ::fprintf(
- stderr,
- "error: rejecting incoming connection from %s (expecting %s)\n",
- accept_addr.GetIPAddress().c_str(),
- addr_in.GetIPAddress().c_str());
- DNBLogThreaded("error: rejecting connection from %s (expecting %s)\n",
- accept_addr.GetIPAddress().c_str(),
- addr_in.GetIPAddress().c_str());
- err.Clear();
- }
- }
- }
- if (err.Fail())
- break;
- }
- for (auto socket : sockets) {
- int ListenFd = socket.first;
- ClosePort(ListenFd, false);
- }
-
- if (err.Fail())
- return rnb_err;
-
- // Keep our TCP packets coming without any delays.
- SetSocketOption(m_fd, IPPROTO_TCP, TCP_NODELAY, 1);
-
- return rnb_success;
-}
-
-rnb_err_t RNBSocket::Connect(const char *host, uint16_t port) {
- auto result = rnb_err;
- Disconnect(false);
-
- auto addresses = lldb_private::SocketAddress::GetAddressInfo(
- host, NULL, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);
-
- for (auto address : addresses) {
- m_fd = ::socket(address.GetFamily(), SOCK_STREAM, IPPROTO_TCP);
- if (m_fd == -1)
- continue;
-
- // Enable local address reuse
- SetSocketOption(m_fd, SOL_SOCKET, SO_REUSEADDR, 1);
-
- address.SetPort(port);
-
- if (-1 == ::connect(m_fd, &address.sockaddr(), address.GetLength())) {
- Disconnect(false);
- continue;
- }
- SetSocketOption(m_fd, IPPROTO_TCP, TCP_NODELAY, 1);
-
- result = rnb_success;
- break;
- }
- return result;
-}
-
-rnb_err_t RNBSocket::useFD(int fd) {
- if (fd < 0) {
- DNBLogThreadedIf(LOG_RNB_COMM, "Bad file descriptor passed in.");
- return rnb_err;
- }
-
- m_fd = fd;
- return rnb_success;
-}
-
-#ifdef WITH_LOCKDOWN
-rnb_err_t RNBSocket::ConnectToService() {
- DNBLog("Connecting to com.apple.%s service...", DEBUGSERVER_PROGRAM_NAME);
- // Disconnect from any previous connections
- Disconnect(false);
- if (::secure_lockdown_checkin(&m_ld_conn, NULL, NULL) != kLDESuccess) {
- DNBLogThreadedIf(LOG_RNB_COMM,
- "::secure_lockdown_checkin(&m_fd, NULL, NULL) failed");
- m_fd = -1;
- return rnb_not_connected;
- }
- m_fd = ::lockdown_get_socket(m_ld_conn);
- if (m_fd == -1) {
- DNBLogThreadedIf(LOG_RNB_COMM, "::lockdown_get_socket() failed");
- return rnb_not_connected;
- }
- m_fd_from_lockdown = true;
- return rnb_success;
-}
-#endif
-
-rnb_err_t RNBSocket::OpenFile(const char *path) {
- DNBError err;
- m_fd = open(path, O_RDWR);
- if (m_fd == -1) {
- err.SetError(errno, DNBError::POSIX);
- err.LogThreaded("can't open file '%s'", path);
- return rnb_not_connected;
- } else {
- struct termios stdin_termios;
-
- if (::tcgetattr(m_fd, &stdin_termios) == 0) {
- stdin_termios.c_lflag &= ~ECHO; // Turn off echoing
- stdin_termios.c_lflag &= ~ICANON; // Get one char at a time
- ::tcsetattr(m_fd, TCSANOW, &stdin_termios);
- }
- }
- return rnb_success;
-}
-
-int RNBSocket::SetSocketOption(int fd, int level, int option_name,
- int option_value) {
- return ::setsockopt(fd, level, option_name, &option_value,
- sizeof(option_value));
-}
-
-rnb_err_t RNBSocket::Disconnect(bool save_errno) {
-#ifdef WITH_LOCKDOWN
- if (m_fd_from_lockdown) {
- m_fd_from_lockdown = false;
- m_fd = -1;
- lockdown_disconnect(m_ld_conn);
- return rnb_success;
- }
-#endif
- return ClosePort(m_fd, save_errno);
-}
-
-rnb_err_t RNBSocket::Read(std::string &p) {
- char buf[1024];
- p.clear();
-
- // Note that BUF is on the stack so we must be careful to keep any
- // writes to BUF from overflowing or we'll have security issues.
-
- if (m_fd == -1)
- return rnb_err;
-
- // DNBLogThreadedIf(LOG_RNB_COMM, "%8u RNBSocket::%s calling read()",
- // (uint32_t)m_timer.ElapsedMicroSeconds(true), __FUNCTION__);
- DNBError err;
- ssize_t bytesread = read(m_fd, buf, sizeof(buf));
- if (bytesread <= 0)
- err.SetError(errno, DNBError::POSIX);
- else
- p.append(buf, bytesread);
-
- if (err.Fail() || DNBLogCheckLogBit(LOG_RNB_COMM))
- err.LogThreaded("::read ( %i, %p, %llu ) => %i", m_fd, buf, sizeof(buf),
- (uint64_t)bytesread);
-
- // Our port went away - we have to mark this so IsConnected will return the
- // truth.
- if (bytesread == 0) {
- m_fd = -1;
- return rnb_not_connected;
- } else if (bytesread == -1) {
- m_fd = -1;
- return rnb_err;
- }
- // Strip spaces from the end of the buffer
- while (!p.empty() && isspace(p[p.size() - 1]))
- p.erase(p.size() - 1);
-
- // Most data in the debugserver packets valid printable characters...
- DNBLogThreadedIf(LOG_RNB_COMM, "read: %s", p.c_str());
- return rnb_success;
-}
-
-rnb_err_t RNBSocket::Write(const void *buffer, size_t length) {
- if (m_fd == -1)
- return rnb_err;
-
- DNBError err;
- ssize_t bytessent = write(m_fd, buffer, length);
- if (bytessent < 0)
- err.SetError(errno, DNBError::POSIX);
-
- if (err.Fail() || DNBLogCheckLogBit(LOG_RNB_COMM))
- err.LogThreaded("::write ( socket = %i, buffer = %p, length = %llu) => %i",
- m_fd, buffer, length, (uint64_t)bytessent);
-
- if (bytessent < 0)
- return rnb_err;
-
- if ((size_t)bytessent != length)
- return rnb_err;
-
- DNBLogThreadedIf(
- LOG_RNB_PACKETS, "putpkt: %*s", (int)length,
- (const char *)
- buffer); // All data is string based in debugserver, so this is safe
- DNBLogThreadedIf(LOG_RNB_COMM, "sent: %*s", (int)length,
- (const char *)buffer);
-
- return rnb_success;
-}
-
-rnb_err_t RNBSocket::ClosePort(int &fd, bool save_errno) {
- int close_err = 0;
- if (fd > 0) {
- errno = 0;
- close_err = close(fd);
- fd = -1;
- }
- return close_err != 0 ? rnb_err : rnb_success;
-}
diff --git a/tools/debugserver/source/RNBSocket.h b/tools/debugserver/source/RNBSocket.h
deleted file mode 100644
index 9f636d855621..000000000000
--- a/tools/debugserver/source/RNBSocket.h
+++ /dev/null
@@ -1,79 +0,0 @@
-//===-- RNBSocket.h ---------------------------------------------*- 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 12/12/07.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __RNBSocket_h__
-#define __RNBSocket_h__
-
-#include "DNBTimer.h"
-#include "RNBDefs.h"
-#include <string>
-#include <sys/socket.h>
-#include <sys/types.h>
-
-#ifdef WITH_LOCKDOWN
-#include "lockdown.h"
-#endif
-
-class RNBSocket {
-public:
- typedef void (*PortBoundCallback)(const void *baton, uint16_t port);
-
- RNBSocket()
- : m_fd(-1),
-#ifdef WITH_LOCKDOWN
- m_fd_from_lockdown(false), m_ld_conn(),
-#endif
- m_timer(true) // Make a thread safe timer
- {
- }
- ~RNBSocket(void) { Disconnect(false); }
-
- rnb_err_t Listen(const char *listen_host, uint16_t port,
- PortBoundCallback callback, const void *callback_baton);
- rnb_err_t Connect(const char *host, uint16_t port);
-
- rnb_err_t useFD(int fd);
-
-#ifdef WITH_LOCKDOWN
- rnb_err_t ConnectToService();
-#endif
- rnb_err_t OpenFile(const char *path);
- rnb_err_t Disconnect(bool save_errno);
- rnb_err_t Read(std::string &p);
- rnb_err_t Write(const void *buffer, size_t length);
-
- bool IsConnected() const { return m_fd != -1; }
- void SaveErrno(int curr_errno);
- DNBTimer &Timer() { return m_timer; }
-
- static int SetSocketOption(int fd, int level, int option_name,
- int option_value);
-
-private:
- // Outlaw some constructors
- RNBSocket(const RNBSocket &);
-
-protected:
- rnb_err_t ClosePort(int &fd, bool save_errno);
-
- int m_fd; // Socket we use to communicate once conn established
-
-#ifdef WITH_LOCKDOWN
- bool m_fd_from_lockdown;
- lockdown_connection m_ld_conn;
-#endif
-
- DNBTimer m_timer;
-};
-
-#endif // #ifndef __RNBSocket_h__
diff --git a/tools/debugserver/source/StdStringExtractor.cpp b/tools/debugserver/source/StdStringExtractor.cpp
deleted file mode 100644
index 3b400b2a89d2..000000000000
--- a/tools/debugserver/source/StdStringExtractor.cpp
+++ /dev/null
@@ -1,401 +0,0 @@
-//===-- StdStringExtractor.cpp ----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "StdStringExtractor.h"
-
-#include <stdlib.h>
-
-
-static inline int xdigit_to_sint(char ch) {
- if (ch >= 'a' && ch <= 'f')
- return 10 + ch - 'a';
- if (ch >= 'A' && ch <= 'F')
- return 10 + ch - 'A';
- if (ch >= '0' && ch <= '9')
- return ch - '0';
- return -1;
-}
-
-//----------------------------------------------------------------------
-// StdStringExtractor constructor
-//----------------------------------------------------------------------
-StdStringExtractor::StdStringExtractor() : m_packet(), m_index(0) {}
-
-StdStringExtractor::StdStringExtractor(const char *packet_cstr)
- : m_packet(), m_index(0) {
- if (packet_cstr)
- m_packet.assign(packet_cstr);
-}
-
-//----------------------------------------------------------------------
-// StdStringExtractor copy constructor
-//----------------------------------------------------------------------
-StdStringExtractor::StdStringExtractor(const StdStringExtractor &rhs)
- : m_packet(rhs.m_packet), m_index(rhs.m_index) {}
-
-//----------------------------------------------------------------------
-// StdStringExtractor assignment operator
-//----------------------------------------------------------------------
-const StdStringExtractor &StdStringExtractor::
-operator=(const StdStringExtractor &rhs) {
- if (this != &rhs) {
- m_packet = rhs.m_packet;
- m_index = rhs.m_index;
- }
- return *this;
-}
-
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-StdStringExtractor::~StdStringExtractor() {}
-
-char StdStringExtractor::GetChar(char fail_value) {
- if (m_index < m_packet.size()) {
- char ch = m_packet[m_index];
- ++m_index;
- return ch;
- }
- m_index = UINT64_MAX;
- return fail_value;
-}
-
-//----------------------------------------------------------------------
-// If a pair of valid hex digits exist at the head of the
-// StdStringExtractor they are decoded into an unsigned byte and returned
-// by this function
-//
-// If there is not a pair of valid hex digits at the head of the
-// StdStringExtractor, it is left unchanged and -1 is returned
-//----------------------------------------------------------------------
-int StdStringExtractor::DecodeHexU8() {
- SkipSpaces();
- if (GetBytesLeft() < 2) {
- return -1;
- }
- const int hi_nibble = xdigit_to_sint(m_packet[m_index]);
- const int lo_nibble = xdigit_to_sint(m_packet[m_index + 1]);
- if (hi_nibble == -1 || lo_nibble == -1) {
- return -1;
- }
- m_index += 2;
- return (uint8_t)((hi_nibble << 4) + lo_nibble);
-}
-
-//----------------------------------------------------------------------
-// Extract an unsigned character from two hex ASCII chars in the packet
-// string, or return fail_value on failure
-//----------------------------------------------------------------------
-uint8_t StdStringExtractor::GetHexU8(uint8_t fail_value, bool set_eof_on_fail) {
- // On success, fail_value will be overwritten with the next
- // character in the stream
- GetHexU8Ex(fail_value, set_eof_on_fail);
- return fail_value;
-}
-
-bool StdStringExtractor::GetHexU8Ex(uint8_t &ch, bool set_eof_on_fail) {
- int byte = DecodeHexU8();
- if (byte == -1) {
- if (set_eof_on_fail || m_index >= m_packet.size())
- m_index = UINT64_MAX;
- // ch should not be changed in case of failure
- return false;
- }
- ch = (uint8_t)byte;
- return true;
-}
-
-uint32_t StdStringExtractor::GetU32(uint32_t fail_value, int base) {
- if (m_index < m_packet.size()) {
- char *end = nullptr;
- const char *start = m_packet.c_str();
- const char *cstr = start + m_index;
- uint32_t result = static_cast<uint32_t>(::strtoul(cstr, &end, base));
-
- if (end && end != cstr) {
- m_index = end - start;
- return result;
- }
- }
- return fail_value;
-}
-
-int32_t StdStringExtractor::GetS32(int32_t fail_value, int base) {
- if (m_index < m_packet.size()) {
- char *end = nullptr;
- const char *start = m_packet.c_str();
- const char *cstr = start + m_index;
- int32_t result = static_cast<int32_t>(::strtol(cstr, &end, base));
-
- if (end && end != cstr) {
- m_index = end - start;
- return result;
- }
- }
- return fail_value;
-}
-
-uint64_t StdStringExtractor::GetU64(uint64_t fail_value, int base) {
- if (m_index < m_packet.size()) {
- char *end = nullptr;
- const char *start = m_packet.c_str();
- const char *cstr = start + m_index;
- uint64_t result = ::strtoull(cstr, &end, base);
-
- if (end && end != cstr) {
- m_index = end - start;
- return result;
- }
- }
- return fail_value;
-}
-
-int64_t StdStringExtractor::GetS64(int64_t fail_value, int base) {
- if (m_index < m_packet.size()) {
- char *end = nullptr;
- const char *start = m_packet.c_str();
- const char *cstr = start + m_index;
- int64_t result = ::strtoll(cstr, &end, base);
-
- if (end && end != cstr) {
- m_index = end - start;
- return result;
- }
- }
- return fail_value;
-}
-
-uint32_t StdStringExtractor::GetHexMaxU32(bool little_endian,
- uint32_t fail_value) {
- uint32_t result = 0;
- uint32_t nibble_count = 0;
-
- SkipSpaces();
- if (little_endian) {
- uint32_t shift_amount = 0;
- while (m_index < m_packet.size() && ::isxdigit(m_packet[m_index])) {
- // Make sure we don't exceed the size of a uint32_t...
- if (nibble_count >= (sizeof(uint32_t) * 2)) {
- m_index = UINT64_MAX;
- return fail_value;
- }
-
- uint8_t nibble_lo;
- uint8_t nibble_hi = xdigit_to_sint(m_packet[m_index]);
- ++m_index;
- if (m_index < m_packet.size() && ::isxdigit(m_packet[m_index])) {
- nibble_lo = xdigit_to_sint(m_packet[m_index]);
- ++m_index;
- result |= ((uint32_t)nibble_hi << (shift_amount + 4));
- result |= ((uint32_t)nibble_lo << shift_amount);
- nibble_count += 2;
- shift_amount += 8;
- } else {
- result |= ((uint32_t)nibble_hi << shift_amount);
- nibble_count += 1;
- shift_amount += 4;
- }
- }
- } else {
- while (m_index < m_packet.size() && ::isxdigit(m_packet[m_index])) {
- // Make sure we don't exceed the size of a uint32_t...
- if (nibble_count >= (sizeof(uint32_t) * 2)) {
- m_index = UINT64_MAX;
- return fail_value;
- }
-
- uint8_t nibble = xdigit_to_sint(m_packet[m_index]);
- // Big Endian
- result <<= 4;
- result |= nibble;
-
- ++m_index;
- ++nibble_count;
- }
- }
- return result;
-}
-
-uint64_t StdStringExtractor::GetHexMaxU64(bool little_endian,
- uint64_t fail_value) {
- uint64_t result = 0;
- uint32_t nibble_count = 0;
-
- SkipSpaces();
- if (little_endian) {
- uint32_t shift_amount = 0;
- while (m_index < m_packet.size() && ::isxdigit(m_packet[m_index])) {
- // Make sure we don't exceed the size of a uint64_t...
- if (nibble_count >= (sizeof(uint64_t) * 2)) {
- m_index = UINT64_MAX;
- return fail_value;
- }
-
- uint8_t nibble_lo;
- uint8_t nibble_hi = xdigit_to_sint(m_packet[m_index]);
- ++m_index;
- if (m_index < m_packet.size() && ::isxdigit(m_packet[m_index])) {
- nibble_lo = xdigit_to_sint(m_packet[m_index]);
- ++m_index;
- result |= ((uint64_t)nibble_hi << (shift_amount + 4));
- result |= ((uint64_t)nibble_lo << shift_amount);
- nibble_count += 2;
- shift_amount += 8;
- } else {
- result |= ((uint64_t)nibble_hi << shift_amount);
- nibble_count += 1;
- shift_amount += 4;
- }
- }
- } else {
- while (m_index < m_packet.size() && ::isxdigit(m_packet[m_index])) {
- // Make sure we don't exceed the size of a uint64_t...
- if (nibble_count >= (sizeof(uint64_t) * 2)) {
- m_index = UINT64_MAX;
- return fail_value;
- }
-
- uint8_t nibble = xdigit_to_sint(m_packet[m_index]);
- // Big Endian
- result <<= 4;
- result |= nibble;
-
- ++m_index;
- ++nibble_count;
- }
- }
- return result;
-}
-
-size_t StdStringExtractor::GetHexBytes(void *dst_void, size_t dst_len,
- uint8_t fail_fill_value) {
- uint8_t *dst = (uint8_t *)dst_void;
- size_t bytes_extracted = 0;
- while (bytes_extracted < dst_len && GetBytesLeft()) {
- dst[bytes_extracted] = GetHexU8(fail_fill_value);
- if (IsGood())
- ++bytes_extracted;
- else
- break;
- }
-
- for (size_t i = bytes_extracted; i < dst_len; ++i)
- dst[i] = fail_fill_value;
-
- return bytes_extracted;
-}
-
-//----------------------------------------------------------------------
-// Decodes all valid hex encoded bytes at the head of the
-// StdStringExtractor, limited by dst_len.
-//
-// Returns the number of bytes successfully decoded
-//----------------------------------------------------------------------
-size_t StdStringExtractor::GetHexBytesAvail(void *dst_void, size_t dst_len) {
- uint8_t *dst = (uint8_t *)dst_void;
- size_t bytes_extracted = 0;
- while (bytes_extracted < dst_len) {
- int decode = DecodeHexU8();
- if (decode == -1) {
- break;
- }
- dst[bytes_extracted++] = (uint8_t)decode;
- }
- return bytes_extracted;
-}
-
-// Consume ASCII hex nibble character pairs until we have decoded byte_size
-// bytes of data.
-
-uint64_t StdStringExtractor::GetHexWithFixedSize(uint32_t byte_size,
- bool little_endian,
- uint64_t fail_value) {
- if (byte_size <= 8 && GetBytesLeft() >= byte_size * 2) {
- uint64_t result = 0;
- uint32_t i;
- if (little_endian) {
- // Little Endian
- uint32_t shift_amount;
- for (i = 0, shift_amount = 0; i < byte_size && IsGood();
- ++i, shift_amount += 8) {
- result |= ((uint64_t)GetHexU8() << shift_amount);
- }
- } else {
- // Big Endian
- for (i = 0; i < byte_size && IsGood(); ++i) {
- result <<= 8;
- result |= GetHexU8();
- }
- }
- }
- m_index = UINT64_MAX;
- return fail_value;
-}
-
-size_t StdStringExtractor::GetHexByteString(std::string &str) {
- str.clear();
- str.reserve(GetBytesLeft() / 2);
- char ch;
- while ((ch = GetHexU8()) != '\0')
- str.append(1, ch);
- return str.size();
-}
-
-size_t StdStringExtractor::GetHexByteStringFixedLength(std::string &str,
- uint32_t nibble_length) {
- str.clear();
-
- uint32_t nibble_count = 0;
- for (const char *pch = Peek();
- (nibble_count < nibble_length) && (pch != nullptr);
- str.append(1, GetHexU8(0, false)), pch = Peek(), nibble_count += 2) {
- }
-
- return str.size();
-}
-
-size_t StdStringExtractor::GetHexByteStringTerminatedBy(std::string &str,
- char terminator) {
- str.clear();
- char ch;
- while ((ch = GetHexU8(0, false)) != '\0')
- str.append(1, ch);
- if (Peek() && *Peek() == terminator)
- return str.size();
-
- str.clear();
- return str.size();
-}
-
-bool StdStringExtractor::GetNameColonValue(std::string &name,
- std::string &value) {
- // Read something in the form of NNNN:VVVV; where NNNN is any character
- // that is not a colon, followed by a ':' character, then a value (one or
- // more ';' chars), followed by a ';'
- if (m_index < m_packet.size()) {
- const size_t colon_idx = m_packet.find(':', m_index);
- if (colon_idx != std::string::npos) {
- const size_t semicolon_idx = m_packet.find(';', colon_idx);
- if (semicolon_idx != std::string::npos) {
- name.assign(m_packet, m_index, colon_idx - m_index);
- value.assign(m_packet, colon_idx + 1, semicolon_idx - (colon_idx + 1));
- m_index = semicolon_idx + 1;
- return true;
- }
- }
- }
- m_index = UINT64_MAX;
- return false;
-}
-
-void StdStringExtractor::SkipSpaces() {
- const size_t n = m_packet.size();
- while (m_index < n && isspace(m_packet[m_index]))
- ++m_index;
-}
diff --git a/tools/debugserver/source/StdStringExtractor.h b/tools/debugserver/source/StdStringExtractor.h
deleted file mode 100644
index 40b57cb08fb5..000000000000
--- a/tools/debugserver/source/StdStringExtractor.h
+++ /dev/null
@@ -1,121 +0,0 @@
-//===-- StdStringExtractor.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_StdStringExtractor_h_
-#define utility_StdStringExtractor_h_
-
-#include <stdint.h>
-#include <string>
-
-
-// Based on StringExtractor, with the added limitation that this file should not
-// take a dependency on LLVM, as it is used from debugserver.
-class StdStringExtractor {
-public:
- enum { BigEndian = 0, LittleEndian = 1 };
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- StdStringExtractor();
- StdStringExtractor(const char *packet_cstr);
- StdStringExtractor(const StdStringExtractor &rhs);
- virtual ~StdStringExtractor();
-
- //------------------------------------------------------------------
- // Operators
- //------------------------------------------------------------------
- const StdStringExtractor &operator=(const StdStringExtractor &rhs);
-
- // Returns true if the file position is still valid for the data
- // contained in this string extractor object.
- bool IsGood() const { return m_index != UINT64_MAX; }
-
- uint64_t GetFilePos() const { return m_index; }
-
- void SetFilePos(uint32_t idx) { m_index = idx; }
-
- void Clear() {
- m_packet.clear();
- m_index = 0;
- }
-
- void SkipSpaces();
-
- std::string &GetStringRef() { return m_packet; }
-
- const std::string &GetStringRef() const { return m_packet; }
-
- bool Empty() { return m_packet.empty(); }
-
- size_t GetBytesLeft() {
- if (m_index < m_packet.size())
- return m_packet.size() - m_index;
- return 0;
- }
-
- char GetChar(char fail_value = '\0');
-
- char PeekChar(char fail_value = '\0') {
- const char *cstr = Peek();
- if (cstr)
- return cstr[0];
- return fail_value;
- }
-
- int DecodeHexU8();
-
- uint8_t GetHexU8(uint8_t fail_value = 0, bool set_eof_on_fail = true);
-
- bool GetHexU8Ex(uint8_t &ch, bool set_eof_on_fail = true);
-
- bool GetNameColonValue(std::string &name, std::string &value);
-
- int32_t GetS32(int32_t fail_value, int base = 0);
-
- uint32_t GetU32(uint32_t fail_value, int base = 0);
-
- int64_t GetS64(int64_t fail_value, int base = 0);
-
- uint64_t GetU64(uint64_t fail_value, int base = 0);
-
- uint32_t GetHexMaxU32(bool little_endian, uint32_t fail_value);
-
- uint64_t GetHexMaxU64(bool little_endian, uint64_t fail_value);
-
- size_t GetHexBytes(void *dst, size_t dst_len, uint8_t fail_fill_value);
-
- size_t GetHexBytesAvail(void *dst, size_t dst_len);
-
- uint64_t GetHexWithFixedSize(uint32_t byte_size, bool little_endian,
- uint64_t fail_value);
-
- size_t GetHexByteString(std::string &str);
-
- size_t GetHexByteStringFixedLength(std::string &str, uint32_t nibble_length);
-
- size_t GetHexByteStringTerminatedBy(std::string &str, char terminator);
-
- const char *Peek() {
- if (m_index < m_packet.size())
- return m_packet.c_str() + m_index;
- return nullptr;
- }
-
-protected:
- //------------------------------------------------------------------
- // For StdStringExtractor only
- //------------------------------------------------------------------
- std::string m_packet; // The string in which to extract data.
- uint64_t m_index; // When extracting data from a packet, this index
- // will march along as things get extracted. If set
- // to UINT64_MAX the end of the packet data was
- // reached when decoding information
-};
-
-#endif // utility_StringExtractor_h_
diff --git a/tools/debugserver/source/SysSignal.cpp b/tools/debugserver/source/SysSignal.cpp
deleted file mode 100644
index c2995f362c03..000000000000
--- a/tools/debugserver/source/SysSignal.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-//===-- SysSignal.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/18/07.
-//
-//===----------------------------------------------------------------------===//
-
-#include "SysSignal.h"
-#include <signal.h>
-#include <stddef.h>
-
-const char *SysSignal::Name(int signal) {
- switch (signal) {
- case SIGHUP:
- return "SIGHUP"; // 1 hangup
- case SIGINT:
- return "SIGINT"; // 2 interrupt
- case SIGQUIT:
- return "SIGQUIT"; // 3 quit
- case SIGILL:
- return "SIGILL"; // 4 illegal instruction (not reset when caught)
- case SIGTRAP:
- return "SIGTRAP"; // 5 trace trap (not reset when caught)
- case SIGABRT:
- return "SIGABRT"; // 6 abort()
-#if defined(_POSIX_C_SOURCE)
- case SIGPOLL:
- return "SIGPOLL"; // 7 pollable event ([XSR] generated, not supported)
-#else // !_POSIX_C_SOURCE
- case SIGEMT:
- return "SIGEMT"; // 7 EMT instruction
-#endif // !_POSIX_C_SOURCE
- case SIGFPE:
- return "SIGFPE"; // 8 floating point exception
- case SIGKILL:
- return "SIGKILL"; // 9 kill (cannot be caught or ignored)
- case SIGBUS:
- return "SIGBUS"; // 10 bus error
- case SIGSEGV:
- return "SIGSEGV"; // 11 segmentation violation
- case SIGSYS:
- return "SIGSYS"; // 12 bad argument to system call
- case SIGPIPE:
- return "SIGPIPE"; // 13 write on a pipe with no one to read it
- case SIGALRM:
- return "SIGALRM"; // 14 alarm clock
- case SIGTERM:
- return "SIGTERM"; // 15 software termination signal from kill
- case SIGURG:
- return "SIGURG"; // 16 urgent condition on IO channel
- case SIGSTOP:
- return "SIGSTOP"; // 17 sendable stop signal not from tty
- case SIGTSTP:
- return "SIGTSTP"; // 18 stop signal from tty
- case SIGCONT:
- return "SIGCONT"; // 19 continue a stopped process
- case SIGCHLD:
- return "SIGCHLD"; // 20 to parent on child stop or exit
- case SIGTTIN:
- return "SIGTTIN"; // 21 to readers pgrp upon background tty read
- case SIGTTOU:
- return "SIGTTOU"; // 22 like TTIN for output if (tp->t_local&LTOSTOP)
-#if !defined(_POSIX_C_SOURCE)
- case SIGIO:
- return "SIGIO"; // 23 input/output possible signal
-#endif
- case SIGXCPU:
- return "SIGXCPU"; // 24 exceeded CPU time limit
- case SIGXFSZ:
- return "SIGXFSZ"; // 25 exceeded file size limit
- case SIGVTALRM:
- return "SIGVTALRM"; // 26 virtual time alarm
- case SIGPROF:
- return "SIGPROF"; // 27 profiling time alarm
-#if !defined(_POSIX_C_SOURCE)
- case SIGWINCH:
- return "SIGWINCH"; // 28 window size changes
- case SIGINFO:
- return "SIGINFO"; // 29 information request
-#endif
- case SIGUSR1:
- return "SIGUSR1"; // 30 user defined signal 1
- case SIGUSR2:
- return "SIGUSR2"; // 31 user defined signal 2
- default:
- break;
- }
- return NULL;
-}
diff --git a/tools/debugserver/source/SysSignal.h b/tools/debugserver/source/SysSignal.h
deleted file mode 100644
index c9827126c18b..000000000000
--- a/tools/debugserver/source/SysSignal.h
+++ /dev/null
@@ -1,22 +0,0 @@
-//===-- SysSignal.h ---------------------------------------------*- 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/18/07.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __SysSignal_h__
-#define __SysSignal_h__
-
-class SysSignal {
-public:
- static const char *Name(int signal);
-};
-
-#endif
diff --git a/tools/debugserver/source/TTYState.cpp b/tools/debugserver/source/TTYState.cpp
deleted file mode 100644
index 5f10050fcdde..000000000000
--- a/tools/debugserver/source/TTYState.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-//===-- TTYState.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 3/26/07.
-//
-//===----------------------------------------------------------------------===//
-
-#include "TTYState.h"
-#include <fcntl.h>
-#include <sys/signal.h>
-#include <unistd.h>
-
-TTYState::TTYState()
- : m_fd(-1), m_tflags(-1), m_ttystateErr(-1), m_processGroup(-1) {}
-
-TTYState::~TTYState() {}
-
-bool TTYState::GetTTYState(int fd, bool saveProcessGroup) {
- if (fd >= 0 && ::isatty(fd)) {
- m_fd = fd;
- m_tflags = fcntl(fd, F_GETFL, 0);
- m_ttystateErr = tcgetattr(fd, &m_ttystate);
- if (saveProcessGroup)
- m_processGroup = tcgetpgrp(0);
- else
- m_processGroup = -1;
- } else {
- m_fd = -1;
- m_tflags = -1;
- m_ttystateErr = -1;
- m_processGroup = -1;
- }
- return m_ttystateErr == 0;
-}
-
-bool TTYState::SetTTYState() const {
- int result = 0;
- if (IsValid()) {
- if (TFlagsValid())
- result = fcntl(m_fd, F_SETFL, m_tflags);
-
- if (TTYStateValid())
- result = tcsetattr(m_fd, TCSANOW, &m_ttystate);
-
- if (ProcessGroupValid()) {
- // Save the original signal handler.
- void (*saved_sigttou_callback)(int) = NULL;
- saved_sigttou_callback = (void (*)(int))signal(SIGTTOU, SIG_IGN);
- // Set the process group
- result = tcsetpgrp(m_fd, m_processGroup);
- // Restore the original signal handler.
- signal(SIGTTOU, saved_sigttou_callback);
- }
- return true;
- }
- return false;
-}
-
-TTYStateSwitcher::TTYStateSwitcher() : m_currentState(~0) {}
-
-TTYStateSwitcher::~TTYStateSwitcher() {}
-
-bool TTYStateSwitcher::GetState(uint32_t idx, int fd, bool saveProcessGroup) {
- if (ValidStateIndex(idx))
- return m_ttystates[idx].GetTTYState(fd, saveProcessGroup);
- return false;
-}
-
-bool TTYStateSwitcher::SetState(uint32_t idx) const {
- if (!ValidStateIndex(idx))
- return false;
-
- // See if we already are in this state?
- if (ValidStateIndex(m_currentState) && (idx == m_currentState) &&
- m_ttystates[idx].IsValid())
- return true;
-
- // Set the state to match the index passed in and only update the
- // current state if there are no errors.
- if (m_ttystates[idx].SetTTYState()) {
- m_currentState = idx;
- return true;
- }
-
- // We failed to set the state. The tty state was invalid or not
- // initialized.
- return false;
-}
diff --git a/tools/debugserver/source/TTYState.h b/tools/debugserver/source/TTYState.h
deleted file mode 100644
index 88b6d3c2462e..000000000000
--- a/tools/debugserver/source/TTYState.h
+++ /dev/null
@@ -1,59 +0,0 @@
-//===-- TTYState.h ----------------------------------------------*- 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 3/26/07.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __TTYState_h__
-#define __TTYState_h__
-
-#include <stdint.h>
-#include <termios.h>
-
-class TTYState {
-public:
- TTYState();
- ~TTYState();
-
- bool GetTTYState(int fd, bool saveProcessGroup);
- bool SetTTYState() const;
-
- bool IsValid() const {
- return FileDescriptorValid() && TFlagsValid() && TTYStateValid();
- }
- bool FileDescriptorValid() const { return m_fd >= 0; }
- bool TFlagsValid() const { return m_tflags != -1; }
- bool TTYStateValid() const { return m_ttystateErr == 0; }
- bool ProcessGroupValid() const { return m_processGroup != -1; }
-
-protected:
- int m_fd; // File descriptor
- int m_tflags;
- int m_ttystateErr;
- struct termios m_ttystate;
- pid_t m_processGroup;
-};
-
-class TTYStateSwitcher {
-public:
- TTYStateSwitcher();
- ~TTYStateSwitcher();
-
- bool GetState(uint32_t idx, int fd, bool saveProcessGroup);
- bool SetState(uint32_t idx) const;
- uint32_t NumStates() const { return sizeof(m_ttystates) / sizeof(TTYState); }
- bool ValidStateIndex(uint32_t idx) const { return idx < NumStates(); }
-
-protected:
- mutable uint32_t m_currentState;
- TTYState m_ttystates[2];
-};
-
-#endif
diff --git a/tools/debugserver/source/com.apple.debugserver.applist.internal.plist b/tools/debugserver/source/com.apple.debugserver.applist.internal.plist
deleted file mode 100644
index e9a74bd0bf79..000000000000
--- a/tools/debugserver/source/com.apple.debugserver.applist.internal.plist
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>Label</key>
- <string>com.apple.debugserver.applist.internal</string>
- <key>ProgramArguments</key>
- <array>
- <string>/Developer/usr/bin/debugserver</string>
- <string>--lockdown</string>
- <string>--applist</string>
- </array>
- <key>AllowByProxy</key>
- <true/>
-</dict>
-</plist>
diff --git a/tools/debugserver/source/com.apple.debugserver.applist.plist b/tools/debugserver/source/com.apple.debugserver.applist.plist
deleted file mode 100644
index 002e90d98d13..000000000000
--- a/tools/debugserver/source/com.apple.debugserver.applist.plist
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>Label</key>
- <string>com.apple.debugserver.applist</string>
- <key>UserName</key>
- <string>mobile</string>
- <key>ProgramArguments</key>
- <array>
- <string>/Developer/usr/bin/debugserver</string>
- <string>--lockdown</string>
- <string>--applist</string>
- <string>--launch=frontboard</string>
- </array>
- <key>AllowByProxy</key>
- <true/>
-</dict>
-</plist>
diff --git a/tools/debugserver/source/com.apple.debugserver.internal.plist b/tools/debugserver/source/com.apple.debugserver.internal.plist
deleted file mode 100644
index b9f57f731232..000000000000
--- a/tools/debugserver/source/com.apple.debugserver.internal.plist
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>Label</key>
- <string>com.apple.debugserver.internal</string>
- <key>ProgramArguments</key>
- <array>
- <string>/Developer/usr/bin/debugserver</string>
- <string>--lockdown</string>
- </array>
- <key>AllowByProxy</key>
- <true/>
-</dict>
-</plist>
diff --git a/tools/debugserver/source/com.apple.debugserver.plist b/tools/debugserver/source/com.apple.debugserver.plist
deleted file mode 100644
index c07466e27cd2..000000000000
--- a/tools/debugserver/source/com.apple.debugserver.plist
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>Label</key>
- <string>com.apple.debugserver</string>
- <key>UserName</key>
- <string>mobile</string>
- <key>ProgramArguments</key>
- <array>
- <string>/Developer/usr/bin/debugserver</string>
- <string>--lockdown</string>
- <string>--launch=frontboard</string>
- </array>
- <key>AllowByProxy</key>
- <true/>
-</dict>
-</plist>
diff --git a/tools/debugserver/source/com.apple.debugserver.posix.plist b/tools/debugserver/source/com.apple.debugserver.posix.plist
deleted file mode 100644
index 4083f8a75c67..000000000000
--- a/tools/debugserver/source/com.apple.debugserver.posix.plist
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>Label</key>
- <string>com.apple.debugserver.posix</string>
- <key>UserName</key>
- <string>mobile</string>
- <key>ProgramArguments</key>
- <array>
- <string>/Developer/usr/bin/debugserver</string>
- <string>--lockdown</string>
- <string>--launch=posix</string>
- </array>
- <key>AllowByProxy</key>
- <true/>
-</dict>
-</plist>
diff --git a/tools/debugserver/source/com.apple.internal.xpc.remote.debugserver.plist b/tools/debugserver/source/com.apple.internal.xpc.remote.debugserver.plist
deleted file mode 100644
index 837ebe7b59ad..000000000000
--- a/tools/debugserver/source/com.apple.internal.xpc.remote.debugserver.plist
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>Label</key>
- <string>com.apple.internal.xpc.remote.debugserver</string>
- <key>RemoteServices</key>
- <dict>
- <key>com.apple.internal.debugserver</key>
- <dict>
- <key>RequireEntitlement</key>
- <string>AppleInternal</string>
- <key>ExposedToUntrustedDevices</key>
- <true/>
- </dict>
- </dict>
- <key>ProgramArguments</key>
- <array>
- <string>/usr/libexec/remotectl</string>
- <string>trampoline</string>
- <string>-2</string>
- <string>42</string>
- <string>com.apple.internal.debugserver</string>
- <string>/usr/local/bin/debugserver-nonui</string>
- <string>--fd</string>
- <string>42</string>
- </array>
- <key>POSIXSpawnType</key>
- <string>Interactive</string>
- <key>EnableTransactions</key>
- <true/>
- <key>EnablePressuredExit</key>
- <true/>
-</dict>
-</plist>
diff --git a/tools/debugserver/source/debugserver-entitlements.plist b/tools/debugserver/source/debugserver-entitlements.plist
deleted file mode 100644
index 6d9f44536f94..000000000000
--- a/tools/debugserver/source/debugserver-entitlements.plist
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>com.apple.springboard.debugapplications</key>
- <true/>
- <key>com.apple.backboardd.launchapplications</key>
- <true/>
- <key>com.apple.backboardd.debugapplications</key>
- <true/>
- <key>com.apple.frontboard.launchapplications</key>
- <true/>
- <key>com.apple.frontboard.debugapplications</key>
- <true/>
- <key>seatbelt-profiles</key>
- <array>
- <string>debugserver</string>
- </array>
- <key>com.apple.diagnosticd.diagnostic</key>
- <true/>
- <key>com.apple.security.network.server</key>
- <true/>
- <key>com.apple.security.network.client</key>
- <true/>
- <key>com.apple.private.memorystatus</key>
- <true/>
- <key>com.apple.private.cs.debugger</key>
- <true/>
-</dict>
-</plist>
diff --git a/tools/debugserver/source/debugserver-macosx-entitlements.plist b/tools/debugserver/source/debugserver-macosx-entitlements.plist
deleted file mode 100644
index 92a0d13fc781..000000000000
--- a/tools/debugserver/source/debugserver-macosx-entitlements.plist
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>com.apple.diagnosticd.diagnostic</key>
- <true/>
- <key>com.apple.private.cs.debugger</key>
- <true/>
-</dict>
-</plist>
diff --git a/tools/debugserver/source/debugserver.cpp b/tools/debugserver/source/debugserver.cpp
deleted file mode 100644
index 8afe17bce37d..000000000000
--- a/tools/debugserver/source/debugserver.cpp
+++ /dev/null
@@ -1,1684 +0,0 @@
-//===-- debugserver.cpp -----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include <arpa/inet.h>
-#include <asl.h>
-#include <crt_externs.h>
-#include <errno.h>
-#include <getopt.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <string>
-#include <sys/select.h>
-#include <sys/socket.h>
-#include <sys/sysctl.h>
-#include <sys/types.h>
-#include <sys/un.h>
-#include <vector>
-
-#if defined(__APPLE__)
-#include <sched.h>
-extern "C" int proc_set_wakemon_params(pid_t, int,
- int); // <libproc_internal.h> SPI
-#endif
-
-#include "CFString.h"
-#include "DNB.h"
-#include "DNBLog.h"
-#include "DNBTimer.h"
-#include "OsLogger.h"
-#include "PseudoTerminal.h"
-#include "RNBContext.h"
-#include "RNBRemote.h"
-#include "RNBServices.h"
-#include "RNBSocket.h"
-#include "SysSignal.h"
-
-// Global PID in case we get a signal and need to stop the process...
-nub_process_t g_pid = INVALID_NUB_PROCESS;
-
-//----------------------------------------------------------------------
-// Run loop modes which determine which run loop function will be called
-//----------------------------------------------------------------------
-typedef enum {
- eRNBRunLoopModeInvalid = 0,
- eRNBRunLoopModeGetStartModeFromRemoteProtocol,
- eRNBRunLoopModeInferiorAttaching,
- eRNBRunLoopModeInferiorLaunching,
- eRNBRunLoopModeInferiorExecuting,
- eRNBRunLoopModePlatformMode,
- eRNBRunLoopModeExit
-} RNBRunLoopMode;
-
-//----------------------------------------------------------------------
-// Global Variables
-//----------------------------------------------------------------------
-RNBRemoteSP g_remoteSP;
-static int g_lockdown_opt = 0;
-static int g_applist_opt = 0;
-static nub_launch_flavor_t g_launch_flavor = eLaunchFlavorDefault;
-int g_disable_aslr = 0;
-
-int g_isatty = 0;
-bool g_detach_on_error = true;
-
-#define RNBLogSTDOUT(fmt, ...) \
- do { \
- if (g_isatty) { \
- fprintf(stdout, fmt, ##__VA_ARGS__); \
- } else { \
- _DNBLog(0, fmt, ##__VA_ARGS__); \
- } \
- } while (0)
-#define RNBLogSTDERR(fmt, ...) \
- do { \
- if (g_isatty) { \
- fprintf(stderr, fmt, ##__VA_ARGS__); \
- } else { \
- _DNBLog(0, fmt, ##__VA_ARGS__); \
- } \
- } while (0)
-
-//----------------------------------------------------------------------
-// Get our program path and arguments from the remote connection.
-// We will need to start up the remote connection without a PID, get the
-// arguments, wait for the new process to finish launching and hit its
-// entry point, and then return the run loop mode that should come next.
-//----------------------------------------------------------------------
-RNBRunLoopMode RNBRunLoopGetStartModeFromRemote(RNBRemote *remote) {
- std::string packet;
-
- if (remote) {
- RNBContext &ctx = remote->Context();
- uint32_t event_mask = RNBContext::event_read_packet_available |
- RNBContext::event_read_thread_exiting;
-
- // Spin waiting to get the A packet.
- while (1) {
- DNBLogThreadedIf(LOG_RNB_MAX,
- "%s ctx.Events().WaitForSetEvents( 0x%08x ) ...",
- __FUNCTION__, event_mask);
- nub_event_t set_events = ctx.Events().WaitForSetEvents(event_mask);
- DNBLogThreadedIf(LOG_RNB_MAX,
- "%s ctx.Events().WaitForSetEvents( 0x%08x ) => 0x%08x",
- __FUNCTION__, event_mask, set_events);
-
- if (set_events & RNBContext::event_read_thread_exiting) {
- RNBLogSTDERR("error: packet read thread exited.\n");
- return eRNBRunLoopModeExit;
- }
-
- if (set_events & RNBContext::event_read_packet_available) {
- rnb_err_t err = rnb_err;
- RNBRemote::PacketEnum type;
-
- err = remote->HandleReceivedPacket(&type);
-
- // check if we tried to attach to a process
- if (type == RNBRemote::vattach || type == RNBRemote::vattachwait ||
- type == RNBRemote::vattachorwait) {
- if (err == rnb_success) {
- RNBLogSTDOUT("Attach succeeded, ready to debug.\n");
- return eRNBRunLoopModeInferiorExecuting;
- } else {
- RNBLogSTDERR("error: attach failed.\n");
- return eRNBRunLoopModeExit;
- }
- }
-
- if (err == rnb_success) {
- // If we got our arguments we are ready to launch using the arguments
- // and any environment variables we received.
- if (type == RNBRemote::set_argv) {
- return eRNBRunLoopModeInferiorLaunching;
- }
- } else if (err == rnb_not_connected) {
- RNBLogSTDERR("error: connection lost.\n");
- return eRNBRunLoopModeExit;
- } else {
- // a catch all for any other gdb remote packets that failed
- DNBLogThreadedIf(LOG_RNB_MINIMAL, "%s Error getting packet.",
- __FUNCTION__);
- continue;
- }
-
- DNBLogThreadedIf(LOG_RNB_MINIMAL, "#### %s", __FUNCTION__);
- } else {
- DNBLogThreadedIf(LOG_RNB_MINIMAL,
- "%s Connection closed before getting \"A\" packet.",
- __FUNCTION__);
- return eRNBRunLoopModeExit;
- }
- }
- }
- return eRNBRunLoopModeExit;
-}
-
-//----------------------------------------------------------------------
-// This run loop mode will wait for the process to launch and hit its
-// entry point. It will currently ignore all events except for the
-// process state changed event, where it watches for the process stopped
-// or crash process state.
-//----------------------------------------------------------------------
-RNBRunLoopMode RNBRunLoopLaunchInferior(RNBRemote *remote,
- const char *stdin_path,
- const char *stdout_path,
- const char *stderr_path,
- bool no_stdio) {
- RNBContext &ctx = remote->Context();
-
- // The Process stuff takes a c array, the RNBContext has a vector...
- // So make up a c array.
-
- DNBLogThreadedIf(LOG_RNB_MINIMAL, "%s Launching '%s'...", __FUNCTION__,
- ctx.ArgumentAtIndex(0));
-
- size_t inferior_argc = ctx.ArgumentCount();
- // Initialize inferior_argv with inferior_argc + 1 NULLs
- std::vector<const char *> inferior_argv(inferior_argc + 1, NULL);
-
- size_t i;
- for (i = 0; i < inferior_argc; i++)
- inferior_argv[i] = ctx.ArgumentAtIndex(i);
-
- // Pass the environment array the same way:
-
- size_t inferior_envc = ctx.EnvironmentCount();
- // Initialize inferior_argv with inferior_argc + 1 NULLs
- std::vector<const char *> inferior_envp(inferior_envc + 1, NULL);
-
- for (i = 0; i < inferior_envc; i++)
- inferior_envp[i] = ctx.EnvironmentAtIndex(i);
-
- // Our launch type hasn't been set to anything concrete, so we need to
- // figure our how we are going to launch automatically.
-
- nub_launch_flavor_t launch_flavor = g_launch_flavor;
- if (launch_flavor == eLaunchFlavorDefault) {
- // Our default launch method is posix spawn
- launch_flavor = eLaunchFlavorPosixSpawn;
-
-#if defined WITH_FBS
- // Check if we have an app bundle, if so launch using BackBoard Services.
- if (strstr(inferior_argv[0], ".app")) {
- launch_flavor = eLaunchFlavorFBS;
- }
-#elif 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")) {
- launch_flavor = eLaunchFlavorSpringBoard;
- }
-#endif
- }
-
- ctx.SetLaunchFlavor(launch_flavor);
- char resolved_path[PATH_MAX];
-
- // If we fail to resolve the path to our executable, then just use what we
- // were given and hope for the best
- if (!DNBResolveExecutablePath(inferior_argv[0], resolved_path,
- sizeof(resolved_path)))
- ::strlcpy(resolved_path, inferior_argv[0], sizeof(resolved_path));
-
- char launch_err_str[PATH_MAX];
- 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], cwd, stdin_path,
- stdout_path, stderr_path, no_stdio, launch_flavor, g_disable_aslr,
- process_event, launch_err_str, sizeof(launch_err_str));
-
- g_pid = pid;
-
- if (pid == INVALID_NUB_PROCESS && strlen(launch_err_str) > 0) {
- DNBLogThreaded("%s DNBProcessLaunch() returned error: '%s'", __FUNCTION__,
- launch_err_str);
- ctx.LaunchStatus().SetError(-1, DNBError::Generic);
- ctx.LaunchStatus().SetErrorString(launch_err_str);
- } else if (pid == INVALID_NUB_PROCESS) {
- DNBLogThreaded(
- "%s DNBProcessLaunch() failed to launch process, unknown failure",
- __FUNCTION__);
- ctx.LaunchStatus().SetError(-1, DNBError::Generic);
- ctx.LaunchStatus().SetErrorString("<unknown failure>");
- } else {
- ctx.LaunchStatus().Clear();
- }
-
- if (remote->Comm().IsConnected()) {
- // It we are connected already, the next thing gdb will do is ask
- // whether the launch succeeded, and if not, whether there is an
- // error code. So we need to fetch one packet from gdb before we wait
- // on the stop from the target.
-
- uint32_t event_mask = RNBContext::event_read_packet_available;
- nub_event_t set_events = ctx.Events().WaitForSetEvents(event_mask);
-
- if (set_events & RNBContext::event_read_packet_available) {
- rnb_err_t err = rnb_err;
- RNBRemote::PacketEnum type;
-
- err = remote->HandleReceivedPacket(&type);
-
- if (err != rnb_success) {
- DNBLogThreadedIf(LOG_RNB_MINIMAL, "%s Error getting packet.",
- __FUNCTION__);
- return eRNBRunLoopModeExit;
- }
- if (type != RNBRemote::query_launch_success) {
- DNBLogThreadedIf(LOG_RNB_MINIMAL,
- "%s Didn't get the expected qLaunchSuccess packet.",
- __FUNCTION__);
- }
- }
- }
-
- while (pid != INVALID_NUB_PROCESS) {
- // Wait for process to start up and hit entry point
- DNBLogThreadedIf(LOG_RNB_EVENTS, "%s DNBProcessWaitForEvent (%4.4x, "
- "eEventProcessRunningStateChanged | "
- "eEventProcessStoppedStateChanged, true, "
- "INFINITE)...",
- __FUNCTION__, pid);
- nub_event_t set_events =
- DNBProcessWaitForEvents(pid, eEventProcessRunningStateChanged |
- eEventProcessStoppedStateChanged,
- true, NULL);
- DNBLogThreadedIf(LOG_RNB_EVENTS, "%s DNBProcessWaitForEvent (%4.4x, "
- "eEventProcessRunningStateChanged | "
- "eEventProcessStoppedStateChanged, true, "
- "INFINITE) => 0x%8.8x",
- __FUNCTION__, pid, set_events);
-
- if (set_events == 0) {
- pid = INVALID_NUB_PROCESS;
- g_pid = pid;
- } else {
- if (set_events & (eEventProcessRunningStateChanged |
- eEventProcessStoppedStateChanged)) {
- nub_state_t pid_state = DNBProcessGetState(pid);
- DNBLogThreadedIf(
- LOG_RNB_EVENTS,
- "%s process %4.4x state changed (eEventProcessStateChanged): %s",
- __FUNCTION__, pid, DNBStateAsString(pid_state));
-
- switch (pid_state) {
- case eStateInvalid:
- case eStateUnloaded:
- case eStateAttaching:
- case eStateLaunching:
- case eStateSuspended:
- break; // Ignore
-
- case eStateRunning:
- case eStateStepping:
- // Still waiting to stop at entry point...
- break;
-
- case eStateStopped:
- case eStateCrashed:
- ctx.SetProcessID(pid);
- return eRNBRunLoopModeInferiorExecuting;
-
- case eStateDetached:
- case eStateExited:
- pid = INVALID_NUB_PROCESS;
- g_pid = pid;
- return eRNBRunLoopModeExit;
- }
- }
-
- DNBProcessResetEvents(pid, set_events);
- }
- }
-
- return eRNBRunLoopModeExit;
-}
-
-//----------------------------------------------------------------------
-// This run loop mode will wait for the process to launch and hit its
-// entry point. It will currently ignore all events except for the
-// process state changed event, where it watches for the process stopped
-// or crash process state.
-//----------------------------------------------------------------------
-RNBRunLoopMode RNBRunLoopLaunchAttaching(RNBRemote *remote,
- nub_process_t attach_pid,
- nub_process_t &pid) {
- RNBContext &ctx = remote->Context();
-
- DNBLogThreadedIf(LOG_RNB_MINIMAL, "%s Attaching to pid %i...", __FUNCTION__,
- attach_pid);
- char err_str[1024];
- pid = DNBProcessAttach(attach_pid, NULL, err_str, sizeof(err_str));
- g_pid = pid;
-
- if (pid == INVALID_NUB_PROCESS) {
- ctx.LaunchStatus().SetError(-1, DNBError::Generic);
- if (err_str[0])
- ctx.LaunchStatus().SetErrorString(err_str);
- return eRNBRunLoopModeExit;
- } else {
- ctx.SetProcessID(pid);
- return eRNBRunLoopModeInferiorExecuting;
- }
-}
-
-//----------------------------------------------------------------------
-// Watch for signals:
-// SIGINT: so we can halt our inferior. (disabled for now)
-// SIGPIPE: in case our child process dies
-//----------------------------------------------------------------------
-int g_sigint_received = 0;
-int g_sigpipe_received = 0;
-void signal_handler(int signo) {
- DNBLogThreadedIf(LOG_RNB_MINIMAL, "%s (%s)", __FUNCTION__,
- SysSignal::Name(signo));
-
- switch (signo) {
- case SIGINT:
- g_sigint_received++;
- if (g_pid != INVALID_NUB_PROCESS) {
- // Only send a SIGINT once...
- if (g_sigint_received == 1) {
- switch (DNBProcessGetState(g_pid)) {
- case eStateRunning:
- case eStateStepping:
- DNBProcessSignal(g_pid, SIGSTOP);
- return;
- default:
- break;
- }
- }
- }
- exit(SIGINT);
- break;
-
- case SIGPIPE:
- g_sigpipe_received = 1;
- break;
- }
-}
-
-// Return the new run loop mode based off of the current process state
-RNBRunLoopMode HandleProcessStateChange(RNBRemote *remote, bool initialize) {
- RNBContext &ctx = remote->Context();
- nub_process_t pid = ctx.ProcessID();
-
- if (pid == INVALID_NUB_PROCESS) {
- DNBLogThreadedIf(LOG_RNB_MINIMAL, "#### %s error: pid invalid, exiting...",
- __FUNCTION__);
- return eRNBRunLoopModeExit;
- }
- nub_state_t pid_state = DNBProcessGetState(pid);
-
- DNBLogThreadedIf(LOG_RNB_MINIMAL,
- "%s (&remote, initialize=%i) pid_state = %s", __FUNCTION__,
- (int)initialize, DNBStateAsString(pid_state));
-
- switch (pid_state) {
- case eStateInvalid:
- case eStateUnloaded:
- // Something bad happened
- return eRNBRunLoopModeExit;
- break;
-
- case eStateAttaching:
- case eStateLaunching:
- return eRNBRunLoopModeInferiorExecuting;
-
- case eStateSuspended:
- case eStateCrashed:
- case eStateStopped:
- // If we stop due to a signal, so clear the fact that we got a SIGINT
- // so we can stop ourselves again (but only while our inferior
- // process is running..)
- g_sigint_received = 0;
- if (initialize == false) {
- // Compare the last stop count to our current notion of a stop count
- // to make sure we don't notify more than once for a given stop.
- nub_size_t prev_pid_stop_count = ctx.GetProcessStopCount();
- bool pid_stop_count_changed =
- ctx.SetProcessStopCount(DNBProcessGetStopCount(pid));
- if (pid_stop_count_changed) {
- remote->FlushSTDIO();
-
- if (ctx.GetProcessStopCount() == 1) {
- DNBLogThreadedIf(
- LOG_RNB_MINIMAL, "%s (&remote, initialize=%i) pid_state = %s "
- "pid_stop_count %llu (old %llu)) Notify??? no, "
- "first stop...",
- __FUNCTION__, (int)initialize, DNBStateAsString(pid_state),
- (uint64_t)ctx.GetProcessStopCount(),
- (uint64_t)prev_pid_stop_count);
- } else {
-
- DNBLogThreadedIf(LOG_RNB_MINIMAL, "%s (&remote, initialize=%i) "
- "pid_state = %s pid_stop_count "
- "%llu (old %llu)) Notify??? YES!!!",
- __FUNCTION__, (int)initialize,
- DNBStateAsString(pid_state),
- (uint64_t)ctx.GetProcessStopCount(),
- (uint64_t)prev_pid_stop_count);
- remote->NotifyThatProcessStopped();
- }
- } else {
- DNBLogThreadedIf(
- LOG_RNB_MINIMAL, "%s (&remote, initialize=%i) pid_state = %s "
- "pid_stop_count %llu (old %llu)) Notify??? "
- "skipping...",
- __FUNCTION__, (int)initialize, DNBStateAsString(pid_state),
- (uint64_t)ctx.GetProcessStopCount(), (uint64_t)prev_pid_stop_count);
- }
- }
- return eRNBRunLoopModeInferiorExecuting;
-
- case eStateStepping:
- case eStateRunning:
- return eRNBRunLoopModeInferiorExecuting;
-
- case eStateExited:
- remote->HandlePacket_last_signal(NULL);
- case eStateDetached:
- return eRNBRunLoopModeExit;
- }
-
- // Catch all...
- return eRNBRunLoopModeExit;
-}
-// This function handles the case where our inferior program is stopped and
-// we are waiting for gdb remote protocol packets. When a packet occurs that
-// makes the inferior run, we need to leave this function with a new state
-// as the return code.
-RNBRunLoopMode RNBRunLoopInferiorExecuting(RNBRemote *remote) {
- DNBLogThreadedIf(LOG_RNB_MINIMAL, "#### %s", __FUNCTION__);
- RNBContext &ctx = remote->Context();
-
- // Init our mode and set 'is_running' based on the current process state
- RNBRunLoopMode mode = HandleProcessStateChange(remote, true);
-
- while (ctx.ProcessID() != INVALID_NUB_PROCESS) {
-
- std::string set_events_str;
- uint32_t event_mask = ctx.NormalEventBits();
-
- if (!ctx.ProcessStateRunning()) {
- // Clear some bits if we are not running so we don't send any async
- // packets
- event_mask &= ~RNBContext::event_proc_stdio_available;
- event_mask &= ~RNBContext::event_proc_profile_data;
- // When we enable async structured data packets over another logical
- // channel,
- // this can be relaxed.
- event_mask &= ~RNBContext::event_darwin_log_data_available;
- }
-
- // We want to make sure we consume all process state changes and have
- // whomever is notifying us to wait for us to reset the event bit before
- // continuing.
- // ctx.Events().SetResetAckMask (RNBContext::event_proc_state_changed);
-
- DNBLogThreadedIf(LOG_RNB_EVENTS,
- "%s ctx.Events().WaitForSetEvents(0x%08x) ...",
- __FUNCTION__, event_mask);
- nub_event_t set_events = ctx.Events().WaitForSetEvents(event_mask);
- DNBLogThreadedIf(LOG_RNB_EVENTS,
- "%s ctx.Events().WaitForSetEvents(0x%08x) => 0x%08x (%s)",
- __FUNCTION__, event_mask, set_events,
- ctx.EventsAsString(set_events, set_events_str));
-
- if (set_events) {
- if ((set_events & RNBContext::event_proc_thread_exiting) ||
- (set_events & RNBContext::event_proc_stdio_available)) {
- remote->FlushSTDIO();
- }
-
- if (set_events & RNBContext::event_proc_profile_data) {
- remote->SendAsyncProfileData();
- }
-
- if (set_events & RNBContext::event_darwin_log_data_available) {
- remote->SendAsyncDarwinLogData();
- }
-
- if (set_events & RNBContext::event_read_packet_available) {
- // handleReceivedPacket will take care of resetting the
- // event_read_packet_available events when there are no more...
- set_events ^= RNBContext::event_read_packet_available;
-
- if (ctx.ProcessStateRunning()) {
- if (remote->HandleAsyncPacket() == rnb_not_connected) {
- // TODO: connect again? Exit?
- }
- } else {
- if (remote->HandleReceivedPacket() == rnb_not_connected) {
- // TODO: connect again? Exit?
- }
- }
- }
-
- if (set_events & RNBContext::event_proc_state_changed) {
- mode = HandleProcessStateChange(remote, false);
- ctx.Events().ResetEvents(RNBContext::event_proc_state_changed);
- set_events ^= RNBContext::event_proc_state_changed;
- }
-
- if (set_events & RNBContext::event_proc_thread_exiting) {
- mode = eRNBRunLoopModeExit;
- }
-
- if (set_events & RNBContext::event_read_thread_exiting) {
- // Out remote packet receiving thread exited, exit for now.
- if (ctx.HasValidProcessID()) {
- // TODO: We should add code that will leave the current process
- // in its current state and listen for another connection...
- if (ctx.ProcessStateRunning()) {
- if (ctx.GetDetachOnError()) {
- DNBLog("debugserver's event read thread is exiting, detaching "
- "from the inferior process.");
- DNBProcessDetach(ctx.ProcessID());
- } else {
- DNBLog("debugserver's event read thread is exiting, killing the "
- "inferior process.");
- DNBProcessKill(ctx.ProcessID());
- }
- } else {
- if (ctx.GetDetachOnError()) {
- DNBLog("debugserver's event read thread is exiting, detaching "
- "from the inferior process.");
- DNBProcessDetach(ctx.ProcessID());
- }
- }
- }
- mode = eRNBRunLoopModeExit;
- }
- }
-
- // Reset all event bits that weren't reset for now...
- if (set_events != 0)
- ctx.Events().ResetEvents(set_events);
-
- if (mode != eRNBRunLoopModeInferiorExecuting)
- break;
- }
-
- return mode;
-}
-
-RNBRunLoopMode RNBRunLoopPlatform(RNBRemote *remote) {
- RNBRunLoopMode mode = eRNBRunLoopModePlatformMode;
- RNBContext &ctx = remote->Context();
-
- while (mode == eRNBRunLoopModePlatformMode) {
- std::string set_events_str;
- const uint32_t event_mask = RNBContext::event_read_packet_available |
- RNBContext::event_read_thread_exiting;
-
- DNBLogThreadedIf(LOG_RNB_EVENTS,
- "%s ctx.Events().WaitForSetEvents(0x%08x) ...",
- __FUNCTION__, event_mask);
- nub_event_t set_events = ctx.Events().WaitForSetEvents(event_mask);
- DNBLogThreadedIf(LOG_RNB_EVENTS,
- "%s ctx.Events().WaitForSetEvents(0x%08x) => 0x%08x (%s)",
- __FUNCTION__, event_mask, set_events,
- ctx.EventsAsString(set_events, set_events_str));
-
- if (set_events) {
- if (set_events & RNBContext::event_read_packet_available) {
- if (remote->HandleReceivedPacket() == rnb_not_connected)
- mode = eRNBRunLoopModeExit;
- }
-
- if (set_events & RNBContext::event_read_thread_exiting) {
- mode = eRNBRunLoopModeExit;
- }
- ctx.Events().ResetEvents(set_events);
- }
- }
- return eRNBRunLoopModeExit;
-}
-
-//----------------------------------------------------------------------
-// Convenience function to set up the remote listening port
-// Returns 1 for success 0 for failure.
-//----------------------------------------------------------------------
-
-static void PortWasBoundCallbackUnixSocket(const void *baton, in_port_t port) {
- //::printf ("PortWasBoundCallbackUnixSocket (baton = %p, port = %u)\n", baton,
- //port);
-
- const char *unix_socket_name = (const char *)baton;
-
- if (unix_socket_name && unix_socket_name[0]) {
- // We were given a unix socket name to use to communicate the port
- // that we ended up binding to back to our parent process
- struct sockaddr_un saddr_un;
- int s = ::socket(AF_UNIX, SOCK_STREAM, 0);
- if (s < 0) {
- perror("error: socket (AF_UNIX, SOCK_STREAM, 0)");
- exit(1);
- }
-
- saddr_un.sun_family = AF_UNIX;
- ::strlcpy(saddr_un.sun_path, unix_socket_name,
- sizeof(saddr_un.sun_path) - 1);
- saddr_un.sun_path[sizeof(saddr_un.sun_path) - 1] = '\0';
- saddr_un.sun_len = SUN_LEN(&saddr_un);
-
- if (::connect(s, (struct sockaddr *)&saddr_un,
- static_cast<socklen_t>(SUN_LEN(&saddr_un))) < 0) {
- perror("error: connect (socket, &saddr_un, saddr_un_len)");
- exit(1);
- }
-
- //::printf ("connect () sucess!!\n");
-
- // We were able to connect to the socket, now write our PID so whomever
- // launched us will know this process's ID
- RNBLogSTDOUT("Listening to port %i...\n", port);
-
- char pid_str[64];
- const int pid_str_len = ::snprintf(pid_str, sizeof(pid_str), "%u", port);
- const ssize_t bytes_sent = ::send(s, pid_str, pid_str_len, 0);
-
- if (pid_str_len != bytes_sent) {
- perror("error: send (s, pid_str, pid_str_len, 0)");
- exit(1);
- }
-
- //::printf ("send () sucess!!\n");
-
- // We are done with the socket
- close(s);
- }
-}
-
-static void PortWasBoundCallbackNamedPipe(const void *baton, uint16_t port) {
- const char *named_pipe = (const char *)baton;
- if (named_pipe && named_pipe[0]) {
- int fd = ::open(named_pipe, O_WRONLY);
- if (fd > -1) {
- char port_str[64];
- const ssize_t port_str_len =
- ::snprintf(port_str, sizeof(port_str), "%u", port);
- // Write the port number as a C string with the NULL terminator
- ::write(fd, port_str, port_str_len + 1);
- close(fd);
- }
- }
-}
-
-static int ConnectRemote(RNBRemote *remote, const char *host, int port,
- bool reverse_connect, const char *named_pipe_path,
- const char *unix_socket_name) {
- if (!remote->Comm().IsConnected()) {
- if (reverse_connect) {
- if (port == 0) {
- DNBLogThreaded(
- "error: invalid port supplied for reverse connection: %i.\n", port);
- return 0;
- }
- if (remote->Comm().Connect(host, port) != rnb_success) {
- DNBLogThreaded("Failed to reverse connect to %s:%i.\n", host, port);
- return 0;
- }
- } else {
- if (port != 0)
- RNBLogSTDOUT("Listening to port %i for a connection from %s...\n", port,
- host ? host : "127.0.0.1");
- if (unix_socket_name && unix_socket_name[0]) {
- if (remote->Comm().Listen(host, port, PortWasBoundCallbackUnixSocket,
- unix_socket_name) != rnb_success) {
- RNBLogSTDERR("Failed to get connection from a remote gdb process.\n");
- return 0;
- }
- } else {
- if (remote->Comm().Listen(host, port, PortWasBoundCallbackNamedPipe,
- named_pipe_path) != rnb_success) {
- RNBLogSTDERR("Failed to get connection from a remote gdb process.\n");
- return 0;
- }
- }
- }
- remote->StartReadRemoteDataThread();
- }
- return 1;
-}
-
-//----------------------------------------------------------------------
-// ASL Logging callback that can be registered with DNBLogSetLogCallback
-//----------------------------------------------------------------------
-void ASLLogCallback(void *baton, uint32_t flags, const char *format,
- va_list args) {
- if (format == NULL)
- return;
- static aslmsg g_aslmsg = NULL;
- if (g_aslmsg == NULL) {
- g_aslmsg = ::asl_new(ASL_TYPE_MSG);
- char asl_key_sender[PATH_MAX];
- snprintf(asl_key_sender, sizeof(asl_key_sender), "com.apple.%s-%s",
- DEBUGSERVER_PROGRAM_NAME, DEBUGSERVER_VERSION_STR);
- ::asl_set(g_aslmsg, ASL_KEY_SENDER, asl_key_sender);
- }
-
- int asl_level;
- if (flags & DNBLOG_FLAG_FATAL)
- asl_level = ASL_LEVEL_CRIT;
- else if (flags & DNBLOG_FLAG_ERROR)
- asl_level = ASL_LEVEL_ERR;
- else if (flags & DNBLOG_FLAG_WARNING)
- asl_level = ASL_LEVEL_WARNING;
- else if (flags & DNBLOG_FLAG_VERBOSE)
- asl_level = ASL_LEVEL_WARNING; // ASL_LEVEL_INFO;
- else
- asl_level = ASL_LEVEL_WARNING; // ASL_LEVEL_DEBUG;
-
- ::asl_vlog(NULL, g_aslmsg, asl_level, format, args);
-}
-
-//----------------------------------------------------------------------
-// FILE based Logging callback that can be registered with
-// DNBLogSetLogCallback
-//----------------------------------------------------------------------
-void FileLogCallback(void *baton, uint32_t flags, const char *format,
- va_list args) {
- if (baton == NULL || format == NULL)
- return;
-
- ::vfprintf((FILE *)baton, format, args);
- ::fprintf((FILE *)baton, "\n");
- ::fflush((FILE *)baton);
-}
-
-void show_usage_and_exit(int exit_code) {
- RNBLogSTDERR(
- "Usage:\n %s host:port [program-name program-arg1 program-arg2 ...]\n",
- DEBUGSERVER_PROGRAM_NAME);
- RNBLogSTDERR(" %s /path/file [program-name program-arg1 program-arg2 ...]\n",
- DEBUGSERVER_PROGRAM_NAME);
- RNBLogSTDERR(" %s host:port --attach=<pid>\n", DEBUGSERVER_PROGRAM_NAME);
- RNBLogSTDERR(" %s /path/file --attach=<pid>\n", DEBUGSERVER_PROGRAM_NAME);
- RNBLogSTDERR(" %s host:port --attach=<process_name>\n",
- DEBUGSERVER_PROGRAM_NAME);
- RNBLogSTDERR(" %s /path/file --attach=<process_name>\n",
- DEBUGSERVER_PROGRAM_NAME);
- exit(exit_code);
-}
-
-//----------------------------------------------------------------------
-// option descriptors for getopt_long_only()
-//----------------------------------------------------------------------
-static struct option g_long_options[] = {
- {"attach", required_argument, NULL, 'a'},
- {"arch", required_argument, NULL, 'A'},
- {"debug", no_argument, NULL, 'g'},
- {"kill-on-error", no_argument, NULL, 'K'},
- {"verbose", no_argument, NULL, 'v'},
- {"lockdown", no_argument, &g_lockdown_opt, 1}, // short option "-k"
- {"applist", no_argument, &g_applist_opt, 1}, // short option "-t"
- {"log-file", required_argument, NULL, 'l'},
- {"log-flags", required_argument, NULL, 'f'},
- {"launch", required_argument, NULL, 'x'}, // Valid values are "auto",
- // "posix-spawn", "fork-exec",
- // "springboard" (arm only)
- {"waitfor", required_argument, NULL,
- 'w'}, // Wait for a process whose name starts with ARG
- {"waitfor-interval", required_argument, NULL,
- 'i'}, // Time in usecs to wait between sampling the pid list when waiting
- // for a process by name
- {"waitfor-duration", required_argument, NULL,
- 'd'}, // The time in seconds to wait for a process to show up by name
- {"native-regs", no_argument, NULL, 'r'}, // Specify to use the native
- // registers instead of the gdb
- // defaults for the architecture.
- {"stdio-path", required_argument, NULL,
- 's'}, // Set the STDIO path to be used when launching applications (STDIN,
- // STDOUT and STDERR) (only if debugserver launches the process)
- {"stdin-path", required_argument, NULL,
- 'I'}, // Set the STDIN path to be used when launching applications (only if
- // debugserver launches the process)
- {"stdout-path", required_argument, NULL,
- 'O'}, // Set the STDOUT path to be used when launching applications (only
- // if debugserver launches the process)
- {"stderr-path", required_argument, NULL,
- 'E'}, // Set the STDERR path to be used when launching applications (only
- // if debugserver launches the process)
- {"no-stdio", no_argument, NULL,
- 'n'}, // Do not set up any stdio (perhaps the program is a GUI program)
- // (only if debugserver launches the process)
- {"setsid", no_argument, NULL,
- 'S'}, // call setsid() to make debugserver run in its own session
- {"disable-aslr", no_argument, NULL, 'D'}, // Use _POSIX_SPAWN_DISABLE_ASLR
- // to avoid shared library
- // randomization
- {"working-dir", required_argument, NULL,
- 'W'}, // The working directory that the inferior process should have (only
- // if debugserver launches the process)
- {"platform", required_argument, NULL,
- 'p'}, // Put this executable into a remote platform mode
- {"unix-socket", required_argument, NULL,
- 'u'}, // If we need to handshake with our parent process, an option will be
- // passed down that specifies a unix socket name to use
- {"fd", required_argument, NULL,
- '2'}, // A file descriptor was passed to this process when spawned that
- // is already open and ready for communication
- {"named-pipe", required_argument, NULL, 'P'},
- {"reverse-connect", no_argument, NULL, 'R'},
- {"env", required_argument, NULL,
- 'e'}, // When debugserver launches the process, set a single environment
- // entry as specified by the option value ("./debugserver -e FOO=1 -e
- // BAR=2 localhost:1234 -- /bin/ls")
- {"forward-env", no_argument, NULL,
- 'F'}, // When debugserver launches the process, forward debugserver's
- // current environment variables to the child process ("./debugserver
- // -F localhost:1234 -- /bin/ls"
- {NULL, 0, NULL, 0}};
-
-//----------------------------------------------------------------------
-// main
-//----------------------------------------------------------------------
-int main(int argc, char *argv[]) {
- // If debugserver is launched with DYLD_INSERT_LIBRARIES, unset it so we
- // don't spawn child processes with this enabled.
- unsetenv("DYLD_INSERT_LIBRARIES");
-
- const char *argv_sub_zero =
- argv[0]; // save a copy of argv[0] for error reporting post-launch
-
-#if defined(__APPLE__)
- pthread_setname_np("main thread");
-#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
- struct sched_param thread_param;
- int thread_sched_policy;
- if (pthread_getschedparam(pthread_self(), &thread_sched_policy,
- &thread_param) == 0) {
- thread_param.sched_priority = 47;
- pthread_setschedparam(pthread_self(), thread_sched_policy, &thread_param);
- }
-
- ::proc_set_wakemon_params(
- getpid(), 500,
- 0); // Allow up to 500 wakeups/sec to avoid EXC_RESOURCE for normal use.
-#endif
-#endif
-
- g_isatty = ::isatty(STDIN_FILENO);
-
- // ::printf ("uid=%u euid=%u gid=%u egid=%u\n",
- // getuid(),
- // geteuid(),
- // getgid(),
- // getegid());
-
- // 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());
-
- RNBRemote *remote = g_remoteSP.get();
- if (remote == NULL) {
- RNBLogSTDERR("error: failed to create a remote connection class\n");
- return -1;
- }
-
- RNBContext &ctx = remote->Context();
-
- int i;
- int attach_pid = INVALID_NUB_PROCESS;
-
- FILE *log_file = NULL;
- uint32_t log_flags = 0;
- // Parse our options
- int ch;
- int long_option_index = 0;
- int debug = 0;
- int communication_fd = -1;
- std::string compile_options;
- std::string waitfor_pid_name; // Wait for a process that starts with this name
- std::string attach_pid_name;
- std::string arch_name;
- std::string working_dir; // The new working directory to use for the inferior
- std::string unix_socket_name; // If we need to handshake with our parent
- // process, an option will be passed down that
- // specifies a unix socket name to use
- std::string named_pipe_path; // If we need to handshake with our parent
- // process, an option will be passed down that
- // specifies a named pipe to use
- useconds_t waitfor_interval = 1000; // Time in usecs between process lists
- // polls when waiting for a process by
- // name, default 1 msec.
- useconds_t waitfor_duration =
- 0; // Time in seconds to wait for a process by name, 0 means wait forever.
- bool no_stdio = false;
- bool reverse_connect = false; // Set to true by an option to indicate we
- // should reverse connect to the host:port
- // supplied as the first debugserver argument
-
-#if !defined(DNBLOG_ENABLED)
- compile_options += "(no-logging) ";
-#endif
-
- RNBRunLoopMode start_mode = eRNBRunLoopModeExit;
-
- char short_options[512];
- uint32_t short_options_idx = 0;
-
- // Handle the two case that don't have short options in g_long_options
- short_options[short_options_idx++] = 'k';
- short_options[short_options_idx++] = 't';
-
- for (i = 0; g_long_options[i].name != NULL; ++i) {
- if (isalpha(g_long_options[i].val)) {
- short_options[short_options_idx++] = g_long_options[i].val;
- switch (g_long_options[i].has_arg) {
- default:
- case no_argument:
- break;
-
- case optional_argument:
- short_options[short_options_idx++] = ':';
- // Fall through to required_argument case below...
- case required_argument:
- short_options[short_options_idx++] = ':';
- break;
- }
- }
- }
- // NULL terminate the short option string.
- short_options[short_options_idx++] = '\0';
-
-#if __GLIBC__
- optind = 0;
-#else
- optreset = 1;
- optind = 1;
-#endif
-
- bool forward_env = false;
- while ((ch = getopt_long_only(argc, argv, short_options, g_long_options,
- &long_option_index)) != -1) {
- DNBLogDebug("option: ch == %c (0x%2.2x) --%s%c%s\n", ch, (uint8_t)ch,
- g_long_options[long_option_index].name,
- g_long_options[long_option_index].has_arg ? '=' : ' ',
- optarg ? optarg : "");
- switch (ch) {
- case 0: // Any optional that auto set themselves will return 0
- break;
-
- case 'A':
- if (optarg && optarg[0])
- arch_name.assign(optarg);
- break;
-
- case 'a':
- if (optarg && optarg[0]) {
- if (isdigit(optarg[0])) {
- char *end = NULL;
- attach_pid = static_cast<int>(strtoul(optarg, &end, 0));
- if (end == NULL || *end != '\0') {
- RNBLogSTDERR("error: invalid pid option '%s'\n", optarg);
- exit(4);
- }
- } else {
- attach_pid_name = optarg;
- }
- start_mode = eRNBRunLoopModeInferiorAttaching;
- }
- break;
-
- // --waitfor=NAME
- case 'w':
- if (optarg && optarg[0]) {
- waitfor_pid_name = optarg;
- start_mode = eRNBRunLoopModeInferiorAttaching;
- }
- break;
-
- // --waitfor-interval=USEC
- case 'i':
- if (optarg && optarg[0]) {
- char *end = NULL;
- waitfor_interval = static_cast<useconds_t>(strtoul(optarg, &end, 0));
- if (end == NULL || *end != '\0') {
- RNBLogSTDERR("error: invalid waitfor-interval option value '%s'.\n",
- optarg);
- exit(6);
- }
- }
- break;
-
- // --waitfor-duration=SEC
- case 'd':
- if (optarg && optarg[0]) {
- char *end = NULL;
- waitfor_duration = static_cast<useconds_t>(strtoul(optarg, &end, 0));
- if (end == NULL || *end != '\0') {
- RNBLogSTDERR("error: invalid waitfor-duration option value '%s'.\n",
- optarg);
- exit(7);
- }
- }
- break;
-
- case 'K':
- g_detach_on_error = false;
- break;
- case 'W':
- if (optarg && optarg[0])
- working_dir.assign(optarg);
- break;
-
- case 'x':
- if (optarg && optarg[0]) {
- if (strcasecmp(optarg, "auto") == 0)
- g_launch_flavor = eLaunchFlavorDefault;
- else if (strcasestr(optarg, "posix") == optarg)
- g_launch_flavor = eLaunchFlavorPosixSpawn;
- else if (strcasestr(optarg, "fork") == optarg)
- g_launch_flavor = eLaunchFlavorForkExec;
-#ifdef WITH_SPRINGBOARD
- 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
-#ifdef WITH_FBS
- else if (strcasestr(optarg, "frontboard") == optarg)
- g_launch_flavor = eLaunchFlavorFBS;
-#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");
-#ifdef WITH_SPRINGBOARD
- RNBLogSTDERR(
- " spring Launch the executable through Springboard.\n");
-#endif
-#ifdef WITH_BKS
- RNBLogSTDERR(" backboard Launch the executable through BackBoard "
- "Services.\n");
-#endif
-#ifdef WITH_FBS
- RNBLogSTDERR(" frontboard Launch the executable through FrontBoard "
- "Services.\n");
-#endif
- exit(5);
- }
- }
- break;
-
- case 'l': // Set Log File
- if (optarg && optarg[0]) {
- if (strcasecmp(optarg, "stdout") == 0)
- log_file = stdout;
- else if (strcasecmp(optarg, "stderr") == 0)
- log_file = stderr;
- else {
- log_file = fopen(optarg, "w");
- if (log_file != NULL)
- setlinebuf(log_file);
- }
-
- if (log_file == NULL) {
- const char *errno_str = strerror(errno);
- RNBLogSTDERR(
- "Failed to open log file '%s' for writing: errno = %i (%s)",
- optarg, errno, errno_str ? errno_str : "unknown error");
- }
- }
- break;
-
- case 'f': // Log Flags
- if (optarg && optarg[0])
- log_flags = static_cast<uint32_t>(strtoul(optarg, NULL, 0));
- break;
-
- case 'g':
- debug = 1;
- DNBLogSetDebug(debug);
- break;
-
- case 't':
- g_applist_opt = 1;
- break;
-
- case 'k':
- g_lockdown_opt = 1;
- break;
-
- case 'r':
- // Do nothing, native regs is the default these days
- break;
-
- case 'R':
- reverse_connect = true;
- break;
- case 'v':
- DNBLogSetVerbose(1);
- break;
-
- case 's':
- ctx.GetSTDIN().assign(optarg);
- ctx.GetSTDOUT().assign(optarg);
- ctx.GetSTDERR().assign(optarg);
- break;
-
- case 'I':
- ctx.GetSTDIN().assign(optarg);
- break;
-
- case 'O':
- ctx.GetSTDOUT().assign(optarg);
- break;
-
- case 'E':
- ctx.GetSTDERR().assign(optarg);
- break;
-
- case 'n':
- no_stdio = true;
- break;
-
- case 'S':
- // Put debugserver into a new session. Terminals group processes
- // into sessions and when a special terminal key sequences
- // (like control+c) are typed they can cause signals to go out to
- // all processes in a session. Using this --setsid (-S) option
- // will cause debugserver to run in its own sessions and be free
- // from such issues.
- //
- // This is useful when debugserver is spawned from a command
- // line application that uses debugserver to do the debugging,
- // yet that application doesn't want debugserver receiving the
- // signals sent to the session (i.e. dying when anyone hits ^C).
- setsid();
- break;
- case 'D':
- g_disable_aslr = 1;
- break;
-
- case 'p':
- start_mode = eRNBRunLoopModePlatformMode;
- break;
-
- case 'u':
- unix_socket_name.assign(optarg);
- break;
-
- case 'P':
- named_pipe_path.assign(optarg);
- break;
-
- case 'e':
- // Pass a single specified environment variable down to the process that
- // gets launched
- remote->Context().PushEnvironment(optarg);
- break;
-
- case 'F':
- forward_env = true;
- break;
-
- case '2':
- // File descriptor passed to this process during fork/exec and is already
- // open and ready for communication.
- communication_fd = atoi(optarg);
- break;
- }
- }
-
- if (arch_name.empty()) {
-#if defined(__arm__)
- arch_name.assign("arm");
-#endif
- } else {
- DNBSetArchitecture(arch_name.c_str());
- }
-
- // if (arch_name.empty())
- // {
- // fprintf(stderr, "error: no architecture was specified\n");
- // exit (8);
- // }
- // Skip any options we consumed with getopt_long_only
- argc -= optind;
- argv += optind;
-
- if (!working_dir.empty()) {
- if (remote->Context().SetWorkingDirectory(working_dir.c_str()) == false) {
- RNBLogSTDERR("error: working directory doesn't exist '%s'.\n",
- working_dir.c_str());
- exit(8);
- }
- }
-
- remote->Context().SetDetachOnError(g_detach_on_error);
-
- remote->Initialize();
-
- // It is ok for us to set NULL as the logfile (this will disable any logging)
-
- if (log_file != NULL) {
- DNBLogSetLogCallback(FileLogCallback, log_file);
- // If our log file was set, yet we have no log flags, log everything!
- if (log_flags == 0)
- log_flags = LOG_ALL | LOG_RNB_ALL;
-
- DNBLogSetLogMask(log_flags);
- } else {
- // Enable DNB logging
-
- // if os_log() support is available, log through that.
- auto log_callback = OsLogger::GetLogFunction();
- if (log_callback) {
- DNBLogSetLogCallback(log_callback, nullptr);
- DNBLog("debugserver will use os_log for internal logging.");
- } else {
- // Fall back to ASL support.
- DNBLogSetLogCallback(ASLLogCallback, NULL);
- DNBLog("debugserver will use ASL for internal logging.");
- }
- DNBLogSetLogMask(log_flags);
- }
-
- if (DNBLogEnabled()) {
- for (i = 0; i < argc; i++)
- DNBLogDebug("argv[%i] = %s", i, argv[i]);
- }
-
- // as long as we're dropping remotenub in as a replacement for gdbserver,
- // explicitly note that this is not gdbserver.
-
- RNBLogSTDOUT("%s-%s %sfor %s.\n", DEBUGSERVER_PROGRAM_NAME,
- DEBUGSERVER_VERSION_STR, compile_options.c_str(), RNB_ARCH);
-
- std::string host;
- int port = INT32_MAX;
- char str[PATH_MAX];
- str[0] = '\0';
-
- if (g_lockdown_opt == 0 && g_applist_opt == 0 && communication_fd == -1) {
- // Make sure we at least have port
- if (argc < 1) {
- show_usage_and_exit(1);
- }
- // accept 'localhost:' prefix on port number
- std::string host_specifier = argv[0];
- auto colon_location = host_specifier.rfind(':');
- if (colon_location != std::string::npos) {
- host = host_specifier.substr(0, colon_location);
- std::string port_str =
- host_specifier.substr(colon_location + 1, std::string::npos);
- char *end_ptr;
- port = strtoul(port_str.c_str(), &end_ptr, 0);
- if (end_ptr < port_str.c_str() + port_str.size())
- show_usage_and_exit(2);
- if (host.front() == '[' && host.back() == ']')
- host = host.substr(1, host.size() - 2);
- DNBLogDebug("host = '%s' port = %i", host.c_str(), port);
- } else {
- // No hostname means "localhost"
- int items_scanned = ::sscanf(argv[0], "%i", &port);
- if (items_scanned == 1) {
- host = "127.0.0.1";
- DNBLogDebug("host = '%s' port = %i", host.c_str(), port);
- } else if (argv[0][0] == '/') {
- port = INT32_MAX;
- strlcpy(str, argv[0], sizeof(str));
- } else {
- show_usage_and_exit(2);
- }
- }
-
- // We just used the 'host:port' or the '/path/file' arg...
- argc--;
- argv++;
- }
-
- // If we know we're waiting to attach, we don't need any of this other info.
- if (start_mode != eRNBRunLoopModeInferiorAttaching &&
- start_mode != eRNBRunLoopModePlatformMode) {
- if (argc == 0 || g_lockdown_opt) {
- if (g_lockdown_opt != 0) {
- // Work around for SIGPIPE crashes due to posix_spawn issue.
- // We have to close STDOUT and STDERR, else the first time we
- // try and do any, we get SIGPIPE and die as posix_spawn is
- // doing bad things with our file descriptors at the moment.
- int null = open("/dev/null", O_RDWR);
- dup2(null, STDOUT_FILENO);
- dup2(null, STDERR_FILENO);
- } else if (g_applist_opt != 0) {
- // List all applications we are able to see
- std::string applist_plist;
- int err = ListApplications(applist_plist, false, false);
- if (err == 0) {
- fputs(applist_plist.c_str(), stdout);
- } else {
- RNBLogSTDERR("error: ListApplications returned error %i\n", err);
- }
- // Exit with appropriate error if we were asked to list the applications
- // with no other args were given (and we weren't trying to do this over
- // lockdown)
- return err;
- }
-
- DNBLogDebug("Get args from remote protocol...");
- start_mode = eRNBRunLoopModeGetStartModeFromRemoteProtocol;
- } else {
- start_mode = eRNBRunLoopModeInferiorLaunching;
- // Fill in the argv array in the context from the rest of our args.
- // Skip the name of this executable and the port number
- for (int i = 0; i < argc; i++) {
- DNBLogDebug("inferior_argv[%i] = '%s'", i, argv[i]);
- ctx.PushArgument(argv[i]);
- }
- }
- }
-
- if (start_mode == eRNBRunLoopModeExit)
- return -1;
-
- if (forward_env || start_mode == eRNBRunLoopModeInferiorLaunching) {
- // Pass the current environment down to the process that gets launched
- // This happens automatically in the "launching" mode. For the rest, we
- // only do that if the user explicitly requested this via --forward-env
- // argument.
- char **host_env = *_NSGetEnviron();
- char *env_entry;
- size_t i;
- for (i = 0; (env_entry = host_env[i]) != NULL; ++i)
- remote->Context().PushEnvironmentIfNeeded(env_entry);
- }
-
- RNBRunLoopMode mode = start_mode;
- char err_str[1024] = {'\0'};
-
- while (mode != eRNBRunLoopModeExit) {
- switch (mode) {
- case eRNBRunLoopModeGetStartModeFromRemoteProtocol:
-#ifdef WITH_LOCKDOWN
- if (g_lockdown_opt) {
- if (!remote->Comm().IsConnected()) {
- if (remote->Comm().ConnectToService() != rnb_success) {
- RNBLogSTDERR(
- "Failed to get connection from a remote gdb process.\n");
- mode = eRNBRunLoopModeExit;
- } else if (g_applist_opt != 0) {
- // List all applications we are able to see
- std::string applist_plist;
- if (ListApplications(applist_plist, false, false) == 0) {
- DNBLogDebug("Task list: %s", applist_plist.c_str());
-
- remote->Comm().Write(applist_plist.c_str(), applist_plist.size());
- // Issue a read that will never yield any data until the other
- // side
- // closes the socket so this process doesn't just exit and cause
- // the
- // socket to close prematurely on the other end and cause data
- // loss.
- std::string buf;
- remote->Comm().Read(buf);
- }
- remote->Comm().Disconnect(false);
- mode = eRNBRunLoopModeExit;
- break;
- } else {
- // Start watching for remote packets
- remote->StartReadRemoteDataThread();
- }
- }
- } else
-#endif
- if (port != INT32_MAX) {
- if (!ConnectRemote(remote, host.c_str(), port, reverse_connect,
- named_pipe_path.c_str(), unix_socket_name.c_str()))
- mode = eRNBRunLoopModeExit;
- } else if (str[0] == '/') {
- if (remote->Comm().OpenFile(str))
- mode = eRNBRunLoopModeExit;
- } else if (communication_fd >= 0) {
- // We were passed a file descriptor to use during fork/exec that is
- // already open
- // in our process, so lets just use it!
- if (remote->Comm().useFD(communication_fd))
- mode = eRNBRunLoopModeExit;
- else
- remote->StartReadRemoteDataThread();
- }
-
- if (mode != eRNBRunLoopModeExit) {
- RNBLogSTDOUT("Got a connection, waiting for process information for "
- "launching or attaching.\n");
-
- mode = RNBRunLoopGetStartModeFromRemote(remote);
- }
- break;
-
- case eRNBRunLoopModeInferiorAttaching:
- if (!waitfor_pid_name.empty()) {
- // Set our end wait time if we are using a waitfor-duration
- // option that may have been specified
- struct timespec attach_timeout_abstime, *timeout_ptr = NULL;
- if (waitfor_duration != 0) {
- DNBTimer::OffsetTimeOfDay(&attach_timeout_abstime, waitfor_duration,
- 0);
- timeout_ptr = &attach_timeout_abstime;
- }
- nub_launch_flavor_t launch_flavor = g_launch_flavor;
- if (launch_flavor == eLaunchFlavorDefault) {
- // Our default launch method is posix spawn
- launch_flavor = eLaunchFlavorPosixSpawn;
-
-#if defined WITH_FBS
- // Check if we have an app bundle, if so launch using SpringBoard.
- if (waitfor_pid_name.find(".app") != std::string::npos) {
- launch_flavor = eLaunchFlavorFBS;
- }
-#elif 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) {
- launch_flavor = eLaunchFlavorSpringBoard;
- }
-#endif
- }
-
- ctx.SetLaunchFlavor(launch_flavor);
- bool ignore_existing = false;
- RNBLogSTDOUT("Waiting to attach to process %s...\n",
- waitfor_pid_name.c_str());
- nub_process_t pid = DNBProcessAttachWait(
- waitfor_pid_name.c_str(), launch_flavor, ignore_existing,
- timeout_ptr, waitfor_interval, err_str, sizeof(err_str));
- g_pid = pid;
-
- if (pid == INVALID_NUB_PROCESS) {
- ctx.LaunchStatus().SetError(-1, DNBError::Generic);
- if (err_str[0])
- ctx.LaunchStatus().SetErrorString(err_str);
- RNBLogSTDERR("error: failed to attach to process named: \"%s\" %s\n",
- waitfor_pid_name.c_str(), err_str);
- mode = eRNBRunLoopModeExit;
- } else {
- ctx.SetProcessID(pid);
- mode = eRNBRunLoopModeInferiorExecuting;
- }
- } else if (attach_pid != INVALID_NUB_PROCESS) {
-
- RNBLogSTDOUT("Attaching to process %i...\n", attach_pid);
- nub_process_t attached_pid;
- mode = RNBRunLoopLaunchAttaching(remote, attach_pid, attached_pid);
- if (mode != eRNBRunLoopModeInferiorExecuting) {
- const char *error_str = remote->Context().LaunchStatus().AsString();
- RNBLogSTDERR("error: failed to attach process %i: %s\n", attach_pid,
- error_str ? error_str : "unknown error.");
- mode = eRNBRunLoopModeExit;
- }
- } else if (!attach_pid_name.empty()) {
- struct timespec attach_timeout_abstime, *timeout_ptr = NULL;
- if (waitfor_duration != 0) {
- DNBTimer::OffsetTimeOfDay(&attach_timeout_abstime, waitfor_duration,
- 0);
- timeout_ptr = &attach_timeout_abstime;
- }
-
- RNBLogSTDOUT("Attaching to process %s...\n", attach_pid_name.c_str());
- nub_process_t pid = DNBProcessAttachByName(
- attach_pid_name.c_str(), timeout_ptr, err_str, sizeof(err_str));
- g_pid = pid;
- if (pid == INVALID_NUB_PROCESS) {
- ctx.LaunchStatus().SetError(-1, DNBError::Generic);
- if (err_str[0])
- ctx.LaunchStatus().SetErrorString(err_str);
- RNBLogSTDERR("error: failed to attach to process named: \"%s\" %s\n",
- waitfor_pid_name.c_str(), err_str);
- mode = eRNBRunLoopModeExit;
- } else {
- ctx.SetProcessID(pid);
- mode = eRNBRunLoopModeInferiorExecuting;
- }
-
- } else {
- RNBLogSTDERR(
- "error: asked to attach with empty name and invalid PID.\n");
- mode = eRNBRunLoopModeExit;
- }
-
- if (mode != eRNBRunLoopModeExit) {
- if (port != INT32_MAX) {
- if (!ConnectRemote(remote, host.c_str(), port, reverse_connect,
- named_pipe_path.c_str(), unix_socket_name.c_str()))
- mode = eRNBRunLoopModeExit;
- } else if (str[0] == '/') {
- if (remote->Comm().OpenFile(str))
- mode = eRNBRunLoopModeExit;
- } else if (communication_fd >= 0) {
- // We were passed a file descriptor to use during fork/exec that is
- // already open
- // in our process, so lets just use it!
- if (remote->Comm().useFD(communication_fd))
- mode = eRNBRunLoopModeExit;
- else
- remote->StartReadRemoteDataThread();
- }
-
- if (mode != eRNBRunLoopModeExit)
- RNBLogSTDOUT("Waiting for debugger instructions for process %d.\n",
- attach_pid);
- }
- break;
-
- case eRNBRunLoopModeInferiorLaunching: {
- mode = RNBRunLoopLaunchInferior(remote, ctx.GetSTDINPath(),
- ctx.GetSTDOUTPath(), ctx.GetSTDERRPath(),
- no_stdio);
-
- if (mode == eRNBRunLoopModeInferiorExecuting) {
- if (port != INT32_MAX) {
- if (!ConnectRemote(remote, host.c_str(), port, reverse_connect,
- named_pipe_path.c_str(), unix_socket_name.c_str()))
- mode = eRNBRunLoopModeExit;
- } else if (str[0] == '/') {
- if (remote->Comm().OpenFile(str))
- mode = eRNBRunLoopModeExit;
- } else if (communication_fd >= 0) {
- // We were passed a file descriptor to use during fork/exec that is
- // already open
- // in our process, so lets just use it!
- if (remote->Comm().useFD(communication_fd))
- mode = eRNBRunLoopModeExit;
- else
- remote->StartReadRemoteDataThread();
- }
-
- if (mode != eRNBRunLoopModeExit) {
- const char *proc_name = "<unknown>";
- if (ctx.ArgumentCount() > 0)
- proc_name = ctx.ArgumentAtIndex(0);
- RNBLogSTDOUT("Got a connection, launched process %s (pid = %d).\n",
- proc_name, ctx.ProcessID());
- }
- } else {
- const char *error_str = remote->Context().LaunchStatus().AsString();
- RNBLogSTDERR("error: failed to launch process %s: %s\n", argv_sub_zero,
- error_str ? error_str : "unknown error.");
- }
- } break;
-
- case eRNBRunLoopModeInferiorExecuting:
- mode = RNBRunLoopInferiorExecuting(remote);
- break;
-
- case eRNBRunLoopModePlatformMode:
- if (port != INT32_MAX) {
- if (!ConnectRemote(remote, host.c_str(), port, reverse_connect,
- named_pipe_path.c_str(), unix_socket_name.c_str()))
- mode = eRNBRunLoopModeExit;
- } else if (str[0] == '/') {
- if (remote->Comm().OpenFile(str))
- mode = eRNBRunLoopModeExit;
- } else if (communication_fd >= 0) {
- // We were passed a file descriptor to use during fork/exec that is
- // already open
- // in our process, so lets just use it!
- if (remote->Comm().useFD(communication_fd))
- mode = eRNBRunLoopModeExit;
- else
- remote->StartReadRemoteDataThread();
- }
-
- if (mode != eRNBRunLoopModeExit)
- mode = RNBRunLoopPlatform(remote);
- break;
-
- default:
- mode = eRNBRunLoopModeExit;
- case eRNBRunLoopModeExit:
- break;
- }
- }
-
- remote->StopReadRemoteDataThread();
- remote->Context().SetProcessID(INVALID_NUB_PROCESS);
- RNBLogSTDOUT("Exiting.\n");
-
- return 0;
-}
diff --git a/tools/debugserver/source/libdebugserver.cpp b/tools/debugserver/source/libdebugserver.cpp
deleted file mode 100644
index 34df67521a7c..000000000000
--- a/tools/debugserver/source/libdebugserver.cpp
+++ /dev/null
@@ -1,383 +0,0 @@
-//===-- libdebugserver.cpp --------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include <errno.h>
-#include <getopt.h>
-#include <netinet/in.h>
-#include <sys/select.h>
-#include <sys/socket.h>
-#include <sys/sysctl.h>
-#include <sys/types.h>
-
-#include "DNB.h"
-#include "DNBLog.h"
-#include "DNBTimer.h"
-#include "PseudoTerminal.h"
-#include "RNBContext.h"
-#include "RNBRemote.h"
-#include "RNBServices.h"
-#include "RNBSocket.h"
-#include "SysSignal.h"
-
-//----------------------------------------------------------------------
-// Run loop modes which determine which run loop function will be called
-//----------------------------------------------------------------------
-typedef enum {
- eRNBRunLoopModeInvalid = 0,
- eRNBRunLoopModeGetStartModeFromRemoteProtocol,
- eRNBRunLoopModeInferiorExecuting,
- eRNBRunLoopModeExit
-} RNBRunLoopMode;
-
-//----------------------------------------------------------------------
-// Global Variables
-//----------------------------------------------------------------------
-RNBRemoteSP g_remoteSP;
-int g_disable_aslr = 0;
-int g_isatty = 0;
-
-#define RNBLogSTDOUT(fmt, ...) \
- do { \
- if (g_isatty) { \
- fprintf(stdout, fmt, ##__VA_ARGS__); \
- } else { \
- _DNBLog(0, fmt, ##__VA_ARGS__); \
- } \
- } while (0)
-#define RNBLogSTDERR(fmt, ...) \
- do { \
- if (g_isatty) { \
- fprintf(stderr, fmt, ##__VA_ARGS__); \
- } else { \
- _DNBLog(0, fmt, ##__VA_ARGS__); \
- } \
- } while (0)
-
-//----------------------------------------------------------------------
-// Get our program path and arguments from the remote connection.
-// We will need to start up the remote connection without a PID, get the
-// arguments, wait for the new process to finish launching and hit its
-// entry point, and then return the run loop mode that should come next.
-//----------------------------------------------------------------------
-RNBRunLoopMode RNBRunLoopGetStartModeFromRemote(RNBRemoteSP &remoteSP) {
- std::string packet;
-
- if (remoteSP.get() != NULL) {
- RNBRemote *remote = remoteSP.get();
- RNBContext &ctx = remote->Context();
- uint32_t event_mask = RNBContext::event_read_packet_available;
-
- // Spin waiting to get the A packet.
- while (1) {
- DNBLogThreadedIf(LOG_RNB_MAX,
- "%s ctx.Events().WaitForSetEvents( 0x%08x ) ...",
- __FUNCTION__, event_mask);
- nub_event_t set_events = ctx.Events().WaitForSetEvents(event_mask);
- DNBLogThreadedIf(LOG_RNB_MAX,
- "%s ctx.Events().WaitForSetEvents( 0x%08x ) => 0x%08x",
- __FUNCTION__, event_mask, set_events);
-
- if (set_events & RNBContext::event_read_packet_available) {
- rnb_err_t err = rnb_err;
- RNBRemote::PacketEnum type;
-
- err = remote->HandleReceivedPacket(&type);
-
- // check if we tried to attach to a process
- if (type == RNBRemote::vattach || type == RNBRemote::vattachwait) {
- if (err == rnb_success)
- return eRNBRunLoopModeInferiorExecuting;
- else {
- RNBLogSTDERR("error: attach failed.");
- return eRNBRunLoopModeExit;
- }
- }
-
- if (err == rnb_success) {
- DNBLogThreadedIf(LOG_RNB_MINIMAL, "%s Got success...", __FUNCTION__);
- continue;
- } else if (err == rnb_not_connected) {
- RNBLogSTDERR("error: connection lost.");
- return eRNBRunLoopModeExit;
- } else {
- // a catch all for any other gdb remote packets that failed
- DNBLogThreadedIf(LOG_RNB_MINIMAL, "%s Error getting packet.",
- __FUNCTION__);
- continue;
- }
-
- DNBLogThreadedIf(LOG_RNB_MINIMAL, "#### %s", __FUNCTION__);
- } else {
- DNBLogThreadedIf(LOG_RNB_MINIMAL,
- "%s Connection closed before getting \"A\" packet.",
- __FUNCTION__);
- return eRNBRunLoopModeExit;
- }
- }
- }
- return eRNBRunLoopModeExit;
-}
-
-//----------------------------------------------------------------------
-// Watch for signals:
-// SIGINT: so we can halt our inferior. (disabled for now)
-// SIGPIPE: in case our child process dies
-//----------------------------------------------------------------------
-nub_process_t g_pid;
-int g_sigpipe_received = 0;
-void signal_handler(int signo) {
- DNBLogThreadedIf(LOG_RNB_MINIMAL, "%s (%s)", __FUNCTION__,
- SysSignal::Name(signo));
-
- switch (signo) {
- // case SIGINT:
- // DNBProcessKill (g_pid, signo);
- // break;
-
- case SIGPIPE:
- g_sigpipe_received = 1;
- break;
- }
-}
-
-// Return the new run loop mode based off of the current process state
-RNBRunLoopMode HandleProcessStateChange(RNBRemoteSP &remote, bool initialize) {
- RNBContext &ctx = remote->Context();
- nub_process_t pid = ctx.ProcessID();
-
- if (pid == INVALID_NUB_PROCESS) {
- DNBLogThreadedIf(LOG_RNB_MINIMAL, "#### %s error: pid invalid, exiting...",
- __FUNCTION__);
- return eRNBRunLoopModeExit;
- }
- nub_state_t pid_state = DNBProcessGetState(pid);
-
- DNBLogThreadedIf(LOG_RNB_MINIMAL,
- "%s (&remote, initialize=%i) pid_state = %s", __FUNCTION__,
- (int)initialize, DNBStateAsString(pid_state));
-
- switch (pid_state) {
- case eStateInvalid:
- case eStateUnloaded:
- // Something bad happened
- return eRNBRunLoopModeExit;
- break;
-
- case eStateAttaching:
- case eStateLaunching:
- return eRNBRunLoopModeInferiorExecuting;
-
- case eStateSuspended:
- case eStateCrashed:
- case eStateStopped:
- if (!initialize) {
- // Compare the last stop count to our current notion of a stop count
- // to make sure we don't notify more than once for a given stop.
- nub_size_t prev_pid_stop_count = ctx.GetProcessStopCount();
- bool pid_stop_count_changed =
- ctx.SetProcessStopCount(DNBProcessGetStopCount(pid));
- if (pid_stop_count_changed) {
- remote->FlushSTDIO();
-
- if (ctx.GetProcessStopCount() == 1) {
- DNBLogThreadedIf(
- LOG_RNB_MINIMAL, "%s (&remote, initialize=%i) pid_state = %s "
- "pid_stop_count %zu (old %zu)) Notify??? no, "
- "first stop...",
- __FUNCTION__, (int)initialize, DNBStateAsString(pid_state),
- ctx.GetProcessStopCount(), prev_pid_stop_count);
- } else {
-
- DNBLogThreadedIf(
- LOG_RNB_MINIMAL, "%s (&remote, initialize=%i) pid_state = %s "
- "pid_stop_count %zu (old %zu)) Notify??? YES!!!",
- __FUNCTION__, (int)initialize, DNBStateAsString(pid_state),
- ctx.GetProcessStopCount(), prev_pid_stop_count);
- remote->NotifyThatProcessStopped();
- }
- } else {
- DNBLogThreadedIf(LOG_RNB_MINIMAL, "%s (&remote, initialize=%i) "
- "pid_state = %s pid_stop_count %zu "
- "(old %zu)) Notify??? skipping...",
- __FUNCTION__, (int)initialize,
- DNBStateAsString(pid_state), ctx.GetProcessStopCount(),
- prev_pid_stop_count);
- }
- }
- return eRNBRunLoopModeInferiorExecuting;
-
- case eStateStepping:
- case eStateRunning:
- return eRNBRunLoopModeInferiorExecuting;
-
- case eStateExited:
- remote->HandlePacket_last_signal(NULL);
- return eRNBRunLoopModeExit;
- case eStateDetached:
- return eRNBRunLoopModeExit;
- }
-
- // Catch all...
- return eRNBRunLoopModeExit;
-}
-// This function handles the case where our inferior program is stopped and
-// we are waiting for gdb remote protocol packets. When a packet occurs that
-// makes the inferior run, we need to leave this function with a new state
-// as the return code.
-RNBRunLoopMode RNBRunLoopInferiorExecuting(RNBRemoteSP &remote) {
- DNBLogThreadedIf(LOG_RNB_MINIMAL, "#### %s", __FUNCTION__);
- RNBContext &ctx = remote->Context();
-
- // Init our mode and set 'is_running' based on the current process state
- RNBRunLoopMode mode = HandleProcessStateChange(remote, true);
-
- while (ctx.ProcessID() != INVALID_NUB_PROCESS) {
-
- std::string set_events_str;
- uint32_t event_mask = ctx.NormalEventBits();
-
- if (!ctx.ProcessStateRunning()) {
- // Clear the stdio bits if we are not running so we don't send any async
- // packets
- event_mask &= ~RNBContext::event_proc_stdio_available;
- }
-
- // We want to make sure we consume all process state changes and have
- // whomever is notifying us to wait for us to reset the event bit before
- // continuing.
- // ctx.Events().SetResetAckMask (RNBContext::event_proc_state_changed);
-
- DNBLogThreadedIf(LOG_RNB_EVENTS,
- "%s ctx.Events().WaitForSetEvents(0x%08x) ...",
- __FUNCTION__, event_mask);
- nub_event_t set_events = ctx.Events().WaitForSetEvents(event_mask);
- DNBLogThreadedIf(LOG_RNB_EVENTS,
- "%s ctx.Events().WaitForSetEvents(0x%08x) => 0x%08x (%s)",
- __FUNCTION__, event_mask, set_events,
- ctx.EventsAsString(set_events, set_events_str));
-
- if (set_events) {
- if ((set_events & RNBContext::event_proc_thread_exiting) ||
- (set_events & RNBContext::event_proc_stdio_available)) {
- remote->FlushSTDIO();
- }
-
- if (set_events & RNBContext::event_read_packet_available) {
- // handleReceivedPacket will take care of resetting the
- // event_read_packet_available events when there are no more...
- set_events ^= RNBContext::event_read_packet_available;
-
- if (ctx.ProcessStateRunning()) {
- if (remote->HandleAsyncPacket() == rnb_not_connected) {
- // TODO: connect again? Exit?
- }
- } else {
- if (remote->HandleReceivedPacket() == rnb_not_connected) {
- // TODO: connect again? Exit?
- }
- }
- }
-
- if (set_events & RNBContext::event_proc_state_changed) {
- mode = HandleProcessStateChange(remote, false);
- ctx.Events().ResetEvents(RNBContext::event_proc_state_changed);
- set_events ^= RNBContext::event_proc_state_changed;
- }
-
- if (set_events & RNBContext::event_proc_thread_exiting) {
- mode = eRNBRunLoopModeExit;
- }
-
- if (set_events & RNBContext::event_read_thread_exiting) {
- // Out remote packet receiving thread exited, exit for now.
- if (ctx.HasValidProcessID()) {
- // TODO: We should add code that will leave the current process
- // in its current state and listen for another connection...
- if (ctx.ProcessStateRunning()) {
- DNBProcessKill(ctx.ProcessID());
- }
- }
- mode = eRNBRunLoopModeExit;
- }
- }
-
- // Reset all event bits that weren't reset for now...
- if (set_events != 0)
- ctx.Events().ResetEvents(set_events);
-
- if (mode != eRNBRunLoopModeInferiorExecuting)
- break;
- }
-
- return mode;
-}
-
-void ASLLogCallback(void *baton, uint32_t flags, const char *format,
- va_list args) {
-#if 0
- vprintf(format, args);
-#endif
-}
-
-extern "C" int debug_server_main(int fd) {
-#if 1
- g_isatty = 0;
-#else
- g_isatty = ::isatty(STDIN_FILENO);
-
- DNBLogSetDebug(1);
- DNBLogSetVerbose(1);
- DNBLogSetLogMask(-1);
- DNBLogSetLogCallback(ASLLogCallback, NULL);
-#endif
-
- signal(SIGPIPE, signal_handler);
-
- g_remoteSP.reset(new RNBRemote);
-
- RNBRemote *remote = g_remoteSP.get();
- if (remote == NULL) {
- RNBLogSTDERR("error: failed to create a remote connection class\n");
- return -1;
- }
-
- RNBRunLoopMode mode = eRNBRunLoopModeGetStartModeFromRemoteProtocol;
-
- while (mode != eRNBRunLoopModeExit) {
- switch (mode) {
- case eRNBRunLoopModeGetStartModeFromRemoteProtocol:
- if (g_remoteSP->Comm().useFD(fd) == rnb_success) {
- RNBLogSTDOUT("Starting remote data thread.\n");
- g_remoteSP->StartReadRemoteDataThread();
-
- RNBLogSTDOUT("Waiting for start mode from remote.\n");
- mode = RNBRunLoopGetStartModeFromRemote(g_remoteSP);
- } else {
- mode = eRNBRunLoopModeExit;
- }
- break;
-
- case eRNBRunLoopModeInferiorExecuting:
- mode = RNBRunLoopInferiorExecuting(g_remoteSP);
- break;
-
- default:
- mode = eRNBRunLoopModeExit;
- break;
-
- case eRNBRunLoopModeExit:
- break;
- }
- }
-
- g_remoteSP->StopReadRemoteDataThread();
- g_remoteSP->Context().SetProcessID(INVALID_NUB_PROCESS);
-
- return 0;
-}
diff --git a/tools/debugserver/source/libdebugserver.h b/tools/debugserver/source/libdebugserver.h
deleted file mode 100644
index 2576e269ee60..000000000000
--- a/tools/debugserver/source/libdebugserver.h
+++ /dev/null
@@ -1,15 +0,0 @@
-//===-- libdebugserver.h ----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef debugserver_libdebugserver_h
-#define debugserver_libdebugserver_h
-
-int debug_server_main(int fd);
-
-#endif