aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-01-02 19:26:05 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-01-02 19:26:05 +0000
commit14f1b3e8826ce43b978db93a62d1166055db5394 (patch)
tree0a00ad8d3498783fe0193f3b656bca17c4c8697d /tools
parent4ee8c119c71a06dcad1e0fecc8c675e480e59337 (diff)
downloadsrc-14f1b3e8826ce43b978db93a62d1166055db5394.tar.gz
src-14f1b3e8826ce43b978db93a62d1166055db5394.zip
Vendor import of lldb trunk r290819:vendor/lldb/lldb-trunk-r290819
Notes
Notes: svn path=/vendor/lldb/dist/; revision=311128 svn path=/vendor/lldb/lldb-trunk-r290819/; revision=311129; tag=vendor/lldb/lldb-trunk-r290819
Diffstat (limited to 'tools')
-rw-r--r--tools/CMakeLists.txt8
-rw-r--r--tools/argdumper/CMakeLists.txt13
-rw-r--r--tools/argdumper/argdumper.cpp39
-rw-r--r--tools/compact-unwind/compact-unwind-dumper.c2814
-rw-r--r--tools/darwin-debug/CMakeLists.txt5
-rw-r--r--tools/darwin-debug/darwin-debug.cpp565
-rw-r--r--tools/darwin-threads/examine-threads.c737
-rw-r--r--tools/debugserver/debugserver.xcodeproj/project.pbxproj176
-rw-r--r--tools/debugserver/source/ARM_DWARF_Registers.h365
-rw-r--r--tools/debugserver/source/ARM_ehframe_Registers.h41
-rw-r--r--tools/debugserver/source/CMakeLists.txt6
-rw-r--r--tools/debugserver/source/DNB.cpp2982
-rw-r--r--tools/debugserver/source/DNB.h274
-rw-r--r--tools/debugserver/source/DNBArch.cpp95
-rw-r--r--tools/debugserver/source/DNBArch.h176
-rw-r--r--tools/debugserver/source/DNBBreakpoint.cpp329
-rw-r--r--tools/debugserver/source/DNBBreakpoint.h232
-rw-r--r--tools/debugserver/source/DNBDataRef.cpp516
-rw-r--r--tools/debugserver/source/DNBDataRef.h170
-rw-r--r--tools/debugserver/source/DNBDefs.h545
-rw-r--r--tools/debugserver/source/DNBError.cpp162
-rw-r--r--tools/debugserver/source/DNBError.h124
-rw-r--r--tools/debugserver/source/DNBLog.cpp452
-rw-r--r--tools/debugserver/source/DNBLog.h175
-rw-r--r--tools/debugserver/source/DNBRegisterInfo.cpp412
-rw-r--r--tools/debugserver/source/DNBRegisterInfo.h13
-rw-r--r--tools/debugserver/source/DNBRuntimeAction.h11
-rw-r--r--tools/debugserver/source/DNBThreadResumeActions.cpp139
-rw-r--r--tools/debugserver/source/DNBThreadResumeActions.h118
-rw-r--r--tools/debugserver/source/DNBTimer.h246
-rw-r--r--tools/debugserver/source/JSON.cpp588
-rw-r--r--tools/debugserver/source/JSON.h303
-rw-r--r--tools/debugserver/source/JSONGenerator.h717
-rw-r--r--tools/debugserver/source/MacOSX/CFBundle.cpp89
-rw-r--r--tools/debugserver/source/MacOSX/CFBundle.h31
-rw-r--r--tools/debugserver/source/MacOSX/CFData.cpp85
-rw-r--r--tools/debugserver/source/MacOSX/CFData.h39
-rw-r--r--tools/debugserver/source/MacOSX/CFString.cpp232
-rw-r--r--tools/debugserver/source/MacOSX/CFString.h38
-rw-r--r--tools/debugserver/source/MacOSX/CFUtils.h91
-rw-r--r--tools/debugserver/source/MacOSX/CMakeLists.txt35
-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.cpp697
-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.cpp509
-rw-r--r--tools/debugserver/source/MacOSX/Genealogy.h190
-rw-r--r--tools/debugserver/source/MacOSX/GenealogySPI.h103
-rw-r--r--tools/debugserver/source/MacOSX/HasAVX.h6
-rw-r--r--tools/debugserver/source/MacOSX/MachException.cpp916
-rw-r--r--tools/debugserver/source/MacOSX/MachException.h201
-rw-r--r--tools/debugserver/source/MacOSX/MachProcess.h771
-rw-r--r--tools/debugserver/source/MacOSX/MachProcess.mm6788
-rw-r--r--tools/debugserver/source/MacOSX/MachTask.h135
-rw-r--r--tools/debugserver/source/MacOSX/MachTask.mm1588
-rw-r--r--tools/debugserver/source/MacOSX/MachThread.cpp1489
-rw-r--r--tools/debugserver/source/MacOSX/MachThread.h243
-rw-r--r--tools/debugserver/source/MacOSX/MachThreadList.cpp996
-rw-r--r--tools/debugserver/source/MacOSX/MachThreadList.h114
-rw-r--r--tools/debugserver/source/MacOSX/MachVMMemory.cpp1012
-rw-r--r--tools/debugserver/source/MacOSX/MachVMMemory.h57
-rw-r--r--tools/debugserver/source/MacOSX/MachVMRegion.cpp318
-rw-r--r--tools/debugserver/source/MacOSX/MachVMRegion.h88
-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.h14
-rw-r--r--tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp3706
-rw-r--r--tools/debugserver/source/MacOSX/arm/DNBArchImpl.h465
-rw-r--r--tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp3693
-rw-r--r--tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.h461
-rw-r--r--tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp3839
-rw-r--r--tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h425
-rw-r--r--tools/debugserver/source/MacOSX/i386/MachRegisterStatesI386.h268
-rw-r--r--tools/debugserver/source/MacOSX/ppc/DNBArchImpl.cpp855
-rw-r--r--tools/debugserver/source/MacOSX/ppc/DNBArchImpl.h267
-rw-r--r--tools/debugserver/source/MacOSX/stack_logging.h152
-rw-r--r--tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp4421
-rw-r--r--tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h426
-rw-r--r--tools/debugserver/source/MacOSX/x86_64/MachRegisterStatesX86_64.h330
-rw-r--r--tools/debugserver/source/PThreadCondition.h32
-rw-r--r--tools/debugserver/source/PThreadEvent.cpp323
-rw-r--r--tools/debugserver/source/PThreadEvent.h73
-rw-r--r--tools/debugserver/source/PThreadMutex.cpp85
-rw-r--r--tools/debugserver/source/PThreadMutex.h178
-rw-r--r--tools/debugserver/source/PseudoTerminal.cpp199
-rw-r--r--tools/debugserver/source/PseudoTerminal.h121
-rw-r--r--tools/debugserver/source/RNBContext.cpp431
-rw-r--r--tools/debugserver/source/RNBContext.h268
-rw-r--r--tools/debugserver/source/RNBDefs.h71
-rw-r--r--tools/debugserver/source/RNBRemote.cpp10883
-rw-r--r--tools/debugserver/source/RNBRemote.h780
-rw-r--r--tools/debugserver/source/RNBServices.cpp391
-rw-r--r--tools/debugserver/source/RNBServices.h15
-rw-r--r--tools/debugserver/source/RNBSocket.cpp645
-rw-r--r--tools/debugserver/source/RNBSocket.h76
-rw-r--r--tools/debugserver/source/StdStringExtractor.cpp405
-rw-r--r--tools/debugserver/source/StdStringExtractor.h125
-rw-r--r--tools/debugserver/source/SysSignal.cpp121
-rw-r--r--tools/debugserver/source/SysSignal.h5
-rw-r--r--tools/debugserver/source/TTYState.cpp152
-rw-r--r--tools/debugserver/source/TTYState.h56
-rw-r--r--tools/debugserver/source/debugserver.cpp2877
-rw-r--r--tools/debugserver/source/libdebugserver.cpp622
-rw-r--r--tools/driver/CMakeLists.txt18
-rw-r--r--tools/driver/Driver.cpp2244
-rw-r--r--tools/driver/Driver.h199
-rw-r--r--tools/driver/Platform.cpp84
-rw-r--r--tools/driver/Platform.h132
-rw-r--r--tools/lldb-mi/CMakeLists.txt13
-rw-r--r--tools/lldb-mi/MICmdArgContext.cpp281
-rw-r--r--tools/lldb-mi/MICmdArgContext.h46
-rw-r--r--tools/lldb-mi/MICmdArgSet.cpp536
-rw-r--r--tools/lldb-mi/MICmdArgSet.h135
-rw-r--r--tools/lldb-mi/MICmdArgValBase.cpp123
-rw-r--r--tools/lldb-mi/MICmdArgValBase.h119
-rw-r--r--tools/lldb-mi/MICmdArgValConsume.cpp88
-rw-r--r--tools/lldb-mi/MICmdArgValConsume.h46
-rw-r--r--tools/lldb-mi/MICmdArgValFile.cpp226
-rw-r--r--tools/lldb-mi/MICmdArgValFile.h42
-rw-r--r--tools/lldb-mi/MICmdArgValListBase.cpp268
-rw-r--r--tools/lldb-mi/MICmdArgValListBase.h120
-rw-r--r--tools/lldb-mi/MICmdArgValListOfN.cpp203
-rw-r--r--tools/lldb-mi/MICmdArgValListOfN.h84
-rw-r--r--tools/lldb-mi/MICmdArgValNumber.cpp193
-rw-r--r--tools/lldb-mi/MICmdArgValNumber.h80
-rw-r--r--tools/lldb-mi/MICmdArgValOptionLong.cpp401
-rw-r--r--tools/lldb-mi/MICmdArgValOptionLong.h115
-rw-r--r--tools/lldb-mi/MICmdArgValOptionShort.cpp117
-rw-r--r--tools/lldb-mi/MICmdArgValOptionShort.h57
-rw-r--r--tools/lldb-mi/MICmdArgValPrintValues.cpp124
-rw-r--r--tools/lldb-mi/MICmdArgValPrintValues.h52
-rw-r--r--tools/lldb-mi/MICmdArgValString.cpp487
-rw-r--r--tools/lldb-mi/MICmdArgValString.h93
-rw-r--r--tools/lldb-mi/MICmdArgValThreadGrp.cpp182
-rw-r--r--tools/lldb-mi/MICmdArgValThreadGrp.h49
-rw-r--r--tools/lldb-mi/MICmdBase.cpp282
-rw-r--r--tools/lldb-mi/MICmdBase.h214
-rw-r--r--tools/lldb-mi/MICmdCmd.cpp146
-rw-r--r--tools/lldb-mi/MICmdCmd.h84
-rw-r--r--tools/lldb-mi/MICmdCmdBreak.cpp1320
-rw-r--r--tools/lldb-mi/MICmdCmdBreak.h361
-rw-r--r--tools/lldb-mi/MICmdCmdData.cpp2325
-rw-r--r--tools/lldb-mi/MICmdCmdData.h573
-rw-r--r--tools/lldb-mi/MICmdCmdEnviro.cpp144
-rw-r--r--tools/lldb-mi/MICmdCmdEnviro.h53
-rw-r--r--tools/lldb-mi/MICmdCmdExec.cpp1379
-rw-r--r--tools/lldb-mi/MICmdCmdExec.h493
-rw-r--r--tools/lldb-mi/MICmdCmdFile.cpp253
-rw-r--r--tools/lldb-mi/MICmdCmdFile.h62
-rw-r--r--tools/lldb-mi/MICmdCmdGdbInfo.cpp273
-rw-r--r--tools/lldb-mi/MICmdCmdGdbInfo.h88
-rw-r--r--tools/lldb-mi/MICmdCmdGdbSet.cpp570
-rw-r--r--tools/lldb-mi/MICmdCmdGdbSet.h107
-rw-r--r--tools/lldb-mi/MICmdCmdGdbShow.cpp433
-rw-r--r--tools/lldb-mi/MICmdCmdGdbShow.h105
-rw-r--r--tools/lldb-mi/MICmdCmdGdbThread.cpp72
-rw-r--r--tools/lldb-mi/MICmdCmdGdbThread.h43
-rw-r--r--tools/lldb-mi/MICmdCmdMiscellanous.cpp729
-rw-r--r--tools/lldb-mi/MICmdCmdMiscellanous.h210
-rw-r--r--tools/lldb-mi/MICmdCmdStack.cpp1301
-rw-r--r--tools/lldb-mi/MICmdCmdStack.h380
-rw-r--r--tools/lldb-mi/MICmdCmdSupportInfo.cpp109
-rw-r--r--tools/lldb-mi/MICmdCmdSupportInfo.h54
-rw-r--r--tools/lldb-mi/MICmdCmdSupportList.cpp84
-rw-r--r--tools/lldb-mi/MICmdCmdSupportList.h43
-rw-r--r--tools/lldb-mi/MICmdCmdSymbol.cpp321
-rw-r--r--tools/lldb-mi/MICmdCmdSymbol.h59
-rw-r--r--tools/lldb-mi/MICmdCmdTarget.cpp611
-rw-r--r--tools/lldb-mi/MICmdCmdTarget.h134
-rw-r--r--tools/lldb-mi/MICmdCmdThread.cpp280
-rw-r--r--tools/lldb-mi/MICmdCmdThread.h73
-rw-r--r--tools/lldb-mi/MICmdCmdTrace.cpp72
-rw-r--r--tools/lldb-mi/MICmdCmdTrace.h43
-rw-r--r--tools/lldb-mi/MICmdCmdVar.cpp1900
-rw-r--r--tools/lldb-mi/MICmdCmdVar.h535
-rw-r--r--tools/lldb-mi/MICmdCommands.cpp159
-rw-r--r--tools/lldb-mi/MICmdCommands.h6
-rw-r--r--tools/lldb-mi/MICmdData.h79
-rw-r--r--tools/lldb-mi/MICmdFactory.cpp235
-rw-r--r--tools/lldb-mi/MICmdFactory.h92
-rw-r--r--tools/lldb-mi/MICmdInterpreter.cpp369
-rw-r--r--tools/lldb-mi/MICmdInterpreter.h74
-rw-r--r--tools/lldb-mi/MICmdInvoker.cpp409
-rw-r--r--tools/lldb-mi/MICmdInvoker.h118
-rw-r--r--tools/lldb-mi/MICmdMgr.cpp317
-rw-r--r--tools/lldb-mi/MICmdMgr.h64
-rw-r--r--tools/lldb-mi/MICmdMgrSetCmdDeleteCallback.cpp82
-rw-r--r--tools/lldb-mi/MICmdMgrSetCmdDeleteCallback.h61
-rw-r--r--tools/lldb-mi/MICmnBase.cpp108
-rw-r--r--tools/lldb-mi/MICmnBase.h44
-rw-r--r--tools/lldb-mi/MICmnConfig.h6
-rw-r--r--tools/lldb-mi/MICmnLLDBBroadcaster.cpp51
-rw-r--r--tools/lldb-mi/MICmnLLDBBroadcaster.h38
-rw-r--r--tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp1187
-rw-r--r--tools/lldb-mi/MICmnLLDBDebugSessionInfo.h404
-rw-r--r--tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.cpp594
-rw-r--r--tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.h211
-rw-r--r--tools/lldb-mi/MICmnLLDBDebugger.cpp1170
-rw-r--r--tools/lldb-mi/MICmnLLDBDebugger.h187
-rw-r--r--tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp2903
-rw-r--r--tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.h126
-rw-r--r--tools/lldb-mi/MICmnLLDBProxySBValue.cpp172
-rw-r--r--tools/lldb-mi/MICmnLLDBProxySBValue.h21
-rw-r--r--tools/lldb-mi/MICmnLLDBUtilSBValue.cpp636
-rw-r--r--tools/lldb-mi/MICmnLLDBUtilSBValue.h93
-rw-r--r--tools/lldb-mi/MICmnLog.cpp388
-rw-r--r--tools/lldb-mi/MICmnLog.h209
-rw-r--r--tools/lldb-mi/MICmnLogMediumFile.cpp402
-rw-r--r--tools/lldb-mi/MICmnLogMediumFile.h111
-rw-r--r--tools/lldb-mi/MICmnMIOutOfBandRecord.cpp231
-rw-r--r--tools/lldb-mi/MICmnMIOutOfBandRecord.h110
-rw-r--r--tools/lldb-mi/MICmnMIResultRecord.cpp122
-rw-r--r--tools/lldb-mi/MICmnMIResultRecord.h79
-rw-r--r--tools/lldb-mi/MICmnMIValue.cpp27
-rw-r--r--tools/lldb-mi/MICmnMIValue.h36
-rw-r--r--tools/lldb-mi/MICmnMIValueConst.cpp71
-rw-r--r--tools/lldb-mi/MICmnMIValueConst.h48
-rw-r--r--tools/lldb-mi/MICmnMIValueList.cpp183
-rw-r--r--tools/lldb-mi/MICmnMIValueList.h45
-rw-r--r--tools/lldb-mi/MICmnMIValueResult.cpp102
-rw-r--r--tools/lldb-mi/MICmnMIValueResult.h63
-rw-r--r--tools/lldb-mi/MICmnMIValueTuple.cpp212
-rw-r--r--tools/lldb-mi/MICmnMIValueTuple.h57
-rw-r--r--tools/lldb-mi/MICmnResources.cpp848
-rw-r--r--tools/lldb-mi/MICmnResources.h608
-rw-r--r--tools/lldb-mi/MICmnStreamStderr.cpp250
-rw-r--r--tools/lldb-mi/MICmnStreamStderr.h77
-rw-r--r--tools/lldb-mi/MICmnStreamStdin.cpp249
-rw-r--r--tools/lldb-mi/MICmnStreamStdin.h69
-rw-r--r--tools/lldb-mi/MICmnStreamStdout.cpp216
-rw-r--r--tools/lldb-mi/MICmnStreamStdout.h80
-rw-r--r--tools/lldb-mi/MICmnThreadMgrStd.cpp149
-rw-r--r--tools/lldb-mi/MICmnThreadMgrStd.h178
-rw-r--r--tools/lldb-mi/MIDataTypes.h5
-rw-r--r--tools/lldb-mi/MIDriver.cpp1719
-rw-r--r--tools/lldb-mi/MIDriver.h275
-rw-r--r--tools/lldb-mi/MIDriverBase.cpp155
-rw-r--r--tools/lldb-mi/MIDriverBase.h62
-rw-r--r--tools/lldb-mi/MIDriverMain.cpp218
-rw-r--r--tools/lldb-mi/MIDriverMgr.cpp1008
-rw-r--r--tools/lldb-mi/MIDriverMgr.h161
-rw-r--r--tools/lldb-mi/MIUtilDateTimeStd.cpp77
-rw-r--r--tools/lldb-mi/MIUtilDateTimeStd.h34
-rw-r--r--tools/lldb-mi/MIUtilDebug.cpp86
-rw-r--r--tools/lldb-mi/MIUtilDebug.h65
-rw-r--r--tools/lldb-mi/MIUtilFileStd.cpp328
-rw-r--r--tools/lldb-mi/MIUtilFileStd.h58
-rw-r--r--tools/lldb-mi/MIUtilMapIdToVariant.cpp85
-rw-r--r--tools/lldb-mi/MIUtilMapIdToVariant.h163
-rw-r--r--tools/lldb-mi/MIUtilParse.cpp75
-rw-r--r--tools/lldb-mi/MIUtilParse.h93
-rw-r--r--tools/lldb-mi/MIUtilSingletonBase.h41
-rw-r--r--tools/lldb-mi/MIUtilSingletonHelper.h73
-rw-r--r--tools/lldb-mi/MIUtilString.cpp1282
-rw-r--r--tools/lldb-mi/MIUtilString.h125
-rw-r--r--tools/lldb-mi/MIUtilThreadBaseStd.cpp306
-rw-r--r--tools/lldb-mi/MIUtilThreadBaseStd.h223
-rw-r--r--tools/lldb-mi/MIUtilVariant.cpp294
-rw-r--r--tools/lldb-mi/MIUtilVariant.h278
-rw-r--r--tools/lldb-mi/Platform.h55
-rw-r--r--tools/lldb-perf/common/clang/lldb_perf_clang.cpp770
-rw-r--r--tools/lldb-perf/common/clang/main.cpp32
-rw-r--r--tools/lldb-perf/common/stepping/lldb-perf-stepping.cpp528
-rw-r--r--tools/lldb-perf/common/stepping/stepping-testcase.cpp65
-rw-r--r--tools/lldb-perf/darwin/formatters/fmts_tester.mm131
-rw-r--r--tools/lldb-perf/darwin/formatters/formatters.cpp456
-rw-r--r--tools/lldb-perf/darwin/sketch/sketch.cpp620
-rw-r--r--tools/lldb-perf/lib/Gauge.cpp63
-rw-r--r--tools/lldb-perf/lib/Gauge.h51
-rw-r--r--tools/lldb-perf/lib/Measurement.h303
-rw-r--r--tools/lldb-perf/lib/MemoryGauge.cpp204
-rw-r--r--tools/lldb-perf/lib/MemoryGauge.h175
-rw-r--r--tools/lldb-perf/lib/Metric.cpp83
-rw-r--r--tools/lldb-perf/lib/Metric.h78
-rw-r--r--tools/lldb-perf/lib/Results.cpp428
-rw-r--r--tools/lldb-perf/lib/Results.h461
-rw-r--r--tools/lldb-perf/lib/TestCase.cpp588
-rw-r--r--tools/lldb-perf/lib/TestCase.h286
-rw-r--r--tools/lldb-perf/lib/Timer.cpp58
-rw-r--r--tools/lldb-perf/lib/Timer.h63
-rw-r--r--tools/lldb-perf/lib/Xcode.cpp238
-rw-r--r--tools/lldb-perf/lib/Xcode.h74
-rw-r--r--tools/lldb-server/Acceptor.cpp194
-rw-r--r--tools/lldb-server/Acceptor.h49
-rw-r--r--tools/lldb-server/CMakeLists.txt147
-rw-r--r--tools/lldb-server/Darwin/resources/lldb-server-Info.plist21
-rw-r--r--tools/lldb-server/Darwin/resources/lldb-server-entitlements.plist28
-rw-r--r--tools/lldb-server/Darwin/resources/lldb-server-macos-entitlements.plist8
-rw-r--r--tools/lldb-server/Darwin/resources/lldb-server-mig.defs5
-rw-r--r--tools/lldb-server/LLDBServerUtilities.cpp74
-rw-r--r--tools/lldb-server/LLDBServerUtilities.h9
-rw-r--r--tools/lldb-server/lldb-gdbserver.cpp744
-rw-r--r--tools/lldb-server/lldb-platform.cpp633
-rw-r--r--tools/lldb-server/lldb-server.cpp93
311 files changed, 63008 insertions, 60320 deletions
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index 49af928c3815..86b9621a198e 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -2,11 +2,9 @@ if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
add_subdirectory(darwin-debug)
add_subdirectory(debugserver)
endif()
- add_subdirectory(argdumper)
- add_subdirectory(driver)
-if (NOT __ANDROID_NDK__)
- add_subdirectory(lldb-mi)
-endif()
+add_subdirectory(argdumper)
+add_subdirectory(driver)
+add_subdirectory(lldb-mi)
if (LLDB_CAN_USE_LLDB_SERVER)
add_subdirectory(lldb-server)
endif()
diff --git a/tools/argdumper/CMakeLists.txt b/tools/argdumper/CMakeLists.txt
index 69bc97c7e518..9bf956396b4f 100644
--- a/tools/argdumper/CMakeLists.txt
+++ b/tools/argdumper/CMakeLists.txt
@@ -1,8 +1,13 @@
-add_lldb_executable(lldb-argdumper
+include(${LLDB_PROJECT_ROOT}/cmake/LLDBDependencies.cmake)
+
+add_lldb_tool(lldb-argdumper INCLUDE_IN_FRAMEWORK
argdumper.cpp
)
-target_link_libraries(lldb-argdumper liblldb)
+if (LLDB_LINKER_SUPPORTS_GROUPS)
+ target_link_libraries(lldb-argdumper -Wl,--start-group ${LLDB_USED_LIBS} -Wl,--end-group)
+else()
+ target_link_libraries(lldb-argdumper ${LLDB_USED_LIBS})
+endif()
+llvm_config(lldb-argdumper ${LLVM_LINK_COMPONENTS})
-install(TARGETS lldb-argdumper
- RUNTIME DESTINATION bin)
diff --git a/tools/argdumper/argdumper.cpp b/tools/argdumper/argdumper.cpp
index 381a9d2f4b22..01a070efb82c 100644
--- a/tools/argdumper/argdumper.cpp
+++ b/tools/argdumper/argdumper.cpp
@@ -1,4 +1,4 @@
-//===-- argdumper.cpp --------------------------------------------*- C++ -*-===//
+//===-- argdumper.cpp --------------------------------------------*- C++-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,25 +14,20 @@
using namespace lldb_private;
-int
-main (int argc, char *argv[])
-{
- JSONArray::SP arguments(new JSONArray());
- for (int i = 1;
- i < argc;
- i++)
- {
- arguments->AppendObject(JSONString::SP(new JSONString(argv[i])));
- }
-
- JSONObject::SP object(new JSONObject());
- object->SetObject("arguments", arguments);
-
- StreamString ss;
-
- object->Write(ss);
-
- std::cout << ss.GetData() << std::endl;
-
- return 0;
+int main(int argc, char *argv[]) {
+ JSONArray::SP arguments(new JSONArray());
+ for (int i = 1; i < argc; i++) {
+ arguments->AppendObject(JSONString::SP(new JSONString(argv[i])));
+ }
+
+ JSONObject::SP object(new JSONObject());
+ object->SetObject("arguments", arguments);
+
+ StreamString ss;
+
+ object->Write(ss);
+
+ std::cout << ss.GetData() << std::endl;
+
+ return 0;
}
diff --git a/tools/compact-unwind/compact-unwind-dumper.c b/tools/compact-unwind/compact-unwind-dumper.c
index f70f602326bf..570c42981a24 100644
--- a/tools/compact-unwind/compact-unwind-dumper.c
+++ b/tools/compact-unwind/compact-unwind-dumper.c
@@ -1,66 +1,64 @@
-#include <stdint.h>
-#include <mach-o/loader.h>
+#include <fcntl.h>
+#include <inttypes.h>
#include <mach-o/compact_unwind_encoding.h>
+#include <mach-o/loader.h>
+#include <mach-o/nlist.h>
#include <mach/machine.h>
-#include <stdlib.h>
#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/mman.h>
#include <sys/errno.h>
+#include <sys/mman.h>
#include <sys/stat.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <mach-o/nlist.h>
-
+#include <sys/types.h>
enum {
- UNWIND_ARM64_MODE_MASK = 0x0F000000,
- UNWIND_ARM64_MODE_FRAMELESS = 0x02000000,
- UNWIND_ARM64_MODE_DWARF = 0x03000000,
- UNWIND_ARM64_MODE_FRAME = 0x04000000,
-
- UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001,
- UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002,
- UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004,
- UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008,
- UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010,
- UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100,
- UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200,
- UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400,
- UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800,
-
- UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK = 0x00FFF000,
- UNWIND_ARM64_DWARF_SECTION_OFFSET = 0x00FFFFFF,
+ UNWIND_ARM64_MODE_MASK = 0x0F000000,
+ UNWIND_ARM64_MODE_FRAMELESS = 0x02000000,
+ UNWIND_ARM64_MODE_DWARF = 0x03000000,
+ UNWIND_ARM64_MODE_FRAME = 0x04000000,
+
+ UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001,
+ UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002,
+ UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004,
+ UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008,
+ UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010,
+ UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100,
+ UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200,
+ UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400,
+ UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800,
+
+ UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK = 0x00FFF000,
+ UNWIND_ARM64_DWARF_SECTION_OFFSET = 0x00FFFFFF,
};
enum {
- UNWIND_ARM_MODE_MASK = 0x0F000000,
- UNWIND_ARM_MODE_FRAME = 0x01000000,
- UNWIND_ARM_MODE_FRAME_D = 0x02000000,
- UNWIND_ARM_MODE_DWARF = 0x04000000,
+ UNWIND_ARM_MODE_MASK = 0x0F000000,
+ UNWIND_ARM_MODE_FRAME = 0x01000000,
+ UNWIND_ARM_MODE_FRAME_D = 0x02000000,
+ UNWIND_ARM_MODE_DWARF = 0x04000000,
- UNWIND_ARM_FRAME_STACK_ADJUST_MASK = 0x00C00000,
+ UNWIND_ARM_FRAME_STACK_ADJUST_MASK = 0x00C00000,
- UNWIND_ARM_FRAME_FIRST_PUSH_R4 = 0x00000001,
- UNWIND_ARM_FRAME_FIRST_PUSH_R5 = 0x00000002,
- UNWIND_ARM_FRAME_FIRST_PUSH_R6 = 0x00000004,
+ UNWIND_ARM_FRAME_FIRST_PUSH_R4 = 0x00000001,
+ UNWIND_ARM_FRAME_FIRST_PUSH_R5 = 0x00000002,
+ UNWIND_ARM_FRAME_FIRST_PUSH_R6 = 0x00000004,
- UNWIND_ARM_FRAME_SECOND_PUSH_R8 = 0x00000008,
- UNWIND_ARM_FRAME_SECOND_PUSH_R9 = 0x00000010,
- UNWIND_ARM_FRAME_SECOND_PUSH_R10 = 0x00000020,
- UNWIND_ARM_FRAME_SECOND_PUSH_R11 = 0x00000040,
- UNWIND_ARM_FRAME_SECOND_PUSH_R12 = 0x00000080,
+ UNWIND_ARM_FRAME_SECOND_PUSH_R8 = 0x00000008,
+ UNWIND_ARM_FRAME_SECOND_PUSH_R9 = 0x00000010,
+ UNWIND_ARM_FRAME_SECOND_PUSH_R10 = 0x00000020,
+ UNWIND_ARM_FRAME_SECOND_PUSH_R11 = 0x00000040,
+ UNWIND_ARM_FRAME_SECOND_PUSH_R12 = 0x00000080,
- UNWIND_ARM_FRAME_D_REG_COUNT_MASK = 0x00000700,
+ UNWIND_ARM_FRAME_D_REG_COUNT_MASK = 0x00000700,
- UNWIND_ARM_DWARF_SECTION_OFFSET = 0x00FFFFFF,
+ UNWIND_ARM_DWARF_SECTION_OFFSET = 0x00FFFFFF,
};
-#define EXTRACT_BITS(value, mask) \
- ( (value >> __builtin_ctz(mask)) & (((1 << __builtin_popcount(mask)))-1) )
-
+#define EXTRACT_BITS(value, mask) \
+ ((value >> __builtin_ctz(mask)) & (((1 << __builtin_popcount(mask))) - 1))
// A quick sketch of a program which can parse the compact unwind info
// used on Darwin systems for exception handling. The output of
@@ -68,1534 +66,1450 @@ enum {
// can dump at least the UNWIND_X86_64_MODE_RBP_FRAME format entries
// correctly.
-struct symbol
-{
- uint64_t file_address;
- const char *name;
+struct symbol {
+ uint64_t file_address;
+ const char *name;
};
-int
-symbol_compare (const void *a, const void *b)
-{
- return (int) ((struct symbol *)a)->file_address - ((struct symbol *)b)->file_address;
+int symbol_compare(const void *a, const void *b) {
+ return (int)((struct symbol *)a)->file_address -
+ ((struct symbol *)b)->file_address;
}
-struct baton
-{
- cpu_type_t cputype;
+struct baton {
+ cpu_type_t cputype;
- uint8_t *mach_header_start; // pointer into this program's address space
- uint8_t *compact_unwind_start; // pointer into this program's address space
+ uint8_t *mach_header_start; // pointer into this program's address space
+ uint8_t *compact_unwind_start; // pointer into this program's address space
- int addr_size; // 4 or 8 bytes, the size of addresses in this file
+ int addr_size; // 4 or 8 bytes, the size of addresses in this file
- uint64_t text_segment_vmaddr; // __TEXT segment vmaddr
- uint64_t text_segment_file_offset;
+ uint64_t text_segment_vmaddr; // __TEXT segment vmaddr
+ uint64_t text_segment_file_offset;
- uint64_t text_section_vmaddr; // __TEXT,__text section vmaddr
- uint64_t text_section_file_offset;
+ uint64_t text_section_vmaddr; // __TEXT,__text section vmaddr
+ uint64_t text_section_file_offset;
- uint64_t eh_section_file_address; // the file address of the __TEXT,__eh_frame section
+ uint64_t eh_section_file_address; // the file address of the __TEXT,__eh_frame
+ // section
- uint8_t *lsda_array_start; // for the currently-being-processed first-level index
- uint8_t *lsda_array_end; // the lsda_array_start for the NEXT first-level index
+ uint8_t
+ *lsda_array_start; // for the currently-being-processed first-level index
+ uint8_t
+ *lsda_array_end; // the lsda_array_start for the NEXT first-level index
- struct symbol *symbols;
- int symbols_count;
+ struct symbol *symbols;
+ int symbols_count;
- uint64_t *function_start_addresses;
- int function_start_addresses_count;
+ uint64_t *function_start_addresses;
+ int function_start_addresses_count;
- int current_index_table_number;
+ int current_index_table_number;
- struct unwind_info_section_header unwind_header;
- struct unwind_info_section_header_index_entry first_level_index_entry;
- struct unwind_info_compressed_second_level_page_header compressed_second_level_page_header;
- struct unwind_info_regular_second_level_page_header regular_second_level_page_header;
+ struct unwind_info_section_header unwind_header;
+ struct unwind_info_section_header_index_entry first_level_index_entry;
+ struct unwind_info_compressed_second_level_page_header
+ compressed_second_level_page_header;
+ struct unwind_info_regular_second_level_page_header
+ regular_second_level_page_header;
};
-
-uint64_t
-read_leb128 (uint8_t **offset)
-{
- uint64_t result = 0;
- int shift = 0;
- while (1)
- {
- uint8_t byte = **offset;
- *offset = *offset + 1;
- result |= (byte & 0x7f) << shift;
- if ((byte & 0x80) == 0)
- break;
- shift += 7;
- }
-
- return result;
+uint64_t read_leb128(uint8_t **offset) {
+ uint64_t result = 0;
+ int shift = 0;
+ while (1) {
+ uint8_t byte = **offset;
+ *offset = *offset + 1;
+ result |= (byte & 0x7f) << shift;
+ if ((byte & 0x80) == 0)
+ break;
+ shift += 7;
+ }
+
+ return result;
}
// step through the load commands in a thin mach-o binary,
// find the cputype and the start of the __TEXT,__unwind_info
// section, return a pointer to that section or NULL if not found.
-static void
-scan_macho_load_commands (struct baton *baton)
-{
- struct symtab_command symtab_cmd;
- uint64_t linkedit_segment_vmaddr;
- uint64_t linkedit_segment_file_offset;
-
- baton->compact_unwind_start = 0;
-
- uint32_t *magic = (uint32_t *) baton->mach_header_start;
-
- if (*magic != MH_MAGIC && *magic != MH_MAGIC_64)
- {
- printf ("Unexpected magic number 0x%x in header, exiting.", *magic);
- exit (1);
- }
-
- bool is_64bit = false;
- if (*magic == MH_MAGIC_64)
- is_64bit = true;
-
- uint8_t *offset = baton->mach_header_start;
-
- struct mach_header mh;
- memcpy (&mh, offset, sizeof (struct mach_header));
- if (is_64bit)
- offset += sizeof (struct mach_header_64);
- else
- offset += sizeof (struct mach_header);
-
- if (is_64bit)
- baton->addr_size = 8;
- else
- baton->addr_size = 4;
-
- baton->cputype = mh.cputype;
-
- uint8_t *start_of_load_commands = offset;
-
- uint32_t cur_cmd = 0;
- while (cur_cmd < mh.ncmds && (offset - start_of_load_commands) < mh.sizeofcmds)
- {
- struct load_command lc;
- uint32_t *lc_cmd = (uint32_t *) offset;
- uint32_t *lc_cmdsize = (uint32_t *) offset + 1;
- uint8_t *start_of_this_load_cmd = offset;
-
- if (*lc_cmd == LC_SEGMENT || *lc_cmd == LC_SEGMENT_64)
- {
- char segment_name[17];
- segment_name[0] = '\0';
- uint32_t nsects = 0;
- uint64_t segment_offset = 0;
- uint64_t segment_vmaddr = 0;
-
- if (*lc_cmd == LC_SEGMENT_64)
- {
- struct segment_command_64 seg;
- memcpy (&seg, offset, sizeof (struct segment_command_64));
- memcpy (&segment_name, &seg.segname, 16);
- segment_name[16] = '\0';
- nsects = seg.nsects;
- segment_offset = seg.fileoff;
- segment_vmaddr = seg.vmaddr;
- offset += sizeof (struct segment_command_64);
- if ((seg.flags & SG_PROTECTED_VERSION_1) == SG_PROTECTED_VERSION_1)
- {
- printf ("Segment '%s' is encrypted.\n", segment_name);
- }
+static void scan_macho_load_commands(struct baton *baton) {
+ struct symtab_command symtab_cmd;
+ uint64_t linkedit_segment_vmaddr;
+ uint64_t linkedit_segment_file_offset;
+
+ baton->compact_unwind_start = 0;
+
+ uint32_t *magic = (uint32_t *)baton->mach_header_start;
+
+ if (*magic != MH_MAGIC && *magic != MH_MAGIC_64) {
+ printf("Unexpected magic number 0x%x in header, exiting.", *magic);
+ exit(1);
+ }
+
+ bool is_64bit = false;
+ if (*magic == MH_MAGIC_64)
+ is_64bit = true;
+
+ uint8_t *offset = baton->mach_header_start;
+
+ struct mach_header mh;
+ memcpy(&mh, offset, sizeof(struct mach_header));
+ if (is_64bit)
+ offset += sizeof(struct mach_header_64);
+ else
+ offset += sizeof(struct mach_header);
+
+ if (is_64bit)
+ baton->addr_size = 8;
+ else
+ baton->addr_size = 4;
+
+ baton->cputype = mh.cputype;
+
+ uint8_t *start_of_load_commands = offset;
+
+ uint32_t cur_cmd = 0;
+ while (cur_cmd < mh.ncmds &&
+ (offset - start_of_load_commands) < mh.sizeofcmds) {
+ struct load_command lc;
+ uint32_t *lc_cmd = (uint32_t *)offset;
+ uint32_t *lc_cmdsize = (uint32_t *)offset + 1;
+ uint8_t *start_of_this_load_cmd = offset;
+
+ if (*lc_cmd == LC_SEGMENT || *lc_cmd == LC_SEGMENT_64) {
+ char segment_name[17];
+ segment_name[0] = '\0';
+ uint32_t nsects = 0;
+ uint64_t segment_offset = 0;
+ uint64_t segment_vmaddr = 0;
+
+ if (*lc_cmd == LC_SEGMENT_64) {
+ struct segment_command_64 seg;
+ memcpy(&seg, offset, sizeof(struct segment_command_64));
+ memcpy(&segment_name, &seg.segname, 16);
+ segment_name[16] = '\0';
+ nsects = seg.nsects;
+ segment_offset = seg.fileoff;
+ segment_vmaddr = seg.vmaddr;
+ offset += sizeof(struct segment_command_64);
+ if ((seg.flags & SG_PROTECTED_VERSION_1) == SG_PROTECTED_VERSION_1) {
+ printf("Segment '%s' is encrypted.\n", segment_name);
+ }
+ }
+
+ if (*lc_cmd == LC_SEGMENT) {
+ struct segment_command seg;
+ memcpy(&seg, offset, sizeof(struct segment_command));
+ memcpy(&segment_name, &seg.segname, 16);
+ segment_name[16] = '\0';
+ nsects = seg.nsects;
+ segment_offset = seg.fileoff;
+ segment_vmaddr = seg.vmaddr;
+ offset += sizeof(struct segment_command);
+ if ((seg.flags & SG_PROTECTED_VERSION_1) == SG_PROTECTED_VERSION_1) {
+ printf("Segment '%s' is encrypted.\n", segment_name);
+ }
+ }
+
+ if (nsects != 0 && strcmp(segment_name, "__TEXT") == 0) {
+ baton->text_segment_vmaddr = segment_vmaddr;
+ baton->text_segment_file_offset = segment_offset;
+
+ uint32_t current_sect = 0;
+ while (current_sect < nsects &&
+ (offset - start_of_this_load_cmd) < *lc_cmdsize) {
+ char sect_name[17];
+ memcpy(&sect_name, offset, 16);
+ sect_name[16] = '\0';
+ if (strcmp(sect_name, "__unwind_info") == 0) {
+ if (is_64bit) {
+ struct section_64 sect;
+ memset(&sect, 0, sizeof(struct section_64));
+ memcpy(&sect, offset, sizeof(struct section_64));
+ baton->compact_unwind_start =
+ baton->mach_header_start + sect.offset;
+ } else {
+ struct section sect;
+ memset(&sect, 0, sizeof(struct section));
+ memcpy(&sect, offset, sizeof(struct section));
+ baton->compact_unwind_start =
+ baton->mach_header_start + sect.offset;
}
-
- if (*lc_cmd == LC_SEGMENT)
- {
- struct segment_command seg;
- memcpy (&seg, offset, sizeof (struct segment_command));
- memcpy (&segment_name, &seg.segname, 16);
- segment_name[16] = '\0';
- nsects = seg.nsects;
- segment_offset = seg.fileoff;
- segment_vmaddr = seg.vmaddr;
- offset += sizeof (struct segment_command);
- if ((seg.flags & SG_PROTECTED_VERSION_1) == SG_PROTECTED_VERSION_1)
- {
- printf ("Segment '%s' is encrypted.\n", segment_name);
- }
+ }
+ if (strcmp(sect_name, "__eh_frame") == 0) {
+ if (is_64bit) {
+ struct section_64 sect;
+ memset(&sect, 0, sizeof(struct section_64));
+ memcpy(&sect, offset, sizeof(struct section_64));
+ baton->eh_section_file_address = sect.addr;
+ } else {
+ struct section sect;
+ memset(&sect, 0, sizeof(struct section));
+ memcpy(&sect, offset, sizeof(struct section));
+ baton->eh_section_file_address = sect.addr;
}
-
- if (nsects != 0 && strcmp (segment_name, "__TEXT") == 0)
- {
- baton->text_segment_vmaddr = segment_vmaddr;
- baton->text_segment_file_offset = segment_offset;
-
- uint32_t current_sect = 0;
- while (current_sect < nsects && (offset - start_of_this_load_cmd) < *lc_cmdsize)
- {
- char sect_name[17];
- memcpy (&sect_name, offset, 16);
- sect_name[16] = '\0';
- if (strcmp (sect_name, "__unwind_info") == 0)
- {
- if (is_64bit)
- {
- struct section_64 sect;
- memset (&sect, 0, sizeof (struct section_64));
- memcpy (&sect, offset, sizeof (struct section_64));
- baton->compact_unwind_start = baton->mach_header_start + sect.offset;
- }
- else
- {
- struct section sect;
- memset (&sect, 0, sizeof (struct section));
- memcpy (&sect, offset, sizeof (struct section));
- baton->compact_unwind_start = baton->mach_header_start + sect.offset;
- }
- }
- if (strcmp (sect_name, "__eh_frame") == 0)
- {
- if (is_64bit)
- {
- struct section_64 sect;
- memset (&sect, 0, sizeof (struct section_64));
- memcpy (&sect, offset, sizeof (struct section_64));
- baton->eh_section_file_address = sect.addr;
- }
- else
- {
- struct section sect;
- memset (&sect, 0, sizeof (struct section));
- memcpy (&sect, offset, sizeof (struct section));
- baton->eh_section_file_address = sect.addr;
- }
- }
- if (strcmp (sect_name, "__text") == 0)
- {
- if (is_64bit)
- {
- struct section_64 sect;
- memset (&sect, 0, sizeof (struct section_64));
- memcpy (&sect, offset, sizeof (struct section_64));
- baton->text_section_vmaddr = sect.addr;
- baton->text_section_file_offset = sect.offset;
- }
- else
- {
- struct section sect;
- memset (&sect, 0, sizeof (struct section));
- memcpy (&sect, offset, sizeof (struct section));
- baton->text_section_vmaddr = sect.addr;
- }
- }
- if (is_64bit)
- {
- offset += sizeof (struct section_64);
- }
- else
- {
- offset += sizeof (struct section);
- }
- }
+ }
+ if (strcmp(sect_name, "__text") == 0) {
+ if (is_64bit) {
+ struct section_64 sect;
+ memset(&sect, 0, sizeof(struct section_64));
+ memcpy(&sect, offset, sizeof(struct section_64));
+ baton->text_section_vmaddr = sect.addr;
+ baton->text_section_file_offset = sect.offset;
+ } else {
+ struct section sect;
+ memset(&sect, 0, sizeof(struct section));
+ memcpy(&sect, offset, sizeof(struct section));
+ baton->text_section_vmaddr = sect.addr;
}
-
- if (strcmp (segment_name, "__LINKEDIT") == 0)
- {
- linkedit_segment_vmaddr = segment_vmaddr;
- linkedit_segment_file_offset = segment_offset;
- }
- }
-
- if (*lc_cmd == LC_SYMTAB)
- {
- memcpy (&symtab_cmd, offset, sizeof (struct symtab_command));
+ }
+ if (is_64bit) {
+ offset += sizeof(struct section_64);
+ } else {
+ offset += sizeof(struct section);
+ }
}
+ }
- if (*lc_cmd == LC_DYSYMTAB)
- {
- struct dysymtab_command dysymtab_cmd;
- memcpy (&dysymtab_cmd, offset, sizeof (struct dysymtab_command));
-
- int nlist_size = 12;
- if (is_64bit)
- nlist_size = 16;
-
- char *string_table = (char *) (baton->mach_header_start + symtab_cmd.stroff);
- uint8_t *local_syms = baton->mach_header_start + symtab_cmd.symoff + (dysymtab_cmd.ilocalsym * nlist_size);
- int local_syms_count = dysymtab_cmd.nlocalsym;
- uint8_t *exported_syms = baton->mach_header_start + symtab_cmd.symoff + (dysymtab_cmd.iextdefsym * nlist_size);
- int exported_syms_count = dysymtab_cmd.nextdefsym;
-
- // We're only going to create records for a small number of these symbols but to
- // simplify the memory management I'll allocate enough space to store all of them.
- baton->symbols = (struct symbol *) malloc (sizeof (struct symbol) * (local_syms_count + exported_syms_count));
- baton->symbols_count = 0;
-
- for (int i = 0; i < local_syms_count; i++)
- {
- struct nlist_64 nlist;
- memset (&nlist, 0, sizeof (struct nlist_64));
- if (is_64bit)
- {
- memcpy (&nlist, local_syms + (i * nlist_size), sizeof (struct nlist_64));
- }
- else
- {
- struct nlist nlist_32;
- memset (&nlist_32, 0, sizeof (struct nlist));
- memcpy (&nlist_32, local_syms + (i * nlist_size), sizeof (struct nlist));
- nlist.n_un.n_strx = nlist_32.n_un.n_strx;
- nlist.n_type = nlist_32.n_type;
- nlist.n_sect = nlist_32.n_sect;
- nlist.n_desc = nlist_32.n_desc;
- nlist.n_value = nlist_32.n_value;
- }
- if ((nlist.n_type & N_STAB) == 0
- && ((nlist.n_type & N_EXT) == 1 ||
- ((nlist.n_type & N_TYPE) == N_TYPE && nlist.n_sect != NO_SECT))
- && nlist.n_value != 0
- && nlist.n_value != baton->text_segment_vmaddr)
- {
- baton->symbols[baton->symbols_count].file_address = nlist.n_value;
- if (baton->cputype == CPU_TYPE_ARM)
- baton->symbols[baton->symbols_count].file_address = baton->symbols[baton->symbols_count].file_address & ~1;
- baton->symbols[baton->symbols_count].name = string_table + nlist.n_un.n_strx;
- baton->symbols_count++;
- }
- }
+ if (strcmp(segment_name, "__LINKEDIT") == 0) {
+ linkedit_segment_vmaddr = segment_vmaddr;
+ linkedit_segment_file_offset = segment_offset;
+ }
+ }
- for (int i = 0; i < exported_syms_count; i++)
- {
- struct nlist_64 nlist;
- memset (&nlist, 0, sizeof (struct nlist_64));
- if (is_64bit)
- {
- memcpy (&nlist, exported_syms + (i * nlist_size), sizeof (struct nlist_64));
- }
- else
- {
- struct nlist nlist_32;
- memcpy (&nlist_32, exported_syms + (i * nlist_size), sizeof (struct nlist));
- nlist.n_un.n_strx = nlist_32.n_un.n_strx;
- nlist.n_type = nlist_32.n_type;
- nlist.n_sect = nlist_32.n_sect;
- nlist.n_desc = nlist_32.n_desc;
- nlist.n_value = nlist_32.n_value;
- }
- if ((nlist.n_type & N_STAB) == 0
- && ((nlist.n_type & N_EXT) == 1 ||
- ((nlist.n_type & N_TYPE) == N_TYPE && nlist.n_sect != NO_SECT))
- && nlist.n_value != 0
- && nlist.n_value != baton->text_segment_vmaddr)
- {
- baton->symbols[baton->symbols_count].file_address = nlist.n_value;
- if (baton->cputype == CPU_TYPE_ARM)
- baton->symbols[baton->symbols_count].file_address = baton->symbols[baton->symbols_count].file_address & ~1;
- baton->symbols[baton->symbols_count].name = string_table + nlist.n_un.n_strx;
- baton->symbols_count++;
- }
- }
+ if (*lc_cmd == LC_SYMTAB) {
+ memcpy(&symtab_cmd, offset, sizeof(struct symtab_command));
+ }
- qsort (baton->symbols, baton->symbols_count, sizeof (struct symbol), symbol_compare);
+ if (*lc_cmd == LC_DYSYMTAB) {
+ struct dysymtab_command dysymtab_cmd;
+ memcpy(&dysymtab_cmd, offset, sizeof(struct dysymtab_command));
+
+ int nlist_size = 12;
+ if (is_64bit)
+ nlist_size = 16;
+
+ char *string_table =
+ (char *)(baton->mach_header_start + symtab_cmd.stroff);
+ uint8_t *local_syms = baton->mach_header_start + symtab_cmd.symoff +
+ (dysymtab_cmd.ilocalsym * nlist_size);
+ int local_syms_count = dysymtab_cmd.nlocalsym;
+ uint8_t *exported_syms = baton->mach_header_start + symtab_cmd.symoff +
+ (dysymtab_cmd.iextdefsym * nlist_size);
+ int exported_syms_count = dysymtab_cmd.nextdefsym;
+
+ // We're only going to create records for a small number of these symbols
+ // but to
+ // simplify the memory management I'll allocate enough space to store all
+ // of them.
+ baton->symbols = (struct symbol *)malloc(
+ sizeof(struct symbol) * (local_syms_count + exported_syms_count));
+ baton->symbols_count = 0;
+
+ for (int i = 0; i < local_syms_count; i++) {
+ struct nlist_64 nlist;
+ memset(&nlist, 0, sizeof(struct nlist_64));
+ if (is_64bit) {
+ memcpy(&nlist, local_syms + (i * nlist_size),
+ sizeof(struct nlist_64));
+ } else {
+ struct nlist nlist_32;
+ memset(&nlist_32, 0, sizeof(struct nlist));
+ memcpy(&nlist_32, local_syms + (i * nlist_size),
+ sizeof(struct nlist));
+ nlist.n_un.n_strx = nlist_32.n_un.n_strx;
+ nlist.n_type = nlist_32.n_type;
+ nlist.n_sect = nlist_32.n_sect;
+ nlist.n_desc = nlist_32.n_desc;
+ nlist.n_value = nlist_32.n_value;
}
-
- if (*lc_cmd == LC_FUNCTION_STARTS)
- {
- struct linkedit_data_command function_starts_cmd;
- memcpy (&function_starts_cmd, offset, sizeof (struct linkedit_data_command));
-
- uint8_t *funcstarts_offset = baton->mach_header_start + function_starts_cmd.dataoff;
- uint8_t *function_end = funcstarts_offset + function_starts_cmd.datasize;
- int count = 0;
-
- while (funcstarts_offset < function_end)
- {
- if (read_leb128 (&funcstarts_offset) != 0)
- {
- count++;
- }
- }
-
- baton->function_start_addresses = (uint64_t *) malloc (sizeof (uint64_t) * count);
- baton->function_start_addresses_count = count;
-
- funcstarts_offset = baton->mach_header_start + function_starts_cmd.dataoff;
- uint64_t current_pc = baton->text_segment_vmaddr;
- int i = 0;
- while (funcstarts_offset < function_end)
- {
- uint64_t func_start = read_leb128 (&funcstarts_offset);
- if (func_start != 0)
- {
- current_pc += func_start;
- baton->function_start_addresses[i++] = current_pc;
- }
- }
+ if ((nlist.n_type & N_STAB) == 0 &&
+ ((nlist.n_type & N_EXT) == 1 ||
+ ((nlist.n_type & N_TYPE) == N_TYPE && nlist.n_sect != NO_SECT)) &&
+ nlist.n_value != 0 && nlist.n_value != baton->text_segment_vmaddr) {
+ baton->symbols[baton->symbols_count].file_address = nlist.n_value;
+ if (baton->cputype == CPU_TYPE_ARM)
+ baton->symbols[baton->symbols_count].file_address =
+ baton->symbols[baton->symbols_count].file_address & ~1;
+ baton->symbols[baton->symbols_count].name =
+ string_table + nlist.n_un.n_strx;
+ baton->symbols_count++;
+ }
+ }
+
+ for (int i = 0; i < exported_syms_count; i++) {
+ struct nlist_64 nlist;
+ memset(&nlist, 0, sizeof(struct nlist_64));
+ if (is_64bit) {
+ memcpy(&nlist, exported_syms + (i * nlist_size),
+ sizeof(struct nlist_64));
+ } else {
+ struct nlist nlist_32;
+ memcpy(&nlist_32, exported_syms + (i * nlist_size),
+ sizeof(struct nlist));
+ nlist.n_un.n_strx = nlist_32.n_un.n_strx;
+ nlist.n_type = nlist_32.n_type;
+ nlist.n_sect = nlist_32.n_sect;
+ nlist.n_desc = nlist_32.n_desc;
+ nlist.n_value = nlist_32.n_value;
+ }
+ if ((nlist.n_type & N_STAB) == 0 &&
+ ((nlist.n_type & N_EXT) == 1 ||
+ ((nlist.n_type & N_TYPE) == N_TYPE && nlist.n_sect != NO_SECT)) &&
+ nlist.n_value != 0 && nlist.n_value != baton->text_segment_vmaddr) {
+ baton->symbols[baton->symbols_count].file_address = nlist.n_value;
+ if (baton->cputype == CPU_TYPE_ARM)
+ baton->symbols[baton->symbols_count].file_address =
+ baton->symbols[baton->symbols_count].file_address & ~1;
+ baton->symbols[baton->symbols_count].name =
+ string_table + nlist.n_un.n_strx;
+ baton->symbols_count++;
}
+ }
- offset = start_of_this_load_cmd + *lc_cmdsize;
- cur_cmd++;
+ qsort(baton->symbols, baton->symbols_count, sizeof(struct symbol),
+ symbol_compare);
}
+ if (*lc_cmd == LC_FUNCTION_STARTS) {
+ struct linkedit_data_command function_starts_cmd;
+ memcpy(&function_starts_cmd, offset,
+ sizeof(struct linkedit_data_command));
- // Augment the symbol table with the function starts table -- adding symbol entries
- // for functions that were stripped.
+ uint8_t *funcstarts_offset =
+ baton->mach_header_start + function_starts_cmd.dataoff;
+ uint8_t *function_end = funcstarts_offset + function_starts_cmd.datasize;
+ int count = 0;
- int unnamed_functions_to_add = 0;
- for (int i = 0; i < baton->function_start_addresses_count; i++)
- {
- struct symbol search_key;
- search_key.file_address = baton->function_start_addresses[i];
- if (baton->cputype == CPU_TYPE_ARM)
- search_key.file_address = search_key.file_address & ~1;
- struct symbol *sym = bsearch (&search_key, baton->symbols, baton->symbols_count, sizeof (struct symbol), symbol_compare);
- if (sym == NULL)
- unnamed_functions_to_add++;
- }
-
- baton->symbols = (struct symbol *) realloc (baton->symbols, sizeof (struct symbol) * (baton->symbols_count + unnamed_functions_to_add));
-
- int current_unnamed_symbol = 1;
- int number_symbols_added = 0;
- for (int i = 0; i < baton->function_start_addresses_count; i++)
- {
- struct symbol search_key;
- search_key.file_address = baton->function_start_addresses[i];
- if (baton->cputype == CPU_TYPE_ARM)
- search_key.file_address = search_key.file_address & ~1;
- struct symbol *sym = bsearch (&search_key, baton->symbols, baton->symbols_count, sizeof (struct symbol), symbol_compare);
- if (sym == NULL)
- {
- char *name;
- asprintf (&name, "unnamed function #%d", current_unnamed_symbol++);
- baton->symbols[baton->symbols_count + number_symbols_added].file_address = baton->function_start_addresses[i];
- baton->symbols[baton->symbols_count + number_symbols_added].name = name;
- number_symbols_added++;
+ while (funcstarts_offset < function_end) {
+ if (read_leb128(&funcstarts_offset) != 0) {
+ count++;
+ }
+ }
+
+ baton->function_start_addresses =
+ (uint64_t *)malloc(sizeof(uint64_t) * count);
+ baton->function_start_addresses_count = count;
+
+ funcstarts_offset =
+ baton->mach_header_start + function_starts_cmd.dataoff;
+ uint64_t current_pc = baton->text_segment_vmaddr;
+ int i = 0;
+ while (funcstarts_offset < function_end) {
+ uint64_t func_start = read_leb128(&funcstarts_offset);
+ if (func_start != 0) {
+ current_pc += func_start;
+ baton->function_start_addresses[i++] = current_pc;
}
+ }
}
- baton->symbols_count += number_symbols_added;
- qsort (baton->symbols, baton->symbols_count, sizeof (struct symbol), symbol_compare);
+ offset = start_of_this_load_cmd + *lc_cmdsize;
+ cur_cmd++;
+ }
+
+ // Augment the symbol table with the function starts table -- adding symbol
+ // entries
+ // for functions that were stripped.
+
+ int unnamed_functions_to_add = 0;
+ for (int i = 0; i < baton->function_start_addresses_count; i++) {
+ struct symbol search_key;
+ search_key.file_address = baton->function_start_addresses[i];
+ if (baton->cputype == CPU_TYPE_ARM)
+ search_key.file_address = search_key.file_address & ~1;
+ struct symbol *sym =
+ bsearch(&search_key, baton->symbols, baton->symbols_count,
+ sizeof(struct symbol), symbol_compare);
+ if (sym == NULL)
+ unnamed_functions_to_add++;
+ }
+
+ baton->symbols = (struct symbol *)realloc(
+ baton->symbols, sizeof(struct symbol) *
+ (baton->symbols_count + unnamed_functions_to_add));
+
+ int current_unnamed_symbol = 1;
+ int number_symbols_added = 0;
+ for (int i = 0; i < baton->function_start_addresses_count; i++) {
+ struct symbol search_key;
+ search_key.file_address = baton->function_start_addresses[i];
+ if (baton->cputype == CPU_TYPE_ARM)
+ search_key.file_address = search_key.file_address & ~1;
+ struct symbol *sym =
+ bsearch(&search_key, baton->symbols, baton->symbols_count,
+ sizeof(struct symbol), symbol_compare);
+ if (sym == NULL) {
+ char *name;
+ asprintf(&name, "unnamed function #%d", current_unnamed_symbol++);
+ baton->symbols[baton->symbols_count + number_symbols_added].file_address =
+ baton->function_start_addresses[i];
+ baton->symbols[baton->symbols_count + number_symbols_added].name = name;
+ number_symbols_added++;
+ }
+ }
+ baton->symbols_count += number_symbols_added;
+ qsort(baton->symbols, baton->symbols_count, sizeof(struct symbol),
+ symbol_compare);
+
+ // printf ("function start addresses\n");
+ // for (int i = 0; i < baton->function_start_addresses_count; i++)
+ // {
+ // printf ("0x%012llx\n", baton->function_start_addresses[i]);
+ // }
+
+ // printf ("symbol table names & addresses\n");
+ // for (int i = 0; i < baton->symbols_count; i++)
+ // {
+ // printf ("0x%012llx %s\n", baton->symbols[i].file_address,
+ // baton->symbols[i].name);
+ // }
+}
-// printf ("function start addresses\n");
-// for (int i = 0; i < baton->function_start_addresses_count; i++)
-// {
-// printf ("0x%012llx\n", baton->function_start_addresses[i]);
-// }
+void print_encoding_x86_64(struct baton baton, uint8_t *function_start,
+ uint32_t encoding) {
+ int mode = encoding & UNWIND_X86_64_MODE_MASK;
+ switch (mode) {
+ case UNWIND_X86_64_MODE_RBP_FRAME: {
+ printf("frame func: CFA is rbp+%d ", 16);
+ printf(" rip=[CFA-8] rbp=[CFA-16]");
+ uint32_t saved_registers_offset =
+ EXTRACT_BITS(encoding, UNWIND_X86_64_RBP_FRAME_OFFSET);
-// printf ("symbol table names & addresses\n");
-// for (int i = 0; i < baton->symbols_count; i++)
-// {
-// printf ("0x%012llx %s\n", baton->symbols[i].file_address, baton->symbols[i].name);
-// }
+ uint32_t saved_registers_locations =
+ EXTRACT_BITS(encoding, UNWIND_X86_64_RBP_FRAME_REGISTERS);
-}
+ saved_registers_offset += 2;
-void
-print_encoding_x86_64 (struct baton baton, uint8_t *function_start, uint32_t encoding)
-{
- int mode = encoding & UNWIND_X86_64_MODE_MASK;
- switch (mode)
- {
- case UNWIND_X86_64_MODE_RBP_FRAME:
- {
- printf ("frame func: CFA is rbp+%d ", 16);
- printf (" rip=[CFA-8] rbp=[CFA-16]");
- uint32_t saved_registers_offset = EXTRACT_BITS (encoding, UNWIND_X86_64_RBP_FRAME_OFFSET);
-
- uint32_t saved_registers_locations = EXTRACT_BITS (encoding, UNWIND_X86_64_RBP_FRAME_REGISTERS);
-
-
- saved_registers_offset += 2;
-
- for (int i = 0; i < 5; i++)
- {
- switch (saved_registers_locations & 0x7)
- {
- case UNWIND_X86_64_REG_NONE:
- break;
- case UNWIND_X86_64_REG_RBX:
- printf (" rbx=[CFA-%d]", saved_registers_offset * 8);
- break;
- case UNWIND_X86_64_REG_R12:
- printf (" r12=[CFA-%d]", saved_registers_offset * 8);
- break;
- case UNWIND_X86_64_REG_R13:
- printf (" r13=[CFA-%d]", saved_registers_offset * 8);
- break;
- case UNWIND_X86_64_REG_R14:
- printf (" r14=[CFA-%d]", saved_registers_offset * 8);
- break;
- case UNWIND_X86_64_REG_R15:
- printf (" r15=[CFA-%d]", saved_registers_offset * 8);
- break;
- }
- saved_registers_offset--;
- saved_registers_locations >>= 3;
- }
- }
+ for (int i = 0; i < 5; i++) {
+ switch (saved_registers_locations & 0x7) {
+ case UNWIND_X86_64_REG_NONE:
break;
+ case UNWIND_X86_64_REG_RBX:
+ printf(" rbx=[CFA-%d]", saved_registers_offset * 8);
+ break;
+ case UNWIND_X86_64_REG_R12:
+ printf(" r12=[CFA-%d]", saved_registers_offset * 8);
+ break;
+ case UNWIND_X86_64_REG_R13:
+ printf(" r13=[CFA-%d]", saved_registers_offset * 8);
+ break;
+ case UNWIND_X86_64_REG_R14:
+ printf(" r14=[CFA-%d]", saved_registers_offset * 8);
+ break;
+ case UNWIND_X86_64_REG_R15:
+ printf(" r15=[CFA-%d]", saved_registers_offset * 8);
+ break;
+ }
+ saved_registers_offset--;
+ saved_registers_locations >>= 3;
+ }
+ } break;
- case UNWIND_X86_64_MODE_STACK_IND:
- case UNWIND_X86_64_MODE_STACK_IMMD:
- {
- uint32_t stack_size = EXTRACT_BITS (encoding, UNWIND_X86_64_FRAMELESS_STACK_SIZE);
- uint32_t register_count = EXTRACT_BITS (encoding, UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT);
- uint32_t permutation = EXTRACT_BITS (encoding, UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION);
-
- if (mode == UNWIND_X86_64_MODE_STACK_IND && function_start)
- {
- uint32_t stack_adjust = EXTRACT_BITS (encoding, UNWIND_X86_64_FRAMELESS_STACK_ADJUST);
+ case UNWIND_X86_64_MODE_STACK_IND:
+ case UNWIND_X86_64_MODE_STACK_IMMD: {
+ uint32_t stack_size =
+ EXTRACT_BITS(encoding, UNWIND_X86_64_FRAMELESS_STACK_SIZE);
+ uint32_t register_count =
+ EXTRACT_BITS(encoding, UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT);
+ uint32_t permutation =
+ EXTRACT_BITS(encoding, UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION);
- // offset into the function instructions; 0 == beginning of first instruction
- uint32_t offset_to_subl_insn = EXTRACT_BITS (encoding, UNWIND_X86_64_FRAMELESS_STACK_SIZE);
+ if (mode == UNWIND_X86_64_MODE_STACK_IND && function_start) {
+ uint32_t stack_adjust =
+ EXTRACT_BITS(encoding, UNWIND_X86_64_FRAMELESS_STACK_ADJUST);
- stack_size = *((uint32_t*) (function_start + offset_to_subl_insn));
+ // offset into the function instructions; 0 == beginning of first
+ // instruction
+ uint32_t offset_to_subl_insn =
+ EXTRACT_BITS(encoding, UNWIND_X86_64_FRAMELESS_STACK_SIZE);
- stack_size += stack_adjust * 8;
+ stack_size = *((uint32_t *)(function_start + offset_to_subl_insn));
- printf ("large stack ");
- }
-
- if (mode == UNWIND_X86_64_MODE_STACK_IND)
- {
- printf ("frameless function: stack size %d, register count %d ", stack_size * 8, register_count);
- }
- else
- {
- printf ("frameless function: stack size %d, register count %d ", stack_size, register_count);
- }
+ stack_size += stack_adjust * 8;
- if (register_count == 0)
- {
- printf (" no registers saved");
- }
- else
- {
-
- // We need to include (up to) 6 registers in 10 bits.
- // That would be 18 bits if we just used 3 bits per reg to indicate
- // the order they're saved on the stack.
- //
- // This is done with Lehmer code permutation, e.g. see
- // http://stackoverflow.com/questions/1506078/fast-permutation-number-permutation-mapping-algorithms
- int permunreg[6];
-
- // This decodes the variable-base number in the 10 bits
- // and gives us the Lehmer code sequence which can then
- // be decoded.
-
- switch (register_count)
- {
- case 6:
- permunreg[0] = permutation/120; // 120 == 5!
- permutation -= (permunreg[0]*120);
- permunreg[1] = permutation/24; // 24 == 4!
- permutation -= (permunreg[1]*24);
- permunreg[2] = permutation/6; // 6 == 3!
- permutation -= (permunreg[2]*6);
- permunreg[3] = permutation/2; // 2 == 2!
- permutation -= (permunreg[3]*2);
- permunreg[4] = permutation; // 1 == 1!
- permunreg[5] = 0;
- break;
- case 5:
- permunreg[0] = permutation/120;
- permutation -= (permunreg[0]*120);
- permunreg[1] = permutation/24;
- permutation -= (permunreg[1]*24);
- permunreg[2] = permutation/6;
- permutation -= (permunreg[2]*6);
- permunreg[3] = permutation/2;
- permutation -= (permunreg[3]*2);
- permunreg[4] = permutation;
- break;
- case 4:
- permunreg[0] = permutation/60;
- permutation -= (permunreg[0]*60);
- permunreg[1] = permutation/12;
- permutation -= (permunreg[1]*12);
- permunreg[2] = permutation/3;
- permutation -= (permunreg[2]*3);
- permunreg[3] = permutation;
- break;
- case 3:
- permunreg[0] = permutation/20;
- permutation -= (permunreg[0]*20);
- permunreg[1] = permutation/4;
- permutation -= (permunreg[1]*4);
- permunreg[2] = permutation;
- break;
- case 2:
- permunreg[0] = permutation/5;
- permutation -= (permunreg[0]*5);
- permunreg[1] = permutation;
- break;
- case 1:
- permunreg[0] = permutation;
- break;
- }
-
- // Decode the Lehmer code for this permutation of
- // the registers v. http://en.wikipedia.org/wiki/Lehmer_code
-
- int registers[6];
- bool used[7] = { false, false, false, false, false, false, false };
- for (int i = 0; i < register_count; i++)
- {
- int renum = 0;
- for (int j = 1; j < 7; j++)
- {
- if (used[j] == false)
- {
- if (renum == permunreg[i])
- {
- registers[i] = j;
- used[j] = true;
- break;
- }
- renum++;
- }
- }
- }
-
-
- if (mode == UNWIND_X86_64_MODE_STACK_IND)
- {
- printf (" CFA is rsp+%d ", stack_size);
- }
- else
- {
- printf (" CFA is rsp+%d ", stack_size * 8);
- }
-
- uint32_t saved_registers_offset = 1;
- printf (" rip=[CFA-%d]", saved_registers_offset * 8);
- saved_registers_offset++;
-
- for (int i = (sizeof (registers) / sizeof (int)) - 1; i >= 0; i--)
- {
- switch (registers[i])
- {
- case UNWIND_X86_64_REG_NONE:
- break;
- case UNWIND_X86_64_REG_RBX:
- printf (" rbx=[CFA-%d]", saved_registers_offset * 8);
- saved_registers_offset++;
- break;
- case UNWIND_X86_64_REG_R12:
- printf (" r12=[CFA-%d]", saved_registers_offset * 8);
- saved_registers_offset++;
- break;
- case UNWIND_X86_64_REG_R13:
- printf (" r13=[CFA-%d]", saved_registers_offset * 8);
- saved_registers_offset++;
- break;
- case UNWIND_X86_64_REG_R14:
- printf (" r14=[CFA-%d]", saved_registers_offset * 8);
- saved_registers_offset++;
- break;
- case UNWIND_X86_64_REG_R15:
- printf (" r15=[CFA-%d]", saved_registers_offset * 8);
- saved_registers_offset++;
- break;
- case UNWIND_X86_64_REG_RBP:
- printf (" rbp=[CFA-%d]", saved_registers_offset * 8);
- saved_registers_offset++;
- break;
- }
- }
+ printf("large stack ");
+ }
- }
+ if (mode == UNWIND_X86_64_MODE_STACK_IND) {
+ printf("frameless function: stack size %d, register count %d ",
+ stack_size * 8, register_count);
+ } else {
+ printf("frameless function: stack size %d, register count %d ",
+ stack_size, register_count);
+ }
- }
+ if (register_count == 0) {
+ printf(" no registers saved");
+ } else {
+
+ // We need to include (up to) 6 registers in 10 bits.
+ // That would be 18 bits if we just used 3 bits per reg to indicate
+ // the order they're saved on the stack.
+ //
+ // This is done with Lehmer code permutation, e.g. see
+ // http://stackoverflow.com/questions/1506078/fast-permutation-number-permutation-mapping-algorithms
+ int permunreg[6];
+
+ // This decodes the variable-base number in the 10 bits
+ // and gives us the Lehmer code sequence which can then
+ // be decoded.
+
+ switch (register_count) {
+ case 6:
+ permunreg[0] = permutation / 120; // 120 == 5!
+ permutation -= (permunreg[0] * 120);
+ permunreg[1] = permutation / 24; // 24 == 4!
+ permutation -= (permunreg[1] * 24);
+ permunreg[2] = permutation / 6; // 6 == 3!
+ permutation -= (permunreg[2] * 6);
+ permunreg[3] = permutation / 2; // 2 == 2!
+ permutation -= (permunreg[3] * 2);
+ permunreg[4] = permutation; // 1 == 1!
+ permunreg[5] = 0;
break;
-
- case UNWIND_X86_64_MODE_DWARF:
- {
- uint32_t dwarf_offset = encoding & UNWIND_X86_DWARF_SECTION_OFFSET;
- printf ("DWARF unwind instructions: FDE at offset %d (file address 0x%" PRIx64 ")",
- dwarf_offset, dwarf_offset + baton.eh_section_file_address);
- }
+ case 5:
+ permunreg[0] = permutation / 120;
+ permutation -= (permunreg[0] * 120);
+ permunreg[1] = permutation / 24;
+ permutation -= (permunreg[1] * 24);
+ permunreg[2] = permutation / 6;
+ permutation -= (permunreg[2] * 6);
+ permunreg[3] = permutation / 2;
+ permutation -= (permunreg[3] * 2);
+ permunreg[4] = permutation;
break;
-
- case 0:
- {
- printf (" no unwind information");
- }
+ case 4:
+ permunreg[0] = permutation / 60;
+ permutation -= (permunreg[0] * 60);
+ permunreg[1] = permutation / 12;
+ permutation -= (permunreg[1] * 12);
+ permunreg[2] = permutation / 3;
+ permutation -= (permunreg[2] * 3);
+ permunreg[3] = permutation;
break;
- }
-}
-
-void
-print_encoding_i386 (struct baton baton, uint8_t *function_start, uint32_t encoding)
-{
- int mode = encoding & UNWIND_X86_MODE_MASK;
- switch (mode)
- {
- case UNWIND_X86_MODE_EBP_FRAME:
- {
- printf ("frame func: CFA is ebp+%d ", 8);
- printf (" eip=[CFA-4] ebp=[CFA-8]");
- uint32_t saved_registers_offset = EXTRACT_BITS (encoding, UNWIND_X86_EBP_FRAME_OFFSET);
-
- uint32_t saved_registers_locations = EXTRACT_BITS (encoding, UNWIND_X86_EBP_FRAME_REGISTERS);
-
-
- saved_registers_offset += 2;
-
- for (int i = 0; i < 5; i++)
- {
- switch (saved_registers_locations & 0x7)
- {
- case UNWIND_X86_REG_NONE:
- break;
- case UNWIND_X86_REG_EBX:
- printf (" ebx=[CFA-%d]", saved_registers_offset * 4);
- break;
- case UNWIND_X86_REG_ECX:
- printf (" ecx=[CFA-%d]", saved_registers_offset * 4);
- break;
- case UNWIND_X86_REG_EDX:
- printf (" edx=[CFA-%d]", saved_registers_offset * 4);
- break;
- case UNWIND_X86_REG_EDI:
- printf (" edi=[CFA-%d]", saved_registers_offset * 4);
- break;
- case UNWIND_X86_REG_ESI:
- printf (" esi=[CFA-%d]", saved_registers_offset * 4);
- break;
- }
- saved_registers_offset--;
- saved_registers_locations >>= 3;
+ case 3:
+ permunreg[0] = permutation / 20;
+ permutation -= (permunreg[0] * 20);
+ permunreg[1] = permutation / 4;
+ permutation -= (permunreg[1] * 4);
+ permunreg[2] = permutation;
+ break;
+ case 2:
+ permunreg[0] = permutation / 5;
+ permutation -= (permunreg[0] * 5);
+ permunreg[1] = permutation;
+ break;
+ case 1:
+ permunreg[0] = permutation;
+ break;
+ }
+
+ // Decode the Lehmer code for this permutation of
+ // the registers v. http://en.wikipedia.org/wiki/Lehmer_code
+
+ int registers[6];
+ bool used[7] = {false, false, false, false, false, false, false};
+ for (int i = 0; i < register_count; i++) {
+ int renum = 0;
+ for (int j = 1; j < 7; j++) {
+ if (used[j] == false) {
+ if (renum == permunreg[i]) {
+ registers[i] = j;
+ used[j] = true;
+ break;
}
+ renum++;
+ }
}
- break;
+ }
+
+ if (mode == UNWIND_X86_64_MODE_STACK_IND) {
+ printf(" CFA is rsp+%d ", stack_size);
+ } else {
+ printf(" CFA is rsp+%d ", stack_size * 8);
+ }
+
+ uint32_t saved_registers_offset = 1;
+ printf(" rip=[CFA-%d]", saved_registers_offset * 8);
+ saved_registers_offset++;
+
+ for (int i = (sizeof(registers) / sizeof(int)) - 1; i >= 0; i--) {
+ switch (registers[i]) {
+ case UNWIND_X86_64_REG_NONE:
+ break;
+ case UNWIND_X86_64_REG_RBX:
+ printf(" rbx=[CFA-%d]", saved_registers_offset * 8);
+ saved_registers_offset++;
+ break;
+ case UNWIND_X86_64_REG_R12:
+ printf(" r12=[CFA-%d]", saved_registers_offset * 8);
+ saved_registers_offset++;
+ break;
+ case UNWIND_X86_64_REG_R13:
+ printf(" r13=[CFA-%d]", saved_registers_offset * 8);
+ saved_registers_offset++;
+ break;
+ case UNWIND_X86_64_REG_R14:
+ printf(" r14=[CFA-%d]", saved_registers_offset * 8);
+ saved_registers_offset++;
+ break;
+ case UNWIND_X86_64_REG_R15:
+ printf(" r15=[CFA-%d]", saved_registers_offset * 8);
+ saved_registers_offset++;
+ break;
+ case UNWIND_X86_64_REG_RBP:
+ printf(" rbp=[CFA-%d]", saved_registers_offset * 8);
+ saved_registers_offset++;
+ break;
+ }
+ }
+ }
- case UNWIND_X86_MODE_STACK_IND:
- case UNWIND_X86_MODE_STACK_IMMD:
- {
- uint32_t stack_size = EXTRACT_BITS (encoding, UNWIND_X86_FRAMELESS_STACK_SIZE);
- uint32_t register_count = EXTRACT_BITS (encoding, UNWIND_X86_FRAMELESS_STACK_REG_COUNT);
- uint32_t permutation = EXTRACT_BITS (encoding, UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION);
+ } break;
- if (mode == UNWIND_X86_MODE_STACK_IND && function_start)
- {
- uint32_t stack_adjust = EXTRACT_BITS (encoding, UNWIND_X86_FRAMELESS_STACK_ADJUST);
+ case UNWIND_X86_64_MODE_DWARF: {
+ uint32_t dwarf_offset = encoding & UNWIND_X86_DWARF_SECTION_OFFSET;
+ printf(
+ "DWARF unwind instructions: FDE at offset %d (file address 0x%" PRIx64
+ ")",
+ dwarf_offset, dwarf_offset + baton.eh_section_file_address);
+ } break;
- // offset into the function instructions; 0 == beginning of first instruction
- uint32_t offset_to_subl_insn = EXTRACT_BITS (encoding, UNWIND_X86_FRAMELESS_STACK_SIZE);
+ case 0: {
+ printf(" no unwind information");
+ } break;
+ }
+}
- stack_size = *((uint32_t*) (function_start + offset_to_subl_insn));
+void print_encoding_i386(struct baton baton, uint8_t *function_start,
+ uint32_t encoding) {
+ int mode = encoding & UNWIND_X86_MODE_MASK;
+ switch (mode) {
+ case UNWIND_X86_MODE_EBP_FRAME: {
+ printf("frame func: CFA is ebp+%d ", 8);
+ printf(" eip=[CFA-4] ebp=[CFA-8]");
+ uint32_t saved_registers_offset =
+ EXTRACT_BITS(encoding, UNWIND_X86_EBP_FRAME_OFFSET);
- stack_size += stack_adjust * 4;
+ uint32_t saved_registers_locations =
+ EXTRACT_BITS(encoding, UNWIND_X86_EBP_FRAME_REGISTERS);
- printf ("large stack ");
- }
-
- if (mode == UNWIND_X86_MODE_STACK_IND)
- {
- printf ("frameless function: stack size %d, register count %d ", stack_size, register_count);
- }
- else
- {
- printf ("frameless function: stack size %d, register count %d ", stack_size * 4, register_count);
- }
-
- if (register_count == 0)
- {
- printf (" no registers saved");
- }
- else
- {
-
- // We need to include (up to) 6 registers in 10 bits.
- // That would be 18 bits if we just used 3 bits per reg to indicate
- // the order they're saved on the stack.
- //
- // This is done with Lehmer code permutation, e.g. see
- // http://stackoverflow.com/questions/1506078/fast-permutation-number-permutation-mapping-algorithms
- int permunreg[6];
-
- // This decodes the variable-base number in the 10 bits
- // and gives us the Lehmer code sequence which can then
- // be decoded.
-
- switch (register_count)
- {
- case 6:
- permunreg[0] = permutation/120; // 120 == 5!
- permutation -= (permunreg[0]*120);
- permunreg[1] = permutation/24; // 24 == 4!
- permutation -= (permunreg[1]*24);
- permunreg[2] = permutation/6; // 6 == 3!
- permutation -= (permunreg[2]*6);
- permunreg[3] = permutation/2; // 2 == 2!
- permutation -= (permunreg[3]*2);
- permunreg[4] = permutation; // 1 == 1!
- permunreg[5] = 0;
- break;
- case 5:
- permunreg[0] = permutation/120;
- permutation -= (permunreg[0]*120);
- permunreg[1] = permutation/24;
- permutation -= (permunreg[1]*24);
- permunreg[2] = permutation/6;
- permutation -= (permunreg[2]*6);
- permunreg[3] = permutation/2;
- permutation -= (permunreg[3]*2);
- permunreg[4] = permutation;
- break;
- case 4:
- permunreg[0] = permutation/60;
- permutation -= (permunreg[0]*60);
- permunreg[1] = permutation/12;
- permutation -= (permunreg[1]*12);
- permunreg[2] = permutation/3;
- permutation -= (permunreg[2]*3);
- permunreg[3] = permutation;
- break;
- case 3:
- permunreg[0] = permutation/20;
- permutation -= (permunreg[0]*20);
- permunreg[1] = permutation/4;
- permutation -= (permunreg[1]*4);
- permunreg[2] = permutation;
- break;
- case 2:
- permunreg[0] = permutation/5;
- permutation -= (permunreg[0]*5);
- permunreg[1] = permutation;
- break;
- case 1:
- permunreg[0] = permutation;
- break;
- }
-
- // Decode the Lehmer code for this permutation of
- // the registers v. http://en.wikipedia.org/wiki/Lehmer_code
-
- int registers[6];
- bool used[7] = { false, false, false, false, false, false, false };
- for (int i = 0; i < register_count; i++)
- {
- int renum = 0;
- for (int j = 1; j < 7; j++)
- {
- if (used[j] == false)
- {
- if (renum == permunreg[i])
- {
- registers[i] = j;
- used[j] = true;
- break;
- }
- renum++;
- }
- }
- }
-
-
- if (mode == UNWIND_X86_MODE_STACK_IND)
- {
- printf (" CFA is esp+%d ", stack_size);
- }
- else
- {
- printf (" CFA is esp+%d ", stack_size * 4);
- }
-
- uint32_t saved_registers_offset = 1;
- printf (" eip=[CFA-%d]", saved_registers_offset * 4);
- saved_registers_offset++;
-
- for (int i = (sizeof (registers) / sizeof (int)) - 1; i >= 0; i--)
- {
- switch (registers[i])
- {
- case UNWIND_X86_REG_NONE:
- break;
- case UNWIND_X86_REG_EBX:
- printf (" ebx=[CFA-%d]", saved_registers_offset * 4);
- saved_registers_offset++;
- break;
- case UNWIND_X86_REG_ECX:
- printf (" ecx=[CFA-%d]", saved_registers_offset * 4);
- saved_registers_offset++;
- break;
- case UNWIND_X86_REG_EDX:
- printf (" edx=[CFA-%d]", saved_registers_offset * 4);
- saved_registers_offset++;
- break;
- case UNWIND_X86_REG_EDI:
- printf (" edi=[CFA-%d]", saved_registers_offset * 4);
- saved_registers_offset++;
- break;
- case UNWIND_X86_REG_ESI:
- printf (" esi=[CFA-%d]", saved_registers_offset * 4);
- saved_registers_offset++;
- break;
- case UNWIND_X86_REG_EBP:
- printf (" ebp=[CFA-%d]", saved_registers_offset * 4);
- saved_registers_offset++;
- break;
- }
- }
+ saved_registers_offset += 2;
- }
-
- }
+ for (int i = 0; i < 5; i++) {
+ switch (saved_registers_locations & 0x7) {
+ case UNWIND_X86_REG_NONE:
break;
-
- case UNWIND_X86_MODE_DWARF:
- {
- uint32_t dwarf_offset = encoding & UNWIND_X86_DWARF_SECTION_OFFSET;
- printf ("DWARF unwind instructions: FDE at offset %d (file address 0x%" PRIx64 ")",
- dwarf_offset, dwarf_offset + baton.eh_section_file_address);
- }
+ case UNWIND_X86_REG_EBX:
+ printf(" ebx=[CFA-%d]", saved_registers_offset * 4);
break;
-
- case 0:
- {
- printf (" no unwind information");
- }
+ case UNWIND_X86_REG_ECX:
+ printf(" ecx=[CFA-%d]", saved_registers_offset * 4);
+ break;
+ case UNWIND_X86_REG_EDX:
+ printf(" edx=[CFA-%d]", saved_registers_offset * 4);
+ break;
+ case UNWIND_X86_REG_EDI:
+ printf(" edi=[CFA-%d]", saved_registers_offset * 4);
+ break;
+ case UNWIND_X86_REG_ESI:
+ printf(" esi=[CFA-%d]", saved_registers_offset * 4);
break;
+ }
+ saved_registers_offset--;
+ saved_registers_locations >>= 3;
}
-}
+ } break;
-void
-print_encoding_arm64 (struct baton baton, uint8_t *function_start, uint32_t encoding)
-{
- const int wordsize = 8;
- int mode = encoding & UNWIND_ARM64_MODE_MASK;
- switch (mode)
- {
- case UNWIND_ARM64_MODE_FRAME:
- {
- printf ("frame func: CFA is fp+%d ", 16);
- printf (" pc=[CFA-8] fp=[CFA-16]");
- int reg_pairs_saved_count = 1;
- uint32_t saved_register_bits = encoding & 0xfff;
- if (saved_register_bits & UNWIND_ARM64_FRAME_X19_X20_PAIR)
- {
- int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
- cfa_offset -= wordsize;
- printf (" x19=[CFA%d]", cfa_offset);
- cfa_offset -= wordsize;
- printf (" x20=[CFA%d]", cfa_offset);
- reg_pairs_saved_count++;
- }
- if (saved_register_bits & UNWIND_ARM64_FRAME_X21_X22_PAIR)
- {
- int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
- cfa_offset -= wordsize;
- printf (" x21=[CFA%d]", cfa_offset);
- cfa_offset -= wordsize;
- printf (" x22=[CFA%d]", cfa_offset);
- reg_pairs_saved_count++;
- }
- if (saved_register_bits & UNWIND_ARM64_FRAME_X23_X24_PAIR)
- {
- int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
- cfa_offset -= wordsize;
- printf (" x23=[CFA%d]", cfa_offset);
- cfa_offset -= wordsize;
- printf (" x24=[CFA%d]", cfa_offset);
- reg_pairs_saved_count++;
- }
- if (saved_register_bits & UNWIND_ARM64_FRAME_X25_X26_PAIR)
- {
- int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
- cfa_offset -= wordsize;
- printf (" x25=[CFA%d]", cfa_offset);
- cfa_offset -= wordsize;
- printf (" x26=[CFA%d]", cfa_offset);
- reg_pairs_saved_count++;
- }
- if (saved_register_bits & UNWIND_ARM64_FRAME_X27_X28_PAIR)
- {
- int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
- cfa_offset -= wordsize;
- printf (" x27=[CFA%d]", cfa_offset);
- cfa_offset -= wordsize;
- printf (" x28=[CFA%d]", cfa_offset);
- reg_pairs_saved_count++;
- }
- if (saved_register_bits & UNWIND_ARM64_FRAME_D8_D9_PAIR)
- {
- int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
- cfa_offset -= wordsize;
- printf (" d8=[CFA%d]", cfa_offset);
- cfa_offset -= wordsize;
- printf (" d9=[CFA%d]", cfa_offset);
- reg_pairs_saved_count++;
- }
- if (saved_register_bits & UNWIND_ARM64_FRAME_D10_D11_PAIR)
- {
- int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
- cfa_offset -= wordsize;
- printf (" d10=[CFA%d]", cfa_offset);
- cfa_offset -= wordsize;
- printf (" d11=[CFA%d]", cfa_offset);
- reg_pairs_saved_count++;
- }
- if (saved_register_bits & UNWIND_ARM64_FRAME_D12_D13_PAIR)
- {
- int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
- cfa_offset -= wordsize;
- printf (" d12=[CFA%d]", cfa_offset);
- cfa_offset -= wordsize;
- printf (" d13=[CFA%d]", cfa_offset);
- reg_pairs_saved_count++;
- }
- if (saved_register_bits & UNWIND_ARM64_FRAME_D14_D15_PAIR)
- {
- int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
- cfa_offset -= wordsize;
- printf (" d14=[CFA%d]", cfa_offset);
- cfa_offset -= wordsize;
- printf (" d15=[CFA%d]", cfa_offset);
- reg_pairs_saved_count++;
- }
+ case UNWIND_X86_MODE_STACK_IND:
+ case UNWIND_X86_MODE_STACK_IMMD: {
+ uint32_t stack_size =
+ EXTRACT_BITS(encoding, UNWIND_X86_FRAMELESS_STACK_SIZE);
+ uint32_t register_count =
+ EXTRACT_BITS(encoding, UNWIND_X86_FRAMELESS_STACK_REG_COUNT);
+ uint32_t permutation =
+ EXTRACT_BITS(encoding, UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION);
- }
- break;
+ if (mode == UNWIND_X86_MODE_STACK_IND && function_start) {
+ uint32_t stack_adjust =
+ EXTRACT_BITS(encoding, UNWIND_X86_FRAMELESS_STACK_ADJUST);
- case UNWIND_ARM64_MODE_FRAMELESS:
- {
- uint32_t stack_size = encoding & UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK;
- printf ("frameless function: stack size %d ", stack_size * 16);
+ // offset into the function instructions; 0 == beginning of first
+ // instruction
+ uint32_t offset_to_subl_insn =
+ EXTRACT_BITS(encoding, UNWIND_X86_FRAMELESS_STACK_SIZE);
- }
- break;
+ stack_size = *((uint32_t *)(function_start + offset_to_subl_insn));
- case UNWIND_ARM64_MODE_DWARF:
- {
- uint32_t dwarf_offset = encoding & UNWIND_ARM64_DWARF_SECTION_OFFSET;
- printf ("DWARF unwind instructions: FDE at offset %d (file address 0x%" PRIx64 ")",
- dwarf_offset, dwarf_offset + baton.eh_section_file_address);
- }
- break;
+ stack_size += stack_adjust * 4;
- case 0:
- {
- printf (" no unwind information");
- }
- break;
+ printf("large stack ");
}
-}
-void
-print_encoding_armv7 (struct baton baton, uint8_t *function_start, uint32_t encoding)
-{
- const int wordsize = 4;
- int mode = encoding & UNWIND_ARM_MODE_MASK;
- switch (mode)
- {
- case UNWIND_ARM_MODE_FRAME_D:
- case UNWIND_ARM_MODE_FRAME:
- {
- int stack_adjust = EXTRACT_BITS (encoding, UNWIND_ARM_FRAME_STACK_ADJUST_MASK) * wordsize;
-
- printf ("frame func: CFA is fp+%d ", (2 * wordsize) + stack_adjust);
- int cfa_offset = -stack_adjust;
-
- cfa_offset -= wordsize;
- printf (" pc=[CFA%d]", cfa_offset);
- cfa_offset -= wordsize;
- printf (" fp=[CFA%d]", cfa_offset);
-
- uint32_t saved_register_bits = encoding & 0xff;
- if (saved_register_bits & UNWIND_ARM_FRAME_FIRST_PUSH_R6)
- {
- cfa_offset -= wordsize;
- printf (" r6=[CFA%d]", cfa_offset);
- }
- if (saved_register_bits & UNWIND_ARM_FRAME_FIRST_PUSH_R5)
- {
- cfa_offset -= wordsize;
- printf (" r5=[CFA%d]", cfa_offset);
- }
- if (saved_register_bits & UNWIND_ARM_FRAME_FIRST_PUSH_R4)
- {
- cfa_offset -= wordsize;
- printf (" r4=[CFA%d]", cfa_offset);
- }
- if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R12)
- {
- cfa_offset -= wordsize;
- printf (" r12=[CFA%d]", cfa_offset);
- }
- if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R11)
- {
- cfa_offset -= wordsize;
- printf (" r11=[CFA%d]", cfa_offset);
- }
- if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R10)
- {
- cfa_offset -= wordsize;
- printf (" r10=[CFA%d]", cfa_offset);
- }
- if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R9)
- {
- cfa_offset -= wordsize;
- printf (" r9=[CFA%d]", cfa_offset);
- }
- if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R8)
- {
- cfa_offset -= wordsize;
- printf (" r8=[CFA%d]", cfa_offset);
- }
+ if (mode == UNWIND_X86_MODE_STACK_IND) {
+ printf("frameless function: stack size %d, register count %d ",
+ stack_size, register_count);
+ } else {
+ printf("frameless function: stack size %d, register count %d ",
+ stack_size * 4, register_count);
+ }
- if (mode == UNWIND_ARM_MODE_FRAME_D)
- {
- uint32_t d_reg_bits = EXTRACT_BITS (encoding, UNWIND_ARM_FRAME_D_REG_COUNT_MASK);
- switch (d_reg_bits)
- {
- case 0:
- // vpush {d8}
- cfa_offset -= 8;
- printf (" d8=[CFA%d]", cfa_offset);
- break;
- case 1:
- // vpush {d10}
- // vpush {d8}
- cfa_offset -= 8;
- printf (" d10=[CFA%d]", cfa_offset);
- cfa_offset -= 8;
- printf (" d8=[CFA%d]", cfa_offset);
- break;
- case 2:
- // vpush {d12}
- // vpush {d10}
- // vpush {d8}
- cfa_offset -= 8;
- printf (" d12=[CFA%d]", cfa_offset);
- cfa_offset -= 8;
- printf (" d10=[CFA%d]", cfa_offset);
- cfa_offset -= 8;
- printf (" d8=[CFA%d]", cfa_offset);
- break;
- case 3:
- // vpush {d14}
- // vpush {d12}
- // vpush {d10}
- // vpush {d8}
- cfa_offset -= 8;
- printf (" d14=[CFA%d]", cfa_offset);
- cfa_offset -= 8;
- printf (" d12=[CFA%d]", cfa_offset);
- cfa_offset -= 8;
- printf (" d10=[CFA%d]", cfa_offset);
- cfa_offset -= 8;
- printf (" d8=[CFA%d]", cfa_offset);
- break;
- case 4:
- // vpush {d14}
- // vpush {d12}
- // sp = (sp - 24) & (-16);
- // vst {d8, d9, d10}
- printf (" d14, d12, d10, d9, d8");
- break;
- case 5:
- // vpush {d14}
- // sp = (sp - 40) & (-16);
- // vst {d8, d9, d10, d11}
- // vst {d12}
- printf (" d14, d11, d10, d9, d8, d12");
- break;
- case 6:
- // sp = (sp - 56) & (-16);
- // vst {d8, d9, d10, d11}
- // vst {d12, d13, d14}
- printf (" d11, d10, d9, d8, d14, d13, d12");
- break;
- case 7:
- // sp = (sp - 64) & (-16);
- // vst {d8, d9, d10, d11}
- // vst {d12, d13, d14, d15}
- printf (" d11, d10, d9, d8, d15, d14, d13, d12");
- break;
- }
- }
- }
+ if (register_count == 0) {
+ printf(" no registers saved");
+ } else {
+
+ // We need to include (up to) 6 registers in 10 bits.
+ // That would be 18 bits if we just used 3 bits per reg to indicate
+ // the order they're saved on the stack.
+ //
+ // This is done with Lehmer code permutation, e.g. see
+ // http://stackoverflow.com/questions/1506078/fast-permutation-number-permutation-mapping-algorithms
+ int permunreg[6];
+
+ // This decodes the variable-base number in the 10 bits
+ // and gives us the Lehmer code sequence which can then
+ // be decoded.
+
+ switch (register_count) {
+ case 6:
+ permunreg[0] = permutation / 120; // 120 == 5!
+ permutation -= (permunreg[0] * 120);
+ permunreg[1] = permutation / 24; // 24 == 4!
+ permutation -= (permunreg[1] * 24);
+ permunreg[2] = permutation / 6; // 6 == 3!
+ permutation -= (permunreg[2] * 6);
+ permunreg[3] = permutation / 2; // 2 == 2!
+ permutation -= (permunreg[3] * 2);
+ permunreg[4] = permutation; // 1 == 1!
+ permunreg[5] = 0;
break;
-
- case UNWIND_ARM_MODE_DWARF:
- {
- uint32_t dwarf_offset = encoding & UNWIND_ARM_DWARF_SECTION_OFFSET;
- printf ("DWARF unwind instructions: FDE at offset %d (file address 0x%" PRIx64 ")",
- dwarf_offset, dwarf_offset + baton.eh_section_file_address);
- }
+ case 5:
+ permunreg[0] = permutation / 120;
+ permutation -= (permunreg[0] * 120);
+ permunreg[1] = permutation / 24;
+ permutation -= (permunreg[1] * 24);
+ permunreg[2] = permutation / 6;
+ permutation -= (permunreg[2] * 6);
+ permunreg[3] = permutation / 2;
+ permutation -= (permunreg[3] * 2);
+ permunreg[4] = permutation;
break;
-
- case 0:
- {
- printf (" no unwind information");
- }
+ case 4:
+ permunreg[0] = permutation / 60;
+ permutation -= (permunreg[0] * 60);
+ permunreg[1] = permutation / 12;
+ permutation -= (permunreg[1] * 12);
+ permunreg[2] = permutation / 3;
+ permutation -= (permunreg[2] * 3);
+ permunreg[3] = permutation;
+ break;
+ case 3:
+ permunreg[0] = permutation / 20;
+ permutation -= (permunreg[0] * 20);
+ permunreg[1] = permutation / 4;
+ permutation -= (permunreg[1] * 4);
+ permunreg[2] = permutation;
+ break;
+ case 2:
+ permunreg[0] = permutation / 5;
+ permutation -= (permunreg[0] * 5);
+ permunreg[1] = permutation;
break;
+ case 1:
+ permunreg[0] = permutation;
+ break;
+ }
+
+ // Decode the Lehmer code for this permutation of
+ // the registers v. http://en.wikipedia.org/wiki/Lehmer_code
+
+ int registers[6];
+ bool used[7] = {false, false, false, false, false, false, false};
+ for (int i = 0; i < register_count; i++) {
+ int renum = 0;
+ for (int j = 1; j < 7; j++) {
+ if (used[j] == false) {
+ if (renum == permunreg[i]) {
+ registers[i] = j;
+ used[j] = true;
+ break;
+ }
+ renum++;
+ }
+ }
+ }
+
+ if (mode == UNWIND_X86_MODE_STACK_IND) {
+ printf(" CFA is esp+%d ", stack_size);
+ } else {
+ printf(" CFA is esp+%d ", stack_size * 4);
+ }
+
+ uint32_t saved_registers_offset = 1;
+ printf(" eip=[CFA-%d]", saved_registers_offset * 4);
+ saved_registers_offset++;
+
+ for (int i = (sizeof(registers) / sizeof(int)) - 1; i >= 0; i--) {
+ switch (registers[i]) {
+ case UNWIND_X86_REG_NONE:
+ break;
+ case UNWIND_X86_REG_EBX:
+ printf(" ebx=[CFA-%d]", saved_registers_offset * 4);
+ saved_registers_offset++;
+ break;
+ case UNWIND_X86_REG_ECX:
+ printf(" ecx=[CFA-%d]", saved_registers_offset * 4);
+ saved_registers_offset++;
+ break;
+ case UNWIND_X86_REG_EDX:
+ printf(" edx=[CFA-%d]", saved_registers_offset * 4);
+ saved_registers_offset++;
+ break;
+ case UNWIND_X86_REG_EDI:
+ printf(" edi=[CFA-%d]", saved_registers_offset * 4);
+ saved_registers_offset++;
+ break;
+ case UNWIND_X86_REG_ESI:
+ printf(" esi=[CFA-%d]", saved_registers_offset * 4);
+ saved_registers_offset++;
+ break;
+ case UNWIND_X86_REG_EBP:
+ printf(" ebp=[CFA-%d]", saved_registers_offset * 4);
+ saved_registers_offset++;
+ break;
+ }
+ }
}
-}
-
+ } break;
+ case UNWIND_X86_MODE_DWARF: {
+ uint32_t dwarf_offset = encoding & UNWIND_X86_DWARF_SECTION_OFFSET;
+ printf(
+ "DWARF unwind instructions: FDE at offset %d (file address 0x%" PRIx64
+ ")",
+ dwarf_offset, dwarf_offset + baton.eh_section_file_address);
+ } break;
-void print_encoding (struct baton baton, uint8_t *function_start, uint32_t encoding)
-{
+ case 0: {
+ printf(" no unwind information");
+ } break;
+ }
+}
- if (baton.cputype == CPU_TYPE_X86_64)
- {
- print_encoding_x86_64 (baton, function_start, encoding);
+void print_encoding_arm64(struct baton baton, uint8_t *function_start,
+ uint32_t encoding) {
+ const int wordsize = 8;
+ int mode = encoding & UNWIND_ARM64_MODE_MASK;
+ switch (mode) {
+ case UNWIND_ARM64_MODE_FRAME: {
+ printf("frame func: CFA is fp+%d ", 16);
+ printf(" pc=[CFA-8] fp=[CFA-16]");
+ int reg_pairs_saved_count = 1;
+ uint32_t saved_register_bits = encoding & 0xfff;
+ if (saved_register_bits & UNWIND_ARM64_FRAME_X19_X20_PAIR) {
+ int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
+ cfa_offset -= wordsize;
+ printf(" x19=[CFA%d]", cfa_offset);
+ cfa_offset -= wordsize;
+ printf(" x20=[CFA%d]", cfa_offset);
+ reg_pairs_saved_count++;
}
- else if (baton.cputype == CPU_TYPE_I386)
- {
- print_encoding_i386 (baton, function_start, encoding);
+ if (saved_register_bits & UNWIND_ARM64_FRAME_X21_X22_PAIR) {
+ int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
+ cfa_offset -= wordsize;
+ printf(" x21=[CFA%d]", cfa_offset);
+ cfa_offset -= wordsize;
+ printf(" x22=[CFA%d]", cfa_offset);
+ reg_pairs_saved_count++;
}
- else if (baton.cputype == CPU_TYPE_ARM64)
- {
- print_encoding_arm64 (baton, function_start, encoding);
+ if (saved_register_bits & UNWIND_ARM64_FRAME_X23_X24_PAIR) {
+ int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
+ cfa_offset -= wordsize;
+ printf(" x23=[CFA%d]", cfa_offset);
+ cfa_offset -= wordsize;
+ printf(" x24=[CFA%d]", cfa_offset);
+ reg_pairs_saved_count++;
}
- else if (baton.cputype == CPU_TYPE_ARM)
- {
- print_encoding_armv7 (baton, function_start, encoding);
+ if (saved_register_bits & UNWIND_ARM64_FRAME_X25_X26_PAIR) {
+ int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
+ cfa_offset -= wordsize;
+ printf(" x25=[CFA%d]", cfa_offset);
+ cfa_offset -= wordsize;
+ printf(" x26=[CFA%d]", cfa_offset);
+ reg_pairs_saved_count++;
}
- else
- {
- printf (" -- unsupported encoding arch -- ");
+ if (saved_register_bits & UNWIND_ARM64_FRAME_X27_X28_PAIR) {
+ int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
+ cfa_offset -= wordsize;
+ printf(" x27=[CFA%d]", cfa_offset);
+ cfa_offset -= wordsize;
+ printf(" x28=[CFA%d]", cfa_offset);
+ reg_pairs_saved_count++;
}
-}
-
-void
-print_function_encoding (struct baton baton, uint32_t idx, uint32_t encoding, uint32_t entry_encoding_index, uint32_t entry_func_offset)
-{
-
- char *entry_encoding_index_str = "";
- if (entry_encoding_index != (uint32_t) -1)
- {
- asprintf (&entry_encoding_index_str, ", encoding #%d", entry_encoding_index);
+ if (saved_register_bits & UNWIND_ARM64_FRAME_D8_D9_PAIR) {
+ int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
+ cfa_offset -= wordsize;
+ printf(" d8=[CFA%d]", cfa_offset);
+ cfa_offset -= wordsize;
+ printf(" d9=[CFA%d]", cfa_offset);
+ reg_pairs_saved_count++;
}
- else
- {
- asprintf (&entry_encoding_index_str, "");
+ if (saved_register_bits & UNWIND_ARM64_FRAME_D10_D11_PAIR) {
+ int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
+ cfa_offset -= wordsize;
+ printf(" d10=[CFA%d]", cfa_offset);
+ cfa_offset -= wordsize;
+ printf(" d11=[CFA%d]", cfa_offset);
+ reg_pairs_saved_count++;
}
-
- uint64_t file_address = baton.first_level_index_entry.functionOffset + entry_func_offset + baton.text_segment_vmaddr;
-
- if (baton.cputype == CPU_TYPE_ARM)
- file_address = file_address & ~1;
-
- printf (" func [%d] offset %d (file addr 0x%" PRIx64 ")%s, encoding is 0x%x",
- idx, entry_func_offset,
- file_address,
- entry_encoding_index_str,
- encoding);
-
- struct symbol *symbol = NULL;
- for (int i = 0; i < baton.symbols_count; i++)
- {
- if (i == baton.symbols_count - 1 && baton.symbols[i].file_address <= file_address)
- {
- symbol = &(baton.symbols[i]);
- break;
- }
- else
- {
- if (baton.symbols[i].file_address <= file_address && baton.symbols[i + 1].file_address > file_address)
- {
- symbol = &(baton.symbols[i]);
- break;
- }
- }
+ if (saved_register_bits & UNWIND_ARM64_FRAME_D12_D13_PAIR) {
+ int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
+ cfa_offset -= wordsize;
+ printf(" d12=[CFA%d]", cfa_offset);
+ cfa_offset -= wordsize;
+ printf(" d13=[CFA%d]", cfa_offset);
+ reg_pairs_saved_count++;
}
-
- printf ("\n ");
- if (symbol)
- {
- int offset = file_address - symbol->file_address;
-
- // FIXME this is a poor heuristic - if we're greater than 16 bytes past the
- // start of the function, this is the unwind info for a stripped function.
- // In reality the compact unwind entry may not line up exactly with the
- // function bounds.
- if (offset >= 0)
- {
- printf ("name: %s", symbol->name);
- if (offset > 0)
- {
- printf (" + %d", offset);
- }
- }
- printf ("\n ");
+ if (saved_register_bits & UNWIND_ARM64_FRAME_D14_D15_PAIR) {
+ int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
+ cfa_offset -= wordsize;
+ printf(" d14=[CFA%d]", cfa_offset);
+ cfa_offset -= wordsize;
+ printf(" d15=[CFA%d]", cfa_offset);
+ reg_pairs_saved_count++;
}
- print_encoding (baton, baton.mach_header_start + baton.first_level_index_entry.functionOffset + baton.text_section_file_offset + entry_func_offset, encoding);
-
- bool has_lsda = encoding & UNWIND_HAS_LSDA;
-
- if (has_lsda)
- {
- uint32_t func_offset = entry_func_offset + baton.first_level_index_entry.functionOffset;
+ } break;
- int lsda_entry_number = -1;
+ case UNWIND_ARM64_MODE_FRAMELESS: {
+ uint32_t stack_size = encoding & UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK;
+ printf("frameless function: stack size %d ", stack_size * 16);
- uint32_t low = 0;
- uint32_t high = (baton.lsda_array_end - baton.lsda_array_start) / sizeof (struct unwind_info_section_header_lsda_index_entry);
+ } break;
- while (low < high)
- {
- uint32_t mid = (low + high) / 2;
+ case UNWIND_ARM64_MODE_DWARF: {
+ uint32_t dwarf_offset = encoding & UNWIND_ARM64_DWARF_SECTION_OFFSET;
+ printf(
+ "DWARF unwind instructions: FDE at offset %d (file address 0x%" PRIx64
+ ")",
+ dwarf_offset, dwarf_offset + baton.eh_section_file_address);
+ } break;
- uint8_t *mid_lsda_entry_addr = (baton.lsda_array_start + (mid * sizeof (struct unwind_info_section_header_lsda_index_entry)));
- struct unwind_info_section_header_lsda_index_entry mid_lsda_entry;
- memcpy (&mid_lsda_entry, mid_lsda_entry_addr, sizeof (struct unwind_info_section_header_lsda_index_entry));
- if (mid_lsda_entry.functionOffset == func_offset)
- {
- lsda_entry_number = (mid_lsda_entry_addr - baton.lsda_array_start) / sizeof (struct unwind_info_section_header_lsda_index_entry);
- break;
- }
- else if (mid_lsda_entry.functionOffset < func_offset)
- {
- low = mid + 1;
- }
- else
- {
- high = mid;
- }
- }
+ case 0: {
+ printf(" no unwind information");
+ } break;
+ }
+}
- if (lsda_entry_number != -1)
- {
- printf (", LSDA entry #%d", lsda_entry_number);
- }
- else
- {
- printf (", LSDA entry not found");
- }
+void print_encoding_armv7(struct baton baton, uint8_t *function_start,
+ uint32_t encoding) {
+ const int wordsize = 4;
+ int mode = encoding & UNWIND_ARM_MODE_MASK;
+ switch (mode) {
+ case UNWIND_ARM_MODE_FRAME_D:
+ case UNWIND_ARM_MODE_FRAME: {
+ int stack_adjust =
+ EXTRACT_BITS(encoding, UNWIND_ARM_FRAME_STACK_ADJUST_MASK) * wordsize;
+
+ printf("frame func: CFA is fp+%d ", (2 * wordsize) + stack_adjust);
+ int cfa_offset = -stack_adjust;
+
+ cfa_offset -= wordsize;
+ printf(" pc=[CFA%d]", cfa_offset);
+ cfa_offset -= wordsize;
+ printf(" fp=[CFA%d]", cfa_offset);
+
+ uint32_t saved_register_bits = encoding & 0xff;
+ if (saved_register_bits & UNWIND_ARM_FRAME_FIRST_PUSH_R6) {
+ cfa_offset -= wordsize;
+ printf(" r6=[CFA%d]", cfa_offset);
}
-
- uint32_t pers_idx = EXTRACT_BITS (encoding, UNWIND_PERSONALITY_MASK);
- if (pers_idx != 0)
- {
- pers_idx--; // Change 1-based to 0-based index
- printf (", personality entry #%d", pers_idx);
+ if (saved_register_bits & UNWIND_ARM_FRAME_FIRST_PUSH_R5) {
+ cfa_offset -= wordsize;
+ printf(" r5=[CFA%d]", cfa_offset);
}
-
- printf ("\n");
-}
-
-void
-print_second_level_index_regular (struct baton baton)
-{
- uint8_t *page_entries = baton.compact_unwind_start + baton.first_level_index_entry.secondLevelPagesSectionOffset + baton.regular_second_level_page_header.entryPageOffset;
- uint32_t entries_count = baton.regular_second_level_page_header.entryCount;
-
- uint8_t *offset = page_entries;
-
- uint32_t idx = 0;
- while (idx < entries_count)
- {
- uint32_t func_offset = *((uint32_t *) (offset));
- uint32_t encoding = *((uint32_t *) (offset + 4));
-
- // UNWIND_SECOND_LEVEL_REGULAR entries have a funcOffset which includes the
- // functionOffset from the containing index table already. UNWIND_SECOND_LEVEL_COMPRESSED
- // entries only have the offset from the containing index table functionOffset.
- // So strip off the containing index table functionOffset value here so they can
- // be treated the same at the lower layers.
-
- print_function_encoding (baton, idx, encoding, (uint32_t) -1, func_offset - baton.first_level_index_entry.functionOffset);
- idx++;
- offset += 8;
+ if (saved_register_bits & UNWIND_ARM_FRAME_FIRST_PUSH_R4) {
+ cfa_offset -= wordsize;
+ printf(" r4=[CFA%d]", cfa_offset);
}
-}
-
-void
-print_second_level_index_compressed (struct baton baton)
-{
- uint8_t *this_index = baton.compact_unwind_start + baton.first_level_index_entry.secondLevelPagesSectionOffset;
- uint8_t *start_of_entries = this_index + baton.compressed_second_level_page_header.entryPageOffset;
- uint8_t *offset = start_of_entries;
- for (uint16_t idx = 0; idx < baton.compressed_second_level_page_header.entryCount; idx++)
- {
- uint32_t entry = *((uint32_t*) offset);
- offset += 4;
- uint32_t encoding;
-
- uint32_t entry_encoding_index = UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX (entry);
- uint32_t entry_func_offset = UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET (entry);
-
- if (entry_encoding_index < baton.unwind_header.commonEncodingsArrayCount)
- {
- // encoding is in common table in section header
- encoding = *((uint32_t*) (baton.compact_unwind_start + baton.unwind_header.commonEncodingsArraySectionOffset + (entry_encoding_index * sizeof (uint32_t))));
- }
- else
- {
- // encoding is in page specific table
- uint32_t page_encoding_index = entry_encoding_index - baton.unwind_header.commonEncodingsArrayCount;
- encoding = *((uint32_t*) (this_index + baton.compressed_second_level_page_header.encodingsPageOffset + (page_encoding_index * sizeof (uint32_t))));
- }
-
-
- print_function_encoding (baton, idx, encoding, entry_encoding_index, entry_func_offset);
+ if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R12) {
+ cfa_offset -= wordsize;
+ printf(" r12=[CFA%d]", cfa_offset);
}
-}
-
-void
-print_second_level_index (struct baton baton)
-{
- uint8_t *index_start = baton.compact_unwind_start + baton.first_level_index_entry.secondLevelPagesSectionOffset;
-
- if ((*(uint32_t*) index_start) == UNWIND_SECOND_LEVEL_REGULAR)
- {
- struct unwind_info_regular_second_level_page_header header;
- memcpy (&header, index_start, sizeof (struct unwind_info_regular_second_level_page_header));
- printf (" UNWIND_SECOND_LEVEL_REGULAR #%d entryPageOffset %d, entryCount %d\n", baton.current_index_table_number, header.entryPageOffset, header.entryCount);
- baton.regular_second_level_page_header = header;
- print_second_level_index_regular (baton);
+ if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R11) {
+ cfa_offset -= wordsize;
+ printf(" r11=[CFA%d]", cfa_offset);
+ }
+ if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R10) {
+ cfa_offset -= wordsize;
+ printf(" r10=[CFA%d]", cfa_offset);
+ }
+ if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R9) {
+ cfa_offset -= wordsize;
+ printf(" r9=[CFA%d]", cfa_offset);
+ }
+ if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R8) {
+ cfa_offset -= wordsize;
+ printf(" r8=[CFA%d]", cfa_offset);
}
- if ((*(uint32_t*) index_start) == UNWIND_SECOND_LEVEL_COMPRESSED)
- {
- struct unwind_info_compressed_second_level_page_header header;
- memcpy (&header, index_start, sizeof (struct unwind_info_compressed_second_level_page_header));
- printf (" UNWIND_SECOND_LEVEL_COMPRESSED #%d entryPageOffset %d, entryCount %d, encodingsPageOffset %d, encodingsCount %d\n", baton.current_index_table_number, header.entryPageOffset, header.entryCount, header.encodingsPageOffset, header.encodingsCount);
- baton.compressed_second_level_page_header = header;
- print_second_level_index_compressed (baton);
+ if (mode == UNWIND_ARM_MODE_FRAME_D) {
+ uint32_t d_reg_bits =
+ EXTRACT_BITS(encoding, UNWIND_ARM_FRAME_D_REG_COUNT_MASK);
+ switch (d_reg_bits) {
+ case 0:
+ // vpush {d8}
+ cfa_offset -= 8;
+ printf(" d8=[CFA%d]", cfa_offset);
+ break;
+ case 1:
+ // vpush {d10}
+ // vpush {d8}
+ cfa_offset -= 8;
+ printf(" d10=[CFA%d]", cfa_offset);
+ cfa_offset -= 8;
+ printf(" d8=[CFA%d]", cfa_offset);
+ break;
+ case 2:
+ // vpush {d12}
+ // vpush {d10}
+ // vpush {d8}
+ cfa_offset -= 8;
+ printf(" d12=[CFA%d]", cfa_offset);
+ cfa_offset -= 8;
+ printf(" d10=[CFA%d]", cfa_offset);
+ cfa_offset -= 8;
+ printf(" d8=[CFA%d]", cfa_offset);
+ break;
+ case 3:
+ // vpush {d14}
+ // vpush {d12}
+ // vpush {d10}
+ // vpush {d8}
+ cfa_offset -= 8;
+ printf(" d14=[CFA%d]", cfa_offset);
+ cfa_offset -= 8;
+ printf(" d12=[CFA%d]", cfa_offset);
+ cfa_offset -= 8;
+ printf(" d10=[CFA%d]", cfa_offset);
+ cfa_offset -= 8;
+ printf(" d8=[CFA%d]", cfa_offset);
+ break;
+ case 4:
+ // vpush {d14}
+ // vpush {d12}
+ // sp = (sp - 24) & (-16);
+ // vst {d8, d9, d10}
+ printf(" d14, d12, d10, d9, d8");
+ break;
+ case 5:
+ // vpush {d14}
+ // sp = (sp - 40) & (-16);
+ // vst {d8, d9, d10, d11}
+ // vst {d12}
+ printf(" d14, d11, d10, d9, d8, d12");
+ break;
+ case 6:
+ // sp = (sp - 56) & (-16);
+ // vst {d8, d9, d10, d11}
+ // vst {d12, d13, d14}
+ printf(" d11, d10, d9, d8, d14, d13, d12");
+ break;
+ case 7:
+ // sp = (sp - 64) & (-16);
+ // vst {d8, d9, d10, d11}
+ // vst {d12, d13, d14, d15}
+ printf(" d11, d10, d9, d8, d15, d14, d13, d12");
+ break;
+ }
}
+ } break;
+
+ case UNWIND_ARM_MODE_DWARF: {
+ uint32_t dwarf_offset = encoding & UNWIND_ARM_DWARF_SECTION_OFFSET;
+ printf(
+ "DWARF unwind instructions: FDE at offset %d (file address 0x%" PRIx64
+ ")",
+ dwarf_offset, dwarf_offset + baton.eh_section_file_address);
+ } break;
+
+ case 0: {
+ printf(" no unwind information");
+ } break;
+ }
}
-
-void
-print_index_sections (struct baton baton)
-{
- uint8_t *index_section_offset = baton.compact_unwind_start + baton.unwind_header.indexSectionOffset;
- uint32_t index_count = baton.unwind_header.indexCount;
-
- uint32_t cur_idx = 0;
-
- uint8_t *offset = index_section_offset;
- while (cur_idx < index_count)
- {
- baton.current_index_table_number = cur_idx;
- struct unwind_info_section_header_index_entry index_entry;
- memcpy (&index_entry, offset, sizeof (struct unwind_info_section_header_index_entry));
- printf ("index section #%d: functionOffset %d, secondLevelPagesSectionOffset %d, lsdaIndexArraySectionOffset %d\n", cur_idx, index_entry.functionOffset, index_entry.secondLevelPagesSectionOffset, index_entry.lsdaIndexArraySectionOffset);
-
- // secondLevelPagesSectionOffset == 0 means this is a sentinel entry
- if (index_entry.secondLevelPagesSectionOffset != 0)
- {
- struct unwind_info_section_header_index_entry next_index_entry;
- memcpy (&next_index_entry, offset + sizeof (struct unwind_info_section_header_index_entry), sizeof (struct unwind_info_section_header_index_entry));
-
- baton.lsda_array_start = baton.compact_unwind_start + index_entry.lsdaIndexArraySectionOffset;
- baton.lsda_array_end = baton.compact_unwind_start + next_index_entry.lsdaIndexArraySectionOffset;
-
- uint8_t *lsda_entry_offset = baton.lsda_array_start;
- uint32_t lsda_count = 0;
- while (lsda_entry_offset < baton.lsda_array_end)
- {
- struct unwind_info_section_header_lsda_index_entry lsda_entry;
- memcpy (&lsda_entry, lsda_entry_offset, sizeof (struct unwind_info_section_header_lsda_index_entry));
- uint64_t function_file_address = baton.first_level_index_entry.functionOffset + lsda_entry.functionOffset + baton.text_segment_vmaddr;
- uint64_t lsda_file_address = lsda_entry.lsdaOffset + baton.text_segment_vmaddr;
- printf (" LSDA [%d] functionOffset %d (%d) (file address 0x%" PRIx64 "), lsdaOffset %d (file address 0x%" PRIx64 ")\n",
- lsda_count, lsda_entry.functionOffset,
- lsda_entry.functionOffset - index_entry.functionOffset,
- function_file_address,
- lsda_entry.lsdaOffset, lsda_file_address);
- lsda_count++;
- lsda_entry_offset += sizeof (struct unwind_info_section_header_lsda_index_entry);
- }
-
- printf ("\n");
-
- baton.first_level_index_entry = index_entry;
- print_second_level_index (baton);
- }
-
- printf ("\n");
-
- cur_idx++;
- offset += sizeof (struct unwind_info_section_header_index_entry);
- }
+void print_encoding(struct baton baton, uint8_t *function_start,
+ uint32_t encoding) {
+
+ if (baton.cputype == CPU_TYPE_X86_64) {
+ print_encoding_x86_64(baton, function_start, encoding);
+ } else if (baton.cputype == CPU_TYPE_I386) {
+ print_encoding_i386(baton, function_start, encoding);
+ } else if (baton.cputype == CPU_TYPE_ARM64) {
+ print_encoding_arm64(baton, function_start, encoding);
+ } else if (baton.cputype == CPU_TYPE_ARM) {
+ print_encoding_armv7(baton, function_start, encoding);
+ } else {
+ printf(" -- unsupported encoding arch -- ");
+ }
}
-int main (int argc, char **argv)
-{
- struct stat st;
- char *file = argv[0];
- if (argc > 1)
- file = argv[1];
- int fd = open (file, O_RDONLY);
- if (fd == -1)
- {
- printf ("Failed to open '%s'\n", file);
- exit (1);
+void print_function_encoding(struct baton baton, uint32_t idx,
+ uint32_t encoding, uint32_t entry_encoding_index,
+ uint32_t entry_func_offset) {
+
+ char *entry_encoding_index_str = "";
+ if (entry_encoding_index != (uint32_t)-1) {
+ asprintf(&entry_encoding_index_str, ", encoding #%d", entry_encoding_index);
+ } else {
+ asprintf(&entry_encoding_index_str, "");
+ }
+
+ uint64_t file_address = baton.first_level_index_entry.functionOffset +
+ entry_func_offset + baton.text_segment_vmaddr;
+
+ if (baton.cputype == CPU_TYPE_ARM)
+ file_address = file_address & ~1;
+
+ printf(
+ " func [%d] offset %d (file addr 0x%" PRIx64 ")%s, encoding is 0x%x",
+ idx, entry_func_offset, file_address, entry_encoding_index_str, encoding);
+
+ struct symbol *symbol = NULL;
+ for (int i = 0; i < baton.symbols_count; i++) {
+ if (i == baton.symbols_count - 1 &&
+ baton.symbols[i].file_address <= file_address) {
+ symbol = &(baton.symbols[i]);
+ break;
+ } else {
+ if (baton.symbols[i].file_address <= file_address &&
+ baton.symbols[i + 1].file_address > file_address) {
+ symbol = &(baton.symbols[i]);
+ break;
+ }
}
- fstat (fd, &st);
- uint8_t *file_mem = (uint8_t*) mmap (0, st.st_size, PROT_READ, MAP_PRIVATE | MAP_FILE, fd, 0);
- if (file_mem == MAP_FAILED)
- {
- printf ("Failed to mmap() '%s'\n", file);
+ }
+
+ printf("\n ");
+ if (symbol) {
+ int offset = file_address - symbol->file_address;
+
+ // FIXME this is a poor heuristic - if we're greater than 16 bytes past the
+ // start of the function, this is the unwind info for a stripped function.
+ // In reality the compact unwind entry may not line up exactly with the
+ // function bounds.
+ if (offset >= 0) {
+ printf("name: %s", symbol->name);
+ if (offset > 0) {
+ printf(" + %d", offset);
+ }
+ }
+ printf("\n ");
+ }
+
+ print_encoding(baton, baton.mach_header_start +
+ baton.first_level_index_entry.functionOffset +
+ baton.text_section_file_offset + entry_func_offset,
+ encoding);
+
+ bool has_lsda = encoding & UNWIND_HAS_LSDA;
+
+ if (has_lsda) {
+ uint32_t func_offset =
+ entry_func_offset + baton.first_level_index_entry.functionOffset;
+
+ int lsda_entry_number = -1;
+
+ uint32_t low = 0;
+ uint32_t high = (baton.lsda_array_end - baton.lsda_array_start) /
+ sizeof(struct unwind_info_section_header_lsda_index_entry);
+
+ while (low < high) {
+ uint32_t mid = (low + high) / 2;
+
+ uint8_t *mid_lsda_entry_addr =
+ (baton.lsda_array_start +
+ (mid * sizeof(struct unwind_info_section_header_lsda_index_entry)));
+ struct unwind_info_section_header_lsda_index_entry mid_lsda_entry;
+ memcpy(&mid_lsda_entry, mid_lsda_entry_addr,
+ sizeof(struct unwind_info_section_header_lsda_index_entry));
+ if (mid_lsda_entry.functionOffset == func_offset) {
+ lsda_entry_number =
+ (mid_lsda_entry_addr - baton.lsda_array_start) /
+ sizeof(struct unwind_info_section_header_lsda_index_entry);
+ break;
+ } else if (mid_lsda_entry.functionOffset < func_offset) {
+ low = mid + 1;
+ } else {
+ high = mid;
+ }
}
- FILE *f = fopen ("a.out", "r");
-
- struct baton baton;
- baton.mach_header_start = file_mem;
- baton.symbols = NULL;
- baton.symbols_count = 0;
- baton.function_start_addresses = NULL;
- baton.function_start_addresses_count = 0;
+ if (lsda_entry_number != -1) {
+ printf(", LSDA entry #%d", lsda_entry_number);
+ } else {
+ printf(", LSDA entry not found");
+ }
+ }
- scan_macho_load_commands (&baton);
+ uint32_t pers_idx = EXTRACT_BITS(encoding, UNWIND_PERSONALITY_MASK);
+ if (pers_idx != 0) {
+ pers_idx--; // Change 1-based to 0-based index
+ printf(", personality entry #%d", pers_idx);
+ }
- if (baton.compact_unwind_start == NULL)
- {
- printf ("could not find __TEXT,__unwind_info section\n");
- exit (1);
- }
+ printf("\n");
+}
+void print_second_level_index_regular(struct baton baton) {
+ uint8_t *page_entries =
+ baton.compact_unwind_start +
+ baton.first_level_index_entry.secondLevelPagesSectionOffset +
+ baton.regular_second_level_page_header.entryPageOffset;
+ uint32_t entries_count = baton.regular_second_level_page_header.entryCount;
+
+ uint8_t *offset = page_entries;
+
+ uint32_t idx = 0;
+ while (idx < entries_count) {
+ uint32_t func_offset = *((uint32_t *)(offset));
+ uint32_t encoding = *((uint32_t *)(offset + 4));
+
+ // UNWIND_SECOND_LEVEL_REGULAR entries have a funcOffset which includes the
+ // functionOffset from the containing index table already.
+ // UNWIND_SECOND_LEVEL_COMPRESSED
+ // entries only have the offset from the containing index table
+ // functionOffset.
+ // So strip off the containing index table functionOffset value here so they
+ // can
+ // be treated the same at the lower layers.
+
+ print_function_encoding(baton, idx, encoding, (uint32_t)-1,
+ func_offset -
+ baton.first_level_index_entry.functionOffset);
+ idx++;
+ offset += 8;
+ }
+}
- struct unwind_info_section_header header;
- memcpy (&header, baton.compact_unwind_start, sizeof (struct unwind_info_section_header));
- printf ("Header:\n");
- printf (" version %u\n", header.version);
- printf (" commonEncodingsArraySectionOffset is %d\n", header.commonEncodingsArraySectionOffset);
- printf (" commonEncodingsArrayCount is %d\n", header.commonEncodingsArrayCount);
- printf (" personalityArraySectionOffset is %d\n", header.personalityArraySectionOffset);
- printf (" personalityArrayCount is %d\n", header.personalityArrayCount);
- printf (" indexSectionOffset is %d\n", header.indexSectionOffset);
- printf (" indexCount is %d\n", header.indexCount);
-
- uint8_t *common_encodings = baton.compact_unwind_start + header.commonEncodingsArraySectionOffset;
- uint32_t encoding_idx = 0;
- while (encoding_idx < header.commonEncodingsArrayCount)
- {
- uint32_t encoding = *((uint32_t*) common_encodings);
- printf (" Common Encoding [%d]: 0x%x ", encoding_idx, encoding);
- print_encoding (baton, NULL, encoding);
- printf ("\n");
- common_encodings += sizeof (uint32_t);
- encoding_idx++;
+void print_second_level_index_compressed(struct baton baton) {
+ uint8_t *this_index =
+ baton.compact_unwind_start +
+ baton.first_level_index_entry.secondLevelPagesSectionOffset;
+ uint8_t *start_of_entries =
+ this_index + baton.compressed_second_level_page_header.entryPageOffset;
+ uint8_t *offset = start_of_entries;
+ for (uint16_t idx = 0;
+ idx < baton.compressed_second_level_page_header.entryCount; idx++) {
+ uint32_t entry = *((uint32_t *)offset);
+ offset += 4;
+ uint32_t encoding;
+
+ uint32_t entry_encoding_index =
+ UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX(entry);
+ uint32_t entry_func_offset =
+ UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET(entry);
+
+ if (entry_encoding_index < baton.unwind_header.commonEncodingsArrayCount) {
+ // encoding is in common table in section header
+ encoding =
+ *((uint32_t *)(baton.compact_unwind_start +
+ baton.unwind_header.commonEncodingsArraySectionOffset +
+ (entry_encoding_index * sizeof(uint32_t))));
+ } else {
+ // encoding is in page specific table
+ uint32_t page_encoding_index =
+ entry_encoding_index - baton.unwind_header.commonEncodingsArrayCount;
+ encoding = *((uint32_t *)(this_index +
+ baton.compressed_second_level_page_header
+ .encodingsPageOffset +
+ (page_encoding_index * sizeof(uint32_t))));
}
- uint8_t *pers_arr = baton.compact_unwind_start + header.personalityArraySectionOffset;
- uint32_t pers_idx = 0;
- while (pers_idx < header.personalityArrayCount)
- {
- int32_t pers_delta = *((int32_t*) (baton.compact_unwind_start + header.personalityArraySectionOffset + (pers_idx * sizeof (uint32_t))));
- printf (" Personality [%d]: personality function ptr @ offset %d (file address 0x%" PRIx64 ")\n", pers_idx, pers_delta, baton.text_segment_vmaddr + pers_delta);
- pers_idx++;
- pers_arr += sizeof (uint32_t);
- }
+ print_function_encoding(baton, idx, encoding, entry_encoding_index,
+ entry_func_offset);
+ }
+}
- printf ("\n");
+void print_second_level_index(struct baton baton) {
+ uint8_t *index_start =
+ baton.compact_unwind_start +
+ baton.first_level_index_entry.secondLevelPagesSectionOffset;
+
+ if ((*(uint32_t *)index_start) == UNWIND_SECOND_LEVEL_REGULAR) {
+ struct unwind_info_regular_second_level_page_header header;
+ memcpy(&header, index_start,
+ sizeof(struct unwind_info_regular_second_level_page_header));
+ printf(
+ " UNWIND_SECOND_LEVEL_REGULAR #%d entryPageOffset %d, entryCount %d\n",
+ baton.current_index_table_number, header.entryPageOffset,
+ header.entryCount);
+ baton.regular_second_level_page_header = header;
+ print_second_level_index_regular(baton);
+ }
+
+ if ((*(uint32_t *)index_start) == UNWIND_SECOND_LEVEL_COMPRESSED) {
+ struct unwind_info_compressed_second_level_page_header header;
+ memcpy(&header, index_start,
+ sizeof(struct unwind_info_compressed_second_level_page_header));
+ printf(" UNWIND_SECOND_LEVEL_COMPRESSED #%d entryPageOffset %d, "
+ "entryCount %d, encodingsPageOffset %d, encodingsCount %d\n",
+ baton.current_index_table_number, header.entryPageOffset,
+ header.entryCount, header.encodingsPageOffset,
+ header.encodingsCount);
+ baton.compressed_second_level_page_header = header;
+ print_second_level_index_compressed(baton);
+ }
+}
- baton.unwind_header = header;
+void print_index_sections(struct baton baton) {
+ uint8_t *index_section_offset =
+ baton.compact_unwind_start + baton.unwind_header.indexSectionOffset;
+ uint32_t index_count = baton.unwind_header.indexCount;
+
+ uint32_t cur_idx = 0;
+
+ uint8_t *offset = index_section_offset;
+ while (cur_idx < index_count) {
+ baton.current_index_table_number = cur_idx;
+ struct unwind_info_section_header_index_entry index_entry;
+ memcpy(&index_entry, offset,
+ sizeof(struct unwind_info_section_header_index_entry));
+ printf("index section #%d: functionOffset %d, "
+ "secondLevelPagesSectionOffset %d, lsdaIndexArraySectionOffset %d\n",
+ cur_idx, index_entry.functionOffset,
+ index_entry.secondLevelPagesSectionOffset,
+ index_entry.lsdaIndexArraySectionOffset);
+
+ // secondLevelPagesSectionOffset == 0 means this is a sentinel entry
+ if (index_entry.secondLevelPagesSectionOffset != 0) {
+ struct unwind_info_section_header_index_entry next_index_entry;
+ memcpy(&next_index_entry,
+ offset + sizeof(struct unwind_info_section_header_index_entry),
+ sizeof(struct unwind_info_section_header_index_entry));
+
+ baton.lsda_array_start =
+ baton.compact_unwind_start + index_entry.lsdaIndexArraySectionOffset;
+ baton.lsda_array_end = baton.compact_unwind_start +
+ next_index_entry.lsdaIndexArraySectionOffset;
+
+ uint8_t *lsda_entry_offset = baton.lsda_array_start;
+ uint32_t lsda_count = 0;
+ while (lsda_entry_offset < baton.lsda_array_end) {
+ struct unwind_info_section_header_lsda_index_entry lsda_entry;
+ memcpy(&lsda_entry, lsda_entry_offset,
+ sizeof(struct unwind_info_section_header_lsda_index_entry));
+ uint64_t function_file_address =
+ baton.first_level_index_entry.functionOffset +
+ lsda_entry.functionOffset + baton.text_segment_vmaddr;
+ uint64_t lsda_file_address =
+ lsda_entry.lsdaOffset + baton.text_segment_vmaddr;
+ printf(" LSDA [%d] functionOffset %d (%d) (file address 0x%" PRIx64
+ "), lsdaOffset %d (file address 0x%" PRIx64 ")\n",
+ lsda_count, lsda_entry.functionOffset,
+ lsda_entry.functionOffset - index_entry.functionOffset,
+ function_file_address, lsda_entry.lsdaOffset, lsda_file_address);
+ lsda_count++;
+ lsda_entry_offset +=
+ sizeof(struct unwind_info_section_header_lsda_index_entry);
+ }
+
+ printf("\n");
+
+ baton.first_level_index_entry = index_entry;
+ print_second_level_index(baton);
+ }
- print_index_sections (baton);
+ printf("\n");
+ cur_idx++;
+ offset += sizeof(struct unwind_info_section_header_index_entry);
+ }
+}
- return 0;
+int main(int argc, char **argv) {
+ struct stat st;
+ char *file = argv[0];
+ if (argc > 1)
+ file = argv[1];
+ int fd = open(file, O_RDONLY);
+ if (fd == -1) {
+ printf("Failed to open '%s'\n", file);
+ exit(1);
+ }
+ fstat(fd, &st);
+ uint8_t *file_mem =
+ (uint8_t *)mmap(0, st.st_size, PROT_READ, MAP_PRIVATE | MAP_FILE, fd, 0);
+ if (file_mem == MAP_FAILED) {
+ printf("Failed to mmap() '%s'\n", file);
+ }
+
+ FILE *f = fopen("a.out", "r");
+
+ struct baton baton;
+ baton.mach_header_start = file_mem;
+ baton.symbols = NULL;
+ baton.symbols_count = 0;
+ baton.function_start_addresses = NULL;
+ baton.function_start_addresses_count = 0;
+
+ scan_macho_load_commands(&baton);
+
+ if (baton.compact_unwind_start == NULL) {
+ printf("could not find __TEXT,__unwind_info section\n");
+ exit(1);
+ }
+
+ struct unwind_info_section_header header;
+ memcpy(&header, baton.compact_unwind_start,
+ sizeof(struct unwind_info_section_header));
+ printf("Header:\n");
+ printf(" version %u\n", header.version);
+ printf(" commonEncodingsArraySectionOffset is %d\n",
+ header.commonEncodingsArraySectionOffset);
+ printf(" commonEncodingsArrayCount is %d\n",
+ header.commonEncodingsArrayCount);
+ printf(" personalityArraySectionOffset is %d\n",
+ header.personalityArraySectionOffset);
+ printf(" personalityArrayCount is %d\n", header.personalityArrayCount);
+ printf(" indexSectionOffset is %d\n", header.indexSectionOffset);
+ printf(" indexCount is %d\n", header.indexCount);
+
+ uint8_t *common_encodings =
+ baton.compact_unwind_start + header.commonEncodingsArraySectionOffset;
+ uint32_t encoding_idx = 0;
+ while (encoding_idx < header.commonEncodingsArrayCount) {
+ uint32_t encoding = *((uint32_t *)common_encodings);
+ printf(" Common Encoding [%d]: 0x%x ", encoding_idx, encoding);
+ print_encoding(baton, NULL, encoding);
+ printf("\n");
+ common_encodings += sizeof(uint32_t);
+ encoding_idx++;
+ }
+
+ uint8_t *pers_arr =
+ baton.compact_unwind_start + header.personalityArraySectionOffset;
+ uint32_t pers_idx = 0;
+ while (pers_idx < header.personalityArrayCount) {
+ int32_t pers_delta = *((int32_t *)(baton.compact_unwind_start +
+ header.personalityArraySectionOffset +
+ (pers_idx * sizeof(uint32_t))));
+ printf(" Personality [%d]: personality function ptr @ offset %d (file "
+ "address 0x%" PRIx64 ")\n",
+ pers_idx, pers_delta, baton.text_segment_vmaddr + pers_delta);
+ pers_idx++;
+ pers_arr += sizeof(uint32_t);
+ }
+
+ printf("\n");
+
+ baton.unwind_header = header;
+
+ print_index_sections(baton);
+
+ return 0;
}
diff --git a/tools/darwin-debug/CMakeLists.txt b/tools/darwin-debug/CMakeLists.txt
index 352a573e25e1..2f28eab3a58f 100644
--- a/tools/darwin-debug/CMakeLists.txt
+++ b/tools/darwin-debug/CMakeLists.txt
@@ -1,6 +1,3 @@
-add_lldb_executable(lldb-launcher
+add_lldb_tool(darwin-debug INCLUDE_IN_FRAMEWORK
darwin-debug.cpp
)
-
-install(TARGETS lldb-launcher
- RUNTIME DESTINATION bin)
diff --git a/tools/darwin-debug/darwin-debug.cpp b/tools/darwin-debug/darwin-debug.cpp
index ca0a8d48328b..e754ded474c4 100644
--- a/tools/darwin-debug/darwin-debug.cpp
+++ b/tools/darwin-debug/darwin-debug.cpp
@@ -18,11 +18,11 @@
// attribute flags to accomplish its task. It uses an "exec only" flag
// which avoids forking this process, and it uses a "stop at entry"
// flag to stop the program at the entry point.
-//
+//
// Since it uses darwin specific flags this code should not be compiled
// on other systems.
//----------------------------------------------------------------------
-#if defined (__APPLE__)
+#if defined(__APPLE__)
#include <crt_externs.h> // for _NSGetEnviron()
#include <getopt.h>
@@ -41,314 +41,297 @@
#include <string>
#ifndef _POSIX_SPAWN_DISABLE_ASLR
-#define _POSIX_SPAWN_DISABLE_ASLR 0x0100
+#define _POSIX_SPAWN_DISABLE_ASLR 0x0100
#endif
-#define streq(a,b) strcmp(a,b) == 0
-
-static struct option g_long_options[] =
-{
- { "arch", required_argument, NULL, 'a' },
- { "disable-aslr", no_argument, NULL, 'd' },
- { "no-env", no_argument, NULL, 'e' },
- { "help", no_argument, NULL, 'h' },
- { "setsid", no_argument, NULL, 's' },
- { "unix-socket", required_argument, NULL, 'u' },
- { "working-dir", required_argument, NULL, 'w' },
- { "env", required_argument, NULL, 'E' },
- { NULL, 0, NULL, 0 }
-};
-
-static void
-usage()
-{
- puts (
-"NAME\n"
-" darwin-debug -- posix spawn a process that is stopped at the entry point\n"
-" for debugging.\n"
-"\n"
-"SYNOPSIS\n"
-" darwin-debug --unix-socket=<SOCKET> [--arch=<ARCH>] [--working-dir=<PATH>] [--disable-aslr] [--no-env] [--setsid] [--help] -- <PROGRAM> [<PROGRAM-ARG> <PROGRAM-ARG> ....]\n"
-"\n"
-"DESCRIPTION\n"
-" darwin-debug will exec itself into a child process <PROGRAM> that is\n"
-" halted for debugging. It does this by using posix_spawn() along with\n"
-" darwin specific posix_spawn flags that allows exec only (no fork), and\n"
-" stop at the program entry point. Any program arguments <PROGRAM-ARG> are\n"
-" passed on to the exec as the arguments for the new process. The current\n"
-" environment will be passed to the new process unless the \"--no-env\"\n"
-" option is used. A unix socket must be supplied using the\n"
-" --unix-socket=<SOCKET> option so the calling program can handshake with\n"
-" this process and get its process id.\n"
-"\n"
-"EXAMPLE\n"
-" darwin-debug --arch=i386 -- /bin/ls -al /tmp\n"
-);
- exit (1);
+#define streq(a, b) strcmp(a, b) == 0
+
+static struct option g_long_options[] = {
+ {"arch", required_argument, NULL, 'a'},
+ {"disable-aslr", no_argument, NULL, 'd'},
+ {"no-env", no_argument, NULL, 'e'},
+ {"help", no_argument, NULL, 'h'},
+ {"setsid", no_argument, NULL, 's'},
+ {"unix-socket", required_argument, NULL, 'u'},
+ {"working-dir", required_argument, NULL, 'w'},
+ {"env", required_argument, NULL, 'E'},
+ {NULL, 0, NULL, 0}};
+
+static void usage() {
+ puts("NAME\n"
+ " darwin-debug -- posix spawn a process that is stopped at the entry "
+ "point\n"
+ " for debugging.\n"
+ "\n"
+ "SYNOPSIS\n"
+ " darwin-debug --unix-socket=<SOCKET> [--arch=<ARCH>] "
+ "[--working-dir=<PATH>] [--disable-aslr] [--no-env] [--setsid] [--help] "
+ "-- <PROGRAM> [<PROGRAM-ARG> <PROGRAM-ARG> ....]\n"
+ "\n"
+ "DESCRIPTION\n"
+ " darwin-debug will exec itself into a child process <PROGRAM> that "
+ "is\n"
+ " halted for debugging. It does this by using posix_spawn() along "
+ "with\n"
+ " darwin specific posix_spawn flags that allows exec only (no fork), "
+ "and\n"
+ " stop at the program entry point. Any program arguments "
+ "<PROGRAM-ARG> are\n"
+ " passed on to the exec as the arguments for the new process. The "
+ "current\n"
+ " environment will be passed to the new process unless the "
+ "\"--no-env\"\n"
+ " option is used. A unix socket must be supplied using the\n"
+ " --unix-socket=<SOCKET> option so the calling program can handshake "
+ "with\n"
+ " this process and get its process id.\n"
+ "\n"
+ "EXAMPLE\n"
+ " darwin-debug --arch=i386 -- /bin/ls -al /tmp\n");
+ exit(1);
}
-static void
-exit_with_errno (int err, const char *prefix)
-{
- if (err)
- {
- fprintf (stderr,
- "%s%s",
- prefix ? prefix : "",
- strerror(err));
- exit (err);
- }
+static void exit_with_errno(int err, const char *prefix) {
+ if (err) {
+ fprintf(stderr, "%s%s", prefix ? prefix : "", strerror(err));
+ exit(err);
+ }
}
-pid_t
-posix_spawn_for_debug
-(
- char *const *argv,
- char *const *envp,
- const char *working_dir,
- cpu_type_t cpu_type,
- int disable_aslr)
-{
- pid_t pid = 0;
-
- const char *path = argv[0];
-
- posix_spawnattr_t attr;
-
- exit_with_errno (::posix_spawnattr_init (&attr), "::posix_spawnattr_init (&attr) error: ");
-
- // Here we are using a darwin specific feature that allows us to exec only
- // since we want this program to turn into the program we want to debug,
- // and also have the new program start suspended (right at __dyld_start)
- // so we can debug it
- short flags = POSIX_SPAWN_START_SUSPENDED | POSIX_SPAWN_SETEXEC | POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK;
-
- // Disable ASLR if we were asked to
- 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);
-
- // Set the flags we just made into our posix spawn attributes
- exit_with_errno (::posix_spawnattr_setflags (&attr, flags), "::posix_spawnattr_setflags (&attr, flags) error: ");
-
-
- // Another darwin specific thing here where we can select the architecture
- // of the binary we want to re-exec as.
- if (cpu_type != 0)
- {
- size_t ocount = 0;
- exit_with_errno (::posix_spawnattr_setbinpref_np (&attr, 1, &cpu_type, &ocount), "posix_spawnattr_setbinpref_np () error: ");
- }
-
- // I wish there was a posix_spawn flag to change the working directory of
- // the inferior process we will spawn, but there currently isn't. If there
- // ever is a better way to do this, we should use it. I would rather not
- // manually fork, chdir in the child process, and then posix_spawn with exec
- // as the whole reason for doing posix_spawn is to not hose anything up
- // after the fork and prior to the exec...
- if (working_dir)
- ::chdir (working_dir);
-
- exit_with_errno (::posix_spawnp (&pid, path, NULL, &attr, (char * const*)argv, (char * const*)envp), "posix_spawn() error: ");
-
- // This code will only be reached if the posix_spawn exec failed...
- ::posix_spawnattr_destroy (&attr);
-
- return pid;
+pid_t posix_spawn_for_debug(char *const *argv, char *const *envp,
+ const char *working_dir, cpu_type_t cpu_type,
+ int disable_aslr) {
+ pid_t pid = 0;
+
+ const char *path = argv[0];
+
+ posix_spawnattr_t attr;
+
+ exit_with_errno(::posix_spawnattr_init(&attr),
+ "::posix_spawnattr_init (&attr) error: ");
+
+ // Here we are using a darwin specific feature that allows us to exec only
+ // since we want this program to turn into the program we want to debug,
+ // and also have the new program start suspended (right at __dyld_start)
+ // so we can debug it
+ short flags = POSIX_SPAWN_START_SUSPENDED | POSIX_SPAWN_SETEXEC |
+ POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK;
+
+ // Disable ASLR if we were asked to
+ 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);
+
+ // Set the flags we just made into our posix spawn attributes
+ exit_with_errno(::posix_spawnattr_setflags(&attr, flags),
+ "::posix_spawnattr_setflags (&attr, flags) error: ");
+
+ // Another darwin specific thing here where we can select the architecture
+ // of the binary we want to re-exec as.
+ if (cpu_type != 0) {
+ size_t ocount = 0;
+ exit_with_errno(
+ ::posix_spawnattr_setbinpref_np(&attr, 1, &cpu_type, &ocount),
+ "posix_spawnattr_setbinpref_np () error: ");
+ }
+
+ // I wish there was a posix_spawn flag to change the working directory of
+ // the inferior process we will spawn, but there currently isn't. If there
+ // ever is a better way to do this, we should use it. I would rather not
+ // manually fork, chdir in the child process, and then posix_spawn with exec
+ // as the whole reason for doing posix_spawn is to not hose anything up
+ // after the fork and prior to the exec...
+ if (working_dir)
+ ::chdir(working_dir);
+
+ exit_with_errno(::posix_spawnp(&pid, path, NULL, &attr, (char *const *)argv,
+ (char *const *)envp),
+ "posix_spawn() error: ");
+
+ // This code will only be reached if the posix_spawn exec failed...
+ ::posix_spawnattr_destroy(&attr);
+
+ return pid;
}
+int main(int argc, char *const *argv, char *const *envp, const char **apple) {
+#if defined(DEBUG_LLDB_LAUNCHER)
+ const char *program_name = strrchr(apple[0], '/');
+
+ if (program_name)
+ program_name++; // Skip the last slash..
+ else
+ program_name = apple[0];
-int main (int argc, char *const *argv, char *const *envp, const char **apple)
-{
-#if defined (DEBUG_LLDB_LAUNCHER)
- const char *program_name = strrchr(apple[0], '/');
-
- if (program_name)
- program_name++; // Skip the last slash..
- else
- program_name = apple[0];
-
- printf("%s called with:\n", program_name);
- for (int i=0; i<argc; ++i)
- printf("argv[%u] = '%s'\n", i, argv[i]);
+ printf("%s called with:\n", program_name);
+ for (int i = 0; i < argc; ++i)
+ printf("argv[%u] = '%s'\n", i, argv[i]);
#endif
- cpu_type_t cpu_type = 0;
- bool show_usage = false;
- int ch;
- int disable_aslr = 0; // By default we disable ASLR
- bool pass_env = true;
- std::string unix_socket_name;
- std::string working_dir;
-
+ cpu_type_t cpu_type = 0;
+ bool show_usage = false;
+ int ch;
+ int disable_aslr = 0; // By default we disable ASLR
+ bool pass_env = true;
+ std::string unix_socket_name;
+ std::string working_dir;
+
#if __GLIBC__
- optind = 0;
+ optind = 0;
#else
- optreset = 1;
- optind = 1;
-#endif
-
- while ((ch = getopt_long_only(argc, argv, "a:deE:hsu:?", g_long_options, NULL)) != -1)
- {
- switch (ch)
- {
- case 0:
- break;
-
- case 'a': // "-a i386" or "--arch=i386"
- if (optarg)
- {
- if (streq (optarg, "i386"))
- cpu_type = CPU_TYPE_I386;
- else if (streq (optarg, "x86_64"))
- cpu_type = CPU_TYPE_X86_64;
- else if (streq (optarg, "x86_64h"))
- cpu_type = 0; // Don't set CPU type when we have x86_64h
- else if (strstr (optarg, "arm") == optarg)
- cpu_type = CPU_TYPE_ARM;
- else
- {
- ::fprintf (stderr, "error: unsupported cpu type '%s'\n", optarg);
- ::exit (1);
- }
- }
- break;
-
- case 'd':
- disable_aslr = 1;
- break;
-
- case 'e':
- pass_env = false;
- break;
-
- case 'E':
- {
- // Since we will exec this program into our new program, we can just set environment
- // variables in this process and they will make it into the child process.
- std::string name;
- std::string value;
- const char *equal_pos = strchr (optarg, '=');
- if (equal_pos)
- {
- name.assign (optarg, equal_pos - optarg);
- value.assign (equal_pos + 1);
- }
- else
- {
- name = optarg;
- }
- ::setenv (name.c_str(), value.c_str(), 1);
- }
- break;
-
- case 's':
- // Create a new session to avoid having control-C presses kill our current
- // terminal session when this program is launched from a .command file
- ::setsid();
- break;
-
- case 'u':
- unix_socket_name.assign (optarg);
- break;
-
- case 'w':
- {
- struct stat working_dir_stat;
- if (stat (optarg, &working_dir_stat) == 0)
- working_dir.assign (optarg);
- else
- ::fprintf(stderr, "warning: working directory doesn't exist: '%s'\n", optarg);
- }
- break;
-
- case 'h':
- case '?':
- default:
- show_usage = true;
- break;
- }
- }
- argc -= optind;
- argv += optind;
-
- if (show_usage || argc <= 0 || unix_socket_name.empty())
- usage();
-
-#if defined (DEBUG_LLDB_LAUNCHER)
- printf ("\n%s post options:\n", program_name);
- for (int i=0; i<argc; ++i)
- printf ("argv[%u] = '%s'\n", i, argv[i]);
+ optreset = 1;
+ optind = 1;
#endif
- // Open the socket that was passed in as an option
- 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);
+ while ((ch = getopt_long_only(argc, argv, "a:deE:hsu:?", g_long_options,
+ NULL)) != -1) {
+ switch (ch) {
+ case 0:
+ break;
+
+ case 'a': // "-a i386" or "--arch=i386"
+ if (optarg) {
+ if (streq(optarg, "i386"))
+ cpu_type = CPU_TYPE_I386;
+ else if (streq(optarg, "x86_64"))
+ cpu_type = CPU_TYPE_X86_64;
+ else if (streq(optarg, "x86_64h"))
+ cpu_type = 0; // Don't set CPU type when we have x86_64h
+ else if (strstr(optarg, "arm") == optarg)
+ cpu_type = CPU_TYPE_ARM;
+ else {
+ ::fprintf(stderr, "error: unsupported cpu type '%s'\n", optarg);
+ ::exit(1);
+ }
+ }
+ break;
+
+ case 'd':
+ disable_aslr = 1;
+ break;
+
+ case 'e':
+ pass_env = false;
+ break;
+
+ case 'E': {
+ // Since we will exec this program into our new program, we can just set
+ // environment
+ // variables in this process and they will make it into the child process.
+ std::string name;
+ std::string value;
+ const char *equal_pos = strchr(optarg, '=');
+ if (equal_pos) {
+ name.assign(optarg, equal_pos - optarg);
+ value.assign(equal_pos + 1);
+ } else {
+ name = optarg;
+ }
+ ::setenv(name.c_str(), value.c_str(), 1);
+ } break;
+
+ case 's':
+ // Create a new session to avoid having control-C presses kill our current
+ // terminal session when this program is launched from a .command file
+ ::setsid();
+ break;
+
+ case 'u':
+ unix_socket_name.assign(optarg);
+ break;
+
+ case 'w': {
+ struct stat working_dir_stat;
+ if (stat(optarg, &working_dir_stat) == 0)
+ working_dir.assign(optarg);
+ else
+ ::fprintf(stderr, "warning: working directory doesn't exist: '%s'\n",
+ optarg);
+ } break;
+
+ case 'h':
+ case '?':
+ default:
+ show_usage = true;
+ break;
}
+ }
+ argc -= optind;
+ argv += optind;
- saddr_un.sun_family = AF_UNIX;
- ::strncpy(saddr_un.sun_path, unix_socket_name.c_str(), 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 (show_usage || argc <= 0 || unix_socket_name.empty())
+ usage();
- if (::connect (s, (struct sockaddr *)&saddr_un, SUN_LEN (&saddr_un)) < 0)
- {
- perror("error: connect (socket, &saddr_un, saddr_un_len)");
- exit(1);
- }
-
- // We were able to connect to the socket, now write our PID so whomever
- // launched us will know this process's ID
- char pid_str[64];
- const int pid_str_len = ::snprintf (pid_str, sizeof(pid_str), "%i", ::getpid());
- const int 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);
- }
-
- // We are done with the socket
- close (s);
+#if defined(DEBUG_LLDB_LAUNCHER)
+ printf("\n%s post options:\n", program_name);
+ for (int i = 0; i < argc; ++i)
+ printf("argv[%u] = '%s'\n", i, argv[i]);
+#endif
- system("clear");
- printf ("Launching: '%s'\n", argv[0]);
- if (working_dir.empty())
- {
- char cwd[PATH_MAX];
- const char *cwd_ptr = getcwd(cwd, sizeof(cwd));
- printf ("Working directory: '%s'\n", cwd_ptr);
- }
- else
- {
- printf ("Working directory: '%s'\n", working_dir.c_str());
- }
- printf ("%i arguments:\n", argc);
-
- for (int i=0; i<argc; ++i)
- printf ("argv[%u] = '%s'\n", i, argv[i]);
-
- // Now we posix spawn to exec this process into the inferior that we want
- // to debug.
- posix_spawn_for_debug (argv,
- pass_env ? *_NSGetEnviron() : NULL, // Pass current environment as we may have modified it if "--env" options was used, do NOT pass "envp" here
- working_dir.empty() ? NULL : working_dir.c_str(),
- cpu_type,
- disable_aslr);
-
- return 0;
+ // Open the socket that was passed in as an option
+ 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;
+ ::strncpy(saddr_un.sun_path, unix_socket_name.c_str(),
+ 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, SUN_LEN(&saddr_un)) < 0) {
+ perror("error: connect (socket, &saddr_un, saddr_un_len)");
+ exit(1);
+ }
+
+ // We were able to connect to the socket, now write our PID so whomever
+ // launched us will know this process's ID
+ char pid_str[64];
+ const int pid_str_len =
+ ::snprintf(pid_str, sizeof(pid_str), "%i", ::getpid());
+ const int 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);
+ }
+
+ // We are done with the socket
+ close(s);
+
+ system("clear");
+ printf("Launching: '%s'\n", argv[0]);
+ if (working_dir.empty()) {
+ char cwd[PATH_MAX];
+ const char *cwd_ptr = getcwd(cwd, sizeof(cwd));
+ printf("Working directory: '%s'\n", cwd_ptr);
+ } else {
+ printf("Working directory: '%s'\n", working_dir.c_str());
+ }
+ printf("%i arguments:\n", argc);
+
+ for (int i = 0; i < argc; ++i)
+ printf("argv[%u] = '%s'\n", i, argv[i]);
+
+ // Now we posix spawn to exec this process into the inferior that we want
+ // to debug.
+ posix_spawn_for_debug(
+ argv,
+ pass_env ? *_NSGetEnviron() : NULL, // Pass current environment as we may
+ // have modified it if "--env" options
+ // was used, do NOT pass "envp" here
+ working_dir.empty() ? NULL : working_dir.c_str(), cpu_type, disable_aslr);
+
+ return 0;
}
#endif // #if defined (__APPLE__)
-
diff --git a/tools/darwin-threads/examine-threads.c b/tools/darwin-threads/examine-threads.c
index 07212e999f99..5d965140cf8b 100644
--- a/tools/darwin-threads/examine-threads.c
+++ b/tools/darwin-threads/examine-threads.c
@@ -1,291 +1,266 @@
+#include <ctype.h>
+#include <dispatch/dispatch.h>
+#include <errno.h>
+#include <libproc.h>
+#include <mach/mach.h>
+#include <mach/task_info.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <mach/mach.h>
-#include <mach/task_info.h>
-#include <time.h>
#include <sys/sysctl.h>
-#include <ctype.h>
-#include <libproc.h>
-#include <errno.h>
-#include <dispatch/dispatch.h>
+#include <time.h>
// from System.framework/Versions/B/PrivateHeaders/sys/codesign.h
-#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);
+#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);
/* Step through the process table, find a matching process name, return
the pid of that matched process.
If there are multiple processes with that name, issue a warning on stdout
and return the highest numbered process.
The proc_pidpath() call is used which gets the full process name including
- directories to the executable and the full (longer than 16 character)
+ directories to the executable and the full (longer than 16 character)
executable name. */
-pid_t
-get_pid_for_process_name (const char *procname)
-{
- int process_count = proc_listpids (PROC_ALL_PIDS, 0, NULL, 0) / sizeof (pid_t);
- if (process_count < 1)
- {
- printf ("Only found %d processes running!\n", process_count);
- exit (1);
- }
+pid_t get_pid_for_process_name(const char *procname) {
+ int process_count = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0) / sizeof(pid_t);
+ if (process_count < 1) {
+ printf("Only found %d processes running!\n", process_count);
+ exit(1);
+ }
// Allocate a few extra slots in case new processes are spawned
- int all_pids_size = sizeof (pid_t) * (process_count + 3);
- pid_t *all_pids = (pid_t *) malloc (all_pids_size);
+ int all_pids_size = sizeof(pid_t) * (process_count + 3);
+ pid_t *all_pids = (pid_t *)malloc(all_pids_size);
- // re-set process_count in case the number of processes changed (got smaller; we won't do bigger)
- process_count = proc_listpids (PROC_ALL_PIDS, 0, all_pids, all_pids_size) / sizeof (pid_t);
+ // re-set process_count in case the number of processes changed (got smaller;
+ // we won't do bigger)
+ process_count =
+ proc_listpids(PROC_ALL_PIDS, 0, all_pids, all_pids_size) / sizeof(pid_t);
int i;
pid_t highest_pid = 0;
int match_count = 0;
- for (i = 1; i < process_count; i++)
- {
- char pidpath[PATH_MAX];
- int pidpath_len = proc_pidpath (all_pids[i], pidpath, sizeof (pidpath));
- if (pidpath_len == 0)
- continue;
- char *j = strrchr (pidpath, '/');
- if ((j == NULL && strcmp (procname, pidpath) == 0)
- || (j != NULL && strcmp (j + 1, procname) == 0))
- {
- match_count++;
- if (all_pids[i] > highest_pid)
- highest_pid = all_pids[i];
- }
+ for (i = 1; i < process_count; i++) {
+ char pidpath[PATH_MAX];
+ int pidpath_len = proc_pidpath(all_pids[i], pidpath, sizeof(pidpath));
+ if (pidpath_len == 0)
+ continue;
+ char *j = strrchr(pidpath, '/');
+ if ((j == NULL && strcmp(procname, pidpath) == 0) ||
+ (j != NULL && strcmp(j + 1, procname) == 0)) {
+ match_count++;
+ if (all_pids[i] > highest_pid)
+ highest_pid = all_pids[i];
}
- free (all_pids);
+ }
+ free(all_pids);
- if (match_count == 0)
- {
- printf ("Did not find process '%s'.\n", procname);
- exit (1);
- }
- if (match_count > 1)
- {
- printf ("Warning: More than one process '%s'!\n", procname);
- printf (" defaulting to the highest-pid one, %d\n", highest_pid);
- }
+ if (match_count == 0) {
+ printf("Did not find process '%s'.\n", procname);
+ exit(1);
+ }
+ if (match_count > 1) {
+ printf("Warning: More than one process '%s'!\n", procname);
+ printf(" defaulting to the highest-pid one, %d\n", highest_pid);
+ }
return highest_pid;
}
-/* Given a pid, get the full executable name (including directory
+/* Given a pid, get the full executable name (including directory
paths and the longer-than-16-chars executable name) and return
the basename of that (i.e. do not include the directory components).
This function mallocs the memory for the string it returns;
the caller must free this memory. */
-const char *
-get_process_name_for_pid (pid_t pid)
-{
+const char *get_process_name_for_pid(pid_t pid) {
char tmp_name[PATH_MAX];
- if (proc_pidpath (pid, tmp_name, sizeof (tmp_name)) == 0)
- {
- printf ("Could not find process with pid of %d\n", (int) pid);
- exit (1);
- }
- if (strrchr (tmp_name, '/'))
- return strdup (strrchr (tmp_name, '/') + 1);
+ if (proc_pidpath(pid, tmp_name, sizeof(tmp_name)) == 0) {
+ printf("Could not find process with pid of %d\n", (int)pid);
+ exit(1);
+ }
+ if (strrchr(tmp_name, '/'))
+ return strdup(strrchr(tmp_name, '/') + 1);
else
- return strdup (tmp_name);
+ return strdup(tmp_name);
}
/* Get a struct kinfo_proc structure for a given pid.
Process name is required for error printing.
- Gives you the current state of the process and whether it is being debugged by anyone.
+ Gives you the current state of the process and whether it is being debugged
+ by anyone.
memory is malloc()'ed for the returned struct kinfo_proc
and must be freed by the caller. */
-struct kinfo_proc *
-get_kinfo_proc_for_pid (pid_t pid, const char *process_name)
-{
- struct kinfo_proc *kinfo = (struct kinfo_proc *) malloc (sizeof (struct kinfo_proc));
- int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid };
- size_t len = sizeof (struct kinfo_proc);
- if (sysctl (mib, sizeof (mib) / sizeof (mib[0]), kinfo, &len, NULL, 0) != 0)
- {
- free ((void *) kinfo);
- printf ("Could not get kinfo_proc for pid %d\n", (int) pid);
- exit (1);
- }
+struct kinfo_proc *get_kinfo_proc_for_pid(pid_t pid, const char *process_name) {
+ struct kinfo_proc *kinfo =
+ (struct kinfo_proc *)malloc(sizeof(struct kinfo_proc));
+ int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid};
+ size_t len = sizeof(struct kinfo_proc);
+ if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), kinfo, &len, NULL, 0) != 0) {
+ free((void *)kinfo);
+ printf("Could not get kinfo_proc for pid %d\n", (int)pid);
+ exit(1);
+ }
return kinfo;
}
/* Get the basic information (thread_basic_info_t) about a given
- thread.
- Gives you the suspend count; thread state; user time; system time; sleep time; etc.
+ thread.
+ Gives you the suspend count; thread state; user time; system time; sleep
+ time; etc.
The return value is a pointer to malloc'ed memory - it is the caller's
responsibility to free it. */
-thread_basic_info_t
-get_thread_basic_info (thread_t thread)
-{
+thread_basic_info_t get_thread_basic_info(thread_t thread) {
kern_return_t kr;
- integer_t *thinfo = (integer_t *) malloc (sizeof (integer_t) * THREAD_INFO_MAX);
+ integer_t *thinfo = (integer_t *)malloc(sizeof(integer_t) * THREAD_INFO_MAX);
mach_msg_type_number_t thread_info_count = THREAD_INFO_MAX;
- kr = thread_info (thread, THREAD_BASIC_INFO,
- (thread_info_t) thinfo, &thread_info_count);
- if (kr != KERN_SUCCESS)
- {
- printf ("Error - unable to get basic thread info for a thread\n");
- exit (1);
- }
- return (thread_basic_info_t) thinfo;
+ kr = thread_info(thread, THREAD_BASIC_INFO, (thread_info_t)thinfo,
+ &thread_info_count);
+ if (kr != KERN_SUCCESS) {
+ printf("Error - unable to get basic thread info for a thread\n");
+ exit(1);
+ }
+ return (thread_basic_info_t)thinfo;
}
-/* Get the thread identifier info (thread_identifier_info_data_t)
- about a given thread.
- Gives you the system-wide unique thread number; the pthread identifier number
+/* Get the thread identifier info (thread_identifier_info_data_t)
+ about a given thread.
+ Gives you the system-wide unique thread number; the pthread identifier number
*/
-thread_identifier_info_data_t
-get_thread_identifier_info (thread_t thread)
-{
+thread_identifier_info_data_t get_thread_identifier_info(thread_t thread) {
kern_return_t kr;
thread_identifier_info_data_t tident;
mach_msg_type_number_t tident_count = THREAD_IDENTIFIER_INFO_COUNT;
- kr = thread_info (thread, THREAD_IDENTIFIER_INFO,
- (thread_info_t) &tident, &tident_count);
- if (kr != KERN_SUCCESS)
- {
- printf ("Error - unable to get thread ident for a thread\n");
- exit (1);
- }
+ kr = thread_info(thread, THREAD_IDENTIFIER_INFO, (thread_info_t)&tident,
+ &tident_count);
+ if (kr != KERN_SUCCESS) {
+ printf("Error - unable to get thread ident for a thread\n");
+ exit(1);
+ }
return tident;
}
-
-/* Given a mach port # (in the examine-threads mach port namespace) for a thread,
- find the mach port # in the inferior program's port namespace.
+/* Given a mach port # (in the examine-threads mach port namespace) for a
+ thread,
+ find the mach port # in the inferior program's port namespace.
Sets inferior_port if successful.
Returns true if successful, false if unable to find the port number. */
-bool
-inferior_namespace_mach_port_num (task_t task, thread_t examine_threads_port, thread_t *inferior_port)
-{
- kern_return_t retval;
- mach_port_name_array_t names;
- mach_msg_type_number_t nameslen;
- mach_port_type_array_t types;
- mach_msg_type_number_t typeslen;
-
- if (inferior_port == NULL)
- return false;
-
- retval = mach_port_names (task, &names, &nameslen, &types, &typeslen);
- if (retval != KERN_SUCCESS)
- {
- printf ("Error - unable to get mach port names for inferior.\n");
- return false;
- }
- int i = 0;
- for (i = 0; i < nameslen; i++)
- {
- mach_port_t local_name;
- mach_msg_type_name_t local_type;
- retval = mach_port_extract_right (task, names[i], MACH_MSG_TYPE_COPY_SEND, &local_name, &local_type);
- if (retval == KERN_SUCCESS)
- {
- mach_port_deallocate (mach_task_self(), local_name);
- if (local_name == examine_threads_port)
- {
- *inferior_port = names[i];
- vm_deallocate (mach_task_self (), (vm_address_t) names, nameslen * sizeof (mach_port_t));
- vm_deallocate (mach_task_self (), (vm_address_t) types, typeslen * sizeof (mach_port_t));
- return true;
- }
- }
- }
- vm_deallocate (mach_task_self (), (vm_address_t) names, nameslen * sizeof (mach_port_t));
- vm_deallocate (mach_task_self (), (vm_address_t) types, typeslen * sizeof (mach_port_t));
+bool inferior_namespace_mach_port_num(task_t task,
+ thread_t examine_threads_port,
+ thread_t *inferior_port) {
+ kern_return_t retval;
+ mach_port_name_array_t names;
+ mach_msg_type_number_t nameslen;
+ mach_port_type_array_t types;
+ mach_msg_type_number_t typeslen;
+
+ if (inferior_port == NULL)
+ return false;
+
+ retval = mach_port_names(task, &names, &nameslen, &types, &typeslen);
+ if (retval != KERN_SUCCESS) {
+ printf("Error - unable to get mach port names for inferior.\n");
return false;
+ }
+ int i = 0;
+ for (i = 0; i < nameslen; i++) {
+ mach_port_t local_name;
+ mach_msg_type_name_t local_type;
+ retval = mach_port_extract_right(task, names[i], MACH_MSG_TYPE_COPY_SEND,
+ &local_name, &local_type);
+ if (retval == KERN_SUCCESS) {
+ mach_port_deallocate(mach_task_self(), local_name);
+ if (local_name == examine_threads_port) {
+ *inferior_port = names[i];
+ vm_deallocate(mach_task_self(), (vm_address_t)names,
+ nameslen * sizeof(mach_port_t));
+ vm_deallocate(mach_task_self(), (vm_address_t)types,
+ typeslen * sizeof(mach_port_t));
+ return true;
+ }
+ }
+ }
+ vm_deallocate(mach_task_self(), (vm_address_t)names,
+ nameslen * sizeof(mach_port_t));
+ vm_deallocate(mach_task_self(), (vm_address_t)types,
+ typeslen * sizeof(mach_port_t));
+ return false;
}
/* Get the current pc value for a given thread. */
-uint64_t
-get_current_pc (thread_t thread, int *wordsize)
-{
- kern_return_t kr ;
+uint64_t get_current_pc(thread_t thread, int *wordsize) {
+ kern_return_t kr;
-#if defined (__x86_64__) || defined (__i386__)
+#if defined(__x86_64__) || defined(__i386__)
x86_thread_state_t gp_regs;
mach_msg_type_number_t gp_count = x86_THREAD_STATE_COUNT;
- kr = thread_get_state (thread, x86_THREAD_STATE,
- (thread_state_t) &gp_regs, &gp_count);
- if (kr != KERN_SUCCESS)
- {
- printf ("Error - unable to get registers for a thread\n");
- exit (1);
- }
+ kr = thread_get_state(thread, x86_THREAD_STATE, (thread_state_t)&gp_regs,
+ &gp_count);
+ if (kr != KERN_SUCCESS) {
+ printf("Error - unable to get registers for a thread\n");
+ exit(1);
+ }
- if (gp_regs.tsh.flavor == x86_THREAD_STATE64)
- {
- *wordsize = 8;
- return gp_regs.uts.ts64.__rip;
- }
- else
- {
- *wordsize = 4;
- return gp_regs.uts.ts32.__eip;
- }
+ if (gp_regs.tsh.flavor == x86_THREAD_STATE64) {
+ *wordsize = 8;
+ return gp_regs.uts.ts64.__rip;
+ } else {
+ *wordsize = 4;
+ return gp_regs.uts.ts32.__eip;
+ }
#endif
-#if defined (__arm__)
+#if defined(__arm__)
arm_thread_state_t gp_regs;
mach_msg_type_number_t gp_count = ARM_THREAD_STATE_COUNT;
- kr = thread_get_state (thread, ARM_THREAD_STATE,
- (thread_state_t) &gp_regs, &gp_count);
- if (kr != KERN_SUCCESS)
- {
- printf ("Error - unable to get registers for a thread\n");
- exit (1);
- }
+ kr = thread_get_state(thread, ARM_THREAD_STATE, (thread_state_t)&gp_regs,
+ &gp_count);
+ if (kr != KERN_SUCCESS) {
+ printf("Error - unable to get registers for a thread\n");
+ exit(1);
+ }
*wordsize = 4;
return gp_regs.__pc;
#endif
-#if defined (__arm64__)
+#if defined(__arm64__)
arm_thread_state64_t gp_regs;
mach_msg_type_number_t gp_count = ARM_THREAD_STATE64_COUNT;
- kr = thread_get_state (thread, ARM_THREAD_STATE64,
- (thread_state_t) &gp_regs, &gp_count);
- if (kr != KERN_SUCCESS)
- {
- printf ("Error - unable to get registers for a thread\n");
- exit (1);
- }
+ kr = thread_get_state(thread, ARM_THREAD_STATE64, (thread_state_t)&gp_regs,
+ &gp_count);
+ if (kr != KERN_SUCCESS) {
+ printf("Error - unable to get registers for a thread\n");
+ exit(1);
+ }
*wordsize = 8;
return gp_regs.__pc;
#endif
-
}
/* Get the proc_threadinfo for a given thread.
- Gives you the thread name, if set; current and max priorities.
+ Gives you the thread name, if set; current and max priorities.
Returns 1 if successful
Returns 0 if proc_pidinfo() failed
*/
-int
-get_proc_threadinfo (pid_t pid, uint64_t thread_handle, struct proc_threadinfo *pth)
-{
+int get_proc_threadinfo(pid_t pid, uint64_t thread_handle,
+ struct proc_threadinfo *pth) {
pth->pth_name[0] = '\0';
- int ret = proc_pidinfo (pid, PROC_PIDTHREADINFO, thread_handle,
- pth, sizeof (struct proc_threadinfo));
+ int ret = proc_pidinfo(pid, PROC_PIDTHREADINFO, thread_handle, pth,
+ sizeof(struct proc_threadinfo));
if (ret != 0)
return 1;
else
return 0;
}
-int
-main (int argc, char **argv)
-{
+int main(int argc, char **argv) {
kern_return_t kr;
task_t task;
pid_t pid = 0;
@@ -294,221 +269,239 @@ main (int argc, char **argv)
int do_loop = 0;
int verbose = 0;
int resume_when_done = 0;
- mach_port_t mytask = mach_task_self ();
+ mach_port_t mytask = mach_task_self();
- if (argc != 2 && argc != 3 && argc != 4 && argc != 5)
- {
- printf ("Usage: tdump [-l] [-v] [-r] pid/procname\n");
- exit (1);
- }
-
- if (argc == 3 || argc == 4)
- {
- int i = 1;
- while (i < argc - 1)
- {
- if (strcmp (argv[i], "-l") == 0)
- do_loop = 1;
- if (strcmp (argv[i], "-v") == 0)
- verbose = 1;
- if (strcmp (argv[i], "-r") == 0)
- resume_when_done++;
- i++;
- }
+ if (argc != 2 && argc != 3 && argc != 4 && argc != 5) {
+ printf("Usage: tdump [-l] [-v] [-r] pid/procname\n");
+ exit(1);
+ }
+
+ if (argc == 3 || argc == 4) {
+ int i = 1;
+ while (i < argc - 1) {
+ if (strcmp(argv[i], "-l") == 0)
+ do_loop = 1;
+ if (strcmp(argv[i], "-v") == 0)
+ verbose = 1;
+ if (strcmp(argv[i], "-r") == 0)
+ resume_when_done++;
+ i++;
}
+ }
char *c = argv[argc - 1];
- if (*c == '\0')
- {
- printf ("Usage: tdump [-l] [-v] pid/procname\n");
- exit (1);
- }
- while (*c != '\0')
- {
- if (!isdigit (*c))
- {
- arg_is_procname = 1;
- procname = argv[argc - 1];
- break;
- }
- c++;
+ if (*c == '\0') {
+ printf("Usage: tdump [-l] [-v] pid/procname\n");
+ exit(1);
+ }
+ while (*c != '\0') {
+ if (!isdigit(*c)) {
+ arg_is_procname = 1;
+ procname = argv[argc - 1];
+ break;
}
+ c++;
+ }
- if (arg_is_procname && procname)
- {
- pid = get_pid_for_process_name (procname);
- }
- else
- {
- errno = 0;
- pid = (pid_t) strtol (argv[argc - 1], NULL, 10);
- if (pid == 0 && errno == EINVAL)
- {
- printf ("Usage: tdump [-l] [-v] pid/procname\n");
- exit (1);
- }
+ if (arg_is_procname && procname) {
+ pid = get_pid_for_process_name(procname);
+ } else {
+ errno = 0;
+ pid = (pid_t)strtol(argv[argc - 1], NULL, 10);
+ if (pid == 0 && errno == EINVAL) {
+ printf("Usage: tdump [-l] [-v] pid/procname\n");
+ exit(1);
}
+ }
- const char *process_name = get_process_name_for_pid (pid);
+ const char *process_name = get_process_name_for_pid(pid);
- // At this point "pid" is the process id and "process_name" is the process name
- // Now we have to get the process list from the kernel (which only has the truncated
+ // At this point "pid" is the process id and "process_name" is the process
+ // name
+ // Now we have to get the process list from the kernel (which only has the
+ // truncated
// 16 char names)
- struct kinfo_proc *kinfo = get_kinfo_proc_for_pid (pid, process_name);
+ struct kinfo_proc *kinfo = get_kinfo_proc_for_pid(pid, process_name);
- printf ("pid %d (%s) is currently ", pid, process_name);
+ printf("pid %d (%s) is currently ", pid, process_name);
switch (kinfo->kp_proc.p_stat) {
- case SIDL: printf ("being created by fork"); break;
- case SRUN: printf ("runnable"); break;
- case SSLEEP: printf ("sleeping on an address"); break;
- case SSTOP: printf ("suspended"); break;
- case SZOMB: printf ("zombie state - awaiting collection by parent"); break;
- default: printf ("unknown");
+ case SIDL:
+ printf("being created by fork");
+ break;
+ case SRUN:
+ printf("runnable");
+ break;
+ case SSLEEP:
+ printf("sleeping on an address");
+ break;
+ case SSTOP:
+ printf("suspended");
+ break;
+ case SZOMB:
+ printf("zombie state - awaiting collection by parent");
+ break;
+ default:
+ printf("unknown");
}
if (kinfo->kp_proc.p_flag & P_TRACED)
- printf (" and is being debugged.");
- free ((void *) kinfo);
+ printf(" and is being debugged.");
+ free((void *)kinfo);
- printf ("\n");
+ printf("\n");
int csops_flags = 0;
- if (csops (pid, CS_OPS_STATUS, &csops_flags, sizeof (csops_flags)) != -1
- && (csops_flags & CS_RESTRICT))
- {
- printf ("pid %d (%s) is restricted so nothing can attach to it.\n", pid, process_name);
+ if (csops(pid, CS_OPS_STATUS, &csops_flags, sizeof(csops_flags)) != -1 &&
+ (csops_flags & CS_RESTRICT)) {
+ printf("pid %d (%s) is restricted so nothing can attach to it.\n", pid,
+ process_name);
}
- kr = task_for_pid (mach_task_self (), pid, &task);
- if (kr != KERN_SUCCESS)
- {
- printf ("Error - unable to task_for_pid()\n");
- exit (1);
- }
+ kr = task_for_pid(mach_task_self(), pid, &task);
+ if (kr != KERN_SUCCESS) {
+ printf("Error - unable to task_for_pid()\n");
+ exit(1);
+ }
struct task_basic_info info;
unsigned int info_count = TASK_BASIC_INFO_COUNT;
- kr = task_info (task, TASK_BASIC_INFO, (task_info_t) &info, &info_count);
- if (kr != KERN_SUCCESS)
- {
- printf ("Error - unable to call task_info.\n");
- exit (1);
- }
- printf ("Task suspend count: %d.\n", info.suspend_count);
+ kr = task_info(task, TASK_BASIC_INFO, (task_info_t)&info, &info_count);
+ if (kr != KERN_SUCCESS) {
+ printf("Error - unable to call task_info.\n");
+ exit(1);
+ }
+ printf("Task suspend count: %d.\n", info.suspend_count);
- struct timespec *rqtp = (struct timespec *) malloc (sizeof (struct timespec));
+ struct timespec *rqtp = (struct timespec *)malloc(sizeof(struct timespec));
rqtp->tv_sec = 0;
rqtp->tv_nsec = 150000000;
int loop_cnt = 1;
- do
- {
- int i;
- if (do_loop)
- printf ("Iteration %d:\n", loop_cnt++);
- thread_array_t thread_list;
- mach_msg_type_number_t thread_count;
-
- kr = task_threads (task, &thread_list, &thread_count);
- if (kr != KERN_SUCCESS)
- {
- printf ("Error - unable to get thread list\n");
- exit (1);
+ do {
+ int i;
+ if (do_loop)
+ printf("Iteration %d:\n", loop_cnt++);
+ thread_array_t thread_list;
+ mach_msg_type_number_t thread_count;
+
+ kr = task_threads(task, &thread_list, &thread_count);
+ if (kr != KERN_SUCCESS) {
+ printf("Error - unable to get thread list\n");
+ exit(1);
+ }
+ printf("pid %d has %d threads\n", pid, thread_count);
+ if (verbose)
+ printf("\n");
+
+ for (i = 0; i < thread_count; i++) {
+ thread_basic_info_t basic_info = get_thread_basic_info(thread_list[i]);
+
+ thread_identifier_info_data_t identifier_info =
+ get_thread_identifier_info(thread_list[i]);
+
+ int wordsize;
+ uint64_t pc = get_current_pc(thread_list[i], &wordsize);
+
+ printf("thread #%d, system-wide-unique-tid %lld, suspend count is %d, ",
+ i, identifier_info.thread_id, basic_info->suspend_count);
+ if (wordsize == 8)
+ printf("pc 0x%016llx, ", pc);
+ else
+ printf("pc 0x%08llx, ", pc);
+ printf("run state is ");
+ switch (basic_info->run_state) {
+ case TH_STATE_RUNNING:
+ puts("running");
+ break;
+ case TH_STATE_STOPPED:
+ puts("stopped");
+ break;
+ case TH_STATE_WAITING:
+ puts("waiting");
+ break;
+ case TH_STATE_UNINTERRUPTIBLE:
+ puts("uninterruptible");
+ break;
+ case TH_STATE_HALTED:
+ puts("halted");
+ break;
+ default:
+ puts("");
+ }
+
+ printf(" pthread handle id 0x%llx (not the same value as "
+ "pthread_self() returns)\n",
+ (uint64_t)identifier_info.thread_handle);
+
+ struct proc_threadinfo pth;
+ int proc_threadinfo_succeeded =
+ get_proc_threadinfo(pid, identifier_info.thread_handle, &pth);
+
+ if (proc_threadinfo_succeeded && pth.pth_name[0] != '\0')
+ printf(" thread name '%s'\n", pth.pth_name);
+
+ printf(" libdispatch qaddr 0x%llx (not the same as the "
+ "dispatch_queue_t token)\n",
+ (uint64_t)identifier_info.dispatch_qaddr);
+
+ if (verbose) {
+ printf(
+ " (examine-threads port namespace) mach port # 0x%4.4x\n",
+ (int)thread_list[i]);
+ thread_t mach_port_inferior_namespace;
+ if (inferior_namespace_mach_port_num(task, thread_list[i],
+ &mach_port_inferior_namespace))
+ printf(" (inferior port namepsace) mach port # 0x%4.4x\n",
+ (int)mach_port_inferior_namespace);
+ printf(" user %d.%06ds, system %d.%06ds",
+ basic_info->user_time.seconds,
+ basic_info->user_time.microseconds,
+ basic_info->system_time.seconds,
+ basic_info->system_time.microseconds);
+ if (basic_info->cpu_usage > 0) {
+ float cpu_percentage = basic_info->cpu_usage / 10.0;
+ printf(", using %.1f%% cpu currently", cpu_percentage);
}
- printf ("pid %d has %d threads\n", pid, thread_count);
- if (verbose)
- printf ("\n");
-
- for (i = 0; i < thread_count; i++)
- {
- thread_basic_info_t basic_info = get_thread_basic_info (thread_list[i]);
-
- thread_identifier_info_data_t identifier_info = get_thread_identifier_info (thread_list[i]);
-
- int wordsize;
- uint64_t pc = get_current_pc (thread_list[i], &wordsize);
-
- printf ("thread #%d, system-wide-unique-tid %lld, suspend count is %d, ", i,
- identifier_info.thread_id,
- basic_info->suspend_count);
- if (wordsize == 8)
- printf ("pc 0x%016llx, ", pc);
- else
- printf ("pc 0x%08llx, ", pc);
- printf ("run state is ");
- switch (basic_info->run_state) {
- case TH_STATE_RUNNING: puts ("running"); break;
- case TH_STATE_STOPPED: puts ("stopped"); break;
- case TH_STATE_WAITING: puts ("waiting"); break;
- case TH_STATE_UNINTERRUPTIBLE: puts ("uninterruptible"); break;
- case TH_STATE_HALTED: puts ("halted"); break;
- default: puts ("");
- }
-
- printf (" pthread handle id 0x%llx (not the same value as pthread_self() returns)\n", (uint64_t) identifier_info.thread_handle);
-
- struct proc_threadinfo pth;
- int proc_threadinfo_succeeded = get_proc_threadinfo (pid, identifier_info.thread_handle, &pth);
-
- if (proc_threadinfo_succeeded && pth.pth_name[0] != '\0')
- printf (" thread name '%s'\n", pth.pth_name);
-
- printf (" libdispatch qaddr 0x%llx (not the same as the dispatch_queue_t token)\n", (uint64_t) identifier_info.dispatch_qaddr);
-
- if (verbose)
- {
- printf (" (examine-threads port namespace) mach port # 0x%4.4x\n", (int) thread_list[i]);
- thread_t mach_port_inferior_namespace;
- if (inferior_namespace_mach_port_num (task, thread_list[i], &mach_port_inferior_namespace))
- printf (" (inferior port namepsace) mach port # 0x%4.4x\n", (int) mach_port_inferior_namespace);
- printf (" user %d.%06ds, system %d.%06ds",
- basic_info->user_time.seconds, basic_info->user_time.microseconds,
- basic_info->system_time.seconds, basic_info->system_time.microseconds);
- if (basic_info->cpu_usage > 0)
- {
- float cpu_percentage = basic_info->cpu_usage / 10.0;
- printf (", using %.1f%% cpu currently", cpu_percentage);
- }
- if (basic_info->sleep_time > 0)
- printf (", this thread has slept for %d seconds", basic_info->sleep_time);
-
- printf ("\n ");
- printf ("scheduling policy %d", basic_info->policy);
-
- if (basic_info->flags != 0)
- {
- printf (", flags %d", basic_info->flags);
- if ((basic_info->flags | TH_FLAGS_SWAPPED) == TH_FLAGS_SWAPPED)
- printf (" (thread is swapped out)");
- if ((basic_info->flags | TH_FLAGS_IDLE) == TH_FLAGS_IDLE)
- printf (" (thread is idle)");
- }
- if (proc_threadinfo_succeeded)
- printf (", current pri %d, max pri %d", pth.pth_curpri, pth.pth_maxpriority);
-
- printf ("\n\n");
- }
-
- free ((void *) basic_info);
+ if (basic_info->sleep_time > 0)
+ printf(", this thread has slept for %d seconds",
+ basic_info->sleep_time);
+
+ printf("\n ");
+ printf("scheduling policy %d", basic_info->policy);
+
+ if (basic_info->flags != 0) {
+ printf(", flags %d", basic_info->flags);
+ if ((basic_info->flags | TH_FLAGS_SWAPPED) == TH_FLAGS_SWAPPED)
+ printf(" (thread is swapped out)");
+ if ((basic_info->flags | TH_FLAGS_IDLE) == TH_FLAGS_IDLE)
+ printf(" (thread is idle)");
}
- if (do_loop)
- printf ("\n");
- vm_deallocate (mytask, (vm_address_t) thread_list,
- thread_count * sizeof (thread_act_t));
- nanosleep (rqtp, NULL);
- } while (do_loop);
-
- while (resume_when_done > 0)
- {
- kern_return_t err = task_resume (task);
- if (err != KERN_SUCCESS)
- printf ("Error resuming task: %d.", err);
- resume_when_done--;
+ if (proc_threadinfo_succeeded)
+ printf(", current pri %d, max pri %d", pth.pth_curpri,
+ pth.pth_maxpriority);
+
+ printf("\n\n");
+ }
+
+ free((void *)basic_info);
}
+ if (do_loop)
+ printf("\n");
+ vm_deallocate(mytask, (vm_address_t)thread_list,
+ thread_count * sizeof(thread_act_t));
+ nanosleep(rqtp, NULL);
+ } while (do_loop);
+
+ while (resume_when_done > 0) {
+ kern_return_t err = task_resume(task);
+ if (err != KERN_SUCCESS)
+ printf("Error resuming task: %d.", err);
+ resume_when_done--;
+ }
- vm_deallocate (mytask, (vm_address_t) task, sizeof (task_t));
- free ((void *) process_name);
+ vm_deallocate(mytask, (vm_address_t)task, sizeof(task_t));
+ free((void *)process_name);
return 0;
}
diff --git a/tools/debugserver/debugserver.xcodeproj/project.pbxproj b/tools/debugserver/debugserver.xcodeproj/project.pbxproj
index 295a2bf4fa17..a4c3de58113e 100644
--- a/tools/debugserver/debugserver.xcodeproj/project.pbxproj
+++ b/tools/debugserver/debugserver.xcodeproj/project.pbxproj
@@ -7,8 +7,29 @@
objects = {
/* Begin PBXBuildFile section */
+ 23043C9D1D35DBEC00FC25CA /* JSON.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 233B4EA51D2DB54300E98261 /* JSON.cpp */; };
+ 23043C9E1D35DBFA00FC25CA /* StringConvert.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 233B4EA81D2DB96A00E98261 /* StringConvert.cpp */; };
+ 2307CCCB1D4A5D630016ABC0 /* LogFilterExactMatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 237821AE1D4917D20028B7A1 /* LogFilterExactMatch.cpp */; };
+ 233B4EA71D2DB54300E98261 /* JSON.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 233B4EA51D2DB54300E98261 /* JSON.cpp */; };
+ 233B4EA91D2DB96A00E98261 /* StringConvert.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 233B4EA81D2DB96A00E98261 /* StringConvert.cpp */; };
+ 23562ED21D3424DF00AB2BD4 /* LogMessageOsLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23562ED01D3424DF00AB2BD4 /* LogMessageOsLog.cpp */; };
+ 23562ED31D3424DF00AB2BD4 /* LogMessageOsLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23562ED01D3424DF00AB2BD4 /* LogMessageOsLog.cpp */; };
+ 23562ED61D342A5A00AB2BD4 /* ActivityStore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23562ED51D342A5A00AB2BD4 /* ActivityStore.cpp */; };
+ 23562ED71D342A5A00AB2BD4 /* ActivityStore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23562ED51D342A5A00AB2BD4 /* ActivityStore.cpp */; };
+ 23562ED91D342B0000AB2BD4 /* LogMessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23562ED81D342B0000AB2BD4 /* LogMessage.cpp */; };
+ 23562EDA1D342B0000AB2BD4 /* LogMessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23562ED81D342B0000AB2BD4 /* LogMessage.cpp */; };
+ 237821B01D4917D20028B7A1 /* LogFilterExactMatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 237821AE1D4917D20028B7A1 /* LogFilterExactMatch.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 */; };
+ 23AC04CF1D2F58AF0072351D /* LogFilterRegex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23AC04CD1D2F58AF0072351D /* LogFilterRegex.cpp */; };
+ 23AC04D01D2F58AF0072351D /* LogFilterRegex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23AC04CD1D2F58AF0072351D /* LogFilterRegex.cpp */; };
+ 23AE72E41D25DECF00945BCE /* DarwinLogCollector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23AE72E21D25DECF00945BCE /* DarwinLogCollector.cpp */; };
+ 23AE72E51D25DEE100945BCE /* DarwinLogCollector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23AE72E21D25DECF00945BCE /* DarwinLogCollector.cpp */; };
+ 23D1B0291D497E8B00FF831B /* OsLogger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23D1B0271D497E8B00FF831B /* OsLogger.cpp */; };
+ 23D1B02A1D497E8B00FF831B /* OsLogger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23D1B0271D497E8B00FF831B /* OsLogger.cpp */; };
264D5D581293835600ED4C01 /* DNBArch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 264D5D571293835600ED4C01 /* DNBArch.cpp */; };
- 2660D9CE1192280900958FBD /* StringExtractor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2660D9CC1192280900958FBD /* StringExtractor.cpp */; };
266B5ED11460A68200E43F0A /* DNBArchImplARM64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266B5ECF1460A68200E43F0A /* DNBArchImplARM64.cpp */; };
26CE05A7115C360D0022F371 /* DNBError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637DE0C71334A0024798E /* DNBError.cpp */; };
26CE05A8115C36170022F371 /* DNBThreadResumeActions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260E7331114BFFE600D1DFB3 /* DNBThreadResumeActions.cpp */; };
@@ -38,7 +59,6 @@
26CE05C1115C36510022F371 /* DNBArchImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2675D4220CCEB705000F49AF /* DNBArchImpl.cpp */; };
26CE05C2115C36550022F371 /* DNBArchImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637FB0C71334A0024798E /* DNBArchImpl.cpp */; };
26CE05C3115C36580022F371 /* CFString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2695DD9B0D3EC160007E4CA2 /* CFString.cpp */; };
- 26CE05C4115C36590022F371 /* CFData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2695DE2E0D3EE55B007E4CA2 /* CFData.cpp */; };
26CE05C5115C36590022F371 /* CFBundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2695DD910D3EBFF6007E4CA2 /* CFBundle.cpp */; };
26CE05CF115C36F70022F371 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26ACA3340D3E956300A2120B /* CoreFoundation.framework */; settings = {ATTRIBUTES = (Required, ); }; };
26CE05F1115C387C0022F371 /* PseudoTerminal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF67ABFF0D34604D0022D128 /* PseudoTerminal.cpp */; };
@@ -71,19 +91,46 @@
456F67601AD46CE9002850C2 /* DNBArchImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2675D4220CCEB705000F49AF /* DNBArchImpl.cpp */; };
456F67611AD46CE9002850C2 /* DNBArchImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C637FB0C71334A0024798E /* DNBArchImpl.cpp */; };
456F67621AD46CE9002850C2 /* CFString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2695DD9B0D3EC160007E4CA2 /* CFString.cpp */; };
- 456F67631AD46CE9002850C2 /* CFData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2695DE2E0D3EE55B007E4CA2 /* CFData.cpp */; };
456F67641AD46CE9002850C2 /* CFBundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2695DD910D3EBFF6007E4CA2 /* CFBundle.cpp */; };
456F67651AD46CE9002850C2 /* PseudoTerminal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF67ABFF0D34604D0022D128 /* PseudoTerminal.cpp */; };
- 456F67661AD46CE9002850C2 /* StringExtractor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2660D9CC1192280900958FBD /* StringExtractor.cpp */; };
456F67671AD46CE9002850C2 /* DNBArch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 264D5D571293835600ED4C01 /* DNBArch.cpp */; };
456F67681AD46CE9002850C2 /* HasAVX.s in Sources */ = {isa = PBXBuildFile; fileRef = 4971AE7113D10F4F00649E37 /* HasAVX.s */; };
456F67691AD46CE9002850C2 /* DNBArchImplARM64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266B5ECF1460A68200E43F0A /* DNBArchImplARM64.cpp */; };
456F676B1AD46CE9002850C2 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26ACA3340D3E956300A2120B /* CoreFoundation.framework */; settings = {ATTRIBUTES = (Required, ); }; };
4971AE7213D10F4F00649E37 /* HasAVX.s in Sources */ = {isa = PBXBuildFile; fileRef = 4971AE7113D10F4F00649E37 /* HasAVX.s */; };
+ AF48558C1D75126800D19C07 /* StdStringExtractor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF48558B1D75126800D19C07 /* StdStringExtractor.cpp */; };
+ AF48558D1D75127500D19C07 /* StdStringExtractor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF48558B1D75126800D19C07 /* StdStringExtractor.cpp */; };
AFEC3364194A8B0B00FF05C6 /* Genealogy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AFEC3363194A8B0B00FF05C6 /* Genealogy.cpp */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
+ 2307CCCC1D4A5DAE0016ABC0 /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; 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>"; };
+ 233B4EA81D2DB96A00E98261 /* StringConvert.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringConvert.cpp; path = ../../../source/Host/common/StringConvert.cpp; sourceTree = "<group>"; };
+ 23562ECF1D34110D00AB2BD4 /* DarwinLogTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DarwinLogTypes.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>"; };
+ 23562ED41D3426DD00AB2BD4 /* ActivityStore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ActivityStore.h; sourceTree = "<group>"; };
+ 23562ED51D342A5A00AB2BD4 /* ActivityStore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ActivityStore.cpp; sourceTree = "<group>"; };
+ 23562ED81D342B0000AB2BD4 /* LogMessage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LogMessage.cpp; sourceTree = "<group>"; };
+ 237821AD1D4917D20028B7A1 /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; 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>"; };
+ 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>"; };
+ 23AC04CC1D2F42F10072351D /* DarwinLogInterfaces.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DarwinLogInterfaces.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>"; };
+ 23AC04D11D2F60130072351D /* LogMessage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LogMessage.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>"; };
+ 23AE72E61D25DEFB00945BCE /* ActivityStreamSPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ActivityStreamSPI.h; sourceTree = "<group>"; };
+ 23CF6F5E1D28A3760088ADC9 /* DarwinLogEvent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DarwinLogEvent.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>"; };
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>"; };
@@ -94,7 +141,6 @@
264D5D571293835600ED4C01 /* DNBArch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DNBArch.cpp; sourceTree = "<group>"; };
264F679A1B2F9EB200140093 /* JSONGenerator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JSONGenerator.h; sourceTree = "<group>"; };
26593A060D4931CC001C9FE3 /* ChangeLog */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ChangeLog; sourceTree = "<group>"; };
- 2660D9CC1192280900958FBD /* StringExtractor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringExtractor.cpp; path = ../../source/Utility/StringExtractor.cpp; sourceTree = SOURCE_ROOT; };
266B5ECF1460A68200E43F0A /* DNBArchImplARM64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DNBArchImplARM64.cpp; sourceTree = "<group>"; };
266B5ED01460A68200E43F0A /* DNBArchImplARM64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DNBArchImplARM64.h; sourceTree = "<group>"; };
2672DBEE0EEF446700E92059 /* PThreadMutex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PThreadMutex.cpp; sourceTree = "<group>"; };
@@ -104,8 +150,6 @@
2695DD920D3EBFF6007E4CA2 /* CFBundle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFBundle.h; sourceTree = "<group>"; };
2695DD9A0D3EC160007E4CA2 /* CFString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFString.h; sourceTree = "<group>"; };
2695DD9B0D3EC160007E4CA2 /* CFString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CFString.cpp; sourceTree = "<group>"; };
- 2695DE2D0D3EE55B007E4CA2 /* CFData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFData.h; sourceTree = "<group>"; };
- 2695DE2E0D3EE55B007E4CA2 /* CFData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CFData.cpp; sourceTree = "<group>"; };
269E8DF8164B2ED200AD65F6 /* com.apple.debugserver.posix.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.debugserver.posix.plist; sourceTree = "<group>"; };
26A02918114AB9240029C479 /* debugserver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debugserver.cpp; sourceTree = "<group>"; };
26A4BAED0D498B7D00A9BEAB /* com.apple.debugserver.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.debugserver.plist; sourceTree = "<group>"; };
@@ -171,6 +215,7 @@
9457ECF61419864100DFE7D8 /* stack_logging.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = stack_logging.h; 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>"; };
+ AF48558B1D75126800D19C07 /* StdStringExtractor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StdStringExtractor.cpp; sourceTree = "<group>"; };
AF61C60418F75ABC00B48D9D /* debugserver-macosx-entitlements.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "debugserver-macosx-entitlements.plist"; 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>"; };
@@ -221,6 +266,34 @@
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 = (
@@ -277,6 +350,8 @@
26C637E20C71334A0024798E /* DNBRegisterInfo.cpp */,
260E7332114BFFE600D1DFB3 /* DNBThreadResumeActions.h */,
260E7331114BFFE600D1DFB3 /* DNBThreadResumeActions.cpp */,
+ 233B4EA61D2DB54300E98261 /* JSON.h */,
+ 233B4EA51D2DB54300E98261 /* JSON.cpp */,
264F679A1B2F9EB200140093 /* JSONGenerator.h */,
AF67AC000D34604D0022D128 /* PseudoTerminal.h */,
AF67ABFF0D34604D0022D128 /* PseudoTerminal.cpp */,
@@ -285,6 +360,7 @@
26C637FE0C71334A0024798E /* PThreadEvent.cpp */,
26C638000C71334A0024798E /* PThreadMutex.h */,
2672DBEE0EEF446700E92059 /* PThreadMutex.cpp */,
+ 233B4EA81D2DB96A00E98261 /* StringConvert.cpp */,
26C638020C71334A0024798E /* SysSignal.h */,
26C638010C71334A0024798E /* SysSignal.cpp */,
26C638060C71334A0024798E /* TTYState.h */,
@@ -319,15 +395,13 @@
26C637E60C71334A0024798E /* MacOSX */ = {
isa = PBXGroup;
children = (
- AF0934BA18E12B92005A11FD /* Genealogy.h */,
- AF0934BB18E12B92005A11FD /* GenealogySPI.h */,
+ 23AC04C31D2F3E9A0072351D /* DarwinLog */,
2695DD920D3EBFF6007E4CA2 /* CFBundle.h */,
2695DD910D3EBFF6007E4CA2 /* CFBundle.cpp */,
- 2695DE2D0D3EE55B007E4CA2 /* CFData.h */,
- 2695DE2E0D3EE55B007E4CA2 /* CFData.cpp */,
2695DD9A0D3EC160007E4CA2 /* CFString.h */,
2695DD9B0D3EC160007E4CA2 /* CFString.cpp */,
26C637E70C71334A0024798E /* CFUtils.h */,
+ 2307CCCC1D4A5DAE0016ABC0 /* CMakeLists.txt */,
2675D41C0CCEB6CF000F49AF /* arm */,
266B5ECE1460A68200E43F0A /* arm64 */,
26C637E90C71334A0024798E /* i386 */,
@@ -337,6 +411,8 @@
4971AE7113D10F4F00649E37 /* HasAVX.s */,
26C637E80C71334A0024798E /* dbgnub-mig.defs */,
AFEC3363194A8B0B00FF05C6 /* Genealogy.cpp */,
+ AF0934BA18E12B92005A11FD /* Genealogy.h */,
+ AF0934BB18E12B92005A11FD /* GenealogySPI.h */,
26C637EF0C71334A0024798E /* MachException.h */,
26C637EE0C71334A0024798E /* MachException.cpp */,
26C637F10C71334A0024798E /* MachProcess.h */,
@@ -351,6 +427,8 @@
26C637F80C71334A0024798E /* MachVMRegion.cpp */,
26B67DE00EE9BC30006C8BC0 /* MachTask.h */,
26B67DE10EE9BC30006C8BC0 /* MachTask.mm */,
+ 23D1B0281D497E8B00FF831B /* OsLogger.h */,
+ 23D1B0271D497E8B00FF831B /* OsLogger.cpp */,
9457ECF61419864100DFE7D8 /* stack_logging.h */,
);
path = MacOSX;
@@ -399,7 +477,7 @@
26A68FD50D10574500665A9E /* RNBRemote.h */,
26A68FD60D10574500665A9E /* RNBRemote.cpp */,
26E6B9DA0D1329010037ECDD /* RNBDefs.h */,
- 2660D9CC1192280900958FBD /* StringExtractor.cpp */,
+ AF48558B1D75126800D19C07 /* StdStringExtractor.cpp */,
);
name = debugserver;
sourceTree = "<group>";
@@ -494,38 +572,48 @@
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 */,
- 26CE05C3115C36580022F371 /* CFString.cpp in Sources */,
- 26CE05C4115C36590022F371 /* CFData.cpp in Sources */,
26CE05C5115C36590022F371 /* CFBundle.cpp in Sources */,
+ 26CE05C3115C36580022F371 /* CFString.cpp in Sources */,
+ 23562ED91D342B0000AB2BD4 /* LogMessage.cpp in Sources */,
26CE05F1115C387C0022F371 /* PseudoTerminal.cpp in Sources */,
- 2660D9CE1192280900958FBD /* StringExtractor.cpp in Sources */,
264D5D581293835600ED4C01 /* DNBArch.cpp in Sources */,
4971AE7213D10F4F00649E37 /* HasAVX.s in Sources */,
+ 237821B01D4917D20028B7A1 /* LogFilterExactMatch.cpp in Sources */,
266B5ED11460A68200E43F0A /* DNBArchImplARM64.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -537,38 +625,48 @@
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 */,
456F67621AD46CE9002850C2 /* CFString.cpp in Sources */,
- 456F67631AD46CE9002850C2 /* CFData.cpp in Sources */,
+ 23AC04CB1D2F42250072351D /* LogFilterChain.cpp in Sources */,
+ AF48558D1D75127500D19C07 /* StdStringExtractor.cpp in Sources */,
456F67641AD46CE9002850C2 /* CFBundle.cpp in Sources */,
456F67651AD46CE9002850C2 /* PseudoTerminal.cpp in Sources */,
- 456F67661AD46CE9002850C2 /* StringExtractor.cpp in Sources */,
456F67671AD46CE9002850C2 /* DNBArch.cpp in Sources */,
456F67681AD46CE9002850C2 /* HasAVX.s in Sources */,
+ 23AC04D01D2F58AF0072351D /* LogFilterRegex.cpp in Sources */,
456F67691AD46CE9002850C2 /* DNBArchImplARM64.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -608,8 +706,11 @@
"LLDB_COMPRESSION_CFLAGS[sdk=macosx10.11]" = "-DHAVE_LIBCOMPRESSION=1";
LLDB_COMPRESSION_LDFLAGS = "";
"LLDB_COMPRESSION_LDFLAGS[sdk=macosx10.11]" = "-weak-lcompression";
+ LLDB_OS_LOG_CFLAGS = "-DLLDB_USE_OS_LOG=$(LLDB_USE_OS_LOG)";
+ LLDB_USE_OS_LOG = 0;
LLDB_ZLIB_CFLAGS = "-DHAVE_LIBZ=1";
LLDB_ZLIB_LDFLAGS = "-lz";
+ MACOSX_DEPLOYMENT_TARGET = 10.10;
ONLY_ACTIVE_ARCH = YES;
OTHER_CFLAGS = "";
STRIP_INSTALLED_PRODUCT = NO;
@@ -649,8 +750,11 @@
"LLDB_COMPRESSION_CFLAGS[sdk=macosx10.11]" = "-DHAVE_LIBCOMPRESSION=1";
LLDB_COMPRESSION_LDFLAGS = "";
"LLDB_COMPRESSION_LDFLAGS[sdk=macosx10.11]" = "-weak-lcompression";
+ LLDB_OS_LOG_CFLAGS = "-DLLDB_USE_OS_LOG=$(LLDB_USE_OS_LOG)";
+ LLDB_USE_OS_LOG = 0;
LLDB_ZLIB_CFLAGS = "-DHAVE_LIBZ=1";
LLDB_ZLIB_LDFLAGS = "-lz";
+ MACOSX_DEPLOYMENT_TARGET = 10.10;
ONLY_ACTIVE_ARCH = YES;
OTHER_CFLAGS = "";
STRIPFLAGS = "-x";
@@ -688,8 +792,11 @@
"LLDB_COMPRESSION_CFLAGS[sdk=macosx10.11]" = "-DHAVE_LIBCOMPRESSION=1";
LLDB_COMPRESSION_LDFLAGS = "";
"LLDB_COMPRESSION_LDFLAGS[sdk=macosx10.11]" = "-weak-lcompression";
+ LLDB_OS_LOG_CFLAGS = "-DLLDB_USE_OS_LOG=$(LLDB_USE_OS_LOG)";
+ LLDB_USE_OS_LOG = 1;
LLDB_ZLIB_CFLAGS = "-DHAVE_LIBZ=1";
LLDB_ZLIB_LDFLAGS = "-lz";
+ MACOSX_DEPLOYMENT_TARGET = 10.10;
OTHER_CFLAGS = "";
STRIPFLAGS = "-x";
STRIP_STYLE = debugging;
@@ -748,6 +855,7 @@
"-DDT_VARIANT_$(DT_VARIANT)",
"$(LLDB_COMPRESSION_CFLAGS)",
"$(LLDB_ZLIB_CFLAGS)",
+ "$(LLDB_OS_LOG_CFLAGS)",
);
"OTHER_CFLAGS[sdk=iphoneos*]" = (
"-Wparentheses",
@@ -757,6 +865,7 @@
"-DOS_OBJECT_USE_OBJC=0",
"$(LLDB_COMPRESSION_CFLAGS)",
"$(LLDB_ZLIB_CFLAGS)",
+ "$(LLDB_OS_LOG_CFLAGS)",
);
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
OTHER_LDFLAGS = "";
@@ -848,6 +957,7 @@
"-DDT_VARIANT_$(DT_VARIANT)",
"$(LLDB_COMPRESSION_CFLAGS)",
"$(LLDB_ZLIB_CFLAGS)",
+ "$(LLDB_OS_LOG_CFLAGS)",
);
"OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
"-Wparentheses",
@@ -857,6 +967,7 @@
"-DOS_OBJECT_USE_OBJC=0",
"$(LLDB_COMPRESSION_CFLAGS)",
"$(LLDB_ZLIB_CFLAGS)",
+ "$(LLDB_OS_LOG_CFLAGS)",
);
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
OTHER_LDFLAGS = "";
@@ -947,6 +1058,7 @@
"-DDT_VARIANT_$(DT_VARIANT)",
"$(LLDB_COMPRESSION_CFLAGS)",
"$(LLDB_ZLIB_CFLAGS)",
+ "$(LLDB_OS_LOG_CFLAGS)",
);
"OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
"-Wparentheses",
@@ -956,6 +1068,7 @@
"-DOS_OBJECT_USE_OBJC=0",
"$(LLDB_COMPRESSION_CFLAGS)",
"$(LLDB_ZLIB_CFLAGS)",
+ "$(LLDB_OS_LOG_CFLAGS)",
);
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
OTHER_LDFLAGS = "";
@@ -1055,6 +1168,7 @@
"-Wparentheses",
"-DOS_OBJECT_USE_OBJC=0",
"-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui",
+ "$(LLDB_OS_LOG_CFLAGS)",
);
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
OTHER_LDFLAGS = "";
@@ -1124,6 +1238,7 @@
"-Wparentheses",
"-DOS_OBJECT_USE_OBJC=0",
"-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui",
+ "$(LLDB_OS_LOG_CFLAGS)",
);
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
OTHER_LDFLAGS = "";
@@ -1189,11 +1304,13 @@
"$(LLDB_COMPRESSION_CFLAGS)",
"$(LLDB_ZLIB_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 = "";
@@ -1260,12 +1377,15 @@
"-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",
@@ -1317,6 +1437,9 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
+ LLDB_OS_LOG_CFLAGS = "-DLLDB_USE_OS_LOG=$(LLDB_USE_OS_LOG)";
+ LLDB_USE_OS_LOG = 0;
+ MACOSX_DEPLOYMENT_TARGET = 10.10;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx.internal;
"SDKROOT[arch=i386]" = macosx;
@@ -1378,6 +1501,7 @@
"-DDT_VARIANT_$(DT_VARIANT)",
"$(LLDB_COMPRESSION_CFLAGS)",
"$(LLDB_ZLIB_CFLAGS)",
+ "$(LLDB_OS_LOG_CFLAGS)",
);
"OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
"-Wparentheses",
@@ -1387,6 +1511,7 @@
"-DOS_OBJECT_USE_OBJC=0",
"$(LLDB_COMPRESSION_CFLAGS)",
"$(LLDB_ZLIB_CFLAGS)",
+ "$(LLDB_OS_LOG_CFLAGS)",
);
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
"OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
@@ -1455,6 +1580,9 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
+ LLDB_OS_LOG_CFLAGS = "-DLLDB_USE_OS_LOG=$(LLDB_USE_OS_LOG)";
+ LLDB_USE_OS_LOG = 0;
+ MACOSX_DEPLOYMENT_TARGET = 10.10;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx.internal;
"SDKROOT[arch=i386]" = macosx;
@@ -1515,6 +1643,7 @@
"$(LLDB_ENERGY_CFLAGS)",
"$(LLDB_COMPRESSION_CFLAGS)",
"$(LLDB_ZLIB_CFLAGS)",
+ "$(LLDB_OS_LOG_CFLAGS)",
);
"OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
"-Wparentheses",
@@ -1524,6 +1653,7 @@
"-DOS_OBJECT_USE_OBJC=0",
"$(LLDB_COMPRESSION_CFLAGS)",
"$(LLDB_ZLIB_CFLAGS)",
+ "$(LLDB_OS_LOG_CFLAGS)",
);
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
"OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
@@ -1598,11 +1728,13 @@
"-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=*]" = (
@@ -1672,6 +1804,9 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
+ LLDB_OS_LOG_CFLAGS = "-DLLDB_USE_OS_LOG=$(LLDB_USE_OS_LOG)";
+ LLDB_USE_OS_LOG = 0;
+ MACOSX_DEPLOYMENT_TARGET = 10.10;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx.internal;
"SDKROOT[arch=i386]" = macosx;
@@ -1723,6 +1858,7 @@
"-DDT_VARIANT_$(DT_VARIANT)",
"$(LLDB_COMPRESSION_CFLAGS)",
"$(LLDB_ZLIB_CFLAGS)",
+ "$(LLDB_OS_LOG_CFLAGS)",
);
"OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
"-Wparentheses",
@@ -1732,6 +1868,7 @@
"-DOS_OBJECT_USE_OBJC=0",
"$(LLDB_COMPRESSION_CFLAGS)",
"$(LLDB_ZLIB_CFLAGS)",
+ "$(LLDB_OS_LOG_CFLAGS)",
);
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
OTHER_LDFLAGS = "";
@@ -1800,6 +1937,9 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
+ LLDB_OS_LOG_CFLAGS = "-DLLDB_USE_OS_LOG=$(LLDB_USE_OS_LOG)";
+ LLDB_USE_OS_LOG = 0;
+ MACOSX_DEPLOYMENT_TARGET = 10.10;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx.internal;
"SDKROOT[arch=i386]" = macosx;
@@ -1852,6 +1992,7 @@
"-DDT_VARIANT_$(DT_VARIANT)",
"$(LLDB_COMPRESSION_CFLAGS)",
"$(LLDB_ZLIB_CFLAGS)",
+ "$(LLDB_OS_LOG_CFLAGS)",
);
"OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
"-Wparentheses",
@@ -1861,6 +2002,7 @@
"-DOS_OBJECT_USE_OBJC=0",
"$(LLDB_COMPRESSION_CFLAGS)",
"$(LLDB_ZLIB_CFLAGS)",
+ "$(LLDB_OS_LOG_CFLAGS)",
);
"OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
"OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
diff --git a/tools/debugserver/source/ARM_DWARF_Registers.h b/tools/debugserver/source/ARM_DWARF_Registers.h
index 845260ba187c..037d28bf1304 100644
--- a/tools/debugserver/source/ARM_DWARF_Registers.h
+++ b/tools/debugserver/source/ARM_DWARF_Registers.h
@@ -10,200 +10,197 @@
#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,
-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,
- 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,
- // 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,
- // 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,
- // 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,
- // 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_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,
- 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,
- // 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,
- // 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
+ // 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
index f6d93b3cee02..9d644b7dc50b 100644
--- a/tools/debugserver/source/ARM_ehframe_Registers.h
+++ b/tools/debugserver/source/ARM_ehframe_Registers.h
@@ -1,4 +1,5 @@
-//===-- ARM_ehframe_Registers.h -------------------------------------*- C++ -*-===//
+//===-- ARM_ehframe_Registers.h -------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,26 +11,24 @@
#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
+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
index 94cef6c31203..43479bd36435 100644
--- a/tools/debugserver/source/CMakeLists.txt
+++ b/tools/debugserver/source/CMakeLists.txt
@@ -1,5 +1,6 @@
include_directories(${CMAKE_CURRENT_BINARY_DIR}/..)
include_directories(${LLDB_SOURCE_DIR}/source)
+include_directories(MacOSX/DarwinLog)
if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
include_directories(MacOSX)
@@ -42,6 +43,11 @@ add_library(lldbDebugserverCommon
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
+ # end JSON reader dependencies
libdebugserver.cpp
PseudoTerminal.cpp
PThreadEvent.cpp
diff --git a/tools/debugserver/source/DNB.cpp b/tools/debugserver/source/DNB.cpp
index bb3603649199..9c6c44d18df1 100644
--- a/tools/debugserver/source/DNB.cpp
+++ b/tools/debugserver/source/DNB.cpp
@@ -13,20 +13,20 @@
#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 <sys/sysctl.h>
-#include <map>
#include <vector>
-#include <libproc.h>
-#if defined (__APPLE__)
+#if defined(__APPLE__)
#include <pthread.h>
#include <sched.h>
#endif
@@ -34,32 +34,34 @@
#define TRY_KQUEUE 1
#ifdef TRY_KQUEUE
- #include <sys/event.h>
- #include <sys/time.h>
- #ifdef NOTE_EXIT_DETAIL
- #define USE_KQUEUE
- #endif
+#include <sys/event.h>
+#include <sys/time.h>
+#ifdef NOTE_EXIT_DETAIL
+#define USE_KQUEUE
+#endif
#endif
-#include "MacOSX/MachProcess.h"
-#include "MacOSX/MachTask.h"
-#include "MacOSX/Genealogy.h"
-#include "MacOSX/ThreadInfo.h"
+#include "CFBundle.h"
#include "CFString.h"
-#include "DNBLog.h"
#include "DNBDataRef.h"
+#include "DNBLog.h"
#include "DNBThreadResumeActions.h"
#include "DNBTimer.h"
-#include "CFBundle.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);
+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.
@@ -67,19 +69,16 @@ static size_t GetAllInfosMatchingName (const char *process_name, std::vector<str
// 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;
+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;
}
//----------------------------------------------------------------------
@@ -89,16 +88,13 @@ GetProcessMap(bool can_create)
// 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;
+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;
}
//----------------------------------------------------------------------
@@ -106,8 +102,8 @@ AddProcessToMap (nub_process_t pid, MachProcessSP& procSP)
//
// Returns the number of items removed from the process map.
//----------------------------------------------------------------------
-//static size_t
-//RemoveProcessFromMap (nub_process_t pid)
+// static size_t
+// RemoveProcessFromMap (nub_process_t pid)
//{
// ProcessMap* process_map = GetProcessMap(false);
// if (process_map)
@@ -123,1079 +119,958 @@ AddProcessToMap (nub_process_t pid, MachProcessSP& procSP)
// 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;
- }
+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;
+ }
+ 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);
- }
+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;
+ 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);
}
- 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;
- }
- }
- }
-}
+ }
+
+ 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;
+ }
-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;
- }
+ int ret =
+ ::pthread_create(&thread, NULL, kqueue_thread, (void *)(intptr_t)kq_id);
- 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;
+ // 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);
- }
+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)
-{
+ 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;
+ 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)
- {
- strncpy(err_str, launch_err_str, err_len-1);
- err_str[err_len-1] = '\0'; // Make sure the error string is terminated
- }
- }
+ 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) {
+ strncpy(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;
- }
+ }
+ }
+
+ 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;
+ }
+ 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;
- }
+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;
-}
-
-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 (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;
}
- 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);
- }
+ DNBProcessResetEvents(pid, set_events);
}
+ }
- return INVALID_NUB_PROCESS;
+ 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;
+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.
+ // 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);
+ 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;
- }
+ 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();
+ // 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]);
- }
+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;
- }
+ }
+ // return the newly added matches.
+ return matching_proc_infos.size();
+}
- if (attach_token == NULL)
- {
- if (ignore_existing)
- num_exclude_proc_infos = GetAllInfosMatchingName (waitfor_process_name, exclude_proc_infos);
- else
- num_exclude_proc_infos = 0;
- }
+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;
- 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 the PrepareForAttach returns a valid token, use MachProcess to check
+ // for the process, otherwise scan the process table.
- // 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;
- }
- }
+ 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 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;
- }
- }
+ // 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...
+ // 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;
- }
+ 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
- }
+ ::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);
- }
+ 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);
+ bool success = waitfor_pid != INVALID_NUB_PROCESS;
+ MachProcess::CleanupAfterAttach(attach_token, launch_flavor, success,
+ prepare_error);
- return waitfor_pid;
+ 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 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 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 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 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 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;
+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;
+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 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;
+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;
+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;
+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;
+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;
+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;
+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;
}
-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 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)
+// 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);
+// DNBLogThreadedIf(LOG_THREAD, "%s(pid = %4.4x, tid = %4.4x, step = %u)",
+// __FUNCTION__, pid, tid, (uint32_t)step);
// MachProcessSP procSP;
// if (GetProcessSP (pid, procSP))
// {
@@ -1204,10 +1079,12 @@ DNBProcessHalt (nub_process_t pid)
// return false;
//}
//
-//nub_bool_t
-//DNBThreadResumeWithSignal (nub_process_t pid, nub_thread_t tid, nub_bool_t step, int signal)
+// 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);
+// 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))
// {
@@ -1216,80 +1093,68 @@ DNBProcessHalt (nub_process_t pid)
// 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;
+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);
+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 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
+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 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
+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;
+uint32_t DNBWatchpointGetNumSupportedHWP(nub_process_t pid) {
+ MachProcessSP procSP;
+ if (GetProcessSP(pid, procSP))
+ return procSP->GetNumSupportedHardwareWatchpoints();
+ return 0;
}
//----------------------------------------------------------------------
@@ -1299,95 +1164,89 @@ DNBWatchpointGetNumSupportedHWP (nub_process_t pid)
//
// 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_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;
}
-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
@@ -1395,31 +1254,27 @@ DNBProcessMemoryReadCStringFixed (nub_process_t pid, nub_addr_t addr, nub_size_t
//
// 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_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_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;
+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;
}
//----------------------------------------------------------------------
@@ -1436,99 +1291,87 @@ DNBProcessMemoryDeallocate (nub_process_t pid, nub_addr_t addr)
// 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);
+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;
+ 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("");
+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;
+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;
+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;
+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;
+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;
+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;
+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;
}
//----------------------------------------------------------------------
@@ -1538,61 +1381,49 @@ DNBThreadGetStopReason (nub_process_t pid, nub_thread_t tid, struct DNBThreadSto
// 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;
+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;
+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.
+// 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_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_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;
+nub_bool_t DNBProcessSharedLibrariesUpdated(nub_process_t pid) {
+ MachProcessSP procSP;
+ if (GetProcessSP(pid, procSP)) {
+ procSP->SharedLibrariesUpdated();
+ return true;
+ }
+ return false;
}
//----------------------------------------------------------------------
@@ -1601,403 +1432,334 @@ DNBProcessSharedLibrariesUpdated(nub_process_t pid)
// 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);
+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;
+ // 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 ();
-
+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);
+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)
-{
+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)
- {
- MachProcessSP procSP;
- if (GetProcessSP (pid, procSP))
- return procSP->SetRegisterValue (tid, set, reg, value);
- }
- return false;
+ return procSP->GetRegisterValue(tid, set, reg, value);
+ }
+ return false;
}
-nub_size_t
-DNBThreadGetRegisterContext (nub_process_t pid, nub_thread_t tid, void *buf, size_t buf_len)
-{
+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))
- {
- if (tid != INVALID_NUB_THREAD)
- return procSP->GetThreadList().GetRegisterContext (tid, buf, buf_len);
- }
- ::bzero (buf, buf_len);
- return 0;
-
+ if (GetProcessSP(pid, procSP))
+ return procSP->SetRegisterValue(tid, set, reg, value);
+ }
+ return false;
}
-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)
-{
+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)
- {
- MachProcessSP procSP;
- if (GetProcessSP (pid, procSP))
- return procSP->GetThreadList().SaveRegisterState (tid);
- }
- return 0;
+ return procSP->GetThreadList().GetRegisterContext(tid, buf, buf_len);
+ }
+ ::bzero(buf, buf_len);
+ return 0;
}
-nub_bool_t
-DNBThreadRestoreRegisterState (nub_process_t pid, nub_thread_t tid, uint32_t save_id)
-{
+
+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)
- {
- MachProcessSP procSP;
- if (GetProcessSP (pid, procSP))
- return procSP->GetThreadList().RestoreRegisterState (tid, save_id);
- }
- return false;
+ 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);
- }
- }
+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;
+ }
+ 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;
- }
- }
+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;
- }
- }
+ 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;
+ ::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;
+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_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_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
-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
-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;
}
-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;
+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;
-
+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;
- }
- }
- }
+nub_bool_t DNBResolveExecutablePath(const char *path, char *resolved_path,
+ size_t resolved_path_size) {
+ if (path == NULL || path[0] == '\0')
+ return false;
- if (realpath(path, max_path))
- {
- // Found the path relatively...
- ::strncpy(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)
- {
- ::strncpy(resolved_path, result.c_str(), resolved_path_size);
- return result.size() + 1 < resolved_path_size;
- }
- }
+ 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...
+ ::strncpy(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) {
+ ::strncpy(resolved_path, result.c_str(), resolved_path_size);
+ return result.size() + 1 < resolved_path_size;
}
+ }
}
- return false;
+ }
+ return false;
}
-bool
-DNBGetOSVersionNumbers (uint64_t *major, uint64_t *minor, uint64_t *patch)
-{
- return MachProcess::GetOSVersionNumbers (major, minor, patch);
+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();
+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;
+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
index fbaf5e348133..7acbd42810cc 100644
--- a/tools/debugserver/source/DNB.h
+++ b/tools/debugserver/source/DNB.h
@@ -14,47 +14,49 @@
#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 "JSONGenerator.h"
-#include "DNBDefs.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)
+#define CPU_TYPE_ARM64 ((cpu_type_t)12 | 0x01000000)
#endif
-typedef bool (*DNBShouldCancelCallback) (void *);
+typedef bool (*DNBShouldCancelCallback)(void *);
-void DNBInitialize ();
-void DNBTerminate ();
+void DNBInitialize();
+void DNBTerminate();
-nub_bool_t DNBSetArchitecture (const char *arch);
+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);
+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.
@@ -63,115 +65,177 @@ nub_process_t DNBProcessAttachWait (const char *wait_name, nub_launch_flavo
// 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;
+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;
-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;
+nub_bool_t DNBProcessIsAlive(nub_process_t pid) DNB_EXPORT;
+nub_state_t DNBProcessGetState(nub_process_t pid) DNB_EXPORT;
+nub_bool_t DNBProcessGetExitStatus(nub_process_t pid, int *status) DNB_EXPORT;
+nub_bool_t DNBProcessSetExitStatus(nub_process_t pid, int status) DNB_EXPORT;
+const char *DNBProcessGetExitInfo(nub_process_t pid) DNB_EXPORT;
+nub_bool_t DNBProcessSetExitInfo(nub_process_t pid,
+ const char *info) DNB_EXPORT;
+nub_size_t DNBProcessGetNumThreads(nub_process_t pid) DNB_EXPORT;
+nub_thread_t DNBProcessGetCurrentThread(nub_process_t pid) DNB_EXPORT;
+nub_thread_t DNBProcessGetCurrentThreadMachPort(nub_process_t pid) DNB_EXPORT;
+nub_thread_t DNBProcessSetCurrentThread(nub_process_t pid,
+ nub_thread_t tid) DNB_EXPORT;
+nub_thread_t DNBProcessGetThreadAtIndex(nub_process_t pid,
+ nub_size_t thread_idx) DNB_EXPORT;
+nub_bool_t DNBProcessSyncThreadState(nub_process_t pid,
+ nub_thread_t tid) DNB_EXPORT;
+nub_addr_t DNBProcessGetSharedLibraryInfoAddress(nub_process_t pid) DNB_EXPORT;
+nub_bool_t DNBProcessSharedLibrariesUpdated(nub_process_t pid) DNB_EXPORT;
+nub_size_t
+DNBProcessGetSharedLibraryInfo(nub_process_t pid, nub_bool_t only_changed,
+ DNBExecutableImageInfo **image_infos) DNB_EXPORT;
+nub_bool_t DNBProcessSetNameToAddressCallback(nub_process_t pid,
+ DNBCallbackNameToAddress callback,
+ void *baton) DNB_EXPORT;
+nub_bool_t DNBProcessSetSharedLibraryInfoCallback(
+ nub_process_t pid, DNBCallbackCopyExecutableImageInfos callback,
+ void *baton) DNB_EXPORT;
+nub_addr_t DNBProcessLookupAddress(nub_process_t pid, const char *name,
+ const char *shlib) DNB_EXPORT;
+nub_size_t DNBProcessGetAvailableSTDOUT(nub_process_t pid, char *buf,
+ nub_size_t buf_size) DNB_EXPORT;
+nub_size_t DNBProcessGetAvailableSTDERR(nub_process_t pid, char *buf,
+ nub_size_t buf_size) DNB_EXPORT;
+nub_size_t DNBProcessGetAvailableProfileData(nub_process_t pid, char *buf,
+ nub_size_t buf_size) DNB_EXPORT;
+nub_size_t DNBProcessGetStopCount(nub_process_t pid) DNB_EXPORT;
+uint32_t DNBProcessGetCPUType(nub_process_t pid) DNB_EXPORT;
//----------------------------------------------------------------------
// Process executable and arguments
//----------------------------------------------------------------------
-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);
+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);
+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);
+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);
+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);
+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);
+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);
+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
index f17a719e92ec..1312bcf7dfdd 100644
--- a/tools/debugserver/source/DNBArch.cpp
+++ b/tools/debugserver/source/DNBArch.cpp
@@ -24,74 +24,57 @@ 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;
+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; }
-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;
+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;
+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;
+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::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;
-
+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;
+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
index c07d3a67400d..317da70e6422 100644
--- a/tools/debugserver/source/DNBArch.h
+++ b/tools/debugserver/source/DNBArch.h
@@ -25,105 +25,103 @@ 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;
+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
-{
+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; }
+ 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
-
+ 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/x86_64/DNBArchImplX86_64.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
index 2645f173306b..89a91287f9e3 100644
--- a/tools/debugserver/source/DNBBreakpoint.cpp
+++ b/tools/debugserver/source/DNBBreakpoint.cpp
@@ -12,214 +12,167 @@
//===----------------------------------------------------------------------===//
#include "DNBBreakpoint.h"
+#include "DNBLog.h"
#include "MachProcess.h"
-#include <assert.h>
#include <algorithm>
+#include <assert.h>
#include <inttypes.h>
-#include "DNBLog.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);
+#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;
-}
-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;
+ return NULL;
}
-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;
-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;
+ 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;
- }
- }
+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);
}
- 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);
- }
+ 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::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::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;
- }
+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
index c764dbd6cf29..889478b28957 100644
--- a/tools/debugserver/source/DNBBreakpoint.h
+++ b/tools/debugserver/source/DNBBreakpoint.h
@@ -23,143 +23,127 @@
class MachProcess;
-class DNBBreakpoint
-{
+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;
- }
+ 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
+ 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
-{
+class DNBBreakpointList {
public:
- DNBBreakpointList();
- ~DNBBreakpointList();
+ 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;
- 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);
- size_t FindBreakpointsThatOverlapRange (nub_addr_t addr,
- nub_addr_t size,
- std::vector<DNBBreakpoint *> &bps);
+ void Dump() const;
- void Dump () const;
+ size_t Size() const { return m_breakpoints.size(); }
+ void DisableAll();
- size_t Size() const { return m_breakpoints.size(); }
- void DisableAll ();
+ void RemoveTrapsFromBuffer(nub_addr_t addr, nub_size_t size, void *buf) const;
- void RemoveTrapsFromBuffer (nub_addr_t addr,
- nub_size_t size,
- void *buf) const;
+ void DisableAllBreakpoints(MachProcess *process);
+ void DisableAllWatchpoints(MachProcess *process);
+ void RemoveDisabled();
- 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;
+ 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
index d52f28ee2fb9..d7dce1ab7338 100644
--- a/tools/debugserver/source/DNBDataRef.cpp
+++ b/tools/debugserver/source/DNBDataRef.cpp
@@ -21,165 +21,139 @@
// 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)
-{
-}
-
+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)
-{
-}
-
+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()
-{
-}
-
+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;
+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;
- val = *(uint16_t*)p;
-
- if (m_swap)
- val = OSSwapInt16(val);
-
- // Advance the offset
- *offset_ptr += sizeof(val);
- }
- return val;
+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;
+ val = *(uint16_t *)p;
+
+ 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;
- val = *(uint32_t*)p;
- if (m_swap)
- val = OSSwapInt32(val);
-
- // Advance the offset
- *offset_ptr += sizeof(val);
- }
- return val;
+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;
+ val = *(uint32_t *)p;
+ 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;
- val = *(uint64_t*)p;
- if (m_swap)
- val = OSSwapInt64(val);
-
- // Advance the offset
- *offset_ptr += sizeof(val);
- }
- return val;
+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;
+ val = *(uint64_t *)p;
+ 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(!"GetMax32 unhandled case!");
- break;
- }
- return 0;
+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(!"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(!"GetMax64 unhandled case!");
- break;
- }
- return 0;
+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(!"GetMax64 unhandled case!");
+ break;
+ }
+ return 0;
}
//----------------------------------------------------------------------
@@ -188,198 +162,190 @@ DNBDataRef::GetMax64(offset_t *offset_ptr, uint32_t size) const
// 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);
+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 = (char*)m_start + *offset_ptr;
-
- // Advance the offset
- if (fixed_length)
- *offset_ptr += fixed_length;
- else
- *offset_ptr += strlen(s) + 1;
- }
- return s;
+const char *DNBDataRef::GetCStr(offset_t *offset_ptr,
+ uint32_t fixed_length) const {
+ const char *s = NULL;
+ if (m_start < m_end) {
+ s = (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;
+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;
+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;
}
- return result;
-}
+ *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;
+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;
}
- return result;
-}
+ // 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;
- }
+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;
- }
+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)));
}
- if (str[0] != '\0')
- DNBLog("%s", str);
+ // 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
+ return offset; // Return the offset at which we ended up
}
diff --git a/tools/debugserver/source/DNBDataRef.h b/tools/debugserver/source/DNBDataRef.h
index d0c34ced6233..9a19f20227e6 100644
--- a/tools/debugserver/source/DNBDataRef.h
+++ b/tools/debugserver/source/DNBDataRef.h
@@ -24,102 +24,102 @@
#define __DNBDataRef_h__
#include "DNBDefs.h"
+#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
-#include <limits.h>
-class DNBDataRef
-{
+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;
+ // 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;
+ }
- 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;
+ }
- 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;
+ }
- 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;
- 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);
- 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;
+ 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
index e3757e903e59..5762bd16e2b7 100644
--- a/tools/debugserver/source/DNBDefs.h
+++ b/tools/debugserver/source/DNBDefs.h
@@ -14,8 +14,8 @@
#ifndef __DNBDefs_h__
#define __DNBDefs_h__
-#include <stdint.h>
#include <signal.h>
+#include <stdint.h>
#include <stdio.h>
#include <sys/syslimits.h>
#include <unistd.h>
@@ -23,22 +23,24 @@
//----------------------------------------------------------------------
// Define nub_addr_t and the invalid address value from the architecture
//----------------------------------------------------------------------
-#if defined (__x86_64__) || defined (__ppc64__) || defined (__arm64__) || defined (__aarch64__)
+#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)
+typedef uint64_t nub_addr_t;
+#define INVALID_NUB_ADDRESS ((nub_addr_t)~0ull)
-#elif defined (__i386__) || defined (__powerpc__) || defined (__ppc__) || defined (__arm__)
+#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)
+typedef uint32_t nub_addr_t;
+#define INVALID_NUB_ADDRESS ((nub_addr_t)~0ul)
#else
@@ -47,326 +49,325 @@ typedef uint32_t nub_addr_t;
//----------------------------------------------------------------------
#warning undefined architecture, defaulting to 8 byte addresses
-typedef uint64_t nub_addr_t;
-#define INVALID_NUB_ADDRESS ((nub_addr_t)~0ull)
-
+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
+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
+#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,
+typedef enum {
+ eLaunchFlavorDefault = 0,
+ eLaunchFlavorPosixSpawn = 1,
+ eLaunchFlavorForkExec = 2,
#ifdef WITH_SPRINGBOARD
- eLaunchFlavorSpringBoard = 3,
+ eLaunchFlavorSpringBoard = 3,
#endif
#ifdef WITH_BKS
- eLaunchFlavorBKS = 4,
+ eLaunchFlavorBKS = 4,
#endif
#ifdef WITH_FBS
- eLaunchFlavorFBS = 5
+ 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 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_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
+#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
+#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
+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 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 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
+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 DNBThreadStopType {
+ eStopTypeInvalid = 0,
+ eStopTypeSignal,
+ eStopTypeException,
+ eStopTypeExec
};
-enum DNBMemoryPermissions
-{
- eMemoryPermissionsWritable = (1 << 0),
- eMemoryPermissionsReadable = (1 << 1),
- eMemoryPermissionsExecutable = (1 << 2)
+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
+#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 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[32];
- int16_t v_sint16[16];
- int32_t v_sint32[8];
- int64_t v_sint64[4];
- uint8_t v_uint8[32];
- uint16_t v_uint16[16];
- uint32_t v_uint32[8];
- uint64_t v_uint64[4];
- float v_float32[8];
- double v_float64[4];
- void *pointer;
- char *c_str;
- } value;
+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[32];
+ int16_t v_sint16[16];
+ int32_t v_sint32[8];
+ int64_t v_sint64[4];
+ uint8_t v_uint8[32];
+ uint16_t v_uint16[16];
+ uint32_t v_uint32[8];
+ uint64_t v_uint64[4];
+ float v_float32[8];
+ double v_float64[4];
+ void *pointer;
+ char *c_str;
+ } value;
};
-enum DNBSharedLibraryState
-{
- eShlibStateUnloaded = 0,
- eShlibStateLoaded = 1
-};
+enum DNBSharedLibraryState { eShlibStateUnloaded = 0, eShlibStateLoaded = 1 };
#ifndef DNB_MAX_SEGMENT_NAME_LENGTH
-#define DNB_MAX_SEGMENT_NAME_LENGTH 32
+#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 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 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;
+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), // By default, excludes eProfileMemoryDirtyPage.
- eProfileMemoryDirtyPage = (1 << 7), // Assume eProfileMemory, get Dirty Page size as well.
- eProfileMemoryAnonymous = (1 << 8), // Assume eProfileMemory, get Anonymous memory as well.
-
- eProfileEnergy = (1 << 9),
-
- eProfileAll = 0xffffffff
+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), // By default, excludes eProfileMemoryDirtyPage.
+ eProfileMemoryDirtyPage =
+ (1 << 7), // Assume eProfileMemory, get Dirty Page size as well.
+ eProfileMemoryAnonymous =
+ (1 << 8), // Assume eProfileMemory, get Anonymous memory as well.
+
+ eProfileEnergy = (1 << 9),
+
+ 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);
+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__
+#endif // #ifndef __DNBDefs_h__
diff --git a/tools/debugserver/source/DNBError.cpp b/tools/debugserver/source/DNBError.cpp
index c9d8ebd58d89..cd04358a4eca 100644
--- a/tools/debugserver/source/DNBError.cpp
+++ b/tools/debugserver/source/DNBError.cpp
@@ -20,109 +20,97 @@
#include <SpringBoardServices/SpringBoardServer.h>
#endif
-const char *
-DNBError::AsString() const
-{
- if (Success())
- return NULL;
+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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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);
+ default:
+ break;
}
- if (m_str.empty())
- return NULL;
- return m_str.c_str();
+ 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);
+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);
- }
+ 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);
+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);
+ 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
index 274ae0d44773..edca38ad6db7 100644
--- a/tools/debugserver/source/DNBError.h
+++ b/tools/debugserver/source/DNBError.h
@@ -19,84 +19,80 @@
#include <stdio.h>
#include <string>
-class DNBError
-{
+class DNBError {
public:
- typedef uint32_t ValueType;
- typedef enum
- {
- Generic = 0,
- MachKernel = 1,
- POSIX = 2
+ typedef uint32_t ValueType;
+ typedef enum {
+ Generic = 0,
+ MachKernel = 1,
+ POSIX = 2
#ifdef WITH_SPRINGBOARD
- , SpringBoard = 3
+ ,
+ SpringBoard = 3
#endif
#ifdef WITH_BKS
- , BackBoard = 4
+ ,
+ BackBoard = 4
#endif
#ifdef WITH_FBS
- , FrontBoard = 5
+ ,
+ FrontBoard = 5
#endif
- } FlavorType;
+ } FlavorType;
- explicit DNBError( ValueType err = 0,
- FlavorType flavor = Generic) :
- m_err(err),
- m_flavor(flavor)
- {
- }
+ 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 Error() const { return m_err; }
- FlavorType Flavor() const { return m_flavor; }
+ const char *AsString() const;
+ void Clear() {
+ m_err = 0;
+ m_flavor = Generic;
+ m_str.clear();
+ }
+ ValueType Error() 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;
- }
+ 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 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 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();
- }
+ 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;
- // 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;
+ ValueType m_err;
+ FlavorType m_flavor;
+ mutable std::string m_str;
};
-
-#endif // #ifndef __DNBError_h__
+#endif // #ifndef __DNBError_h__
diff --git a/tools/debugserver/source/DNBLog.cpp b/tools/debugserver/source/DNBLog.cpp
index 18d8d2ad3a67..c3d42a2a84da 100644
--- a/tools/debugserver/source/DNBLog.cpp
+++ b/tools/debugserver/source/DNBLog.cpp
@@ -16,362 +16,272 @@
static int g_debug = 0;
static int g_verbose = 0;
-#if defined (DNBLOG_ENABLED)
+#if defined(DNBLOG_ENABLED)
-#include <stdio.h>
+#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>
-#include <mach/mach.h>
-#include <pthread.h>
-#include "PThreadMutex.h"
uint32_t g_log_bits = 0;
static DNBCallbackLog g_log_callback = NULL;
static void *g_log_baton = NULL;
+int DNBLogGetDebug() { return g_debug; }
-int
-DNBLogGetDebug ()
-{
- return g_debug;
-}
-
+void DNBLogSetDebug(int g) { g_debug = g; }
-void
-DNBLogSetDebug (int g)
-{
- g_debug = g;
-}
+int DNBLogGetVerbose() { return g_verbose; }
-int
-DNBLogGetVerbose ()
-{
- return g_verbose;
-}
+void DNBLogSetVerbose(int v) { g_verbose = v; }
-void
-DNBLogSetVerbose (int v)
-{
- g_verbose = v;
-}
+bool DNBLogCheckLogBit(uint32_t bit) { return (g_log_bits & bit) != 0; }
-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
-DNBLogSetLogMask (uint32_t mask)
-{
- uint32_t old = g_log_bits;
- g_log_bits = mask;
- return old;
-}
+uint32_t DNBLogGetLogMask() { return g_log_bits; }
-uint32_t
-DNBLogGetLogMask ()
-{
- return g_log_bits;
+void DNBLogSetLogCallback(DNBCallbackLog callback, void *baton) {
+ g_log_callback = callback;
+ g_log_baton = baton;
}
-void
-DNBLogSetLogCallback (DNBCallbackLog callback, void *baton)
-{
- g_log_callback = callback;
- g_log_baton = baton;
-}
+DNBCallbackLog DNBLogGetLogCallback() { return g_log_callback; }
-DNBCallbackLog
-DNBLogGetLogCallback ()
-{
- return g_log_callback;
-}
+bool DNBLogEnabled() { return g_log_callback != NULL; }
-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);
-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);
+ 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);
+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);
- }
+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);
- }
+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);
- }
+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);
- }
+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);
- }
+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);
+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);
- }
+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);
- }
+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);
- }
+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
index 01add065abcd..65181caa412d 100644
--- a/tools/debugserver/source/DNBLog.h
+++ b/tools/debugserver/source/DNBLog.h
@@ -14,78 +14,135 @@
#ifndef __DNBLog_h__
#define __DNBLog_h__
-#include <stdio.h>
-#include <stdint.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)
+// 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)
+#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);
+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)
+#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)
+#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)
+#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)
diff --git a/tools/debugserver/source/DNBRegisterInfo.cpp b/tools/debugserver/source/DNBRegisterInfo.cpp
index acc7ba9946be..fadcc5ddb06e 100644
--- a/tools/debugserver/source/DNBRegisterInfo.cpp
+++ b/tools/debugserver/source/DNBRegisterInfo.cpp
@@ -15,205 +15,237 @@
#include "DNBLog.h"
#include <string.h>
-DNBRegisterValueClass::DNBRegisterValueClass(const DNBRegisterInfo *regInfo)
-{
- Clear();
- if (regInfo)
- info = *regInfo;
+DNBRegisterValueClass::DNBRegisterValueClass(const DNBRegisterInfo *regInfo) {
+ Clear();
+ if (regInfo)
+ info = *regInfo;
}
-void
-DNBRegisterValueClass::Clear()
-{
- memset(&info, 0, sizeof(DNBRegisterInfo));
- memset(&value, 0, sizeof(value));
+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);
+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) { strncpy(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:
- strncpy(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;
- }
+#define PRINT_COMMA_SEPARATOR \
+ do { \
+ if (pos < end) { \
+ if (i > 0) { \
+ strncpy(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:
+ strncpy(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;
}
- 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);
- 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;
+ 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);
+ 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;
- DNBLog("%s%4s = %s%s", pre ? pre : "", info.name, str, post ? post : "");
+ 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
index 666c397e0b5e..d665e3cb9485 100644
--- a/tools/debugserver/source/DNBRegisterInfo.h
+++ b/tools/debugserver/source/DNBRegisterInfo.h
@@ -14,17 +14,16 @@
#ifndef __DNBRegisterInfo_h__
#define __DNBRegisterInfo_h__
+#include "DNBDefs.h"
#include <stdint.h>
#include <stdio.h>
-#include "DNBDefs.h"
-struct DNBRegisterValueClass : public DNBRegisterValue
-{
+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;
+ DNBRegisterValueClass(const DNBRegisterInfo *regInfo = NULL);
+ void Clear();
+ void Dump(const char *pre, const char *post) const;
+ bool IsValid() const;
#endif
};
diff --git a/tools/debugserver/source/DNBRuntimeAction.h b/tools/debugserver/source/DNBRuntimeAction.h
index d77bda8c604d..85d7bc1df0a5 100644
--- a/tools/debugserver/source/DNBRuntimeAction.h
+++ b/tools/debugserver/source/DNBRuntimeAction.h
@@ -14,12 +14,11 @@
#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;
+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
index b50dd0617843..4a97abc20e24 100644
--- a/tools/debugserver/source/DNBThreadResumeActions.cpp
+++ b/tools/debugserver/source/DNBThreadResumeActions.cpp
@@ -13,104 +13,77 @@
#include "DNBThreadResumeActions.h"
-DNBThreadResumeActions::DNBThreadResumeActions() :
- m_actions (),
- m_signal_handled ()
-{
-}
+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(
+ 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);
+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::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);
+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;
+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;
+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;
+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;
- }
+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
index 81c7c43b7222..40d2da03e9e4 100644
--- a/tools/debugserver/source/DNBThreadResumeActions.h
+++ b/tools/debugserver/source/DNBThreadResumeActions.h
@@ -11,7 +11,6 @@
//
//===----------------------------------------------------------------------===//
-
#ifndef __DNBThreadResumeActions_h__
#define __DNBThreadResumeActions_h__
@@ -19,84 +18,49 @@
#include "DNBDefs.h"
-
-class DNBThreadResumeActions
-{
+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();
- }
+ 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;
+ std::vector<DNBThreadResumeAction> m_actions;
+ mutable std::vector<bool> m_signal_handled;
};
-
-#endif // #ifndef __DNBThreadResumeActions_h__
+#endif // #ifndef __DNBThreadResumeActions_h__
diff --git a/tools/debugserver/source/DNBTimer.h b/tools/debugserver/source/DNBTimer.h
index ca56e30c7090..881b8cdcde76 100644
--- a/tools/debugserver/source/DNBTimer.h
+++ b/tools/debugserver/source/DNBTimer.h
@@ -14,150 +14,132 @@
#ifndef __DNBTimer_h__
#define __DNBTimer_h__
-#include <sys/time.h>
-#include <stdint.h>
-#include <memory>
#include "DNBDefs.h"
#include "PThreadMutex.h"
+#include <memory>
+#include <stdint.h>
+#include <sys/time.h>
-class DNBTimer
-{
+class DNBTimer {
public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- DNBTimer (bool threadSafe) :
- m_mutexAP()
- {
- if (threadSafe)
- m_mutexAP.reset(new PThreadMutex(PTHREAD_MUTEX_RECURSIVE));
- Reset();
- }
+ //------------------------------------------------------------------
+ // 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 (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& 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() {}
- ~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;
+ }
- 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;
+ }
- 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 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;
+ }
+ }
- 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;
+ //------------------------------------------------------------------
+ // 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
new file mode 100644
index 000000000000..19ebfd000f51
--- /dev/null
+++ b/tools/debugserver/source/JSON.cpp
@@ -0,0 +1,588 @@
+//===--------------------- 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;
+ }
+ assert("Unhandled data type");
+}
+
+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;
+ }
+ assert("Unhandled data type");
+}
+
+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;
+ }
+ assert("Unhandled data type");
+}
+
+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::Error;
+
+ } 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::Error;
+ }
+ } else if (is_end_quote) {
+ return Token::String;
+ } else if (is_null) {
+ value = "error: missing end quote for string";
+ return Token::Error;
+ }
+ }
+ }
+ } 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::Error;
+ } 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::Error;
+ } 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::Error;
+ }
+ 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::Error;
+ }
+ } 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::Error;
+ }
+ }
+ } 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::Error;
+ }
+ }
+ } else {
+ error << "error: invalid number found at offset " << start_index;
+ value = error.str();
+ return Token::Error;
+ }
+ } break;
+ default:
+ break;
+ }
+ error << "error: failed to parse token at offset " << start_index
+ << " (around character '" << ch << "')";
+ value = error.str();
+ return Token::Error;
+}
+
+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
new file mode 100644
index 000000000000..eee62f453327
--- /dev/null
+++ b/tools/debugserver/source/JSON.h
@@ -0,0 +1,303 @@
+//===---------------------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,
+ Error,
+ 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
index 423b2bd57927..a85dcb6e8608 100644
--- a/tools/debugserver/source/JSONGenerator.h
+++ b/tools/debugserver/source/JSONGenerator.h
@@ -29,462 +29,291 @@
/// and printing it as a JSON string.
//----------------------------------------------------------------------
-class JSONGenerator
-{
+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 Object;