aboutsummaryrefslogtreecommitdiffstats
path: root/source/Plugins/Process
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 /source/Plugins/Process
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 'source/Plugins/Process')
-rw-r--r--source/Plugins/Process/CMakeLists.txt3
-rw-r--r--source/Plugins/Process/Darwin/CFBundle.cpp79
-rw-r--r--source/Plugins/Process/Darwin/CFBundle.h38
-rw-r--r--source/Plugins/Process/Darwin/CFString.cpp163
-rw-r--r--source/Plugins/Process/Darwin/CFString.h43
-rw-r--r--source/Plugins/Process/Darwin/CFUtils.h78
-rw-r--r--source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp653
-rw-r--r--source/Plugins/Process/Darwin/DarwinProcessLauncher.h48
-rw-r--r--source/Plugins/Process/Darwin/LaunchFlavor.h33
-rw-r--r--source/Plugins/Process/Darwin/MachException.cpp543
-rw-r--r--source/Plugins/Process/Darwin/MachException.h140
-rw-r--r--source/Plugins/Process/Darwin/NativeProcessDarwin.cpp1576
-rw-r--r--source/Plugins/Process/Darwin/NativeProcessDarwin.h384
-rw-r--r--source/Plugins/Process/Darwin/NativeThreadDarwin.cpp284
-rw-r--r--source/Plugins/Process/Darwin/NativeThreadDarwin.h178
-rw-r--r--source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp698
-rw-r--r--source/Plugins/Process/Darwin/NativeThreadListDarwin.h139
-rw-r--r--source/Plugins/Process/FreeBSD/FreeBSDThread.cpp1089
-rw-r--r--source/Plugins/Process/FreeBSD/FreeBSDThread.h163
-rw-r--r--source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp69
-rw-r--r--source/Plugins/Process/FreeBSD/POSIXStopInfo.h68
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp1476
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessFreeBSD.h286
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessMonitor.cpp2144
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessMonitor.h460
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h73
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp428
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.h89
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp423
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.h90
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp413
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.h90
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp452
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.h102
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp1037
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.h93
-rw-r--r--source/Plugins/Process/Linux/NativeProcessLinux.cpp4619
-rw-r--r--source/Plugins/Process/Linux/NativeProcessLinux.h297
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp315
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux.h105
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp1626
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h219
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp1635
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h220
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp2144
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h166
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp1050
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h131
-rwxr-xr-xsource/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp2096
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h191
-rw-r--r--source/Plugins/Process/Linux/NativeThreadLinux.cpp758
-rw-r--r--source/Plugins/Process/Linux/NativeThreadLinux.h145
-rw-r--r--source/Plugins/Process/Linux/ProcFileReader.cpp139
-rw-r--r--source/Plugins/Process/Linux/ProcFileReader.h24
-rw-r--r--source/Plugins/Process/Linux/Procfs.h14
-rw-r--r--source/Plugins/Process/Linux/SingleStepCheck.cpp249
-rw-r--r--source/Plugins/Process/Linux/SingleStepCheck.h35
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp2403
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h547
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp1834
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h417
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp302
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h55
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp224
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h53
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp227
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h56
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp170
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h48
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp171
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h49
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp268
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h101
-rw-r--r--source/Plugins/Process/POSIX/CrashReason.cpp577
-rw-r--r--source/Plugins/Process/POSIX/CrashReason.h74
-rw-r--r--source/Plugins/Process/POSIX/ProcessMessage.cpp103
-rw-r--r--source/Plugins/Process/POSIX/ProcessMessage.h299
-rw-r--r--source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp311
-rw-r--r--source/Plugins/Process/POSIX/ProcessPOSIXLog.h169
-rw-r--r--source/Plugins/Process/Utility/ARMDefines.h255
-rw-r--r--source/Plugins/Process/Utility/ARMUtils.h567
-rw-r--r--source/Plugins/Process/Utility/CMakeLists.txt3
-rw-r--r--source/Plugins/Process/Utility/DynamicRegisterInfo.cpp1379
-rw-r--r--source/Plugins/Process/Utility/DynamicRegisterInfo.h115
-rw-r--r--source/Plugins/Process/Utility/FreeBSDSignals.cpp146
-rw-r--r--source/Plugins/Process/Utility/FreeBSDSignals.h8
-rw-r--r--source/Plugins/Process/Utility/GDBRemoteSignals.cpp16
-rw-r--r--source/Plugins/Process/Utility/GDBRemoteSignals.h10
-rw-r--r--source/Plugins/Process/Utility/HistoryThread.cpp106
-rw-r--r--source/Plugins/Process/Utility/HistoryThread.h158
-rw-r--r--source/Plugins/Process/Utility/HistoryUnwind.cpp86
-rw-r--r--source/Plugins/Process/Utility/HistoryUnwind.h31
-rw-r--r--source/Plugins/Process/Utility/InferiorCallPOSIX.cpp386
-rw-r--r--source/Plugins/Process/Utility/InferiorCallPOSIX.h8
-rw-r--r--source/Plugins/Process/Utility/InstructionUtils.h138
-rw-r--r--source/Plugins/Process/Utility/LinuxSignals.cpp153
-rw-r--r--source/Plugins/Process/Utility/LinuxSignals.h8
-rw-r--r--source/Plugins/Process/Utility/MipsLinuxSignals.cpp156
-rw-r--r--source/Plugins/Process/Utility/MipsLinuxSignals.h11
-rw-r--r--source/Plugins/Process/Utility/NetBSDSignals.cpp22
-rw-r--r--source/Plugins/Process/Utility/NetBSDSignals.h8
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp2654
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_arm.h447
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp1673
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h428
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp1582
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_i386.h393
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp1756
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h434
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDummy.cpp148
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDummy.h76
-rw-r--r--source/Plugins/Process/Utility/RegisterContextFreeBSD_arm.cpp100
-rw-r--r--source/Plugins/Process/Utility/RegisterContextFreeBSD_arm.h98
-rw-r--r--source/Plugins/Process/Utility/RegisterContextFreeBSD_arm64.cpp86
-rw-r--r--source/Plugins/Process/Utility/RegisterContextFreeBSD_arm64.h78
-rw-r--r--source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp102
-rw-r--r--source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.h15
-rw-r--r--source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp120
-rw-r--r--source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h16
-rw-r--r--source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp406
-rw-r--r--source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h55
-rw-r--r--source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp222
-rw-r--r--source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h20
-rw-r--r--source/Plugins/Process/Utility/RegisterContextHistory.cpp151
-rw-r--r--source/Plugins/Process/Utility/RegisterContextHistory.h80
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLLDB.cpp3704
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLLDB.h437
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_arm.cpp100
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_arm.h99
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_arm64.cpp89
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_arm64.h80
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp200
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_i386.h24
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp62
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_mips.h23
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp139
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_mips64.h29
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp95
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_s390x.h29
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp304
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h31
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp252
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h59
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMach_arm.cpp72
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMach_arm.h49
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMach_i386.cpp57
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMach_i386.h45
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp60
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMach_x86_64.h48
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMemory.cpp204
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMemory.h107
-rw-r--r--source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp570
-rw-r--r--source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h20
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp385
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h158
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp376
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h157
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp265
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h83
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp368
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h330
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp291
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h111
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp1032
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h323
-rw-r--r--source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp390
-rw-r--r--source/Plugins/Process/Utility/RegisterContextThreadMemory.h163
-rw-r--r--source/Plugins/Process/Utility/RegisterContext_mips.h702
-rw-r--r--source/Plugins/Process/Utility/RegisterContext_powerpc.h219
-rw-r--r--source/Plugins/Process/Utility/RegisterContext_s390x.h148
-rw-r--r--source/Plugins/Process/Utility/RegisterContext_x86.h553
-rw-r--r--source/Plugins/Process/Utility/RegisterInfoInterface.h99
-rw-r--r--source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp99
-rw-r--r--source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h70
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_arm.h2027
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_arm64.h956
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_i386.h385
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_mips.h59
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_mips64.h198
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_powerpc.h329
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_s390x.h93
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_x86_64.h728
-rw-r--r--source/Plugins/Process/Utility/StopInfoMachException.cpp1019
-rw-r--r--source/Plugins/Process/Utility/StopInfoMachException.h71
-rw-r--r--source/Plugins/Process/Utility/ThreadMemory.cpp171
-rw-r--r--source/Plugins/Process/Utility/ThreadMemory.h201
-rw-r--r--source/Plugins/Process/Utility/UnwindLLDB.cpp879
-rw-r--r--source/Plugins/Process/Utility/UnwindLLDB.h248
-rw-r--r--source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp443
-rw-r--r--source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h68
-rw-r--r--source/Plugins/Process/Utility/lldb-arm-register-enums.h363
-rw-r--r--source/Plugins/Process/Utility/lldb-arm64-register-enums.h397
-rw-r--r--source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h106
-rw-r--r--source/Plugins/Process/Utility/lldb-mips-linux-register-enums.h522
-rw-r--r--source/Plugins/Process/Utility/lldb-s390x-register-enums.h139
-rw-r--r--source/Plugins/Process/Utility/lldb-x86-register-enums.h558
-rw-r--r--source/Plugins/Process/Windows/Common/CMakeLists.txt4
-rw-r--r--source/Plugins/Process/Windows/Common/DebuggerThread.cpp549
-rw-r--r--source/Plugins/Process/Windows/Common/DebuggerThread.h106
-rw-r--r--source/Plugins/Process/Windows/Common/ExceptionRecord.h105
-rw-r--r--source/Plugins/Process/Windows/Common/ForwardDecl.h (renamed from source/Plugins/Process/Windows/Live/ForwardDecl.h)19
-rw-r--r--source/Plugins/Process/Windows/Common/IDebugDelegate.h (renamed from source/Plugins/Process/Windows/Live/IDebugDelegate.h)30
-rw-r--r--source/Plugins/Process/Windows/Common/LocalDebugDelegate.cpp73
-rw-r--r--source/Plugins/Process/Windows/Common/LocalDebugDelegate.h (renamed from source/Plugins/Process/Windows/Live/LocalDebugDelegate.h)51
-rw-r--r--source/Plugins/Process/Windows/Common/NtStructures.h23
-rw-r--r--source/Plugins/Process/Windows/Common/ProcessWindows.cpp1067
-rw-r--r--source/Plugins/Process/Windows/Common/ProcessWindows.h117
-rw-r--r--source/Plugins/Process/Windows/Common/ProcessWindowsLog.cpp260
-rw-r--r--source/Plugins/Process/Windows/Common/ProcessWindowsLog.h151
-rw-r--r--source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp168
-rw-r--r--source/Plugins/Process/Windows/Common/RegisterContextWindows.h64
-rw-r--r--source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp143
-rw-r--r--source/Plugins/Process/Windows/Common/TargetThreadWindows.h53
-rw-r--r--source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp437
-rw-r--r--source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.h40
-rw-r--r--source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp361
-rw-r--r--source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.h45
-rw-r--r--source/Plugins/Process/Windows/Live/CMakeLists.txt24
-rw-r--r--source/Plugins/Process/Windows/Live/DebuggerThread.cpp549
-rw-r--r--source/Plugins/Process/Windows/Live/DebuggerThread.h100
-rw-r--r--source/Plugins/Process/Windows/Live/LocalDebugDelegate.cpp91
-rw-r--r--source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp1069
-rw-r--r--source/Plugins/Process/Windows/Live/ProcessWindowsLive.h125
-rw-r--r--source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.cpp147
-rw-r--r--source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.h55
-rw-r--r--source/Plugins/Process/Windows/Live/x64/RegisterContextWindowsLive_x64.cpp171
-rw-r--r--source/Plugins/Process/Windows/Live/x64/RegisterContextWindowsLive_x64.h40
-rw-r--r--source/Plugins/Process/Windows/Live/x86/RegisterContextWindowsLive_x86.cpp100
-rw-r--r--source/Plugins/Process/Windows/Live/x86/RegisterContextWindowsLive_x86.h36
-rw-r--r--source/Plugins/Process/Windows/MiniDump/CMakeLists.txt21
-rw-r--r--source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp710
-rw-r--r--source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h104
-rw-r--r--source/Plugins/Process/Windows/MiniDump/ThreadWinMiniDump.cpp104
-rw-r--r--source/Plugins/Process/Windows/MiniDump/ThreadWinMiniDump.h49
-rw-r--r--source/Plugins/Process/Windows/MiniDump/x64/RegisterContextWindowsMiniDump_x64.cpp47
-rw-r--r--source/Plugins/Process/Windows/MiniDump/x64/RegisterContextWindowsMiniDump_x64.h36
-rw-r--r--source/Plugins/Process/Windows/MiniDump/x86/RegisterContextWindowsMiniDump_x86.cpp47
-rw-r--r--source/Plugins/Process/Windows/MiniDump/x86/RegisterContextWindowsMiniDump_x86.h36
-rw-r--r--source/Plugins/Process/elf-core/ProcessElfCore.cpp1077
-rw-r--r--source/Plugins/Process/elf-core/ProcessElfCore.h229
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp102
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h55
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp102
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h55
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp102
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h55
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp169
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h70
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp138
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h54
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp127
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h51
-rw-r--r--source/Plugins/Process/elf-core/ThreadElfCore.cpp496
-rw-r--r--source/Plugins/Process/elf-core/ThreadElfCore.h296
-rw-r--r--source/Plugins/Process/gdb-remote/CMakeLists.txt1
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp376
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h144
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp2469
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h538
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp7509
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h1188
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp154
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h61
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp2074
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h205
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp5426
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h364
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp896
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h128
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp1926
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h181
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp9096
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemote.h711
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp342
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h58
-rw-r--r--source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp569
-rw-r--r--source/Plugins/Process/gdb-remote/ThreadGDBRemote.h154
-rw-r--r--source/Plugins/Process/mach-core/ProcessMachCore.cpp1009
-rw-r--r--source/Plugins/Process/mach-core/ProcessMachCore.h258
-rw-r--r--source/Plugins/Process/mach-core/ThreadMachCore.cpp139
-rw-r--r--source/Plugins/Process/mach-core/ThreadMachCore.h87
-rw-r--r--source/Plugins/Process/minidump/CMakeLists.txt10
-rw-r--r--source/Plugins/Process/minidump/MinidumpParser.cpp458
-rw-r--r--source/Plugins/Process/minidump/MinidumpParser.h102
-rw-r--r--source/Plugins/Process/minidump/MinidumpTypes.cpp235
-rw-r--r--source/Plugins/Process/minidump/MinidumpTypes.h470
-rw-r--r--source/Plugins/Process/minidump/NtStructures.h37
-rw-r--r--source/Plugins/Process/minidump/ProcessMinidump.cpp301
-rw-r--r--source/Plugins/Process/minidump/ProcessMinidump.h105
-rw-r--r--source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp99
-rw-r--r--source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h138
-rw-r--r--source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp113
-rw-r--r--source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.h183
-rw-r--r--source/Plugins/Process/minidump/ThreadMinidump.cpp114
-rw-r--r--source/Plugins/Process/minidump/ThreadMinidump.h52
295 files changed, 64303 insertions, 61823 deletions
diff --git a/source/Plugins/Process/CMakeLists.txt b/source/Plugins/Process/CMakeLists.txt
index d15df94414b3..defa493088b6 100644
--- a/source/Plugins/Process/CMakeLists.txt
+++ b/source/Plugins/Process/CMakeLists.txt
@@ -7,8 +7,6 @@ elseif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
elseif (CMAKE_SYSTEM_NAME MATCHES "NetBSD")
add_subdirectory(POSIX)
elseif (CMAKE_SYSTEM_NAME MATCHES "Windows")
- add_subdirectory(Windows/Live)
- add_subdirectory(Windows/MiniDump)
add_subdirectory(Windows/Common)
elseif (CMAKE_SYSTEM_NAME MATCHES "Darwin")
add_subdirectory(MacOSX-Kernel)
@@ -17,3 +15,4 @@ add_subdirectory(gdb-remote)
add_subdirectory(Utility)
add_subdirectory(mach-core)
add_subdirectory(elf-core)
+add_subdirectory(minidump)
diff --git a/source/Plugins/Process/Darwin/CFBundle.cpp b/source/Plugins/Process/Darwin/CFBundle.cpp
new file mode 100644
index 000000000000..7b080e60cdb3
--- /dev/null
+++ b/source/Plugins/Process/Darwin/CFBundle.cpp
@@ -0,0 +1,79 @@
+//===-- CFBundle.cpp --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Created by Greg Clayton on 1/16/08.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CFBundle.h"
+#include "CFString.h"
+
+//----------------------------------------------------------------------
+// CFBundle constructor
+//----------------------------------------------------------------------
+CFBundle::CFBundle(const char *path)
+ : CFReleaser<CFBundleRef>(), m_bundle_url() {
+ if (path && path[0])
+ SetPath(path);
+}
+
+//----------------------------------------------------------------------
+// CFBundle copy constructor
+//----------------------------------------------------------------------
+CFBundle::CFBundle(const CFBundle &rhs)
+ : CFReleaser<CFBundleRef>(rhs), m_bundle_url(rhs.m_bundle_url) {}
+
+//----------------------------------------------------------------------
+// CFBundle copy constructor
+//----------------------------------------------------------------------
+CFBundle &CFBundle::operator=(const CFBundle &rhs) {
+ *this = rhs;
+ return *this;
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+CFBundle::~CFBundle() {}
+
+//----------------------------------------------------------------------
+// Set the path for a bundle by supplying a
+//----------------------------------------------------------------------
+bool CFBundle::SetPath(const char *path) {
+ CFAllocatorRef alloc = kCFAllocatorDefault;
+ // Release our old bundle and ULR
+ reset(); // This class is a CFReleaser<CFBundleRef>
+ m_bundle_url.reset();
+ // Make a CFStringRef from the supplied path
+ CFString cf_path;
+ cf_path.SetFileSystemRepresentation(path);
+ if (cf_path.get()) {
+ // Make our Bundle URL
+ m_bundle_url.reset(::CFURLCreateWithFileSystemPath(
+ alloc, cf_path.get(), kCFURLPOSIXPathStyle, true));
+ if (m_bundle_url.get()) {
+ reset(::CFBundleCreate(alloc, m_bundle_url.get()));
+ }
+ }
+ return get() != NULL;
+}
+
+CFStringRef CFBundle::GetIdentifier() const {
+ CFBundleRef bundle = get();
+ if (bundle != NULL)
+ return ::CFBundleGetIdentifier(bundle);
+ return NULL;
+}
+
+CFURLRef CFBundle::CopyExecutableURL() const {
+ CFBundleRef bundle = get();
+ if (bundle != NULL)
+ return CFBundleCopyExecutableURL(bundle);
+ return NULL;
+}
diff --git a/source/Plugins/Process/Darwin/CFBundle.h b/source/Plugins/Process/Darwin/CFBundle.h
new file mode 100644
index 000000000000..09957af534b3
--- /dev/null
+++ b/source/Plugins/Process/Darwin/CFBundle.h
@@ -0,0 +1,38 @@
+//===-- CFBundle.h ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Created by Greg Clayton on 1/16/08.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __CFBundle_h__
+#define __CFBundle_h__
+
+#include "CFUtils.h"
+
+class CFBundle : public CFReleaser<CFBundleRef> {
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ CFBundle(const char *path = NULL);
+ CFBundle(const CFBundle &rhs);
+ CFBundle &operator=(const CFBundle &rhs);
+ virtual ~CFBundle();
+ bool SetPath(const char *path);
+
+ CFStringRef GetIdentifier() const;
+
+ CFURLRef CopyExecutableURL() const;
+
+protected:
+ CFReleaser<CFURLRef> m_bundle_url;
+};
+
+#endif // #ifndef __CFBundle_h__
diff --git a/source/Plugins/Process/Darwin/CFString.cpp b/source/Plugins/Process/Darwin/CFString.cpp
new file mode 100644
index 000000000000..84ad56774d7c
--- /dev/null
+++ b/source/Plugins/Process/Darwin/CFString.cpp
@@ -0,0 +1,163 @@
+//===-- CFString.cpp --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Created by Greg Clayton on 1/16/08.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CFString.h"
+#include <glob.h>
+#include <string>
+
+//----------------------------------------------------------------------
+// CFString constructor
+//----------------------------------------------------------------------
+CFString::CFString(CFStringRef s) : CFReleaser<CFStringRef>(s) {}
+
+//----------------------------------------------------------------------
+// CFString copy constructor
+//----------------------------------------------------------------------
+CFString::CFString(const CFString &rhs) : CFReleaser<CFStringRef>(rhs) {}
+
+//----------------------------------------------------------------------
+// CFString copy constructor
+//----------------------------------------------------------------------
+CFString &CFString::operator=(const CFString &rhs) {
+ if (this != &rhs)
+ *this = rhs;
+ return *this;
+}
+
+CFString::CFString(const char *cstr, CFStringEncoding cstr_encoding)
+ : CFReleaser<CFStringRef>() {
+ if (cstr && cstr[0]) {
+ reset(
+ ::CFStringCreateWithCString(kCFAllocatorDefault, cstr, cstr_encoding));
+ }
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+CFString::~CFString() {}
+
+const char *CFString::GetFileSystemRepresentation(std::string &s) {
+ return CFString::FileSystemRepresentation(get(), s);
+}
+
+CFStringRef CFString::SetFileSystemRepresentation(const char *path) {
+ CFStringRef new_value = NULL;
+ if (path && path[0])
+ new_value =
+ ::CFStringCreateWithFileSystemRepresentation(kCFAllocatorDefault, path);
+ reset(new_value);
+ return get();
+}
+
+CFStringRef CFString::SetFileSystemRepresentationFromCFType(CFTypeRef cf_type) {
+ CFStringRef new_value = NULL;
+ if (cf_type != NULL) {
+ CFTypeID cf_type_id = ::CFGetTypeID(cf_type);
+
+ if (cf_type_id == ::CFStringGetTypeID()) {
+ // Retain since we are using the existing object
+ new_value = (CFStringRef)::CFRetain(cf_type);
+ } else if (cf_type_id == ::CFURLGetTypeID()) {
+ new_value =
+ ::CFURLCopyFileSystemPath((CFURLRef)cf_type, kCFURLPOSIXPathStyle);
+ }
+ }
+ reset(new_value);
+ return get();
+}
+
+CFStringRef
+CFString::SetFileSystemRepresentationAndExpandTilde(const char *path) {
+ std::string expanded_path;
+ if (CFString::GlobPath(path, expanded_path))
+ SetFileSystemRepresentation(expanded_path.c_str());
+ else
+ reset();
+ return get();
+}
+
+const char *CFString::UTF8(std::string &str) {
+ return CFString::UTF8(get(), str);
+}
+
+// Static function that puts a copy of the UTF8 contents of CF_STR into STR
+// and returns the C string pointer that is contained in STR when successful,
+// else
+// NULL is returned. This allows the std::string parameter to own the extracted
+// string,
+// and also allows that string to be returned as a C string pointer that can be
+// used.
+
+const char *CFString::UTF8(CFStringRef cf_str, std::string &str) {
+ if (cf_str) {
+ const CFStringEncoding encoding = kCFStringEncodingUTF8;
+ CFIndex max_utf8_str_len = CFStringGetLength(cf_str);
+ max_utf8_str_len =
+ CFStringGetMaximumSizeForEncoding(max_utf8_str_len, encoding);
+ if (max_utf8_str_len > 0) {
+ str.resize(max_utf8_str_len);
+ if (!str.empty()) {
+ if (CFStringGetCString(cf_str, &str[0], str.size(), encoding)) {
+ str.resize(strlen(str.c_str()));
+ return str.c_str();
+ }
+ }
+ }
+ }
+ return NULL;
+}
+
+// Static function that puts a copy of the file system representation of CF_STR
+// into STR and returns the C string pointer that is contained in STR when
+// successful, else NULL is returned. This allows the std::string parameter
+// to own the extracted string, and also allows that string to be returned as
+// a C string pointer that can be used.
+
+const char *CFString::FileSystemRepresentation(CFStringRef cf_str,
+ std::string &str) {
+ if (cf_str) {
+ CFIndex max_length =
+ ::CFStringGetMaximumSizeOfFileSystemRepresentation(cf_str);
+ if (max_length > 0) {
+ str.resize(max_length);
+ if (!str.empty()) {
+ if (::CFStringGetFileSystemRepresentation(cf_str, &str[0],
+ str.size())) {
+ str.erase(::strlen(str.c_str()));
+ return str.c_str();
+ }
+ }
+ }
+ }
+ str.erase();
+ return NULL;
+}
+
+CFIndex CFString::GetLength() const {
+ CFStringRef str = get();
+ if (str)
+ return CFStringGetLength(str);
+ return 0;
+}
+
+const char *CFString::GlobPath(const char *path, std::string &expanded_path) {
+ glob_t globbuf;
+ if (::glob(path, GLOB_TILDE, NULL, &globbuf) == 0) {
+ expanded_path = globbuf.gl_pathv[0];
+ ::globfree(&globbuf);
+ } else
+ expanded_path.clear();
+
+ return expanded_path.c_str();
+}
diff --git a/source/Plugins/Process/Darwin/CFString.h b/source/Plugins/Process/Darwin/CFString.h
new file mode 100644
index 000000000000..18d60a5a74bd
--- /dev/null
+++ b/source/Plugins/Process/Darwin/CFString.h
@@ -0,0 +1,43 @@
+//===-- CFString.h ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Created by Greg Clayton on 1/16/08.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __CFString_h__
+#define __CFString_h__
+
+#include "CFUtils.h"
+#include <iosfwd>
+
+class CFString : public CFReleaser<CFStringRef> {
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ CFString(CFStringRef cf_str = NULL);
+ CFString(const char *s, CFStringEncoding encoding = kCFStringEncodingUTF8);
+ CFString(const CFString &rhs);
+ CFString &operator=(const CFString &rhs);
+ virtual ~CFString();
+
+ const char *GetFileSystemRepresentation(std::string &str);
+ CFStringRef SetFileSystemRepresentation(const char *path);
+ CFStringRef SetFileSystemRepresentationFromCFType(CFTypeRef cf_type);
+ CFStringRef SetFileSystemRepresentationAndExpandTilde(const char *path);
+ const char *UTF8(std::string &str);
+ CFIndex GetLength() const;
+ static const char *UTF8(CFStringRef cf_str, std::string &str);
+ static const char *FileSystemRepresentation(CFStringRef cf_str,
+ std::string &str);
+ static const char *GlobPath(const char *path, std::string &expanded_path);
+};
+
+#endif // #ifndef __CFString_h__
diff --git a/source/Plugins/Process/Darwin/CFUtils.h b/source/Plugins/Process/Darwin/CFUtils.h
new file mode 100644
index 000000000000..a904cd0ea6f0
--- /dev/null
+++ b/source/Plugins/Process/Darwin/CFUtils.h
@@ -0,0 +1,78 @@
+//===-- CFUtils.h -----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Created by Greg Clayton on 3/5/07.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __CFUtils_h__
+#define __CFUtils_h__
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#ifdef __cplusplus
+
+//----------------------------------------------------------------------
+// Templatized CF helper class that can own any CF pointer and will
+// call CFRelease() on any valid pointer it owns unless that pointer is
+// explicitly released using the release() member function.
+//----------------------------------------------------------------------
+template <class T> class CFReleaser {
+public:
+ // Type names for the avlue
+ typedef T element_type;
+
+ // Constructors and destructors
+ CFReleaser(T ptr = NULL) : _ptr(ptr) {}
+ CFReleaser(const CFReleaser &copy) : _ptr(copy.get()) {
+ if (get())
+ ::CFRetain(get());
+ }
+ virtual ~CFReleaser() { reset(); }
+
+ // Assignments
+ CFReleaser &operator=(const CFReleaser<T> &copy) {
+ if (copy != *this) {
+ // Replace our owned pointer with the new one
+ reset(copy.get());
+ // Retain the current pointer that we own
+ if (get())
+ ::CFRetain(get());
+ }
+ }
+ // Get the address of the contained type
+ T *ptr_address() { return &_ptr; }
+
+ // Access the pointer itself
+ const T get() const { return _ptr; }
+ T get() { return _ptr; }
+
+ // Set a new value for the pointer and CFRelease our old
+ // value if we had a valid one.
+ void reset(T ptr = NULL) {
+ if (ptr != _ptr) {
+ if (_ptr != NULL)
+ ::CFRelease(_ptr);
+ _ptr = ptr;
+ }
+ }
+
+ // Release ownership without calling CFRelease
+ T release() {
+ T tmp = _ptr;
+ _ptr = NULL;
+ return tmp;
+ }
+
+private:
+ element_type _ptr;
+};
+
+#endif // #ifdef __cplusplus
+#endif // #ifndef __CFUtils_h__
diff --git a/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp b/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp
new file mode 100644
index 000000000000..63b1ae6da968
--- /dev/null
+++ b/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp
@@ -0,0 +1,653 @@
+//===-- DarwinProcessLauncher.cpp -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//
+// DarwinProcessLauncher.cpp
+// lldb
+//
+// Created by Todd Fiala on 8/30/16.
+//
+//
+
+#include "DarwinProcessLauncher.h"
+
+// C includes
+#include <spawn.h>
+#include <sys/ptrace.h>
+#include <sys/stat.h>
+#include <sys/sysctl.h>
+
+#ifndef _POSIX_SPAWN_DISABLE_ASLR
+#define _POSIX_SPAWN_DISABLE_ASLR 0x0100
+#endif
+
+// LLDB includes
+#include "lldb/lldb-enumerations.h"
+
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Target/ProcessLaunchInfo.h"
+#include "lldb/Utility/PseudoTerminal.h"
+
+#include "CFBundle.h"
+#include "CFString.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_darwin;
+using namespace lldb_private::darwin_process_launcher;
+
+namespace {
+static LaunchFlavor g_launch_flavor = LaunchFlavor::Default;
+}
+
+namespace lldb_private {
+namespace darwin_process_launcher {
+
+static uint32_t GetCPUTypeForLocalProcess(::pid_t pid) {
+ int mib[CTL_MAXNAME] = {
+ 0,
+ };
+ size_t len = CTL_MAXNAME;
+ if (::sysctlnametomib("sysctl.proc_cputype", mib, &len))
+ return 0;
+
+ mib[len] = pid;
+ len++;
+
+ cpu_type_t cpu;
+ size_t cpu_len = sizeof(cpu);
+ if (::sysctl(mib, static_cast<u_int>(len), &cpu, &cpu_len, 0, 0))
+ cpu = 0;
+ return cpu;
+}
+
+static bool ResolveExecutablePath(const char *path, char *resolved_path,
+ size_t resolved_path_size) {
+ if (path == NULL || path[0] == '\0')
+ return false;
+
+ char max_path[PATH_MAX];
+ std::string result;
+ CFString::GlobPath(path, result);
+
+ if (result.empty())
+ result = path;
+
+ struct stat path_stat;
+ if (::stat(path, &path_stat) == 0) {
+ if ((path_stat.st_mode & S_IFMT) == S_IFDIR) {
+ CFBundle bundle(path);
+ CFReleaser<CFURLRef> url(bundle.CopyExecutableURL());
+ if (url.get()) {
+ if (::CFURLGetFileSystemRepresentation(
+ url.get(), true, (UInt8 *)resolved_path, resolved_path_size))
+ return true;
+ }
+ }
+ }
+
+ if (realpath(path, max_path)) {
+ // Found the path relatively...
+ ::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;
+}
+
+// TODO check if we have a general purpose fork and exec. We may be
+// able to get rid of this entirely.
+static Error ForkChildForPTraceDebugging(const char *path, char const *argv[],
+ char const *envp[], ::pid_t *pid,
+ int *pty_fd) {
+ Error error;
+ if (!path || !argv || !envp || !pid || !pty_fd) {
+ error.SetErrorString("invalid arguments");
+ return error;
+ }
+
+ // Use a fork that ties the child process's stdin/out/err to a pseudo
+ // terminal so we can read it in our MachProcess::STDIOThread
+ // as unbuffered io.
+ lldb_utility::PseudoTerminal pty;
+ char fork_error[256];
+ memset(fork_error, 0, sizeof(fork_error));
+ *pid = static_cast<::pid_t>(pty.Fork(fork_error, sizeof(fork_error)));
+ if (*pid < 0) {
+ //--------------------------------------------------------------
+ // Error during fork.
+ //--------------------------------------------------------------
+ *pid = static_cast<::pid_t>(LLDB_INVALID_PROCESS_ID);
+ error.SetErrorStringWithFormat("%s(): fork failed: %s", __FUNCTION__,
+ fork_error);
+ return error;
+ } else if (pid == 0) {
+ //--------------------------------------------------------------
+ // Child process
+ //--------------------------------------------------------------
+
+ // Debug this process.
+ ::ptrace(PT_TRACE_ME, 0, 0, 0);
+
+ // Get BSD signals as mach exceptions.
+ ::ptrace(PT_SIGEXC, 0, 0, 0);
+
+ // If our parent is setgid, lets make sure we don't inherit those
+ // extra powers due to nepotism.
+ if (::setgid(getgid()) == 0) {
+ // Let the child have its own process group. We need to execute
+ // this call in both the child and parent to avoid a race
+ // condition between the two processes.
+
+ // Set the child process group to match its pid.
+ ::setpgid(0, 0);
+
+ // Sleep a bit to before the exec call.
+ ::sleep(1);
+
+ // Turn this process into the given executable.
+ ::execv(path, (char *const *)argv);
+ }
+ // Exit with error code. Child process should have taken
+ // over in above exec call and if the exec fails it will
+ // exit the child process below.
+ ::exit(127);
+ } else {
+ //--------------------------------------------------------------
+ // Parent process
+ //--------------------------------------------------------------
+ // Let the child have its own process group. We need to execute
+ // this call in both the child and parent to avoid a race condition
+ // between the two processes.
+
+ // Set the child process group to match its pid
+ ::setpgid(*pid, *pid);
+ if (pty_fd) {
+ // Release our master pty file descriptor so the pty class doesn't
+ // close it and so we can continue to use it in our STDIO thread
+ *pty_fd = pty.ReleaseMasterFileDescriptor();
+ }
+ }
+ return error;
+}
+
+static Error
+CreatePosixSpawnFileAction(const FileAction &action,
+ posix_spawn_file_actions_t *file_actions) {
+ Error error;
+
+ // Log it.
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log) {
+ StreamString stream;
+ stream.PutCString("converting file action for posix_spawn(): ");
+ action.Dump(stream);
+ stream.Flush();
+ log->PutCString(stream.GetString().c_str());
+ }
+
+ // Validate args.
+ if (!file_actions) {
+ error.SetErrorString("mandatory file_actions arg is null");
+ return error;
+ }
+
+ // Build the posix file action.
+ switch (action.GetAction()) {
+ case FileAction::eFileActionOpen: {
+ const int error_code = ::posix_spawn_file_actions_addopen(
+ file_actions, action.GetFD(), action.GetPath(),
+ action.GetActionArgument(), 0);
+ if (error_code != 0) {
+ error.SetError(error_code, eErrorTypePOSIX);
+ return error;
+ }
+ break;
+ }
+
+ case FileAction::eFileActionClose: {
+ const int error_code =
+ ::posix_spawn_file_actions_addclose(file_actions, action.GetFD());
+ if (error_code != 0) {
+ error.SetError(error_code, eErrorTypePOSIX);
+ return error;
+ }
+ break;
+ }
+
+ case FileAction::eFileActionDuplicate: {
+ const int error_code = ::posix_spawn_file_actions_adddup2(
+ file_actions, action.GetFD(), action.GetActionArgument());
+ if (error_code != 0) {
+ error.SetError(error_code, eErrorTypePOSIX);
+ return error;
+ }
+ break;
+ }
+
+ case FileAction::eFileActionNone:
+ default:
+ if (log)
+ log->Printf("%s(): unsupported file action %u", __FUNCTION__,
+ action.GetAction());
+ break;
+ }
+
+ return error;
+}
+
+static Error PosixSpawnChildForPTraceDebugging(const char *path,
+ ProcessLaunchInfo &launch_info,
+ ::pid_t *pid,
+ cpu_type_t *actual_cpu_type) {
+ Error error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ if (!pid) {
+ error.SetErrorStringWithFormat("%s(): pid arg cannot be null",
+ __FUNCTION__);
+ return error;
+ }
+
+ posix_spawnattr_t attr;
+ short flags;
+ if (log) {
+ StreamString stream;
+ stream.Printf("%s(path='%s',...)\n", __FUNCTION__, path);
+ launch_info.Dump(stream, nullptr);
+ stream.Flush();
+ log->PutCString(stream.GetString().c_str());
+ }
+
+ int error_code;
+ if ((error_code = ::posix_spawnattr_init(&attr)) != 0) {
+ if (log)
+ log->Printf("::posix_spawnattr_init(&attr) failed");
+ error.SetError(error_code, eErrorTypePOSIX);
+ return error;
+ }
+
+ // Ensure we clean up the spawnattr structure however we exit this
+ // function.
+ std::unique_ptr<posix_spawnattr_t, int (*)(posix_spawnattr_t *)> spawnattr_up(
+ &attr, ::posix_spawnattr_destroy);
+
+ flags = POSIX_SPAWN_START_SUSPENDED | POSIX_SPAWN_SETSIGDEF |
+ POSIX_SPAWN_SETSIGMASK;
+ if (launch_info.GetFlags().Test(eLaunchFlagDisableASLR))
+ 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);
+
+ if ((error_code = ::posix_spawnattr_setflags(&attr, flags)) != 0) {
+ if (log)
+ log->Printf("::posix_spawnattr_setflags(&attr, "
+ "POSIX_SPAWN_START_SUSPENDED%s) failed: %s",
+ flags & _POSIX_SPAWN_DISABLE_ASLR
+ ? " | _POSIX_SPAWN_DISABLE_ASLR"
+ : "",
+ strerror(error_code));
+ error.SetError(error_code, eErrorTypePOSIX);
+ return error;
+ }
+
+#if !defined(__arm__)
+
+ // We don't need to do this for ARM, and we really shouldn't now that we
+ // have multiple CPU subtypes and no posix_spawnattr call that allows us
+ // to set which CPU subtype to launch...
+ cpu_type_t desired_cpu_type = launch_info.GetArchitecture().GetMachOCPUType();
+ if (desired_cpu_type != LLDB_INVALID_CPUTYPE) {
+ size_t ocount = 0;
+ error_code =
+ ::posix_spawnattr_setbinpref_np(&attr, 1, &desired_cpu_type, &ocount);
+ if (error_code != 0) {
+ if (log)
+ log->Printf("::posix_spawnattr_setbinpref_np(&attr, 1, "
+ "cpu_type = 0x%8.8x, count => %llu): %s",
+ desired_cpu_type, (uint64_t)ocount, strerror(error_code));
+ error.SetError(error_code, eErrorTypePOSIX);
+ return error;
+ }
+ if (ocount != 1) {
+ error.SetErrorStringWithFormat("posix_spawnattr_setbinpref_np "
+ "did not set the expected number "
+ "of cpu_type entries: expected 1 "
+ "but was %zu",
+ ocount);
+ return error;
+ }
+ }
+#endif
+
+ posix_spawn_file_actions_t file_actions;
+ if ((error_code = ::posix_spawn_file_actions_init(&file_actions)) != 0) {
+ if (log)
+ log->Printf("::posix_spawn_file_actions_init(&file_actions) "
+ "failed: %s",
+ strerror(error_code));
+ error.SetError(error_code, eErrorTypePOSIX);
+ return error;
+ }
+
+ // Ensure we clean up file actions however we exit this. When the
+ // file_actions_up below goes out of scope, we'll get our file action
+ // cleanup.
+ std::unique_ptr<posix_spawn_file_actions_t,
+ int (*)(posix_spawn_file_actions_t *)>
+ file_actions_up(&file_actions, ::posix_spawn_file_actions_destroy);
+
+ // We assume the caller has setup the file actions appropriately. We
+ // are not in the business of figuring out what we really need here.
+ // lldb-server will have already called FinalizeFileActions() as well
+ // to button these up properly.
+ const size_t num_actions = launch_info.GetNumFileActions();
+ for (size_t action_index = 0; action_index < num_actions; ++action_index) {
+ const FileAction *const action =
+ launch_info.GetFileActionAtIndex(action_index);
+ if (!action)
+ continue;
+
+ error = CreatePosixSpawnFileAction(*action, &file_actions);
+ if (!error.Success()) {
+ if (log)
+ log->Printf("%s(): error converting FileAction to posix_spawn "
+ "file action: %s",
+ __FUNCTION__, error.AsCString());
+ return error;
+ }
+ }
+
+ // TODO: Verify if we can set the working directory back immediately
+ // after the posix_spawnp call without creating a race condition???
+ const char *const working_directory =
+ launch_info.GetWorkingDirectory().GetCString();
+ if (working_directory && working_directory[0])
+ ::chdir(working_directory);
+
+ auto argv = launch_info.GetArguments().GetArgumentVector();
+ auto envp = launch_info.GetEnvironmentEntries().GetArgumentVector();
+ error_code = ::posix_spawnp(pid, path, &file_actions, &attr,
+ (char *const *)argv, (char *const *)envp);
+ if (error_code != 0) {
+ if (log)
+ log->Printf("::posix_spawnp(pid => %p, path = '%s', file_actions "
+ "= %p, attr = %p, argv = %p, envp = %p) failed: %s",
+ pid, path, &file_actions, &attr, argv, envp,
+ strerror(error_code));
+ error.SetError(error_code, eErrorTypePOSIX);
+ return error;
+ }
+
+ // Validate we got a pid.
+ if (pid == LLDB_INVALID_PROCESS_ID) {
+ error.SetErrorString("posix_spawn() did not indicate a failure but it "
+ "failed to return a pid, aborting.");
+ return error;
+ }
+
+ if (actual_cpu_type) {
+ *actual_cpu_type = GetCPUTypeForLocalProcess(*pid);
+ if (log)
+ log->Printf("%s(): cpu type for launched process pid=%i: "
+ "cpu_type=0x%8.8x",
+ __FUNCTION__, *pid, *actual_cpu_type);
+ }
+
+ return error;
+}
+
+Error LaunchInferior(ProcessLaunchInfo &launch_info, int *pty_master_fd,
+ LaunchFlavor *launch_flavor) {
+ Error error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ if (!launch_flavor) {
+ error.SetErrorString("mandatory launch_flavor field was null");
+ return error;
+ }
+
+ if (log) {
+ StreamString stream;
+ stream.Printf("NativeProcessDarwin::%s(): launching with the "
+ "following launch info:",
+ __FUNCTION__);
+ launch_info.Dump(stream, nullptr);
+ stream.Flush();
+ log->PutCString(stream.GetString().c_str());
+ }
+
+ // Retrieve the binary name given to us.
+ char given_path[PATH_MAX];
+ given_path[0] = '\0';
+ launch_info.GetExecutableFile().GetPath(given_path, sizeof(given_path));
+
+ // Determine the manner in which we'll launch.
+ *launch_flavor = g_launch_flavor;
+ if (*launch_flavor == LaunchFlavor::Default) {
+ // Our default launch method is posix spawn
+ *launch_flavor = LaunchFlavor::PosixSpawn;
+#if defined WITH_FBS
+ // Check if we have an app bundle, if so launch using BackBoard Services.
+ if (strstr(given_path, ".app")) {
+ *launch_flavor = eLaunchFlavorFBS;
+ }
+#elif defined WITH_BKS
+ // Check if we have an app bundle, if so launch using BackBoard Services.
+ if (strstr(given_path, ".app")) {
+ *launch_flavor = eLaunchFlavorBKS;
+ }
+#elif defined WITH_SPRINGBOARD
+ // Check if we have an app bundle, if so launch using SpringBoard.
+ if (strstr(given_path, ".app")) {
+ *launch_flavor = eLaunchFlavorSpringBoard;
+ }
+#endif
+ }
+
+ // Attempt to resolve the binary name to an absolute path.
+ char resolved_path[PATH_MAX];
+ resolved_path[0] = '\0';
+
+ if (log)
+ log->Printf("%s(): attempting to resolve given binary path: \"%s\"",
+ __FUNCTION__, given_path);
+
+ // If we fail to resolve the path to our executable, then just use what we
+ // were given and hope for the best
+ if (!ResolveExecutablePath(given_path, resolved_path,
+ sizeof(resolved_path))) {
+ if (log)
+ log->Printf("%s(): failed to resolve binary path, using "
+ "what was given verbatim and hoping for the best",
+ __FUNCTION__);
+ ::strncpy(resolved_path, given_path, sizeof(resolved_path));
+ } else {
+ if (log)
+ log->Printf("%s(): resolved given binary path to: \"%s\"", __FUNCTION__,
+ resolved_path);
+ }
+
+ char launch_err_str[PATH_MAX];
+ launch_err_str[0] = '\0';
+
+ // TODO figure out how to handle QSetProcessEvent
+ // const char *process_event = ctx.GetProcessEvent();
+
+ // Ensure the binary is there.
+ struct stat path_stat;
+ if (::stat(resolved_path, &path_stat) == -1) {
+ error.SetErrorToErrno();
+ return error;
+ }
+
+ // Fork a child process for debugging
+ // state_callback(eStateLaunching);
+
+ const auto argv = launch_info.GetArguments().GetConstArgumentVector();
+ const auto envp =
+ launch_info.GetEnvironmentEntries().GetConstArgumentVector();
+
+ switch (*launch_flavor) {
+ case LaunchFlavor::ForkExec: {
+ ::pid_t pid = LLDB_INVALID_PROCESS_ID;
+ error = ForkChildForPTraceDebugging(resolved_path, argv, envp, &pid,
+ pty_master_fd);
+ if (error.Success()) {
+ launch_info.SetProcessID(static_cast<lldb::pid_t>(pid));
+ } else {
+ // Reset any variables that might have been set during a failed
+ // launch attempt.
+ if (pty_master_fd)
+ *pty_master_fd = -1;
+
+ // We're done.
+ return error;
+ }
+ } break;
+
+#ifdef WITH_FBS
+ case LaunchFlavor::FBS: {
+ const char *app_ext = strstr(path, ".app");
+ if (app_ext && (app_ext[4] == '\0' || app_ext[4] == '/')) {
+ std::string app_bundle_path(path, app_ext + strlen(".app"));
+ m_flags |= eMachProcessFlagsUsingFBS;
+ if (BoardServiceLaunchForDebug(app_bundle_path.c_str(), argv, envp,
+ no_stdio, disable_aslr, event_data,
+ launch_err) != 0)
+ return m_pid; // A successful SBLaunchForDebug() returns and assigns a
+ // non-zero m_pid.
+ else
+ break; // We tried a FBS launch, but didn't succeed lets get out
+ }
+ } break;
+#endif
+
+#ifdef WITH_BKS
+ case LaunchFlavor::BKS: {
+ const char *app_ext = strstr(path, ".app");
+ if (app_ext && (app_ext[4] == '\0' || app_ext[4] == '/')) {
+ std::string app_bundle_path(path, app_ext + strlen(".app"));
+ m_flags |= eMachProcessFlagsUsingBKS;
+ if (BoardServiceLaunchForDebug(app_bundle_path.c_str(), argv, envp,
+ no_stdio, disable_aslr, event_data,
+ launch_err) != 0)
+ return m_pid; // A successful SBLaunchForDebug() returns and assigns a
+ // non-zero m_pid.
+ else
+ break; // We tried a BKS launch, but didn't succeed lets get out
+ }
+ } break;
+#endif
+
+#ifdef WITH_SPRINGBOARD
+ case LaunchFlavor::SpringBoard: {
+ // .../whatever.app/whatever ?
+ // Or .../com.apple.whatever.app/whatever -- be careful of ".app" in
+ // "com.apple.whatever" here
+ const char *app_ext = strstr(path, ".app/");
+ if (app_ext == NULL) {
+ // .../whatever.app ?
+ int len = strlen(path);
+ if (len > 5) {
+ if (strcmp(path + len - 4, ".app") == 0) {
+ app_ext = path + len - 4;
+ }
+ }
+ }
+ if (app_ext) {
+ std::string app_bundle_path(path, app_ext + strlen(".app"));
+ if (SBLaunchForDebug(app_bundle_path.c_str(), argv, envp, no_stdio,
+ disable_aslr, launch_err) != 0)
+ return m_pid; // A successful SBLaunchForDebug() returns and assigns a
+ // non-zero m_pid.
+ else
+ break; // We tried a springboard launch, but didn't succeed lets get out
+ }
+ } break;
+#endif
+
+ case LaunchFlavor::PosixSpawn: {
+ ::pid_t pid = LLDB_INVALID_PROCESS_ID;
+
+ // Retrieve paths for stdin/stdout/stderr.
+ cpu_type_t actual_cpu_type = 0;
+ error = PosixSpawnChildForPTraceDebugging(resolved_path, launch_info, &pid,
+ &actual_cpu_type);
+ if (error.Success()) {
+ launch_info.SetProcessID(static_cast<lldb::pid_t>(pid));
+ if (pty_master_fd)
+ *pty_master_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
+ } else {
+ // Reset any variables that might have been set during a failed
+ // launch attempt.
+ if (pty_master_fd)
+ *pty_master_fd = -1;
+
+ // We're done.
+ return error;
+ }
+ break;
+ }
+
+ default:
+ // Invalid launch flavor.
+ error.SetErrorStringWithFormat("NativeProcessDarwin::%s(): unknown "
+ "launch flavor %d",
+ __FUNCTION__, (int)*launch_flavor);
+ return error;
+ }
+
+ if (launch_info.GetProcessID() == LLDB_INVALID_PROCESS_ID) {
+ // If we don't have a valid process ID and no one has set the error,
+ // then return a generic error.
+ if (error.Success())
+ error.SetErrorStringWithFormat("%s(): failed to launch, no reason "
+ "specified",
+ __FUNCTION__);
+ }
+
+ // We're done with the launch side of the operation.
+ return error;
+}
+}
+} // namespaces
diff --git a/source/Plugins/Process/Darwin/DarwinProcessLauncher.h b/source/Plugins/Process/Darwin/DarwinProcessLauncher.h
new file mode 100644
index 000000000000..d1af4d09f8b7
--- /dev/null
+++ b/source/Plugins/Process/Darwin/DarwinProcessLauncher.h
@@ -0,0 +1,48 @@
+//===-- DarwinProcessLauncher.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef DarwinProcessLauncher_h
+#define DarwinProcessLauncher_h
+
+// C headers
+#include <mach/machine.h>
+#include <sys/types.h>
+
+// C++ headers
+#include <functional>
+
+// LLDB headers
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+
+#include "LaunchFlavor.h"
+
+namespace lldb_private {
+namespace darwin_process_launcher {
+// =============================================================================
+/// Launches a process for debugging.
+///
+/// @param[inout] launch_info
+/// Specifies details about the process to launch (e.g. path, architecture,
+/// etc.). On output, includes the launched ProcessID (pid).
+///
+/// @param[out] pty_master_fd
+/// Returns the master side of the pseudo-terminal used to communicate
+/// with stdin/stdout from the launched process. May be nullptr.
+///
+/// @param[out] launch_flavor
+/// Contains the launch flavor used when launching the process.
+// =============================================================================
+Error LaunchInferior(ProcessLaunchInfo &launch_info, int *pty_master_fd,
+ lldb_private::process_darwin::LaunchFlavor *launch_flavor);
+
+} // darwin_process_launcher
+} // lldb_private
+
+#endif /* DarwinProcessLauncher_h */
diff --git a/source/Plugins/Process/Darwin/LaunchFlavor.h b/source/Plugins/Process/Darwin/LaunchFlavor.h
new file mode 100644
index 000000000000..7b161712cffd
--- /dev/null
+++ b/source/Plugins/Process/Darwin/LaunchFlavor.h
@@ -0,0 +1,33 @@
+//===-- LaunchFlavor.h ---------------------------------------- -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LaunchFlavor_h
+#define LaunchFlavor_h
+
+namespace lldb_private {
+namespace process_darwin {
+
+enum class LaunchFlavor {
+ Default = 0,
+ PosixSpawn = 1,
+ ForkExec = 2,
+#ifdef WITH_SPRINGBOARD
+ SpringBoard = 3,
+#endif
+#ifdef WITH_BKS
+ BKS = 4,
+#endif
+#ifdef WITH_FBS
+ FBS = 5
+#endif
+};
+}
+} // namespaces
+
+#endif /* LaunchFlavor_h */
diff --git a/source/Plugins/Process/Darwin/MachException.cpp b/source/Plugins/Process/Darwin/MachException.cpp
new file mode 100644
index 000000000000..81706441494a
--- /dev/null
+++ b/source/Plugins/Process/Darwin/MachException.cpp
@@ -0,0 +1,543 @@
+//===-- MachException.cpp ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Created by Greg Clayton on 6/18/07.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MachException.h"
+
+// C includes
+#include <errno.h>
+#include <sys/ptrace.h>
+#include <sys/types.h>
+
+// C++ includes
+#include <mutex>
+
+// LLDB includes
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Target/UnixSignals.h"
+#include "lldb/Utility/LLDBAssert.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_darwin;
+
+// Routine mach_exception_raise
+extern "C" kern_return_t
+catch_mach_exception_raise(mach_port_t exception_port, mach_port_t thread,
+ mach_port_t task, exception_type_t exception,
+ mach_exception_data_t code,
+ mach_msg_type_number_t codeCnt);
+
+extern "C" kern_return_t catch_mach_exception_raise_state(
+ mach_port_t exception_port, exception_type_t exception,
+ const mach_exception_data_t code, mach_msg_type_number_t codeCnt,
+ int *flavor, const thread_state_t old_state,
+ mach_msg_type_number_t old_stateCnt, thread_state_t new_state,
+ mach_msg_type_number_t *new_stateCnt);
+
+// Routine mach_exception_raise_state_identity
+extern "C" kern_return_t catch_mach_exception_raise_state_identity(
+ mach_port_t exception_port, mach_port_t thread, mach_port_t task,
+ exception_type_t exception, mach_exception_data_t code,
+ mach_msg_type_number_t codeCnt, int *flavor, thread_state_t old_state,
+ mach_msg_type_number_t old_stateCnt, thread_state_t new_state,
+ mach_msg_type_number_t *new_stateCnt);
+
+extern "C" boolean_t mach_exc_server(mach_msg_header_t *InHeadP,
+ mach_msg_header_t *OutHeadP);
+
+// Any access to the g_message variable should be done by locking the
+// g_message_mutex first, using the g_message variable, then unlocking
+// the g_message_mutex. See MachException::Message::CatchExceptionRaise()
+// for sample code.
+
+static MachException::Data *g_message = NULL;
+
+extern "C" kern_return_t catch_mach_exception_raise_state(
+ mach_port_t exc_port, exception_type_t exc_type,
+ const mach_exception_data_t exc_data, mach_msg_type_number_t exc_data_count,
+ int *flavor, const thread_state_t old_state,
+ mach_msg_type_number_t old_stateCnt, thread_state_t new_state,
+ mach_msg_type_number_t *new_stateCnt) {
+ // TODO change to LIBLLDB_LOG_EXCEPTION
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
+ if (log) {
+ log->Printf("::%s(exc_port = 0x%4.4x, exc_type = %d (%s), "
+ "exc_data = 0x%llx, exc_data_count = %d)",
+ __FUNCTION__, exc_port, exc_type, MachException::Name(exc_type),
+ (uint64_t)exc_data, exc_data_count);
+ }
+ return KERN_FAILURE;
+}
+
+extern "C" kern_return_t catch_mach_exception_raise_state_identity(
+ mach_port_t exc_port, mach_port_t thread_port, mach_port_t task_port,
+ exception_type_t exc_type, mach_exception_data_t exc_data,
+ mach_msg_type_number_t exc_data_count, int *flavor,
+ thread_state_t old_state, mach_msg_type_number_t old_stateCnt,
+ thread_state_t new_state, mach_msg_type_number_t *new_stateCnt) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
+ if (log) {
+ log->Printf("::%s(exc_port = 0x%4.4x, thd_port = 0x%4.4x, "
+ "tsk_port = 0x%4.4x, exc_type = %d (%s), exc_data[%d] = "
+ "{ 0x%llx, 0x%llx })",
+ __FUNCTION__, exc_port, thread_port, task_port, exc_type,
+ MachException::Name(exc_type), exc_data_count,
+ (uint64_t)(exc_data_count > 0 ? exc_data[0] : 0xBADDBADD),
+ (uint64_t)(exc_data_count > 1 ? exc_data[1] : 0xBADDBADD));
+ }
+ mach_port_deallocate(mach_task_self(), task_port);
+ mach_port_deallocate(mach_task_self(), thread_port);
+
+ return KERN_FAILURE;
+}
+
+extern "C" kern_return_t
+catch_mach_exception_raise(mach_port_t exc_port, mach_port_t thread_port,
+ mach_port_t task_port, exception_type_t exc_type,
+ mach_exception_data_t exc_data,
+ mach_msg_type_number_t exc_data_count) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
+ if (log) {
+ log->Printf("::%s(exc_port = 0x%4.4x, thd_port = 0x%4.4x, "
+ "tsk_port = 0x%4.4x, exc_type = %d (%s), exc_data[%d] "
+ "= { 0x%llx, 0x%llx })",
+ __FUNCTION__, exc_port, thread_port, task_port, exc_type,
+ MachException::Name(exc_type), exc_data_count,
+ (uint64_t)(exc_data_count > 0 ? exc_data[0] : 0xBADDBADD),
+ (uint64_t)(exc_data_count > 1 ? exc_data[1] : 0xBADDBADD));
+ }
+
+ if (task_port == g_message->task_port) {
+ g_message->task_port = task_port;
+ g_message->thread_port = thread_port;
+ g_message->exc_type = exc_type;
+ g_message->exc_data.resize(exc_data_count);
+ ::memcpy(&g_message->exc_data[0], exc_data,
+ g_message->exc_data.size() * sizeof(mach_exception_data_type_t));
+ return KERN_SUCCESS;
+ }
+ return KERN_FAILURE;
+}
+
+#if 0
+void
+MachException::Message::Dump(Stream &stream) const
+{
+ stream.Printf("exc_msg { bits = 0x%8.8x size = 0x%8.8x remote-port = "
+ "0x%8.8x local-port = 0x%8.8x reserved = 0x%8.8x "
+ "id = 0x%8.8x }\n",
+ exc_msg.hdr.msgh_bits,
+ exc_msg.hdr.msgh_size,
+ exc_msg.hdr.msgh_remote_port,
+ exc_msg.hdr.msgh_local_port,
+ exc_msg.hdr.msgh_reserved,
+ exc_msg.hdr.msgh_id);
+
+ stream.Printf("reply_msg { bits = 0x%8.8x size = 0x%8.8x remote-port "
+ "= 0x%8.8x local-port = 0x%8.8x reserved = 0x%8.8x "
+ "id = 0x%8.8x }",
+ reply_msg.hdr.msgh_bits,
+ reply_msg.hdr.msgh_size,
+ reply_msg.hdr.msgh_remote_port,
+ reply_msg.hdr.msgh_local_port,
+ reply_msg.hdr.msgh_reserved,
+ reply_msg.hdr.msgh_id);
+ stream.Flush();
+}
+#endif
+
+bool MachException::Data::GetStopInfo(struct ThreadStopInfo *stop_info,
+ const UnixSignals &signals,
+ Stream &stream) const {
+ if (!stop_info)
+ return false;
+
+ // Zero out the structure.
+ memset(stop_info, 0, sizeof(struct ThreadStopInfo));
+
+ if (exc_type == 0) {
+ stop_info->reason = eStopReasonInvalid;
+ return true;
+ }
+
+ // We always stop with a mach exception.
+ stop_info->reason = eStopReasonException;
+ // Save the EXC_XXXX exception type.
+ stop_info->details.exception.type = exc_type;
+
+ // Fill in a text description
+ const char *exc_name = MachException::Name(exc_type);
+ if (exc_name)
+ stream.Printf("%s", exc_name);
+ else
+ stream.Printf("%i", exc_type);
+
+ stop_info->details.exception.data_count = exc_data.size();
+
+ int soft_signal = SoftSignal();
+ if (soft_signal) {
+ const char *sig_str = signals.GetSignalAsCString(soft_signal);
+ stream.Printf(" EXC_SOFT_SIGNAL( %i ( %s ))", soft_signal,
+ sig_str ? sig_str : "unknown signal");
+ } else {
+ // No special disassembly for exception data, just print it.
+ size_t idx;
+ stream.Printf(" data[%llu] = {",
+ (uint64_t)stop_info->details.exception.data_count);
+
+ for (idx = 0; idx < stop_info->details.exception.data_count; ++idx) {
+ stream.Printf(
+ "0x%llx%c", (uint64_t)exc_data[idx],
+ ((idx + 1 == stop_info->details.exception.data_count) ? '}' : ','));
+ }
+ }
+
+ // Copy the exception data
+ for (size_t i = 0; i < stop_info->details.exception.data_count; i++)
+ stop_info->details.exception.data[i] = exc_data[i];
+
+ return true;
+}
+
+Error MachException::Message::Receive(mach_port_t port,
+ mach_msg_option_t options,
+ mach_msg_timeout_t timeout,
+ mach_port_t notify_port) {
+ Error error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
+
+ mach_msg_timeout_t mach_msg_timeout =
+ options & MACH_RCV_TIMEOUT ? timeout : 0;
+ if (log && ((options & MACH_RCV_TIMEOUT) == 0)) {
+ // Dump this log message if we have no timeout in case it never returns
+ log->Printf("::mach_msg(msg->{bits = %#x, size = %u remote_port = %#x, "
+ "local_port = %#x, reserved = 0x%x, id = 0x%x}, "
+ "option = %#x, send_size = 0, rcv_size = %llu, "
+ "rcv_name = %#x, timeout = %u, notify = %#x)",
+ exc_msg.hdr.msgh_bits, exc_msg.hdr.msgh_size,
+ exc_msg.hdr.msgh_remote_port, exc_msg.hdr.msgh_local_port,
+ exc_msg.hdr.msgh_reserved, exc_msg.hdr.msgh_id, options,
+ (uint64_t)sizeof(exc_msg.data), port, mach_msg_timeout,
+ notify_port);
+ }
+
+ mach_msg_return_t mach_err =
+ ::mach_msg(&exc_msg.hdr,
+ options, // options
+ 0, // Send size
+ sizeof(exc_msg.data), // Receive size
+ port, // exception port to watch for
+ // exception on
+ mach_msg_timeout, // timeout in msec (obeyed only
+ // if MACH_RCV_TIMEOUT is ORed
+ // into the options parameter)
+ notify_port);
+ error.SetError(mach_err, eErrorTypeMachKernel);
+
+ // Dump any errors we get
+ if (error.Fail() && log) {
+ log->Printf("::mach_msg(msg->{bits = %#x, size = %u remote_port = %#x, "
+ "local_port = %#x, reserved = 0x%x, id = 0x%x}, "
+ "option = %#x, send_size = %u, rcv_size = %lu, rcv_name "
+ "= %#x, timeout = %u, notify = %#x) failed: %s",
+ exc_msg.hdr.msgh_bits, exc_msg.hdr.msgh_size,
+ exc_msg.hdr.msgh_remote_port, exc_msg.hdr.msgh_local_port,
+ exc_msg.hdr.msgh_reserved, exc_msg.hdr.msgh_id, options, 0,
+ sizeof(exc_msg.data), port, mach_msg_timeout, notify_port,
+ error.AsCString());
+ }
+ return error;
+}
+
+void MachException::Message::Dump(Stream &stream) const {
+ stream.Printf(" exc_msg { bits = 0x%8.8x size = 0x%8.8x remote-port = "
+ "0x%8.8x local-port = 0x%8.8x reserved = 0x%8.8x id = "
+ "0x%8.8x }\n",
+ exc_msg.hdr.msgh_bits, exc_msg.hdr.msgh_size,
+ exc_msg.hdr.msgh_remote_port, exc_msg.hdr.msgh_local_port,
+ exc_msg.hdr.msgh_reserved, exc_msg.hdr.msgh_id);
+
+ stream.Printf(" reply_msg { bits = 0x%8.8x size = 0x%8.8x remote-port = "
+ "0x%8.8x local-port = 0x%8.8x reserved = 0x%8.8x id = "
+ "0x%8.8x }",
+ reply_msg.hdr.msgh_bits, reply_msg.hdr.msgh_size,
+ reply_msg.hdr.msgh_remote_port, reply_msg.hdr.msgh_local_port,
+ reply_msg.hdr.msgh_reserved, reply_msg.hdr.msgh_id);
+}
+
+bool MachException::Message::CatchExceptionRaise(task_t task) {
+ bool success = false;
+ // locker will keep a mutex locked until it goes out of scope
+ // PThreadMutex::Locker locker(&g_message_mutex);
+ // DNBLogThreaded("calling mach_exc_server");
+ state.task_port = task;
+ g_message = &state;
+ // The exc_server function is the MIG generated server handling function
+ // to handle messages from the kernel relating to the occurrence of an
+ // exception in a thread. Such messages are delivered to the exception port
+ // set via thread_set_exception_ports or task_set_exception_ports. When an
+ // exception occurs in a thread, the thread sends an exception message to
+ // its exception port, blocking in the kernel waiting for the receipt of a
+ // reply. The exc_server function performs all necessary argument handling
+ // for this kernel message and calls catch_exception_raise,
+ // catch_exception_raise_state or catch_exception_raise_state_identity,
+ // which should handle the exception. If the called routine returns
+ // KERN_SUCCESS, a reply message will be sent, allowing the thread to
+ // continue from the point of the exception; otherwise, no reply message
+ // is sent and the called routine must have dealt with the exception
+ // thread directly.
+ if (mach_exc_server(&exc_msg.hdr, &reply_msg.hdr)) {
+ success = true;
+ } else {
+ Log *log(
+ GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
+ if (log)
+ log->Printf("MachException::Message::%s(): mach_exc_server "
+ "returned zero...",
+ __FUNCTION__);
+ }
+ g_message = NULL;
+ return success;
+}
+
+Error MachException::Message::Reply(::pid_t inferior_pid, task_t inferior_task,
+ int signal) {
+ // Reply to the exception...
+ Error error;
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
+
+ // If we had a soft signal, we need to update the thread first so it can
+ // continue without signaling
+ int soft_signal = state.SoftSignal();
+ if (soft_signal) {
+ int state_pid = -1;
+ if (inferior_task == state.task_port) {
+ // This is our task, so we can update the signal to send to it
+ state_pid = inferior_pid;
+ soft_signal = signal;
+ } else {
+ auto mach_err = ::pid_for_task(state.task_port, &state_pid);
+ if (mach_err) {
+ error.SetError(mach_err, eErrorTypeMachKernel);
+ if (log)
+ log->Printf("MachException::Message::%s(): pid_for_task() "
+ "failed: %s",
+ __FUNCTION__, error.AsCString());
+ return error;
+ }
+ }
+
+ lldbassert(state_pid != -1);
+ if (state_pid != -1) {
+ errno = 0;
+ caddr_t thread_port_caddr = (caddr_t)(uintptr_t)state.thread_port;
+ if (::ptrace(PT_THUPDATE, state_pid, thread_port_caddr, soft_signal) != 0)
+ error.SetError(errno, eErrorTypePOSIX);
+
+ if (!error.Success()) {
+ if (log)
+ log->Printf("::ptrace(request = PT_THUPDATE, pid = "
+ "0x%4.4x, tid = 0x%4.4x, signal = %i)",
+ state_pid, state.thread_port, soft_signal);
+ return error;
+ }
+ }
+ }
+
+ if (log)
+ log->Printf("::mach_msg ( msg->{bits = %#x, size = %u, remote_port "
+ "= %#x, local_port = %#x, reserved = 0x%x, id = 0x%x}, "
+ "option = %#x, send_size = %u, rcv_size = %u, rcv_name "
+ "= %#x, timeout = %u, notify = %#x)",
+ reply_msg.hdr.msgh_bits, reply_msg.hdr.msgh_size,
+ reply_msg.hdr.msgh_remote_port, reply_msg.hdr.msgh_local_port,
+ reply_msg.hdr.msgh_reserved, reply_msg.hdr.msgh_id,
+ MACH_SEND_MSG | MACH_SEND_INTERRUPT, reply_msg.hdr.msgh_size, 0,
+ MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+
+ auto mach_err =
+ ::mach_msg(&reply_msg.hdr, MACH_SEND_MSG | MACH_SEND_INTERRUPT,
+ reply_msg.hdr.msgh_size, 0, MACH_PORT_NULL,
+ MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+ if (mach_err)
+ error.SetError(mach_err, eErrorTypeMachKernel);
+
+ // Log our error if we have one.
+ if (error.Fail() && log) {
+ if (error.GetError() == MACH_SEND_INTERRUPTED) {
+ log->PutCString("::mach_msg() - send interrupted");
+ // TODO: keep retrying to reply???
+ } else if (state.task_port == inferior_task) {
+ log->Printf("mach_msg(): returned an error when replying "
+ "to a mach exception: error = %u (%s)",
+ error.GetError(), error.AsCString());
+ } else {
+ log->Printf("::mach_msg() - failed (child of task): %u (%s)",
+ error.GetError(), error.AsCString());
+ }
+ }
+
+ return error;
+}
+
+#define PREV_EXC_MASK_ALL \
+ (EXC_MASK_BAD_ACCESS | EXC_MASK_BAD_INSTRUCTION | EXC_MASK_ARITHMETIC | \
+ EXC_MASK_EMULATION | EXC_MASK_SOFTWARE | EXC_MASK_BREAKPOINT | \
+ EXC_MASK_SYSCALL | EXC_MASK_MACH_SYSCALL | EXC_MASK_RPC_ALERT | \
+ EXC_MASK_MACHINE)
+
+// Don't listen for EXC_RESOURCE, it should really get handled by the system
+// handler.
+
+#ifndef EXC_RESOURCE
+#define EXC_RESOURCE 11
+#endif
+
+#ifndef EXC_MASK_RESOURCE
+#define EXC_MASK_RESOURCE (1 << EXC_RESOURCE)
+#endif
+
+#define LLDB_EXC_MASK (EXC_MASK_ALL & ~EXC_MASK_RESOURCE)
+
+Error MachException::PortInfo::Save(task_t task) {
+ Error error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
+
+ if (log)
+ log->Printf("MachException::PortInfo::%s(task = 0x%4.4x)", __FUNCTION__,
+ task);
+
+ // Be careful to be able to have debugserver built on a newer OS than what
+ // it is currently running on by being able to start with all exceptions
+ // and back off to just what is supported on the current system
+ mask = LLDB_EXC_MASK;
+
+ count = (sizeof(ports) / sizeof(ports[0]));
+ auto mach_err = ::task_get_exception_ports(task, mask, masks, &count, ports,
+ behaviors, flavors);
+ if (mach_err)
+ error.SetError(mach_err, eErrorTypeMachKernel);
+
+ if (log) {
+ if (error.Success()) {
+ log->Printf("::task_get_exception_ports(task = 0x%4.4x, mask = "
+ "0x%x, maskCnt => %u, ports, behaviors, flavors)",
+ task, mask, count);
+ } else {
+ log->Printf("::task_get_exception_ports(task = 0x%4.4x, mask = 0x%x, "
+ "maskCnt => %u, ports, behaviors, flavors) error: %u (%s)",
+ task, mask, count, error.GetError(), error.AsCString());
+ }
+ }
+
+ if ((error.GetError() == KERN_INVALID_ARGUMENT) &&
+ (mask != PREV_EXC_MASK_ALL)) {
+ mask = PREV_EXC_MASK_ALL;
+ count = (sizeof(ports) / sizeof(ports[0]));
+ mach_err = ::task_get_exception_ports(task, mask, masks, &count, ports,
+ behaviors, flavors);
+ error.SetError(mach_err, eErrorTypeMachKernel);
+ if (log) {
+ if (error.Success()) {
+ log->Printf("::task_get_exception_ports(task = 0x%4.4x, "
+ "mask = 0x%x, maskCnt => %u, ports, behaviors, "
+ "flavors)",
+ task, mask, count);
+ } else {
+ log->Printf("::task_get_exception_ports(task = 0x%4.4x, mask = "
+ "0x%x, maskCnt => %u, ports, behaviors, flavors) "
+ "error: %u (%s)",
+ task, mask, count, error.GetError(), error.AsCString());
+ }
+ }
+ }
+ if (error.Fail()) {
+ mask = 0;
+ count = 0;
+ }
+ return error;
+}
+
+Error MachException::PortInfo::Restore(task_t task) {
+ Error error;
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
+
+ if (log)
+ log->Printf("MachException::PortInfo::Restore(task = 0x%4.4x)", task);
+
+ uint32_t i = 0;
+ if (count > 0) {
+ for (i = 0; i < count; i++) {
+ auto mach_err = ::task_set_exception_ports(task, masks[i], ports[i],
+ behaviors[i], flavors[i]);
+ if (mach_err)
+ error.SetError(mach_err, eErrorTypeMachKernel);
+ if (log) {
+ if (error.Success()) {
+ log->Printf("::task_set_exception_ports(task = 0x%4.4x, "
+ "exception_mask = 0x%8.8x, new_port = 0x%4.4x, "
+ "behavior = 0x%8.8x, new_flavor = 0x%8.8x)",
+ task, masks[i], ports[i], behaviors[i], flavors[i]);
+ } else {
+ log->Printf("::task_set_exception_ports(task = 0x%4.4x, "
+ "exception_mask = 0x%8.8x, new_port = 0x%4.4x, "
+ "behavior = 0x%8.8x, new_flavor = 0x%8.8x): "
+ "error %u (%s)",
+ task, masks[i], ports[i], behaviors[i], flavors[i],
+ error.GetError(), error.AsCString());
+ }
+ }
+
+ // Bail if we encounter any errors
+ if (error.Fail())
+ break;
+ }
+ }
+
+ count = 0;
+ return error;
+}
+
+const char *MachException::Name(exception_type_t exc_type) {
+ switch (exc_type) {
+ case EXC_BAD_ACCESS:
+ return "EXC_BAD_ACCESS";
+ case EXC_BAD_INSTRUCTION:
+ return "EXC_BAD_INSTRUCTION";
+ case EXC_ARITHMETIC:
+ return "EXC_ARITHMETIC";
+ case EXC_EMULATION:
+ return "EXC_EMULATION";
+ case EXC_SOFTWARE:
+ return "EXC_SOFTWARE";
+ case EXC_BREAKPOINT:
+ return "EXC_BREAKPOINT";
+ case EXC_SYSCALL:
+ return "EXC_SYSCALL";
+ case EXC_MACH_SYSCALL:
+ return "EXC_MACH_SYSCALL";
+ case EXC_RPC_ALERT:
+ return "EXC_RPC_ALERT";
+#ifdef EXC_CRASH
+ case EXC_CRASH:
+ return "EXC_CRASH";
+#endif
+ default:
+ break;
+ }
+ return NULL;
+}
diff --git a/source/Plugins/Process/Darwin/MachException.h b/source/Plugins/Process/Darwin/MachException.h
new file mode 100644
index 000000000000..ac8cd7030c55
--- /dev/null
+++ b/source/Plugins/Process/Darwin/MachException.h
@@ -0,0 +1,140 @@
+//===-- MachException.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Created by Greg Clayton on 6/18/07.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __MachException_h__
+#define __MachException_h__
+
+#include <mach/mach.h>
+#include <vector>
+
+#include "lldb/Host/Debug.h"
+#include "lldb/lldb-private-forward.h"
+#include "lldb/lldb-types.h"
+
+namespace lldb_private {
+namespace process_darwin {
+
+typedef union MachMessageTag {
+ mach_msg_header_t hdr;
+ char data[1024];
+} MachMessage;
+
+class MachException {
+public:
+ struct PortInfo {
+ exception_mask_t mask; // the exception mask for this device which may be a
+ // subset of EXC_MASK_ALL...
+ exception_mask_t masks[EXC_TYPES_COUNT];
+ mach_port_t ports[EXC_TYPES_COUNT];
+ exception_behavior_t behaviors[EXC_TYPES_COUNT];
+ thread_state_flavor_t flavors[EXC_TYPES_COUNT];
+ mach_msg_type_number_t count;
+
+ Error Save(task_t task);
+
+ Error Restore(task_t task);
+ };
+
+ struct Data {
+ task_t task_port;
+ thread_t thread_port;
+ exception_type_t exc_type;
+ std::vector<mach_exception_data_type_t> exc_data;
+ Data()
+ : task_port(TASK_NULL), thread_port(THREAD_NULL), exc_type(0),
+ exc_data() {}
+
+ void Clear() {
+ task_port = TASK_NULL;
+ thread_port = THREAD_NULL;
+ exc_type = 0;
+ exc_data.clear();
+ }
+
+ bool IsValid() const {
+ return task_port != TASK_NULL && thread_port != THREAD_NULL &&
+ exc_type != 0;
+ }
+
+ // Return the SoftSignal for this MachException data, or zero if there is
+ // none
+ int SoftSignal() const {
+ if (exc_type == EXC_SOFTWARE && exc_data.size() == 2 &&
+ exc_data[0] == EXC_SOFT_SIGNAL)
+ return static_cast<int>(exc_data[1]);
+ return 0;
+ }
+
+ bool IsBreakpoint() const {
+ return (exc_type == EXC_BREAKPOINT ||
+ ((exc_type == EXC_SOFTWARE) && exc_data[0] == 1));
+ }
+
+ bool GetStopInfo(ThreadStopInfo *stop_info, const UnixSignals &signals,
+ Stream &stream) const;
+ };
+
+ struct Message {
+ MachMessage exc_msg;
+ MachMessage reply_msg;
+ Data state;
+
+ Message() : state() {
+ memset(&exc_msg, 0, sizeof(exc_msg));
+ memset(&reply_msg, 0, sizeof(reply_msg));
+ }
+
+ bool CatchExceptionRaise(task_t task);
+
+ Error Reply(::pid_t inferior_pid, task_t inferior_task, int signal);
+
+ Error Receive(mach_port_t receive_port, mach_msg_option_t options,
+ mach_msg_timeout_t timeout,
+ mach_port_t notify_port = MACH_PORT_NULL);
+
+ void Dump(Stream &stream) const;
+
+ typedef std::vector<Message> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+ };
+
+ enum {
+ e_actionForward, // Forward signal to inferior process
+ e_actionStop, // Stop when this signal is received
+ };
+ struct Action {
+ task_t task_port; // Set to TASK_NULL for any TASK
+ thread_t thread_port; // Set to THREAD_NULL for any thread
+ exception_type_t exc_mask; // Mach exception mask to watch for
+ std::vector<mach_exception_data_type_t> exc_data_mask; // Mask to apply to
+ // exception data, or
+ // empty to ignore
+ // exc_data value for
+ // exception
+ std::vector<mach_exception_data_type_t> exc_data_value; // Value to compare
+ // to exception data
+ // after masking, or
+ // empty to ignore
+ // exc_data value
+ // for exception
+ uint8_t flags; // Action flags describing what to do with the exception
+ };
+
+ static const char *Name(exception_type_t exc_type);
+};
+
+} // namespace process_darwin
+} // namespace lldb_private
+
+#endif
diff --git a/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp b/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp
new file mode 100644
index 000000000000..e56375ebaa49
--- /dev/null
+++ b/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp
@@ -0,0 +1,1576 @@
+//===-- NativeProcessDarwin.cpp ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "NativeProcessDarwin.h"
+
+// C includes
+#include <mach/mach_init.h>
+#include <mach/mach_traps.h>
+#include <sys/ptrace.h>
+#include <sys/stat.h>
+#include <sys/sysctl.h>
+#include <sys/types.h>
+
+// C++ includes
+// LLDB includes
+#include "lldb/Core/Log.h"
+#include "lldb/Core/State.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Target/ProcessLaunchInfo.h"
+#include "lldb/Utility/PseudoTerminal.h"
+
+#include "CFBundle.h"
+#include "CFString.h"
+#include "DarwinProcessLauncher.h"
+
+#include "MachException.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_darwin;
+using namespace lldb_private::darwin_process_launcher;
+
+// -----------------------------------------------------------------------------
+// Hidden Impl
+// -----------------------------------------------------------------------------
+
+namespace {
+struct hack_task_dyld_info {
+ mach_vm_address_t all_image_info_addr;
+ mach_vm_size_t all_image_info_size;
+};
+}
+
+// -----------------------------------------------------------------------------
+// Public Static Methods
+// -----------------------------------------------------------------------------
+
+Error NativeProcessProtocol::Launch(
+ ProcessLaunchInfo &launch_info,
+ NativeProcessProtocol::NativeDelegate &native_delegate, MainLoop &mainloop,
+ NativeProcessProtocolSP &native_process_sp) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ Error error;
+
+ // Verify the working directory is valid if one was specified.
+ FileSpec working_dir(launch_info.GetWorkingDirectory());
+ if (working_dir &&
+ (!working_dir.ResolvePath() ||
+ working_dir.GetFileType() != FileSpec::eFileTypeDirectory)) {
+ error.SetErrorStringWithFormat("No such file or directory: %s",
+ working_dir.GetCString());
+ return error;
+ }
+
+ // Launch the inferior.
+ int pty_master_fd = -1;
+ LaunchFlavor launch_flavor = LaunchFlavor::Default;
+
+ error = LaunchInferior(launch_info, &pty_master_fd, &launch_flavor);
+
+ // Handle launch failure.
+ if (!error.Success()) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s() failed to launch process: "
+ "%s",
+ __FUNCTION__, error.AsCString());
+ return error;
+ }
+
+ // Handle failure to return a pid.
+ if (launch_info.GetProcessID() == LLDB_INVALID_PROCESS_ID) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s() launch succeeded but no "
+ "pid was returned! Aborting.",
+ __FUNCTION__);
+ return error;
+ }
+
+ // Create the Darwin native process impl.
+ std::shared_ptr<NativeProcessDarwin> np_darwin_sp(
+ new NativeProcessDarwin(launch_info.GetProcessID(), pty_master_fd));
+ if (!np_darwin_sp->RegisterNativeDelegate(native_delegate)) {
+ native_process_sp.reset();
+ error.SetErrorStringWithFormat("failed to register the native delegate");
+ return error;
+ }
+
+ // Finalize the processing needed to debug the launched process with
+ // a NativeProcessDarwin instance.
+ error = np_darwin_sp->FinalizeLaunch(launch_flavor, mainloop);
+ if (!error.Success()) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s() aborting, failed to finalize"
+ " the launching of the process: %s",
+ __FUNCTION__, error.AsCString());
+ return error;
+ }
+
+ // Return the process and process id to the caller through the launch args.
+ native_process_sp = np_darwin_sp;
+ return error;
+}
+
+Error NativeProcessProtocol::Attach(
+ lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
+ MainLoop &mainloop, NativeProcessProtocolSP &native_process_sp) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(pid = %" PRIi64 ")", __FUNCTION__,
+ pid);
+
+ // Retrieve the architecture for the running process.
+ ArchSpec process_arch;
+ Error error = ResolveProcessArchitecture(pid, process_arch);
+ if (!error.Success())
+ return error;
+
+ // TODO get attach to return this value.
+ const int pty_master_fd = -1;
+ std::shared_ptr<NativeProcessDarwin> native_process_darwin_sp(
+ new NativeProcessDarwin(pid, pty_master_fd));
+
+ if (!native_process_darwin_sp->RegisterNativeDelegate(native_delegate)) {
+ error.SetErrorStringWithFormat("failed to register the native "
+ "delegate");
+ return error;
+ }
+
+ native_process_darwin_sp->AttachToInferior(mainloop, pid, error);
+ if (!error.Success())
+ return error;
+
+ native_process_sp = native_process_darwin_sp;
+ return error;
+}
+
+// -----------------------------------------------------------------------------
+// ctor/dtor
+// -----------------------------------------------------------------------------
+
+NativeProcessDarwin::NativeProcessDarwin(lldb::pid_t pid, int pty_master_fd)
+ : NativeProcessProtocol(pid), m_task(TASK_NULL), m_did_exec(false),
+ m_cpu_type(0), m_exception_port(MACH_PORT_NULL), m_exc_port_info(),
+ m_exception_thread(nullptr), m_exception_messages_mutex(),
+ m_sent_interrupt_signo(0), m_auto_resume_signo(0), m_thread_list(),
+ m_thread_actions(), m_waitpid_pipe(), m_waitpid_thread(nullptr),
+ m_waitpid_reader_handle() {
+ // TODO add this to the NativeProcessProtocol constructor.
+ m_terminal_fd = pty_master_fd;
+}
+
+NativeProcessDarwin::~NativeProcessDarwin() {}
+
+// -----------------------------------------------------------------------------
+// Instance methods
+// -----------------------------------------------------------------------------
+
+Error NativeProcessDarwin::FinalizeLaunch(LaunchFlavor launch_flavor,
+ MainLoop &main_loop) {
+ Error error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+#if 0
+ m_path = path;
+ size_t i;
+ char const *arg;
+ for (i=0; (arg = argv[i]) != NULL; i++)
+ m_args.push_back(arg);
+#endif
+
+ error = StartExceptionThread();
+ if (!error.Success()) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): failure starting the "
+ "mach exception port monitor thread: %s",
+ __FUNCTION__, error.AsCString());
+
+ // Terminate the inferior process. There's nothing meaningful we can
+ // do if we can't receive signals and exceptions. Since we launched
+ // the process, it's fair game for us to kill it.
+ ::ptrace(PT_KILL, m_pid, 0, 0);
+ SetState(eStateExited);
+
+ return error;
+ }
+
+ StartSTDIOThread();
+
+ if (launch_flavor == LaunchFlavor::PosixSpawn) {
+ SetState(eStateAttaching);
+ errno = 0;
+ int err = ::ptrace(PT_ATTACHEXC, m_pid, 0, 0);
+ if (err == 0) {
+ // m_flags |= eMachProcessFlagsAttached;
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): successfully spawned "
+ "process with pid %" PRIu64,
+ __FUNCTION__, m_pid);
+ } else {
+ error.SetErrorToErrno();
+ SetState(eStateExited);
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): error: failed to "
+ "attach to spawned pid %" PRIu64 " (error=%d (%s))",
+ __FUNCTION__, m_pid, (int)error.GetError(),
+ error.AsCString());
+ return error;
+ }
+ }
+
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): new pid is %" PRIu64 "...",
+ __FUNCTION__, m_pid);
+
+ // Spawn a thread to reap our child inferior process...
+ error = StartWaitpidThread(main_loop);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): failed to start waitpid() "
+ "thread: %s",
+ __FUNCTION__, error.AsCString());
+ kill(SIGKILL, static_cast<::pid_t>(m_pid));
+ return error;
+ }
+
+ if (TaskPortForProcessID(error) == 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.
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): could not get task port "
+ "for process, sending SIGKILL and exiting: %s",
+ __FUNCTION__, error.AsCString());
+ kill(SIGKILL, static_cast<::pid_t>(m_pid));
+ return error;
+ }
+
+ // Indicate that we're stopped, as we always launch suspended.
+ SetState(eStateStopped);
+
+ // Success.
+ return error;
+}
+
+Error NativeProcessDarwin::SaveExceptionPortInfo() {
+ return m_exc_port_info.Save(m_task);
+}
+
+bool NativeProcessDarwin::ProcessUsingSpringBoard() const {
+ // TODO implement flags
+ // return (m_flags & eMachProcessFlagsUsingSBS) != 0;
+ return false;
+}
+
+bool NativeProcessDarwin::ProcessUsingBackBoard() const {
+ // TODO implement flags
+ // return (m_flags & eMachProcessFlagsUsingBKS) != 0;
+ return false;
+}
+
+// Called by the exception thread when an exception has been received from
+// our process. The exception message is completely filled and the exception
+// data has already been copied.
+void NativeProcessDarwin::ExceptionMessageReceived(
+ const MachException::Message &message) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
+
+ std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex);
+ if (m_exception_messages.empty()) {
+ // Suspend the task the moment we receive our first exception message.
+ SuspendTask();
+ }
+
+ // Use a locker to automatically unlock our mutex in case of exceptions
+ // Add the exception to our internal exception stack
+ m_exception_messages.push_back(message);
+
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): new queued message count: %lu",
+ __FUNCTION__, m_exception_messages.size());
+}
+
+void *NativeProcessDarwin::ExceptionThread(void *arg) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
+ if (!arg) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): cannot run mach exception "
+ "thread, mandatory process arg was null",
+ __FUNCTION__);
+ return nullptr;
+ }
+
+ return reinterpret_cast<NativeProcessDarwin *>(arg)->DoExceptionThread();
+}
+
+void *NativeProcessDarwin::DoExceptionThread() {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
+
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(arg=%p) starting thread...",
+ __FUNCTION__, this);
+
+ pthread_setname_np("exception monitoring thread");
+
+ // Ensure we don't get CPU starved.
+ MaybeRaiseThreadPriority();
+
+ // We keep a count of the number of consecutive exceptions received so
+ // we know to grab all exceptions without a timeout. We do this to get a
+ // bunch of related exceptions on our exception port so we can process
+ // then together. When we have multiple threads, we can get an exception
+ // per thread and they will come in consecutively. The main loop in this
+ // thread can stop periodically if needed to service things related to this
+ // process.
+ //
+ // [did we lose some words here?]
+ //
+ // flag set in the options, so we will wait forever for an exception on
+ // 0 our exception port. After we get one exception, we then will use the
+ // MACH_RCV_TIMEOUT option with a zero timeout to grab all other current
+ // exceptions for our process. After we have received the last pending
+ // exception, we will get a timeout which enables us to then notify
+ // our main thread that we have an exception bundle available. We then wait
+ // for the main thread to tell this exception thread to start trying to get
+ // exceptions messages again and we start again with a mach_msg read with
+ // infinite timeout.
+ //
+ // We choose to park a thread on this, rather than polling, because the
+ // polling is expensive. On devices, we need to minimize overhead caused
+ // by the process monitor.
+ uint32_t num_exceptions_received = 0;
+ Error error;
+ task_t task = m_task;
+ mach_msg_timeout_t periodic_timeout = 0;
+
+#if defined(WITH_SPRINGBOARD) && !defined(WITH_BKS)
+ mach_msg_timeout_t watchdog_elapsed = 0;
+ mach_msg_timeout_t watchdog_timeout = 60 * 1000;
+ ::pid_t pid = (::pid_t)process->GetID();
+ CFReleaser<SBSWatchdogAssertionRef> watchdog;
+
+ if (process->ProcessUsingSpringBoard()) {
+ // Request a renewal for every 60 seconds if we attached using
+ // SpringBoard.
+ watchdog.reset(::SBSWatchdogAssertionCreateForPID(nullptr, pid, 60));
+ if (log)
+ log->Printf("::SBSWatchdogAssertionCreateForPID(NULL, %4.4x, 60) "
+ "=> %p",
+ pid, watchdog.get());
+
+ if (watchdog.get()) {
+ ::SBSWatchdogAssertionRenew(watchdog.get());
+
+ CFTimeInterval watchdogRenewalInterval =
+ ::SBSWatchdogAssertionGetRenewalInterval(watchdog.get());
+ if (log)
+ log->Printf("::SBSWatchdogAssertionGetRenewalInterval(%p) => "
+ "%g seconds",
+ watchdog.get(), watchdogRenewalInterval);
+ if (watchdogRenewalInterval > 0.0) {
+ watchdog_timeout = (mach_msg_timeout_t)watchdogRenewalInterval * 1000;
+ if (watchdog_timeout > 3000) {
+ // Give us a second to renew our timeout.
+ watchdog_timeout -= 1000;
+ } else if (watchdog_timeout > 1000) {
+ // Give us a quarter of a second to renew our timeout.
+ watchdog_timeout -= 250;
+ }
+ }
+ }
+ if (periodic_timeout == 0 || periodic_timeout > watchdog_timeout)
+ periodic_timeout = watchdog_timeout;
+ }
+#endif // #if defined (WITH_SPRINGBOARD) && !defined (WITH_BKS)
+
+#ifdef WITH_BKS
+ CFReleaser<BKSWatchdogAssertionRef> watchdog;
+ if (process->ProcessUsingBackBoard()) {
+ ::pid_t pid = process->GetID();
+ CFAllocatorRef alloc = kCFAllocatorDefault;
+ watchdog.reset(::BKSWatchdogAssertionCreateForPID(alloc, pid));
+ }
+#endif // #ifdef WITH_BKS
+
+ // Do we want to use a weak pointer to the NativeProcessDarwin here, in
+ // which case we can guarantee we don't whack the process monitor if we
+ // race between this thread and the main one on shutdown?
+ while (IsExceptionPortValid()) {
+ ::pthread_testcancel();
+
+ MachException::Message exception_message;
+
+ if (num_exceptions_received > 0) {
+ // We don't want a timeout here, just receive as many exceptions as
+ // we can since we already have one. We want to get all currently
+ // available exceptions for this task at once.
+ error = exception_message.Receive(
+ GetExceptionPort(),
+ MACH_RCV_MSG | MACH_RCV_INTERRUPT | MACH_RCV_TIMEOUT, 0);
+ } else if (periodic_timeout > 0) {
+ // We need to stop periodically in this loop, so try and get a mach
+ // message with a valid timeout (ms).
+ error = exception_message.Receive(GetExceptionPort(),
+ MACH_RCV_MSG | MACH_RCV_INTERRUPT |
+ MACH_RCV_TIMEOUT,
+ periodic_timeout);
+ } else {
+ // We don't need to parse all current exceptions or stop
+ // periodically, just wait for an exception forever.
+ error = exception_message.Receive(GetExceptionPort(),
+ MACH_RCV_MSG | MACH_RCV_INTERRUPT, 0);
+ }
+
+ if (error.Success()) {
+ // We successfully received an exception.
+ if (exception_message.CatchExceptionRaise(task)) {
+ ++num_exceptions_received;
+ ExceptionMessageReceived(exception_message);
+ }
+ } else {
+ if (error.GetError() == MACH_RCV_INTERRUPTED) {
+ // We were interrupted.
+
+ // If we have no task port we should exit this thread, as it implies
+ // the inferior went down.
+ if (!IsExceptionPortValid()) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): the inferior "
+ "exception port is no longer valid, "
+ "canceling exception thread...",
+ __FUNCTION__);
+ // Should we be setting a process state here?
+ break;
+ }
+
+ // Make sure the inferior task is still valid.
+ if (IsTaskValid()) {
+ // Task is still ok.
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): interrupted, but "
+ "the inferior task iss till valid, "
+ "continuing...",
+ __FUNCTION__);
+ continue;
+ } else {
+ // The inferior task is no longer valid. Time to exit as
+ // the process has gone away.
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): the inferior task "
+ "has exited, and so will we...",
+ __FUNCTION__);
+ // Does this race at all with our waitpid()?
+ SetState(eStateExited);
+ break;
+ }
+ } else if (error.GetError() == MACH_RCV_TIMED_OUT) {
+ // We timed out when waiting for exceptions.
+
+ if (num_exceptions_received > 0) {
+ // We were receiving all current exceptions with a timeout of
+ // zero. It is time to go back to our normal looping mode.
+ num_exceptions_received = 0;
+
+ // Notify our main thread we have a complete exception message
+ // bundle available. Get the possibly updated task port back
+ // from the process in case we exec'ed and our task port
+ // changed.
+ task = ExceptionMessageBundleComplete();
+
+ // In case we use a timeout value when getting exceptions,
+ // make sure our task is still valid.
+ if (IsTaskValid(task)) {
+ // Task is still ok.
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): got a timeout, "
+ "continuing...",
+ __FUNCTION__);
+ continue;
+ } else {
+ // The inferior task is no longer valid. Time to exit as
+ // the process has gone away.
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): the inferior "
+ "task has exited, and so will we...",
+ __FUNCTION__);
+ // Does this race at all with our waitpid()?
+ SetState(eStateExited);
+ break;
+ }
+ }
+
+#if defined(WITH_SPRINGBOARD) && !defined(WITH_BKS)
+ if (watchdog.get()) {
+ watchdog_elapsed += periodic_timeout;
+ if (watchdog_elapsed >= watchdog_timeout) {
+ if (log)
+ log->Printf("SBSWatchdogAssertionRenew(%p)", watchdog.get());
+ ::SBSWatchdogAssertionRenew(watchdog.get());
+ watchdog_elapsed = 0;
+ }
+ }
+#endif
+ } else {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): continuing after "
+ "receiving an unexpected error: %u (%s)",
+ __FUNCTION__, error.GetError(), error.AsCString());
+ // TODO: notify of error?
+ }
+ }
+ }
+
+#if defined(WITH_SPRINGBOARD) && !defined(WITH_BKS)
+ if (watchdog.get()) {
+ // TODO: change SBSWatchdogAssertionRelease to SBSWatchdogAssertionCancel
+ // when we
+ // all are up and running on systems that support it. The SBS framework has
+ // a #define
+ // that will forward SBSWatchdogAssertionRelease to
+ // SBSWatchdogAssertionCancel for now
+ // so it should still build either way.
+ DNBLogThreadedIf(LOG_TASK, "::SBSWatchdogAssertionRelease(%p)",
+ watchdog.get());
+ ::SBSWatchdogAssertionRelease(watchdog.get());
+ }
+#endif // #if defined (WITH_SPRINGBOARD) && !defined (WITH_BKS)
+
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(%p): thread exiting...", __FUNCTION__,
+ this);
+ return nullptr;
+}
+
+Error NativeProcessDarwin::StartExceptionThread() {
+ Error error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("NativeProcessDarwin::%s() called", __FUNCTION__);
+
+ // Make sure we've looked up the inferior port.
+ TaskPortForProcessID(error);
+
+ // Ensure the inferior task is valid.
+ if (!IsTaskValid()) {
+ error.SetErrorStringWithFormat("cannot start exception thread: "
+ "task 0x%4.4x is not valid",
+ m_task);
+ return error;
+ }
+
+ // Get the mach port for the process monitor.
+ mach_port_t task_self = mach_task_self();
+
+ // Allocate an exception port that we will use to track our child process
+ auto mach_err = ::mach_port_allocate(task_self, MACH_PORT_RIGHT_RECEIVE,
+ &m_exception_port);
+ error.SetError(mach_err, eErrorTypeMachKernel);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): mach_port_allocate("
+ "task_self=0x%4.4x, MACH_PORT_RIGHT_RECEIVE, "
+ "&m_exception_port) failed: %u (%s)",
+ __FUNCTION__, task_self, error.GetError(), error.AsCString());
+ return error;
+ }
+
+ // Add the ability to send messages on the new exception port
+ mach_err = ::mach_port_insert_right(
+ task_self, m_exception_port, m_exception_port, MACH_MSG_TYPE_MAKE_SEND);
+ error.SetError(mach_err, eErrorTypeMachKernel);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): mach_port_insert_right("
+ "task_self=0x%4.4x, m_exception_port=0x%4.4x, "
+ "m_exception_port=0x%4.4x, MACH_MSG_TYPE_MAKE_SEND) "
+ "failed: %u (%s)",
+ __FUNCTION__, task_self, m_exception_port, m_exception_port,
+ error.GetError(), error.AsCString());
+ return error;
+ }
+
+ // Save the original state of the exception ports for our child process.
+ error = SaveExceptionPortInfo();
+ if (error.Fail() || (m_exc_port_info.mask == 0)) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): SaveExceptionPortInfo() "
+ "failed, cannot install exception handler: %s",
+ __FUNCTION__, error.AsCString());
+ return error;
+ }
+
+ // Set the ability to get all exceptions on this port.
+ mach_err = ::task_set_exception_ports(
+ m_task, m_exc_port_info.mask, m_exception_port,
+ EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES, THREAD_STATE_NONE);
+ error.SetError(mach_err, eErrorTypeMachKernel);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("::task_set_exception_ports (task = 0x%4.4x, "
+ "exception_mask = 0x%8.8x, new_port = 0x%4.4x, "
+ "behavior = 0x%8.8x, new_flavor = 0x%8.8x) failed: "
+ "%u (%s)",
+ m_task, m_exc_port_info.mask, m_exception_port,
+ (EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES), THREAD_STATE_NONE,
+ error.GetError(), error.AsCString());
+ return error;
+ }
+
+ // Create the exception thread.
+ auto pthread_err =
+ ::pthread_create(&m_exception_thread, nullptr, ExceptionThread, this);
+ error.SetError(pthread_err, eErrorTypePOSIX);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): failed to create Mach "
+ "exception-handling thread: %u (%s)",
+ __FUNCTION__, error.GetError(), error.AsCString());
+ }
+
+ return error;
+}
+
+lldb::addr_t
+NativeProcessDarwin::GetDYLDAllImageInfosAddress(Error &error) const {
+ error.Clear();
+
+ struct hack_task_dyld_info dyld_info;
+ mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
+ // Make sure that COUNT isn't bigger than our hacked up struct
+ // hack_task_dyld_info. If it is, then make COUNT smaller to match.
+ if (count > (sizeof(struct hack_task_dyld_info) / sizeof(natural_t))) {
+ count = (sizeof(struct hack_task_dyld_info) / sizeof(natural_t));
+ }
+
+ TaskPortForProcessID(error);
+ if (error.Fail())
+ return LLDB_INVALID_ADDRESS;
+
+ auto mach_err =
+ ::task_info(m_task, TASK_DYLD_INFO, (task_info_t)&dyld_info, &count);
+ error.SetError(mach_err, eErrorTypeMachKernel);
+ if (error.Success()) {
+ // We now have the address of the all image infos structure.
+ return dyld_info.all_image_info_addr;
+ }
+
+ // We don't have it.
+ return LLDB_INVALID_ADDRESS;
+}
+
+uint32_t NativeProcessDarwin::GetCPUTypeForLocalProcess(::pid_t pid) {
+ int mib[CTL_MAXNAME] = {
+ 0,
+ };
+ size_t len = CTL_MAXNAME;
+
+ if (::sysctlnametomib("sysctl.proc_cputype", mib, &len))
+ return 0;
+
+ mib[len] = pid;
+ len++;
+
+ cpu_type_t cpu;
+ size_t cpu_len = sizeof(cpu);
+ if (::sysctl(mib, static_cast<u_int>(len), &cpu, &cpu_len, 0, 0))
+ cpu = 0;
+ return cpu;
+}
+
+uint32_t NativeProcessDarwin::GetCPUType() const {
+ if (m_cpu_type == 0 && m_pid != 0)
+ m_cpu_type = GetCPUTypeForLocalProcess(m_pid);
+ return m_cpu_type;
+}
+
+task_t NativeProcessDarwin::ExceptionMessageBundleComplete() {
+ // We have a complete bundle of exceptions for our child process.
+ Error error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
+
+ std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex);
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): processing %lu exception "
+ "messages.",
+ __FUNCTION__, m_exception_messages.size());
+
+ if (m_exception_messages.empty()) {
+ // Not particularly useful...
+ return m_task;
+ }
+
+ bool auto_resume = false;
+ m_did_exec = false;
+
+ // First check for any SIGTRAP and make sure we didn't exec
+ const task_t task = m_task;
+ size_t i;
+ if (m_pid != 0) {
+ bool received_interrupt = false;
+ uint32_t num_task_exceptions = 0;
+ for (i = 0; i < m_exception_messages.size(); ++i) {
+ if (m_exception_messages[i].state.task_port != task) {
+ // This is an exception that is not for our inferior, ignore.
+ continue;
+ }
+
+ // This is an exception for the inferior.
+ ++num_task_exceptions;
+ const int signo = m_exception_messages[i].state.SoftSignal();
+ if (signo == SIGTRAP) {
+ // SIGTRAP could mean that we exec'ed. We need to check the
+ // dyld all_image_infos.infoArray to see if it is NULL and if
+ // so, say that we exec'ed.
+ const addr_t aii_addr = GetDYLDAllImageInfosAddress(error);
+ if (aii_addr == LLDB_INVALID_ADDRESS)
+ break;
+
+ const addr_t info_array_count_addr = aii_addr + 4;
+ uint32_t info_array_count = 0;
+ size_t bytes_read = 0;
+ Error read_error;
+ read_error = ReadMemory(info_array_count_addr, // source addr
+ &info_array_count, // dest addr
+ 4, // byte count
+ bytes_read); // #bytes read
+ if (read_error.Success() && (bytes_read == 4)) {
+ if (info_array_count == 0) {
+ // We got the all infos address, and there are zero
+ // entries. We think we exec'd.
+ m_did_exec = true;
+
+ // Force the task port to update itself in case the
+ // task port changed after exec
+ const task_t old_task = m_task;
+ const bool force_update = true;
+ const task_t new_task = TaskPortForProcessID(error, force_update);
+ if (old_task != new_task) {
+ if (log)
+ log->Printf("exec: inferior task port changed "
+ "from 0x%4.4x to 0x%4.4x",
+ old_task, new_task);
+ }
+ }
+ } else {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s() warning: "
+ "failed to read all_image_infos."
+ "infoArrayCount from 0x%8.8llx",
+ __FUNCTION__, info_array_count_addr);
+ }
+ } else if ((m_sent_interrupt_signo != 0) &&
+ (signo == m_sent_interrupt_signo)) {
+ // We just received the interrupt that we sent to ourselves.
+ received_interrupt = true;
+ }
+ }
+
+ if (m_did_exec) {
+ cpu_type_t process_cpu_type = GetCPUTypeForLocalProcess(m_pid);
+ if (m_cpu_type != process_cpu_type) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): arch changed from "
+ "0x%8.8x to 0x%8.8x",
+ __FUNCTION__, m_cpu_type, process_cpu_type);
+ m_cpu_type = process_cpu_type;
+ // TODO figure out if we need to do something here.
+ // DNBArchProtocol::SetArchitecture (process_cpu_type);
+ }
+ m_thread_list.Clear();
+
+ // TODO hook up breakpoints.
+ // m_breakpoints.DisableAll();
+ }
+
+ if (m_sent_interrupt_signo != 0) {
+ if (received_interrupt) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): process "
+ "successfully interrupted with signal %i",
+ __FUNCTION__, m_sent_interrupt_signo);
+
+ // Mark that we received the interrupt signal
+ m_sent_interrupt_signo = 0;
+ // Now check if we had a case where:
+ // 1 - We called NativeProcessDarwin::Interrupt() but we stopped
+ // for another reason.
+ // 2 - We called NativeProcessDarwin::Resume() (but still
+ // haven't gotten the interrupt signal).
+ // 3 - We are now incorrectly stopped because we are handling
+ // the interrupt signal we missed.
+ // 4 - We might need to resume if we stopped only with the
+ // interrupt signal that we never handled.
+ if (m_auto_resume_signo != 0) {
+ // Only auto_resume if we stopped with _only_ the interrupt
+ // signal.
+ if (num_task_exceptions == 1) {
+ auto_resume = true;
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): auto "
+ "resuming due to unhandled interrupt "
+ "signal %i",
+ __FUNCTION__, m_auto_resume_signo);
+ }
+ m_auto_resume_signo = 0;
+ }
+ } else {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): didn't get signal "
+ "%i after MachProcess::Interrupt()",
+ __FUNCTION__, m_sent_interrupt_signo);
+ }
+ }
+ }
+
+ // Let all threads recover from stopping and do any clean up based
+ // on the previous thread state (if any).
+ m_thread_list.ProcessDidStop(*this);
+
+ // Let each thread know of any exceptions
+ for (i = 0; i < m_exception_messages.size(); ++i) {
+ // Let the thread list forward all exceptions on down to each thread.
+ if (m_exception_messages[i].state.task_port == task) {
+ // This exception is for our inferior.
+ m_thread_list.NotifyException(m_exception_messages[i].state);
+ }
+
+ if (log) {
+ StreamString stream;
+ m_exception_messages[i].Dump(stream);
+ stream.Flush();
+ log->PutCString(stream.GetString().c_str());
+ }
+ }
+
+ if (log) {
+ StreamString stream;
+ m_thread_list.Dump(stream);
+ stream.Flush();
+ log->PutCString(stream.GetString().c_str());
+ }
+
+ bool step_more = false;
+ if (m_thread_list.ShouldStop(step_more) && (auto_resume == false)) {
+// TODO - need to hook up event system here. !!!!
+#if 0
+ // Wait for the eEventProcessRunningStateChanged event to be reset
+ // before changing state to stopped to avoid race condition with
+ // very fast start/stops.
+ struct timespec timeout;
+
+ //DNBTimer::OffsetTimeOfDay(&timeout, 0, 250 * 1000); // Wait for 250 ms
+ DNBTimer::OffsetTimeOfDay(&timeout, 1, 0); // Wait for 250 ms
+ m_events.WaitForEventsToReset(eEventProcessRunningStateChanged,
+ &timeout);
+#endif
+ SetState(eStateStopped);
+ } else {
+ // Resume without checking our current state.
+ PrivateResume();
+ }
+
+ return m_task;
+}
+
+void NativeProcessDarwin::StartSTDIOThread() {
+ // TODO implement
+}
+
+Error NativeProcessDarwin::StartWaitpidThread(MainLoop &main_loop) {
+ Error error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ // Strategy: create a thread that sits on waitpid(), waiting for the
+ // inferior process to die, reaping it in the process. Arrange for
+ // the thread to have a pipe file descriptor that it can send a byte
+ // over when the waitpid completes. Have the main loop have a read
+ // object for the other side of the pipe, and have the callback for
+ // the read do the process termination message sending.
+
+ // Create a single-direction communication channel.
+ const bool child_inherits = false;
+ error = m_waitpid_pipe.CreateNew(child_inherits);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): failed to create waitpid "
+ "communication pipe: %s",
+ __FUNCTION__, error.AsCString());
+ return error;
+ }
+
+ // Hook up the waitpid reader callback.
+
+ // TODO make PipePOSIX derive from IOObject. This is goofy here.
+ const bool transfer_ownership = false;
+ auto io_sp = IOObjectSP(
+ new File(m_waitpid_pipe.GetReadFileDescriptor(), transfer_ownership));
+ m_waitpid_reader_handle = main_loop.RegisterReadObject(
+ io_sp, [this](MainLoopBase &) { HandleWaitpidResult(); }, error);
+
+ // Create the thread.
+ auto pthread_err =
+ ::pthread_create(&m_waitpid_thread, nullptr, WaitpidThread, this);
+ error.SetError(pthread_err, eErrorTypePOSIX);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): failed to create waitpid "
+ "handling thread: %u (%s)",
+ __FUNCTION__, error.GetError(), error.AsCString());
+ return error;
+ }
+
+ return error;
+}
+
+void *NativeProcessDarwin::WaitpidThread(void *arg) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (!arg) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): cannot run waitpid "
+ "thread, mandatory process arg was null",
+ __FUNCTION__);
+ return nullptr;
+ }
+
+ return reinterpret_cast<NativeProcessDarwin *>(arg)->DoWaitpidThread();
+}
+
+void NativeProcessDarwin::MaybeRaiseThreadPriority() {
+#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
+}
+
+void *NativeProcessDarwin::DoWaitpidThread() {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ if (m_pid == LLDB_INVALID_PROCESS_ID) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): inferior process ID is "
+ "not set, cannot waitpid on it",
+ __FUNCTION__);
+ return nullptr;
+ }
+
+ // Name the thread.
+ pthread_setname_np("waitpid thread");
+
+ // Ensure we don't get CPU starved.
+ MaybeRaiseThreadPriority();
+
+ Error error;
+ int status = -1;
+
+ while (1) {
+ // Do a waitpid.
+ ::pid_t child_pid = ::waitpid(m_pid, &status, 0);
+ if (child_pid < 0)
+ error.SetErrorToErrno();
+ if (error.Fail()) {
+ if (error.GetError() == EINTR) {
+ // This is okay, we can keep going.
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
+ ", &status, 0) interrupted, continuing",
+ __FUNCTION__, m_pid);
+ continue;
+ }
+
+ // This error is not okay, abort.
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
+ ", &status, 0) aborting due to error: %u (%s)",
+ __FUNCTION__, m_pid, error.GetError(), error.AsCString());
+ break;
+ }
+
+ // Log the successful result.
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
+ ", &status, 0) => %i, status = %i",
+ __FUNCTION__, m_pid, child_pid, status);
+
+ // Handle the result.
+ if (WIFSTOPPED(status)) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
+ ") received a stop, continuing waitpid() loop",
+ __FUNCTION__, m_pid);
+ continue;
+ } else // if (WIFEXITED(status) || WIFSIGNALED(status))
+ {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(pid = %" PRIu64 "): "
+ "waitpid thread is setting exit status for pid = "
+ "%i to %i",
+ __FUNCTION__, m_pid, child_pid, status);
+
+ error = SendInferiorExitStatusToMainLoop(child_pid, status);
+ return nullptr;
+ }
+ }
+
+ // We should never exit as long as our child process is alive. If we
+ // get here, something completely unexpected went wrong and we should exit.
+ if (log)
+ log->Printf(
+ "NativeProcessDarwin::%s(): internal error: waitpid thread "
+ "exited out of its main loop in an unexpected way. pid = %" PRIu64
+ ". Sending exit status of -1.",
+ __FUNCTION__, m_pid);
+
+ error = SendInferiorExitStatusToMainLoop((::pid_t)m_pid, -1);
+ return nullptr;
+}
+
+Error NativeProcessDarwin::SendInferiorExitStatusToMainLoop(::pid_t pid,
+ int status) {
+ Error error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ size_t bytes_written = 0;
+
+ // Send the pid.
+ error = m_waitpid_pipe.Write(&pid, sizeof(pid), bytes_written);
+ if (error.Fail() || (bytes_written < sizeof(pid))) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s() - failed to write "
+ "waitpid exiting pid to the pipe. Client will not "
+ "hear about inferior exit status!",
+ __FUNCTION__);
+ return error;
+ }
+
+ // Send the status.
+ bytes_written = 0;
+ error = m_waitpid_pipe.Write(&status, sizeof(status), bytes_written);
+ if (error.Fail() || (bytes_written < sizeof(status))) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s() - failed to write "
+ "waitpid exit result to the pipe. Client will not "
+ "hear about inferior exit status!",
+ __FUNCTION__);
+ }
+ return error;
+}
+
+Error NativeProcessDarwin::HandleWaitpidResult() {
+ Error error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ // Read the pid.
+ const bool notify_status = true;
+
+ ::pid_t pid = -1;
+ size_t bytes_read = 0;
+ error = m_waitpid_pipe.Read(&pid, sizeof(pid), bytes_read);
+ if (error.Fail() || (bytes_read < sizeof(pid))) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s() - failed to read "
+ "waitpid exiting pid from the pipe. Will notify "
+ "as if parent process died with exit status -1.",
+ __FUNCTION__);
+ SetExitStatus(eExitTypeInvalid, -1, "failed to receive waitpid result",
+ notify_status);
+ return error;
+ }
+
+ // Read the status.
+ int status = -1;
+ error = m_waitpid_pipe.Read(&status, sizeof(status), bytes_read);
+ if (error.Fail() || (bytes_read < sizeof(status))) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s() - failed to read "
+ "waitpid exit status from the pipe. Will notify "
+ "as if parent process died with exit status -1.",
+ __FUNCTION__);
+ SetExitStatus(eExitTypeInvalid, -1, "failed to receive waitpid result",
+ notify_status);
+ return error;
+ }
+
+ // Notify the monitor that our state has changed.
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): main loop received waitpid "
+ "exit status info: pid=%i (%s), status=%i",
+ __FUNCTION__, pid,
+ (pid == m_pid) ? "the inferior" : "not the inferior", status);
+
+ ExitType exit_type = eExitTypeInvalid;
+ int exit_status = -1;
+
+ if (WIFEXITED(status)) {
+ exit_type = eExitTypeExit;
+ exit_status = WEXITSTATUS(status);
+ } else if (WIFSIGNALED(status)) {
+ exit_type = eExitTypeSignal;
+ exit_status = WTERMSIG(status);
+ }
+
+ SetExitStatus(exit_type, exit_status, nullptr, notify_status);
+ return error;
+}
+
+task_t NativeProcessDarwin::TaskPortForProcessID(Error &error,
+ bool force) const {
+ if ((m_task == TASK_NULL) || force) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (m_pid == LLDB_INVALID_PROCESS_ID) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): cannot get task due "
+ "to invalid pid",
+ __FUNCTION__);
+ return TASK_NULL;
+ }
+
+ const uint32_t num_retries = 10;
+ const uint32_t usec_interval = 10000;
+
+ mach_port_t task_self = mach_task_self();
+ task_t task = TASK_NULL;
+
+ for (uint32_t i = 0; i < num_retries; i++) {
+ kern_return_t err = ::task_for_pid(task_self, m_pid, &task);
+ if (err == 0) {
+ // Succeeded. Save and return it.
+ error.Clear();
+ m_task = task;
+ log->Printf("NativeProcessDarwin::%s(): ::task_for_pid("
+ "stub_port = 0x%4.4x, pid = %llu, &task) "
+ "succeeded: inferior task port = 0x%4.4x",
+ __FUNCTION__, task_self, m_pid, m_task);
+ return m_task;
+ } else {
+ // Failed to get the task for the inferior process.
+ error.SetError(err, eErrorTypeMachKernel);
+ if (log) {
+ log->Printf("NativeProcessDarwin::%s(): ::task_for_pid("
+ "stub_port = 0x%4.4x, pid = %llu, &task) "
+ "failed, err = 0x%8.8x (%s)",
+ __FUNCTION__, task_self, m_pid, err, error.AsCString());
+ }
+ }
+
+ // Sleep a bit and try again
+ ::usleep(usec_interval);
+ }
+
+ // We failed to get the task for the inferior process.
+ // Ensure that it is cleared out.
+ m_task = TASK_NULL;
+ }
+ return m_task;
+}
+
+void NativeProcessDarwin::AttachToInferior(MainLoop &mainloop, lldb::pid_t pid,
+ Error &error) {
+ error.SetErrorString("TODO: implement");
+}
+
+Error NativeProcessDarwin::PrivateResume() {
+ Error error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex);
+ m_auto_resume_signo = m_sent_interrupt_signo;
+
+ if (log) {
+ if (m_auto_resume_signo)
+ log->Printf("NativeProcessDarwin::%s(): task 0x%x resuming (with "
+ "unhandled interrupt signal %i)...",
+ __FUNCTION__, m_task, m_auto_resume_signo);
+ else
+ log->Printf("NativeProcessDarwin::%s(): task 0x%x resuming...",
+ __FUNCTION__, m_task);
+ }
+
+ error = ReplyToAllExceptions();
+ if (error.Fail()) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): aborting, failed to "
+ "reply to exceptions: %s",
+ __FUNCTION__, error.AsCString());
+ return error;
+ }
+ // bool stepOverBreakInstruction = step;
+
+ // Let the thread prepare to resume and see if any threads want us to
+ // step over a breakpoint instruction (ProcessWillResume will modify
+ // the value of stepOverBreakInstruction).
+ m_thread_list.ProcessWillResume(*this, m_thread_actions);
+
+ // Set our state accordingly
+ if (m_thread_actions.NumActionsWithState(eStateStepping))
+ SetState(eStateStepping);
+ else
+ SetState(eStateRunning);
+
+ // Now resume our task.
+ error = ResumeTask();
+ return error;
+}
+
+Error NativeProcessDarwin::ReplyToAllExceptions() {
+ Error error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
+
+ TaskPortForProcessID(error);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): no task port, aborting",
+ __FUNCTION__);
+ return error;
+ }
+
+ std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex);
+ if (m_exception_messages.empty()) {
+ // We're done.
+ return error;
+ }
+
+ size_t index = 0;
+ for (auto &message : m_exception_messages) {
+ if (log) {
+ log->Printf("NativeProcessDarwin::%s(): replying to exception "
+ "%zu...",
+ __FUNCTION__, index++);
+ }
+
+ int thread_reply_signal = 0;
+
+ const tid_t tid =
+ m_thread_list.GetThreadIDByMachPortNumber(message.state.thread_port);
+ const ResumeAction *action = nullptr;
+ if (tid != LLDB_INVALID_THREAD_ID)
+ action = m_thread_actions.GetActionForThread(tid, false);
+
+ if (action) {
+ thread_reply_signal = action->signal;
+ if (thread_reply_signal)
+ m_thread_actions.SetSignalHandledForThread(tid);
+ }
+
+ error = message.Reply(m_pid, m_task, thread_reply_signal);
+ if (error.Fail() && log) {
+ // We log any error here, but we don't stop the exception
+ // response handling.
+ log->Printf("NativeProcessDarwin::%s(): failed to reply to "
+ "exception: %s",
+ __FUNCTION__, error.AsCString());
+ error.Clear();
+ }
+ }
+
+ // Erase all exception message as we should have used and replied
+ // to them all already.
+ m_exception_messages.clear();
+ return error;
+}
+
+Error NativeProcessDarwin::ResumeTask() {
+ Error error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ TaskPortForProcessID(error);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): failed to get task port "
+ "for process when attempting to resume: %s",
+ __FUNCTION__, error.AsCString());
+ return error;
+ }
+ if (m_task == TASK_NULL) {
+ error.SetErrorString("task port retrieval succeeded but task port is "
+ "null when attempting to resume the task");
+ return error;
+ }
+
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): requesting resume of task "
+ "0x%4.4x",
+ __FUNCTION__, m_task);
+
+ // Get the BasicInfo struct to verify that we're suspended before we try
+ // to resume the task.
+ struct task_basic_info task_info;
+ error = GetTaskBasicInfo(m_task, &task_info);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): failed to get task "
+ "BasicInfo when attempting to resume: %s",
+ __FUNCTION__, error.AsCString());
+ return error;
+ }
+
+ // task_resume isn't counted like task_suspend calls are, so if the
+ // task is not suspended, don't try and resume it since it is already
+ // running
+ if (task_info.suspend_count > 0) {
+ auto mach_err = ::task_resume(m_task);
+ error.SetError(mach_err, eErrorTypeMachKernel);
+ if (log) {
+ if (error.Success())
+ log->Printf("::task_resume(target_task = 0x%4.4x): success", m_task);
+ else
+ log->Printf("::task_resume(target_task = 0x%4.4x) error: %s", m_task,
+ error.AsCString());
+ }
+ } else {
+ if (log)
+ log->Printf("::task_resume(target_task = 0x%4.4x): ignored, "
+ "already running",
+ m_task);
+ }
+
+ return error;
+}
+
+bool NativeProcessDarwin::IsTaskValid() const {
+ if (m_task == TASK_NULL)
+ return false;
+
+ struct task_basic_info task_info;
+ return GetTaskBasicInfo(m_task, &task_info).Success();
+}
+
+bool NativeProcessDarwin::IsTaskValid(task_t task) const {
+ if (task == TASK_NULL)
+ return false;
+
+ struct task_basic_info task_info;
+ return GetTaskBasicInfo(task, &task_info).Success();
+}
+
+mach_port_t NativeProcessDarwin::GetExceptionPort() const {
+ return m_exception_port;
+}
+
+bool NativeProcessDarwin::IsExceptionPortValid() const {
+ return MACH_PORT_VALID(m_exception_port);
+}
+
+Error NativeProcessDarwin::GetTaskBasicInfo(
+ task_t task, struct task_basic_info *info) const {
+ Error error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ // Validate args.
+ if (info == NULL) {
+ error.SetErrorStringWithFormat("NativeProcessDarwin::%s(): mandatory "
+ "info arg is null",
+ __FUNCTION__);
+ return error;
+ }
+
+ // Grab the task if we don't already have it.
+ if (task == TASK_NULL) {
+ error.SetErrorStringWithFormat("NativeProcessDarwin::%s(): given task "
+ "is invalid",
+ __FUNCTION__);
+ }
+
+ mach_msg_type_number_t count = TASK_BASIC_INFO_COUNT;
+ auto err = ::task_info(m_task, TASK_BASIC_INFO, (task_info_t)info, &count);
+ error.SetError(err, eErrorTypeMachKernel);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("::task_info(target_task = 0x%4.4x, "
+ "flavor = TASK_BASIC_INFO, task_info_out => %p, "
+ "task_info_outCnt => %u) failed: %u (%s)",
+ m_task, info, count, error.GetError(), error.AsCString());
+ return error;
+ }
+
+ Log *verbose_log(
+ GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
+ if (verbose_log) {
+ float user = (float)info->user_time.seconds +
+ (float)info->user_time.microseconds / 1000000.0f;
+ float system = (float)info->user_time.seconds +
+ (float)info->user_time.microseconds / 1000000.0f;
+ verbose_log->Printf("task_basic_info = { suspend_count = %i, "
+ "virtual_size = 0x%8.8llx, resident_size = "
+ "0x%8.8llx, user_time = %f, system_time = %f }",
+ info->suspend_count, (uint64_t)info->virtual_size,
+ (uint64_t)info->resident_size, user, system);
+ }
+ return error;
+}
+
+Error NativeProcessDarwin::SuspendTask() {
+ Error error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ if (m_task == TASK_NULL) {
+ error.SetErrorString("task port is null, cannot suspend task");
+ if (log)
+ log->Printf("NativeProcessDarwin::%s() failed: %s", __FUNCTION__,
+ error.AsCString());
+ return error;
+ }
+
+ auto mach_err = ::task_suspend(m_task);
+ error.SetError(mach_err, eErrorTypeMachKernel);
+ if (error.Fail() && log)
+ log->Printf("::task_suspend(target_task = 0x%4.4x)", m_task);
+
+ return error;
+}
+
+Error NativeProcessDarwin::Resume(const ResumeActionList &resume_actions) {
+ Error error;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ if (log)
+ log->Printf("NativeProcessDarwin::%s() called", __FUNCTION__);
+
+ if (CanResume()) {
+ m_thread_actions = resume_actions;
+ error = PrivateResume();
+ return error;
+ }
+
+ auto state = GetState();
+ if (state == eStateRunning) {
+ if (log)
+ log->Printf("NativeProcessDarwin::%s(): task 0x%x is already "
+ "running, ignoring...",
+ __FUNCTION__, TaskPortForProcessID(error));
+ return error;
+ }
+
+ // We can't resume from this state.
+ error.SetErrorStringWithFormat("task 0x%x has state %s, can't resume",
+ TaskPortForProcessID(error),
+ StateAsCString(state));
+ return error;
+}
+
+Error NativeProcessDarwin::Halt() {
+ Error error;
+ error.SetErrorString("TODO: implement");
+ return error;
+}
+
+Error NativeProcessDarwin::Detach() {
+ Error error;
+ error.SetErrorString("TODO: implement");
+ return error;
+}
+
+Error NativeProcessDarwin::Signal(int signo) {
+ Error error;
+ error.SetErrorString("TODO: implement");
+ return error;
+}
+
+Error NativeProcessDarwin::Interrupt() {
+ Error error;
+ error.SetErrorString("TODO: implement");
+ return error;
+}
+
+Error NativeProcessDarwin::Kill() {
+ Error error;
+ error.SetErrorString("TODO: implement");
+ return error;
+}
+
+Error NativeProcessDarwin::GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &range_info) {
+ Error error;
+ error.SetErrorString("TODO: implement");
+ return error;
+}
+
+Error NativeProcessDarwin::ReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ size_t &bytes_read) {
+ Error error;
+ error.SetErrorString("TODO: implement");
+ return error;
+}
+
+Error NativeProcessDarwin::ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf,
+ size_t size,
+ size_t &bytes_read) {
+ Error error;
+ error.SetErrorString("TODO: implement");
+ return error;
+}
+
+Error NativeProcessDarwin::WriteMemory(lldb::addr_t addr, const void *buf,
+ size_t size, size_t &bytes_written) {
+ Error error;
+ error.SetErrorString("TODO: implement");
+ return error;
+}
+
+Error NativeProcessDarwin::AllocateMemory(size_t size, uint32_t permissions,
+ lldb::addr_t &addr) {
+ Error error;
+ error.SetErrorString("TODO: implement");
+ return error;
+}
+
+Error NativeProcessDarwin::DeallocateMemory(lldb::addr_t addr) {
+ Error error;
+ error.SetErrorString("TODO: implement");
+ return error;
+}
+
+lldb::addr_t NativeProcessDarwin::GetSharedLibraryInfoAddress() {
+ return LLDB_INVALID_ADDRESS;
+}
+
+size_t NativeProcessDarwin::UpdateThreads() { return 0; }
+
+bool NativeProcessDarwin::GetArchitecture(ArchSpec &arch) const {
+ return false;
+}
+
+Error NativeProcessDarwin::SetBreakpoint(lldb::addr_t addr, uint32_t size,
+ bool hardware) {
+ Error error;
+ error.SetErrorString("TODO: implement");
+ return error;
+}
+
+void NativeProcessDarwin::DoStopIDBumped(uint32_t newBumpId) {}
+
+Error NativeProcessDarwin::GetLoadedModuleFileSpec(const char *module_path,
+ FileSpec &file_spec) {
+ Error error;
+ error.SetErrorString("TODO: implement");
+ return error;
+}
+
+Error NativeProcessDarwin::GetFileLoadAddress(const llvm::StringRef &file_name,
+ lldb::addr_t &load_addr) {
+ Error error;
+ error.SetErrorString("TODO: implement");
+ return error;
+}
+
+// -----------------------------------------------------------------
+// NativeProcessProtocol protected interface
+// -----------------------------------------------------------------
+Error NativeProcessDarwin::GetSoftwareBreakpointTrapOpcode(
+ size_t trap_opcode_size_hint, size_t &actual_opcode_size,
+ const uint8_t *&trap_opcode_bytes) {
+ Error error;
+ error.SetErrorString("TODO: implement");
+ return error;
+}
diff --git a/source/Plugins/Process/Darwin/NativeProcessDarwin.h b/source/Plugins/Process/Darwin/NativeProcessDarwin.h
new file mode 100644
index 000000000000..69c1b8d9e4cc
--- /dev/null
+++ b/source/Plugins/Process/Darwin/NativeProcessDarwin.h
@@ -0,0 +1,384 @@
+//===-- NativeProcessDarwin.h --------------------------------- -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef NativeProcessDarwin_h
+#define NativeProcessDarwin_h
+
+// NOTE: this code should only be compiled on Apple Darwin systems. It is
+// not cross-platform code and is not intended to build on any other platform.
+// Therefore, platform-specific headers and code are okay here.
+
+// C includes
+#include <mach/mach_types.h>
+
+// C++ includes
+#include <mutex>
+#include <unordered_set>
+
+// Other libraries and framework includes
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Host/Debug.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Host/HostThread.h"
+#include "lldb/Host/Pipe.h"
+#include "lldb/Host/common/NativeProcessProtocol.h"
+#include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/lldb-types.h"
+
+#include "LaunchFlavor.h"
+#include "MachException.h"
+#include "NativeThreadDarwin.h"
+#include "NativeThreadListDarwin.h"
+
+namespace lldb_private {
+class Error;
+class Scalar;
+
+namespace process_darwin {
+
+/// @class NativeProcessDarwin
+/// @brief Manages communication with the inferior (debugee) process.
+///
+/// Upon construction, this class prepares and launches an inferior
+/// process for debugging.
+///
+/// Changes in the inferior process state are broadcasted.
+class NativeProcessDarwin : public NativeProcessProtocol {
+ friend Error NativeProcessProtocol::Launch(
+ ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate,
+ MainLoop &mainloop, NativeProcessProtocolSP &process_sp);
+
+ friend Error NativeProcessProtocol::Attach(
+ lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
+ MainLoop &mainloop, NativeProcessProtocolSP &process_sp);
+
+public:
+ ~NativeProcessDarwin() override;
+
+ // -----------------------------------------------------------------
+ // NativeProcessProtocol Interface
+ // -----------------------------------------------------------------
+ Error Resume(const ResumeActionList &resume_actions) override;
+
+ Error Halt() override;
+
+ Error Detach() override;
+
+ Error Signal(int signo) override;
+
+ Error Interrupt() override;
+
+ Error Kill() override;
+
+ Error GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &range_info) override;
+
+ Error ReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ size_t &bytes_read) override;
+
+ Error ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size,
+ size_t &bytes_read) override;
+
+ Error WriteMemory(lldb::addr_t addr, const void *buf, size_t size,
+ size_t &bytes_written) override;
+
+ Error AllocateMemory(size_t size, uint32_t permissions,
+ lldb::addr_t &addr) override;
+
+ Error DeallocateMemory(lldb::addr_t addr) override;
+
+ lldb::addr_t GetSharedLibraryInfoAddress() override;
+
+ size_t UpdateThreads() override;
+
+ bool GetArchitecture(ArchSpec &arch) const override;
+
+ Error SetBreakpoint(lldb::addr_t addr, uint32_t size, bool hardware) override;
+
+ void DoStopIDBumped(uint32_t newBumpId) override;
+
+ Error GetLoadedModuleFileSpec(const char *module_path,
+ FileSpec &file_spec) override;
+
+ Error GetFileLoadAddress(const llvm::StringRef &file_name,
+ lldb::addr_t &load_addr) override;
+
+ NativeThreadDarwinSP GetThreadByID(lldb::tid_t id);
+
+ task_t GetTask() const { return m_task; }
+
+ // -----------------------------------------------------------------
+ // Interface used by NativeRegisterContext-derived classes.
+ // -----------------------------------------------------------------
+ static Error PtraceWrapper(int req, lldb::pid_t pid, void *addr = nullptr,
+ void *data = nullptr, size_t data_size = 0,
+ long *result = nullptr);
+
+ bool SupportHardwareSingleStepping() const;
+
+protected:
+ // -----------------------------------------------------------------
+ // NativeProcessProtocol protected interface
+ // -----------------------------------------------------------------
+ Error
+ GetSoftwareBreakpointTrapOpcode(size_t trap_opcode_size_hint,
+ size_t &actual_opcode_size,
+ const uint8_t *&trap_opcode_bytes) override;
+
+private:
+ // -----------------------------------------------------------------
+ /// Mach task-related Member Variables
+ // -----------------------------------------------------------------
+
+ // The task port for the inferior process.
+ mutable task_t m_task;
+
+ // True if the inferior process did an exec since we started
+ // monitoring it.
+ bool m_did_exec;
+
+ // The CPU type of this process.
+ mutable cpu_type_t m_cpu_type;
+
+ // -----------------------------------------------------------------
+ /// Exception/Signal Handling Member Variables
+ // -----------------------------------------------------------------
+
+ // Exception port on which we will receive child exceptions
+ mach_port_t m_exception_port;
+
+ // Saved state of the child exception port prior to us installing
+ // our own intercepting port.
+ MachException::PortInfo m_exc_port_info;
+
+ // The thread that runs the Mach exception read and reply handler.
+ pthread_t m_exception_thread;
+
+ // TODO see if we can remove this if we get the exception collection
+ // and distribution to happen in a single-threaded fashion.
+ std::recursive_mutex m_exception_messages_mutex;
+
+ // A collection of exception messages caught when listening to the
+ // exception port.
+ MachException::Message::collection m_exception_messages;
+
+ // When we call MachProcess::Interrupt(), we want to send this
+ // signal (if non-zero).
+ int m_sent_interrupt_signo;
+
+ // If we resume the process and still haven't received our
+ // interrupt signal (if this is non-zero).
+ int m_auto_resume_signo;
+
+ // -----------------------------------------------------------------
+ /// Thread-related Member Variables
+ // -----------------------------------------------------------------
+ NativeThreadListDarwin m_thread_list;
+ ResumeActionList m_thread_actions;
+
+ // -----------------------------------------------------------------
+ /// Process Lifetime Member Variable
+ // -----------------------------------------------------------------
+
+ // The pipe over which the waitpid thread and the main loop will
+ // communicate.
+ Pipe m_waitpid_pipe;
+
+ // The thread that runs the waitpid handler.
+ pthread_t m_waitpid_thread;
+
+ // waitpid reader callback handle.
+ MainLoop::ReadHandleUP m_waitpid_reader_handle;
+
+#if 0
+ ArchSpec m_arch;
+
+ LazyBool m_supports_mem_region;
+ std::vector<MemoryRegionInfo> m_mem_region_cache;
+
+ lldb::tid_t m_pending_notification_tid;
+
+ // List of thread ids stepping with a breakpoint with the address of
+ // the relevan breakpoint
+ std::map<lldb::tid_t, lldb::addr_t>
+ m_threads_stepping_with_breakpoint;
+#endif
+
+ // -----------------------------------------------------------------
+ // Private Instance Methods
+ // -----------------------------------------------------------------
+ NativeProcessDarwin(lldb::pid_t pid, int pty_master_fd);
+
+ // -----------------------------------------------------------------
+ /// Finalize the launch.
+ ///
+ /// This method associates the NativeProcessDarwin instance with
+ /// the host process that was just launched. It peforms actions
+ /// like attaching a listener to the inferior exception port,
+ /// ptracing the process, and the like.
+ ///
+ /// @param[in] launch_flavor
+ /// The launch flavor that was used to launch the process.
+ ///
+ /// @param[in] main_loop
+ /// The main loop that will run the process monitor. Work
+ /// that needs to be done (e.g. reading files) gets registered
+ /// here along with callbacks to process the work.
+ ///
+ /// @return
+ /// Any error that occurred during the aforementioned
+ /// operations. Failure here will force termination of the
+ /// launched process and debugging session.
+ // -----------------------------------------------------------------
+ Error FinalizeLaunch(LaunchFlavor launch_flavor, MainLoop &main_loop);
+
+ Error SaveExceptionPortInfo();
+
+ void ExceptionMessageReceived(const MachException::Message &message);
+
+ void MaybeRaiseThreadPriority();
+
+ Error StartExceptionThread();
+
+ Error SendInferiorExitStatusToMainLoop(::pid_t pid, int status);
+
+ Error HandleWaitpidResult();
+
+ bool ProcessUsingSpringBoard() const;
+
+ bool ProcessUsingBackBoard() const;
+
+ static void *ExceptionThread(void *arg);
+
+ void *DoExceptionThread();
+
+ lldb::addr_t GetDYLDAllImageInfosAddress(Error &error) const;
+
+ static uint32_t GetCPUTypeForLocalProcess(::pid_t pid);
+
+ uint32_t GetCPUType() const;
+
+ task_t ExceptionMessageBundleComplete();
+
+ void StartSTDIOThread();
+
+ Error StartWaitpidThread(MainLoop &main_loop);
+
+ static void *WaitpidThread(void *arg);
+
+ void *DoWaitpidThread();
+
+ task_t TaskPortForProcessID(Error &error, bool force = false) const;
+
+ /// Attaches to an existing process. Forms the
+ /// implementation of Process::DoAttach.
+ void AttachToInferior(MainLoop &mainloop, lldb::pid_t pid, Error &error);
+
+ ::pid_t Attach(lldb::pid_t pid, Error &error);
+
+ Error PrivateResume();
+
+ Error ReplyToAllExceptions();
+
+ Error ResumeTask();
+
+ bool IsTaskValid() const;
+
+ bool IsTaskValid(task_t task) const;
+
+ mach_port_t GetExceptionPort() const;
+
+ bool IsExceptionPortValid() const;
+
+ Error GetTaskBasicInfo(task_t task, struct task_basic_info *info) const;
+
+ Error SuspendTask();
+
+ static Error SetDefaultPtraceOpts(const lldb::pid_t);
+
+ static void *MonitorThread(void *baton);
+
+ void MonitorCallback(lldb::pid_t pid, bool exited, int signal, int status);
+
+ void WaitForNewThread(::pid_t tid);
+
+ void MonitorSIGTRAP(const siginfo_t &info, NativeThreadDarwin &thread);
+
+ void MonitorTrace(NativeThreadDarwin &thread);
+
+ void MonitorBreakpoint(NativeThreadDarwin &thread);
+
+ void MonitorWatchpoint(NativeThreadDarwin &thread, uint32_t wp_index);
+
+ void MonitorSignal(const siginfo_t &info, NativeThreadDarwin &thread,
+ bool exited);
+
+ Error SetupSoftwareSingleStepping(NativeThreadDarwin &thread);
+
+#if 0
+ static ::ProcessMessage::CrashReason
+ GetCrashReasonForSIGSEGV(const siginfo_t *info);
+
+ static ::ProcessMessage::CrashReason
+ GetCrashReasonForSIGILL(const siginfo_t *info);
+
+ static ::ProcessMessage::CrashReason
+ GetCrashReasonForSIGFPE(const siginfo_t *info);
+
+ static ::ProcessMessage::CrashReason
+ GetCrashReasonForSIGBUS(const siginfo_t *info);
+#endif
+
+ bool HasThreadNoLock(lldb::tid_t thread_id);
+
+ bool StopTrackingThread(lldb::tid_t thread_id);
+
+ NativeThreadDarwinSP AddThread(lldb::tid_t thread_id);
+
+ Error GetSoftwareBreakpointPCOffset(uint32_t &actual_opcode_size);
+
+ Error FixupBreakpointPCAsNeeded(NativeThreadDarwin &thread);
+
+ /// Writes a siginfo_t structure corresponding to the given thread
+ /// ID to the memory region pointed to by @p siginfo.
+ Error GetSignalInfo(lldb::tid_t tid, void *siginfo);
+
+ /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG)
+ /// corresponding to the given thread ID to the memory pointed to
+ /// by @p message.
+ Error GetEventMessage(lldb::tid_t tid, unsigned long *message);
+
+ void NotifyThreadDeath(lldb::tid_t tid);
+
+ Error Detach(lldb::tid_t tid);
+
+ // This method is requests a stop on all threads which are still
+ // running. It sets up a deferred delegate notification, which will
+ // fire once threads report as stopped. The triggerring_tid will be
+ // set as the current thread (main stop reason).
+ void StopRunningThreads(lldb::tid_t triggering_tid);
+
+ // Notify the delegate if all threads have stopped.
+ void SignalIfAllThreadsStopped();
+
+ // Resume the given thread, optionally passing it the given signal.
+ // The type of resume operation (continue, single-step) depends on
+ // the state parameter.
+ Error ResumeThread(NativeThreadDarwin &thread, lldb::StateType state,
+ int signo);
+
+ void ThreadWasCreated(NativeThreadDarwin &thread);
+
+ void SigchldHandler();
+};
+
+} // namespace process_darwin
+} // namespace lldb_private
+
+#endif /* NativeProcessDarwin_h */
diff --git a/source/Plugins/Process/Darwin/NativeThreadDarwin.cpp b/source/Plugins/Process/Darwin/NativeThreadDarwin.cpp
new file mode 100644
index 000000000000..5e7f9ae7e6f9
--- /dev/null
+++ b/source/Plugins/Process/Darwin/NativeThreadDarwin.cpp
@@ -0,0 +1,284 @@
+//===-- NativeThreadDarwin.cpp -------------------------------- -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "NativeThreadDarwin.h"
+
+// C includes
+#include <libproc.h>
+
+// LLDB includes
+#include "lldb/Core/Stream.h"
+
+#include "NativeProcessDarwin.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_darwin;
+
+uint64_t NativeThreadDarwin::GetGloballyUniqueThreadIDForMachPortID(
+ ::thread_t mach_port_id) {
+ thread_identifier_info_data_t tident;
+ mach_msg_type_number_t tident_count = THREAD_IDENTIFIER_INFO_COUNT;
+
+ auto mach_err = ::thread_info(mach_port_id, THREAD_IDENTIFIER_INFO,
+ (thread_info_t)&tident, &tident_count);
+ if (mach_err != KERN_SUCCESS) {
+ // When we fail to get thread info for the supposed port, assume it is
+ // really a globally unique thread id already, or return the best thing
+ // we can, which is the thread port.
+ return mach_port_id;
+ }
+ return tident.thread_id;
+}
+
+NativeThreadDarwin::NativeThreadDarwin(NativeProcessDarwin *process,
+ bool is_64_bit,
+ lldb::tid_t unique_thread_id,
+ ::thread_t mach_thread_port)
+ : NativeThreadProtocol(process, unique_thread_id),
+ m_mach_thread_port(mach_thread_port), m_basic_info(),
+ m_proc_threadinfo() {}
+
+bool NativeThreadDarwin::GetIdentifierInfo() {
+ // Don't try to get the thread info once and cache it for the life of the
+ // thread. It changes over time, for instance
+ // if the thread name changes, then the thread_handle also changes... So you
+ // have to refetch it every time.
+ mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
+ kern_return_t kret = ::thread_info(m_mach_thread_port, THREAD_IDENTIFIER_INFO,
+ (thread_info_t)&m_ident_info, &count);
+ return kret == KERN_SUCCESS;
+
+ return false;
+}
+
+std::string NativeThreadDarwin::GetName() {
+ std::string name;
+
+ if (GetIdentifierInfo()) {
+ auto process_sp = GetProcess();
+ if (!process_sp) {
+ name = "<unavailable>";
+ return name;
+ }
+
+ int len = ::proc_pidinfo(process_sp->GetID(), PROC_PIDTHREADINFO,
+ m_ident_info.thread_handle, &m_proc_threadinfo,
+ sizeof(m_proc_threadinfo));
+
+ if (len && m_proc_threadinfo.pth_name[0])
+ name = m_proc_threadinfo.pth_name;
+ }
+ return name;
+}
+
+lldb::StateType NativeThreadDarwin::GetState() {
+ // TODO implement
+ return eStateInvalid;
+}
+
+bool NativeThreadDarwin::GetStopReason(ThreadStopInfo &stop_info,
+ std::string &description) {
+ // TODO implement
+ return false;
+}
+
+NativeRegisterContextSP NativeThreadDarwin::GetRegisterContext() {
+ // TODO implement
+ return NativeRegisterContextSP();
+}
+
+Error NativeThreadDarwin::SetWatchpoint(lldb::addr_t addr, size_t size,
+ uint32_t watch_flags, bool hardware) {
+ Error error;
+ error.SetErrorString("not yet implemented");
+ return error;
+}
+
+Error NativeThreadDarwin::RemoveWatchpoint(lldb::addr_t addr) {
+ Error error;
+ error.SetErrorString("not yet implemented");
+ return error;
+}
+
+void NativeThreadDarwin::Dump(Stream &stream) const {
+// This is what we really want once we have the thread class wired up.
+#if 0
+ DNBLogThreaded("[%3u] #%3u tid: 0x%8.8" PRIx64 ", pc: 0x%16.16" PRIx64 ", sp: 0x%16.16" PRIx64 ", user: %d.%6.6d, system: %d.%6.6d, cpu: %2d, policy: %2d, run_state: %2d (%s), flags: %2d, suspend_count: %2d (current %2d), sleep_time: %d",
+ index,
+ m_seq_id,
+ m_unique_id,
+ GetPC(INVALID_NUB_ADDRESS),
+ GetSP(INVALID_NUB_ADDRESS),
+ m_basic_info.user_time.seconds, m_basic_info.user_time.microseconds,
+ m_basic_info.system_time.seconds, m_basic_info.system_time.microseconds,
+ m_basic_info.cpu_usage,
+ m_basic_info.policy,
+ m_basic_info.run_state,
+ thread_run_state,
+ m_basic_info.flags,
+ m_basic_info.suspend_count, m_suspend_count,
+ m_basic_info.sleep_time);
+
+#else
+ // Here's all we have right now.
+ stream.Printf("tid: 0x%8.8" PRIx64 ", thread port: 0x%4.4x", GetID(),
+ m_mach_thread_port);
+#endif
+}
+
+bool NativeThreadDarwin::NotifyException(MachException::Data &exc) {
+// TODO implement this.
+#if 0
+ // Allow the arch specific protocol to process (MachException::Data &)exc
+ // first before possible reassignment of m_stop_exception with exc.
+ // See also MachThread::GetStopException().
+ bool handled = m_arch_ap->NotifyException(exc);
+
+ if (m_stop_exception.IsValid())
+ {
+ // We may have more than one exception for a thread, but we need to
+ // only remember the one that we will say is the reason we stopped.
+ // We may have been single stepping and also gotten a signal exception,
+ // so just remember the most pertinent one.
+ if (m_stop_exception.IsBreakpoint())
+ m_stop_exception = exc;
+ }
+ else
+ {
+ m_stop_exception = exc;
+ }
+
+ return handled;
+#else
+ // Pretend we handled it.
+ return true;
+#endif
+}
+
+bool NativeThreadDarwin::ShouldStop(bool &step_more) const {
+// TODO: implement this
+#if 0
+ // See if this thread is at a breakpoint?
+ DNBBreakpoint *bp = CurrentBreakpoint();
+
+ if (bp)
+ {
+ // This thread is sitting at a breakpoint, ask the breakpoint
+ // if we should be stopping here.
+ return true;
+ }
+ else
+ {
+ if (m_arch_ap->StepNotComplete())
+ {
+ step_more = true;
+ return false;
+ }
+ // The thread state is used to let us know what the thread was
+ // trying to do. MachThread::ThreadWillResume() will set the
+ // thread state to various values depending if the thread was
+ // the current thread and if it was to be single stepped, or
+ // resumed.
+ if (GetState() == eStateRunning)
+ {
+ // If our state is running, then we should continue as we are in
+ // the process of stepping over a breakpoint.
+ return false;
+ }
+ else
+ {
+ // Stop if we have any kind of valid exception for this
+ // thread.
+ if (GetStopException().IsValid())
+ return true;
+ }
+ }
+ return false;
+#else
+ return false;
+#endif
+}
+
+void NativeThreadDarwin::ThreadDidStop() {
+// TODO implement this.
+#if 0
+ // This thread has existed prior to resuming under debug nub control,
+ // and has just been stopped. Do any cleanup that needs to be done
+ // after running.
+
+ // The thread state and breakpoint will still have the same values
+ // as they had prior to resuming the thread, so it makes it easy to check
+ // if we were trying to step a thread, or we tried to resume while being
+ // at a breakpoint.
+
+ // When this method gets called, the process state is still in the
+ // state it was in while running so we can act accordingly.
+ m_arch_ap->ThreadDidStop();
+
+
+ // We may have suspended this thread so the primary thread could step
+ // without worrying about race conditions, so lets restore our suspend
+ // count.
+ RestoreSuspendCountAfterStop();
+
+ // Update the basic information for a thread
+ MachThread::GetBasicInfo(m_mach_port_number, &m_basic_info);
+
+ if (m_basic_info.suspend_count > 0)
+ SetState(eStateSuspended);
+ else
+ SetState(eStateStopped);
+#endif
+}
+
+bool NativeThreadDarwin::MachPortNumberIsValid(::thread_t thread) {
+ return thread != (::thread_t)(0);
+}
+
+const struct thread_basic_info *NativeThreadDarwin::GetBasicInfo() const {
+ if (GetBasicInfo(m_mach_thread_port, &m_basic_info))
+ return &m_basic_info;
+ return NULL;
+}
+
+bool NativeThreadDarwin::GetBasicInfo(::thread_t thread,
+ struct thread_basic_info *basicInfoPtr) {
+ if (MachPortNumberIsValid(thread)) {
+ unsigned int info_count = THREAD_BASIC_INFO_COUNT;
+ kern_return_t err = ::thread_info(thread, THREAD_BASIC_INFO,
+ (thread_info_t)basicInfoPtr, &info_count);
+ if (err == KERN_SUCCESS)
+ return true;
+ }
+ ::memset(basicInfoPtr, 0, sizeof(struct thread_basic_info));
+ return false;
+}
+
+bool NativeThreadDarwin::IsUserReady() const {
+ if (m_basic_info.run_state == 0)
+ GetBasicInfo();
+
+ switch (m_basic_info.run_state) {
+ default:
+ case TH_STATE_UNINTERRUPTIBLE:
+ break;
+
+ case TH_STATE_RUNNING:
+ case TH_STATE_STOPPED:
+ case TH_STATE_WAITING:
+ case TH_STATE_HALTED:
+ return true;
+ }
+ return false;
+}
+
+NativeProcessDarwinSP NativeThreadDarwin::GetNativeProcessDarwinSP() {
+ return std::static_pointer_cast<NativeProcessDarwin>(GetProcess());
+}
diff --git a/source/Plugins/Process/Darwin/NativeThreadDarwin.h b/source/Plugins/Process/Darwin/NativeThreadDarwin.h
new file mode 100644
index 000000000000..b8d9089e673e
--- /dev/null
+++ b/source/Plugins/Process/Darwin/NativeThreadDarwin.h
@@ -0,0 +1,178 @@
+//===-- NativeThreadDarwin.h ---------------------------------- -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef NativeThreadDarwin_H
+#define NativeThreadDarwin_H
+
+// C includes
+#include <mach/mach_types.h>
+#include <sched.h>
+#include <sys/proc_info.h>
+
+// C++ includes
+#include <map>
+#include <memory>
+#include <string>
+
+// LLDB includes
+#include "lldb/Host/common/NativeThreadProtocol.h"
+#include "lldb/lldb-private-forward.h"
+
+#include "MachException.h"
+
+namespace lldb_private {
+namespace process_darwin {
+
+class NativeProcessDarwin;
+using NativeProcessDarwinSP = std::shared_ptr<NativeProcessDarwin>;
+
+class NativeThreadListDarwin;
+
+class NativeThreadDarwin : public NativeThreadProtocol {
+ friend class NativeProcessDarwin;
+ friend class NativeThreadListDarwin;
+
+public:
+ static uint64_t
+ GetGloballyUniqueThreadIDForMachPortID(::thread_t mach_port_id);
+
+ NativeThreadDarwin(NativeProcessDarwin *process, bool is_64_bit,
+ lldb::tid_t unique_thread_id = 0,
+ ::thread_t mach_thread_port = 0);
+
+ // -----------------------------------------------------------------
+ // NativeThreadProtocol Interface
+ // -----------------------------------------------------------------
+ std::string GetName() override;
+
+ lldb::StateType GetState() override;
+
+ bool GetStopReason(ThreadStopInfo &stop_info,
+ std::string &description) override;
+
+ NativeRegisterContextSP GetRegisterContext() override;
+
+ Error SetWatchpoint(lldb::addr_t addr, size_t size, uint32_t watch_flags,
+ bool hardware) override;
+
+ Error RemoveWatchpoint(lldb::addr_t addr) override;
+
+ // -----------------------------------------------------------------
+ // New methods that are fine for others to call.
+ // -----------------------------------------------------------------
+ void Dump(Stream &stream) const;
+
+private:
+ // -----------------------------------------------------------------
+ // Interface for friend classes
+ // -----------------------------------------------------------------
+
+ /// Resumes the thread. If @p signo is anything but
+ /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread.
+ Error Resume(uint32_t signo);
+
+ /// Single steps the thread. If @p signo is anything but
+ /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread.
+ Error SingleStep(uint32_t signo);
+
+ bool NotifyException(MachException::Data &exc);
+
+ bool ShouldStop(bool &step_more) const;
+
+ void ThreadDidStop();
+
+ void SetStoppedBySignal(uint32_t signo, const siginfo_t *info = nullptr);
+
+ /// Return true if the thread is stopped.
+ /// If stopped by a signal, indicate the signo in the signo
+ /// argument. Otherwise, return LLDB_INVALID_SIGNAL_NUMBER.
+ bool IsStopped(int *signo);
+
+ const struct thread_basic_info *GetBasicInfo() const;
+
+ static bool GetBasicInfo(::thread_t thread,
+ struct thread_basic_info *basicInfoPtr);
+
+ bool IsUserReady() const;
+
+ void SetStoppedByExec();
+
+ void SetStoppedByBreakpoint();
+
+ void SetStoppedByWatchpoint(uint32_t wp_index);
+
+ bool IsStoppedAtBreakpoint();
+
+ bool IsStoppedAtWatchpoint();
+
+ void SetStoppedByTrace();
+
+ void SetStoppedWithNoReason();
+
+ void SetExited();
+
+ Error RequestStop();
+
+ // -------------------------------------------------------------------------
+ /// Return the mach thread port number for this thread.
+ ///
+ /// @return
+ /// The mach port number for this thread. Returns NULL_THREAD
+ /// when the thread is invalid.
+ // -------------------------------------------------------------------------
+ thread_t GetMachPortNumber() const { return m_mach_thread_port; }
+
+ static bool MachPortNumberIsValid(::thread_t thread);
+
+ // ---------------------------------------------------------------------
+ // Private interface
+ // ---------------------------------------------------------------------
+ bool GetIdentifierInfo();
+
+ void MaybeLogStateChange(lldb::StateType new_state);
+
+ NativeProcessDarwinSP GetNativeProcessDarwinSP();
+
+ void SetStopped();
+
+ inline void MaybePrepareSingleStepWorkaround();
+
+ inline void MaybeCleanupSingleStepWorkaround();
+
+ // -----------------------------------------------------------------
+ // Member Variables
+ // -----------------------------------------------------------------
+
+ // The mach thread port for the thread.
+ ::thread_t m_mach_thread_port;
+
+ // The most recently-retrieved thread basic info.
+ mutable ::thread_basic_info m_basic_info;
+
+ struct proc_threadinfo m_proc_threadinfo;
+
+ thread_identifier_info_data_t m_ident_info;
+
+#if 0
+ lldb::StateType m_state;
+ ThreadStopInfo m_stop_info;
+ NativeRegisterContextSP m_reg_context_sp;
+ std::string m_stop_description;
+ using WatchpointIndexMap = std::map<lldb::addr_t, uint32_t>;
+ WatchpointIndexMap m_watchpoint_index_map;
+ // cpu_set_t m_original_cpu_set; // For single-step workaround.
+#endif
+};
+
+typedef std::shared_ptr<NativeThreadDarwin> NativeThreadDarwinSP;
+
+} // namespace process_darwin
+} // namespace lldb_private
+
+#endif // #ifndef NativeThreadDarwin_H
diff --git a/source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp b/source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp
new file mode 100644
index 000000000000..aa9b04157658
--- /dev/null
+++ b/source/Plugins/Process/Darwin/NativeThreadListDarwin.cpp
@@ -0,0 +1,698 @@
+//===-- NativeThreadListDarwin.cpp ------------------------------------*- C++
+//-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Created by Greg Clayton on 6/19/07.
+//
+//===----------------------------------------------------------------------===//
+
+#include "NativeThreadListDarwin.h"
+
+// C includes
+#include <inttypes.h>
+#include <mach/vm_map.h>
+#include <sys/sysctl.h>
+
+// LLDB includes
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/lldb-enumerations.h"
+
+#include "NativeProcessDarwin.h"
+#include "NativeThreadDarwin.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_darwin;
+
+NativeThreadListDarwin::NativeThreadListDarwin()
+ : m_threads(), m_threads_mutex(), m_is_64_bit(false) {}
+
+NativeThreadListDarwin::~NativeThreadListDarwin() {}
+
+// These methods will be accessed directly from NativeThreadDarwin
+#if 0
+nub_state_t
+NativeThreadListDarwin::GetState(nub_thread_t tid)
+{
+ MachThreadSP thread_sp (GetThreadByID (tid));
+ if (thread_sp)
+ return thread_sp->GetState();
+ return eStateInvalid;
+}
+
+const char *
+NativeThreadListDarwin::GetName (nub_thread_t tid)
+{
+ MachThreadSP thread_sp (GetThreadByID (tid));
+ if (thread_sp)
+ return thread_sp->GetName();
+ return NULL;
+}
+#endif
+
+// TODO: figure out if we need to add this to NativeThreadDarwin yet.
+#if 0
+ThreadInfo::QoS
+NativeThreadListDarwin::GetRequestedQoS (nub_thread_t tid, nub_addr_t tsd, uint64_t dti_qos_class_index)
+{
+ MachThreadSP thread_sp (GetThreadByID (tid));
+ if (thread_sp)
+ return thread_sp->GetRequestedQoS(tsd, dti_qos_class_index);
+ return ThreadInfo::QoS();
+}
+
+nub_addr_t
+NativeThreadListDarwin::GetPThreadT (nub_thread_t tid)
+{
+ MachThreadSP thread_sp (GetThreadByID (tid));
+ if (thread_sp)
+ return thread_sp->GetPThreadT();
+ return INVALID_NUB_ADDRESS;
+}
+
+nub_addr_t
+NativeThreadListDarwin::GetDispatchQueueT (nub_thread_t tid)
+{
+ MachThreadSP thread_sp (GetThreadByID (tid));
+ if (thread_sp)
+ return thread_sp->GetDispatchQueueT();
+ return INVALID_NUB_ADDRESS;
+}
+
+nub_addr_t
+NativeThreadListDarwin::GetTSDAddressForThread (nub_thread_t tid, uint64_t plo_pthread_tsd_base_address_offset, uint64_t plo_pthread_tsd_base_offset, uint64_t plo_pthread_tsd_entry_size)
+{
+ MachThreadSP thread_sp (GetThreadByID (tid));
+ if (thread_sp)
+ return thread_sp->GetTSDAddressForThread(plo_pthread_tsd_base_address_offset, plo_pthread_tsd_base_offset, plo_pthread_tsd_entry_size);
+ return INVALID_NUB_ADDRESS;
+}
+#endif
+
+// TODO implement these
+#if 0
+nub_thread_t
+NativeThreadListDarwin::SetCurrentThread(nub_thread_t tid)
+{
+ MachThreadSP thread_sp (GetThreadByID (tid));
+ if (thread_sp)
+ {
+ m_current_thread = thread_sp;
+ return tid;
+ }
+ return INVALID_NUB_THREAD;
+}
+
+
+bool
+NativeThreadListDarwin::GetThreadStoppedReason(nub_thread_t tid, struct DNBThreadStopInfo *stop_info) const
+{
+ MachThreadSP thread_sp (GetThreadByID (tid));
+ if (thread_sp)
+ return thread_sp->GetStopException().GetStopInfo(stop_info);
+ return false;
+}
+
+bool
+NativeThreadListDarwin::GetIdentifierInfo (nub_thread_t tid, thread_identifier_info_data_t *ident_info)
+{
+ thread_t mach_port_number = GetMachPortNumberByThreadID (tid);
+
+ mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
+ return ::thread_info (mach_port_number, THREAD_IDENTIFIER_INFO, (thread_info_t)ident_info, &count) == KERN_SUCCESS;
+}
+
+void
+NativeThreadListDarwin::DumpThreadStoppedReason (nub_thread_t tid) const
+{
+ MachThreadSP thread_sp (GetThreadByID (tid));
+ if (thread_sp)
+ thread_sp->GetStopException().DumpStopReason();
+}
+
+const char *
+NativeThreadListDarwin::GetThreadInfo (nub_thread_t tid) const
+{
+ MachThreadSP thread_sp (GetThreadByID (tid));
+ if (thread_sp)
+ return thread_sp->GetBasicInfoAsString();
+ return NULL;
+}
+
+#endif
+
+NativeThreadDarwinSP
+NativeThreadListDarwin::GetThreadByID(lldb::tid_t tid) const {
+ std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
+ for (auto thread_sp : m_threads) {
+ if (thread_sp && (thread_sp->GetID() == tid))
+ return thread_sp;
+ }
+ return NativeThreadDarwinSP();
+}
+
+NativeThreadDarwinSP NativeThreadListDarwin::GetThreadByMachPortNumber(
+ ::thread_t mach_port_number) const {
+ std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
+ for (auto thread_sp : m_threads) {
+ if (thread_sp && (thread_sp->GetMachPortNumber() == mach_port_number))
+ return thread_sp;
+ }
+ return NativeThreadDarwinSP();
+}
+
+lldb::tid_t NativeThreadListDarwin::GetThreadIDByMachPortNumber(
+ ::thread_t mach_port_number) const {
+ std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
+ for (auto thread_sp : m_threads) {
+ if (thread_sp && (thread_sp->GetMachPortNumber() == mach_port_number))
+ return thread_sp->GetID();
+ }
+ return LLDB_INVALID_THREAD_ID;
+}
+
+// TODO implement
+#if 0
+thread_t
+NativeThreadListDarwin::GetMachPortNumberByThreadID (nub_thread_t globally_unique_id) const
+{
+ PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
+ MachThreadSP thread_sp;
+ const size_t num_threads = m_threads.size();
+ for (size_t idx = 0; idx < num_threads; ++idx)
+ {
+ if (m_threads[idx]->ThreadID() == globally_unique_id)
+ {
+ return m_threads[idx]->MachPortNumber();
+ }
+ }
+ return 0;
+}
+
+bool
+NativeThreadListDarwin::GetRegisterValue (nub_thread_t tid, uint32_t set, uint32_t reg, DNBRegisterValue *reg_value ) const
+{
+ MachThreadSP thread_sp (GetThreadByID (tid));
+ if (thread_sp)
+ return thread_sp->GetRegisterValue(set, reg, reg_value);
+
+ return false;
+}
+
+bool
+NativeThreadListDarwin::SetRegisterValue (nub_thread_t tid, uint32_t set, uint32_t reg, const DNBRegisterValue *reg_value ) const
+{
+ MachThreadSP thread_sp (GetThreadByID (tid));
+ if (thread_sp)
+ return thread_sp->SetRegisterValue(set, reg, reg_value);
+
+ return false;
+}
+
+nub_size_t
+NativeThreadListDarwin::GetRegisterContext (nub_thread_t tid, void *buf, size_t buf_len)
+{
+ MachThreadSP thread_sp (GetThreadByID (tid));
+ if (thread_sp)
+ return thread_sp->GetRegisterContext (buf, buf_len);
+ return 0;
+}
+
+nub_size_t
+NativeThreadListDarwin::SetRegisterContext (nub_thread_t tid, const void *buf, size_t buf_len)
+{
+ MachThreadSP thread_sp (GetThreadByID (tid));
+ if (thread_sp)
+ return thread_sp->SetRegisterContext (buf, buf_len);
+ return 0;
+}
+
+uint32_t
+NativeThreadListDarwin::SaveRegisterState (nub_thread_t tid)
+{
+ MachThreadSP thread_sp (GetThreadByID (tid));
+ if (thread_sp)
+ return thread_sp->SaveRegisterState ();
+ return 0;
+}
+
+bool
+NativeThreadListDarwin::RestoreRegisterState (nub_thread_t tid, uint32_t save_id)
+{
+ MachThreadSP thread_sp (GetThreadByID (tid));
+ if (thread_sp)
+ return thread_sp->RestoreRegisterState (save_id);
+ return 0;
+}
+#endif
+
+size_t NativeThreadListDarwin::GetNumberOfThreads() const {
+ std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
+ return static_cast<size_t>(m_threads.size());
+}
+
+// TODO implement
+#if 0
+nub_thread_t
+NativeThreadListDarwin::ThreadIDAtIndex (nub_size_t idx) const
+{
+ PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
+ if (idx < m_threads.size())
+ return m_threads[idx]->ThreadID();
+ return INVALID_NUB_THREAD;
+}
+
+nub_thread_t
+NativeThreadListDarwin::CurrentThreadID ( )
+{
+ MachThreadSP thread_sp;
+ CurrentThread(thread_sp);
+ if (thread_sp.get())
+ return thread_sp->ThreadID();
+ return INVALID_NUB_THREAD;
+}
+
+#endif
+
+bool NativeThreadListDarwin::NotifyException(MachException::Data &exc) {
+ auto thread_sp = GetThreadByMachPortNumber(exc.thread_port);
+ if (thread_sp) {
+ thread_sp->NotifyException(exc);
+ return true;
+ }
+ return false;
+}
+
+void NativeThreadListDarwin::Clear() {
+ std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
+ m_threads.clear();
+}
+
+uint32_t NativeThreadListDarwin::UpdateThreadList(NativeProcessDarwin &process,
+ bool update,
+ collection *new_threads) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
+
+ std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
+ if (log)
+ log->Printf("NativeThreadListDarwin::%s() (pid = %" PRIu64 ", update = "
+ "%u) process stop count = %u",
+ __FUNCTION__, process.GetID(), update, process.GetStopID());
+
+ if (process.GetStopID() == 0) {
+ // On our first stop, we'll record details like 32/64 bitness and
+ // select the proper architecture implementation.
+ //
+ int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, (int)process.GetID()};
+
+ struct kinfo_proc processInfo;
+ size_t bufsize = sizeof(processInfo);
+ if ((sysctl(mib, (unsigned)(sizeof(mib) / sizeof(int)), &processInfo,
+ &bufsize, NULL, 0) == 0) &&
+ (bufsize > 0)) {
+ if (processInfo.kp_proc.p_flag & P_LP64)
+ m_is_64_bit = true;
+ }
+
+// TODO implement architecture selection and abstraction.
+#if 0
+#if defined(__i386__) || defined(__x86_64__)
+ if (m_is_64_bit)
+ DNBArchProtocol::SetArchitecture(CPU_TYPE_X86_64);
+ else
+ DNBArchProtocol::SetArchitecture(CPU_TYPE_I386);
+#elif defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
+ if (m_is_64_bit)
+ DNBArchProtocol::SetArchitecture(CPU_TYPE_ARM64);
+ else
+ DNBArchProtocol::SetArchitecture(CPU_TYPE_ARM);
+#endif
+#endif
+ }
+
+ if (m_threads.empty() || update) {
+ thread_array_t thread_list = nullptr;
+ mach_msg_type_number_t thread_list_count = 0;
+ task_t task = process.GetTask();
+
+ Error error;
+ auto mach_err = ::task_threads(task, &thread_list, &thread_list_count);
+ error.SetError(mach_err, eErrorTypeMachKernel);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("::task_threads(task = 0x%4.4x, thread_list => %p, "
+ "thread_list_count => %u) failed: %u (%s)",
+ task, thread_list, thread_list_count, error.GetError(),
+ error.AsCString());
+ return 0;
+ }
+
+ if (thread_list_count > 0) {
+ collection currThreads;
+ size_t idx;
+ // Iterator through the current thread list and see which threads
+ // we already have in our list (keep them), which ones we don't
+ // (add them), and which ones are not around anymore (remove them).
+ for (idx = 0; idx < thread_list_count; ++idx) {
+ // Get the Mach thread port.
+ const ::thread_t mach_port_num = thread_list[idx];
+
+ // Get the unique thread id for the mach port number.
+ uint64_t unique_thread_id =
+ NativeThreadDarwin::GetGloballyUniqueThreadIDForMachPortID(
+ mach_port_num);
+
+ // Retrieve the thread if it exists.
+ auto thread_sp = GetThreadByID(unique_thread_id);
+ if (thread_sp) {
+ // We are already tracking it. Keep the existing native
+ // thread instance.
+ currThreads.push_back(thread_sp);
+ } else {
+ // We don't have a native thread instance for this thread.
+ // Create it now.
+ thread_sp.reset(new NativeThreadDarwin(
+ &process, m_is_64_bit, unique_thread_id, mach_port_num));
+
+ // Add the new thread regardless of its is user ready state.
+ // Make sure the thread is ready to be displayed and shown
+ // to users before we add this thread to our list...
+ if (thread_sp->IsUserReady()) {
+ if (new_threads)
+ new_threads->push_back(thread_sp);
+
+ currThreads.push_back(thread_sp);
+ }
+ }
+ }
+
+ m_threads.swap(currThreads);
+ m_current_thread.reset();
+
+ // Free the vm memory given to us by ::task_threads()
+ vm_size_t thread_list_size =
+ (vm_size_t)(thread_list_count * sizeof(::thread_t));
+ ::vm_deallocate(::mach_task_self(), (vm_address_t)thread_list,
+ thread_list_size);
+ }
+ }
+ return static_cast<uint32_t>(m_threads.size());
+}
+
+// TODO implement
+#if 0
+
+void
+NativeThreadListDarwin::CurrentThread (MachThreadSP& thread_sp)
+{
+ // locker will keep a mutex locked until it goes out of scope
+ PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
+ if (m_current_thread.get() == NULL)
+ {
+ // Figure out which thread is going to be our current thread.
+ // This is currently done by finding the first thread in the list
+ // that has a valid exception.
+ const size_t num_threads = m_threads.size();
+ for (uint32_t idx = 0; idx < num_threads; ++idx)
+ {
+ if (m_threads[idx]->GetStopException().IsValid())
+ {
+ m_current_thread = m_threads[idx];
+ break;
+ }
+ }
+ }
+ thread_sp = m_current_thread;
+}
+
+#endif
+
+void NativeThreadListDarwin::Dump(Stream &stream) const {
+ bool first = true;
+
+ std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
+ for (auto thread_sp : m_threads) {
+ if (thread_sp) {
+ // Handle newlines between thread entries.
+ if (first)
+ first = false;
+ else
+ stream.PutChar('\n');
+ thread_sp->Dump(stream);
+ }
+ }
+}
+
+void NativeThreadListDarwin::ProcessWillResume(
+ NativeProcessDarwin &process, const ResumeActionList &thread_actions) {
+ std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
+
+ // Update our thread list, because sometimes libdispatch or the kernel
+ // will spawn threads while a task is suspended.
+ NativeThreadListDarwin::collection new_threads;
+
+// TODO implement this.
+#if 0
+ // First figure out if we were planning on running only one thread, and if
+ // so, force that thread to resume.
+ bool run_one_thread;
+ thread_t solo_thread = THREAD_NULL;
+ if ((thread_actions.GetSize() > 0) &&
+ (thread_actions.NumActionsWithState(eStateStepping) +
+ thread_actions.NumActionsWithState (eStateRunning) == 1))
+ {
+ run_one_thread = true;
+ const DNBThreadResumeAction *action_ptr = thread_actions.GetFirst();
+ size_t num_actions = thread_actions.GetSize();
+ for (size_t i = 0; i < num_actions; i++, action_ptr++)
+ {
+ if (action_ptr->state == eStateStepping || action_ptr->state == eStateRunning)
+ {
+ solo_thread = action_ptr->tid;
+ break;
+ }
+ }
+ }
+ else
+ run_one_thread = false;
+#endif
+
+ UpdateThreadList(process, true, &new_threads);
+
+#if 0
+ DNBThreadResumeAction resume_new_threads = { -1U, eStateRunning, 0, INVALID_NUB_ADDRESS };
+ // If we are planning to run only one thread, any new threads should be suspended.
+ if (run_one_thread)
+ resume_new_threads.state = eStateSuspended;
+
+ const size_t num_new_threads = new_threads.size();
+ const size_t num_threads = m_threads.size();
+ for (uint32_t idx = 0; idx < num_threads; ++idx)
+ {
+ MachThread *thread = m_threads[idx].get();
+ bool handled = false;
+ for (uint32_t new_idx = 0; new_idx < num_new_threads; ++new_idx)
+ {
+ if (thread == new_threads[new_idx].get())
+ {
+ thread->ThreadWillResume(&resume_new_threads);
+ handled = true;
+ break;
+ }
+ }
+
+ if (!handled)
+ {
+ const DNBThreadResumeAction *thread_action = thread_actions.GetActionForThread (thread->ThreadID(), true);
+ // There must always be a thread action for every thread.
+ assert (thread_action);
+ bool others_stopped = false;
+ if (solo_thread == thread->ThreadID())
+ others_stopped = true;
+ thread->ThreadWillResume (thread_action, others_stopped);
+ }
+ }
+
+ if (new_threads.size())
+ {
+ for (uint32_t idx = 0; idx < num_new_threads; ++idx)
+ {
+ DNBLogThreadedIf (LOG_THREAD, "NativeThreadListDarwin::ProcessWillResume (pid = %4.4x) stop-id=%u, resuming newly discovered thread: 0x%8.8" PRIx64 ", thread-is-user-ready=%i)",
+ process->ProcessID(),
+ process->StopCount(),
+ new_threads[idx]->ThreadID(),
+ new_threads[idx]->IsUserReady());
+ }
+ }
+#endif
+}
+
+uint32_t NativeThreadListDarwin::ProcessDidStop(NativeProcessDarwin &process) {
+ std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
+
+ // Update our thread list.
+ UpdateThreadList(process, true);
+
+ for (auto thread_sp : m_threads) {
+ if (thread_sp)
+ thread_sp->ThreadDidStop();
+ }
+ return (uint32_t)m_threads.size();
+}
+
+//----------------------------------------------------------------------
+// Check each thread in our thread list to see if we should notify our
+// client of the current halt in execution.
+//
+// Breakpoints can have callback functions associated with them than
+// can return true to stop, or false to continue executing the inferior.
+//
+// RETURNS
+// true if we should stop and notify our clients
+// false if we should resume our child process and skip notification
+//----------------------------------------------------------------------
+bool NativeThreadListDarwin::ShouldStop(bool &step_more) {
+ std::lock_guard<std::recursive_mutex> locker(m_threads_mutex);
+ for (auto thread_sp : m_threads) {
+ if (thread_sp && thread_sp->ShouldStop(step_more))
+ return true;
+ }
+ return false;
+}
+
+// Implement.
+#if 0
+
+void
+NativeThreadListDarwin::NotifyBreakpointChanged (const DNBBreakpoint *bp)
+{
+ PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
+ const size_t num_threads = m_threads.size();
+ for (uint32_t idx = 0; idx < num_threads; ++idx)
+ {
+ m_threads[idx]->NotifyBreakpointChanged(bp);
+ }
+}
+
+
+uint32_t
+NativeThreadListDarwin::EnableHardwareBreakpoint (const DNBBreakpoint* bp) const
+{
+ if (bp != NULL)
+ {
+ const size_t num_threads = m_threads.size();
+ for (uint32_t idx = 0; idx < num_threads; ++idx)
+ m_threads[idx]->EnableHardwareBreakpoint(bp);
+ }
+ return INVALID_NUB_HW_INDEX;
+}
+
+bool
+NativeThreadListDarwin::DisableHardwareBreakpoint (const DNBBreakpoint* bp) const
+{
+ if (bp != NULL)
+ {
+ const size_t num_threads = m_threads.size();
+ for (uint32_t idx = 0; idx < num_threads; ++idx)
+ m_threads[idx]->DisableHardwareBreakpoint(bp);
+ }
+ return false;
+}
+
+// DNBWatchpointSet() -> MachProcess::CreateWatchpoint() -> MachProcess::EnableWatchpoint()
+// -> NativeThreadListDarwin::EnableHardwareWatchpoint().
+uint32_t
+NativeThreadListDarwin::EnableHardwareWatchpoint (const DNBBreakpoint* wp) const
+{
+ uint32_t hw_index = INVALID_NUB_HW_INDEX;
+ if (wp != NULL)
+ {
+ PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
+ const size_t num_threads = m_threads.size();
+ // On Mac OS X we have to prime the control registers for new threads. We do this
+ // using the control register data for the first thread, for lack of a better way of choosing.
+ bool also_set_on_task = true;
+ for (uint32_t idx = 0; idx < num_threads; ++idx)
+ {
+ if ((hw_index = m_threads[idx]->EnableHardwareWatchpoint(wp, also_set_on_task)) == INVALID_NUB_HW_INDEX)
+ {
+ // We know that idx failed for some reason. Let's rollback the transaction for [0, idx).
+ for (uint32_t i = 0; i < idx; ++i)
+ m_threads[i]->RollbackTransForHWP();
+ return INVALID_NUB_HW_INDEX;
+ }
+ also_set_on_task = false;
+ }
+ // Notify each thread to commit the pending transaction.
+ for (uint32_t idx = 0; idx < num_threads; ++idx)
+ m_threads[idx]->FinishTransForHWP();
+
+ }
+ return hw_index;
+}
+
+bool
+NativeThreadListDarwin::DisableHardwareWatchpoint (const DNBBreakpoint* wp) const
+{
+ if (wp != NULL)
+ {
+ PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
+ const size_t num_threads = m_threads.size();
+
+ // On Mac OS X we have to prime the control registers for new threads. We do this
+ // using the control register data for the first thread, for lack of a better way of choosing.
+ bool also_set_on_task = true;
+ for (uint32_t idx = 0; idx < num_threads; ++idx)
+ {
+ if (!m_threads[idx]->DisableHardwareWatchpoint(wp, also_set_on_task))
+ {
+ // We know that idx failed for some reason. Let's rollback the transaction for [0, idx).
+ for (uint32_t i = 0; i < idx; ++i)
+ m_threads[i]->RollbackTransForHWP();
+ return false;
+ }
+ also_set_on_task = false;
+ }
+ // Notify each thread to commit the pending transaction.
+ for (uint32_t idx = 0; idx < num_threads; ++idx)
+ m_threads[idx]->FinishTransForHWP();
+
+ return true;
+ }
+ return false;
+}
+
+uint32_t
+NativeThreadListDarwin::NumSupportedHardwareWatchpoints () const
+{
+ PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
+ const size_t num_threads = m_threads.size();
+ // Use an arbitrary thread to retrieve the number of supported hardware watchpoints.
+ if (num_threads)
+ return m_threads[0]->NumSupportedHardwareWatchpoints();
+ return 0;
+}
+
+uint32_t
+NativeThreadListDarwin::GetThreadIndexForThreadStoppedWithSignal (const int signo) const
+{
+ PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
+ uint32_t should_stop = false;
+ const size_t num_threads = m_threads.size();
+ for (uint32_t idx = 0; !should_stop && idx < num_threads; ++idx)
+ {
+ if (m_threads[idx]->GetStopException().SoftSignal () == signo)
+ return idx;
+ }
+ return UINT32_MAX;
+}
+
+#endif
diff --git a/source/Plugins/Process/Darwin/NativeThreadListDarwin.h b/source/Plugins/Process/Darwin/NativeThreadListDarwin.h
new file mode 100644
index 000000000000..2b194bcc1537
--- /dev/null
+++ b/source/Plugins/Process/Darwin/NativeThreadListDarwin.h
@@ -0,0 +1,139 @@
+//===-- NativeThreadListDarwin.h --------------------------------------*- C++
+//-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Created by Greg Clayton on 6/19/07.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __NativeThreadListDarwin_h__
+#define __NativeThreadListDarwin_h__
+
+#include <memory>
+#include <mutex>
+#include <vector>
+
+#include "lldb/lldb-private-forward.h"
+#include "lldb/lldb-types.h"
+
+#include "MachException.h"
+
+// #include "ThreadInfo.h"
+
+namespace lldb_private {
+namespace process_darwin {
+
+class NativeBreakpointDarwin;
+class NativeProcessDarwin;
+
+class NativeThreadDarwin;
+using NativeThreadDarwinSP = std::shared_ptr<NativeThreadDarwin>;
+
+class NativeThreadListDarwin {
+public:
+ NativeThreadListDarwin();
+ ~NativeThreadListDarwin();
+
+ void Clear();
+
+ void Dump(Stream &stream) const;
+
+// These methods will be accessed directly from NativeThreadDarwin
+#if 0
+ bool GetRegisterValue (nub_thread_t tid, uint32_t set, uint32_t reg, DNBRegisterValue *reg_value) const;
+ bool SetRegisterValue (nub_thread_t tid, uint32_t set, uint32_t reg, const DNBRegisterValue *reg_value) const;
+ nub_size_t GetRegisterContext (nub_thread_t tid, void *buf, size_t buf_len);
+ nub_size_t SetRegisterContext (nub_thread_t tid, const void *buf, size_t buf_len);
+ uint32_t SaveRegisterState (nub_thread_t tid);
+ bool RestoreRegisterState (nub_thread_t tid, uint32_t save_id);
+#endif
+
+ const char *GetThreadInfo(lldb::tid_t tid) const;
+
+ void ProcessWillResume(NativeProcessDarwin &process,
+ const ResumeActionList &thread_actions);
+
+ uint32_t ProcessDidStop(NativeProcessDarwin &process);
+
+ bool NotifyException(MachException::Data &exc);
+
+ bool ShouldStop(bool &step_more);
+
+// These methods will be accessed directly from NativeThreadDarwin
+#if 0
+ const char * GetName (nub_thread_t tid);
+ nub_state_t GetState (nub_thread_t tid);
+ nub_thread_t SetCurrentThread (nub_thread_t tid);
+#endif
+
+// TODO: figure out if we need to add this to NativeThreadDarwin yet.
+#if 0
+ ThreadInfo::QoS GetRequestedQoS (nub_thread_t tid, nub_addr_t tsd, uint64_t dti_qos_class_index);
+ nub_addr_t GetPThreadT (nub_thread_t tid);
+ nub_addr_t GetDispatchQueueT (nub_thread_t tid);
+ nub_addr_t GetTSDAddressForThread (nub_thread_t tid, uint64_t plo_pthread_tsd_base_address_offset, uint64_t plo_pthread_tsd_base_offset, uint64_t plo_pthread_tsd_entry_size);
+#endif
+
+// These methods will be accessed directly from NativeThreadDarwin
+#if 0
+ bool GetThreadStoppedReason (nub_thread_t tid, struct DNBThreadStopInfo *stop_info) const;
+ void DumpThreadStoppedReason (nub_thread_t tid) const;
+ bool GetIdentifierInfo (nub_thread_t tid, thread_identifier_info_data_t *ident_info);
+#endif
+
+ size_t GetNumberOfThreads() const;
+
+ lldb::tid_t ThreadIDAtIndex(size_t idx) const;
+
+ lldb::tid_t GetCurrentThreadID();
+
+ NativeThreadDarwinSP GetCurrentThread();
+
+ void NotifyBreakpointChanged(const NativeBreakpointDarwin *bp);
+
+ uint32_t EnableHardwareBreakpoint(const NativeBreakpointDarwin *bp) const;
+
+ bool DisableHardwareBreakpoint(const NativeBreakpointDarwin *bp) const;
+
+ uint32_t EnableHardwareWatchpoint(const NativeBreakpointDarwin *wp) const;
+
+ bool DisableHardwareWatchpoint(const NativeBreakpointDarwin *wp) const;
+
+ uint32_t GetNumberOfSupportedHardwareWatchpoints() const;
+
+ size_t GetThreadIndexForThreadStoppedWithSignal(const int signo) const;
+
+ NativeThreadDarwinSP GetThreadByID(lldb::tid_t tid) const;
+
+ NativeThreadDarwinSP
+ GetThreadByMachPortNumber(::thread_t mach_port_number) const;
+
+ lldb::tid_t GetThreadIDByMachPortNumber(::thread_t mach_port_number) const;
+
+ thread_t GetMachPortNumberByThreadID(lldb::tid_t globally_unique_id) const;
+
+protected:
+ typedef std::vector<NativeThreadDarwinSP> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+
+ // Consider having this return an lldb_private::Error.
+ uint32_t UpdateThreadList(NativeProcessDarwin &process, bool update,
+ collection *num_threads = nullptr);
+
+ collection m_threads;
+ mutable std::recursive_mutex m_threads_mutex;
+ NativeThreadDarwinSP m_current_thread;
+ bool m_is_64_bit;
+};
+
+} // namespace process_darwin
+} // namespace lldb_private
+
+#endif // #ifndef __NativeThreadListDarwin_h__
diff --git a/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp b/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
index 3cb1cec6983f..0b09296cb7fd 100644
--- a/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
+++ b/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
@@ -16,684 +16,603 @@
#include "lldb/Target/UnixSignals.h"
// Project includes
-#include "lldb/Breakpoint/Watchpoint.h"
+#include "FreeBSDThread.h"
+#include "POSIXStopInfo.h"
+#include "Plugins/Process/Utility/RegisterContextFreeBSD_arm.h"
+#include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h"
+#include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h"
+#include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h"
+#include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
+#include "Plugins/Process/Utility/UnwindLLDB.h"
+#include "ProcessFreeBSD.h"
+#include "ProcessMonitor.h"
+#include "ProcessPOSIXLog.h"
+#include "RegisterContextPOSIXProcessMonitor_arm.h"
+#include "RegisterContextPOSIXProcessMonitor_arm64.h"
+#include "RegisterContextPOSIXProcessMonitor_mips64.h"
+#include "RegisterContextPOSIXProcessMonitor_powerpc.h"
+#include "RegisterContextPOSIXProcessMonitor_x86.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
+#include "lldb/Breakpoint/Watchpoint.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/State.h"
#include "lldb/Host/Host.h"
-#include "lldb/Host/HostNativeThread.h"
#include "lldb/Host/HostInfo.h"
+#include "lldb/Host/HostNativeThread.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/ThreadSpec.h"
#include "llvm/ADT/SmallString.h"
-#include "POSIXStopInfo.h"
-#include "FreeBSDThread.h"
-#include "ProcessFreeBSD.h"
-#include "ProcessPOSIXLog.h"
-#include "ProcessMonitor.h"
-#include "RegisterContextPOSIXProcessMonitor_arm.h"
-#include "RegisterContextPOSIXProcessMonitor_arm64.h"
-#include "RegisterContextPOSIXProcessMonitor_mips64.h"
-#include "RegisterContextPOSIXProcessMonitor_powerpc.h"
-#include "RegisterContextPOSIXProcessMonitor_x86.h"
-#include "Plugins/Process/Utility/RegisterContextFreeBSD_arm.h"
-#include "Plugins/Process/Utility/RegisterContextFreeBSD_arm64.h"
-#include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h"
-#include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h"
-#include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h"
-#include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h"
-#include "Plugins/Process/Utility/UnwindLLDB.h"
using namespace lldb;
using namespace lldb_private;
FreeBSDThread::FreeBSDThread(Process &process, lldb::tid_t tid)
- : Thread(process, tid),
- m_frame_ap (),
- m_breakpoint (),
- m_thread_name_valid (false),
- m_thread_name (),
- m_posix_thread(NULL)
-{
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
- if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
- log->Printf ("FreeBSDThread::%s (tid = %" PRIi64 ")", __FUNCTION__, tid);
-
- // Set the current watchpoints for this thread.
- Target &target = GetProcess()->GetTarget();
- const WatchpointList &wp_list = target.GetWatchpointList();
- size_t wp_size = wp_list.GetSize();
-
- for (uint32_t wp_idx = 0; wp_idx < wp_size; wp_idx++)
- {
- lldb::WatchpointSP wp = wp_list.GetByIndex(wp_idx);
- if (wp.get() && wp->IsEnabled())
- {
- // This watchpoint as been enabled; obviously this "new" thread
- // has been created since that watchpoint was enabled. Since
- // the POSIXBreakpointProtocol has yet to be initialized, its
- // m_watchpoints_initialized member will be FALSE. Attempting to
- // read the debug status register to determine if a watchpoint
- // has been hit would result in the zeroing of that register.
- // Since the active debug registers would have been cloned when
- // this thread was created, simply force the m_watchpoints_initized
- // member to TRUE and avoid resetting dr6 and dr7.
- GetPOSIXBreakpointProtocol()->ForceWatchpointsInitialized();
- }
+ : Thread(process, tid), m_frame_ap(), m_breakpoint(),
+ m_thread_name_valid(false), m_thread_name(), m_posix_thread(NULL) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+ if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
+ log->Printf("FreeBSDThread::%s (tid = %" PRIi64 ")", __FUNCTION__, tid);
+
+ // Set the current watchpoints for this thread.
+ Target &target = GetProcess()->GetTarget();
+ const WatchpointList &wp_list = target.GetWatchpointList();
+ size_t wp_size = wp_list.GetSize();
+
+ for (uint32_t wp_idx = 0; wp_idx < wp_size; wp_idx++) {
+ lldb::WatchpointSP wp = wp_list.GetByIndex(wp_idx);
+ if (wp.get() && wp->IsEnabled()) {
+ // This watchpoint as been enabled; obviously this "new" thread
+ // has been created since that watchpoint was enabled. Since
+ // the POSIXBreakpointProtocol has yet to be initialized, its
+ // m_watchpoints_initialized member will be FALSE. Attempting to
+ // read the debug status register to determine if a watchpoint
+ // has been hit would result in the zeroing of that register.
+ // Since the active debug registers would have been cloned when
+ // this thread was created, simply force the m_watchpoints_initized
+ // member to TRUE and avoid resetting dr6 and dr7.
+ GetPOSIXBreakpointProtocol()->ForceWatchpointsInitialized();
}
+ }
}
-FreeBSDThread::~FreeBSDThread()
-{
- DestroyThread();
-}
+FreeBSDThread::~FreeBSDThread() { DestroyThread(); }
-ProcessMonitor &
-FreeBSDThread::GetMonitor()
-{
- ProcessSP base = GetProcess();
- ProcessFreeBSD &process = static_cast<ProcessFreeBSD&>(*base);
- return process.GetMonitor();
+ProcessMonitor &FreeBSDThread::GetMonitor() {
+ ProcessSP base = GetProcess();
+ ProcessFreeBSD &process = static_cast<ProcessFreeBSD &>(*base);
+ return process.GetMonitor();
}
-void
-FreeBSDThread::RefreshStateAfterStop()
-{
- // Invalidate all registers in our register context. We don't set "force" to
- // true because the stop reply packet might have had some register values
- // that were expedited and these will already be copied into the register
- // context by the time this function gets called. The KDPRegisterContext
- // class has been made smart enough to detect when it needs to invalidate
- // which registers are valid by putting hooks in the register read and
- // register supply functions where they check the process stop ID and do
- // the right thing.
- //if (StateIsStoppedState(GetState())
- {
- const bool force = false;
- GetRegisterContext()->InvalidateIfNeeded (force);
- }
+void FreeBSDThread::RefreshStateAfterStop() {
+ // Invalidate all registers in our register context. We don't set "force" to
+ // true because the stop reply packet might have had some register values
+ // that were expedited and these will already be copied into the register
+ // context by the time this function gets called. The KDPRegisterContext
+ // class has been made smart enough to detect when it needs to invalidate
+ // which registers are valid by putting hooks in the register read and
+ // register supply functions where they check the process stop ID and do
+ // the right thing.
+ // if (StateIsStoppedState(GetState())
+ {
+ const bool force = false;
+ GetRegisterContext()->InvalidateIfNeeded(force);
+ }
}
-const char *
-FreeBSDThread::GetInfo()
-{
- return NULL;
-}
+const char *FreeBSDThread::GetInfo() { return NULL; }
-void
-FreeBSDThread::SetName (const char *name)
-{
- m_thread_name_valid = (name && name[0]);
- if (m_thread_name_valid)
- m_thread_name.assign (name);
- else
- m_thread_name.clear();
+void FreeBSDThread::SetName(const char *name) {
+ m_thread_name_valid = (name && name[0]);
+ if (m_thread_name_valid)
+ m_thread_name.assign(name);
+ else
+ m_thread_name.clear();
}
-const char *
-FreeBSDThread::GetName ()
-{
- if (!m_thread_name_valid)
- {
- llvm::SmallString<32> thread_name;
- HostNativeThread::GetName(GetID(), thread_name);
- m_thread_name = thread_name.c_str();
- m_thread_name_valid = true;
- }
+const char *FreeBSDThread::GetName() {
+ if (!m_thread_name_valid) {
+ llvm::SmallString<32> thread_name;
+ HostNativeThread::GetName(GetID(), thread_name);
+ m_thread_name = thread_name.c_str();
+ m_thread_name_valid = true;
+ }
- if (m_thread_name.empty())
- return NULL;
- return m_thread_name.c_str();
+ if (m_thread_name.empty())
+ return NULL;
+ return m_thread_name.c_str();
}
-lldb::RegisterContextSP
-FreeBSDThread::GetRegisterContext()
-{
- if (!m_reg_context_sp)
- {
- m_posix_thread = NULL;
-
- RegisterInfoInterface *reg_interface = NULL;
- const ArchSpec &target_arch = GetProcess()->GetTarget().GetArchitecture();
-
- assert(target_arch.GetTriple().getOS() == llvm::Triple::FreeBSD);
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::aarch64:
- reg_interface = new RegisterContextFreeBSD_arm64(target_arch);
- break;
- case llvm::Triple::arm:
- reg_interface = new RegisterContextFreeBSD_arm(target_arch);
- break;
- case llvm::Triple::ppc:
+lldb::RegisterContextSP FreeBSDThread::GetRegisterContext() {
+ if (!m_reg_context_sp) {
+ m_posix_thread = NULL;
+
+ RegisterInfoInterface *reg_interface = NULL;
+ const ArchSpec &target_arch = GetProcess()->GetTarget().GetArchitecture();
+
+ assert(target_arch.GetTriple().getOS() == llvm::Triple::FreeBSD);
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::aarch64:
+ reg_interface = new RegisterInfoPOSIX_arm64(target_arch);
+ break;
+ case llvm::Triple::arm:
+ reg_interface = new RegisterContextFreeBSD_arm(target_arch);
+ break;
+ case llvm::Triple::ppc:
#ifndef __powerpc64__
- reg_interface = new RegisterContextFreeBSD_powerpc32(target_arch);
- break;
+ reg_interface = new RegisterContextFreeBSD_powerpc32(target_arch);
+ break;
#endif
- case llvm::Triple::ppc64:
- reg_interface = new RegisterContextFreeBSD_powerpc64(target_arch);
- break;
- case llvm::Triple::mips64:
- reg_interface = new RegisterContextFreeBSD_mips64(target_arch);
- break;
- case llvm::Triple::x86:
- reg_interface = new RegisterContextFreeBSD_i386(target_arch);
- break;
- case llvm::Triple::x86_64:
- reg_interface = new RegisterContextFreeBSD_x86_64(target_arch);
- break;
- default:
- llvm_unreachable("CPU not supported");
- }
+ case llvm::Triple::ppc64:
+ reg_interface = new RegisterContextFreeBSD_powerpc64(target_arch);
+ break;
+ case llvm::Triple::mips64:
+ reg_interface = new RegisterContextFreeBSD_mips64(target_arch);
+ break;
+ case llvm::Triple::x86:
+ reg_interface = new RegisterContextFreeBSD_i386(target_arch);
+ break;
+ case llvm::Triple::x86_64:
+ reg_interface = new RegisterContextFreeBSD_x86_64(target_arch);
+ break;
+ default:
+ llvm_unreachable("CPU not supported");
+ }
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::aarch64:
- {
- RegisterContextPOSIXProcessMonitor_arm64 *reg_ctx = new RegisterContextPOSIXProcessMonitor_arm64(*this, 0, reg_interface);
- m_posix_thread = reg_ctx;
- m_reg_context_sp.reset(reg_ctx);
- break;
- }
- case llvm::Triple::arm:
- {
- RegisterContextPOSIXProcessMonitor_arm *reg_ctx = new RegisterContextPOSIXProcessMonitor_arm(*this, 0, reg_interface);
- m_posix_thread = reg_ctx;
- m_reg_context_sp.reset(reg_ctx);
- break;
- }
- case llvm::Triple::mips64:
- {
- RegisterContextPOSIXProcessMonitor_mips64 *reg_ctx = new RegisterContextPOSIXProcessMonitor_mips64(*this, 0, reg_interface);
- m_posix_thread = reg_ctx;
- m_reg_context_sp.reset(reg_ctx);
- break;
- }
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- {
- RegisterContextPOSIXProcessMonitor_powerpc *reg_ctx = new RegisterContextPOSIXProcessMonitor_powerpc(*this, 0, reg_interface);
- m_posix_thread = reg_ctx;
- m_reg_context_sp.reset(reg_ctx);
- break;
- }
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- {
- RegisterContextPOSIXProcessMonitor_x86_64 *reg_ctx = new RegisterContextPOSIXProcessMonitor_x86_64(*this, 0, reg_interface);
- m_posix_thread = reg_ctx;
- m_reg_context_sp.reset(reg_ctx);
- break;
- }
- default:
- break;
- }
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::aarch64: {
+ RegisterContextPOSIXProcessMonitor_arm64 *reg_ctx =
+ new RegisterContextPOSIXProcessMonitor_arm64(*this, 0, reg_interface);
+ m_posix_thread = reg_ctx;
+ m_reg_context_sp.reset(reg_ctx);
+ break;
+ }
+ case llvm::Triple::arm: {
+ RegisterContextPOSIXProcessMonitor_arm *reg_ctx =
+ new RegisterContextPOSIXProcessMonitor_arm(*this, 0, reg_interface);
+ m_posix_thread = reg_ctx;
+ m_reg_context_sp.reset(reg_ctx);
+ break;
}
- return m_reg_context_sp;
+ case llvm::Triple::mips64: {
+ RegisterContextPOSIXProcessMonitor_mips64 *reg_ctx =
+ new RegisterContextPOSIXProcessMonitor_mips64(*this, 0,
+ reg_interface);
+ m_posix_thread = reg_ctx;
+ m_reg_context_sp.reset(reg_ctx);
+ break;
+ }
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64: {
+ RegisterContextPOSIXProcessMonitor_powerpc *reg_ctx =
+ new RegisterContextPOSIXProcessMonitor_powerpc(*this, 0,
+ reg_interface);
+ m_posix_thread = reg_ctx;
+ m_reg_context_sp.reset(reg_ctx);
+ break;
+ }
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64: {
+ RegisterContextPOSIXProcessMonitor_x86_64 *reg_ctx =
+ new RegisterContextPOSIXProcessMonitor_x86_64(*this, 0,
+ reg_interface);
+ m_posix_thread = reg_ctx;
+ m_reg_context_sp.reset(reg_ctx);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ return m_reg_context_sp;
}
lldb::RegisterContextSP
-FreeBSDThread::CreateRegisterContextForFrame(lldb_private::StackFrame *frame)
-{
- lldb::RegisterContextSP reg_ctx_sp;
- uint32_t concrete_frame_idx = 0;
-
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
- if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
- log->Printf ("FreeBSDThread::%s ()", __FUNCTION__);
-
- if (frame)
- concrete_frame_idx = frame->GetConcreteFrameIndex();
-
- if (concrete_frame_idx == 0)
- reg_ctx_sp = GetRegisterContext();
- else
- {
- assert(GetUnwinder());
- reg_ctx_sp = GetUnwinder()->CreateRegisterContextForFrame(frame);
- }
+FreeBSDThread::CreateRegisterContextForFrame(lldb_private::StackFrame *frame) {
+ lldb::RegisterContextSP reg_ctx_sp;
+ uint32_t concrete_frame_idx = 0;
- return reg_ctx_sp;
-}
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+ if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
+ log->Printf("FreeBSDThread::%s ()", __FUNCTION__);
-lldb::addr_t
-FreeBSDThread::GetThreadPointer ()
-{
- ProcessMonitor &monitor = GetMonitor();
- addr_t addr;
- if (monitor.ReadThreadPointer (GetID(), addr))
- return addr;
- else
- return LLDB_INVALID_ADDRESS;
-}
+ if (frame)
+ concrete_frame_idx = frame->GetConcreteFrameIndex();
-bool
-FreeBSDThread::CalculateStopInfo()
-{
- SetStopInfo (m_stop_info_sp);
- return true;
-}
-
-Unwind *
-FreeBSDThread::GetUnwinder()
-{
- if (m_unwinder_ap.get() == NULL)
- m_unwinder_ap.reset(new UnwindLLDB(*this));
+ if (concrete_frame_idx == 0)
+ reg_ctx_sp = GetRegisterContext();
+ else {
+ assert(GetUnwinder());
+ reg_ctx_sp = GetUnwinder()->CreateRegisterContextForFrame(frame);
+ }
- return m_unwinder_ap.get();
+ return reg_ctx_sp;
}
-void
-FreeBSDThread::DidStop()
-{
- // Don't set the thread state to stopped unless we really stopped.
+lldb::addr_t FreeBSDThread::GetThreadPointer() {
+ ProcessMonitor &monitor = GetMonitor();
+ addr_t addr;
+ if (monitor.ReadThreadPointer(GetID(), addr))
+ return addr;
+ else
+ return LLDB_INVALID_ADDRESS;
}
-void
-FreeBSDThread::WillResume(lldb::StateType resume_state)
-{
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
- if (log)
- log->Printf("tid %lu resume_state = %s", GetID(),
- lldb_private::StateAsCString(resume_state));
- ProcessSP process_sp(GetProcess());
- ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(process_sp.get());
- int signo = GetResumeSignal();
- bool signo_valid = process->GetUnixSignals()->SignalIsValid(signo);
-
- switch (resume_state)
- {
- case eStateSuspended:
- case eStateStopped:
- process->m_suspend_tids.push_back(GetID());
- break;
- case eStateRunning:
- process->m_run_tids.push_back(GetID());
- if (signo_valid)
- process->m_resume_signo = signo;
- break;
- case eStateStepping:
- process->m_step_tids.push_back(GetID());
- if (signo_valid)
- process->m_resume_signo = signo;
- break;
- default:
- break;
- }
+bool FreeBSDThread::CalculateStopInfo() {
+ SetStopInfo(m_stop_info_sp);
+ return true;
}
-bool
-FreeBSDThread::Resume()
-{
- lldb::StateType resume_state = GetResumeState();
- ProcessMonitor &monitor = GetMonitor();
- bool status;
+Unwind *FreeBSDThread::GetUnwinder() {
+ if (m_unwinder_ap.get() == NULL)
+ m_unwinder_ap.reset(new UnwindLLDB(*this));
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
- if (log)
- log->Printf ("FreeBSDThread::%s (), resume_state = %s", __FUNCTION__,
- StateAsCString(resume_state));
-
- switch (resume_state)
- {
- default:
- assert(false && "Unexpected state for resume!");
- status = false;
- break;
-
- case lldb::eStateRunning:
- SetState(resume_state);
- status = monitor.Resume(GetID(), GetResumeSignal());
- break;
-
- case lldb::eStateStepping:
- SetState(resume_state);
- status = monitor.SingleStep(GetID(), GetResumeSignal());
- break;
- case lldb::eStateStopped:
- case lldb::eStateSuspended:
- status = true;
- break;
- }
-
- return status;
+ return m_unwinder_ap.get();
}
-void
-FreeBSDThread::Notify(const ProcessMessage &message)
-{
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
- if (log)
- log->Printf ("FreeBSDThread::%s () message kind = '%s' for tid %" PRIu64,
- __FUNCTION__, message.PrintKind(), GetID());
-
- switch (message.GetKind())
- {
- default:
- assert(false && "Unexpected message kind!");
- break;
-
- case ProcessMessage::eExitMessage:
- // Nothing to be done.
- break;
-
- case ProcessMessage::eLimboMessage:
- LimboNotify(message);
- break;
-
- case ProcessMessage::eSignalMessage:
- SignalNotify(message);
- break;
-
- case ProcessMessage::eSignalDeliveredMessage:
- SignalDeliveredNotify(message);
- break;
-
- case ProcessMessage::eTraceMessage:
- TraceNotify(message);
- break;
-
- case ProcessMessage::eBreakpointMessage:
- BreakNotify(message);
- break;
-
- case ProcessMessage::eWatchpointMessage:
- WatchNotify(message);
- break;
+void FreeBSDThread::DidStop() {
+ // Don't set the thread state to stopped unless we really stopped.
+}
- case ProcessMessage::eCrashMessage:
- CrashNotify(message);
- break;
+void FreeBSDThread::WillResume(lldb::StateType resume_state) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+ if (log)
+ log->Printf("tid %lu resume_state = %s", GetID(),
+ lldb_private::StateAsCString(resume_state));
+ ProcessSP process_sp(GetProcess());
+ ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(process_sp.get());
+ int signo = GetResumeSignal();
+ bool signo_valid = process->GetUnixSignals()->SignalIsValid(signo);
+
+ switch (resume_state) {
+ case eStateSuspended:
+ case eStateStopped:
+ process->m_suspend_tids.push_back(GetID());
+ break;
+ case eStateRunning:
+ process->m_run_tids.push_back(GetID());
+ if (signo_valid)
+ process->m_resume_signo = signo;
+ break;
+ case eStateStepping:
+ process->m_step_tids.push_back(GetID());
+ if (signo_valid)
+ process->m_resume_signo = signo;
+ break;
+ default:
+ break;
+ }
+}
- case ProcessMessage::eExecMessage:
- ExecNotify(message);
- break;
- }
+bool FreeBSDThread::Resume() {
+ lldb::StateType resume_state = GetResumeState();
+ ProcessMonitor &monitor = GetMonitor();
+ bool status;
+
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+ if (log)
+ log->Printf("FreeBSDThread::%s (), resume_state = %s", __FUNCTION__,
+ StateAsCString(resume_state));
+
+ switch (resume_state) {
+ default:
+ assert(false && "Unexpected state for resume!");
+ status = false;
+ break;
+
+ case lldb::eStateRunning:
+ SetState(resume_state);
+ status = monitor.Resume(GetID(), GetResumeSignal());
+ break;
+
+ case lldb::eStateStepping:
+ SetState(resume_state);
+ status = monitor.SingleStep(GetID(), GetResumeSignal());
+ break;
+ case lldb::eStateStopped:
+ case lldb::eStateSuspended:
+ status = true;
+ break;
+ }
+
+ return status;
}
-bool
-FreeBSDThread::EnableHardwareWatchpoint(Watchpoint *wp)
-{
- bool wp_set = false;
- if (wp)
- {
- addr_t wp_addr = wp->GetLoadAddress();
- size_t wp_size = wp->GetByteSize();
- bool wp_read = wp->WatchpointRead();
- bool wp_write = wp->WatchpointWrite();
- uint32_t wp_hw_index = wp->GetHardwareIndex();
- POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol();
- if (reg_ctx)
- wp_set = reg_ctx->SetHardwareWatchpointWithIndex(wp_addr, wp_size,
- wp_read, wp_write,
- wp_hw_index);
- }
- return wp_set;
+void FreeBSDThread::Notify(const ProcessMessage &message) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+ if (log)
+ log->Printf("FreeBSDThread::%s () message kind = '%s' for tid %" PRIu64,
+ __FUNCTION__, message.PrintKind(), GetID());
+
+ switch (message.GetKind()) {
+ default:
+ assert(false && "Unexpected message kind!");
+ break;
+
+ case ProcessMessage::eExitMessage:
+ // Nothing to be done.
+ break;
+
+ case ProcessMessage::eLimboMessage:
+ LimboNotify(message);
+ break;
+
+ case ProcessMessage::eSignalMessage:
+ SignalNotify(message);
+ break;
+
+ case ProcessMessage::eSignalDeliveredMessage:
+ SignalDeliveredNotify(message);
+ break;
+
+ case ProcessMessage::eTraceMessage:
+ TraceNotify(message);
+ break;
+
+ case ProcessMessage::eBreakpointMessage:
+ BreakNotify(message);
+ break;
+
+ case ProcessMessage::eWatchpointMessage:
+ WatchNotify(message);
+ break;
+
+ case ProcessMessage::eCrashMessage:
+ CrashNotify(message);
+ break;
+
+ case ProcessMessage::eExecMessage:
+ ExecNotify(message);
+ break;
+ }
}
-bool
-FreeBSDThread::DisableHardwareWatchpoint(Watchpoint *wp)
-{
- bool result = false;
- if (wp)
- {
- lldb::RegisterContextSP reg_ctx_sp = GetRegisterContext();
- if (reg_ctx_sp.get())
- result = reg_ctx_sp->ClearHardwareWatchpoint(wp->GetHardwareIndex());
- }
- return result;
+bool FreeBSDThread::EnableHardwareWatchpoint(Watchpoint *wp) {
+ bool wp_set = false;
+ if (wp) {
+ addr_t wp_addr = wp->GetLoadAddress();
+ size_t wp_size = wp->GetByteSize();
+ bool wp_read = wp->WatchpointRead();
+ bool wp_write = wp->WatchpointWrite();
+ uint32_t wp_hw_index = wp->GetHardwareIndex();
+ POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
+ if (reg_ctx)
+ wp_set = reg_ctx->SetHardwareWatchpointWithIndex(
+ wp_addr, wp_size, wp_read, wp_write, wp_hw_index);
+ }
+ return wp_set;
}
-uint32_t
-FreeBSDThread::NumSupportedHardwareWatchpoints()
-{
+bool FreeBSDThread::DisableHardwareWatchpoint(Watchpoint *wp) {
+ bool result = false;
+ if (wp) {
lldb::RegisterContextSP reg_ctx_sp = GetRegisterContext();
if (reg_ctx_sp.get())
- return reg_ctx_sp->NumSupportedHardwareWatchpoints();
- return 0;
+ result = reg_ctx_sp->ClearHardwareWatchpoint(wp->GetHardwareIndex());
+ }
+ return result;
}
-uint32_t
-FreeBSDThread::FindVacantWatchpointIndex()
-{
- uint32_t hw_index = LLDB_INVALID_INDEX32;
- uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
- uint32_t wp_idx;
- POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol();
- if (reg_ctx)
- {
- for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++)
- {
- if (reg_ctx->IsWatchpointVacant(wp_idx))
- {
- hw_index = wp_idx;
- break;
- }
- }
+uint32_t FreeBSDThread::NumSupportedHardwareWatchpoints() {
+ lldb::RegisterContextSP reg_ctx_sp = GetRegisterContext();
+ if (reg_ctx_sp.get())
+ return reg_ctx_sp->NumSupportedHardwareWatchpoints();
+ return 0;
+}
+
+uint32_t FreeBSDThread::FindVacantWatchpointIndex() {
+ uint32_t hw_index = LLDB_INVALID_INDEX32;
+ uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
+ uint32_t wp_idx;
+ POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
+ if (reg_ctx) {
+ for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) {
+ if (reg_ctx->IsWatchpointVacant(wp_idx)) {
+ hw_index = wp_idx;
+ break;
+ }
}
- return hw_index;
+ }
+ return hw_index;
}
-void
-FreeBSDThread::BreakNotify(const ProcessMessage &message)
-{
- bool status;
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
-
- assert(GetRegisterContext());
- status = GetPOSIXBreakpointProtocol()->UpdateAfterBreakpoint();
- assert(status && "Breakpoint update failed!");
-
- // With our register state restored, resolve the breakpoint object
- // corresponding to our current PC.
- assert(GetRegisterContext());
- lldb::addr_t pc = GetRegisterContext()->GetPC();
- if (log)
- log->Printf ("FreeBSDThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc);
- lldb::BreakpointSiteSP bp_site(GetProcess()->GetBreakpointSiteList().FindByAddress(pc));
-
- // If the breakpoint is for this thread, then we'll report the hit, but if it is for another thread,
- // we create a stop reason with should_stop=false. If there is no breakpoint location, then report
- // an invalid stop reason. We don't need to worry about stepping over the breakpoint here, that will
- // be taken care of when the thread resumes and notices that there's a breakpoint under the pc.
- if (bp_site)
- {
- lldb::break_id_t bp_id = bp_site->GetID();
- // If we have an operating system plug-in, we might have set a thread specific breakpoint using the
- // operating system thread ID, so we can't make any assumptions about the thread ID so we must always
- // report the breakpoint regardless of the thread.
- if (bp_site->ValidForThisThread(this) || GetProcess()->GetOperatingSystem () != NULL)
- SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id));
- else
- {
- const bool should_stop = false;
- SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id, should_stop));
- }
+void FreeBSDThread::BreakNotify(const ProcessMessage &message) {
+ bool status;
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+
+ assert(GetRegisterContext());
+ status = GetPOSIXBreakpointProtocol()->UpdateAfterBreakpoint();
+ assert(status && "Breakpoint update failed!");
+
+ // With our register state restored, resolve the breakpoint object
+ // corresponding to our current PC.
+ assert(GetRegisterContext());
+ lldb::addr_t pc = GetRegisterContext()->GetPC();
+ if (log)
+ log->Printf("FreeBSDThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc);
+ lldb::BreakpointSiteSP bp_site(
+ GetProcess()->GetBreakpointSiteList().FindByAddress(pc));
+
+ // If the breakpoint is for this thread, then we'll report the hit, but if it
+ // is for another thread,
+ // we create a stop reason with should_stop=false. If there is no breakpoint
+ // location, then report
+ // an invalid stop reason. We don't need to worry about stepping over the
+ // breakpoint here, that will
+ // be taken care of when the thread resumes and notices that there's a
+ // breakpoint under the pc.
+ if (bp_site) {
+ lldb::break_id_t bp_id = bp_site->GetID();
+ // If we have an operating system plug-in, we might have set a thread
+ // specific breakpoint using the
+ // operating system thread ID, so we can't make any assumptions about the
+ // thread ID so we must always
+ // report the breakpoint regardless of the thread.
+ if (bp_site->ValidForThisThread(this) ||
+ GetProcess()->GetOperatingSystem() != NULL)
+ SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id));
+ else {
+ const bool should_stop = false;
+ SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id,
+ should_stop));
}
- else
- SetStopInfo(StopInfoSP());
+ } else
+ SetStopInfo(StopInfoSP());
}
-void
-FreeBSDThread::WatchNotify(const ProcessMessage &message)
-{
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
+void FreeBSDThread::WatchNotify(const ProcessMessage &message) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
- lldb::addr_t halt_addr = message.GetHWAddress();
- if (log)
- log->Printf ("FreeBSDThread::%s () Hardware Watchpoint Address = 0x%8.8"
- PRIx64, __FUNCTION__, halt_addr);
+ lldb::addr_t halt_addr = message.GetHWAddress();
+ if (log)
+ log->Printf(
+ "FreeBSDThread::%s () Hardware Watchpoint Address = 0x%8.8" PRIx64,
+ __FUNCTION__, halt_addr);
- POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol();
- if (reg_ctx)
- {
- uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints();
- uint32_t wp_idx;
- for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++)
- {
- if (reg_ctx->IsWatchpointHit(wp_idx))
- {
- // Clear the watchpoint hit here
- reg_ctx->ClearWatchpointHits();
- break;
- }
- }
+ POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
+ if (reg_ctx) {
+ uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints();
+ uint32_t wp_idx;
+ for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) {
+ if (reg_ctx->IsWatchpointHit(wp_idx)) {
+ // Clear the watchpoint hit here
+ reg_ctx->ClearWatchpointHits();
+ break;
+ }
+ }
- if (wp_idx == num_hw_wps)
- return;
+ if (wp_idx == num_hw_wps)
+ return;
- Target &target = GetProcess()->GetTarget();
- lldb::addr_t wp_monitor_addr = reg_ctx->GetWatchpointAddress(wp_idx);
- const WatchpointList &wp_list = target.GetWatchpointList();
- lldb::WatchpointSP wp_sp = wp_list.FindByAddress(wp_monitor_addr);
+ Target &target = GetProcess()->GetTarget();
+ lldb::addr_t wp_monitor_addr = reg_ctx->GetWatchpointAddress(wp_idx);
+ const WatchpointList &wp_list = target.GetWatchpointList();
+ lldb::WatchpointSP wp_sp = wp_list.FindByAddress(wp_monitor_addr);
- assert(wp_sp.get() && "No watchpoint found");
- SetStopInfo (StopInfo::CreateStopReasonWithWatchpointID(*this,
- wp_sp->GetID()));
- }
+ assert(wp_sp.get() && "No watchpoint found");
+ SetStopInfo(
+ StopInfo::CreateStopReasonWithWatchpointID(*this, wp_sp->GetID()));
+ }
}
-void
-FreeBSDThread::TraceNotify(const ProcessMessage &message)
-{
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
-
- // Try to resolve the breakpoint object corresponding to the current PC.
- assert(GetRegisterContext());
- lldb::addr_t pc = GetRegisterContext()->GetPC();
- if (log)
- log->Printf ("FreeBSDThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc);
- lldb::BreakpointSiteSP bp_site(GetProcess()->GetBreakpointSiteList().FindByAddress(pc));
-
- // If the current pc is a breakpoint site then set the StopInfo to Breakpoint.
- // Otherwise, set the StopInfo to Watchpoint or Trace.
- // If we have an operating system plug-in, we might have set a thread specific breakpoint using the
- // operating system thread ID, so we can't make any assumptions about the thread ID so we must always
- // report the breakpoint regardless of the thread.
- if (bp_site && (bp_site->ValidForThisThread(this) || GetProcess()->GetOperatingSystem () != NULL))
- SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_site->GetID()));
- else
- {
- POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol();
- if (reg_ctx)
- {
- uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints();
- uint32_t wp_idx;
- for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++)
- {
- if (reg_ctx->IsWatchpointHit(wp_idx))
- {
- WatchNotify(message);
- return;
- }
- }
+void FreeBSDThread::TraceNotify(const ProcessMessage &message) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+
+ // Try to resolve the breakpoint object corresponding to the current PC.
+ assert(GetRegisterContext());
+ lldb::addr_t pc = GetRegisterContext()->GetPC();
+ if (log)
+ log->Printf("FreeBSDThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc);
+ lldb::BreakpointSiteSP bp_site(
+ GetProcess()->GetBreakpointSiteList().FindByAddress(pc));
+
+ // If the current pc is a breakpoint site then set the StopInfo to Breakpoint.
+ // Otherwise, set the StopInfo to Watchpoint or Trace.
+ // If we have an operating system plug-in, we might have set a thread specific
+ // breakpoint using the
+ // operating system thread ID, so we can't make any assumptions about the
+ // thread ID so we must always
+ // report the breakpoint regardless of the thread.
+ if (bp_site && (bp_site->ValidForThisThread(this) ||
+ GetProcess()->GetOperatingSystem() != NULL))
+ SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID(
+ *this, bp_site->GetID()));
+ else {
+ POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
+ if (reg_ctx) {
+ uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints();
+ uint32_t wp_idx;
+ for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) {
+ if (reg_ctx->IsWatchpointHit(wp_idx)) {
+ WatchNotify(message);
+ return;
}
- SetStopInfo (StopInfo::CreateStopReasonToTrace(*this));
+ }
}
+ SetStopInfo(StopInfo::CreateStopReasonToTrace(*this));
+ }
}
-void
-FreeBSDThread::LimboNotify(const ProcessMessage &message)
-{
- SetStopInfo (lldb::StopInfoSP(new POSIXLimboStopInfo(*this)));
+void FreeBSDThread::LimboNotify(const ProcessMessage &message) {
+ SetStopInfo(lldb::StopInfoSP(new POSIXLimboStopInfo(*this)));
}
-void
-FreeBSDThread::SignalNotify(const ProcessMessage &message)
-{
- int signo = message.GetSignal();
- SetStopInfo (StopInfo::CreateStopReasonWithSignal(*this, signo));
+void FreeBSDThread::SignalNotify(const ProcessMessage &message) {
+ int signo = message.GetSignal();
+ SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, signo));
}
-void
-FreeBSDThread::SignalDeliveredNotify(const ProcessMessage &message)
-{
- int signo = message.GetSignal();
- SetStopInfo (StopInfo::CreateStopReasonWithSignal(*this, signo));
+void FreeBSDThread::SignalDeliveredNotify(const ProcessMessage &message) {
+ int signo = message.GetSignal();
+ SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, signo));
}
-void
-FreeBSDThread::CrashNotify(const ProcessMessage &message)
-{
- // FIXME: Update stop reason as per bugzilla 14598
- int signo = message.GetSignal();
+void FreeBSDThread::CrashNotify(const ProcessMessage &message) {
+ // FIXME: Update stop reason as per bugzilla 14598
+ int signo = message.GetSignal();
- assert(message.GetKind() == ProcessMessage::eCrashMessage);
+ assert(message.GetKind() == ProcessMessage::eCrashMessage);
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
- if (log)
- log->Printf ("FreeBSDThread::%s () signo = %i, reason = '%s'",
- __FUNCTION__, signo, message.PrintCrashReason());
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+ if (log)
+ log->Printf("FreeBSDThread::%s () signo = %i, reason = '%s'", __FUNCTION__,
+ signo, message.PrintCrashReason());
- SetStopInfo (lldb::StopInfoSP(new POSIXCrashStopInfo(*this, signo,
- message.GetCrashReason(),
- message.GetFaultAddress())));
+ SetStopInfo(lldb::StopInfoSP(new POSIXCrashStopInfo(
+ *this, signo, message.GetCrashReason(), message.GetFaultAddress())));
}
-unsigned
-FreeBSDThread::GetRegisterIndexFromOffset(unsigned offset)
-{
- unsigned reg = LLDB_INVALID_REGNUM;
- ArchSpec arch = HostInfo::GetArchitecture();
-
- switch (arch.GetMachine())
- {
- default:
- llvm_unreachable("CPU type not supported!");
- break;
-
- case llvm::Triple::aarch64:
- case llvm::Triple::arm:
- case llvm::Triple::mips64:
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- {
- POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol();
- reg = reg_ctx->GetRegisterIndexFromOffset(offset);
- }
- break;
- }
- return reg;
+unsigned FreeBSDThread::GetRegisterIndexFromOffset(unsigned offset) {
+ unsigned reg = LLDB_INVALID_REGNUM;
+ ArchSpec arch = HostInfo::GetArchitecture();
+
+ switch (arch.GetMachine()) {
+ default:
+ llvm_unreachable("CPU type not supported!");
+ break;
+
+ case llvm::Triple::aarch64:
+ case llvm::Triple::arm:
+ case llvm::Triple::mips64:
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64: {
+ POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
+ reg = reg_ctx->GetRegisterIndexFromOffset(offset);
+ } break;
+ }
+ return reg;
}
-void
-FreeBSDThread::ExecNotify(const ProcessMessage &message)
-{
- SetStopInfo (StopInfo::CreateStopReasonWithExec(*this));
+void FreeBSDThread::ExecNotify(const ProcessMessage &message) {
+ SetStopInfo(StopInfo::CreateStopReasonWithExec(*this));
}
-const char *
-FreeBSDThread::GetRegisterName(unsigned reg)
-{
- const char * name = nullptr;
- ArchSpec arch = HostInfo::GetArchitecture();
-
- switch (arch.GetMachine())
- {
- default:
- assert(false && "CPU type not supported!");
- break;
-
- case llvm::Triple::aarch64:
- case llvm::Triple::arm:
- case llvm::Triple::mips64:
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- name = GetRegisterContext()->GetRegisterName(reg);
- break;
- }
- return name;
+const char *FreeBSDThread::GetRegisterName(unsigned reg) {
+ const char *name = nullptr;
+ ArchSpec arch = HostInfo::GetArchitecture();
+
+ switch (arch.GetMachine()) {
+ default:
+ assert(false && "CPU type not supported!");
+ break;
+
+ case llvm::Triple::aarch64:
+ case llvm::Triple::arm:
+ case llvm::Triple::mips64:
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ name = GetRegisterContext()->GetRegisterName(reg);
+ break;
+ }
+ return name;
}
-const char *
-FreeBSDThread::GetRegisterNameFromOffset(unsigned offset)
-{
- return GetRegisterName(GetRegisterIndexFromOffset(offset));
+const char *FreeBSDThread::GetRegisterNameFromOffset(unsigned offset) {
+ return GetRegisterName(GetRegisterIndexFromOffset(offset));
}
-
diff --git a/source/Plugins/Process/FreeBSD/FreeBSDThread.h b/source/Plugins/Process/FreeBSD/FreeBSDThread.h
index 90c11dbefcb0..72e846459552 100644
--- a/source/Plugins/Process/FreeBSD/FreeBSDThread.h
+++ b/source/Plugins/Process/FreeBSD/FreeBSDThread.h
@@ -15,8 +15,8 @@
#include <string>
// Other libraries and framework includes
-#include "lldb/Target/Thread.h"
#include "RegisterContextPOSIX.h"
+#include "lldb/Target/Thread.h"
class ProcessMessage;
class ProcessMonitor;
@@ -25,118 +25,99 @@ class POSIXBreakpointProtocol;
//------------------------------------------------------------------------------
// @class FreeBSDThread
// @brief Abstraction of a FreeBSD thread.
-class FreeBSDThread
- : public lldb_private::Thread
-{
+class FreeBSDThread : public lldb_private::Thread {
public:
+ //------------------------------------------------------------------
+ // Constructors and destructors
+ //------------------------------------------------------------------
+ FreeBSDThread(lldb_private::Process &process, lldb::tid_t tid);
- //------------------------------------------------------------------
- // Constructors and destructors
- //------------------------------------------------------------------
- FreeBSDThread(lldb_private::Process &process, lldb::tid_t tid);
-
- virtual ~FreeBSDThread();
+ virtual ~FreeBSDThread();
- // POSIXThread
- void
- RefreshStateAfterStop() override;
+ // POSIXThread
+ void RefreshStateAfterStop() override;
- // This notifies the thread when a private stop occurs.
- void
- DidStop () override;
+ // This notifies the thread when a private stop occurs.
+ void DidStop() override;
- const char *
- GetInfo() override;
+ const char *GetInfo() override;
- void
- SetName (const char *name) override;
+ void SetName(const char *name) override;
- const char *
- GetName () override;
+ const char *GetName() override;
- lldb::RegisterContextSP
- GetRegisterContext() override;
+ lldb::RegisterContextSP GetRegisterContext() override;
- lldb::RegisterContextSP
- CreateRegisterContextForFrame (lldb_private::StackFrame *frame) override;
+ lldb::RegisterContextSP
+ CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
- lldb::addr_t
- GetThreadPointer () override;
+ lldb::addr_t GetThreadPointer() override;
- //--------------------------------------------------------------------------
- // These functions provide a mapping from the register offset
- // back to the register index or name for use in debugging or log
- // output.
+ //--------------------------------------------------------------------------
+ // These functions provide a mapping from the register offset
+ // back to the register index or name for use in debugging or log
+ // output.
- unsigned
- GetRegisterIndexFromOffset(unsigned offset);
+ unsigned GetRegisterIndexFromOffset(unsigned offset);
- const char *
- GetRegisterName(unsigned reg);
+ const char *GetRegisterName(unsigned reg);
- const char *
- GetRegisterNameFromOffset(unsigned offset);
+ const char *GetRegisterNameFromOffset(unsigned offset);
- //--------------------------------------------------------------------------
- // These methods form a specialized interface to POSIX threads.
- //
- bool Resume();
+ //--------------------------------------------------------------------------
+ // These methods form a specialized interface to POSIX threads.
+ //
+ bool Resume();
- void Notify(const ProcessMessage &message);
+ void Notify(const ProcessMessage &message);
- //--------------------------------------------------------------------------
- // These methods provide an interface to watchpoints
- //
- bool EnableHardwareWatchpoint(lldb_private::Watchpoint *wp);
+ //--------------------------------------------------------------------------
+ // These methods provide an interface to watchpoints
+ //
+ bool EnableHardwareWatchpoint(lldb_private::Watchpoint *wp);
- bool DisableHardwareWatchpoint(lldb_private::Watchpoint *wp);
+ bool DisableHardwareWatchpoint(lldb_private::Watchpoint *wp);
- uint32_t NumSupportedHardwareWatchpoints();
+ uint32_t NumSupportedHardwareWatchpoints();
- uint32_t FindVacantWatchpointIndex();
+ uint32_t FindVacantWatchpointIndex();
protected:
- POSIXBreakpointProtocol *
- GetPOSIXBreakpointProtocol ()
- {
- if (!m_reg_context_sp)
- m_reg_context_sp = GetRegisterContext();
- return m_posix_thread;
- }
-
- std::unique_ptr<lldb_private::StackFrame> m_frame_ap;
-
- lldb::BreakpointSiteSP m_breakpoint;
-
- bool m_thread_name_valid;
- std::string m_thread_name;
- POSIXBreakpointProtocol *m_posix_thread;
-
- ProcessMonitor &
- GetMonitor();
-
- bool
- CalculateStopInfo() override;
-
- void BreakNotify(const ProcessMessage &message);
- void WatchNotify(const ProcessMessage &message);
- virtual void TraceNotify(const ProcessMessage &message);
- void LimboNotify(const ProcessMessage &message);
- void SignalNotify(const ProcessMessage &message);
- void SignalDeliveredNotify(const ProcessMessage &message);
- void CrashNotify(const ProcessMessage &message);
- void ExitNotify(const ProcessMessage &message);
- void ExecNotify(const ProcessMessage &message);
-
- lldb_private::Unwind *
- GetUnwinder() override;
-
- //--------------------------------------------------------------------------
- // FreeBSDThread internal API.
-
- // POSIXThread override
- virtual void
- WillResume(lldb::StateType resume_state) override;
+ POSIXBreakpointProtocol *GetPOSIXBreakpointProtocol() {
+ if (!m_reg_context_sp)
+ m_reg_context_sp = GetRegisterContext();
+ return m_posix_thread;
+ }
+
+ std::unique_ptr<lldb_private::StackFrame> m_frame_ap;
+
+ lldb::BreakpointSiteSP m_breakpoint;
+
+ bool m_thread_name_valid;
+ std::string m_thread_name;
+ POSIXBreakpointProtocol *m_posix_thread;
+
+ ProcessMonitor &GetMonitor();
+
+ bool CalculateStopInfo() override;
+
+ void BreakNotify(const ProcessMessage &message);
+ void WatchNotify(const ProcessMessage &message);
+ virtual void TraceNotify(const ProcessMessage &message);
+ void LimboNotify(const ProcessMessage &message);
+ void SignalNotify(const ProcessMessage &message);
+ void SignalDeliveredNotify(const ProcessMessage &message);
+ void CrashNotify(const ProcessMessage &message);
+ void ExitNotify(const ProcessMessage &message);
+ void ExecNotify(const ProcessMessage &message);
+
+ lldb_private::Unwind *GetUnwinder() override;
+
+ //--------------------------------------------------------------------------
+ // FreeBSDThread internal API.
+
+ // POSIXThread override
+ virtual void WillResume(lldb::StateType resume_state) override;
};
#endif // #ifndef liblldb_FreeBSDThread_H_
diff --git a/source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp b/source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp
index 409cf8c46b03..dfbd695899ff 100644
--- a/source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp
+++ b/source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp
@@ -12,81 +12,50 @@
using namespace lldb;
using namespace lldb_private;
-
//===----------------------------------------------------------------------===//
// POSIXLimboStopInfo
-POSIXLimboStopInfo::~POSIXLimboStopInfo() { }
+POSIXLimboStopInfo::~POSIXLimboStopInfo() {}
-lldb::StopReason
-POSIXLimboStopInfo::GetStopReason() const
-{
- return lldb::eStopReasonThreadExiting;
+lldb::StopReason POSIXLimboStopInfo::GetStopReason() const {
+ return lldb::eStopReasonThreadExiting;
}
-const char *
-POSIXLimboStopInfo::GetDescription()
-{
- return "thread exiting";
-}
+const char *POSIXLimboStopInfo::GetDescription() { return "thread exiting"; }
-bool
-POSIXLimboStopInfo::ShouldStop(Event *event_ptr)
-{
- return false;
-}
+bool POSIXLimboStopInfo::ShouldStop(Event *event_ptr) { return false; }
-bool
-POSIXLimboStopInfo::ShouldNotify(Event *event_ptr)
-{
- return false;
-}
+bool POSIXLimboStopInfo::ShouldNotify(Event *event_ptr) { return false; }
//===----------------------------------------------------------------------===//
// POSIXCrashStopInfo
-POSIXCrashStopInfo::POSIXCrashStopInfo(FreeBSDThread &thread,
- uint32_t status,
+POSIXCrashStopInfo::POSIXCrashStopInfo(FreeBSDThread &thread, uint32_t status,
CrashReason reason,
lldb::addr_t fault_addr)
- : POSIXStopInfo(thread, status)
-{
- m_description = ::GetCrashReasonString(reason, fault_addr);
+ : POSIXStopInfo(thread, status) {
+ m_description = ::GetCrashReasonString(reason, fault_addr);
}
-POSIXCrashStopInfo::~POSIXCrashStopInfo() { }
+POSIXCrashStopInfo::~POSIXCrashStopInfo() {}
-lldb::StopReason
-POSIXCrashStopInfo::GetStopReason() const
-{
- return lldb::eStopReasonException;
+lldb::StopReason POSIXCrashStopInfo::GetStopReason() const {
+ return lldb::eStopReasonException;
}
//===----------------------------------------------------------------------===//
// POSIXNewThreadStopInfo
-POSIXNewThreadStopInfo::~POSIXNewThreadStopInfo() { }
+POSIXNewThreadStopInfo::~POSIXNewThreadStopInfo() {}
-lldb::StopReason
-POSIXNewThreadStopInfo::GetStopReason() const
-{
- return lldb::eStopReasonNone;
+lldb::StopReason POSIXNewThreadStopInfo::GetStopReason() const {
+ return lldb::eStopReasonNone;
}
-const char *
-POSIXNewThreadStopInfo::GetDescription()
-{
- return "thread spawned";
+const char *POSIXNewThreadStopInfo::GetDescription() {
+ return "thread spawned";
}
-bool
-POSIXNewThreadStopInfo::ShouldStop(Event *event_ptr)
-{
- return false;
-}
+bool POSIXNewThreadStopInfo::ShouldStop(Event *event_ptr) { return false; }
-bool
-POSIXNewThreadStopInfo::ShouldNotify(Event *event_ptr)
-{
- return false;
-}
+bool POSIXNewThreadStopInfo::ShouldNotify(Event *event_ptr) { return false; }
diff --git a/source/Plugins/Process/FreeBSD/POSIXStopInfo.h b/source/Plugins/Process/FreeBSD/POSIXStopInfo.h
index ace6c98017b7..1ee16dd5f8f4 100644
--- a/source/Plugins/Process/FreeBSD/POSIXStopInfo.h
+++ b/source/Plugins/Process/FreeBSD/POSIXStopInfo.h
@@ -25,58 +25,42 @@
/// @class POSIXStopInfo
/// @brief Simple base class for all POSIX-specific StopInfo objects.
///
-class POSIXStopInfo
- : public lldb_private::StopInfo
-{
+class POSIXStopInfo : public lldb_private::StopInfo {
public:
- POSIXStopInfo(lldb_private::Thread &thread, uint32_t status)
- : StopInfo(thread, status)
- { }
+ POSIXStopInfo(lldb_private::Thread &thread, uint32_t status)
+ : StopInfo(thread, status) {}
};
//===----------------------------------------------------------------------===//
/// @class POSIXLimboStopInfo
/// @brief Represents the stop state of a process ready to exit.
///
-class POSIXLimboStopInfo
- : public POSIXStopInfo
-{
+class POSIXLimboStopInfo : public POSIXStopInfo {
public:
- POSIXLimboStopInfo(FreeBSDThread &thread)
- : POSIXStopInfo(thread, 0)
- { }
+ POSIXLimboStopInfo(FreeBSDThread &thread) : POSIXStopInfo(thread, 0) {}
- ~POSIXLimboStopInfo();
+ ~POSIXLimboStopInfo();
- lldb::StopReason
- GetStopReason() const;
+ lldb::StopReason GetStopReason() const;
- const char *
- GetDescription();
+ const char *GetDescription();
- bool
- ShouldStop(lldb_private::Event *event_ptr);
+ bool ShouldStop(lldb_private::Event *event_ptr);
- bool
- ShouldNotify(lldb_private::Event *event_ptr);
+ bool ShouldNotify(lldb_private::Event *event_ptr);
};
-
//===----------------------------------------------------------------------===//
/// @class POSIXCrashStopInfo
/// @brief Represents the stop state of process that is ready to crash.
///
-class POSIXCrashStopInfo
- : public POSIXStopInfo
-{
+class POSIXCrashStopInfo : public POSIXStopInfo {
public:
- POSIXCrashStopInfo(FreeBSDThread &thread, uint32_t status,
- CrashReason reason,
- lldb::addr_t fault_addr);
- ~POSIXCrashStopInfo();
+ POSIXCrashStopInfo(FreeBSDThread &thread, uint32_t status, CrashReason reason,
+ lldb::addr_t fault_addr);
+ ~POSIXCrashStopInfo();
- lldb::StopReason
- GetStopReason() const;
+ lldb::StopReason GetStopReason() const;
};
//===----------------------------------------------------------------------===//
@@ -84,27 +68,19 @@ public:
/// @brief Represents the stop state of process when a new thread is spawned.
///
-class POSIXNewThreadStopInfo
- : public POSIXStopInfo
-{
+class POSIXNewThreadStopInfo : public POSIXStopInfo {
public:
- POSIXNewThreadStopInfo (FreeBSDThread &thread)
- : POSIXStopInfo (thread, 0)
- { }
+ POSIXNewThreadStopInfo(FreeBSDThread &thread) : POSIXStopInfo(thread, 0) {}
- ~POSIXNewThreadStopInfo();
+ ~POSIXNewThreadStopInfo();
- lldb::StopReason
- GetStopReason() const;
+ lldb::StopReason GetStopReason() const;
- const char *
- GetDescription();
+ const char *GetDescription();
- bool
- ShouldStop(lldb_private::Event *event_ptr);
+ bool ShouldStop(lldb_private::Event *event_ptr);
- bool
- ShouldNotify(lldb_private::Event *event_ptr);
+ bool ShouldNotify(lldb_private::Event *event_ptr);
};
#endif
diff --git a/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp b/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
index 3a72a65da696..82e45a5d5fc1 100644
--- a/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
+++ b/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
@@ -1,4 +1,5 @@
-//===-- ProcessFreeBSD.cpp ----------------------------------------*- C++ -*-===//
+//===-- ProcessFreeBSD.cpp ----------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -21,12 +22,12 @@
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/Target.h"
-#include "ProcessFreeBSD.h"
-#include "ProcessPOSIXLog.h"
-#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
+#include "FreeBSDThread.h"
#include "Plugins/Process/Utility/FreeBSDSignals.h"
+#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
+#include "ProcessFreeBSD.h"
#include "ProcessMonitor.h"
-#include "FreeBSDThread.h"
+#include "ProcessPOSIXLog.h"
// Other libraries and framework includes
#include "lldb/Breakpoint/BreakpointLocation.h"
@@ -44,18 +45,14 @@
#include "lldb/Host/posix/Fcntl.h"
-
using namespace lldb;
using namespace lldb_private;
-namespace
-{
- UnixSignalsSP&
- GetFreeBSDSignals ()
- {
- static UnixSignalsSP s_freebsd_signals_sp (new FreeBSDSignals ());
- return s_freebsd_signals_sp;
- }
+namespace {
+UnixSignalsSP &GetFreeBSDSignals() {
+ static UnixSignalsSP s_freebsd_signals_sp(new FreeBSDSignals());
+ return s_freebsd_signals_sp;
+}
}
//------------------------------------------------------------------------------
@@ -64,869 +61,756 @@ namespace
lldb::ProcessSP
ProcessFreeBSD::CreateInstance(lldb::TargetSP target_sp,
lldb::ListenerSP listener_sp,
- const FileSpec *crash_file_path)
-{
- lldb::ProcessSP process_sp;
- if (crash_file_path == NULL)
- process_sp.reset(new ProcessFreeBSD (target_sp, listener_sp, GetFreeBSDSignals()));
- return process_sp;
+ const FileSpec *crash_file_path) {
+ lldb::ProcessSP process_sp;
+ if (crash_file_path == NULL)
+ process_sp.reset(
+ new ProcessFreeBSD(target_sp, listener_sp, GetFreeBSDSignals()));
+ return process_sp;
}
-void
-ProcessFreeBSD::Initialize()
-{
- static std::once_flag g_once_flag;
-
- std::call_once(g_once_flag, []() {
- PluginManager::RegisterPlugin(GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
- ProcessPOSIXLog::Initialize(GetPluginNameStatic());
- });
+void ProcessFreeBSD::Initialize() {
+ static std::once_flag g_once_flag;
+
+ std::call_once(g_once_flag, []() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
+ ProcessPOSIXLog::Initialize(GetPluginNameStatic());
+ });
}
-lldb_private::ConstString
-ProcessFreeBSD::GetPluginNameStatic()
-{
- static ConstString g_name("freebsd");
- return g_name;
+lldb_private::ConstString ProcessFreeBSD::GetPluginNameStatic() {
+ static ConstString g_name("freebsd");
+ return g_name;
}
-const char *
-ProcessFreeBSD::GetPluginDescriptionStatic()
-{
- return "Process plugin for FreeBSD";
+const char *ProcessFreeBSD::GetPluginDescriptionStatic() {
+ return "Process plugin for FreeBSD";
}
//------------------------------------------------------------------------------
// ProcessInterface protocol.
-lldb_private::ConstString
-ProcessFreeBSD::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString ProcessFreeBSD::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-ProcessFreeBSD::GetPluginVersion()
-{
- return 1;
-}
+uint32_t ProcessFreeBSD::GetPluginVersion() { return 1; }
-void
-ProcessFreeBSD::Terminate()
-{
-}
-
-Error
-ProcessFreeBSD::DoDetach(bool keep_stopped)
-{
- Error error;
- if (keep_stopped)
- {
- error.SetErrorString("Detaching with keep_stopped true is not currently supported on FreeBSD.");
- return error;
- }
-
- error = m_monitor->Detach(GetID());
-
- if (error.Success())
- SetPrivateState(eStateDetached);
+void ProcessFreeBSD::Terminate() {}
+Error ProcessFreeBSD::DoDetach(bool keep_stopped) {
+ Error error;
+ if (keep_stopped) {
+ error.SetErrorString("Detaching with keep_stopped true is not currently "
+ "supported on FreeBSD.");
return error;
-}
-
-Error
-ProcessFreeBSD::DoResume()
-{
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
-
- SetPrivateState(eStateRunning);
-
- std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
- bool do_step = false;
+ }
+
+ error = m_monitor->Detach(GetID());
+
+ if (error.Success())
+ SetPrivateState(eStateDetached);
+
+ return error;
+}
+
+Error ProcessFreeBSD::DoResume() {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+
+ SetPrivateState(eStateRunning);
+
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
+ bool do_step = false;
+
+ for (tid_collection::const_iterator t_pos = m_run_tids.begin(),
+ t_end = m_run_tids.end();
+ t_pos != t_end; ++t_pos) {
+ m_monitor->ThreadSuspend(*t_pos, false);
+ }
+ for (tid_collection::const_iterator t_pos = m_step_tids.begin(),
+ t_end = m_step_tids.end();
+ t_pos != t_end; ++t_pos) {
+ m_monitor->ThreadSuspend(*t_pos, false);
+ do_step = true;
+ }
+ for (tid_collection::const_iterator t_pos = m_suspend_tids.begin(),
+ t_end = m_suspend_tids.end();
+ t_pos != t_end; ++t_pos) {
+ m_monitor->ThreadSuspend(*t_pos, true);
+ // XXX Cannot PT_CONTINUE properly with suspended threads.
+ do_step = true;
+ }
+
+ if (log)
+ log->Printf("process %" PRIu64 " resuming (%s)", GetID(),
+ do_step ? "step" : "continue");
+ if (do_step)
+ m_monitor->SingleStep(GetID(), m_resume_signo);
+ else
+ m_monitor->Resume(GetID(), m_resume_signo);
+
+ return Error();
+}
+
+bool ProcessFreeBSD::UpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ if (log)
+ log->Printf("ProcessFreeBSD::%s (pid = %" PRIu64 ")", __FUNCTION__,
+ GetID());
+
+ std::vector<lldb::pid_t> tds;
+ if (!GetMonitor().GetCurrentThreadIDs(tds)) {
+ return false;
+ }
- for (tid_collection::const_iterator t_pos = m_run_tids.begin(), t_end = m_run_tids.end(); t_pos != t_end; ++t_pos)
- {
- m_monitor->ThreadSuspend(*t_pos, false);
- }
- for (tid_collection::const_iterator t_pos = m_step_tids.begin(), t_end = m_step_tids.end(); t_pos != t_end; ++t_pos)
- {
- m_monitor->ThreadSuspend(*t_pos, false);
- do_step = true;
+ ThreadList old_thread_list_copy(old_thread_list);
+ for (size_t i = 0; i < tds.size(); ++i) {
+ tid_t tid = tds[i];
+ ThreadSP thread_sp(old_thread_list_copy.RemoveThreadByID(tid, false));
+ if (!thread_sp) {
+ thread_sp.reset(new FreeBSDThread(*this, tid));
+ if (log)
+ log->Printf("ProcessFreeBSD::%s new tid = %" PRIu64, __FUNCTION__, tid);
+ } else {
+ if (log)
+ log->Printf("ProcessFreeBSD::%s existing tid = %" PRIu64, __FUNCTION__,
+ tid);
}
- for (tid_collection::const_iterator t_pos = m_suspend_tids.begin(), t_end = m_suspend_tids.end(); t_pos != t_end; ++t_pos)
- {
- m_monitor->ThreadSuspend(*t_pos, true);
- // XXX Cannot PT_CONTINUE properly with suspended threads.
- do_step = true;
+ new_thread_list.AddThread(thread_sp);
+ }
+ for (size_t i = 0; i < old_thread_list_copy.GetSize(false); ++i) {
+ ThreadSP old_thread_sp(old_thread_list_copy.GetThreadAtIndex(i, false));
+ if (old_thread_sp) {
+ if (log)
+ log->Printf("ProcessFreeBSD::%s remove tid", __FUNCTION__);
}
+ }
- if (log)
- log->Printf("process %" PRIu64 " resuming (%s)", GetID(), do_step ? "step" : "continue");
- if (do_step)
- m_monitor->SingleStep(GetID(), m_resume_signo);
- else
- m_monitor->Resume(GetID(), m_resume_signo);
-
- return Error();
+ return true;
}
-bool
-ProcessFreeBSD::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
-{
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
- if (log)
- log->Printf("ProcessFreeBSD::%s (pid = %" PRIu64 ")", __FUNCTION__, GetID());
-
- std::vector<lldb::pid_t> tds;
- if (!GetMonitor().GetCurrentThreadIDs(tds))
- {
- return false;
- }
+Error ProcessFreeBSD::WillResume() {
+ m_resume_signo = 0;
+ m_suspend_tids.clear();
+ m_run_tids.clear();
+ m_step_tids.clear();
+ return Process::WillResume();
+}
- ThreadList old_thread_list_copy(old_thread_list);
- for (size_t i = 0; i < tds.size(); ++i)
- {
- tid_t tid = tds[i];
- ThreadSP thread_sp (old_thread_list_copy.RemoveThreadByID(tid, false));
- if (!thread_sp)
- {
- thread_sp.reset(new FreeBSDThread(*this, tid));
- if (log)
- log->Printf("ProcessFreeBSD::%s new tid = %" PRIu64, __FUNCTION__, tid);
- }
- else
- {
- if (log)
- log->Printf("ProcessFreeBSD::%s existing tid = %" PRIu64, __FUNCTION__, tid);
- }
- new_thread_list.AddThread(thread_sp);
- }
- for (size_t i = 0; i < old_thread_list_copy.GetSize(false); ++i)
- {
- ThreadSP old_thread_sp(old_thread_list_copy.GetThreadAtIndex(i, false));
- if (old_thread_sp)
- {
- if (log)
- log->Printf("ProcessFreeBSD::%s remove tid", __FUNCTION__);
- }
- }
+void ProcessFreeBSD::SendMessage(const ProcessMessage &message) {
+ std::lock_guard<std::recursive_mutex> guard(m_message_mutex);
- return true;
-}
+ switch (message.GetKind()) {
+ case ProcessMessage::eInvalidMessage:
+ return;
-Error
-ProcessFreeBSD::WillResume()
-{
- m_resume_signo = 0;
- m_suspend_tids.clear();
- m_run_tids.clear();
- m_step_tids.clear();
- return Process::WillResume();
-}
+ case ProcessMessage::eAttachMessage:
+ SetPrivateState(eStateStopped);
+ return;
-void
-ProcessFreeBSD::SendMessage(const ProcessMessage &message)
-{
- std::lock_guard<std::recursive_mutex> guard(m_message_mutex);
+ case ProcessMessage::eLimboMessage:
+ case ProcessMessage::eExitMessage:
+ SetExitStatus(message.GetExitStatus(), NULL);
+ break;
- switch (message.GetKind())
- {
- case ProcessMessage::eInvalidMessage:
- return;
+ case ProcessMessage::eSignalMessage:
+ case ProcessMessage::eSignalDeliveredMessage:
+ case ProcessMessage::eBreakpointMessage:
+ case ProcessMessage::eTraceMessage:
+ case ProcessMessage::eWatchpointMessage:
+ case ProcessMessage::eCrashMessage:
+ SetPrivateState(eStateStopped);
+ break;
- case ProcessMessage::eAttachMessage:
- SetPrivateState(eStateStopped);
- return;
+ case ProcessMessage::eNewThreadMessage:
+ llvm_unreachable("eNewThreadMessage unexpected on FreeBSD");
+ break;
- case ProcessMessage::eLimboMessage:
- case ProcessMessage::eExitMessage:
- SetExitStatus(message.GetExitStatus(), NULL);
- break;
-
- case ProcessMessage::eSignalMessage:
- case ProcessMessage::eSignalDeliveredMessage:
- case ProcessMessage::eBreakpointMessage:
- case ProcessMessage::eTraceMessage:
- case ProcessMessage::eWatchpointMessage:
- case ProcessMessage::eCrashMessage:
- SetPrivateState(eStateStopped);
- break;
-
- case ProcessMessage::eNewThreadMessage:
- llvm_unreachable("eNewThreadMessage unexpected on FreeBSD");
- break;
-
- case ProcessMessage::eExecMessage:
- SetPrivateState(eStateStopped);
- break;
- }
+ case ProcessMessage::eExecMessage:
+ SetPrivateState(eStateStopped);
+ break;
+ }
- m_message_queue.push(message);
+ m_message_queue.push(message);
}
//------------------------------------------------------------------------------
// Constructors and destructors.
-ProcessFreeBSD::ProcessFreeBSD(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, UnixSignalsSP &unix_signals_sp)
+ProcessFreeBSD::ProcessFreeBSD(lldb::TargetSP target_sp,
+ lldb::ListenerSP listener_sp,
+ UnixSignalsSP &unix_signals_sp)
: Process(target_sp, listener_sp, unix_signals_sp),
- m_byte_order(endian::InlHostByteOrder()),
- m_monitor(NULL),
- m_module(NULL),
- m_message_mutex(),
- m_exit_now(false),
- m_seen_initial_stop(),
- m_resume_signo(0)
-{
- // FIXME: Putting this code in the ctor and saving the byte order in a
- // member variable is a hack to avoid const qual issues in GetByteOrder.
- lldb::ModuleSP module = GetTarget().GetExecutableModule();
- if (module && module->GetObjectFile())
- m_byte_order = module->GetObjectFile()->GetByteOrder();
+ m_byte_order(endian::InlHostByteOrder()), m_monitor(NULL), m_module(NULL),
+ m_message_mutex(), m_exit_now(false), m_seen_initial_stop(),
+ m_resume_signo(0) {
+ // FIXME: Putting this code in the ctor and saving the byte order in a
+ // member variable is a hack to avoid const qual issues in GetByteOrder.
+ lldb::ModuleSP module = GetTarget().GetExecutableModule();
+ if (module && module->GetObjectFile())
+ m_byte_order = module->GetObjectFile()->GetByteOrder();
}
-ProcessFreeBSD::~ProcessFreeBSD()
-{
- delete m_monitor;
-}
+ProcessFreeBSD::~ProcessFreeBSD() { delete m_monitor; }
//------------------------------------------------------------------------------
// Process protocol.
-void
-ProcessFreeBSD::Finalize()
-{
+void ProcessFreeBSD::Finalize() {
Process::Finalize();
if (m_monitor)
m_monitor->StopMonitor();
}
-bool
-ProcessFreeBSD::CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name)
-{
- // For now we are just making sure the file exists for a given module
- ModuleSP exe_module_sp(target_sp->GetExecutableModule());
- if (exe_module_sp.get())
- return exe_module_sp->GetFileSpec().Exists();
- // If there is no executable module, we return true since we might be preparing to attach.
- return true;
+bool ProcessFreeBSD::CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) {
+ // For now we are just making sure the file exists for a given module
+ ModuleSP exe_module_sp(target_sp->GetExecutableModule());
+ if (exe_module_sp.get())
+ return exe_module_sp->GetFileSpec().Exists();
+ // If there is no executable module, we return true since we might be
+ // preparing to attach.
+ return true;
}
-Error
-ProcessFreeBSD::DoAttachToProcessWithID (lldb::pid_t pid, const ProcessAttachInfo &attach_info)
-{
- Error error;
- assert(m_monitor == NULL);
+Error ProcessFreeBSD::DoAttachToProcessWithID(
+ lldb::pid_t pid, const ProcessAttachInfo &attach_info) {
+ Error error;
+ assert(m_monitor == NULL);
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
- if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
- log->Printf ("ProcessFreeBSD::%s(pid = %" PRIi64 ")", __FUNCTION__, GetID());
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
+ log->Printf("ProcessFreeBSD::%s(pid = %" PRIi64 ")", __FUNCTION__, GetID());
- m_monitor = new ProcessMonitor(this, pid, error);
+ m_monitor = new ProcessMonitor(this, pid, error);
- if (!error.Success())
- return error;
+ if (!error.Success())
+ return error;
- PlatformSP platform_sp (GetTarget().GetPlatform ());
- assert (platform_sp.get());
- if (!platform_sp)
- return error; // FIXME: Detatch?
-
- // Find out what we can about this process
- ProcessInstanceInfo process_info;
- platform_sp->GetProcessInfo (pid, process_info);
-
- // Resolve the executable module
- ModuleSP exe_module_sp;
- FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths());
- ModuleSpec exe_module_spec(process_info.GetExecutableFile(), GetTarget().GetArchitecture());
- error = platform_sp->ResolveExecutable(exe_module_spec,
- exe_module_sp,
- executable_search_paths.GetSize() ? &executable_search_paths : NULL);
- if (!error.Success())
- return error;
+ PlatformSP platform_sp(GetTarget().GetPlatform());
+ assert(platform_sp.get());
+ if (!platform_sp)
+ return error; // FIXME: Detatch?
+
+ // Find out what we can about this process
+ ProcessInstanceInfo process_info;
+ platform_sp->GetProcessInfo(pid, process_info);
+
+ // Resolve the executable module
+ ModuleSP exe_module_sp;
+ FileSpecList executable_search_paths(
+ Target::GetDefaultExecutableSearchPaths());
+ ModuleSpec exe_module_spec(process_info.GetExecutableFile(),
+ GetTarget().GetArchitecture());
+ error = platform_sp->ResolveExecutable(
+ exe_module_spec, exe_module_sp,
+ executable_search_paths.GetSize() ? &executable_search_paths : NULL);
+ if (!error.Success())
+ return error;
- // Fix the target architecture if necessary
- const ArchSpec &module_arch = exe_module_sp->GetArchitecture();
- if (module_arch.IsValid() && !GetTarget().GetArchitecture().IsExactMatch(module_arch))
- GetTarget().SetArchitecture(module_arch);
+ // Fix the target architecture if necessary
+ const ArchSpec &module_arch = exe_module_sp->GetArchitecture();
+ if (module_arch.IsValid() &&
+ !GetTarget().GetArchitecture().IsExactMatch(module_arch))
+ GetTarget().SetArchitecture(module_arch);
- // Initialize the target module list
- GetTarget().SetExecutableModule (exe_module_sp, true);
+ // Initialize the target module list
+ GetTarget().SetExecutableModule(exe_module_sp, true);
- SetSTDIOFileDescriptor(m_monitor->GetTerminalFD());
+ SetSTDIOFileDescriptor(m_monitor->GetTerminalFD());
- SetID(pid);
+ SetID(pid);
- return error;
+ return error;
}
-Error
-ProcessFreeBSD::WillLaunch(Module* module)
-{
- Error error;
- return error;
+Error ProcessFreeBSD::WillLaunch(Module *module) {
+ Error error;
+ return error;
}
FileSpec
ProcessFreeBSD::GetFileSpec(const lldb_private::FileAction *file_action,
- const FileSpec &default_file_spec,
- const FileSpec &dbg_pts_file_spec)
-{
- FileSpec file_spec{};
-
- if (file_action && file_action->GetAction() == FileAction::eFileActionOpen)
- {
- file_spec = file_action->GetFileSpec();
- // By default the stdio paths passed in will be pseudo-terminal
- // (/dev/pts). If so, convert to using a different default path
- // instead to redirect I/O to the debugger console. This should
- // also handle user overrides to /dev/null or a different file.
- if (!file_spec || file_spec == dbg_pts_file_spec)
- file_spec = default_file_spec;
- }
- return file_spec;
-}
-
-Error
-ProcessFreeBSD::DoLaunch (Module *module,
- ProcessLaunchInfo &launch_info)
-{
- Error error;
- assert(m_monitor == NULL);
-
- FileSpec working_dir = launch_info.GetWorkingDirectory();
- if (working_dir &&
- (!working_dir.ResolvePath() ||
- working_dir.GetFileType() != FileSpec::eFileTypeDirectory))
- {
- error.SetErrorStringWithFormat("No such file or directory: %s",
- working_dir.GetCString());
- return error;
- }
+ const FileSpec &default_file_spec,
+ const FileSpec &dbg_pts_file_spec) {
+ FileSpec file_spec{};
+
+ if (file_action && file_action->GetAction() == FileAction::eFileActionOpen) {
+ file_spec = file_action->GetFileSpec();
+ // By default the stdio paths passed in will be pseudo-terminal
+ // (/dev/pts). If so, convert to using a different default path
+ // instead to redirect I/O to the debugger console. This should
+ // also handle user overrides to /dev/null or a different file.
+ if (!file_spec || file_spec == dbg_pts_file_spec)
+ file_spec = default_file_spec;
+ }
+ return file_spec;
+}
+
+Error ProcessFreeBSD::DoLaunch(Module *module, ProcessLaunchInfo &launch_info) {
+ Error error;
+ assert(m_monitor == NULL);
+
+ FileSpec working_dir = launch_info.GetWorkingDirectory();
+ if (working_dir &&
+ (!working_dir.ResolvePath() ||
+ working_dir.GetFileType() != FileSpec::eFileTypeDirectory)) {
+ error.SetErrorStringWithFormat("No such file or directory: %s",
+ working_dir.GetCString());
+ return error;
+ }
- SetPrivateState(eStateLaunching);
+ SetPrivateState(eStateLaunching);
- const lldb_private::FileAction *file_action;
+ const lldb_private::FileAction *file_action;
- // Default of empty will mean to use existing open file descriptors
- FileSpec stdin_file_spec{};
- FileSpec stdout_file_spec{};
- FileSpec stderr_file_spec{};
+ // Default of empty will mean to use existing open file descriptors
+ FileSpec stdin_file_spec{};
+ FileSpec stdout_file_spec{};
+ FileSpec stderr_file_spec{};
- const FileSpec dbg_pts_file_spec{launch_info.GetPTY().GetSlaveName(NULL,0), false};
+ const FileSpec dbg_pts_file_spec{launch_info.GetPTY().GetSlaveName(NULL, 0),
+ false};
- file_action = launch_info.GetFileActionForFD (STDIN_FILENO);
- stdin_file_spec = GetFileSpec(file_action, stdin_file_spec, dbg_pts_file_spec);
+ file_action = launch_info.GetFileActionForFD(STDIN_FILENO);
+ stdin_file_spec =
+ GetFileSpec(file_action, stdin_file_spec, dbg_pts_file_spec);
- file_action = launch_info.GetFileActionForFD (STDOUT_FILENO);
- stdout_file_spec = GetFileSpec(file_action, stdout_file_spec, dbg_pts_file_spec);
+ file_action = launch_info.GetFileActionForFD(STDOUT_FILENO);
+ stdout_file_spec =
+ GetFileSpec(file_action, stdout_file_spec, dbg_pts_file_spec);
- file_action = launch_info.GetFileActionForFD (STDERR_FILENO);
- stderr_file_spec = GetFileSpec(file_action, stderr_file_spec, dbg_pts_file_spec);
+ file_action = launch_info.GetFileActionForFD(STDERR_FILENO);
+ stderr_file_spec =
+ GetFileSpec(file_action, stderr_file_spec, dbg_pts_file_spec);
- m_monitor = new ProcessMonitor(this,
- module,
- launch_info.GetArguments().GetConstArgumentVector(),
- launch_info.GetEnvironmentEntries().GetConstArgumentVector(),
- stdin_file_spec,
- stdout_file_spec,
- stderr_file_spec,
- working_dir,
- launch_info,
- error);
+ m_monitor = new ProcessMonitor(
+ this, module, launch_info.GetArguments().GetConstArgumentVector(),
+ launch_info.GetEnvironmentEntries().GetConstArgumentVector(),
+ stdin_file_spec, stdout_file_spec, stderr_file_spec, working_dir,
+ launch_info, error);
- m_module = module;
+ m_module = module;
- if (!error.Success())
- return error;
+ if (!error.Success())
+ return error;
- int terminal = m_monitor->GetTerminalFD();
- if (terminal >= 0) {
- // The reader thread will close the file descriptor when done, so we pass it a copy.
+ int terminal = m_monitor->GetTerminalFD();
+ if (terminal >= 0) {
+// The reader thread will close the file descriptor when done, so we pass it a
+// copy.
#ifdef F_DUPFD_CLOEXEC
- int stdio = fcntl(terminal, F_DUPFD_CLOEXEC, 0);
- if (stdio == -1) {
- error.SetErrorToErrno();
- return error;
- }
+ int stdio = fcntl(terminal, F_DUPFD_CLOEXEC, 0);
+ if (stdio == -1) {
+ error.SetErrorToErrno();
+ return error;
+ }
#else
- // Special case when F_DUPFD_CLOEXEC does not exist (Debian kFreeBSD)
- int stdio = fcntl(terminal, F_DUPFD, 0);
- if (stdio == -1) {
- error.SetErrorToErrno();
- return error;
- }
- stdio = fcntl(terminal, F_SETFD, FD_CLOEXEC);
- if (stdio == -1) {
- error.SetErrorToErrno();
- return error;
- }
-#endif
- SetSTDIOFileDescriptor(stdio);
+ // Special case when F_DUPFD_CLOEXEC does not exist (Debian kFreeBSD)
+ int stdio = fcntl(terminal, F_DUPFD, 0);
+ if (stdio == -1) {
+ error.SetErrorToErrno();
+ return error;
+ }
+ stdio = fcntl(terminal, F_SETFD, FD_CLOEXEC);
+ if (stdio == -1) {
+ error.SetErrorToErrno();
+ return error;
}
+#endif
+ SetSTDIOFileDescriptor(stdio);
+ }
- SetID(m_monitor->GetPID());
- return error;
+ SetID(m_monitor->GetPID());
+ return error;
}
-void
-ProcessFreeBSD::DidLaunch()
-{
-}
+void ProcessFreeBSD::DidLaunch() {}
-addr_t
-ProcessFreeBSD::GetImageInfoAddress()
-{
- Target *target = &GetTarget();
- ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
- Address addr = obj_file->GetImageInfoAddress(target);
+addr_t ProcessFreeBSD::GetImageInfoAddress() {
+ Target *target = &GetTarget();
+ ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
+ Address addr = obj_file->GetImageInfoAddress(target);
- if (addr.IsValid())
- return addr.GetLoadAddress(target);
- return LLDB_INVALID_ADDRESS;
+ if (addr.IsValid())
+ return addr.GetLoadAddress(target);
+ return LLDB_INVALID_ADDRESS;
}
-Error
-ProcessFreeBSD::DoHalt(bool &caused_stop)
-{
- Error error;
+Error ProcessFreeBSD::DoHalt(bool &caused_stop) {
+ Error error;
- if (IsStopped())
- {
- caused_stop = false;
- }
- else if (kill(GetID(), SIGSTOP))
- {
- caused_stop = false;
- error.SetErrorToErrno();
- }
- else
- {
- caused_stop = true;
- }
- return error;
+ if (IsStopped()) {
+ caused_stop = false;
+ } else if (kill(GetID(), SIGSTOP)) {
+ caused_stop = false;
+ error.SetErrorToErrno();
+ } else {
+ caused_stop = true;
+ }
+ return error;
}
-Error
-ProcessFreeBSD::DoSignal(int signal)
-{
- Error error;
+Error ProcessFreeBSD::DoSignal(int signal) {
+ Error error;
- if (kill(GetID(), signal))
- error.SetErrorToErrno();
+ if (kill(GetID(), signal))
+ error.SetErrorToErrno();
- return error;
+ return error;
}
-Error
-ProcessFreeBSD::DoDestroy()
-{
- Error error;
-
- if (!HasExited())
- {
- assert(m_monitor);
- m_exit_now = true;
- if (GetID() == LLDB_INVALID_PROCESS_ID)
- {
- error.SetErrorString("invalid process id");
- return error;
- }
- if (!m_monitor->Kill())
- {
- error.SetErrorToErrno();
- return error;
- }
-
- SetPrivateState(eStateExited);
- }
+Error ProcessFreeBSD::DoDestroy() {
+ Error error;
- return error;
-}
+ if (!HasExited()) {
+ assert(m_monitor);
+ m_exit_now = true;
+ if (GetID() == LLDB_INVALID_PROCESS_ID) {
+ error.SetErrorString("invalid process id");
+ return error;
+ }
+ if (!m_monitor->Kill()) {
+ error.SetErrorToErrno();
+ return error;
+ }
-void
-ProcessFreeBSD::DoDidExec()
-{
- Target *target = &GetTarget();
- if (target)
- {
- PlatformSP platform_sp (target->GetPlatform());
- assert (platform_sp.get());
- if (platform_sp)
- {
- ProcessInstanceInfo process_info;
- platform_sp->GetProcessInfo(GetID(), process_info);
- ModuleSP exe_module_sp;
- ModuleSpec exe_module_spec(process_info.GetExecutableFile(), target->GetArchitecture());
- FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths());
- Error error = platform_sp->ResolveExecutable(exe_module_spec,
- exe_module_sp,
- executable_search_paths.GetSize() ? &executable_search_paths : NULL);
- if (!error.Success())
- return;
- target->SetExecutableModule(exe_module_sp, true);
- }
+ SetPrivateState(eStateExited);
+ }
+
+ return error;
+}
+
+void ProcessFreeBSD::DoDidExec() {
+ Target *target = &GetTarget();
+ if (target) {
+ PlatformSP platform_sp(target->GetPlatform());
+ assert(platform_sp.get());
+ if (platform_sp) {
+ ProcessInstanceInfo process_info;
+ platform_sp->GetProcessInfo(GetID(), process_info);
+ ModuleSP exe_module_sp;
+ ModuleSpec exe_module_spec(process_info.GetExecutableFile(),
+ target->GetArchitecture());
+ FileSpecList executable_search_paths(
+ Target::GetDefaultExecutableSearchPaths());
+ Error error = platform_sp->ResolveExecutable(
+ exe_module_spec, exe_module_sp,
+ executable_search_paths.GetSize() ? &executable_search_paths : NULL);
+ if (!error.Success())
+ return;
+ target->SetExecutableModule(exe_module_sp, true);
}
+ }
}
-bool
-ProcessFreeBSD::AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid)
-{
- bool added_to_set = false;
- ThreadStopSet::iterator it = m_seen_initial_stop.find(stop_tid);
- if (it == m_seen_initial_stop.end())
- {
- m_seen_initial_stop.insert(stop_tid);
- added_to_set = true;
- }
- return added_to_set;
+bool ProcessFreeBSD::AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid) {
+ bool added_to_set = false;
+ ThreadStopSet::iterator it = m_seen_initial_stop.find(stop_tid);
+ if (it == m_seen_initial_stop.end()) {
+ m_seen_initial_stop.insert(stop_tid);
+ added_to_set = true;
+ }
+ return added_to_set;
}
-bool
-ProcessFreeBSD::WaitingForInitialStop(lldb::tid_t stop_tid)
-{
- return (m_seen_initial_stop.find(stop_tid) == m_seen_initial_stop.end());
+bool ProcessFreeBSD::WaitingForInitialStop(lldb::tid_t stop_tid) {
+ return (m_seen_initial_stop.find(stop_tid) == m_seen_initial_stop.end());
}
FreeBSDThread *
-ProcessFreeBSD::CreateNewFreeBSDThread(lldb_private::Process &process, lldb::tid_t tid)
-{
- return new FreeBSDThread(process, tid);
+ProcessFreeBSD::CreateNewFreeBSDThread(lldb_private::Process &process,
+ lldb::tid_t tid) {
+ return new FreeBSDThread(process, tid);
}
-void
-ProcessFreeBSD::RefreshStateAfterStop()
-{
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
- if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
- log->Printf ("ProcessFreeBSD::%s(), message_queue size = %d", __FUNCTION__, (int)m_message_queue.size());
-
- std::lock_guard<std::recursive_mutex> guard(m_message_mutex);
+void ProcessFreeBSD::RefreshStateAfterStop() {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
+ log->Printf("ProcessFreeBSD::%s(), message_queue size = %d", __FUNCTION__,
+ (int)m_message_queue.size());
- // This method used to only handle one message. Changing it to loop allows
- // it to handle the case where we hit a breakpoint while handling a different
- // breakpoint.
- while (!m_message_queue.empty())
- {
- ProcessMessage &message = m_message_queue.front();
+ std::lock_guard<std::recursive_mutex> guard(m_message_mutex);
- // Resolve the thread this message corresponds to and pass it along.
- lldb::tid_t tid = message.GetTID();
- if (log)
- log->Printf ("ProcessFreeBSD::%s(), message_queue size = %d, pid = %" PRIi64, __FUNCTION__, (int)m_message_queue.size(), tid);
+ // This method used to only handle one message. Changing it to loop allows
+ // it to handle the case where we hit a breakpoint while handling a different
+ // breakpoint.
+ while (!m_message_queue.empty()) {
+ ProcessMessage &message = m_message_queue.front();
- m_thread_list.RefreshStateAfterStop();
+ // Resolve the thread this message corresponds to and pass it along.
+ lldb::tid_t tid = message.GetTID();
+ if (log)
+ log->Printf(
+ "ProcessFreeBSD::%s(), message_queue size = %d, pid = %" PRIi64,
+ __FUNCTION__, (int)m_message_queue.size(), tid);
- FreeBSDThread *thread = static_cast<FreeBSDThread*>(
- GetThreadList().FindThreadByID(tid, false).get());
- if (thread)
- thread->Notify(message);
+ m_thread_list.RefreshStateAfterStop();
- if (message.GetKind() == ProcessMessage::eExitMessage)
- {
- // FIXME: We should tell the user about this, but the limbo message is probably better for that.
- if (log)
- log->Printf ("ProcessFreeBSD::%s() removing thread, tid = %" PRIi64, __FUNCTION__, tid);
+ FreeBSDThread *thread = static_cast<FreeBSDThread *>(
+ GetThreadList().FindThreadByID(tid, false).get());
+ if (thread)
+ thread->Notify(message);
- std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
+ if (message.GetKind() == ProcessMessage::eExitMessage) {
+ // FIXME: We should tell the user about this, but the limbo message is
+ // probably better for that.
+ if (log)
+ log->Printf("ProcessFreeBSD::%s() removing thread, tid = %" PRIi64,
+ __FUNCTION__, tid);
- ThreadSP thread_sp = m_thread_list.RemoveThreadByID(tid, false);
- thread_sp.reset();
- m_seen_initial_stop.erase(tid);
- }
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
- m_message_queue.pop();
+ ThreadSP thread_sp = m_thread_list.RemoveThreadByID(tid, false);
+ thread_sp.reset();
+ m_seen_initial_stop.erase(tid);
}
+
+ m_message_queue.pop();
+ }
}
-bool
-ProcessFreeBSD::IsAlive()
-{
- StateType state = GetPrivateState();
- return state != eStateDetached
- && state != eStateExited
- && state != eStateInvalid
- && state != eStateUnloaded;
+bool ProcessFreeBSD::IsAlive() {
+ StateType state = GetPrivateState();
+ return state != eStateDetached && state != eStateExited &&
+ state != eStateInvalid && state != eStateUnloaded;
}
-size_t
-ProcessFreeBSD::DoReadMemory(addr_t vm_addr,
- void *buf, size_t size, Error &error)
-{
- assert(m_monitor);
- return m_monitor->ReadMemory(vm_addr, buf, size, error);
+size_t ProcessFreeBSD::DoReadMemory(addr_t vm_addr, void *buf, size_t size,
+ Error &error) {
+ assert(m_monitor);
+ return m_monitor->ReadMemory(vm_addr, buf, size, error);
}
-size_t
-ProcessFreeBSD::DoWriteMemory(addr_t vm_addr, const void *buf, size_t size,
- Error &error)
-{
- assert(m_monitor);
- return m_monitor->WriteMemory(vm_addr, buf, size, error);
+size_t ProcessFreeBSD::DoWriteMemory(addr_t vm_addr, const void *buf,
+ size_t size, Error &error) {
+ assert(m_monitor);
+ return m_monitor->WriteMemory(vm_addr, buf, size, error);
}
-addr_t
-ProcessFreeBSD::DoAllocateMemory(size_t size, uint32_t permissions,
- Error &error)
-{
- addr_t allocated_addr = LLDB_INVALID_ADDRESS;
-
- unsigned prot = 0;
- if (permissions & lldb::ePermissionsReadable)
- prot |= eMmapProtRead;
- if (permissions & lldb::ePermissionsWritable)
- prot |= eMmapProtWrite;
- if (permissions & lldb::ePermissionsExecutable)
- prot |= eMmapProtExec;
-
- if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
- eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
- m_addr_to_mmap_size[allocated_addr] = size;
- error.Clear();
- } else {
- allocated_addr = LLDB_INVALID_ADDRESS;
- error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions));
- }
+addr_t ProcessFreeBSD::DoAllocateMemory(size_t size, uint32_t permissions,
+ Error &error) {
+ addr_t allocated_addr = LLDB_INVALID_ADDRESS;
+
+ unsigned prot = 0;
+ if (permissions & lldb::ePermissionsReadable)
+ prot |= eMmapProtRead;
+ if (permissions & lldb::ePermissionsWritable)
+ prot |= eMmapProtWrite;
+ if (permissions & lldb::ePermissionsExecutable)
+ prot |= eMmapProtExec;
- return allocated_addr;
+ if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
+ eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
+ m_addr_to_mmap_size[allocated_addr] = size;
+ error.Clear();
+ } else {
+ allocated_addr = LLDB_INVALID_ADDRESS;
+ error.SetErrorStringWithFormat(
+ "unable to allocate %zu bytes of memory with permissions %s", size,
+ GetPermissionsAsCString(permissions));
+ }
+
+ return allocated_addr;
}
-Error
-ProcessFreeBSD::DoDeallocateMemory(lldb::addr_t addr)
-{
- Error error;
- MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
- if (pos != m_addr_to_mmap_size.end() &&
- InferiorCallMunmap(this, addr, pos->second))
- m_addr_to_mmap_size.erase (pos);
- else
- error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64, addr);
+Error ProcessFreeBSD::DoDeallocateMemory(lldb::addr_t addr) {
+ Error error;
+ MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
+ if (pos != m_addr_to_mmap_size.end() &&
+ InferiorCallMunmap(this, addr, pos->second))
+ m_addr_to_mmap_size.erase(pos);
+ else
+ error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64,
+ addr);
- return error;
+ return error;
}
size_t
-ProcessFreeBSD::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site)
-{
- static const uint8_t g_aarch64_opcode[] = { 0x00, 0x00, 0x20, 0xD4 };
- static const uint8_t g_i386_opcode[] = { 0xCC };
-
- ArchSpec arch = GetTarget().GetArchitecture();
- const uint8_t *opcode = NULL;
- size_t opcode_size = 0;
-
- switch (arch.GetMachine())
- {
- default:
- assert(false && "CPU type not supported!");
- break;
-
- case llvm::Triple::arm:
- {
- // The ARM reference recommends the use of 0xe7fddefe and 0xdefe
- // but the linux kernel does otherwise.
- static const uint8_t g_arm_breakpoint_opcode[] = { 0xf0, 0x01, 0xf0, 0xe7 };
- static const uint8_t g_thumb_breakpoint_opcode[] = { 0x01, 0xde };
-
- lldb::BreakpointLocationSP bp_loc_sp (bp_site->GetOwnerAtIndex (0));
- AddressClass addr_class = eAddressClassUnknown;
-
- if (bp_loc_sp)
- addr_class = bp_loc_sp->GetAddress ().GetAddressClass ();
-
- if (addr_class == eAddressClassCodeAlternateISA
- || (addr_class == eAddressClassUnknown
- && bp_loc_sp->GetAddress().GetOffset() & 1))
- {
- opcode = g_thumb_breakpoint_opcode;
- opcode_size = sizeof(g_thumb_breakpoint_opcode);
- }
- else
- {
- opcode = g_arm_breakpoint_opcode;
- opcode_size = sizeof(g_arm_breakpoint_opcode);
- }
- }
- break;
- case llvm::Triple::aarch64:
- opcode = g_aarch64_opcode;
- opcode_size = sizeof(g_aarch64_opcode);
- break;
-
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- opcode = g_i386_opcode;
- opcode_size = sizeof(g_i386_opcode);
- break;
+ProcessFreeBSD::GetSoftwareBreakpointTrapOpcode(BreakpointSite *bp_site) {
+ static const uint8_t g_aarch64_opcode[] = {0x00, 0x00, 0x20, 0xD4};
+ static const uint8_t g_i386_opcode[] = {0xCC};
+
+ ArchSpec arch = GetTarget().GetArchitecture();
+ const uint8_t *opcode = NULL;
+ size_t opcode_size = 0;
+
+ switch (arch.GetMachine()) {
+ default:
+ assert(false && "CPU type not supported!");
+ break;
+
+ case llvm::Triple::arm: {
+ // The ARM reference recommends the use of 0xe7fddefe and 0xdefe
+ // but the linux kernel does otherwise.
+ static const uint8_t g_arm_breakpoint_opcode[] = {0xf0, 0x01, 0xf0, 0xe7};
+ static const uint8_t g_thumb_breakpoint_opcode[] = {0x01, 0xde};
+
+ lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetOwnerAtIndex(0));
+ AddressClass addr_class = eAddressClassUnknown;
+
+ if (bp_loc_sp)
+ addr_class = bp_loc_sp->GetAddress().GetAddressClass();
+
+ if (addr_class == eAddressClassCodeAlternateISA ||
+ (addr_class == eAddressClassUnknown &&
+ bp_loc_sp->GetAddress().GetOffset() & 1)) {
+ opcode = g_thumb_breakpoint_opcode;
+ opcode_size = sizeof(g_thumb_breakpoint_opcode);
+ } else {
+ opcode = g_arm_breakpoint_opcode;
+ opcode_size = sizeof(g_arm_breakpoint_opcode);
}
+ } break;
+ case llvm::Triple::aarch64:
+ opcode = g_aarch64_opcode;
+ opcode_size = sizeof(g_aarch64_opcode);
+ break;
+
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ opcode = g_i386_opcode;
+ opcode_size = sizeof(g_i386_opcode);
+ break;
+ }
- bp_site->SetTrapOpcode(opcode, opcode_size);
- return opcode_size;
+ bp_site->SetTrapOpcode(opcode, opcode_size);
+ return opcode_size;
}
-Error
-ProcessFreeBSD::EnableBreakpointSite(BreakpointSite *bp_site)
-{
- return EnableSoftwareBreakpoint(bp_site);
+Error ProcessFreeBSD::EnableBreakpointSite(BreakpointSite *bp_site) {
+ return EnableSoftwareBreakpoint(bp_site);
}
-Error
-ProcessFreeBSD::DisableBreakpointSite(BreakpointSite *bp_site)
-{
- return DisableSoftwareBreakpoint(bp_site);
+Error ProcessFreeBSD::DisableBreakpointSite(BreakpointSite *bp_site) {
+ return DisableSoftwareBreakpoint(bp_site);
}
-Error
-ProcessFreeBSD::EnableWatchpoint(Watchpoint *wp, bool notify)
-{
- Error error;
- if (wp)
- {
- user_id_t watchID = wp->GetID();
- addr_t addr = wp->GetLoadAddress();
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64 ")",
- watchID);
- if (wp->IsEnabled())
- {
- if (log)
- log->Printf("ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64
- ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
- watchID, (uint64_t)addr);
- return error;
- }
-
- // Try to find a vacant watchpoint slot in the inferiors' main thread
- uint32_t wp_hw_index = LLDB_INVALID_INDEX32;
- std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
- FreeBSDThread *thread = static_cast<FreeBSDThread*>(
- m_thread_list.GetThreadAtIndex(0, false).get());
+Error ProcessFreeBSD::EnableWatchpoint(Watchpoint *wp, bool notify) {
+ Error error;
+ if (wp) {
+ user_id_t watchID = wp->GetID();
+ addr_t addr = wp->GetLoadAddress();
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
+ if (log)
+ log->Printf("ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64 ")",
+ watchID);
+ if (wp->IsEnabled()) {
+ if (log)
+ log->Printf("ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64
+ ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
+ watchID, (uint64_t)addr);
+ return error;
+ }
- if (thread)
- wp_hw_index = thread->FindVacantWatchpointIndex();
+ // Try to find a vacant watchpoint slot in the inferiors' main thread
+ uint32_t wp_hw_index = LLDB_INVALID_INDEX32;
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
+ FreeBSDThread *thread = static_cast<FreeBSDThread *>(
+ m_thread_list.GetThreadAtIndex(0, false).get());
+
+ if (thread)
+ wp_hw_index = thread->FindVacantWatchpointIndex();
- if (wp_hw_index == LLDB_INVALID_INDEX32)
- {
- error.SetErrorString("Setting hardware watchpoint failed.");
- }
+ if (wp_hw_index == LLDB_INVALID_INDEX32) {
+ error.SetErrorString("Setting hardware watchpoint failed.");
+ } else {
+ wp->SetHardwareIndex(wp_hw_index);
+ bool wp_enabled = true;
+ uint32_t thread_count = m_thread_list.GetSize(false);
+ for (uint32_t i = 0; i < thread_count; ++i) {
+ thread = static_cast<FreeBSDThread *>(
+ m_thread_list.GetThreadAtIndex(i, false).get());
+ if (thread)
+ wp_enabled &= thread->EnableHardwareWatchpoint(wp);
else
- {
- wp->SetHardwareIndex(wp_hw_index);
- bool wp_enabled = true;
- uint32_t thread_count = m_thread_list.GetSize(false);
- for (uint32_t i = 0; i < thread_count; ++i)
- {
- thread = static_cast<FreeBSDThread*>(
- m_thread_list.GetThreadAtIndex(i, false).get());
- if (thread)
- wp_enabled &= thread->EnableHardwareWatchpoint(wp);
- else
- wp_enabled = false;
- }
- if (wp_enabled)
- {
- wp->SetEnabled(true, notify);
- return error;
- }
- else
- {
- // Watchpoint enabling failed on at least one
- // of the threads so roll back all of them
- DisableWatchpoint(wp, false);
- error.SetErrorString("Setting hardware watchpoint failed");
- }
- }
+ wp_enabled = false;
+ }
+ if (wp_enabled) {
+ wp->SetEnabled(true, notify);
+ return error;
+ } else {
+ // Watchpoint enabling failed on at least one
+ // of the threads so roll back all of them
+ DisableWatchpoint(wp, false);
+ error.SetErrorString("Setting hardware watchpoint failed");
+ }
}
- else
- error.SetErrorString("Watchpoint argument was NULL.");
- return error;
+ } else
+ error.SetErrorString("Watchpoint argument was NULL.");
+ return error;
}
-Error
-ProcessFreeBSD::DisableWatchpoint(Watchpoint *wp, bool notify)
-{
- Error error;
- if (wp)
- {
- user_id_t watchID = wp->GetID();
- addr_t addr = wp->GetLoadAddress();
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- if (log)
- log->Printf("ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64 ")",
- watchID);
- if (!wp->IsEnabled())
- {
- if (log)
- log->Printf("ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64
- ") addr = 0x%8.8" PRIx64 ": watchpoint already disabled.",
- watchID, (uint64_t)addr);
- // This is needed (for now) to keep watchpoints disabled correctly
- wp->SetEnabled(false, notify);
- return error;
- }
-
- if (wp->IsHardware())
- {
- bool wp_disabled = true;
- std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
- uint32_t thread_count = m_thread_list.GetSize(false);
- for (uint32_t i = 0; i < thread_count; ++i)
- {
- FreeBSDThread *thread = static_cast<FreeBSDThread*>(
- m_thread_list.GetThreadAtIndex(i, false).get());
- if (thread)
- wp_disabled &= thread->DisableHardwareWatchpoint(wp);
- else
- wp_disabled = false;
- }
- if (wp_disabled)
- {
- wp->SetHardwareIndex(LLDB_INVALID_INDEX32);
- wp->SetEnabled(false, notify);
- return error;
- }
- else
- error.SetErrorString("Disabling hardware watchpoint failed");
- }
+Error ProcessFreeBSD::DisableWatchpoint(Watchpoint *wp, bool notify) {
+ Error error;
+ if (wp) {
+ user_id_t watchID = wp->GetID();
+ addr_t addr = wp->GetLoadAddress();
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
+ if (log)
+ log->Printf("ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64 ")",
+ watchID);
+ if (!wp->IsEnabled()) {
+ if (log)
+ log->Printf("ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64
+ ") addr = 0x%8.8" PRIx64 ": watchpoint already disabled.",
+ watchID, (uint64_t)addr);
+ // This is needed (for now) to keep watchpoints disabled correctly
+ wp->SetEnabled(false, notify);
+ return error;
}
- else
- error.SetErrorString("Watchpoint argument was NULL.");
- return error;
+
+ if (wp->IsHardware()) {
+ bool wp_disabled = true;
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
+ uint32_t thread_count = m_thread_list.GetSize(false);
+ for (uint32_t i = 0; i < thread_count; ++i) {
+ FreeBSDThread *thread = static_cast<FreeBSDThread *>(
+ m_thread_list.GetThreadAtIndex(i, false).get());
+ if (thread)
+ wp_disabled &= thread->DisableHardwareWatchpoint(wp);
+ else
+ wp_disabled = false;
+ }
+ if (wp_disabled) {
+ wp->SetHardwareIndex(LLDB_INVALID_INDEX32);
+ wp->SetEnabled(false, notify);
+ return error;
+ } else
+ error.SetErrorString("Disabling hardware watchpoint failed");
+ }
+ } else
+ error.SetErrorString("Watchpoint argument was NULL.");
+ return error;
}
-Error
-ProcessFreeBSD::GetWatchpointSupportInfo(uint32_t &num)
-{
- Error error;
- std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
- FreeBSDThread *thread = static_cast<FreeBSDThread*>(
- m_thread_list.GetThreadAtIndex(0, false).get());
- if (thread)
- num = thread->NumSupportedHardwareWatchpoints();
- else
- error.SetErrorString("Process does not exist.");
- return error;
+Error ProcessFreeBSD::GetWatchpointSupportInfo(uint32_t &num) {
+ Error error;
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
+ FreeBSDThread *thread = static_cast<FreeBSDThread *>(
+ m_thread_list.GetThreadAtIndex(0, false).get());
+ if (thread)
+ num = thread->NumSupportedHardwareWatchpoints();
+ else
+ error.SetErrorString("Process does not exist.");
+ return error;
}
-Error
-ProcessFreeBSD::GetWatchpointSupportInfo(uint32_t &num, bool &after)
-{
- Error error = GetWatchpointSupportInfo(num);
- // Watchpoints trigger and halt the inferior after
- // the corresponding instruction has been executed.
- after = true;
- return error;
+Error ProcessFreeBSD::GetWatchpointSupportInfo(uint32_t &num, bool &after) {
+ Error error = GetWatchpointSupportInfo(num);
+ // Watchpoints trigger and halt the inferior after
+ // the corresponding instruction has been executed.
+ after = true;
+ return error;
}
-uint32_t
-ProcessFreeBSD::UpdateThreadListIfNeeded()
-{
- std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
- // Do not allow recursive updates.
- return m_thread_list.GetSize(false);
+uint32_t ProcessFreeBSD::UpdateThreadListIfNeeded() {
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
+ // Do not allow recursive updates.
+ return m_thread_list.GetSize(false);
}
#if 0
@@ -955,91 +839,77 @@ ProcessFreeBSD::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_th
}
#endif
-ByteOrder
-ProcessFreeBSD::GetByteOrder() const
-{
- // FIXME: We should be able to extract this value directly. See comment in
- // ProcessFreeBSD().
- return m_byte_order;
+ByteOrder ProcessFreeBSD::GetByteOrder() const {
+ // FIXME: We should be able to extract this value directly. See comment in
+ // ProcessFreeBSD().
+ return m_byte_order;
}
-size_t
-ProcessFreeBSD::PutSTDIN(const char *buf, size_t len, Error &error)
-{
- ssize_t status;
- if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0)
- {
- error.SetErrorToErrno();
- return 0;
- }
- return status;
+size_t ProcessFreeBSD::PutSTDIN(const char *buf, size_t len, Error &error) {
+ ssize_t status;
+ if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0) {
+ error.SetErrorToErrno();
+ return 0;
+ }
+ return status;
}
//------------------------------------------------------------------------------
// Utility functions.
-bool
-ProcessFreeBSD::HasExited()
-{
- switch (GetPrivateState())
- {
- default:
- break;
-
- case eStateDetached:
- case eStateExited:
- return true;
- }
-
- return false;
-}
+bool ProcessFreeBSD::HasExited() {
+ switch (GetPrivateState()) {
+ default:
+ break;
-bool
-ProcessFreeBSD::IsStopped()
-{
- switch (GetPrivateState())
- {
- default:
- break;
-
- case eStateStopped:
- case eStateCrashed:
- case eStateSuspended:
- return true;
- }
+ case eStateDetached:
+ case eStateExited:
+ return true;
+ }
- return false;
+ return false;
}
-bool
-ProcessFreeBSD::IsAThreadRunning()
-{
- bool is_running = false;
- std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
- uint32_t thread_count = m_thread_list.GetSize(false);
- for (uint32_t i = 0; i < thread_count; ++i)
- {
- FreeBSDThread *thread = static_cast<FreeBSDThread*>(
- m_thread_list.GetThreadAtIndex(i, false).get());
- StateType thread_state = thread->GetState();
- if (thread_state == eStateRunning || thread_state == eStateStepping)
- {
- is_running = true;
- break;
- }
- }
- return is_running;
-}
+bool ProcessFreeBSD::IsStopped() {
+ switch (GetPrivateState()) {
+ default:
+ break;
-const DataBufferSP
-ProcessFreeBSD::GetAuxvData ()
-{
- // If we're the local platform, we can ask the host for auxv data.
- PlatformSP platform_sp = GetTarget().GetPlatform ();
- if (platform_sp && platform_sp->IsHost ())
- return lldb_private::Host::GetAuxvData(this);
-
- // Somewhat unexpected - the process is not running locally or we don't have a platform.
- assert (false && "no platform or not the host - how did we get here with ProcessFreeBSD?");
- return DataBufferSP ();
+ case eStateStopped:
+ case eStateCrashed:
+ case eStateSuspended:
+ return true;
+ }
+
+ return false;
+}
+
+bool ProcessFreeBSD::IsAThreadRunning() {
+ bool is_running = false;
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
+ uint32_t thread_count = m_thread_list.GetSize(false);
+ for (uint32_t i = 0; i < thread_count; ++i) {
+ FreeBSDThread *thread = static_cast<FreeBSDThread *>(
+ m_thread_list.GetThreadAtIndex(i, false).get());
+ StateType thread_state = thread->GetState();
+ if (thread_state == eStateRunning || thread_state == eStateStepping) {
+ is_running = true;
+ break;
+ }
+ }
+ return is_running;
+}
+
+const DataBufferSP ProcessFreeBSD::GetAuxvData() {
+ // If we're the local platform, we can ask the host for auxv data.
+ PlatformSP platform_sp = GetTarget().GetPlatform();
+ if (platform_sp && platform_sp->IsHost())
+ return lldb_private::Host::GetAuxvData(this);
+
+ // Somewhat unexpected - the process is not running locally or we don't have a
+ // platform.
+ assert(
+ false &&
+ "no platform or not the host - how did we get here with ProcessFreeBSD?");
+ return DataBufferSP();
}
diff --git a/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h b/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h
index 888e2a90ad76..cd38989f973c 100644
--- a/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h
+++ b/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h
@@ -1,4 +1,5 @@
-//===-- ProcessFreeBSD.h ------------------------------------------*- C++ -*-===//
+//===-- ProcessFreeBSD.h ------------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,233 +19,200 @@
#include <set>
// Other libraries and framework includes
+#include "ProcessFreeBSD.h"
+#include "ProcessMessage.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/ThreadList.h"
-#include "ProcessMessage.h"
-#include "ProcessFreeBSD.h"
class ProcessMonitor;
class FreeBSDThread;
-class ProcessFreeBSD :
- public lldb_private::Process
-{
+class ProcessFreeBSD : public lldb_private::Process {
public:
- //------------------------------------------------------------------
- // Static functions.
- //------------------------------------------------------------------
- static lldb::ProcessSP
- CreateInstance(lldb::TargetSP target_sp,
- lldb::ListenerSP listener_sp,
- const lldb_private::FileSpec *crash_file_path);
+ //------------------------------------------------------------------
+ // Static functions.
+ //------------------------------------------------------------------
+ static lldb::ProcessSP
+ CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
+ const lldb_private::FileSpec *crash_file_path);
- static void
- Initialize();
+ static void Initialize();
- static void
- Terminate();
+ static void Terminate();
- static lldb_private::ConstString
- GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
- static const char *
- GetPluginDescriptionStatic();
+ static const char *GetPluginDescriptionStatic();
- //------------------------------------------------------------------
- // Constructors and destructors
- //------------------------------------------------------------------
- ProcessFreeBSD(lldb::TargetSP target_sp,
- lldb::ListenerSP listener_sp,
- lldb::UnixSignalsSP &unix_signals_sp);
+ //------------------------------------------------------------------
+ // Constructors and destructors
+ //------------------------------------------------------------------
+ ProcessFreeBSD(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
+ lldb::UnixSignalsSP &unix_signals_sp);
- ~ProcessFreeBSD();
+ ~ProcessFreeBSD();
- virtual lldb_private::Error
- WillResume() override;
+ virtual lldb_private::Error WillResume() override;
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- virtual lldb_private::ConstString
- GetPluginName() override;
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ virtual lldb_private::ConstString GetPluginName() override;
- virtual uint32_t
- GetPluginVersion() override;
+ virtual uint32_t GetPluginVersion() override;
public:
- //------------------------------------------------------------------
- // Process protocol.
- //------------------------------------------------------------------
- void
- Finalize() override;
+ //------------------------------------------------------------------
+ // Process protocol.
+ //------------------------------------------------------------------
+ void Finalize() override;
- bool
- CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) override;
+ bool CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) override;
- lldb_private::Error
- WillLaunch(lldb_private::Module *module) override;
+ lldb_private::Error WillLaunch(lldb_private::Module *module) override;
- lldb_private::Error
- DoAttachToProcessWithID (lldb::pid_t pid, const lldb_private::ProcessAttachInfo &attach_info) override;
+ lldb_private::Error DoAttachToProcessWithID(
+ lldb::pid_t pid,
+ const lldb_private::ProcessAttachInfo &attach_info) override;
- lldb_private::Error
- DoLaunch (lldb_private::Module *exe_module,
- lldb_private::ProcessLaunchInfo &launch_info) override;
+ lldb_private::Error
+ DoLaunch(lldb_private::Module *exe_module,
+ lldb_private::ProcessLaunchInfo &launch_info) override;
- void
- DidLaunch() override;
+ void DidLaunch() override;
- lldb_private::Error
- DoResume() override;
+ lldb_private::Error DoResume() override;
- lldb_private::Error
- DoHalt(bool &caused_stop) override;
+ lldb_private::Error DoHalt(bool &caused_stop) override;
- lldb_private::Error
- DoDetach(bool keep_stopped) override;
+ lldb_private::Error DoDetach(bool keep_stopped) override;
- lldb_private::Error
- DoSignal(int signal) override;
+ lldb_private::Error DoSignal(int signal) override;
- lldb_private::Error
- DoDestroy() override;
+ lldb_private::Error DoDestroy() override;
- void
- DoDidExec() override;
+ void DoDidExec() override;
- void
- RefreshStateAfterStop() override;
+ void RefreshStateAfterStop() override;
- bool
- IsAlive() override;
+ bool IsAlive() override;
- size_t
- DoReadMemory(lldb::addr_t vm_addr,
- void *buf,
- size_t size,
- lldb_private::Error &error) override;
+ size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
+ lldb_private::Error &error) override;
- size_t
- DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size,
- lldb_private::Error &error) override;
+ size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size,
+ lldb_private::Error &error) override;
- lldb::addr_t
- DoAllocateMemory(size_t size, uint32_t permissions,
- lldb_private::Error &error) override;
+ lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions,
+ lldb_private::Error &error) override;
- lldb_private::Error
- DoDeallocateMemory(lldb::addr_t ptr) override;
+ lldb_private::Error DoDeallocateMemory(lldb::addr_t ptr) override;
- virtual size_t
- GetSoftwareBreakpointTrapOpcode(lldb_private::BreakpointSite* bp_site);
+ virtual size_t
+ GetSoftwareBreakpointTrapOpcode(lldb_private::BreakpointSite *bp_site);
- lldb_private::Error
- EnableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
+ lldb_private::Error
+ EnableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
- lldb_private::Error
- DisableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
+ lldb_private::Error
+ DisableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
- lldb_private::Error
- EnableWatchpoint(lldb_private::Watchpoint *wp, bool notify = true) override;
+ lldb_private::Error EnableWatchpoint(lldb_private::Watchpoint *wp,
+ bool notify = true) override;
- lldb_private::Error
- DisableWatchpoint(lldb_private::Watchpoint *wp, bool notify = true) override;
+ lldb_private::Error DisableWatchpoint(lldb_private::Watchpoint *wp,
+ bool notify = true) override;
- lldb_private::Error
- GetWatchpointSupportInfo(uint32_t &num) override;
+ lldb_private::Error GetWatchpointSupportInfo(uint32_t &num) override;
- lldb_private::Error
- GetWatchpointSupportInfo(uint32_t &num, bool &after) override;
+ lldb_private::Error GetWatchpointSupportInfo(uint32_t &num,
+ bool &after) override;
- virtual uint32_t
- UpdateThreadListIfNeeded();
+ virtual uint32_t UpdateThreadListIfNeeded();
- bool
- UpdateThreadList(lldb_private::ThreadList &old_thread_list,
- lldb_private::ThreadList &new_thread_list) override;
+ bool UpdateThreadList(lldb_private::ThreadList &old_thread_list,
+ lldb_private::ThreadList &new_thread_list) override;
- virtual lldb::ByteOrder
- GetByteOrder() const;
+ virtual lldb::ByteOrder GetByteOrder() const;
- lldb::addr_t
- GetImageInfoAddress() override;
+ lldb::addr_t GetImageInfoAddress() override;
- size_t
- PutSTDIN(const char *buf, size_t len, lldb_private::Error &error) override;
+ size_t PutSTDIN(const char *buf, size_t len,
+ lldb_private::Error &error) override;
- const lldb::DataBufferSP
- GetAuxvData () override;
+ const lldb::DataBufferSP GetAuxvData() override;
- //--------------------------------------------------------------------------
- // ProcessFreeBSD internal API.
+ //--------------------------------------------------------------------------
+ // ProcessFreeBSD internal API.
- /// Registers the given message with this process.
- virtual void
- SendMessage(const ProcessMessage &message);
+ /// Registers the given message with this process.
+ virtual void SendMessage(const ProcessMessage &message);
- ProcessMonitor &
- GetMonitor() { assert(m_monitor); return *m_monitor; }
+ ProcessMonitor &GetMonitor() {
+ assert(m_monitor);
+ return *m_monitor;
+ }
- lldb_private::FileSpec
- GetFileSpec(const lldb_private::FileAction *file_action,
- const lldb_private::FileSpec &default_file_spec,
- const lldb_private::FileSpec &dbg_pts_file_spec);
+ lldb_private::FileSpec
+ GetFileSpec(const lldb_private::FileAction *file_action,
+ const lldb_private::FileSpec &default_file_spec,
+ const lldb_private::FileSpec &dbg_pts_file_spec);
- /// Adds the thread to the list of threads for which we have received the initial stopping signal.
- /// The \p stop_tid parameter indicates the thread which the stop happened for.
- bool
- AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid);
+ /// Adds the thread to the list of threads for which we have received the
+ /// initial stopping signal.
+ /// The \p stop_tid parameter indicates the thread which the stop happened
+ /// for.
+ bool AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid);
- bool
- WaitingForInitialStop(lldb::tid_t stop_tid);
+ bool WaitingForInitialStop(lldb::tid_t stop_tid);
- virtual FreeBSDThread *
- CreateNewFreeBSDThread(lldb_private::Process &process, lldb::tid_t tid);
+ virtual FreeBSDThread *CreateNewFreeBSDThread(lldb_private::Process &process,
+ lldb::tid_t tid);
protected:
- /// Target byte order.
- lldb::ByteOrder m_byte_order;
-
- /// Process monitor;
- ProcessMonitor *m_monitor;
+ /// Target byte order.
+ lldb::ByteOrder m_byte_order;
- /// The module we are executing.
- lldb_private::Module *m_module;
+ /// Process monitor;
+ ProcessMonitor *m_monitor;
- /// Message queue notifying this instance of inferior process state changes.
- std::recursive_mutex m_message_mutex;
- std::queue<ProcessMessage> m_message_queue;
+ /// The module we are executing.
+ lldb_private::Module *m_module;
- /// Drive any exit events to completion.
- bool m_exit_now;
+ /// Message queue notifying this instance of inferior process state changes.
+ std::recursive_mutex m_message_mutex;
+ std::queue<ProcessMessage> m_message_queue;
- /// Returns true if the process has exited.
- bool HasExited();
+ /// Drive any exit events to completion.
+ bool m_exit_now;
- /// Returns true if the process is stopped.
- bool IsStopped();
+ /// Returns true if the process has exited.
+ bool HasExited();
- /// Returns true if at least one running is currently running
- bool IsAThreadRunning();
+ /// Returns true if the process is stopped.
+ bool IsStopped();
- typedef std::map<lldb::addr_t, lldb::addr_t> MMapMap;
- MMapMap m_addr_to_mmap_size;
+ /// Returns true if at least one running is currently running
+ bool IsAThreadRunning();
- typedef std::set<lldb::tid_t> ThreadStopSet;
- /// Every thread begins with a stop signal. This keeps track
- /// of the threads for which we have received the stop signal.
- ThreadStopSet m_seen_initial_stop;
+ typedef std::map<lldb::addr_t, lldb::addr_t> MMapMap;
+ MMapMap m_addr_to_mmap_size;
- friend class FreeBSDThread;
+ typedef std::set<lldb::tid_t> ThreadStopSet;
+ /// Every thread begins with a stop signal. This keeps track
+ /// of the threads for which we have received the stop signal.
+ ThreadStopSet m_seen_initial_stop;
- typedef std::vector<lldb::tid_t> tid_collection;
- tid_collection m_suspend_tids;
- tid_collection m_run_tids;
- tid_collection m_step_tids;
+ friend class FreeBSDThread;
- int m_resume_signo;
+ typedef std::vector<lldb::tid_t> tid_collection;
+ tid_collection m_suspend_tids;
+ tid_collection m_run_tids;
+ tid_collection m_step_tids;
+ int m_resume_signo;
};
-#endif // liblldb_ProcessFreeBSD_H_
+#endif // liblldb_ProcessFreeBSD_H_
diff --git a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
index 16707a5c8b97..afc649de3b65 100644
--- a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
+++ b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
@@ -10,14 +10,14 @@
// C Includes
#include <errno.h>
#include <poll.h>
-#include <string.h>
-#include <stdint.h>
-#include <unistd.h>
#include <signal.h>
+#include <stdint.h>
+#include <string.h>
#include <sys/ptrace.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <unistd.h>
// C++ Includes
// Other libraries and framework includes
@@ -26,20 +26,20 @@
#include "lldb/Core/Scalar.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/ThreadLauncher.h"
-#include "lldb/Target/Thread.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Thread.h"
#include "lldb/Target/UnixSignals.h"
#include "lldb/Utility/PseudoTerminal.h"
-#include "Plugins/Process/POSIX/CrashReason.h"
#include "FreeBSDThread.h"
+#include "Plugins/Process/POSIX/CrashReason.h"
#include "ProcessFreeBSD.h"
-#include "ProcessPOSIXLog.h"
#include "ProcessMonitor.h"
+#include "ProcessPOSIXLog.h"
extern "C" {
- extern char ** environ;
- }
+extern char **environ;
+}
using namespace lldb;
using namespace lldb_private;
@@ -49,96 +49,103 @@ using namespace lldb_private;
#ifndef LLDB_CONFIGURATION_BUILDANDINTEGRATION
// Wrapper for ptrace to catch errors and log calls.
-const char *
-Get_PT_IO_OP(int op)
-{
- switch (op) {
- case PIOD_READ_D: return "READ_D";
- case PIOD_WRITE_D: return "WRITE_D";
- case PIOD_READ_I: return "READ_I";
- case PIOD_WRITE_I: return "WRITE_I";
- default: return "Unknown op";
- }
+const char *Get_PT_IO_OP(int op) {
+ switch (op) {
+ case PIOD_READ_D:
+ return "READ_D";
+ case PIOD_WRITE_D:
+ return "WRITE_D";
+ case PIOD_READ_I:
+ return "READ_I";
+ case PIOD_WRITE_I:
+ return "WRITE_I";
+ default:
+ return "Unknown op";
+ }
}
// Wrapper for ptrace to catch errors and log calls.
-// Note that ptrace sets errno on error because -1 is reserved as a valid result.
-extern long
-PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data,
- const char* reqName, const char* file, int line)
-{
- long int result;
-
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
-
- if (log) {
- log->Printf("ptrace(%s, %" PRIu64 ", %p, %x) called from file %s line %d",
- reqName, pid, addr, data, file, line);
- if (req == PT_IO) {
- struct ptrace_io_desc *pi = (struct ptrace_io_desc *) addr;
-
- log->Printf("PT_IO: op=%s offs=%zx size=%zu",
- Get_PT_IO_OP(pi->piod_op), (size_t)pi->piod_offs, pi->piod_len);
- }
+// Note that ptrace sets errno on error because -1 is reserved as a valid
+// result.
+extern long PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data,
+ const char *reqName, const char *file, int line) {
+ long int result;
+
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
+
+ if (log) {
+ log->Printf("ptrace(%s, %" PRIu64 ", %p, %x) called from file %s line %d",
+ reqName, pid, addr, data, file, line);
+ if (req == PT_IO) {
+ struct ptrace_io_desc *pi = (struct ptrace_io_desc *)addr;
+
+ log->Printf("PT_IO: op=%s offs=%zx size=%zu", Get_PT_IO_OP(pi->piod_op),
+ (size_t)pi->piod_offs, pi->piod_len);
}
-
- //PtraceDisplayBytes(req, data);
-
- errno = 0;
- result = ptrace(req, pid, (caddr_t) addr, data);
-
- //PtraceDisplayBytes(req, data);
-
- if (log && errno != 0)
- {
- const char* str;
- switch (errno)
- {
- case ESRCH: str = "ESRCH"; break;
- case EINVAL: str = "EINVAL"; break;
- case EBUSY: str = "EBUSY"; break;
- case EPERM: str = "EPERM"; break;
- default: str = "<unknown>";
- }
- log->Printf("ptrace() failed; errno=%d (%s)", errno, str);
+ }
+
+ // PtraceDisplayBytes(req, data);
+
+ errno = 0;
+ result = ptrace(req, pid, (caddr_t)addr, data);
+
+ // PtraceDisplayBytes(req, data);
+
+ if (log && errno != 0) {
+ const char *str;
+ switch (errno) {
+ case ESRCH:
+ str = "ESRCH";
+ break;
+ case EINVAL:
+ str = "EINVAL";
+ break;
+ case EBUSY:
+ str = "EBUSY";
+ break;
+ case EPERM:
+ str = "EPERM";
+ break;
+ default:
+ str = "<unknown>";
}
+ log->Printf("ptrace() failed; errno=%d (%s)", errno, str);
+ }
- if (log) {
+ if (log) {
#ifdef __amd64__
- if (req == PT_GETREGS) {
- struct reg *r = (struct reg *) addr;
-
- log->Printf("PT_GETREGS: rip=0x%lx rsp=0x%lx rbp=0x%lx rax=0x%lx",
- r->r_rip, r->r_rsp, r->r_rbp, r->r_rax);
- }
- if (req == PT_GETDBREGS || req == PT_SETDBREGS) {
- struct dbreg *r = (struct dbreg *) addr;
- char setget = (req == PT_GETDBREGS) ? 'G' : 'S';
-
- for (int i = 0; i <= 7; i++)
- log->Printf("PT_%cETDBREGS: dr[%d]=0x%lx", setget, i, r->dr[i]);
- }
-#endif
+ if (req == PT_GETREGS) {
+ struct reg *r = (struct reg *)addr;
+
+ log->Printf("PT_GETREGS: rip=0x%lx rsp=0x%lx rbp=0x%lx rax=0x%lx",
+ r->r_rip, r->r_rsp, r->r_rbp, r->r_rax);
}
-
- return result;
+ if (req == PT_GETDBREGS || req == PT_SETDBREGS) {
+ struct dbreg *r = (struct dbreg *)addr;
+ char setget = (req == PT_GETDBREGS) ? 'G' : 'S';
+
+ for (int i = 0; i <= 7; i++)
+ log->Printf("PT_%cETDBREGS: dr[%d]=0x%lx", setget, i, r->dr[i]);
+ }
+#endif
+ }
+
+ return result;
}
// Wrapper for ptrace when logging is not required.
// Sets errno to 0 prior to calling ptrace.
-extern long
-PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data)
-{
- long result = 0;
- errno = 0;
- result = ptrace(req, pid, (caddr_t)addr, data);
- return result;
+extern long PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data) {
+ long result = 0;
+ errno = 0;
+ result = ptrace(req, pid, (caddr_t)addr, data);
+ return result;
}
-#define PTRACE(req, pid, addr, data) \
- PtraceWrapper((req), (pid), (addr), (data), #req, __FILE__, __LINE__)
+#define PTRACE(req, pid, addr, data) \
+ PtraceWrapper((req), (pid), (addr), (data), #req, __FILE__, __LINE__)
#else
- PtraceWrapper((req), (pid), (addr), (data))
+PtraceWrapper((req), (pid), (addr), (data))
#endif
//------------------------------------------------------------------------------
@@ -146,58 +153,50 @@ PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data)
// ProcessMonitor::WriteMemory. This enables mutual recursion between these
// functions without needed to go thru the thread funnel.
-static size_t
-DoReadMemory(lldb::pid_t pid, lldb::addr_t vm_addr, void *buf, size_t size,
- Error &error)
-{
- struct ptrace_io_desc pi_desc;
+static size_t DoReadMemory(lldb::pid_t pid, lldb::addr_t vm_addr, void *buf,
+ size_t size, Error &error) {
+ struct ptrace_io_desc pi_desc;
- pi_desc.piod_op = PIOD_READ_D;
- pi_desc.piod_offs = (void *)vm_addr;
- pi_desc.piod_addr = buf;
- pi_desc.piod_len = size;
+ pi_desc.piod_op = PIOD_READ_D;
+ pi_desc.piod_offs = (void *)vm_addr;
+ pi_desc.piod_addr = buf;
+ pi_desc.piod_len = size;
- if (PTRACE(PT_IO, pid, (caddr_t)&pi_desc, 0) < 0)
- error.SetErrorToErrno();
- return pi_desc.piod_len;
+ if (PTRACE(PT_IO, pid, (caddr_t)&pi_desc, 0) < 0)
+ error.SetErrorToErrno();
+ return pi_desc.piod_len;
}
-static size_t
-DoWriteMemory(lldb::pid_t pid, lldb::addr_t vm_addr, const void *buf,
- size_t size, Error &error)
-{
- struct ptrace_io_desc pi_desc;
+static size_t DoWriteMemory(lldb::pid_t pid, lldb::addr_t vm_addr,
+ const void *buf, size_t size, Error &error) {
+ struct ptrace_io_desc pi_desc;
- pi_desc.piod_op = PIOD_WRITE_D;
- pi_desc.piod_offs = (void *)vm_addr;
- pi_desc.piod_addr = (void *)buf;
- pi_desc.piod_len = size;
+ pi_desc.piod_op = PIOD_WRITE_D;
+ pi_desc.piod_offs = (void *)vm_addr;
+ pi_desc.piod_addr = (void *)buf;
+ pi_desc.piod_len = size;
- if (PTRACE(PT_IO, pid, (caddr_t)&pi_desc, 0) < 0)
- error.SetErrorToErrno();
- return pi_desc.piod_len;
+ if (PTRACE(PT_IO, pid, (caddr_t)&pi_desc, 0) < 0)
+ error.SetErrorToErrno();
+ return pi_desc.piod_len;
}
// Simple helper function to ensure flags are enabled on the given file
// descriptor.
-static bool
-EnsureFDFlags(int fd, int flags, Error &error)
-{
- int status;
-
- if ((status = fcntl(fd, F_GETFL)) == -1)
- {
- error.SetErrorToErrno();
- return false;
- }
+static bool EnsureFDFlags(int fd, int flags, Error &error) {
+ int status;
- if (fcntl(fd, F_SETFL, status | flags) == -1)
- {
- error.SetErrorToErrno();
- return false;
- }
+ if ((status = fcntl(fd, F_GETFL)) == -1) {
+ error.SetErrorToErrno();
+ return false;
+ }
+
+ if (fcntl(fd, F_SETFL, status | flags) == -1) {
+ error.SetErrorToErrno();
+ return false;
+ }
- return true;
+ return true;
}
//------------------------------------------------------------------------------
@@ -211,1383 +210,1216 @@ EnsureFDFlags(int fd, int flags, Error &error)
/// task. The Operation class provides an abstract base for all services the
/// ProcessMonitor must perform via the single virtual function Execute, thus
/// encapsulating the code that needs to run in the privileged context.
-class Operation
-{
+class Operation {
public:
- virtual ~Operation() {}
- virtual void Execute(ProcessMonitor *monitor) = 0;
+ virtual ~Operation() {}
+ virtual void Execute(ProcessMonitor *monitor) = 0;
};
//------------------------------------------------------------------------------
/// @class ReadOperation
/// @brief Implements ProcessMonitor::ReadMemory.
-class ReadOperation : public Operation
-{
+class ReadOperation : public Operation {
public:
- ReadOperation(lldb::addr_t addr, void *buff, size_t size,
- Error &error, size_t &result)
- : m_addr(addr), m_buff(buff), m_size(size),
- m_error(error), m_result(result)
- { }
+ ReadOperation(lldb::addr_t addr, void *buff, size_t size, Error &error,
+ size_t &result)
+ : m_addr(addr), m_buff(buff), m_size(size), m_error(error),
+ m_result(result) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- lldb::addr_t m_addr;
- void *m_buff;
- size_t m_size;
- Error &m_error;
- size_t &m_result;
+ lldb::addr_t m_addr;
+ void *m_buff;
+ size_t m_size;
+ Error &m_error;
+ size_t &m_result;
};
-void
-ReadOperation::Execute(ProcessMonitor *monitor)
-{
- lldb::pid_t pid = monitor->GetPID();
+void ReadOperation::Execute(ProcessMonitor *monitor) {
+ lldb::pid_t pid = monitor->GetPID();
- m_result = DoReadMemory(pid, m_addr, m_buff, m_size, m_error);
+ m_result = DoReadMemory(pid, m_addr, m_buff, m_size, m_error);
}
//------------------------------------------------------------------------------
/// @class WriteOperation
/// @brief Implements ProcessMonitor::WriteMemory.
-class WriteOperation : public Operation
-{
+class WriteOperation : public Operation {
public:
- WriteOperation(lldb::addr_t addr, const void *buff, size_t size,
- Error &error, size_t &result)
- : m_addr(addr), m_buff(buff), m_size(size),
- m_error(error), m_result(result)
- { }
+ WriteOperation(lldb::addr_t addr, const void *buff, size_t size, Error &error,
+ size_t &result)
+ : m_addr(addr), m_buff(buff), m_size(size), m_error(error),
+ m_result(result) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- lldb::addr_t m_addr;
- const void *m_buff;
- size_t m_size;
- Error &m_error;
- size_t &m_result;
+ lldb::addr_t m_addr;
+ const void *m_buff;
+ size_t m_size;
+ Error &m_error;
+ size_t &m_result;
};
-void
-WriteOperation::Execute(ProcessMonitor *monitor)
-{
- lldb::pid_t pid = monitor->GetPID();
+void WriteOperation::Execute(ProcessMonitor *monitor) {
+ lldb::pid_t pid = monitor->GetPID();
- m_result = DoWriteMemory(pid, m_addr, m_buff, m_size, m_error);
+ m_result = DoWriteMemory(pid, m_addr, m_buff, m_size, m_error);
}
//------------------------------------------------------------------------------
/// @class ReadRegOperation
/// @brief Implements ProcessMonitor::ReadRegisterValue.
-class ReadRegOperation : public Operation
-{
+class ReadRegOperation : public Operation {
public:
- ReadRegOperation(lldb::tid_t tid, unsigned offset, unsigned size,
- RegisterValue &value, bool &result)
- : m_tid(tid), m_offset(offset), m_size(size),
- m_value(value), m_result(result)
- { }
+ ReadRegOperation(lldb::tid_t tid, unsigned offset, unsigned size,
+ RegisterValue &value, bool &result)
+ : m_tid(tid), m_offset(offset), m_size(size), m_value(value),
+ m_result(result) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- lldb::tid_t m_tid;
- unsigned m_offset;
- unsigned m_size;
- RegisterValue &m_value;
- bool &m_result;
+ lldb::tid_t m_tid;
+ unsigned m_offset;
+ unsigned m_size;
+ RegisterValue &m_value;
+ bool &m_result;
};
-void
-ReadRegOperation::Execute(ProcessMonitor *monitor)
-{
- struct reg regs;
- int rc;
-
- if ((rc = PTRACE(PT_GETREGS, m_tid, (caddr_t)&regs, 0)) < 0) {
- m_result = false;
- } else {
- // 'struct reg' contains only 32- or 64-bit register values. Punt on
- // others. Also, not all entries may be uintptr_t sized, such as 32-bit
- // processes on powerpc64 (probably the same for i386 on amd64)
- if (m_size == sizeof(uint32_t))
- m_value = *(uint32_t *)(((caddr_t)&regs) + m_offset);
- else if (m_size == sizeof(uint64_t))
- m_value = *(uint64_t *)(((caddr_t)&regs) + m_offset);
- else
- memcpy((void *)&m_value, (((caddr_t)&regs) + m_offset), m_size);
- m_result = true;
- }
+void ReadRegOperation::Execute(ProcessMonitor *monitor) {
+ struct reg regs;
+ int rc;
+
+ if ((rc = PTRACE(PT_GETREGS, m_tid, (caddr_t)&regs, 0)) < 0) {
+ m_result = false;
+ } else {
+ // 'struct reg' contains only 32- or 64-bit register values. Punt on
+ // others. Also, not all entries may be uintptr_t sized, such as 32-bit
+ // processes on powerpc64 (probably the same for i386 on amd64)
+ if (m_size == sizeof(uint32_t))
+ m_value = *(uint32_t *)(((caddr_t)&regs) + m_offset);
+ else if (m_size == sizeof(uint64_t))
+ m_value = *(uint64_t *)(((caddr_t)&regs) + m_offset);
+ else
+ memcpy((void *)&m_value, (((caddr_t)&regs) + m_offset), m_size);
+ m_result = true;
+ }
}
//------------------------------------------------------------------------------
/// @class WriteRegOperation
/// @brief Implements ProcessMonitor::WriteRegisterValue.
-class WriteRegOperation : public Operation
-{
+class WriteRegOperation : public Operation {
public:
- WriteRegOperation(lldb::tid_t tid, unsigned offset,
- const RegisterValue &value, bool &result)
- : m_tid(tid), m_offset(offset),
- m_value(value), m_result(result)
- { }
+ WriteRegOperation(lldb::tid_t tid, unsigned offset,
+ const RegisterValue &value, bool &result)
+ : m_tid(tid), m_offset(offset), m_value(value), m_result(result) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- lldb::tid_t m_tid;
- unsigned m_offset;
- const RegisterValue &m_value;
- bool &m_result;
+ lldb::tid_t m_tid;
+ unsigned m_offset;
+ const RegisterValue &m_value;
+ bool &m_result;
};
-void
-WriteRegOperation::Execute(ProcessMonitor *monitor)
-{
- struct reg regs;
+void WriteRegOperation::Execute(ProcessMonitor *monitor) {
+ struct reg regs;
- if (PTRACE(PT_GETREGS, m_tid, (caddr_t)&regs, 0) < 0) {
- m_result = false;
- return;
- }
- *(uintptr_t *)(((caddr_t)&regs) + m_offset) = (uintptr_t)m_value.GetAsUInt64();
- if (PTRACE(PT_SETREGS, m_tid, (caddr_t)&regs, 0) < 0)
- m_result = false;
- else
- m_result = true;
+ if (PTRACE(PT_GETREGS, m_tid, (caddr_t)&regs, 0) < 0) {
+ m_result = false;
+ return;
+ }
+ *(uintptr_t *)(((caddr_t)&regs) + m_offset) =
+ (uintptr_t)m_value.GetAsUInt64();
+ if (PTRACE(PT_SETREGS, m_tid, (caddr_t)&regs, 0) < 0)
+ m_result = false;
+ else
+ m_result = true;
}
//------------------------------------------------------------------------------
/// @class ReadDebugRegOperation
/// @brief Implements ProcessMonitor::ReadDebugRegisterValue.
-class ReadDebugRegOperation : public Operation
-{
+class ReadDebugRegOperation : public Operation {
public:
- ReadDebugRegOperation(lldb::tid_t tid, unsigned offset, unsigned size,
- RegisterValue &value, bool &result)
- : m_tid(tid), m_offset(offset), m_size(size),
- m_value(value), m_result(result)
- { }
+ ReadDebugRegOperation(lldb::tid_t tid, unsigned offset, unsigned size,
+ RegisterValue &value, bool &result)
+ : m_tid(tid), m_offset(offset), m_size(size), m_value(value),
+ m_result(result) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- lldb::tid_t m_tid;
- unsigned m_offset;
- unsigned m_size;
- RegisterValue &m_value;
- bool &m_result;
+ lldb::tid_t m_tid;
+ unsigned m_offset;
+ unsigned m_size;
+ RegisterValue &m_value;
+ bool &m_result;
};
-void
-ReadDebugRegOperation::Execute(ProcessMonitor *monitor)
-{
- struct dbreg regs;
- int rc;
-
- if ((rc = PTRACE(PT_GETDBREGS, m_tid, (caddr_t)&regs, 0)) < 0) {
- m_result = false;
- } else {
- if (m_size == sizeof(uintptr_t))
- m_value = *(uintptr_t *)(((caddr_t)&regs) + m_offset);
- else
- memcpy((void *)&m_value, (((caddr_t)&regs) + m_offset), m_size);
- m_result = true;
- }
+void ReadDebugRegOperation::Execute(ProcessMonitor *monitor) {
+ struct dbreg regs;
+ int rc;
+
+ if ((rc = PTRACE(PT_GETDBREGS, m_tid, (caddr_t)&regs, 0)) < 0) {
+ m_result = false;
+ } else {
+ if (m_size == sizeof(uintptr_t))
+ m_value = *(uintptr_t *)(((caddr_t)&regs) + m_offset);
+ else
+ memcpy((void *)&m_value, (((caddr_t)&regs) + m_offset), m_size);
+ m_result = true;
+ }
}
//------------------------------------------------------------------------------
/// @class WriteDebugRegOperation
/// @brief Implements ProcessMonitor::WriteDebugRegisterValue.
-class WriteDebugRegOperation : public Operation
-{
+class WriteDebugRegOperation : public Operation {
public:
- WriteDebugRegOperation(lldb::tid_t tid, unsigned offset,
- const RegisterValue &value, bool &result)
- : m_tid(tid), m_offset(offset),
- m_value(value), m_result(result)
- { }
+ WriteDebugRegOperation(lldb::tid_t tid, unsigned offset,
+ const RegisterValue &value, bool &result)
+ : m_tid(tid), m_offset(offset), m_value(value), m_result(result) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- lldb::tid_t m_tid;
- unsigned m_offset;
- const RegisterValue &m_value;
- bool &m_result;
+ lldb::tid_t m_tid;
+ unsigned m_offset;
+ const RegisterValue &m_value;
+ bool &m_result;
};
-void
-WriteDebugRegOperation::Execute(ProcessMonitor *monitor)
-{
- struct dbreg regs;
+void WriteDebugRegOperation::Execute(ProcessMonitor *monitor) {
+ struct dbreg regs;
- if (PTRACE(PT_GETDBREGS, m_tid, (caddr_t)&regs, 0) < 0) {
- m_result = false;
- return;
- }
- *(uintptr_t *)(((caddr_t)&regs) + m_offset) = (uintptr_t)m_value.GetAsUInt64();
- if (PTRACE(PT_SETDBREGS, m_tid, (caddr_t)&regs, 0) < 0)
- m_result = false;
- else
- m_result = true;
+ if (PTRACE(PT_GETDBREGS, m_tid, (caddr_t)&regs, 0) < 0) {
+ m_result = false;
+ return;
+ }
+ *(uintptr_t *)(((caddr_t)&regs) + m_offset) =
+ (uintptr_t)m_value.GetAsUInt64();
+ if (PTRACE(PT_SETDBREGS, m_tid, (caddr_t)&regs, 0) < 0)
+ m_result = false;
+ else
+ m_result = true;
}
//------------------------------------------------------------------------------
/// @class ReadGPROperation
/// @brief Implements ProcessMonitor::ReadGPR.
-class ReadGPROperation : public Operation
-{
+class ReadGPROperation : public Operation {
public:
- ReadGPROperation(lldb::tid_t tid, void *buf, bool &result)
- : m_tid(tid), m_buf(buf), m_result(result)
- { }
+ ReadGPROperation(lldb::tid_t tid, void *buf, bool &result)
+ : m_tid(tid), m_buf(buf), m_result(result) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- lldb::tid_t m_tid;
- void *m_buf;
- bool &m_result;
+ lldb::tid_t m_tid;
+ void *m_buf;
+ bool &m_result;
};
-void
-ReadGPROperation::Execute(ProcessMonitor *monitor)
-{
- int rc;
+void ReadGPROperation::Execute(ProcessMonitor *monitor) {
+ int rc;
- errno = 0;
- rc = PTRACE(PT_GETREGS, m_tid, (caddr_t)m_buf, 0);
- if (errno != 0)
- m_result = false;
- else
- m_result = true;
+ errno = 0;
+ rc = PTRACE(PT_GETREGS, m_tid, (caddr_t)m_buf, 0);
+ if (errno != 0)
+ m_result = false;
+ else
+ m_result = true;
}
//------------------------------------------------------------------------------
/// @class ReadFPROperation
/// @brief Implements ProcessMonitor::ReadFPR.
-class ReadFPROperation : public Operation
-{
+class ReadFPROperation : public Operation {
public:
- ReadFPROperation(lldb::tid_t tid, void *buf, bool &result)
- : m_tid(tid), m_buf(buf), m_result(result)
- { }
+ ReadFPROperation(lldb::tid_t tid, void *buf, bool &result)
+ : m_tid(tid), m_buf(buf), m_result(result) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- lldb::tid_t m_tid;
- void *m_buf;
- bool &m_result;
+ lldb::tid_t m_tid;
+ void *m_buf;
+ bool &m_result;
};
-void
-ReadFPROperation::Execute(ProcessMonitor *monitor)
-{
- if (PTRACE(PT_GETFPREGS, m_tid, (caddr_t)m_buf, 0) < 0)
- m_result = false;
- else
- m_result = true;
+void ReadFPROperation::Execute(ProcessMonitor *monitor) {
+ if (PTRACE(PT_GETFPREGS, m_tid, (caddr_t)m_buf, 0) < 0)
+ m_result = false;
+ else
+ m_result = true;
}
//------------------------------------------------------------------------------
/// @class WriteGPROperation
/// @brief Implements ProcessMonitor::WriteGPR.
-class WriteGPROperation : public Operation
-{
+class WriteGPROperation : public Operation {
public:
- WriteGPROperation(lldb::tid_t tid, void *buf, bool &result)
- : m_tid(tid), m_buf(buf), m_result(result)
- { }
+ WriteGPROperation(lldb::tid_t tid, void *buf, bool &result)
+ : m_tid(tid), m_buf(buf), m_result(result) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- lldb::tid_t m_tid;
- void *m_buf;
- bool &m_result;
+ lldb::tid_t m_tid;
+ void *m_buf;
+ bool &m_result;
};
-void
-WriteGPROperation::Execute(ProcessMonitor *monitor)
-{
- if (PTRACE(PT_SETREGS, m_tid, (caddr_t)m_buf, 0) < 0)
- m_result = false;
- else
- m_result = true;
+void WriteGPROperation::Execute(ProcessMonitor *monitor) {
+ if (PTRACE(PT_SETREGS, m_tid, (caddr_t)m_buf, 0) < 0)
+ m_result = false;
+ else
+ m_result = true;
}
//------------------------------------------------------------------------------
/// @class WriteFPROperation
/// @brief Implements ProcessMonitor::WriteFPR.
-class WriteFPROperation : public Operation
-{
+class WriteFPROperation : public Operation {
public:
- WriteFPROperation(lldb::tid_t tid, void *buf, bool &result)
- : m_tid(tid), m_buf(buf), m_result(result)
- { }
+ WriteFPROperation(lldb::tid_t tid, void *buf, bool &result)
+ : m_tid(tid), m_buf(buf), m_result(result) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- lldb::tid_t m_tid;
- void *m_buf;
- bool &m_result;
+ lldb::tid_t m_tid;
+ void *m_buf;
+ bool &m_result;
};
-void
-WriteFPROperation::Execute(ProcessMonitor *monitor)
-{
- if (PTRACE(PT_SETFPREGS, m_tid, (caddr_t)m_buf, 0) < 0)
- m_result = false;
- else
- m_result = true;
+void WriteFPROperation::Execute(ProcessMonitor *monitor) {
+ if (PTRACE(PT_SETFPREGS, m_tid, (caddr_t)m_buf, 0) < 0)
+ m_result = false;
+ else
+ m_result = true;
}
//------------------------------------------------------------------------------
/// @class ResumeOperation
/// @brief Implements ProcessMonitor::Resume.
-class ResumeOperation : public Operation
-{
+class ResumeOperation : public Operation {
public:
- ResumeOperation(uint32_t signo, bool &result) :
- m_signo(signo), m_result(result) { }
+ ResumeOperation(uint32_t signo, bool &result)
+ : m_signo(signo), m_result(result) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- uint32_t m_signo;
- bool &m_result;
+ uint32_t m_signo;
+ bool &m_result;
};
-void
-ResumeOperation::Execute(ProcessMonitor *monitor)
-{
- lldb::pid_t pid = monitor->GetPID();
- int data = 0;
+void ResumeOperation::Execute(ProcessMonitor *monitor) {
+ lldb::pid_t pid = monitor->GetPID();
+ int data = 0;
- if (m_signo != LLDB_INVALID_SIGNAL_NUMBER)
- data = m_signo;
+ if (m_signo != LLDB_INVALID_SIGNAL_NUMBER)
+ data = m_signo;
- if (PTRACE(PT_CONTINUE, pid, (caddr_t)1, data))
- {
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
+ if (PTRACE(PT_CONTINUE, pid, (caddr_t)1, data)) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- if (log)
- log->Printf ("ResumeOperation (%" PRIu64 ") failed: %s", pid, strerror(errno));
- m_result = false;
- }
- else
- m_result = true;
+ if (log)
+ log->Printf("ResumeOperation (%" PRIu64 ") failed: %s", pid,
+ strerror(errno));
+ m_result = false;
+ } else
+ m_result = true;
}
//------------------------------------------------------------------------------
/// @class SingleStepOperation
/// @brief Implements ProcessMonitor::SingleStep.
-class SingleStepOperation : public Operation
-{
+class SingleStepOperation : public Operation {
public:
- SingleStepOperation(uint32_t signo, bool &result)
- : m_signo(signo), m_result(result) { }
+ SingleStepOperation(uint32_t signo, bool &result)
+ : m_signo(signo), m_result(result) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- uint32_t m_signo;
- bool &m_result;
+ uint32_t m_signo;
+ bool &m_result;
};
-void
-SingleStepOperation::Execute(ProcessMonitor *monitor)
-{
- lldb::pid_t pid = monitor->GetPID();
- int data = 0;
+void SingleStepOperation::Execute(ProcessMonitor *monitor) {
+ lldb::pid_t pid = monitor->GetPID();
+ int data = 0;
- if (m_signo != LLDB_INVALID_SIGNAL_NUMBER)
- data = m_signo;
+ if (m_signo != LLDB_INVALID_SIGNAL_NUMBER)
+ data = m_signo;
- if (PTRACE(PT_STEP, pid, NULL, data))
- m_result = false;
- else
- m_result = true;
+ if (PTRACE(PT_STEP, pid, NULL, data))
+ m_result = false;
+ else
+ m_result = true;
}
//------------------------------------------------------------------------------
/// @class LwpInfoOperation
/// @brief Implements ProcessMonitor::GetLwpInfo.
-class LwpInfoOperation : public Operation
-{
+class LwpInfoOperation : public Operation {
public:
- LwpInfoOperation(lldb::tid_t tid, void *info, bool &result, int &ptrace_err)
- : m_tid(tid), m_info(info), m_result(result), m_err(ptrace_err) { }
+ LwpInfoOperation(lldb::tid_t tid, void *info, bool &result, int &ptrace_err)
+ : m_tid(tid), m_info(info), m_result(result), m_err(ptrace_err) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- lldb::tid_t m_tid;
- void *m_info;
- bool &m_result;
- int &m_err;
+ lldb::tid_t m_tid;
+ void *m_info;
+ bool &m_result;
+ int &m_err;
};
-void
-LwpInfoOperation::Execute(ProcessMonitor *monitor)
-{
- struct ptrace_lwpinfo plwp;
-
- if (PTRACE(PT_LWPINFO, m_tid, (caddr_t)&plwp, sizeof(plwp))) {
- m_result = false;
- m_err = errno;
- } else {
- memcpy(m_info, &plwp, sizeof(plwp));
- m_result = true;
- }
+void LwpInfoOperation::Execute(ProcessMonitor *monitor) {
+ struct ptrace_lwpinfo plwp;
+
+ if (PTRACE(PT_LWPINFO, m_tid, (caddr_t)&plwp, sizeof(plwp))) {
+ m_result = false;
+ m_err = errno;
+ } else {
+ memcpy(m_info, &plwp, sizeof(plwp));
+ m_result = true;
+ }
}
//------------------------------------------------------------------------------
/// @class ThreadSuspendOperation
/// @brief Implements ProcessMonitor::ThreadSuspend.
-class ThreadSuspendOperation : public Operation
-{
+class ThreadSuspendOperation : public Operation {
public:
- ThreadSuspendOperation(lldb::tid_t tid, bool suspend, bool &result)
- : m_tid(tid), m_suspend(suspend), m_result(result) { }
+ ThreadSuspendOperation(lldb::tid_t tid, bool suspend, bool &result)
+ : m_tid(tid), m_suspend(suspend), m_result(result) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- lldb::tid_t m_tid;
- bool m_suspend;
- bool &m_result;
-} ;
-
-void
-ThreadSuspendOperation::Execute(ProcessMonitor *monitor)
-{
- m_result = !PTRACE(m_suspend ? PT_SUSPEND : PT_RESUME, m_tid, NULL, 0);
-}
-
+ lldb::tid_t m_tid;
+ bool m_suspend;
+ bool &m_result;
+};
+void ThreadSuspendOperation::Execute(ProcessMonitor *monitor) {
+ m_result = !PTRACE(m_suspend ? PT_SUSPEND : PT_RESUME, m_tid, NULL, 0);
+}
//------------------------------------------------------------------------------
/// @class EventMessageOperation
/// @brief Implements ProcessMonitor::GetEventMessage.
-class EventMessageOperation : public Operation
-{
+class EventMessageOperation : public Operation {
public:
- EventMessageOperation(lldb::tid_t tid, unsigned long *message, bool &result)
- : m_tid(tid), m_message(message), m_result(result) { }
+ EventMessageOperation(lldb::tid_t tid, unsigned long *message, bool &result)
+ : m_tid(tid), m_message(message), m_result(result) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- lldb::tid_t m_tid;
- unsigned long *m_message;
- bool &m_result;
+ lldb::tid_t m_tid;
+ unsigned long *m_message;
+ bool &m_result;
};
-void
-EventMessageOperation::Execute(ProcessMonitor *monitor)
-{
- struct ptrace_lwpinfo plwp;
+void EventMessageOperation::Execute(ProcessMonitor *monitor) {
+ struct ptrace_lwpinfo plwp;
- if (PTRACE(PT_LWPINFO, m_tid, (caddr_t)&plwp, sizeof(plwp)))
- m_result = false;
- else {
- if (plwp.pl_flags & PL_FLAG_FORKED) {
- *m_message = plwp.pl_child_pid;
- m_result = true;
- } else
- m_result = false;
- }
+ if (PTRACE(PT_LWPINFO, m_tid, (caddr_t)&plwp, sizeof(plwp)))
+ m_result = false;
+ else {
+ if (plwp.pl_flags & PL_FLAG_FORKED) {
+ *m_message = plwp.pl_child_pid;
+ m_result = true;
+ } else
+ m_result = false;
+ }
}
//------------------------------------------------------------------------------
/// @class KillOperation
/// @brief Implements ProcessMonitor::Kill.
-class KillOperation : public Operation
-{
+class KillOperation : public Operation {
public:
- KillOperation(bool &result) : m_result(result) { }
+ KillOperation(bool &result) : m_result(result) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- bool &m_result;
+ bool &m_result;
};
-void
-KillOperation::Execute(ProcessMonitor *monitor)
-{
- lldb::pid_t pid = monitor->GetPID();
+void KillOperation::Execute(ProcessMonitor *monitor) {
+ lldb::pid_t pid = monitor->GetPID();
- if (PTRACE(PT_KILL, pid, NULL, 0))
- m_result = false;
- else
- m_result = true;
+ if (PTRACE(PT_KILL, pid, NULL, 0))
+ m_result = false;
+ else
+ m_result = true;
}
//------------------------------------------------------------------------------
/// @class DetachOperation
/// @brief Implements ProcessMonitor::Detach.
-class DetachOperation : public Operation
-{
+class DetachOperation : public Operation {
public:
- DetachOperation(Error &result) : m_error(result) { }
+ DetachOperation(Error &result) : m_error(result) {}
- void Execute(ProcessMonitor *monitor);
+ void Execute(ProcessMonitor *monitor);
private:
- Error &m_error;
+ Error &m_error;
};
-void
-DetachOperation::Execute(ProcessMonitor *monitor)
-{
- lldb::pid_t pid = monitor->GetPID();
+void DetachOperation::Execute(ProcessMonitor *monitor) {
+ lldb::pid_t pid = monitor->GetPID();
- if (PTRACE(PT_DETACH, pid, NULL, 0) < 0)
- m_error.SetErrorToErrno();
-
+ if (PTRACE(PT_DETACH, pid, NULL, 0) < 0)
+ m_error.SetErrorToErrno();
}
ProcessMonitor::OperationArgs::OperationArgs(ProcessMonitor *monitor)
- : m_monitor(monitor)
-{
- sem_init(&m_semaphore, 0, 0);
+ : m_monitor(monitor) {
+ sem_init(&m_semaphore, 0, 0);
}
-ProcessMonitor::OperationArgs::~OperationArgs()
-{
- sem_destroy(&m_semaphore);
-}
+ProcessMonitor::OperationArgs::~OperationArgs() { sem_destroy(&m_semaphore); }
ProcessMonitor::LaunchArgs::LaunchArgs(ProcessMonitor *monitor,
lldb_private::Module *module,
- char const **argv,
- char const **envp,
+ char const **argv, char const **envp,
const FileSpec &stdin_file_spec,
const FileSpec &stdout_file_spec,
const FileSpec &stderr_file_spec,
const FileSpec &working_dir)
- : OperationArgs(monitor),
- m_module(module),
- m_argv(argv),
- m_envp(envp),
- m_stdin_file_spec(stdin_file_spec),
- m_stdout_file_spec(stdout_file_spec),
- m_stderr_file_spec(stderr_file_spec),
- m_working_dir(working_dir) { }
+ : OperationArgs(monitor), m_module(module), m_argv(argv), m_envp(envp),
+ m_stdin_file_spec(stdin_file_spec), m_stdout_file_spec(stdout_file_spec),
+ m_stderr_file_spec(stderr_file_spec), m_working_dir(working_dir) {}
-ProcessMonitor::LaunchArgs::~LaunchArgs()
-{ }
+ProcessMonitor::LaunchArgs::~LaunchArgs() {}
-ProcessMonitor::AttachArgs::AttachArgs(ProcessMonitor *monitor,
- lldb::pid_t pid)
- : OperationArgs(monitor), m_pid(pid) { }
+ProcessMonitor::AttachArgs::AttachArgs(ProcessMonitor *monitor, lldb::pid_t pid)
+ : OperationArgs(monitor), m_pid(pid) {}
-ProcessMonitor::AttachArgs::~AttachArgs()
-{ }
+ProcessMonitor::AttachArgs::~AttachArgs() {}
//------------------------------------------------------------------------------
/// The basic design of the ProcessMonitor is built around two threads.
///
/// One thread (@see SignalThread) simply blocks on a call to waitpid() looking
/// for changes in the debugee state. When a change is detected a
-/// ProcessMessage is sent to the associated ProcessFreeBSD instance. This thread
+/// ProcessMessage is sent to the associated ProcessFreeBSD instance. This
+/// thread
/// "drives" state changes in the debugger.
///
/// The second thread (@see OperationThread) is responsible for two things 1)
/// launching or attaching to the inferior process, and then 2) servicing
/// operations such as register reads/writes, stepping, etc. See the comments
/// on the Operation class for more info as to why this is needed.
-ProcessMonitor::ProcessMonitor(ProcessFreeBSD *process,
- Module *module,
- const char *argv[],
- const char *envp[],
- const FileSpec &stdin_file_spec,
- const FileSpec &stdout_file_spec,
- const FileSpec &stderr_file_spec,
- const FileSpec &working_dir,
- const lldb_private::ProcessLaunchInfo & /* launch_info */,
- lldb_private::Error &error)
+ProcessMonitor::ProcessMonitor(
+ ProcessFreeBSD *process, Module *module, const char *argv[],
+ const char *envp[], const FileSpec &stdin_file_spec,
+ const FileSpec &stdout_file_spec, const FileSpec &stderr_file_spec,
+ const FileSpec &working_dir,
+ const lldb_private::ProcessLaunchInfo & /* launch_info */,
+ lldb_private::Error &error)
: m_process(static_cast<ProcessFreeBSD *>(process)),
- m_pid(LLDB_INVALID_PROCESS_ID),
- m_terminal_fd(-1),
- m_operation(0)
-{
- using namespace std::placeholders;
-
- std::unique_ptr<LaunchArgs> args(new LaunchArgs(this, module, argv, envp,
- stdin_file_spec,
- stdout_file_spec,
- stderr_file_spec,
- working_dir));
-
-
- sem_init(&m_operation_pending, 0, 0);
- sem_init(&m_operation_done, 0, 0);
-
- StartLaunchOpThread(args.get(), error);
- if (!error.Success())
- return;
+ m_pid(LLDB_INVALID_PROCESS_ID), m_terminal_fd(-1), m_operation(0) {
+ using namespace std::placeholders;
-WAIT_AGAIN:
- // Wait for the operation thread to initialize.
- if (sem_wait(&args->m_semaphore))
- {
- if (errno == EINTR)
- goto WAIT_AGAIN;
- else
- {
- error.SetErrorToErrno();
- return;
- }
- }
+ std::unique_ptr<LaunchArgs> args(
+ new LaunchArgs(this, module, argv, envp, stdin_file_spec,
+ stdout_file_spec, stderr_file_spec, working_dir));
- // Check that the launch was a success.
- if (!args->m_error.Success())
- {
- StopOpThread();
- error = args->m_error;
- return;
- }
+ sem_init(&m_operation_pending, 0, 0);
+ sem_init(&m_operation_done, 0, 0);
+
+ StartLaunchOpThread(args.get(), error);
+ if (!error.Success())
+ return;
- // Finally, start monitoring the child process for change in state.
- m_monitor_thread = Host::StartMonitoringChildProcess(
- std::bind(&ProcessMonitor::MonitorCallback, this, _1, _2, _3, _4), GetPID(), true);
- if (!m_monitor_thread.IsJoinable())
- {
- error.SetErrorToGenericError();
- error.SetErrorString("Process launch failed.");
- return;
+WAIT_AGAIN:
+ // Wait for the operation thread to initialize.
+ if (sem_wait(&args->m_semaphore)) {
+ if (errno == EINTR)
+ goto WAIT_AGAIN;
+ else {
+ error.SetErrorToErrno();
+ return;
}
-}
+ }
-ProcessMonitor::ProcessMonitor(ProcessFreeBSD *process,
- lldb::pid_t pid,
+ // Check that the launch was a success.
+ if (!args->m_error.Success()) {
+ StopOpThread();
+ error = args->m_error;
+ return;
+ }
+
+ // Finally, start monitoring the child process for change in state.
+ m_monitor_thread = Host::StartMonitoringChildProcess(
+ std::bind(&ProcessMonitor::MonitorCallback, this, _1, _2, _3, _4),
+ GetPID(), true);
+ if (!m_monitor_thread.IsJoinable()) {
+ error.SetErrorToGenericError();
+ error.SetErrorString("Process launch failed.");
+ return;
+ }
+}
+
+ProcessMonitor::ProcessMonitor(ProcessFreeBSD *process, lldb::pid_t pid,
lldb_private::Error &error)
- : m_process(static_cast<ProcessFreeBSD *>(process)),
- m_pid(pid),
- m_terminal_fd(-1),
- m_operation(0)
-{
- using namespace std::placeholders;
-
- sem_init(&m_operation_pending, 0, 0);
- sem_init(&m_operation_done, 0, 0);
+ : m_process(static_cast<ProcessFreeBSD *>(process)), m_pid(pid),
+ m_terminal_fd(-1), m_operation(0) {
+ using namespace std::placeholders;
+ sem_init(&m_operation_pending, 0, 0);
+ sem_init(&m_operation_done, 0, 0);
- std::unique_ptr<AttachArgs> args(new AttachArgs(this, pid));
+ std::unique_ptr<AttachArgs> args(new AttachArgs(this, pid));
- StartAttachOpThread(args.get(), error);
- if (!error.Success())
- return;
+ StartAttachOpThread(args.get(), error);
+ if (!error.Success())
+ return;
WAIT_AGAIN:
- // Wait for the operation thread to initialize.
- if (sem_wait(&args->m_semaphore))
- {
- if (errno == EINTR)
- goto WAIT_AGAIN;
- else
- {
- error.SetErrorToErrno();
- return;
- }
+ // Wait for the operation thread to initialize.
+ if (sem_wait(&args->m_semaphore)) {
+ if (errno == EINTR)
+ goto WAIT_AGAIN;
+ else {
+ error.SetErrorToErrno();
+ return;
}
+ }
- // Check that the attach was a success.
- if (!args->m_error.Success())
- {
- StopOpThread();
- error = args->m_error;
- return;
- }
+ // Check that the attach was a success.
+ if (!args->m_error.Success()) {
+ StopOpThread();
+ error = args->m_error;
+ return;
+ }
- // Finally, start monitoring the child process for change in state.
- m_monitor_thread = Host::StartMonitoringChildProcess(
- std::bind(&ProcessMonitor::MonitorCallback, this, _1, _2, _3, _4), GetPID(), true);
- if (!m_monitor_thread.IsJoinable())
- {
- error.SetErrorToGenericError();
- error.SetErrorString("Process attach failed.");
- return;
- }
+ // Finally, start monitoring the child process for change in state.
+ m_monitor_thread = Host::StartMonitoringChildProcess(
+ std::bind(&ProcessMonitor::MonitorCallback, this, _1, _2, _3, _4),
+ GetPID(), true);
+ if (!m_monitor_thread.IsJoinable()) {
+ error.SetErrorToGenericError();
+ error.SetErrorString("Process attach failed.");
+ return;
+ }
}
-ProcessMonitor::~ProcessMonitor()
-{
- StopMonitor();
-}
+ProcessMonitor::~ProcessMonitor() { StopMonitor(); }
//------------------------------------------------------------------------------
// Thread setup and tear down.
-void
-ProcessMonitor::StartLaunchOpThread(LaunchArgs *args, Error &error)
-{
- static const char *g_thread_name = "lldb.process.freebsd.operation";
+void ProcessMonitor::StartLaunchOpThread(LaunchArgs *args, Error &error) {
+ static const char *g_thread_name = "lldb.process.freebsd.operation";
- if (m_operation_thread.IsJoinable())
- return;
+ if (m_operation_thread.IsJoinable())
+ return;
- m_operation_thread = ThreadLauncher::LaunchThread(g_thread_name, LaunchOpThread, args, &error);
+ m_operation_thread =
+ ThreadLauncher::LaunchThread(g_thread_name, LaunchOpThread, args, &error);
}
-void *
-ProcessMonitor::LaunchOpThread(void *arg)
-{
- LaunchArgs *args = static_cast<LaunchArgs*>(arg);
+void *ProcessMonitor::LaunchOpThread(void *arg) {
+ LaunchArgs *args = static_cast<LaunchArgs *>(arg);
- if (!Launch(args)) {
- sem_post(&args->m_semaphore);
- return NULL;
- }
-
- ServeOperation(args);
+ if (!Launch(args)) {
+ sem_post(&args->m_semaphore);
return NULL;
-}
-
-bool
-ProcessMonitor::Launch(LaunchArgs *args)
-{
- ProcessMonitor *monitor = args->m_monitor;
- ProcessFreeBSD &process = monitor->GetProcess();
- const char **argv = args->m_argv;
- const char **envp = args->m_envp;
- const FileSpec &stdin_file_spec = args->m_stdin_file_spec;
- const FileSpec &stdout_file_spec = args->m_stdout_file_spec;
- const FileSpec &stderr_file_spec = args->m_stderr_file_spec;
- const FileSpec &working_dir = args->m_working_dir;
-
- lldb_utility::PseudoTerminal terminal;
- const size_t err_len = 1024;
- char err_str[err_len];
- ::pid_t pid;
-
- // Propagate the environment if one is not supplied.
- if (envp == NULL || envp[0] == NULL)
- envp = const_cast<const char **>(environ);
-
- if ((pid = terminal.Fork(err_str, err_len)) == -1)
- {
- args->m_error.SetErrorToGenericError();
- args->m_error.SetErrorString("Process fork failed.");
- goto FINISH;
- }
-
- // Recognized child exit status codes.
- enum {
- ePtraceFailed = 1,
- eDupStdinFailed,
- eDupStdoutFailed,
- eDupStderrFailed,
- eChdirFailed,
- eExecFailed,
- eSetGidFailed
- };
-
- // Child process.
- if (pid == 0)
- {
- // Trace this process.
- if (PTRACE(PT_TRACE_ME, 0, NULL, 0) < 0)
- exit(ePtraceFailed);
-
- // terminal has already dupped the tty descriptors to stdin/out/err.
- // This closes original fd from which they were copied (and avoids
- // leaking descriptors to the debugged process.
- terminal.CloseSlaveFileDescriptor();
-
- // Do not inherit setgid powers.
- if (setgid(getgid()) != 0)
- exit(eSetGidFailed);
-
- // Let us have our own process group.
- setpgid(0, 0);
-
- // Dup file descriptors if needed.
- //
- // FIXME: If two or more of the paths are the same we needlessly open
- // the same file multiple times.
- if (stdin_file_spec)
- if (!DupDescriptor(stdin_file_spec, STDIN_FILENO, O_RDONLY))
- exit(eDupStdinFailed);
-
- if (stdout_file_spec)
- if (!DupDescriptor(stdout_file_spec, STDOUT_FILENO, O_WRONLY | O_CREAT))
- exit(eDupStdoutFailed);
-
- if (stderr_file_spec)
- if (!DupDescriptor(stderr_file_spec, STDERR_FILENO, O_WRONLY | O_CREAT))
- exit(eDupStderrFailed);
-
- // Change working directory
- if (working_dir && 0 != ::chdir(working_dir.GetCString()))
- exit(eChdirFailed);
-
- // Execute. We should never return.
- execve(argv[0],
- const_cast<char *const *>(argv),
- const_cast<char *const *>(envp));
- exit(eExecFailed);
- }
-
- // Wait for the child process to to trap on its call to execve.
- ::pid_t wpid;
- int status;
- if ((wpid = waitpid(pid, &status, 0)) < 0)
- {
- args->m_error.SetErrorToErrno();
- goto FINISH;
- }
- else if (WIFEXITED(status))
- {
- // open, dup or execve likely failed for some reason.
- args->m_error.SetErrorToGenericError();
- switch (WEXITSTATUS(status))
- {
- case ePtraceFailed:
- args->m_error.SetErrorString("Child ptrace failed.");
- break;
- case eDupStdinFailed:
- args->m_error.SetErrorString("Child open stdin failed.");
- break;
- case eDupStdoutFailed:
- args->m_error.SetErrorString("Child open stdout failed.");
- break;
- case eDupStderrFailed:
- args->m_error.SetErrorString("Child open stderr failed.");
- break;
- case eChdirFailed:
- args->m_error.SetErrorString("Child failed to set working directory.");
- break;
- case eExecFailed:
- args->m_error.SetErrorString("Child exec failed.");
- break;
- case eSetGidFailed:
- args->m_error.SetErrorString("Child setgid failed.");
- break;
- default:
- args->m_error.SetErrorString("Child returned unknown exit status.");
- break;
- }
- goto FINISH;
+ }
+
+ ServeOperation(args);
+ return NULL;
+}
+
+bool ProcessMonitor::Launch(LaunchArgs *args) {
+ ProcessMonitor *monitor = args->m_monitor;
+ ProcessFreeBSD &process = monitor->GetProcess();
+ const char **argv = args->m_argv;
+ const char **envp = args->m_envp;
+ const FileSpec &stdin_file_spec = args->m_stdin_file_spec;
+ const FileSpec &stdout_file_spec = args->m_stdout_file_spec;
+ const FileSpec &stderr_file_spec = args->m_stderr_file_spec;
+ const FileSpec &working_dir = args->m_working_dir;
+
+ lldb_utility::PseudoTerminal terminal;
+ const size_t err_len = 1024;
+ char err_str[err_len];
+ ::pid_t pid;
+
+ // Propagate the environment if one is not supplied.
+ if (envp == NULL || envp[0] == NULL)
+ envp = const_cast<const char **>(environ);
+
+ if ((pid = terminal.Fork(err_str, err_len)) == -1) {
+ args->m_error.SetErrorToGenericError();
+ args->m_error.SetErrorString("Process fork failed.");
+ goto FINISH;
+ }
+
+ // Recognized child exit status codes.
+ enum {
+ ePtraceFailed = 1,
+ eDupStdinFailed,
+ eDupStdoutFailed,
+ eDupStderrFailed,
+ eChdirFailed,
+ eExecFailed,
+ eSetGidFailed
+ };
+
+ // Child process.
+ if (pid == 0) {
+ // Trace this process.
+ if (PTRACE(PT_TRACE_ME, 0, NULL, 0) < 0)
+ exit(ePtraceFailed);
+
+ // terminal has already dupped the tty descriptors to stdin/out/err.
+ // This closes original fd from which they were copied (and avoids
+ // leaking descriptors to the debugged process.
+ terminal.CloseSlaveFileDescriptor();
+
+ // Do not inherit setgid powers.
+ if (setgid(getgid()) != 0)
+ exit(eSetGidFailed);
+
+ // Let us have our own process group.
+ setpgid(0, 0);
+
+ // Dup file descriptors if needed.
+ //
+ // FIXME: If two or more of the paths are the same we needlessly open
+ // the same file multiple times.
+ if (stdin_file_spec)
+ if (!DupDescriptor(stdin_file_spec, STDIN_FILENO, O_RDONLY))
+ exit(eDupStdinFailed);
+
+ if (stdout_file_spec)
+ if (!DupDescriptor(stdout_file_spec, STDOUT_FILENO, O_WRONLY | O_CREAT))
+ exit(eDupStdoutFailed);
+
+ if (stderr_file_spec)
+ if (!DupDescriptor(stderr_file_spec, STDERR_FILENO, O_WRONLY | O_CREAT))
+ exit(eDupStderrFailed);
+
+ // Change working directory
+ if (working_dir && 0 != ::chdir(working_dir.GetCString()))
+ exit(eChdirFailed);
+
+ // Execute. We should never return.
+ execve(argv[0], const_cast<char *const *>(argv),
+ const_cast<char *const *>(envp));
+ exit(eExecFailed);
+ }
+
+ // Wait for the child process to to trap on its call to execve.
+ ::pid_t wpid;
+ int status;
+ if ((wpid = waitpid(pid, &status, 0)) < 0) {
+ args->m_error.SetErrorToErrno();
+ goto FINISH;
+ } else if (WIFEXITED(status)) {
+ // open, dup or execve likely failed for some reason.
+ args->m_error.SetErrorToGenericError();
+ switch (WEXITSTATUS(status)) {
+ case ePtraceFailed:
+ args->m_error.SetErrorString("Child ptrace failed.");
+ break;
+ case eDupStdinFailed:
+ args->m_error.SetErrorString("Child open stdin failed.");
+ break;
+ case eDupStdoutFailed:
+ args->m_error.SetErrorString("Child open stdout failed.");
+ break;
+ case eDupStderrFailed:
+ args->m_error.SetErrorString("Child open stderr failed.");
+ break;
+ case eChdirFailed:
+ args->m_error.SetErrorString("Child failed to set working directory.");
+ break;
+ case eExecFailed:
+ args->m_error.SetErrorString("Child exec failed.");
+ break;
+ case eSetGidFailed:
+ args->m_error.SetErrorString("Child setgid failed.");
+ break;
+ default:
+ args->m_error.SetErrorString("Child returned unknown exit status.");
+ break;
}
- assert(WIFSTOPPED(status) && wpid == (::pid_t)pid &&
- "Could not sync with inferior process.");
+ goto FINISH;
+ }
+ assert(WIFSTOPPED(status) && wpid == (::pid_t)pid &&
+ "Could not sync with inferior process.");
#ifdef notyet
- // Have the child raise an event on exit. This is used to keep the child in
- // limbo until it is destroyed.
- if (PTRACE(PTRACE_SETOPTIONS, pid, NULL, PTRACE_O_TRACEEXIT) < 0)
- {
- args->m_error.SetErrorToErrno();
- goto FINISH;
- }
+ // Have the child raise an event on exit. This is used to keep the child in
+ // limbo until it is destroyed.
+ if (PTRACE(PTRACE_SETOPTIONS, pid, NULL, PTRACE_O_TRACEEXIT) < 0) {
+ args->m_error.SetErrorToErrno();
+ goto FINISH;
+ }
#endif
- // Release the master terminal descriptor and pass it off to the
- // ProcessMonitor instance. Similarly stash the inferior pid.
- monitor->m_terminal_fd = terminal.ReleaseMasterFileDescriptor();
- monitor->m_pid = pid;
+ // Release the master terminal descriptor and pass it off to the
+ // ProcessMonitor instance. Similarly stash the inferior pid.
+ monitor->m_terminal_fd = terminal.ReleaseMasterFileDescriptor();
+ monitor->m_pid = pid;
- // Set the terminal fd to be in non blocking mode (it simplifies the
- // implementation of ProcessFreeBSD::GetSTDOUT to have a non-blocking
- // descriptor to read from).
- if (!EnsureFDFlags(monitor->m_terminal_fd, O_NONBLOCK, args->m_error))
- goto FINISH;
+ // Set the terminal fd to be in non blocking mode (it simplifies the
+ // implementation of ProcessFreeBSD::GetSTDOUT to have a non-blocking
+ // descriptor to read from).
+ if (!EnsureFDFlags(monitor->m_terminal_fd, O_NONBLOCK, args->m_error))
+ goto FINISH;
- process.SendMessage(ProcessMessage::Attach(pid));
+ process.SendMessage(ProcessMessage::Attach(pid));
FINISH:
- return args->m_error.Success();
+ return args->m_error.Success();
}
-void
-ProcessMonitor::StartAttachOpThread(AttachArgs *args, lldb_private::Error &error)
-{
- static const char *g_thread_name = "lldb.process.freebsd.operation";
+void ProcessMonitor::StartAttachOpThread(AttachArgs *args,
+ lldb_private::Error &error) {
+ static const char *g_thread_name = "lldb.process.freebsd.operation";
- if (m_operation_thread.IsJoinable())
- return;
+ if (m_operation_thread.IsJoinable())
+ return;
- m_operation_thread = ThreadLauncher::LaunchThread(g_thread_name, AttachOpThread, args, &error);
+ m_operation_thread =
+ ThreadLauncher::LaunchThread(g_thread_name, AttachOpThread, args, &error);
}
-void *
-ProcessMonitor::AttachOpThread(void *arg)
-{
- AttachArgs *args = static_cast<AttachArgs*>(arg);
+void *ProcessMonitor::AttachOpThread(void *arg) {
+ AttachArgs *args = static_cast<AttachArgs *>(arg);
- Attach(args);
+ Attach(args);
- ServeOperation(args);
- return NULL;
+ ServeOperation(args);
+ return NULL;
}
-void
-ProcessMonitor::Attach(AttachArgs *args)
-{
- lldb::pid_t pid = args->m_pid;
+void ProcessMonitor::Attach(AttachArgs *args) {
+ lldb::pid_t pid = args->m_pid;
- ProcessMonitor *monitor = args->m_monitor;
- ProcessFreeBSD &process = monitor->GetProcess();
+ ProcessMonitor *monitor = args->m_monitor;
+ ProcessFreeBSD &process = monitor->GetProcess();
- if (pid <= 1)
- {
- args->m_error.SetErrorToGenericError();
- args->m_error.SetErrorString("Attaching to process 1 is not allowed.");
- return;
- }
+ if (pid <= 1) {
+ args->m_error.SetErrorToGenericError();
+ args->m_error.SetErrorString("Attaching to process 1 is not allowed.");
+ return;
+ }
- // Attach to the requested process.
- if (PTRACE(PT_ATTACH, pid, NULL, 0) < 0)
- {
- args->m_error.SetErrorToErrno();
- return;
- }
+ // Attach to the requested process.
+ if (PTRACE(PT_ATTACH, pid, NULL, 0) < 0) {
+ args->m_error.SetErrorToErrno();
+ return;
+ }
- int status;
- if ((status = waitpid(pid, NULL, 0)) < 0)
- {
- args->m_error.SetErrorToErrno();
- return;
- }
+ int status;
+ if ((status = waitpid(pid, NULL, 0)) < 0) {
+ args->m_error.SetErrorToErrno();
+ return;
+ }
- process.SendMessage(ProcessMessage::Attach(pid));
+ process.SendMessage(ProcessMessage::Attach(pid));
}
size_t
-ProcessMonitor::GetCurrentThreadIDs(std::vector<lldb::tid_t>&thread_ids)
-{
- lwpid_t *tids;
- int tdcnt;
-
- thread_ids.clear();
-
- tdcnt = PTRACE(PT_GETNUMLWPS, m_pid, NULL, 0);
- if (tdcnt <= 0)
- return 0;
- tids = (lwpid_t *)malloc(tdcnt * sizeof(*tids));
- if (tids == NULL)
- return 0;
- if (PTRACE(PT_GETLWPLIST, m_pid, (void *)tids, tdcnt) < 0) {
- free(tids);
- return 0;
- }
- thread_ids = std::vector<lldb::tid_t>(tids, tids + tdcnt);
+ProcessMonitor::GetCurrentThreadIDs(std::vector<lldb::tid_t> &thread_ids) {
+ lwpid_t *tids;
+ int tdcnt;
+
+ thread_ids.clear();
+
+ tdcnt = PTRACE(PT_GETNUMLWPS, m_pid, NULL, 0);
+ if (tdcnt <= 0)
+ return 0;
+ tids = (lwpid_t *)malloc(tdcnt * sizeof(*tids));
+ if (tids == NULL)
+ return 0;
+ if (PTRACE(PT_GETLWPLIST, m_pid, (void *)tids, tdcnt) < 0) {
free(tids);
- return thread_ids.size();
+ return 0;
+ }
+ thread_ids = std::vector<lldb::tid_t>(tids, tids + tdcnt);
+ free(tids);
+ return thread_ids.size();
}
-bool
-ProcessMonitor::MonitorCallback(ProcessMonitor *monitor, lldb::pid_t pid, bool exited, int signal, int status)
-{
- ProcessMessage message;
- ProcessFreeBSD *process = monitor->m_process;
- assert(process);
- bool stop_monitoring;
- struct ptrace_lwpinfo plwp;
- int ptrace_err;
-
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
-
- if (exited)
- {
- if (log)
- log->Printf ("ProcessMonitor::%s() got exit signal, tid = %" PRIu64, __FUNCTION__, pid);
- message = ProcessMessage::Exit(pid, status);
- process->SendMessage(message);
- return pid == process->GetID();
- }
+bool ProcessMonitor::MonitorCallback(ProcessMonitor *monitor, lldb::pid_t pid,
+ bool exited, int signal, int status) {
+ ProcessMessage message;
+ ProcessFreeBSD *process = monitor->m_process;
+ assert(process);
+ bool stop_monitoring;
+ struct ptrace_lwpinfo plwp;
+ int ptrace_err;
- if (!monitor->GetLwpInfo(pid, &plwp, ptrace_err))
- stop_monitoring = true; // pid is gone. Bail.
- else {
- switch (plwp.pl_siginfo.si_signo)
- {
- case SIGTRAP:
- message = MonitorSIGTRAP(monitor, &plwp.pl_siginfo, plwp.pl_lwpid);
- break;
-
- default:
- message = MonitorSignal(monitor, &plwp.pl_siginfo, plwp.pl_lwpid);
- break;
- }
-
- process->SendMessage(message);
- stop_monitoring = message.GetKind() == ProcessMessage::eExitMessage;
- }
-
- return stop_monitoring;
-}
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-ProcessMessage
-ProcessMonitor::MonitorSIGTRAP(ProcessMonitor *monitor,
- const siginfo_t *info, lldb::tid_t tid)
-{
- ProcessMessage message;
-
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
-
- assert(monitor);
- assert(info && info->si_signo == SIGTRAP && "Unexpected child signal!");
+ if (exited) {
+ if (log)
+ log->Printf("ProcessMonitor::%s() got exit signal, tid = %" PRIu64,
+ __FUNCTION__, pid);
+ message = ProcessMessage::Exit(pid, status);
+ process->SendMessage(message);
+ return pid == process->GetID();
+ }
+
+ if (!monitor->GetLwpInfo(pid, &plwp, ptrace_err))
+ stop_monitoring = true; // pid is gone. Bail.
+ else {
+ switch (plwp.pl_siginfo.si_signo) {
+ case SIGTRAP:
+ message = MonitorSIGTRAP(monitor, &plwp.pl_siginfo, plwp.pl_lwpid);
+ break;
- switch (info->si_code)
- {
default:
- assert(false && "Unexpected SIGTRAP code!");
- break;
-
- case (SIGTRAP /* | (PTRACE_EVENT_EXIT << 8) */):
- {
- // The inferior process is about to exit. Maintain the process in a
- // state of "limbo" until we are explicitly commanded to detach,
- // destroy, resume, etc.
- unsigned long data = 0;
- if (!monitor->GetEventMessage(tid, &data))
- data = -1;
- if (log)
- log->Printf ("ProcessMonitor::%s() received exit? event, data = %lx, tid = %" PRIu64, __FUNCTION__, data, tid);
- message = ProcessMessage::Limbo(tid, (data >> 8));
- break;
+ message = MonitorSignal(monitor, &plwp.pl_siginfo, plwp.pl_lwpid);
+ break;
}
- case 0:
- case TRAP_TRACE:
- if (log)
- log->Printf ("ProcessMonitor::%s() received trace event, tid = %" PRIu64 " : si_code = %d", __FUNCTION__, tid, info->si_code);
- message = ProcessMessage::Trace(tid);
- break;
-
- case SI_KERNEL:
- case TRAP_BRKPT:
- if (log)
- log->Printf ("ProcessMonitor::%s() received breakpoint event, tid = %" PRIu64, __FUNCTION__, tid);
- message = ProcessMessage::Break(tid);
- break;
- }
+ process->SendMessage(message);
+ stop_monitoring = message.GetKind() == ProcessMessage::eExitMessage;
+ }
- return message;
+ return stop_monitoring;
}
-ProcessMessage
-ProcessMonitor::MonitorSignal(ProcessMonitor *monitor,
- const siginfo_t *info, lldb::tid_t tid)
-{
- ProcessMessage message;
- int signo = info->si_signo;
+ProcessMessage ProcessMonitor::MonitorSIGTRAP(ProcessMonitor *monitor,
+ const siginfo_t *info,
+ lldb::tid_t tid) {
+ ProcessMessage message;
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- // POSIX says that process behaviour is undefined after it ignores a SIGFPE,
- // SIGILL, SIGSEGV, or SIGBUS *unless* that signal was generated by a
- // kill(2) or raise(3). Similarly for tgkill(2) on FreeBSD.
- //
- // IOW, user generated signals never generate what we consider to be a
- // "crash".
- //
- // Similarly, ACK signals generated by this monitor.
- if (info->si_code == SI_USER)
- {
- if (log)
- log->Printf ("ProcessMonitor::%s() received signal %s with code %s, pid = %d",
- __FUNCTION__,
- monitor->m_process->GetUnixSignals()->GetSignalAsCString (signo),
- "SI_USER",
- info->si_pid);
- if (info->si_pid == getpid())
- return ProcessMessage::SignalDelivered(tid, signo);
- else
- return ProcessMessage::Signal(tid, signo);
- }
+ assert(monitor);
+ assert(info && info->si_signo == SIGTRAP && "Unexpected child signal!");
+ switch (info->si_code) {
+ default:
+ assert(false && "Unexpected SIGTRAP code!");
+ break;
+
+ case (SIGTRAP /* | (PTRACE_EVENT_EXIT << 8) */): {
+ // The inferior process is about to exit. Maintain the process in a
+ // state of "limbo" until we are explicitly commanded to detach,
+ // destroy, resume, etc.
+ unsigned long data = 0;
+ if (!monitor->GetEventMessage(tid, &data))
+ data = -1;
if (log)
- log->Printf ("ProcessMonitor::%s() received signal %s", __FUNCTION__, monitor->m_process->GetUnixSignals()->GetSignalAsCString (signo));
-
- switch (signo)
- {
- case SIGSEGV:
- case SIGILL:
- case SIGFPE:
- case SIGBUS:
- lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
- const auto reason = GetCrashReason(*info);
- return ProcessMessage::Crash(tid, reason, signo, fault_addr);
- }
+ log->Printf("ProcessMonitor::%s() received exit? event, data = %lx, tid "
+ "= %" PRIu64,
+ __FUNCTION__, data, tid);
+ message = ProcessMessage::Limbo(tid, (data >> 8));
+ break;
+ }
+
+ case 0:
+ case TRAP_TRACE:
+ if (log)
+ log->Printf("ProcessMonitor::%s() received trace event, tid = %" PRIu64
+ " : si_code = %d",
+ __FUNCTION__, tid, info->si_code);
+ message = ProcessMessage::Trace(tid);
+ break;
+
+ case SI_KERNEL:
+ case TRAP_BRKPT:
+ if (log)
+ log->Printf(
+ "ProcessMonitor::%s() received breakpoint event, tid = %" PRIu64,
+ __FUNCTION__, tid);
+ message = ProcessMessage::Break(tid);
+ break;
+ }
+
+ return message;
+}
+
+ProcessMessage ProcessMonitor::MonitorSignal(ProcessMonitor *monitor,
+ const siginfo_t *info,
+ lldb::tid_t tid) {
+ ProcessMessage message;
+ int signo = info->si_signo;
+
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+
+ // POSIX says that process behaviour is undefined after it ignores a SIGFPE,
+ // SIGILL, SIGSEGV, or SIGBUS *unless* that signal was generated by a
+ // kill(2) or raise(3). Similarly for tgkill(2) on FreeBSD.
+ //
+ // IOW, user generated signals never generate what we consider to be a
+ // "crash".
+ //
+ // Similarly, ACK signals generated by this monitor.
+ if (info->si_code == SI_USER) {
+ if (log)
+ log->Printf(
+ "ProcessMonitor::%s() received signal %s with code %s, pid = %d",
+ __FUNCTION__,
+ monitor->m_process->GetUnixSignals()->GetSignalAsCString(signo),
+ "SI_USER", info->si_pid);
+ if (info->si_pid == getpid())
+ return ProcessMessage::SignalDelivered(tid, signo);
+ else
+ return ProcessMessage::Signal(tid, signo);
+ }
+
+ if (log)
+ log->Printf(
+ "ProcessMonitor::%s() received signal %s", __FUNCTION__,
+ monitor->m_process->GetUnixSignals()->GetSignalAsCString(signo));
- // Everything else is "normal" and does not require any special action on
- // our part.
- return ProcessMessage::Signal(tid, signo);
+ switch (signo) {
+ case SIGSEGV:
+ case SIGILL:
+ case SIGFPE:
+ case SIGBUS:
+ lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
+ const auto reason = GetCrashReason(*info);
+ return ProcessMessage::Crash(tid, reason, signo, fault_addr);
+ }
+
+ // Everything else is "normal" and does not require any special action on
+ // our part.
+ return ProcessMessage::Signal(tid, signo);
}
-void
-ProcessMonitor::ServeOperation(OperationArgs *args)
-{
- ProcessMonitor *monitor = args->m_monitor;
+void ProcessMonitor::ServeOperation(OperationArgs *args) {
+ ProcessMonitor *monitor = args->m_monitor;
- // We are finised with the arguments and are ready to go. Sync with the
- // parent thread and start serving operations on the inferior.
- sem_post(&args->m_semaphore);
+ // We are finised with the arguments and are ready to go. Sync with the
+ // parent thread and start serving operations on the inferior.
+ sem_post(&args->m_semaphore);
- for (;;)
- {
- // wait for next pending operation
- sem_wait(&monitor->m_operation_pending);
+ for (;;) {
+ // wait for next pending operation
+ sem_wait(&monitor->m_operation_pending);
- monitor->m_operation->Execute(monitor);
+ monitor->m_operation->Execute(monitor);
- // notify calling thread that operation is complete
- sem_post(&monitor->m_operation_done);
- }
+ // notify calling thread that operation is complete
+ sem_post(&monitor->m_operation_done);
+ }
}
-void
-ProcessMonitor::DoOperation(Operation *op)
-{
- std::lock_guard<std::mutex> guard(m_operation_mutex);
+void ProcessMonitor::DoOperation(Operation *op) {
+ std::lock_guard<std::mutex> guard(m_operation_mutex);
- m_operation = op;
+ m_operation = op;
- // notify operation thread that an operation is ready to be processed
- sem_post(&m_operation_pending);
+ // notify operation thread that an operation is ready to be processed
+ sem_post(&m_operation_pending);
- // wait for operation to complete
- sem_wait(&m_operation_done);
+ // wait for operation to complete
+ sem_wait(&m_operation_done);
}
-size_t
-ProcessMonitor::ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
- Error &error)
-{
- size_t result;
- ReadOperation op(vm_addr, buf, size, error, result);
- DoOperation(&op);
- return result;
+size_t ProcessMonitor::ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
+ Error &error) {
+ size_t result;
+ ReadOperation op(vm_addr, buf, size, error, result);
+ DoOperation(&op);
+ return result;
}
-size_t
-ProcessMonitor::WriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size,
- lldb_private::Error &error)
-{
- size_t result;
- WriteOperation op(vm_addr, buf, size, error, result);
- DoOperation(&op);
- return result;
+size_t ProcessMonitor::WriteMemory(lldb::addr_t vm_addr, const void *buf,
+ size_t size, lldb_private::Error &error) {
+ size_t result;
+ WriteOperation op(vm_addr, buf, size, error, result);
+ DoOperation(&op);
+ return result;
}
-bool
-ProcessMonitor::ReadRegisterValue(lldb::tid_t tid, unsigned offset, const char* reg_name,
- unsigned size, RegisterValue &value)
-{
- bool result;
- ReadRegOperation op(tid, offset, size, value, result);
- DoOperation(&op);
- return result;
+bool ProcessMonitor::ReadRegisterValue(lldb::tid_t tid, unsigned offset,
+ const char *reg_name, unsigned size,
+ RegisterValue &value) {
+ bool result;
+ ReadRegOperation op(tid, offset, size, value, result);
+ DoOperation(&op);
+ return result;
}
-bool
-ProcessMonitor::WriteRegisterValue(lldb::tid_t tid, unsigned offset,
- const char* reg_name, const RegisterValue &value)
-{
- bool result;
- WriteRegOperation op(tid, offset, value, result);
- DoOperation(&op);
- return result;
+bool ProcessMonitor::WriteRegisterValue(lldb::tid_t tid, unsigned offset,
+ const char *reg_name,
+ const RegisterValue &value) {
+ bool result;
+ WriteRegOperation op(tid, offset, value, result);
+ DoOperation(&op);
+ return result;
}
-bool
-ProcessMonitor::ReadDebugRegisterValue(lldb::tid_t tid, unsigned offset,
- const char *reg_name, unsigned size,
- lldb_private::RegisterValue &value)
-{
- bool result;
- ReadDebugRegOperation op(tid, offset, size, value, result);
- DoOperation(&op);
- return result;
+bool ProcessMonitor::ReadDebugRegisterValue(
+ lldb::tid_t tid, unsigned offset, const char *reg_name, unsigned size,
+ lldb_private::RegisterValue &value) {
+ bool result;
+ ReadDebugRegOperation op(tid, offset, size, value, result);
+ DoOperation(&op);
+ return result;
}
-bool
-ProcessMonitor::WriteDebugRegisterValue(lldb::tid_t tid, unsigned offset,
- const char *reg_name,
- const lldb_private::RegisterValue &value)
-{
- bool result;
- WriteDebugRegOperation op(tid, offset, value, result);
- DoOperation(&op);
- return result;
+bool ProcessMonitor::WriteDebugRegisterValue(
+ lldb::tid_t tid, unsigned offset, const char *reg_name,
+ const lldb_private::RegisterValue &value) {
+ bool result;
+ WriteDebugRegOperation op(tid, offset, value, result);
+ DoOperation(&op);
+ return result;
}
-bool
-ProcessMonitor::ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size)
-{
- bool result;
- ReadGPROperation op(tid, buf, result);
- DoOperation(&op);
- return result;
+bool ProcessMonitor::ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size) {
+ bool result;
+ ReadGPROperation op(tid, buf, result);
+ DoOperation(&op);
+ return result;
}
-bool
-ProcessMonitor::ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size)
-{
- bool result;
- ReadFPROperation op(tid, buf, result);
- DoOperation(&op);
- return result;
+bool ProcessMonitor::ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size) {
+ bool result;
+ ReadFPROperation op(tid, buf, result);
+ DoOperation(&op);
+ return result;
}
-bool
-ProcessMonitor::ReadRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset)
-{
- return false;
+bool ProcessMonitor::ReadRegisterSet(lldb::tid_t tid, void *buf,
+ size_t buf_size, unsigned int regset) {
+ return false;
}
-bool
-ProcessMonitor::WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size)
-{
- bool result;
- WriteGPROperation op(tid, buf, result);
- DoOperation(&op);
- return result;
+bool ProcessMonitor::WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size) {
+ bool result;
+ WriteGPROperation op(tid, buf, result);
+ DoOperation(&op);
+ return result;
}
-bool
-ProcessMonitor::WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size)
-{
- bool result;
- WriteFPROperation op(tid, buf, result);
- DoOperation(&op);
- return result;
+bool ProcessMonitor::WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size) {
+ bool result;
+ WriteFPROperation op(tid, buf, result);
+ DoOperation(&op);
+ return result;
}
-bool
-ProcessMonitor::WriteRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset)
-{
- return false;
+bool ProcessMonitor::WriteRegisterSet(lldb::tid_t tid, void *buf,
+ size_t buf_size, unsigned int regset) {
+ return false;
}
-bool
-ProcessMonitor::ReadThreadPointer(lldb::tid_t tid, lldb::addr_t &value)
-{
- return false;
+bool ProcessMonitor::ReadThreadPointer(lldb::tid_t tid, lldb::addr_t &value) {
+ return false;
}
-bool
-ProcessMonitor::Resume(lldb::tid_t unused, uint32_t signo)
-{
- bool result;
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
-
- if (log) {
- const char *signame = m_process->GetUnixSignals()->GetSignalAsCString (signo);
- if (signame == nullptr)
- signame = "<none>";
- log->Printf("ProcessMonitor::%s() resuming pid %" PRIu64 " with signal %s",
- __FUNCTION__, GetPID(), signame);
- }
- ResumeOperation op(signo, result);
- DoOperation(&op);
- if (log)
- log->Printf ("ProcessMonitor::%s() resuming result = %s", __FUNCTION__, result ? "true" : "false");
- return result;
+bool ProcessMonitor::Resume(lldb::tid_t unused, uint32_t signo) {
+ bool result;
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+
+ if (log) {
+ const char *signame =
+ m_process->GetUnixSignals()->GetSignalAsCString(signo);
+ if (signame == nullptr)
+ signame = "<none>";
+ log->Printf("ProcessMonitor::%s() resuming pid %" PRIu64 " with signal %s",
+ __FUNCTION__, GetPID(), signame);
+ }
+ ResumeOperation op(signo, result);
+ DoOperation(&op);
+ if (log)
+ log->Printf("ProcessMonitor::%s() resuming result = %s", __FUNCTION__,
+ result ? "true" : "false");
+ return result;
}
-bool
-ProcessMonitor::SingleStep(lldb::tid_t unused, uint32_t signo)
-{
- bool result;
- SingleStepOperation op(signo, result);
- DoOperation(&op);
- return result;
+bool ProcessMonitor::SingleStep(lldb::tid_t unused, uint32_t signo) {
+ bool result;
+ SingleStepOperation op(signo, result);
+ DoOperation(&op);
+ return result;
}
-bool
-ProcessMonitor::Kill()
-{
- bool result;
- KillOperation op(result);
- DoOperation(&op);
- return result;
+bool ProcessMonitor::Kill() {
+ bool result;
+ KillOperation op(result);
+ DoOperation(&op);
+ return result;
}
-bool
-ProcessMonitor::GetLwpInfo(lldb::tid_t tid, void *lwpinfo, int &ptrace_err)
-{
- bool result;
- LwpInfoOperation op(tid, lwpinfo, result, ptrace_err);
- DoOperation(&op);
- return result;
+bool ProcessMonitor::GetLwpInfo(lldb::tid_t tid, void *lwpinfo,
+ int &ptrace_err) {
+ bool result;
+ LwpInfoOperation op(tid, lwpinfo, result, ptrace_err);
+ DoOperation(&op);
+ return result;
}
-bool
-ProcessMonitor::ThreadSuspend(lldb::tid_t tid, bool suspend)
-{
- bool result;
- ThreadSuspendOperation op(tid, suspend, result);
- DoOperation(&op);
- return result;
+bool ProcessMonitor::ThreadSuspend(lldb::tid_t tid, bool suspend) {
+ bool result;
+ ThreadSuspendOperation op(tid, suspend, result);
+ DoOperation(&op);
+ return result;
}
-bool
-ProcessMonitor::GetEventMessage(lldb::tid_t tid, unsigned long *message)
-{
- bool result;
- EventMessageOperation op(tid, message, result);
- DoOperation(&op);
- return result;
+bool ProcessMonitor::GetEventMessage(lldb::tid_t tid, unsigned long *message) {
+ bool result;
+ EventMessageOperation op(tid, message, result);
+ DoOperation(&op);
+ return result;
}
-lldb_private::Error
-ProcessMonitor::Detach(lldb::tid_t tid)
-{
- lldb_private::Error error;
- if (tid != LLDB_INVALID_THREAD_ID)
- {
- DetachOperation op(error);
- DoOperation(&op);
- }
- return error;
-}
+lldb_private::Error ProcessMonitor::Detach(lldb::tid_t tid) {
+ lldb_private::Error error;
+ if (tid != LLDB_INVALID_THREAD_ID) {
+ DetachOperation op(error);
+ DoOperation(&op);
+ }
+ return error;
+}
-bool
-ProcessMonitor::DupDescriptor(const FileSpec &file_spec, int fd, int flags)
-{
- int target_fd = open(file_spec.GetCString(), flags, 0666);
+bool ProcessMonitor::DupDescriptor(const FileSpec &file_spec, int fd,
+ int flags) {
+ int target_fd = open(file_spec.GetCString(), flags, 0666);
- if (target_fd == -1)
- return false;
+ if (target_fd == -1)
+ return false;
- if (dup2(target_fd, fd) == -1)
- return false;
+ if (dup2(target_fd, fd) == -1)
+ return false;
- return (close(target_fd) == -1) ? false : true;
+ return (close(target_fd) == -1) ? false : true;
}
-void
-ProcessMonitor::StopMonitoringChildProcess()
-{
- if (m_monitor_thread.IsJoinable())
- {
- m_monitor_thread.Cancel();
- m_monitor_thread.Join(nullptr);
- m_monitor_thread.Reset();
- }
+void ProcessMonitor::StopMonitoringChildProcess() {
+ if (m_monitor_thread.IsJoinable()) {
+ m_monitor_thread.Cancel();
+ m_monitor_thread.Join(nullptr);
+ m_monitor_thread.Reset();
+ }
}
-void
-ProcessMonitor::StopMonitor()
-{
- StopMonitoringChildProcess();
- StopOpThread();
- sem_destroy(&m_operation_pending);
- sem_destroy(&m_operation_done);
- if (m_terminal_fd >= 0) {
- close(m_terminal_fd);
- m_terminal_fd = -1;
- }
+void ProcessMonitor::StopMonitor() {
+ StopMonitoringChildProcess();
+ StopOpThread();
+ sem_destroy(&m_operation_pending);
+ sem_destroy(&m_operation_done);
+ if (m_terminal_fd >= 0) {
+ close(m_terminal_fd);
+ m_terminal_fd = -1;
+ }
}
// FIXME: On Linux, when a new thread is created, we receive to notifications,
@@ -1607,19 +1439,13 @@ ProcessMonitor::StopMonitor()
// We really should figure out what actually happens on FreeBSD and move the
// Linux-specific logic out of ProcessPOSIX as needed.
-bool
-ProcessMonitor::WaitForInitialTIDStop(lldb::tid_t tid)
-{
- return true;
-}
+bool ProcessMonitor::WaitForInitialTIDStop(lldb::tid_t tid) { return true; }
-void
-ProcessMonitor::StopOpThread()
-{
- if (!m_operation_thread.IsJoinable())
- return;
+void ProcessMonitor::StopOpThread() {
+ if (!m_operation_thread.IsJoinable())
+ return;
- m_operation_thread.Cancel();
- m_operation_thread.Join(nullptr);
- m_operation_thread.Reset();
+ m_operation_thread.Cancel();
+ m_operation_thread.Join(nullptr);
+ m_operation_thread.Reset();
}
diff --git a/source/Plugins/Process/FreeBSD/ProcessMonitor.h b/source/Plugins/Process/FreeBSD/ProcessMonitor.h
index 93f6be111361..4c2594e9da6a 100644
--- a/source/Plugins/Process/FreeBSD/ProcessMonitor.h
+++ b/source/Plugins/Process/FreeBSD/ProcessMonitor.h
@@ -18,12 +18,11 @@
#include <mutex>
// Other libraries and framework includes
-#include "lldb/lldb-types.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/HostThread.h"
+#include "lldb/lldb-types.h"
-namespace lldb_private
-{
+namespace lldb_private {
class Error;
class Module;
class Scalar;
@@ -44,285 +43,242 @@ class Operation;
///
/// A purposely minimal set of operations are provided to interrogate and change
/// the inferior process state.
-class ProcessMonitor
-{
+class ProcessMonitor {
public:
-
- /// Launches an inferior process ready for debugging. Forms the
- /// implementation of Process::DoLaunch.
- ProcessMonitor(ProcessFreeBSD *process,
- lldb_private::Module *module,
- char const *argv[],
- char const *envp[],
- const lldb_private::FileSpec &stdin_file_spec,
- const lldb_private::FileSpec &stdout_file_spec,
- const lldb_private::FileSpec &stderr_file_spec,
- const lldb_private::FileSpec &working_dir,
- const lldb_private::ProcessLaunchInfo &launch_info,
- lldb_private::Error &error);
-
- ProcessMonitor(ProcessFreeBSD *process,
- lldb::pid_t pid,
- lldb_private::Error &error);
-
- ~ProcessMonitor();
-
- /// Provides the process number of debugee.
- lldb::pid_t
- GetPID() const { return m_pid; }
-
- /// Returns the process associated with this ProcessMonitor.
- ProcessFreeBSD &
- GetProcess() { return *m_process; }
-
- /// Returns a file descriptor to the controlling terminal of the inferior
- /// process.
- ///
- /// Reads from this file descriptor yield both the standard output and
- /// standard error of this debugee. Even if stderr and stdout were
- /// redirected on launch it may still happen that data is available on this
- /// descriptor (if the inferior process opens /dev/tty, for example). This descriptor is
- /// closed after a call to StopMonitor().
- ///
- /// If this monitor was attached to an existing process this method returns
- /// -1.
- int
- GetTerminalFD() const { return m_terminal_fd; }
-
- /// Reads @p size bytes from address @vm_adder in the inferior process
- /// address space.
- ///
- /// This method is provided to implement Process::DoReadMemory.
- size_t
- ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
- lldb_private::Error &error);
-
- /// Writes @p size bytes from address @p vm_adder in the inferior process
- /// address space.
- ///
- /// This method is provided to implement Process::DoWriteMemory.
- size_t
- WriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size,
- lldb_private::Error &error);
-
- /// Reads the contents from the register identified by the given (architecture
- /// dependent) offset.
- ///
- /// This method is provided for use by RegisterContextFreeBSD derivatives.
- bool
- ReadRegisterValue(lldb::tid_t tid, unsigned offset, const char *reg_name,
- unsigned size, lldb_private::RegisterValue &value);
-
- /// Writes the given value to the register identified by the given
- /// (architecture dependent) offset.
- ///
- /// This method is provided for use by RegisterContextFreeBSD derivatives.
- bool
- WriteRegisterValue(lldb::tid_t tid, unsigned offset, const char *reg_name,
- const lldb_private::RegisterValue &value);
-
- /// Reads the contents from the debug register identified by the given
- /// (architecture dependent) offset.
- ///
- /// This method is provided for use by RegisterContextFreeBSD derivatives.
- bool
- ReadDebugRegisterValue(lldb::tid_t tid, unsigned offset,
- const char *reg_name, unsigned size,
- lldb_private::RegisterValue &value);
-
- /// Writes the given value to the debug register identified by the given
- /// (architecture dependent) offset.
- ///
- /// This method is provided for use by RegisterContextFreeBSD derivatives.
- bool
- WriteDebugRegisterValue(lldb::tid_t tid, unsigned offset,
- const char *reg_name,
- const lldb_private::RegisterValue &value);
- /// Reads all general purpose registers into the specified buffer.
- bool
- ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size);
-
- /// Reads all floating point registers into the specified buffer.
- bool
- ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size);
-
- /// Reads the specified register set into the specified buffer.
- ///
- /// This method is provided for use by RegisterContextFreeBSD derivatives.
- bool
- ReadRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset);
-
- /// Writes all general purpose registers into the specified buffer.
- bool
- WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size);
-
- /// Writes all floating point registers into the specified buffer.
- bool
- WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size);
-
- /// Writes the specified register set into the specified buffer.
- ///
- /// This method is provided for use by RegisterContextFreeBSD derivatives.
- bool
- WriteRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset);
-
- /// Reads the value of the thread-specific pointer for a given thread ID.
- bool
- ReadThreadPointer(lldb::tid_t tid, lldb::addr_t &value);
-
- /// Returns current thread IDs in process
- size_t
- GetCurrentThreadIDs(std::vector<lldb::tid_t> &thread_ids);
-
- /// Writes a ptrace_lwpinfo structure corresponding to the given thread ID
- /// to the memory region pointed to by @p lwpinfo.
- bool
- GetLwpInfo(lldb::tid_t tid, void *lwpinfo, int &error_no);
-
- /// Suspends or unsuspends a thread prior to process resume or step.
- bool
- ThreadSuspend(lldb::tid_t tid, bool suspend);
-
- /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG)
- /// corresponding to the given thread IDto the memory pointed to by @p
- /// message.
- bool
- GetEventMessage(lldb::tid_t tid, unsigned long *message);
-
- /// Resumes the process. If @p signo is anything but
- /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the process.
- bool
- Resume(lldb::tid_t unused, uint32_t signo);
-
- /// Single steps the process. If @p signo is anything but
- /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the process.
- bool
- SingleStep(lldb::tid_t unused, uint32_t signo);
-
- /// Terminate the traced process.
- bool
- Kill();
-
- lldb_private::Error
- Detach(lldb::tid_t tid);
-
- void
- StopMonitor();
-
- // Waits for the initial stop message from a new thread.
- bool
- WaitForInitialTIDStop(lldb::tid_t tid);
+ /// Launches an inferior process ready for debugging. Forms the
+ /// implementation of Process::DoLaunch.
+ ProcessMonitor(ProcessFreeBSD *process, lldb_private::Module *module,
+ char const *argv[], char const *envp[],
+ const lldb_private::FileSpec &stdin_file_spec,
+ const lldb_private::FileSpec &stdout_file_spec,
+ const lldb_private::FileSpec &stderr_file_spec,
+ const lldb_private::FileSpec &working_dir,
+ const lldb_private::ProcessLaunchInfo &launch_info,
+ lldb_private::Error &error);
+
+ ProcessMonitor(ProcessFreeBSD *process, lldb::pid_t pid,
+ lldb_private::Error &error);
+
+ ~ProcessMonitor();
+
+ /// Provides the process number of debugee.
+ lldb::pid_t GetPID() const { return m_pid; }
+
+ /// Returns the process associated with this ProcessMonitor.
+ ProcessFreeBSD &GetProcess() { return *m_process; }
+
+ /// Returns a file descriptor to the controlling terminal of the inferior
+ /// process.
+ ///
+ /// Reads from this file descriptor yield both the standard output and
+ /// standard error of this debugee. Even if stderr and stdout were
+ /// redirected on launch it may still happen that data is available on this
+ /// descriptor (if the inferior process opens /dev/tty, for example). This
+ /// descriptor is
+ /// closed after a call to StopMonitor().
+ ///
+ /// If this monitor was attached to an existing process this method returns
+ /// -1.
+ int GetTerminalFD() const { return m_terminal_fd; }
+
+ /// Reads @p size bytes from address @vm_adder in the inferior process
+ /// address space.
+ ///
+ /// This method is provided to implement Process::DoReadMemory.
+ size_t ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
+ lldb_private::Error &error);
+
+ /// Writes @p size bytes from address @p vm_adder in the inferior process
+ /// address space.
+ ///
+ /// This method is provided to implement Process::DoWriteMemory.
+ size_t WriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size,
+ lldb_private::Error &error);
+
+ /// Reads the contents from the register identified by the given (architecture
+ /// dependent) offset.
+ ///
+ /// This method is provided for use by RegisterContextFreeBSD derivatives.
+ bool ReadRegisterValue(lldb::tid_t tid, unsigned offset, const char *reg_name,
+ unsigned size, lldb_private::RegisterValue &value);
+
+ /// Writes the given value to the register identified by the given
+ /// (architecture dependent) offset.
+ ///
+ /// This method is provided for use by RegisterContextFreeBSD derivatives.
+ bool WriteRegisterValue(lldb::tid_t tid, unsigned offset,
+ const char *reg_name,
+ const lldb_private::RegisterValue &value);
+
+ /// Reads the contents from the debug register identified by the given
+ /// (architecture dependent) offset.
+ ///
+ /// This method is provided for use by RegisterContextFreeBSD derivatives.
+ bool ReadDebugRegisterValue(lldb::tid_t tid, unsigned offset,
+ const char *reg_name, unsigned size,
+ lldb_private::RegisterValue &value);
+
+ /// Writes the given value to the debug register identified by the given
+ /// (architecture dependent) offset.
+ ///
+ /// This method is provided for use by RegisterContextFreeBSD derivatives.
+ bool WriteDebugRegisterValue(lldb::tid_t tid, unsigned offset,
+ const char *reg_name,
+ const lldb_private::RegisterValue &value);
+ /// Reads all general purpose registers into the specified buffer.
+ bool ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size);
+
+ /// Reads all floating point registers into the specified buffer.
+ bool ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size);
+
+ /// Reads the specified register set into the specified buffer.
+ ///
+ /// This method is provided for use by RegisterContextFreeBSD derivatives.
+ bool ReadRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size,
+ unsigned int regset);
+
+ /// Writes all general purpose registers into the specified buffer.
+ bool WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size);
+
+ /// Writes all floating point registers into the specified buffer.
+ bool WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size);
+
+ /// Writes the specified register set into the specified buffer.
+ ///
+ /// This method is provided for use by RegisterContextFreeBSD derivatives.
+ bool WriteRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size,
+ unsigned int regset);
+
+ /// Reads the value of the thread-specific pointer for a given thread ID.
+ bool ReadThreadPointer(lldb::tid_t tid, lldb::addr_t &value);
+
+ /// Returns current thread IDs in process
+ size_t GetCurrentThreadIDs(std::vector<lldb::tid_t> &thread_ids);
+
+ /// Writes a ptrace_lwpinfo structure corresponding to the given thread ID
+ /// to the memory region pointed to by @p lwpinfo.
+ bool GetLwpInfo(lldb::tid_t tid, void *lwpinfo, int &error_no);
+
+ /// Suspends or unsuspends a thread prior to process resume or step.
+ bool ThreadSuspend(lldb::tid_t tid, bool suspend);
+
+ /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG)
+ /// corresponding to the given thread IDto the memory pointed to by @p
+ /// message.
+ bool GetEventMessage(lldb::tid_t tid, unsigned long *message);
+
+ /// Resumes the process. If @p signo is anything but
+ /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the process.
+ bool Resume(lldb::tid_t unused, uint32_t signo);
+
+ /// Single steps the process. If @p signo is anything but
+ /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the process.
+ bool SingleStep(lldb::tid_t unused, uint32_t signo);
+
+ /// Terminate the traced process.
+ bool Kill();
+
+ lldb_private::Error Detach(lldb::tid_t tid);
+
+ void StopMonitor();
+
+ // Waits for the initial stop message from a new thread.
+ bool WaitForInitialTIDStop(lldb::tid_t tid);
private:
- ProcessFreeBSD *m_process;
+ ProcessFreeBSD *m_process;
- lldb_private::HostThread m_operation_thread;
- lldb_private::HostThread m_monitor_thread;
- lldb::pid_t m_pid;
+ lldb_private::HostThread m_operation_thread;
+ lldb_private::HostThread m_monitor_thread;
+ lldb::pid_t m_pid;
- int m_terminal_fd;
+ int m_terminal_fd;
- // current operation which must be executed on the privileged thread
- Operation *m_operation;
- std::mutex m_operation_mutex;
+ // current operation which must be executed on the privileged thread
+ Operation *m_operation;
+ std::mutex m_operation_mutex;
- // semaphores notified when Operation is ready to be processed and when
- // the operation is complete.
- sem_t m_operation_pending;
- sem_t m_operation_done;
+ // semaphores notified when Operation is ready to be processed and when
+ // the operation is complete.
+ sem_t m_operation_pending;
+ sem_t m_operation_done;
- struct OperationArgs
- {
- OperationArgs(ProcessMonitor *monitor);
+ struct OperationArgs {
+ OperationArgs(ProcessMonitor *monitor);
- ~OperationArgs();
+ ~OperationArgs();
- ProcessMonitor *m_monitor; // The monitor performing the attach.
- sem_t m_semaphore; // Posted to once operation complete.
- lldb_private::Error m_error; // Set if process operation failed.
- };
+ ProcessMonitor *m_monitor; // The monitor performing the attach.
+ sem_t m_semaphore; // Posted to once operation complete.
+ lldb_private::Error m_error; // Set if process operation failed.
+ };
- /// @class LauchArgs
- ///
- /// @brief Simple structure to pass data to the thread responsible for
- /// launching a child process.
- struct LaunchArgs : OperationArgs
- {
- LaunchArgs(ProcessMonitor *monitor,
- lldb_private::Module *module,
- char const **argv,
- char const **envp,
- const lldb_private::FileSpec &stdin_file_spec,
- const lldb_private::FileSpec &stdout_file_spec,
- const lldb_private::FileSpec &stderr_file_spec,
- const lldb_private::FileSpec &working_dir);
+ /// @class LauchArgs
+ ///
+ /// @brief Simple structure to pass data to the thread responsible for
+ /// launching a child process.
+ struct LaunchArgs : OperationArgs {
+ LaunchArgs(ProcessMonitor *monitor, lldb_private::Module *module,
+ char const **argv, char const **envp,
+ const lldb_private::FileSpec &stdin_file_spec,
+ const lldb_private::FileSpec &stdout_file_spec,
+ const lldb_private::FileSpec &stderr_file_spec,
+ const lldb_private::FileSpec &working_dir);
- ~LaunchArgs();
+ ~LaunchArgs();
- lldb_private::Module *m_module; // The executable image to launch.
- char const **m_argv; // Process arguments.
- char const **m_envp; // Process environment.
- const lldb_private::FileSpec m_stdin_file_spec; // Redirect stdin or empty.
- const lldb_private::FileSpec m_stdout_file_spec; // Redirect stdout or empty.
- const lldb_private::FileSpec m_stderr_file_spec; // Redirect stderr or empty.
- const lldb_private::FileSpec m_working_dir; // Working directory or empty.
- };
+ lldb_private::Module *m_module; // The executable image to launch.
+ char const **m_argv; // Process arguments.
+ char const **m_envp; // Process environment.
+ const lldb_private::FileSpec m_stdin_file_spec; // Redirect stdin or empty.
+ const lldb_private::FileSpec
+ m_stdout_file_spec; // Redirect stdout or empty.
+ const lldb_private::FileSpec
+ m_stderr_file_spec; // Redirect stderr or empty.
+ const lldb_private::FileSpec m_working_dir; // Working directory or empty.
+ };
- void
- StartLaunchOpThread(LaunchArgs *args, lldb_private::Error &error);
+ void StartLaunchOpThread(LaunchArgs *args, lldb_private::Error &error);
- static void *
- LaunchOpThread(void *arg);
+ static void *LaunchOpThread(void *arg);
- static bool
- Launch(LaunchArgs *args);
+ static bool Launch(LaunchArgs *args);
- struct AttachArgs : OperationArgs
- {
- AttachArgs(ProcessMonitor *monitor,
- lldb::pid_t pid);
+ struct AttachArgs : OperationArgs {
+ AttachArgs(ProcessMonitor *monitor, lldb::pid_t pid);
- ~AttachArgs();
+ ~AttachArgs();
- lldb::pid_t m_pid; // pid of the process to be attached.
- };
+ lldb::pid_t m_pid; // pid of the process to be attached.
+ };
- void
- StartAttachOpThread(AttachArgs *args, lldb_private::Error &error);
+ void StartAttachOpThread(AttachArgs *args, lldb_private::Error &error);
- static void *
- AttachOpThread(void *args);
+ static void *AttachOpThread(void *args);
- static void
- Attach(AttachArgs *args);
+ static void Attach(AttachArgs *args);
- static void
- ServeOperation(OperationArgs *args);
+ static void ServeOperation(OperationArgs *args);
- static bool
- DupDescriptor(const lldb_private::FileSpec &file_spec, int fd, int flags);
+ static bool DupDescriptor(const lldb_private::FileSpec &file_spec, int fd,
+ int flags);
- static bool
- MonitorCallback(ProcessMonitor *monitor, lldb::pid_t pid, bool exited, int signal, int status);
+ static bool MonitorCallback(ProcessMonitor *monitor, lldb::pid_t pid,
+ bool exited, int signal, int status);
- static ProcessMessage
- MonitorSIGTRAP(ProcessMonitor *monitor,
- const siginfo_t *info, lldb::pid_t pid);
+ static ProcessMessage MonitorSIGTRAP(ProcessMonitor *monitor,
+ const siginfo_t *info, lldb::pid_t pid);
- static ProcessMessage
- MonitorSignal(ProcessMonitor *monitor,
- const siginfo_t *info, lldb::pid_t pid);
+ static ProcessMessage MonitorSignal(ProcessMonitor *monitor,
+ const siginfo_t *info, lldb::pid_t pid);
- void
- DoOperation(Operation *op);
+ void DoOperation(Operation *op);
- /// Stops the child monitor thread.
- void
- StopMonitoringChildProcess();
+ /// Stops the child monitor thread.
+ void StopMonitoringChildProcess();
- /// Stops the operation thread used to attach/launch a process.
- void
- StopOpThread();
+ /// Stops the operation thread used to attach/launch a process.
+ void StopOpThread();
};
#endif // #ifndef liblldb_ProcessMonitor_H_
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h b/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h
index 6ddd9cfe4c21..c0b9b2f4a2d3 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h
@@ -13,67 +13,56 @@
// C Includes
// C++ Includes
// Other libraries and framework includes
+#include "RegisterInfoInterface.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Target/RegisterContext.h"
-#include "RegisterInfoInterface.h"
//------------------------------------------------------------------------------
/// @class POSIXBreakpointProtocol
///
/// @brief Extends RegisterClass with a few virtual operations useful on POSIX.
-class POSIXBreakpointProtocol
-{
+class POSIXBreakpointProtocol {
public:
- POSIXBreakpointProtocol()
- { m_watchpoints_initialized = false; }
- virtual ~POSIXBreakpointProtocol() {}
+ POSIXBreakpointProtocol() { m_watchpoints_initialized = false; }
+ virtual ~POSIXBreakpointProtocol() {}
- /// Updates the register state of the associated thread after hitting a
- /// breakpoint (if that make sense for the architecture). Default
- /// implementation simply returns true for architectures which do not
- /// require any update.
- ///
- /// @return
- /// True if the operation succeeded and false otherwise.
- virtual bool UpdateAfterBreakpoint() = 0;
+ /// Updates the register state of the associated thread after hitting a
+ /// breakpoint (if that make sense for the architecture). Default
+ /// implementation simply returns true for architectures which do not
+ /// require any update.
+ ///
+ /// @return
+ /// True if the operation succeeded and false otherwise.
+ virtual bool UpdateAfterBreakpoint() = 0;
- /// Determines the index in lldb's register file given a kernel byte offset.
- virtual unsigned
- GetRegisterIndexFromOffset(unsigned offset) = 0;
+ /// Determines the index in lldb's register file given a kernel byte offset.
+ virtual unsigned GetRegisterIndexFromOffset(unsigned offset) = 0;
- // Checks to see if a watchpoint specified by hw_index caused the inferior
- // to stop.
- virtual bool
- IsWatchpointHit (uint32_t hw_index) = 0;
+ // Checks to see if a watchpoint specified by hw_index caused the inferior
+ // to stop.
+ virtual bool IsWatchpointHit(uint32_t hw_index) = 0;
- // Resets any watchpoints that have been hit.
- virtual bool
- ClearWatchpointHits () = 0;
+ // Resets any watchpoints that have been hit.
+ virtual bool ClearWatchpointHits() = 0;
- // Returns the watchpoint address associated with a watchpoint hardware
- // index.
- virtual lldb::addr_t
- GetWatchpointAddress (uint32_t hw_index) = 0;
+ // Returns the watchpoint address associated with a watchpoint hardware
+ // index.
+ virtual lldb::addr_t GetWatchpointAddress(uint32_t hw_index) = 0;
- virtual bool
- IsWatchpointVacant (uint32_t hw_index) = 0;
+ virtual bool IsWatchpointVacant(uint32_t hw_index) = 0;
- virtual bool
- SetHardwareWatchpointWithIndex (lldb::addr_t addr, size_t size,
- bool read, bool write,
- uint32_t hw_index) = 0;
+ virtual bool SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size,
+ bool read, bool write,
+ uint32_t hw_index) = 0;
- // From lldb_private::RegisterContext
- virtual uint32_t
- NumSupportedHardwareWatchpoints () = 0;
+ // From lldb_private::RegisterContext
+ virtual uint32_t NumSupportedHardwareWatchpoints() = 0;
- // Force m_watchpoints_initialized to TRUE
- void
- ForceWatchpointsInitialized () {m_watchpoints_initialized = true;}
+ // Force m_watchpoints_initialized to TRUE
+ void ForceWatchpointsInitialized() { m_watchpoints_initialized = true; }
protected:
- bool m_watchpoints_initialized;
+ bool m_watchpoints_initialized;
};
#endif // #ifndef liblldb_RegisterContextPOSIX_H_
-
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp
index 9922311fd9db..f8d5f2edd3a3 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp
@@ -11,312 +11,250 @@
#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Thread.h"
-#include "RegisterContextPOSIX_arm.h"
#include "ProcessFreeBSD.h"
-#include "RegisterContextPOSIXProcessMonitor_arm.h"
#include "ProcessMonitor.h"
+#include "RegisterContextPOSIXProcessMonitor_arm.h"
+#include "RegisterContextPOSIX_arm.h"
using namespace lldb_private;
using namespace lldb;
#define REG_CONTEXT_SIZE (GetGPRSize())
-RegisterContextPOSIXProcessMonitor_arm::RegisterContextPOSIXProcessMonitor_arm(Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info)
- : RegisterContextPOSIX_arm(thread, concrete_frame_idx, register_info)
-{
-}
+RegisterContextPOSIXProcessMonitor_arm::RegisterContextPOSIXProcessMonitor_arm(
+ Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info)
+ : RegisterContextPOSIX_arm(thread, concrete_frame_idx, register_info) {}
-ProcessMonitor &
-RegisterContextPOSIXProcessMonitor_arm::GetMonitor()
-{
- ProcessSP base = CalculateProcess();
- ProcessFreeBSD *process = static_cast<ProcessFreeBSD*>(base.get());
- return process->GetMonitor();
+ProcessMonitor &RegisterContextPOSIXProcessMonitor_arm::GetMonitor() {
+ ProcessSP base = CalculateProcess();
+ ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(base.get());
+ return process->GetMonitor();
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::ReadGPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadGPR(m_thread.GetID(), &m_gpr_arm, GetGPRSize());
+bool RegisterContextPOSIXProcessMonitor_arm::ReadGPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.ReadGPR(m_thread.GetID(), &m_gpr_arm, GetGPRSize());
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::ReadFPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadFPR(m_thread.GetID(), &m_fpr, sizeof(m_fpr));
+bool RegisterContextPOSIXProcessMonitor_arm::ReadFPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.ReadFPR(m_thread.GetID(), &m_fpr, sizeof(m_fpr));
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::WriteGPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteGPR(m_thread.GetID(), &m_gpr_arm, GetGPRSize());
+bool RegisterContextPOSIXProcessMonitor_arm::WriteGPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.WriteGPR(m_thread.GetID(), &m_gpr_arm, GetGPRSize());
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::WriteFPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteFPR(m_thread.GetID(), &m_fpr, sizeof(m_fpr));
+bool RegisterContextPOSIXProcessMonitor_arm::WriteFPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.WriteFPR(m_thread.GetID(), &m_fpr, sizeof(m_fpr));
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::ReadRegister(const unsigned reg,
- RegisterValue &value)
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadRegisterValue(m_thread.GetID(),
- GetRegisterOffset(reg),
- GetRegisterName(reg),
- GetRegisterSize(reg),
- value);
+bool RegisterContextPOSIXProcessMonitor_arm::ReadRegister(
+ const unsigned reg, RegisterValue &value) {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.ReadRegisterValue(m_thread.GetID(), GetRegisterOffset(reg),
+ GetRegisterName(reg), GetRegisterSize(reg),
+ value);
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::WriteRegister(const unsigned reg,
- const RegisterValue &value)
-{
- unsigned reg_to_write = reg;
- RegisterValue value_to_write = value;
-
- // Check if this is a subregister of a full register.
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
- if (reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM))
- {
- RegisterValue full_value;
- uint32_t full_reg = reg_info->invalidate_regs[0];
- const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
-
- // Read the full register.
- if (ReadRegister(full_reg_info, full_value))
- {
- Error error;
- ByteOrder byte_order = GetByteOrder();
- uint8_t dst[RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the full register.
- const uint32_t dest_size = full_value.GetAsMemoryData (full_reg_info,
- dst,
- sizeof(dst),
- byte_order,
- error);
- if (error.Success() && dest_size)
- {
- uint8_t src[RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the source data.
- const uint32_t src_size = value.GetAsMemoryData (reg_info, src, sizeof(src), byte_order, error);
- if (error.Success() && src_size && (src_size < dest_size))
- {
- // Copy the src bytes to the destination.
- memcpy (dst + (reg_info->byte_offset & 0x1), src, src_size);
- // Set this full register as the value to write.
- value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
- value_to_write.SetType(full_reg_info);
- reg_to_write = full_reg;
- }
- }
+bool RegisterContextPOSIXProcessMonitor_arm::WriteRegister(
+ const unsigned reg, const RegisterValue &value) {
+ unsigned reg_to_write = reg;
+ RegisterValue value_to_write = value;
+
+ // Check if this is a subregister of a full register.
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
+ if (reg_info->invalidate_regs &&
+ (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) {
+ RegisterValue full_value;
+ uint32_t full_reg = reg_info->invalidate_regs[0];
+ const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
+
+ // Read the full register.
+ if (ReadRegister(full_reg_info, full_value)) {
+ Error error;
+ ByteOrder byte_order = GetByteOrder();
+ uint8_t dst[RegisterValue::kMaxRegisterByteSize];
+
+ // Get the bytes for the full register.
+ const uint32_t dest_size = full_value.GetAsMemoryData(
+ full_reg_info, dst, sizeof(dst), byte_order, error);
+ if (error.Success() && dest_size) {
+ uint8_t src[RegisterValue::kMaxRegisterByteSize];
+
+ // Get the bytes for the source data.
+ const uint32_t src_size = value.GetAsMemoryData(
+ reg_info, src, sizeof(src), byte_order, error);
+ if (error.Success() && src_size && (src_size < dest_size)) {
+ // Copy the src bytes to the destination.
+ memcpy(dst + (reg_info->byte_offset & 0x1), src, src_size);
+ // Set this full register as the value to write.
+ value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
+ value_to_write.SetType(full_reg_info);
+ reg_to_write = full_reg;
}
+ }
}
+ }
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteRegisterValue(m_thread.GetID(),
- GetRegisterOffset(reg_to_write),
- GetRegisterName(reg_to_write),
- value_to_write);
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.WriteRegisterValue(
+ m_thread.GetID(), GetRegisterOffset(reg_to_write),
+ GetRegisterName(reg_to_write), value_to_write);
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
-{
- if (!reg_info)
- return false;
-
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
-
- if (IsFPR(reg))
- {
- if (!ReadFPR())
- return false;
- }
- else
- {
- return ReadRegister(reg, value);
- }
+bool RegisterContextPOSIXProcessMonitor_arm::ReadRegister(
+ const RegisterInfo *reg_info, RegisterValue &value) {
+ if (!reg_info)
+ return false;
- // Get pointer to m_fpr variable and set the data from it.
- assert (reg_info->byte_offset < sizeof m_fpr);
- uint8_t *src = (uint8_t *)&m_fpr + reg_info->byte_offset;
- switch (reg_info->byte_size)
- {
- case 2:
- value.SetUInt16(*(uint16_t *)src);
- return true;
- case 4:
- value.SetUInt32(*(uint32_t *)src);
- return true;
- case 8:
- value.SetUInt64(*(uint64_t *)src);
- return true;
- default:
- assert(false && "Unhandled data size.");
- return false;
- }
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+
+ if (IsFPR(reg)) {
+ if (!ReadFPR())
+ return false;
+ } else {
+ return ReadRegister(reg, value);
+ }
+
+ // Get pointer to m_fpr variable and set the data from it.
+ assert(reg_info->byte_offset < sizeof m_fpr);
+ uint8_t *src = (uint8_t *)&m_fpr + reg_info->byte_offset;
+ switch (reg_info->byte_size) {
+ case 2:
+ value.SetUInt16(*(uint16_t *)src);
+ return true;
+ case 4:
+ value.SetUInt32(*(uint32_t *)src);
+ return true;
+ case 8:
+ value.SetUInt64(*(uint64_t *)src);
+ return true;
+ default:
+ assert(false && "Unhandled data size.");
+ return false;
+ }
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value)
-{
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+bool RegisterContextPOSIXProcessMonitor_arm::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &value) {
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- if (IsGPR(reg))
- {
- return WriteRegister(reg, value);
- }
- else if (IsFPR(reg))
- {
- return WriteFPR();
- }
+ if (IsGPR(reg)) {
+ return WriteRegister(reg, value);
+ } else if (IsFPR(reg)) {
+ return WriteFPR();
+ }
- return false;
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::ReadAllRegisterValues(DataBufferSP &data_sp)
-{
- bool success = false;
- data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
- if (data_sp && ReadGPR () && ReadFPR ())
- {
- uint8_t *dst = data_sp->GetBytes();
- success = dst != 0;
-
- if (success)
- {
- ::memcpy (dst, &m_gpr_arm, GetGPRSize());
- dst += GetGPRSize();
- ::memcpy (dst, &m_fpr, sizeof(m_fpr));
- }
+bool RegisterContextPOSIXProcessMonitor_arm::ReadAllRegisterValues(
+ DataBufferSP &data_sp) {
+ bool success = false;
+ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (data_sp && ReadGPR() && ReadFPR()) {
+ uint8_t *dst = data_sp->GetBytes();
+ success = dst != 0;
+
+ if (success) {
+ ::memcpy(dst, &m_gpr_arm, GetGPRSize());
+ dst += GetGPRSize();
+ ::memcpy(dst, &m_fpr, sizeof(m_fpr));
}
- return success;
+ }
+ return success;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::WriteAllRegisterValues(const DataBufferSP &data_sp)
-{
- bool success = false;
- if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE)
- {
- uint8_t *src = data_sp->GetBytes();
- if (src)
- {
- ::memcpy (&m_gpr_arm, src, GetGPRSize());
-
- if (WriteGPR())
- {
- src += GetGPRSize();
- ::memcpy (&m_fpr, src, sizeof(m_fpr));
-
- success = WriteFPR();
- }
- }
+bool RegisterContextPOSIXProcessMonitor_arm::WriteAllRegisterValues(
+ const DataBufferSP &data_sp) {
+ bool success = false;
+ if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
+ uint8_t *src = data_sp->GetBytes();
+ if (src) {
+ ::memcpy(&m_gpr_arm, src, GetGPRSize());
+
+ if (WriteGPR()) {
+ src += GetGPRSize();
+ ::memcpy(&m_fpr, src, sizeof(m_fpr));
+
+ success = WriteFPR();
+ }
}
- return success;
+ }
+ return success;
}
-uint32_t
-RegisterContextPOSIXProcessMonitor_arm::SetHardwareWatchpoint(addr_t addr, size_t size,
- bool read, bool write)
-{
- const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
- uint32_t hw_index;
-
- for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index)
- {
- if (IsWatchpointVacant(hw_index))
- return SetHardwareWatchpointWithIndex(addr, size,
- read, write,
- hw_index);
- }
+uint32_t RegisterContextPOSIXProcessMonitor_arm::SetHardwareWatchpoint(
+ addr_t addr, size_t size, bool read, bool write) {
+ const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
+ uint32_t hw_index;
+
+ for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index) {
+ if (IsWatchpointVacant(hw_index))
+ return SetHardwareWatchpointWithIndex(addr, size, read, write, hw_index);
+ }
- return LLDB_INVALID_INDEX32;
+ return LLDB_INVALID_INDEX32;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::ClearHardwareWatchpoint(uint32_t hw_index)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_arm::ClearHardwareWatchpoint(
+ uint32_t hw_index) {
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::HardwareSingleStep(bool enable)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_arm::HardwareSingleStep(bool enable) {
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::UpdateAfterBreakpoint()
-{
- lldb::addr_t pc;
+bool RegisterContextPOSIXProcessMonitor_arm::UpdateAfterBreakpoint() {
+ lldb::addr_t pc;
- if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
- return false;
+ if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
+ return false;
- return true;
+ return true;
}
-unsigned
-RegisterContextPOSIXProcessMonitor_arm::GetRegisterIndexFromOffset(unsigned offset)
-{
- unsigned reg;
- for (reg = 0; reg < k_num_registers_arm; reg++)
- {
- if (GetRegisterInfo()[reg].byte_offset == offset)
- break;
- }
- assert(reg < k_num_registers_arm && "Invalid register offset.");
- return reg;
+unsigned RegisterContextPOSIXProcessMonitor_arm::GetRegisterIndexFromOffset(
+ unsigned offset) {
+ unsigned reg;
+ for (reg = 0; reg < k_num_registers_arm; reg++) {
+ if (GetRegisterInfo()[reg].byte_offset == offset)
+ break;
+ }
+ assert(reg < k_num_registers_arm && "Invalid register offset.");
+ return reg;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::IsWatchpointHit(uint32_t hw_index)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_arm::IsWatchpointHit(
+ uint32_t hw_index) {
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::ClearWatchpointHits()
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_arm::ClearWatchpointHits() {
+ return false;
}
-addr_t
-RegisterContextPOSIXProcessMonitor_arm::GetWatchpointAddress(uint32_t hw_index)
-{
- return LLDB_INVALID_ADDRESS;
+addr_t RegisterContextPOSIXProcessMonitor_arm::GetWatchpointAddress(
+ uint32_t hw_index) {
+ return LLDB_INVALID_ADDRESS;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::IsWatchpointVacant(uint32_t hw_index)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_arm::IsWatchpointVacant(
+ uint32_t hw_index) {
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm::SetHardwareWatchpointWithIndex(addr_t addr, size_t size,
- bool read, bool write,
- uint32_t hw_index)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_arm::SetHardwareWatchpointWithIndex(
+ addr_t addr, size_t size, bool read, bool write, uint32_t hw_index) {
+ return false;
}
uint32_t
-RegisterContextPOSIXProcessMonitor_arm::NumSupportedHardwareWatchpoints()
-{
- return 0;
+RegisterContextPOSIXProcessMonitor_arm::NumSupportedHardwareWatchpoints() {
+ return 0;
}
-
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.h b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.h
index 3787502a390c..6aa71c24f1cd 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.h
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.h
@@ -10,87 +10,68 @@
#ifndef liblldb_RegisterContextPOSIXProcessMonitor_arm_H_
#define liblldb_RegisterContextPOSIXProcessMonitor_arm_H_
-#include "RegisterContextPOSIX.h"
#include "Plugins/Process/Utility/RegisterContextPOSIX_arm.h"
+#include "RegisterContextPOSIX.h"
-class RegisterContextPOSIXProcessMonitor_arm:
- public RegisterContextPOSIX_arm,
- public POSIXBreakpointProtocol
-{
+class RegisterContextPOSIXProcessMonitor_arm : public RegisterContextPOSIX_arm,
+ public POSIXBreakpointProtocol {
public:
- RegisterContextPOSIXProcessMonitor_arm(lldb_private::Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info);
+ RegisterContextPOSIXProcessMonitor_arm(
+ lldb_private::Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info);
protected:
- bool
- ReadGPR();
+ bool ReadGPR();
- bool
- ReadFPR();
+ bool ReadFPR();
- bool
- WriteGPR();
+ bool WriteGPR();
- bool
- WriteFPR();
+ bool WriteFPR();
- // lldb_private::RegisterContext
- bool
- ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
+ // lldb_private::RegisterContext
+ bool ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
- bool
- WriteRegister(const unsigned reg, const lldb_private::RegisterValue &value);
+ bool WriteRegister(const unsigned reg,
+ const lldb_private::RegisterValue &value);
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value);
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value);
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value);
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
- uint32_t
- SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write);
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read,
+ bool write);
- bool
- ClearHardwareWatchpoint(uint32_t hw_index);
+ bool ClearHardwareWatchpoint(uint32_t hw_index);
- bool
- HardwareSingleStep(bool enable);
+ bool HardwareSingleStep(bool enable);
- // POSIXBreakpointProtocol
- bool
- UpdateAfterBreakpoint();
+ // POSIXBreakpointProtocol
+ bool UpdateAfterBreakpoint();
- unsigned
- GetRegisterIndexFromOffset(unsigned offset);
+ unsigned GetRegisterIndexFromOffset(unsigned offset);
- bool
- IsWatchpointHit(uint32_t hw_index);
+ bool IsWatchpointHit(uint32_t hw_index);
- bool
- ClearWatchpointHits();
+ bool ClearWatchpointHits();
- lldb::addr_t
- GetWatchpointAddress(uint32_t hw_index);
+ lldb::addr_t GetWatchpointAddress(uint32_t hw_index);
- bool
- IsWatchpointVacant(uint32_t hw_index);
+ bool IsWatchpointVacant(uint32_t hw_index);
- bool
- SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read, bool write, uint32_t hw_index);
+ bool SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read,
+ bool write, uint32_t hw_index);
- uint32_t
- NumSupportedHardwareWatchpoints();
+ uint32_t NumSupportedHardwareWatchpoints();
private:
- ProcessMonitor &
- GetMonitor();
+ ProcessMonitor &GetMonitor();
};
#endif
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp
index a1a0cab82a15..98a213a370fe 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp
@@ -21,298 +21,245 @@
using namespace lldb;
using namespace lldb_private;
-RegisterContextPOSIXProcessMonitor_arm64::RegisterContextPOSIXProcessMonitor_arm64(lldb_private::Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info)
- : RegisterContextPOSIX_arm64(thread, concrete_frame_idx, register_info)
-{
+RegisterContextPOSIXProcessMonitor_arm64::
+ RegisterContextPOSIXProcessMonitor_arm64(
+ lldb_private::Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info)
+ : RegisterContextPOSIX_arm64(thread, concrete_frame_idx, register_info) {}
+
+ProcessMonitor &RegisterContextPOSIXProcessMonitor_arm64::GetMonitor() {
+ lldb::ProcessSP base = CalculateProcess();
+ ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(base.get());
+ return process->GetMonitor();
}
-ProcessMonitor &
-RegisterContextPOSIXProcessMonitor_arm64::GetMonitor()
-{
- lldb::ProcessSP base = CalculateProcess();
- ProcessFreeBSD *process = static_cast<ProcessFreeBSD*>(base.get());
- return process->GetMonitor();
+bool RegisterContextPOSIXProcessMonitor_arm64::ReadGPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.ReadGPR(m_thread.GetID(), &m_gpr_arm64, GetGPRSize());
}
-bool
-RegisterContextPOSIXProcessMonitor_arm64::ReadGPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadGPR(m_thread.GetID(), &m_gpr_arm64, GetGPRSize());
+bool RegisterContextPOSIXProcessMonitor_arm64::ReadFPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.ReadFPR(m_thread.GetID(), &m_fpr, sizeof m_fpr);
}
-bool
-RegisterContextPOSIXProcessMonitor_arm64::ReadFPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadFPR(m_thread.GetID(), &m_fpr, sizeof m_fpr);
+bool RegisterContextPOSIXProcessMonitor_arm64::WriteGPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.WriteGPR(m_thread.GetID(), &m_gpr_arm64, GetGPRSize());
}
-bool
-RegisterContextPOSIXProcessMonitor_arm64::WriteGPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteGPR(m_thread.GetID(), &m_gpr_arm64, GetGPRSize());
+bool RegisterContextPOSIXProcessMonitor_arm64::WriteFPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.WriteFPR(m_thread.GetID(), &m_fpr, sizeof m_fpr);
}
-bool
-RegisterContextPOSIXProcessMonitor_arm64::WriteFPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteFPR(m_thread.GetID(), &m_fpr, sizeof m_fpr);
+bool RegisterContextPOSIXProcessMonitor_arm64::ReadRegister(
+ const unsigned reg, lldb_private::RegisterValue &value) {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.ReadRegisterValue(m_thread.GetID(), GetRegisterOffset(reg),
+ GetRegisterName(reg), GetRegisterSize(reg),
+ value);
}
-bool
-RegisterContextPOSIXProcessMonitor_arm64::ReadRegister(const unsigned reg,
- lldb_private::RegisterValue &value)
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadRegisterValue(m_thread.GetID(),
- GetRegisterOffset(reg),
- GetRegisterName(reg),
- GetRegisterSize(reg),
- value);
-}
-
-bool
-RegisterContextPOSIXProcessMonitor_arm64::WriteRegister(const unsigned reg,
- const lldb_private::RegisterValue &value)
-{
- unsigned reg_to_write = reg;
- lldb_private::RegisterValue value_to_write = value;
-
- // Check if this is a subregister of a full register.
- const lldb_private::RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
- if (reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM))
- {
- lldb_private::RegisterValue full_value;
- uint32_t full_reg = reg_info->invalidate_regs[0];
- const lldb_private::RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
-
- // Read the full register.
- if (ReadRegister(full_reg_info, full_value))
- {
- lldb_private::Error error;
- lldb::ByteOrder byte_order = GetByteOrder();
- uint8_t dst[lldb_private::RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the full register.
- const uint32_t dest_size = full_value.GetAsMemoryData (full_reg_info,
- dst,
- sizeof(dst),
- byte_order,
- error);
- if (error.Success() && dest_size)
- {
- uint8_t src[lldb_private::RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the source data.
- const uint32_t src_size = value.GetAsMemoryData (reg_info, src, sizeof(src), byte_order, error);
- if (error.Success() && src_size && (src_size < dest_size))
- {
- // Copy the src bytes to the destination.
- ::memcpy (dst + (reg_info->byte_offset & 0x1), src, src_size);
- // Set this full register as the value to write.
- value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
- value_to_write.SetType(full_reg_info);
- reg_to_write = full_reg;
- }
- }
+bool RegisterContextPOSIXProcessMonitor_arm64::WriteRegister(
+ const unsigned reg, const lldb_private::RegisterValue &value) {
+ unsigned reg_to_write = reg;
+ lldb_private::RegisterValue value_to_write = value;
+
+ // Check if this is a subregister of a full register.
+ const lldb_private::RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
+ if (reg_info->invalidate_regs &&
+ (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) {
+ lldb_private::RegisterValue full_value;
+ uint32_t full_reg = reg_info->invalidate_regs[0];
+ const lldb_private::RegisterInfo *full_reg_info =
+ GetRegisterInfoAtIndex(full_reg);
+
+ // Read the full register.
+ if (ReadRegister(full_reg_info, full_value)) {
+ lldb_private::Error error;
+ lldb::ByteOrder byte_order = GetByteOrder();
+ uint8_t dst[lldb_private::RegisterValue::kMaxRegisterByteSize];
+
+ // Get the bytes for the full register.
+ const uint32_t dest_size = full_value.GetAsMemoryData(
+ full_reg_info, dst, sizeof(dst), byte_order, error);
+ if (error.Success() && dest_size) {
+ uint8_t src[lldb_private::RegisterValue::kMaxRegisterByteSize];
+
+ // Get the bytes for the source data.
+ const uint32_t src_size = value.GetAsMemoryData(
+ reg_info, src, sizeof(src), byte_order, error);
+ if (error.Success() && src_size && (src_size < dest_size)) {
+ // Copy the src bytes to the destination.
+ ::memcpy(dst + (reg_info->byte_offset & 0x1), src, src_size);
+ // Set this full register as the value to write.
+ value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
+ value_to_write.SetType(full_reg_info);
+ reg_to_write = full_reg;
}
+ }
}
+ }
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteRegisterValue(m_thread.GetID(),
- GetRegisterOffset(reg_to_write),
- GetRegisterName(reg_to_write),
- value_to_write);
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.WriteRegisterValue(
+ m_thread.GetID(), GetRegisterOffset(reg_to_write),
+ GetRegisterName(reg_to_write), value_to_write);
}
-bool
-RegisterContextPOSIXProcessMonitor_arm64::ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value)
-{
- if (!reg_info)
- return false;
+bool RegisterContextPOSIXProcessMonitor_arm64::ReadRegister(
+ const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) {
+ if (!reg_info)
+ return false;
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (IsFPR(reg))
- {
- if (!ReadFPR())
- return false;
- }
- else
- {
- uint32_t full_reg = reg;
- bool is_subreg = reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
-
- if (is_subreg)
- {
- // Read the full aligned 64-bit register.
- full_reg = reg_info->invalidate_regs[0];
- }
- return ReadRegister(full_reg, value);
- }
+ if (IsFPR(reg)) {
+ if (!ReadFPR())
+ return false;
+ } else {
+ uint32_t full_reg = reg;
+ bool is_subreg = reg_info->invalidate_regs &&
+ (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
- // Get pointer to m_fpr variable and set the data from it.
- assert (reg_info->byte_offset < sizeof m_fpr);
- uint8_t *src = (uint8_t *)&m_fpr + reg_info->byte_offset;
- switch (reg_info->byte_size)
- {
- case 2:
- value.SetUInt16(*(uint16_t *)src);
- return true;
- case 4:
- value.SetUInt32(*(uint32_t *)src);
- return true;
- case 8:
- value.SetUInt64(*(uint64_t *)src);
- return true;
- default:
- assert(false && "Unhandled data size.");
- return false;
+ if (is_subreg) {
+ // Read the full aligned 64-bit register.
+ full_reg = reg_info->invalidate_regs[0];
}
+ return ReadRegister(full_reg, value);
+ }
+
+ // Get pointer to m_fpr variable and set the data from it.
+ assert(reg_info->byte_offset < sizeof m_fpr);
+ uint8_t *src = (uint8_t *)&m_fpr + reg_info->byte_offset;
+ switch (reg_info->byte_size) {
+ case 2:
+ value.SetUInt16(*(uint16_t *)src);
+ return true;
+ case 4:
+ value.SetUInt32(*(uint32_t *)src);
+ return true;
+ case 8:
+ value.SetUInt64(*(uint64_t *)src);
+ return true;
+ default:
+ assert(false && "Unhandled data size.");
+ return false;
+ }
}
-bool
-RegisterContextPOSIXProcessMonitor_arm64::WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value)
-{
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+bool RegisterContextPOSIXProcessMonitor_arm64::WriteRegister(
+ const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) {
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (IsGPR(reg))
- return WriteRegister(reg, value);
+ if (IsGPR(reg))
+ return WriteRegister(reg, value);
- return false;
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm64::ReadAllRegisterValues(lldb::DataBufferSP &data_sp)
-{
- bool success = false;
- data_sp.reset (new lldb_private::DataBufferHeap (REG_CONTEXT_SIZE, 0));
- if (data_sp && ReadGPR () && ReadFPR ())
- {
- uint8_t *dst = data_sp->GetBytes();
- success = dst != 0;
-
- if (success)
- {
- ::memcpy (dst, &m_gpr_arm64, GetGPRSize());
- dst += GetGPRSize();
- ::memcpy (dst, &m_fpr, sizeof m_fpr);
- }
+bool RegisterContextPOSIXProcessMonitor_arm64::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ bool success = false;
+ data_sp.reset(new lldb_private::DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (data_sp && ReadGPR() && ReadFPR()) {
+ uint8_t *dst = data_sp->GetBytes();
+ success = dst != 0;
+
+ if (success) {
+ ::memcpy(dst, &m_gpr_arm64, GetGPRSize());
+ dst += GetGPRSize();
+ ::memcpy(dst, &m_fpr, sizeof m_fpr);
}
- return success;
+ }
+ return success;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm64::WriteAllRegisterValues(const lldb::DataBufferSP &data_sp)
-{
- bool success = false;
- if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE)
- {
- uint8_t *src = data_sp->GetBytes();
- if (src)
- {
- ::memcpy (&m_gpr_arm64, src, GetGPRSize());
- if (WriteGPR()) {
- src += GetGPRSize();
- ::memcpy (&m_fpr, src, sizeof m_fpr);
- success = WriteFPR();
- }
- }
+bool RegisterContextPOSIXProcessMonitor_arm64::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ bool success = false;
+ if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
+ uint8_t *src = data_sp->GetBytes();
+ if (src) {
+ ::memcpy(&m_gpr_arm64, src, GetGPRSize());
+ if (WriteGPR()) {
+ src += GetGPRSize();
+ ::memcpy(&m_fpr, src, sizeof m_fpr);
+ success = WriteFPR();
+ }
}
- return success;
+ }
+ return success;
}
-uint32_t
-RegisterContextPOSIXProcessMonitor_arm64::SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
- bool read, bool write)
-{
- const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
- uint32_t hw_index;
-
- for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index)
- {
- if (IsWatchpointVacant(hw_index))
- return SetHardwareWatchpointWithIndex(addr, size,
- read, write,
- hw_index);
- }
+uint32_t RegisterContextPOSIXProcessMonitor_arm64::SetHardwareWatchpoint(
+ lldb::addr_t addr, size_t size, bool read, bool write) {
+ const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
+ uint32_t hw_index;
+
+ for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index) {
+ if (IsWatchpointVacant(hw_index))
+ return SetHardwareWatchpointWithIndex(addr, size, read, write, hw_index);
+ }
- return LLDB_INVALID_INDEX32;
+ return LLDB_INVALID_INDEX32;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm64::ClearHardwareWatchpoint(uint32_t hw_index)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_arm64::ClearHardwareWatchpoint(
+ uint32_t hw_index) {
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm64::HardwareSingleStep(bool enable)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_arm64::HardwareSingleStep(bool enable) {
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm64::UpdateAfterBreakpoint()
-{
- if (GetPC() == LLDB_INVALID_ADDRESS)
- return false;
+bool RegisterContextPOSIXProcessMonitor_arm64::UpdateAfterBreakpoint() {
+ if (GetPC() == LLDB_INVALID_ADDRESS)
+ return false;
- return true;
+ return true;
}
-unsigned
-RegisterContextPOSIXProcessMonitor_arm64::GetRegisterIndexFromOffset(unsigned offset)
-{
- unsigned reg;
- for (reg = 0; reg < k_num_registers_arm64; reg++)
- {
- if (GetRegisterInfo()[reg].byte_offset == offset)
- break;
- }
- assert(reg < k_num_registers_arm64 && "Invalid register offset.");
- return reg;
+unsigned RegisterContextPOSIXProcessMonitor_arm64::GetRegisterIndexFromOffset(
+ unsigned offset) {
+ unsigned reg;
+ for (reg = 0; reg < k_num_registers_arm64; reg++) {
+ if (GetRegisterInfo()[reg].byte_offset == offset)
+ break;
+ }
+ assert(reg < k_num_registers_arm64 && "Invalid register offset.");
+ return reg;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm64::IsWatchpointHit(uint32_t hw_index)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_arm64::IsWatchpointHit(
+ uint32_t hw_index) {
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm64::ClearWatchpointHits()
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_arm64::ClearWatchpointHits() {
+ return false;
}
-lldb::addr_t
-RegisterContextPOSIXProcessMonitor_arm64::GetWatchpointAddress(uint32_t hw_index)
-{
- return LLDB_INVALID_ADDRESS;
+lldb::addr_t RegisterContextPOSIXProcessMonitor_arm64::GetWatchpointAddress(
+ uint32_t hw_index) {
+ return LLDB_INVALID_ADDRESS;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm64::IsWatchpointVacant(uint32_t hw_index)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_arm64::IsWatchpointVacant(
+ uint32_t hw_index) {
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_arm64::SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size,
- bool read, bool write,
- uint32_t hw_index)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_arm64::SetHardwareWatchpointWithIndex(
+ lldb::addr_t addr, size_t size, bool read, bool write, uint32_t hw_index) {
+ return false;
}
uint32_t
-RegisterContextPOSIXProcessMonitor_arm64::NumSupportedHardwareWatchpoints()
-{
- return 0;
+RegisterContextPOSIXProcessMonitor_arm64::NumSupportedHardwareWatchpoints() {
+ return 0;
}
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.h b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.h
index 729385c4a76e..8591c83be541 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.h
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.h
@@ -10,87 +10,69 @@
#ifndef liblldb_RegisterContextPOSIXProcessMonitor_arm64_H_
#define liblldb_RegisterContextPOSIXProcessMonitor_arm64_H_
-#include "RegisterContextPOSIX.h"
#include "Plugins/Process/Utility/RegisterContextPOSIX_arm64.h"
+#include "RegisterContextPOSIX.h"
-class RegisterContextPOSIXProcessMonitor_arm64:
- public RegisterContextPOSIX_arm64,
- public POSIXBreakpointProtocol
-{
+class RegisterContextPOSIXProcessMonitor_arm64
+ : public RegisterContextPOSIX_arm64,
+ public POSIXBreakpointProtocol {
public:
- RegisterContextPOSIXProcessMonitor_arm64(lldb_private::Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info);
+ RegisterContextPOSIXProcessMonitor_arm64(
+ lldb_private::Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info);
protected:
- bool
- ReadGPR();
+ bool ReadGPR();
- bool
- ReadFPR();
+ bool ReadFPR();
- bool
- WriteGPR();
+ bool WriteGPR();
- bool
- WriteFPR();
+ bool WriteFPR();
- // lldb_private::RegisterContext
- bool
- ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
+ // lldb_private::RegisterContext
+ bool ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
- bool
- WriteRegister(const unsigned reg, const lldb_private::RegisterValue &value);
+ bool WriteRegister(const unsigned reg,
+ const lldb_private::RegisterValue &value);
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value);
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value);
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value);
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
- uint32_t
- SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write);
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read,
+ bool write);
- bool
- ClearHardwareWatchpoint(uint32_t hw_index);
+ bool ClearHardwareWatchpoint(uint32_t hw_index);
- bool
- HardwareSingleStep(bool enable);
+ bool HardwareSingleStep(bool enable);
- // POSIXBreakpointProtocol
- bool
- UpdateAfterBreakpoint();
+ // POSIXBreakpointProtocol
+ bool UpdateAfterBreakpoint();
- unsigned
- GetRegisterIndexFromOffset(unsigned offset);
+ unsigned GetRegisterIndexFromOffset(unsigned offset);
- bool
- IsWatchpointHit(uint32_t hw_index);
+ bool IsWatchpointHit(uint32_t hw_index);
- bool
- ClearWatchpointHits();
+ bool ClearWatchpointHits();
- lldb::addr_t
- GetWatchpointAddress(uint32_t hw_index);
+ lldb::addr_t GetWatchpointAddress(uint32_t hw_index);
- bool
- IsWatchpointVacant(uint32_t hw_index);
+ bool IsWatchpointVacant(uint32_t hw_index);
- bool
- SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read, bool write, uint32_t hw_index);
+ bool SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read,
+ bool write, uint32_t hw_index);
- uint32_t
- NumSupportedHardwareWatchpoints();
+ uint32_t NumSupportedHardwareWatchpoints();
private:
- ProcessMonitor &
- GetMonitor();
+ ProcessMonitor &GetMonitor();
};
#endif
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp
index eeada4b16337..020636eb0a6b 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp
@@ -1,11 +1,11 @@
-//===-- RegisterContextPOSIXProcessMonitor_mips64.h ------------*- C++ -*-===//
+//===-- RegisterContextPOSIXProcessMonitor_mips64.cpp -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
-//===---------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/RegisterValue.h"
@@ -21,298 +21,243 @@ using namespace lldb;
#define REG_CONTEXT_SIZE (GetGPRSize())
-RegisterContextPOSIXProcessMonitor_mips64::RegisterContextPOSIXProcessMonitor_mips64(Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info)
- : RegisterContextPOSIX_mips64(thread, concrete_frame_idx, register_info)
-{
-}
+RegisterContextPOSIXProcessMonitor_mips64::
+ RegisterContextPOSIXProcessMonitor_mips64(
+ Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info)
+ : RegisterContextPOSIX_mips64(thread, concrete_frame_idx, register_info) {}
-ProcessMonitor &
-RegisterContextPOSIXProcessMonitor_mips64::GetMonitor()
-{
- ProcessSP base = CalculateProcess();
- ProcessFreeBSD *process = static_cast<ProcessFreeBSD*>(base.get());
- return process->GetMonitor();
+ProcessMonitor &RegisterContextPOSIXProcessMonitor_mips64::GetMonitor() {
+ ProcessSP base = CalculateProcess();
+ ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(base.get());
+ return process->GetMonitor();
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::ReadGPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadGPR(m_thread.GetID(), &m_gpr_mips64, GetGPRSize());
+bool RegisterContextPOSIXProcessMonitor_mips64::ReadGPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.ReadGPR(m_thread.GetID(), &m_gpr_mips64, GetGPRSize());
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::ReadFPR()
-{
- // XXX not yet implemented
- return false;
+bool RegisterContextPOSIXProcessMonitor_mips64::ReadFPR() {
+ // XXX not yet implemented
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::WriteGPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteGPR(m_thread.GetID(), &m_gpr_mips64, GetGPRSize());
+bool RegisterContextPOSIXProcessMonitor_mips64::WriteGPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.WriteGPR(m_thread.GetID(), &m_gpr_mips64, GetGPRSize());
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::WriteFPR()
-{
- // XXX not yet implemented
- return false;
+bool RegisterContextPOSIXProcessMonitor_mips64::WriteFPR() {
+ // XXX not yet implemented
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::ReadRegister(const unsigned reg,
- RegisterValue &value)
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadRegisterValue(m_thread.GetID(),
- GetRegisterOffset(reg),
- GetRegisterName(reg),
- GetRegisterSize(reg),
- value);
+bool RegisterContextPOSIXProcessMonitor_mips64::ReadRegister(
+ const unsigned reg, RegisterValue &value) {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.ReadRegisterValue(m_thread.GetID(), GetRegisterOffset(reg),
+ GetRegisterName(reg), GetRegisterSize(reg),
+ value);
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::WriteRegister(const unsigned reg,
- const RegisterValue &value)
-{
- unsigned reg_to_write = reg;
- RegisterValue value_to_write = value;
-
- // Check if this is a subregister of a full register.
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
- if (reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM))
- {
- RegisterValue full_value;
- uint32_t full_reg = reg_info->invalidate_regs[0];
- const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
-
- // Read the full register.
- if (ReadRegister(full_reg_info, full_value))
- {
- Error error;
- ByteOrder byte_order = GetByteOrder();
- uint8_t dst[RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the full register.
- const uint32_t dest_size = full_value.GetAsMemoryData (full_reg_info,
- dst,
- sizeof(dst),
- byte_order,
- error);
- if (error.Success() && dest_size)
- {
- uint8_t src[RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the source data.
- const uint32_t src_size = value.GetAsMemoryData (reg_info, src, sizeof(src), byte_order, error);
- if (error.Success() && src_size && (src_size < dest_size))
- {
- // Copy the src bytes to the destination.
- memcpy (dst + (reg_info->byte_offset & 0x1), src, src_size);
- // Set this full register as the value to write.
- value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
- value_to_write.SetType(full_reg_info);
- reg_to_write = full_reg;
- }
- }
+bool RegisterContextPOSIXProcessMonitor_mips64::WriteRegister(
+ const unsigned reg, const RegisterValue &value) {
+ unsigned reg_to_write = reg;
+ RegisterValue value_to_write = value;
+
+ // Check if this is a subregister of a full register.
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
+ if (reg_info->invalidate_regs &&
+ (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) {
+ RegisterValue full_value;
+ uint32_t full_reg = reg_info->invalidate_regs[0];
+ const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
+
+ // Read the full register.
+ if (ReadRegister(full_reg_info, full_value)) {
+ Error error;
+ ByteOrder byte_order = GetByteOrder();
+ uint8_t dst[RegisterValue::kMaxRegisterByteSize];
+
+ // Get the bytes for the full register.
+ const uint32_t dest_size = full_value.GetAsMemoryData(
+ full_reg_info, dst, sizeof(dst), byte_order, error);
+ if (error.Success() && dest_size) {
+ uint8_t src[RegisterValue::kMaxRegisterByteSize];
+
+ // Get the bytes for the source data.
+ const uint32_t src_size = value.GetAsMemoryData(
+ reg_info, src, sizeof(src), byte_order, error);
+ if (error.Success() && src_size && (src_size < dest_size)) {
+ // Copy the src bytes to the destination.
+ memcpy(dst + (reg_info->byte_offset & 0x1), src, src_size);
+ // Set this full register as the value to write.
+ value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
+ value_to_write.SetType(full_reg_info);
+ reg_to_write = full_reg;
}
+ }
}
+ }
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteRegisterValue(m_thread.GetID(),
- GetRegisterOffset(reg_to_write),
- GetRegisterName(reg_to_write),
- value_to_write);
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.WriteRegisterValue(
+ m_thread.GetID(), GetRegisterOffset(reg_to_write),
+ GetRegisterName(reg_to_write), value_to_write);
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
-{
- if (!reg_info)
- return false;
+bool RegisterContextPOSIXProcessMonitor_mips64::ReadRegister(
+ const RegisterInfo *reg_info, RegisterValue &value) {
+ if (!reg_info)
+ return false;
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- if (IsFPR(reg))
- {
- if (!ReadFPR())
- return false;
+ if (IsFPR(reg)) {
+ if (!ReadFPR())
+ return false;
+ } else {
+ uint32_t full_reg = reg;
+ bool is_subreg = reg_info->invalidate_regs &&
+ (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
+
+ if (is_subreg) {
+ // Read the full aligned 64-bit register.
+ full_reg = reg_info->invalidate_regs[0];
}
- else
- {
- uint32_t full_reg = reg;
- bool is_subreg = reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
-
- if (is_subreg)
- {
- // Read the full aligned 64-bit register.
- full_reg = reg_info->invalidate_regs[0];
- }
- bool success = ReadRegister(full_reg, value);
+ bool success = ReadRegister(full_reg, value);
- if (success)
- {
- // If our read was not aligned (for ah,bh,ch,dh), shift our returned value one byte to the right.
- if (is_subreg && (reg_info->byte_offset & 0x1))
- value.SetUInt64(value.GetAsUInt64() >> 8);
+ if (success) {
+ // If our read was not aligned (for ah,bh,ch,dh), shift our returned value
+ // one byte to the right.
+ if (is_subreg && (reg_info->byte_offset & 0x1))
+ value.SetUInt64(value.GetAsUInt64() >> 8);
- // If our return byte size was greater than the return value reg size, then
- // use the type specified by reg_info rather than the uint64_t default
- if (value.GetByteSize() > reg_info->byte_size)
- value.SetType(reg_info);
- }
- return success;
+ // If our return byte size was greater than the return value reg size,
+ // then
+ // use the type specified by reg_info rather than the uint64_t default
+ if (value.GetByteSize() > reg_info->byte_size)
+ value.SetType(reg_info);
}
+ return success;
+ }
- return false;
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value)
-{
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+bool RegisterContextPOSIXProcessMonitor_mips64::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &value) {
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- if (IsGPR(reg))
- return WriteRegister(reg, value);
+ if (IsGPR(reg))
+ return WriteRegister(reg, value);
- return false;
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::ReadAllRegisterValues(DataBufferSP &data_sp)
-{
- bool success = false;
- data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
- if (data_sp && ReadGPR () && ReadFPR ())
- {
- uint8_t *dst = data_sp->GetBytes();
- success = dst != 0;
-
- if (success)
- {
- ::memcpy (dst, &m_gpr_mips64, GetGPRSize());
- }
+bool RegisterContextPOSIXProcessMonitor_mips64::ReadAllRegisterValues(
+ DataBufferSP &data_sp) {
+ bool success = false;
+ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (data_sp && ReadGPR() && ReadFPR()) {
+ uint8_t *dst = data_sp->GetBytes();
+ success = dst != 0;
+
+ if (success) {
+ ::memcpy(dst, &m_gpr_mips64, GetGPRSize());
}
- return success;
+ }
+ return success;
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::WriteAllRegisterValues(const DataBufferSP &data_sp)
-{
- bool success = false;
- if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE)
- {
- uint8_t *src = data_sp->GetBytes();
- if (src)
- {
- ::memcpy (&m_gpr_mips64, src, GetGPRSize());
-
- if (WriteGPR())
- {
- src += GetGPRSize();
- }
- }
+bool RegisterContextPOSIXProcessMonitor_mips64::WriteAllRegisterValues(
+ const DataBufferSP &data_sp) {
+ bool success = false;
+ if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
+ uint8_t *src = data_sp->GetBytes();
+ if (src) {
+ ::memcpy(&m_gpr_mips64, src, GetGPRSize());
+
+ if (WriteGPR()) {
+ src += GetGPRSize();
+ }
}
- return success;
+ }
+ return success;
}
-uint32_t
-RegisterContextPOSIXProcessMonitor_mips64::SetHardwareWatchpoint(addr_t addr, size_t size,
- bool read, bool write)
-{
- const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
- uint32_t hw_index;
-
- for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index)
- {
- if (IsWatchpointVacant(hw_index))
- return SetHardwareWatchpointWithIndex(addr, size,
- read, write,
- hw_index);
- }
+uint32_t RegisterContextPOSIXProcessMonitor_mips64::SetHardwareWatchpoint(
+ addr_t addr, size_t size, bool read, bool write) {
+ const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
+ uint32_t hw_index;
+
+ for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index) {
+ if (IsWatchpointVacant(hw_index))
+ return SetHardwareWatchpointWithIndex(addr, size, read, write, hw_index);
+ }
- return LLDB_INVALID_INDEX32;
+ return LLDB_INVALID_INDEX32;
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::ClearHardwareWatchpoint(uint32_t hw_index)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_mips64::ClearHardwareWatchpoint(
+ uint32_t hw_index) {
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::HardwareSingleStep(bool enable)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_mips64::HardwareSingleStep(
+ bool enable) {
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::UpdateAfterBreakpoint()
-{
- // PC points one byte past the int3 responsible for the breakpoint.
- lldb::addr_t pc;
+bool RegisterContextPOSIXProcessMonitor_mips64::UpdateAfterBreakpoint() {
+ // PC points one byte past the int3 responsible for the breakpoint.
+ lldb::addr_t pc;
- if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
- return false;
+ if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
+ return false;
- SetPC(pc - 1);
- return true;
+ SetPC(pc - 1);
+ return true;
}
-unsigned
-RegisterContextPOSIXProcessMonitor_mips64::GetRegisterIndexFromOffset(unsigned offset)
-{
- unsigned reg;
- for (reg = 0; reg < k_num_registers_mips64; reg++)
- {
- if (GetRegisterInfo()[reg].byte_offset == offset)
- break;
- }
- assert(reg < k_num_registers_mips64 && "Invalid register offset.");
- return reg;
+unsigned RegisterContextPOSIXProcessMonitor_mips64::GetRegisterIndexFromOffset(
+ unsigned offset) {
+ unsigned reg;
+ for (reg = 0; reg < k_num_registers_mips64; reg++) {
+ if (GetRegisterInfo()[reg].byte_offset == offset)
+ break;
+ }
+ assert(reg < k_num_registers_mips64 && "Invalid register offset.");
+ return reg;
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::IsWatchpointHit(uint32_t hw_index)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_mips64::IsWatchpointHit(
+ uint32_t hw_index) {
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::ClearWatchpointHits()
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_mips64::ClearWatchpointHits() {
+ return false;
}
-addr_t
-RegisterContextPOSIXProcessMonitor_mips64::GetWatchpointAddress(uint32_t hw_index)
-{
- return LLDB_INVALID_ADDRESS;
+addr_t RegisterContextPOSIXProcessMonitor_mips64::GetWatchpointAddress(
+ uint32_t hw_index) {
+ return LLDB_INVALID_ADDRESS;
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::IsWatchpointVacant(uint32_t hw_index)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_mips64::IsWatchpointVacant(
+ uint32_t hw_index) {
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_mips64::SetHardwareWatchpointWithIndex(addr_t addr, size_t size,
- bool read, bool write,
- uint32_t hw_index)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_mips64::SetHardwareWatchpointWithIndex(
+ addr_t addr, size_t size, bool read, bool write, uint32_t hw_index) {
+ return false;
}
uint32_t
-RegisterContextPOSIXProcessMonitor_mips64::NumSupportedHardwareWatchpoints()
-{
- return 0;
+RegisterContextPOSIXProcessMonitor_mips64::NumSupportedHardwareWatchpoints() {
+ return 0;
}
-
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.h b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.h
index e61621bec197..2f75e6058fbc 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.h
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.h
@@ -10,87 +10,69 @@
#ifndef liblldb_RegisterContextPOSIXProcessMonitor_mips64_H_
#define liblldb_RegisterContextPOSIXProcessMonitor_mips64_H_
-#include "RegisterContextPOSIX.h"
#include "Plugins/Process/Utility/RegisterContextPOSIX_mips64.h"
+#include "RegisterContextPOSIX.h"
-class RegisterContextPOSIXProcessMonitor_mips64:
- public RegisterContextPOSIX_mips64,
- public POSIXBreakpointProtocol
-{
+class RegisterContextPOSIXProcessMonitor_mips64
+ : public RegisterContextPOSIX_mips64,
+ public POSIXBreakpointProtocol {
public:
- RegisterContextPOSIXProcessMonitor_mips64(lldb_private::Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info);
+ RegisterContextPOSIXProcessMonitor_mips64(
+ lldb_private::Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info);
protected:
- bool
- ReadGPR();
+ bool ReadGPR();
- bool
- ReadFPR();
+ bool ReadFPR();
- bool
- WriteGPR();
+ bool WriteGPR();
- bool
- WriteFPR();
+ bool WriteFPR();
- // lldb_private::RegisterContext
- bool
- ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
+ // lldb_private::RegisterContext
+ bool ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
- bool
- WriteRegister(const unsigned reg, const lldb_private::RegisterValue &value);
+ bool WriteRegister(const unsigned reg,
+ const lldb_private::RegisterValue &value);
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value);
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value);
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value);
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
- uint32_t
- SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write);
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read,
+ bool write);
- bool
- ClearHardwareWatchpoint(uint32_t hw_index);
+ bool ClearHardwareWatchpoint(uint32_t hw_index);
- bool
- HardwareSingleStep(bool enable);
+ bool HardwareSingleStep(bool enable);
- // POSIXBreakpointProtocol
- bool
- UpdateAfterBreakpoint();
+ // POSIXBreakpointProtocol
+ bool UpdateAfterBreakpoint();
- unsigned
- GetRegisterIndexFromOffset(unsigned offset);
+ unsigned GetRegisterIndexFromOffset(unsigned offset);
- bool
- IsWatchpointHit(uint32_t hw_index);
+ bool IsWatchpointHit(uint32_t hw_index);
- bool
- ClearWatchpointHits();
+ bool ClearWatchpointHits();
- lldb::addr_t
- GetWatchpointAddress(uint32_t hw_index);
+ lldb::addr_t GetWatchpointAddress(uint32_t hw_index);
- bool
- IsWatchpointVacant(uint32_t hw_index);
+ bool IsWatchpointVacant(uint32_t hw_index);
- bool
- SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read, bool write, uint32_t hw_index);
+ bool SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read,
+ bool write, uint32_t hw_index);
- uint32_t
- NumSupportedHardwareWatchpoints();
+ uint32_t NumSupportedHardwareWatchpoints();
private:
- ProcessMonitor &
- GetMonitor();
+ ProcessMonitor &GetMonitor();
};
#endif
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp
index 321e6ea262ce..e7b01fa8634a 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp
@@ -1,337 +1,275 @@
-//===-- RegisterContextPOSIXProcessMonitor_powerpc.h ------------*- C++ -*-===//
+//===-- RegisterContextPOSIXProcessMonitor_powerpc.cpp ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
-//===---------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Thread.h"
-#include "RegisterContextPOSIX_powerpc.h"
#include "ProcessFreeBSD.h"
-#include "RegisterContextPOSIXProcessMonitor_powerpc.h"
#include "ProcessMonitor.h"
+#include "RegisterContextPOSIXProcessMonitor_powerpc.h"
+#include "RegisterContextPOSIX_powerpc.h"
using namespace lldb_private;
using namespace lldb;
#define REG_CONTEXT_SIZE (GetGPRSize())
-RegisterContextPOSIXProcessMonitor_powerpc::RegisterContextPOSIXProcessMonitor_powerpc(Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info)
- : RegisterContextPOSIX_powerpc(thread, concrete_frame_idx, register_info)
-{
-}
+RegisterContextPOSIXProcessMonitor_powerpc::
+ RegisterContextPOSIXProcessMonitor_powerpc(
+ Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info)
+ : RegisterContextPOSIX_powerpc(thread, concrete_frame_idx, register_info) {}
-ProcessMonitor &
-RegisterContextPOSIXProcessMonitor_powerpc::GetMonitor()
-{
- ProcessSP base = CalculateProcess();
- ProcessFreeBSD *process = static_cast<ProcessFreeBSD*>(base.get());
- return process->GetMonitor();
+ProcessMonitor &RegisterContextPOSIXProcessMonitor_powerpc::GetMonitor() {
+ ProcessSP base = CalculateProcess();
+ ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(base.get());
+ return process->GetMonitor();
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::ReadGPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadGPR(m_thread.GetID(), &m_gpr_powerpc, GetGPRSize());
+bool RegisterContextPOSIXProcessMonitor_powerpc::ReadGPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.ReadGPR(m_thread.GetID(), &m_gpr_powerpc, GetGPRSize());
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::ReadFPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadFPR(m_thread.GetID(), &m_fpr_powerpc, sizeof(m_fpr_powerpc));
+bool RegisterContextPOSIXProcessMonitor_powerpc::ReadFPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.ReadFPR(m_thread.GetID(), &m_fpr_powerpc,
+ sizeof(m_fpr_powerpc));
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::ReadVMX()
-{
- // XXX: Need a way to read/write process VMX registers with ptrace.
- return false;
+bool RegisterContextPOSIXProcessMonitor_powerpc::ReadVMX() {
+ // XXX: Need a way to read/write process VMX registers with ptrace.
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::WriteGPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteGPR(m_thread.GetID(), &m_gpr_powerpc, GetGPRSize());
+bool RegisterContextPOSIXProcessMonitor_powerpc::WriteGPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.WriteGPR(m_thread.GetID(), &m_gpr_powerpc, GetGPRSize());
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::WriteFPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteFPR(m_thread.GetID(), &m_fpr_powerpc, sizeof(m_fpr_powerpc));
+bool RegisterContextPOSIXProcessMonitor_powerpc::WriteFPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.WriteFPR(m_thread.GetID(), &m_fpr_powerpc,
+ sizeof(m_fpr_powerpc));
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::WriteVMX()
-{
- // XXX: Need a way to read/write process VMX registers with ptrace.
- return false;
+bool RegisterContextPOSIXProcessMonitor_powerpc::WriteVMX() {
+ // XXX: Need a way to read/write process VMX registers with ptrace.
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::ReadRegister(const unsigned reg,
- RegisterValue &value)
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadRegisterValue(m_thread.GetID(),
- GetRegisterOffset(reg),
- GetRegisterName(reg),
- GetRegisterSize(reg),
- value);
+bool RegisterContextPOSIXProcessMonitor_powerpc::ReadRegister(
+ const unsigned reg, RegisterValue &value) {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.ReadRegisterValue(m_thread.GetID(), GetRegisterOffset(reg),
+ GetRegisterName(reg), GetRegisterSize(reg),
+ value);
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::WriteRegister(const unsigned reg,
- const RegisterValue &value)
-{
- unsigned reg_to_write = reg;
- RegisterValue value_to_write = value;
-
- // Check if this is a subregister of a full register.
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
- if (reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM))
- {
- RegisterValue full_value;
- uint32_t full_reg = reg_info->invalidate_regs[0];
- const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
-
- // Read the full register.
- if (ReadRegister(full_reg_info, full_value))
- {
- Error error;
- ByteOrder byte_order = GetByteOrder();
- uint8_t dst[RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the full register.
- const uint32_t dest_size = full_value.GetAsMemoryData (full_reg_info,
- dst,
- sizeof(dst),
- byte_order,
- error);
- if (error.Success() && dest_size)
- {
- uint8_t src[RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the source data.
- const uint32_t src_size = value.GetAsMemoryData (reg_info, src, sizeof(src), byte_order, error);
- if (error.Success() && src_size && (src_size < dest_size))
- {
- // Copy the src bytes to the destination.
- memcpy (dst + (reg_info->byte_offset & 0x1), src, src_size);
- // Set this full register as the value to write.
- value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
- value_to_write.SetType(full_reg_info);
- reg_to_write = full_reg;
- }
- }
+bool RegisterContextPOSIXProcessMonitor_powerpc::WriteRegister(
+ const unsigned reg, const RegisterValue &value) {
+ unsigned reg_to_write = reg;
+ RegisterValue value_to_write = value;
+
+ // Check if this is a subregister of a full register.
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
+ if (reg_info->invalidate_regs &&
+ (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) {
+ RegisterValue full_value;
+ uint32_t full_reg = reg_info->invalidate_regs[0];
+ const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
+
+ // Read the full register.
+ if (ReadRegister(full_reg_info, full_value)) {
+ Error error;
+ ByteOrder byte_order = GetByteOrder();
+ uint8_t dst[RegisterValue::kMaxRegisterByteSize];
+
+ // Get the bytes for the full register.
+ const uint32_t dest_size = full_value.GetAsMemoryData(
+ full_reg_info, dst, sizeof(dst), byte_order, error);
+ if (error.Success() && dest_size) {
+ uint8_t src[RegisterValue::kMaxRegisterByteSize];
+
+ // Get the bytes for the source data.
+ const uint32_t src_size = value.GetAsMemoryData(
+ reg_info, src, sizeof(src), byte_order, error);
+ if (error.Success() && src_size && (src_size < dest_size)) {
+ // Copy the src bytes to the destination.
+ memcpy(dst + (reg_info->byte_offset & 0x1), src, src_size);
+ // Set this full register as the value to write.
+ value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
+ value_to_write.SetType(full_reg_info);
+ reg_to_write = full_reg;
}
+ }
}
-
- ProcessMonitor &monitor = GetMonitor();
- // Account for the fact that 32-bit targets on powerpc64 really use 64-bit
- // registers in ptrace, but expose here 32-bit registers with a higher
- // offset.
- uint64_t offset = GetRegisterOffset(reg_to_write);
- offset &= ~(sizeof(uintptr_t) - 1);
- return monitor.WriteRegisterValue(m_thread.GetID(),
- offset,
- GetRegisterName(reg_to_write),
- value_to_write);
+ }
+
+ ProcessMonitor &monitor = GetMonitor();
+ // Account for the fact that 32-bit targets on powerpc64 really use 64-bit
+ // registers in ptrace, but expose here 32-bit registers with a higher
+ // offset.
+ uint64_t offset = GetRegisterOffset(reg_to_write);
+ offset &= ~(sizeof(uintptr_t) - 1);
+ return monitor.WriteRegisterValue(
+ m_thread.GetID(), offset, GetRegisterName(reg_to_write), value_to_write);
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
-{
- if (!reg_info)
- return false;
-
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+bool RegisterContextPOSIXProcessMonitor_powerpc::ReadRegister(
+ const RegisterInfo *reg_info, RegisterValue &value) {
+ if (!reg_info)
+ return false;
- if (IsFPR(reg))
- {
- if (!ReadFPR())
- return false;
- uint8_t *src = (uint8_t *)&m_fpr_powerpc + reg_info->byte_offset;
- value.SetUInt64(*(uint64_t*)src);
- }
- else if (IsGPR(reg))
- {
- bool success = ReadRegister(reg, value);
-
- if (success)
- {
- // If our return byte size was greater than the return value reg size, then
- // use the type specified by reg_info rather than the uint64_t default
- if (value.GetByteSize() > reg_info->byte_size)
- value.SetType(reg_info);
- }
- return success;
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+
+ if (IsFPR(reg)) {
+ if (!ReadFPR())
+ return false;
+ uint8_t *src = (uint8_t *)&m_fpr_powerpc + reg_info->byte_offset;
+ value.SetUInt64(*(uint64_t *)src);
+ } else if (IsGPR(reg)) {
+ bool success = ReadRegister(reg, value);
+
+ if (success) {
+ // If our return byte size was greater than the return value reg size,
+ // then
+ // use the type specified by reg_info rather than the uint64_t default
+ if (value.GetByteSize() > reg_info->byte_size)
+ value.SetType(reg_info);
}
+ return success;
+ }
- return false;
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value)
-{
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+bool RegisterContextPOSIXProcessMonitor_powerpc::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &value) {
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- if (IsGPR(reg))
- {
- return WriteRegister(reg, value);
- }
- else if (IsFPR(reg))
- {
- assert (reg_info->byte_offset < sizeof(m_fpr_powerpc));
- uint8_t *dst = (uint8_t *)&m_fpr_powerpc + reg_info->byte_offset;
- *(uint64_t *)dst = value.GetAsUInt64();
- return WriteFPR();
- }
+ if (IsGPR(reg)) {
+ return WriteRegister(reg, value);
+ } else if (IsFPR(reg)) {
+ assert(reg_info->byte_offset < sizeof(m_fpr_powerpc));
+ uint8_t *dst = (uint8_t *)&m_fpr_powerpc + reg_info->byte_offset;
+ *(uint64_t *)dst = value.GetAsUInt64();
+ return WriteFPR();
+ }
- return false;
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::ReadAllRegisterValues(DataBufferSP &data_sp)
-{
- bool success = false;
- data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
- if (data_sp && ReadGPR () && ReadFPR ())
- {
- uint8_t *dst = data_sp->GetBytes();
- success = dst != 0;
-
- if (success)
- {
- ::memcpy (dst, &m_gpr_powerpc, GetGPRSize());
- dst += GetGPRSize();
- }
+bool RegisterContextPOSIXProcessMonitor_powerpc::ReadAllRegisterValues(
+ DataBufferSP &data_sp) {
+ bool success = false;
+ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (data_sp && ReadGPR() && ReadFPR()) {
+ uint8_t *dst = data_sp->GetBytes();
+ success = dst != 0;
+
+ if (success) {
+ ::memcpy(dst, &m_gpr_powerpc, GetGPRSize());
+ dst += GetGPRSize();
}
- return success;
+ }
+ return success;
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::WriteAllRegisterValues(const DataBufferSP &data_sp)
-{
- bool success = false;
- if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE)
- {
- uint8_t *src = data_sp->GetBytes();
- if (src)
- {
- ::memcpy (&m_gpr_powerpc, src, GetGPRSize());
-
- if (WriteGPR())
- {
- src += GetGPRSize();
- ::memcpy (&m_fpr_powerpc, src, sizeof(m_fpr_powerpc));
-
- success = WriteFPR();
- }
- }
+bool RegisterContextPOSIXProcessMonitor_powerpc::WriteAllRegisterValues(
+ const DataBufferSP &data_sp) {
+ bool success = false;
+ if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
+ uint8_t *src = data_sp->GetBytes();
+ if (src) {
+ ::memcpy(&m_gpr_powerpc, src, GetGPRSize());
+
+ if (WriteGPR()) {
+ src += GetGPRSize();
+ ::memcpy(&m_fpr_powerpc, src, sizeof(m_fpr_powerpc));
+
+ success = WriteFPR();
+ }
}
- return success;
+ }
+ return success;
}
-uint32_t
-RegisterContextPOSIXProcessMonitor_powerpc::SetHardwareWatchpoint(addr_t addr, size_t size,
- bool read, bool write)
-{
- const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
- uint32_t hw_index;
-
- for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index)
- {
- if (IsWatchpointVacant(hw_index))
- return SetHardwareWatchpointWithIndex(addr, size,
- read, write,
- hw_index);
- }
+uint32_t RegisterContextPOSIXProcessMonitor_powerpc::SetHardwareWatchpoint(
+ addr_t addr, size_t size, bool read, bool write) {
+ const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
+ uint32_t hw_index;
- return LLDB_INVALID_INDEX32;
+ for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index) {
+ if (IsWatchpointVacant(hw_index))
+ return SetHardwareWatchpointWithIndex(addr, size, read, write, hw_index);
+ }
+
+ return LLDB_INVALID_INDEX32;
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::ClearHardwareWatchpoint(uint32_t hw_index)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_powerpc::ClearHardwareWatchpoint(
+ uint32_t hw_index) {
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::HardwareSingleStep(bool enable)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_powerpc::HardwareSingleStep(
+ bool enable) {
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::UpdateAfterBreakpoint()
-{
- lldb::addr_t pc;
+bool RegisterContextPOSIXProcessMonitor_powerpc::UpdateAfterBreakpoint() {
+ lldb::addr_t pc;
- if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
- return false;
+ if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
+ return false;
- return true;
+ return true;
}
-unsigned
-RegisterContextPOSIXProcessMonitor_powerpc::GetRegisterIndexFromOffset(unsigned offset)
-{
- unsigned reg;
- for (reg = 0; reg < k_num_registers_powerpc; reg++)
- {
- if (GetRegisterInfo()[reg].byte_offset == offset)
- break;
- }
- assert(reg < k_num_registers_powerpc && "Invalid register offset.");
- return reg;
+unsigned RegisterContextPOSIXProcessMonitor_powerpc::GetRegisterIndexFromOffset(
+ unsigned offset) {
+ unsigned reg;
+ for (reg = 0; reg < k_num_registers_powerpc; reg++) {
+ if (GetRegisterInfo()[reg].byte_offset == offset)
+ break;
+ }
+ assert(reg < k_num_registers_powerpc && "Invalid register offset.");
+ return reg;
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::IsWatchpointHit(uint32_t hw_index)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_powerpc::IsWatchpointHit(
+ uint32_t hw_index) {
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::ClearWatchpointHits()
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_powerpc::ClearWatchpointHits() {
+ return false;
}
-addr_t
-RegisterContextPOSIXProcessMonitor_powerpc::GetWatchpointAddress(uint32_t hw_index)
-{
- return LLDB_INVALID_ADDRESS;
+addr_t RegisterContextPOSIXProcessMonitor_powerpc::GetWatchpointAddress(
+ uint32_t hw_index) {
+ return LLDB_INVALID_ADDRESS;
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::IsWatchpointVacant(uint32_t hw_index)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_powerpc::IsWatchpointVacant(
+ uint32_t hw_index) {
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_powerpc::SetHardwareWatchpointWithIndex(addr_t addr, size_t size,
- bool read, bool write,
- uint32_t hw_index)
-{
- return false;
+bool RegisterContextPOSIXProcessMonitor_powerpc::SetHardwareWatchpointWithIndex(
+ addr_t addr, size_t size, bool read, bool write, uint32_t hw_index) {
+ return false;
}
uint32_t
-RegisterContextPOSIXProcessMonitor_powerpc::NumSupportedHardwareWatchpoints()
-{
- return 0;
+RegisterContextPOSIXProcessMonitor_powerpc::NumSupportedHardwareWatchpoints() {
+ return 0;
}
-
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.h b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.h
index ff1d0f36171b..188ddea7d473 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.h
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.h
@@ -1,4 +1,5 @@
-//===-- RegisterContextPOSIXProcessMonitor_powerpc.h -------------*- C++ -*-===//
+//===-- RegisterContextPOSIXProcessMonitor_powerpc.h -------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,96 +11,75 @@
#ifndef liblldb_RegisterContextPOSIXProcessMonitor_powerpc_H_
#define liblldb_RegisterContextPOSIXProcessMonitor_powerpc_H_
-#include "RegisterContextPOSIX.h"
#include "Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h"
+#include "RegisterContextPOSIX.h"
-class RegisterContextPOSIXProcessMonitor_powerpc:
- public RegisterContextPOSIX_powerpc,
- public POSIXBreakpointProtocol
-{
+class RegisterContextPOSIXProcessMonitor_powerpc
+ : public RegisterContextPOSIX_powerpc,
+ public POSIXBreakpointProtocol {
public:
- RegisterContextPOSIXProcessMonitor_powerpc(lldb_private::Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info);
+ RegisterContextPOSIXProcessMonitor_powerpc(
+ lldb_private::Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info);
protected:
- bool
- IsVMX();
+ bool IsVMX();
- bool
- ReadGPR();
+ bool ReadGPR();
- bool
- ReadFPR();
+ bool ReadFPR();
- bool
- ReadVMX();
+ bool ReadVMX();
- bool
- WriteGPR();
+ bool WriteGPR();
- bool
- WriteFPR();
+ bool WriteFPR();
- bool
- WriteVMX();
+ bool WriteVMX();
- // lldb_private::RegisterContext
- bool
- ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
+ // lldb_private::RegisterContext
+ bool ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
- bool
- WriteRegister(const unsigned reg, const lldb_private::RegisterValue &value);
+ bool WriteRegister(const unsigned reg,
+ const lldb_private::RegisterValue &value);
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value);
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value);
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value);
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
- uint32_t
- SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write);
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read,
+ bool write);
- bool
- ClearHardwareWatchpoint(uint32_t hw_index);
+ bool ClearHardwareWatchpoint(uint32_t hw_index);
- bool
- HardwareSingleStep(bool enable);
+ bool HardwareSingleStep(bool enable);
- // POSIXBreakpointProtocol
- bool
- UpdateAfterBreakpoint();
+ // POSIXBreakpointProtocol
+ bool UpdateAfterBreakpoint();
- unsigned
- GetRegisterIndexFromOffset(unsigned offset);
+ unsigned GetRegisterIndexFromOffset(unsigned offset);
- bool
- IsWatchpointHit(uint32_t hw_index);
+ bool IsWatchpointHit(uint32_t hw_index);
- bool
- ClearWatchpointHits();
+ bool ClearWatchpointHits();
- lldb::addr_t
- GetWatchpointAddress(uint32_t hw_index);
+ lldb::addr_t GetWatchpointAddress(uint32_t hw_index);
- bool
- IsWatchpointVacant(uint32_t hw_index);
+ bool IsWatchpointVacant(uint32_t hw_index);
- bool
- SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read, bool write, uint32_t hw_index);
+ bool SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read,
+ bool write, uint32_t hw_index);
- uint32_t
- NumSupportedHardwareWatchpoints();
+ uint32_t NumSupportedHardwareWatchpoints();
private:
- ProcessMonitor &
- GetMonitor();
+ ProcessMonitor &GetMonitor();
};
#endif
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp
index 31b9e7a38b21..976b190b2355 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp
@@ -1,673 +1,614 @@
-//===-- RegisterContextPOSIXProcessMonitor_x86.h ---------------*- C++ -*-===//
+//===-- RegisterContextPOSIXProcessMonitor_x86.cpp --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
-//===---------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Thread.h"
#include "Plugins/Process/FreeBSD/ProcessFreeBSD.h"
-#include "RegisterContextPOSIXProcessMonitor_x86.h"
#include "Plugins/Process/FreeBSD/ProcessMonitor.h"
+#include "RegisterContextPOSIXProcessMonitor_x86.h"
using namespace lldb_private;
using namespace lldb;
// Support ptrace extensions even when compiled without required kernel support
#ifndef NT_X86_XSTATE
- #define NT_X86_XSTATE 0x202
+#define NT_X86_XSTATE 0x202
#endif
#define REG_CONTEXT_SIZE (GetGPRSize() + sizeof(FPR))
-static uint32_t
-size_and_rw_bits(size_t size, bool read, bool write)
-{
- uint32_t rw;
-
- if (read)
- rw = 0x3; // READ or READ/WRITE
- else if (write)
- rw = 0x1; // WRITE
- else
- assert(0 && "read and write cannot both be false");
-
- switch (size)
- {
- case 1:
- return rw;
- case 2:
- return (0x1 << 2) | rw;
- case 4:
- return (0x3 << 2) | rw;
- case 8:
- return (0x2 << 2) | rw;
- default:
- assert(0 && "invalid size, must be one of 1, 2, 4, or 8");
- return 0; // Unreachable. Just to silence compiler.
- }
+static uint32_t size_and_rw_bits(size_t size, bool read, bool write) {
+ uint32_t rw;
+
+ if (read)
+ rw = 0x3; // READ or READ/WRITE
+ else if (write)
+ rw = 0x1; // WRITE
+ else
+ assert(0 && "read and write cannot both be false");
+
+ switch (size) {
+ case 1:
+ return rw;
+ case 2:
+ return (0x1 << 2) | rw;
+ case 4:
+ return (0x3 << 2) | rw;
+ case 8:
+ return (0x2 << 2) | rw;
+ default:
+ assert(0 && "invalid size, must be one of 1, 2, 4, or 8");
+ return 0; // Unreachable. Just to silence compiler.
+ }
}
-RegisterContextPOSIXProcessMonitor_x86_64::RegisterContextPOSIXProcessMonitor_x86_64(Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info)
- : RegisterContextPOSIX_x86(thread, concrete_frame_idx, register_info)
-{
- // Store byte offset of fctrl (i.e. first register of FPR) wrt 'UserArea'
- const RegisterInfo *reg_info_fctrl = GetRegisterInfoByName("fctrl");
- m_fctrl_offset_in_userarea = reg_info_fctrl->byte_offset;
+RegisterContextPOSIXProcessMonitor_x86_64::
+ RegisterContextPOSIXProcessMonitor_x86_64(
+ Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info)
+ : RegisterContextPOSIX_x86(thread, concrete_frame_idx, register_info) {
+ // Store byte offset of fctrl (i.e. first register of FPR) wrt 'UserArea'
+ const RegisterInfo *reg_info_fctrl = GetRegisterInfoByName("fctrl");
+ m_fctrl_offset_in_userarea = reg_info_fctrl->byte_offset;
}
-ProcessMonitor &
-RegisterContextPOSIXProcessMonitor_x86_64::GetMonitor()
-{
- ProcessSP base = CalculateProcess();
- ProcessFreeBSD *process = static_cast<ProcessFreeBSD*>(base.get());
- return process->GetMonitor();
+ProcessMonitor &RegisterContextPOSIXProcessMonitor_x86_64::GetMonitor() {
+ ProcessSP base = CalculateProcess();
+ ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(base.get());
+ return process->GetMonitor();
}
-bool
-RegisterContextPOSIXProcessMonitor_x86_64::ReadGPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadGPR(m_thread.GetID(), &m_gpr_x86_64, GetGPRSize());
+bool RegisterContextPOSIXProcessMonitor_x86_64::ReadGPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.ReadGPR(m_thread.GetID(), &m_gpr_x86_64, GetGPRSize());
}
-bool
-RegisterContextPOSIXProcessMonitor_x86_64::ReadFPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- if (GetFPRType() == eFXSAVE)
- return monitor.ReadFPR(m_thread.GetID(), &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave));
+bool RegisterContextPOSIXProcessMonitor_x86_64::ReadFPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ if (GetFPRType() == eFXSAVE)
+ return monitor.ReadFPR(m_thread.GetID(), &m_fpr.xstate.fxsave,
+ sizeof(m_fpr.xstate.fxsave));
- if (GetFPRType() == eXSAVE)
- return monitor.ReadRegisterSet(m_thread.GetID(), &m_iovec, sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
- return false;
+ if (GetFPRType() == eXSAVE)
+ return monitor.ReadRegisterSet(m_thread.GetID(), &m_iovec,
+ sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_x86_64::WriteGPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteGPR(m_thread.GetID(), &m_gpr_x86_64, GetGPRSize());
+bool RegisterContextPOSIXProcessMonitor_x86_64::WriteGPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.WriteGPR(m_thread.GetID(), &m_gpr_x86_64, GetGPRSize());
}
-bool
-RegisterContextPOSIXProcessMonitor_x86_64::WriteFPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- if (GetFPRType() == eFXSAVE)
- return monitor.WriteFPR(m_thread.GetID(), &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave));
+bool RegisterContextPOSIXProcessMonitor_x86_64::WriteFPR() {
+ ProcessMonitor &monitor = GetMonitor();
+ if (GetFPRType() == eFXSAVE)
+ return monitor.WriteFPR(m_thread.GetID(), &m_fpr.xstate.fxsave,
+ sizeof(m_fpr.xstate.fxsave));
- if (GetFPRType() == eXSAVE)
- return monitor.WriteRegisterSet(m_thread.GetID(), &m_iovec, sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
- return false;
+ if (GetFPRType() == eXSAVE)
+ return monitor.WriteRegisterSet(m_thread.GetID(), &m_iovec,
+ sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_x86_64::ReadRegister(const unsigned reg,
- RegisterValue &value)
-{
- ProcessMonitor &monitor = GetMonitor();
+bool RegisterContextPOSIXProcessMonitor_x86_64::ReadRegister(
+ const unsigned reg, RegisterValue &value) {
+ ProcessMonitor &monitor = GetMonitor();
#if defined(__FreeBSD__)
- if (reg >= m_reg_info.first_dr)
- return monitor.ReadDebugRegisterValue(m_thread.GetID(),
- GetRegisterOffset(reg),
- GetRegisterName(reg),
- GetRegisterSize(reg),
- value);
+ if (reg >= m_reg_info.first_dr)
+ return monitor.ReadDebugRegisterValue(
+ m_thread.GetID(), GetRegisterOffset(reg), GetRegisterName(reg),
+ GetRegisterSize(reg), value);
#endif
- return monitor.ReadRegisterValue(m_thread.GetID(),
- GetRegisterOffset(reg),
- GetRegisterName(reg),
- GetRegisterSize(reg),
- value);
+ return monitor.ReadRegisterValue(m_thread.GetID(), GetRegisterOffset(reg),
+ GetRegisterName(reg), GetRegisterSize(reg),
+ value);
}
-bool
-RegisterContextPOSIXProcessMonitor_x86_64::WriteRegister(const unsigned reg,
- const RegisterValue &value)
-{
- unsigned reg_to_write = reg;
- RegisterValue value_to_write = value;
-
- // Check if this is a subregister of a full register.
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
- if (reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM))
- {
- RegisterValue full_value;
- uint32_t full_reg = reg_info->invalidate_regs[0];
- const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
-
- // Read the full register.
- if (ReadRegister(full_reg_info, full_value))
- {
- Error error;
- ByteOrder byte_order = GetByteOrder();
- uint8_t dst[RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the full register.
- const uint32_t dest_size = full_value.GetAsMemoryData (full_reg_info,
- dst,
- sizeof(dst),
- byte_order,
- error);
- if (error.Success() && dest_size)
- {
- uint8_t src[RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the source data.
- const uint32_t src_size = value.GetAsMemoryData (reg_info, src, sizeof(src), byte_order, error);
- if (error.Success() && src_size && (src_size < dest_size))
- {
- // Copy the src bytes to the destination.
- memcpy (dst + (reg_info->byte_offset & 0x1), src, src_size);
- // Set this full register as the value to write.
- value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
- value_to_write.SetType(full_reg_info);
- reg_to_write = full_reg;
- }
- }
+bool RegisterContextPOSIXProcessMonitor_x86_64::WriteRegister(
+ const unsigned reg, const RegisterValue &value) {
+ unsigned reg_to_write = reg;
+ RegisterValue value_to_write = value;
+
+ // Check if this is a subregister of a full register.
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
+ if (reg_info->invalidate_regs &&
+ (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) {
+ RegisterValue full_value;
+ uint32_t full_reg = reg_info->invalidate_regs[0];
+ const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
+
+ // Read the full register.
+ if (ReadRegister(full_reg_info, full_value)) {
+ Error error;
+ ByteOrder byte_order = GetByteOrder();
+ uint8_t dst[RegisterValue::kMaxRegisterByteSize];
+
+ // Get the bytes for the full register.
+ const uint32_t dest_size = full_value.GetAsMemoryData(
+ full_reg_info, dst, sizeof(dst), byte_order, error);
+ if (error.Success() && dest_size) {
+ uint8_t src[RegisterValue::kMaxRegisterByteSize];
+
+ // Get the bytes for the source data.
+ const uint32_t src_size = value.GetAsMemoryData(
+ reg_info, src, sizeof(src), byte_order, error);
+ if (error.Success() && src_size && (src_size < dest_size)) {
+ // Copy the src bytes to the destination.
+ memcpy(dst + (reg_info->byte_offset & 0x1), src, src_size);
+ // Set this full register as the value to write.
+ value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
+ value_to_write.SetType(full_reg_info);
+ reg_to_write = full_reg;
}
+ }
}
+ }
- ProcessMonitor &monitor = GetMonitor();
+ ProcessMonitor &monitor = GetMonitor();
#if defined(__FreeBSD__)
- if (reg >= m_reg_info.first_dr)
- return monitor.WriteDebugRegisterValue(m_thread.GetID(),
- GetRegisterOffset(reg_to_write),
- GetRegisterName(reg_to_write),
- value_to_write);
+ if (reg >= m_reg_info.first_dr)
+ return monitor.WriteDebugRegisterValue(
+ m_thread.GetID(), GetRegisterOffset(reg_to_write),
+ GetRegisterName(reg_to_write), value_to_write);
#endif
- return monitor.WriteRegisterValue(m_thread.GetID(),
- GetRegisterOffset(reg_to_write),
- GetRegisterName(reg_to_write),
- value_to_write);
+ return monitor.WriteRegisterValue(
+ m_thread.GetID(), GetRegisterOffset(reg_to_write),
+ GetRegisterName(reg_to_write), value_to_write);
}
-bool
-RegisterContextPOSIXProcessMonitor_x86_64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
-{
- if (!reg_info)
- return false;
+bool RegisterContextPOSIXProcessMonitor_x86_64::ReadRegister(
+ const RegisterInfo *reg_info, RegisterValue &value) {
+ if (!reg_info)
+ return false;
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- if (IsFPR(reg, GetFPRType()))
- {
- if (!ReadFPR())
- return false;
+ if (IsFPR(reg, GetFPRType())) {
+ if (!ReadFPR())
+ return false;
+ } else {
+ uint32_t full_reg = reg;
+ bool is_subreg = reg_info->invalidate_regs &&
+ (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
+
+ if (is_subreg) {
+ // Read the full aligned 64-bit register.
+ full_reg = reg_info->invalidate_regs[0];
}
- else
- {
- uint32_t full_reg = reg;
- bool is_subreg = reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
-
- if (is_subreg)
- {
- // Read the full aligned 64-bit register.
- full_reg = reg_info->invalidate_regs[0];
- }
- bool success = ReadRegister(full_reg, value);
+ bool success = ReadRegister(full_reg, value);
- if (success)
- {
- // If our read was not aligned (for ah,bh,ch,dh), shift our returned value one byte to the right.
- if (is_subreg && (reg_info->byte_offset & 0x1))
- value.SetUInt64(value.GetAsUInt64() >> 8);
+ if (success) {
+ // If our read was not aligned (for ah,bh,ch,dh), shift our returned value
+ // one byte to the right.
+ if (is_subreg && (reg_info->byte_offset & 0x1))
+ value.SetUInt64(value.GetAsUInt64() >> 8);
- // If our return byte size was greater than the return value reg size, then
- // use the type specified by reg_info rather than the uint64_t default
- if (value.GetByteSize() > reg_info->byte_size)
- value.SetType(reg_info);
- }
- return success;
+ // If our return byte size was greater than the return value reg size,
+ // then
+ // use the type specified by reg_info rather than the uint64_t default
+ if (value.GetByteSize() > reg_info->byte_size)
+ value.SetType(reg_info);
}
+ return success;
+ }
+
+ if (reg_info->encoding == eEncodingVector) {
+ ByteOrder byte_order = GetByteOrder();
+
+ if (byte_order != ByteOrder::eByteOrderInvalid) {
+ if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
+ value.SetBytes(
+ m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_st].bytes,
+ reg_info->byte_size, byte_order);
+ if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
+ value.SetBytes(
+ m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_mm].bytes,
+ reg_info->byte_size, byte_order);
+ if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
+ value.SetBytes(
+ m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_xmm].bytes,
+ reg_info->byte_size, byte_order);
+ if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) {
+ // Concatenate ymm using the register halves in xmm.bytes and ymmh.bytes
+ if (GetFPRType() == eXSAVE && CopyXSTATEtoYMM(reg, byte_order))
+ value.SetBytes(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
+ reg_info->byte_size, byte_order);
+ else
+ return false;
+ }
+ return value.GetType() == RegisterValue::eTypeBytes;
+ }
+ return false;
+ }
+
+ // Get pointer to m_fpr.xstate.fxsave variable and set the data from it.
+ // Byte offsets of all registers are calculated wrt 'UserArea' structure.
+ // However, ReadFPR() reads fpu registers {using ptrace(PT_GETFPREGS,..)}
+ // and stores them in 'm_fpr' (of type FPR structure). To extract values of
+ // fpu
+ // registers, m_fpr should be read at byte offsets calculated wrt to FPR
+ // structure.
+
+ // Since, FPR structure is also one of the member of UserArea structure.
+ // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) -
+ // byte_offset(fctrl wrt UserArea)
+ assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) < sizeof(m_fpr));
+ uint8_t *src =
+ (uint8_t *)&m_fpr + reg_info->byte_offset - m_fctrl_offset_in_userarea;
+ switch (reg_info->byte_size) {
+ case 1:
+ value.SetUInt8(*(uint8_t *)src);
+ return true;
+ case 2:
+ value.SetUInt16(*(uint16_t *)src);
+ return true;
+ case 4:
+ value.SetUInt32(*(uint32_t *)src);
+ return true;
+ case 8:
+ value.SetUInt64(*(uint64_t *)src);
+ return true;
+ default:
+ assert(false && "Unhandled data size.");
+ return false;
+ }
+}
- if (reg_info->encoding == eEncodingVector)
- {
- ByteOrder byte_order = GetByteOrder();
-
- if (byte_order != ByteOrder::eByteOrderInvalid)
- {
- if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
- value.SetBytes(m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_st].bytes, reg_info->byte_size, byte_order);
- if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
- value.SetBytes(m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_mm].bytes, reg_info->byte_size, byte_order);
- if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
- value.SetBytes(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_xmm].bytes, reg_info->byte_size, byte_order);
- if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm)
- {
- // Concatenate ymm using the register halves in xmm.bytes and ymmh.bytes
- if (GetFPRType() == eXSAVE && CopyXSTATEtoYMM(reg, byte_order))
- value.SetBytes(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, reg_info->byte_size, byte_order);
- else
- return false;
- }
- return value.GetType() == RegisterValue::eTypeBytes;
- }
+bool RegisterContextPOSIXProcessMonitor_x86_64::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &value) {
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+
+ if (IsGPR(reg))
+ return WriteRegister(reg, value);
+
+ if (IsFPR(reg, GetFPRType())) {
+ if (reg_info->encoding == eEncodingVector) {
+ if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
+ ::memcpy(m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_st].bytes,
+ value.GetBytes(), value.GetByteSize());
+
+ if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
+ ::memcpy(m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_mm].bytes,
+ value.GetBytes(), value.GetByteSize());
+
+ if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
+ ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_xmm].bytes,
+ value.GetBytes(), value.GetByteSize());
+
+ if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) {
+ if (GetFPRType() != eXSAVE)
+ return false; // the target processor does not support AVX
+
+ // Store ymm register content, and split into the register halves in
+ // xmm.bytes and ymmh.bytes
+ ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
+ value.GetBytes(), value.GetByteSize());
+ if (false == CopyYMMtoXSTATE(reg, GetByteOrder()))
+ return false;
+ }
+ } else {
+ // Get pointer to m_fpr.xstate.fxsave variable and set the data to it.
+ // Byte offsets of all registers are calculated wrt 'UserArea' structure.
+ // However, WriteFPR() takes m_fpr (of type FPR structure) and writes only
+ // fpu
+ // registers using ptrace(PT_SETFPREGS,..) API. Hence fpu registers should
+ // be written in m_fpr at byte offsets calculated wrt FPR structure.
+
+ // Since, FPR structure is also one of the member of UserArea structure.
+ // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) -
+ // byte_offset(fctrl wrt UserArea)
+ assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) <
+ sizeof(m_fpr));
+ uint8_t *dst = (uint8_t *)&m_fpr + reg_info->byte_offset -
+ m_fctrl_offset_in_userarea;
+ switch (reg_info->byte_size) {
+ case 1:
+ *(uint8_t *)dst = value.GetAsUInt8();
+ break;
+ case 2:
+ *(uint16_t *)dst = value.GetAsUInt16();
+ break;
+ case 4:
+ *(uint32_t *)dst = value.GetAsUInt32();
+ break;
+ case 8:
+ *(uint64_t *)dst = value.GetAsUInt64();
+ break;
+ default:
+ assert(false && "Unhandled data size.");
return false;
+ }
}
- // Get pointer to m_fpr.xstate.fxsave variable and set the data from it.
- // Byte offsets of all registers are calculated wrt 'UserArea' structure.
- // However, ReadFPR() reads fpu registers {using ptrace(PT_GETFPREGS,..)}
- // and stores them in 'm_fpr' (of type FPR structure). To extract values of fpu
- // registers, m_fpr should be read at byte offsets calculated wrt to FPR structure.
-
- // Since, FPR structure is also one of the member of UserArea structure.
- // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) - byte_offset(fctrl wrt UserArea)
- assert ( (reg_info->byte_offset - m_fctrl_offset_in_userarea) < sizeof(m_fpr));
- uint8_t *src = (uint8_t *)&m_fpr + reg_info->byte_offset - m_fctrl_offset_in_userarea;
- switch (reg_info->byte_size)
- {
- case 1:
- value.SetUInt8(*(uint8_t *)src);
- return true;
- case 2:
- value.SetUInt16(*(uint16_t *)src);
- return true;
- case 4:
- value.SetUInt32(*(uint32_t *)src);
- return true;
- case 8:
- value.SetUInt64(*(uint64_t *)src);
- return true;
- default:
- assert(false && "Unhandled data size.");
- return false;
+ if (WriteFPR()) {
+ if (IsAVX(reg))
+ return CopyYMMtoXSTATE(reg, GetByteOrder());
+ return true;
}
+ }
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_x86_64::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value)
-{
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
-
- if (IsGPR(reg))
- return WriteRegister(reg, value);
-
- if (IsFPR(reg, GetFPRType()))
- {
- if (reg_info->encoding == eEncodingVector)
- {
- if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
- ::memcpy (m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_st].bytes, value.GetBytes(), value.GetByteSize());
-
- if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
- ::memcpy (m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_mm].bytes, value.GetBytes(), value.GetByteSize());
-
- if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
- ::memcpy (m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_xmm].bytes, value.GetBytes(), value.GetByteSize());
-
- if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm)
- {
- if (GetFPRType() != eXSAVE)
- return false; // the target processor does not support AVX
-
- // Store ymm register content, and split into the register halves in xmm.bytes and ymmh.bytes
- ::memcpy (m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, value.GetBytes(), value.GetByteSize());
- if (false == CopyYMMtoXSTATE(reg, GetByteOrder()))
- return false;
- }
- }
- else
- {
- // Get pointer to m_fpr.xstate.fxsave variable and set the data to it.
- // Byte offsets of all registers are calculated wrt 'UserArea' structure.
- // However, WriteFPR() takes m_fpr (of type FPR structure) and writes only fpu
- // registers using ptrace(PT_SETFPREGS,..) API. Hence fpu registers should
- // be written in m_fpr at byte offsets calculated wrt FPR structure.
-
- // Since, FPR structure is also one of the member of UserArea structure.
- // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) - byte_offset(fctrl wrt UserArea)
- assert ( (reg_info->byte_offset - m_fctrl_offset_in_userarea) < sizeof(m_fpr));
- uint8_t *dst = (uint8_t *)&m_fpr + reg_info->byte_offset - m_fctrl_offset_in_userarea;
- switch (reg_info->byte_size)
- {
- case 1:
- *(uint8_t *)dst = value.GetAsUInt8();
- break;
- case 2:
- *(uint16_t *)dst = value.GetAsUInt16();
- break;
- case 4:
- *(uint32_t *)dst = value.GetAsUInt32();
- break;
- case 8:
- *(uint64_t *)dst = value.GetAsUInt64();
- break;
- default:
- assert(false && "Unhandled data size.");
- return false;
- }
- }
+bool RegisterContextPOSIXProcessMonitor_x86_64::ReadAllRegisterValues(
+ DataBufferSP &data_sp) {
+ bool success = false;
+ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (data_sp && ReadGPR() && ReadFPR()) {
+ uint8_t *dst = data_sp->GetBytes();
+ success = dst != 0;
+
+ if (success) {
+ ::memcpy(dst, &m_gpr_x86_64, GetGPRSize());
+ dst += GetGPRSize();
+ if (GetFPRType() == eFXSAVE)
+ ::memcpy(dst, &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave));
+ }
- if (WriteFPR())
- {
-