aboutsummaryrefslogtreecommitdiff
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())
- {
- if (IsAVX(reg))
- return CopyYMMtoXSTATE(reg, GetByteOrder());
- return true;
- }
+ if (GetFPRType() == eXSAVE) {
+ ByteOrder byte_order = GetByteOrder();
+
+ // Assemble the YMM register content from the register halves.
+ for (uint32_t reg = m_reg_info.first_ymm;
+ success && reg <= m_reg_info.last_ymm; ++reg)
+ success = CopyXSTATEtoYMM(reg, byte_order);
+
+ if (success) {
+ // Copy the extended register state including the assembled ymm
+ // registers.
+ ::memcpy(dst, &m_fpr, sizeof(m_fpr));
+ }
}
- return false;
+ }
+ return success;
}
-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));
- }
-
+bool RegisterContextPOSIXProcessMonitor_x86_64::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_x86_64, src, GetGPRSize());
+
+ if (WriteGPR()) {
+ src += GetGPRSize();
+ if (GetFPRType() == eFXSAVE)
+ ::memcpy(&m_fpr.xstate.fxsave, src, sizeof(m_fpr.xstate.fxsave));
if (GetFPRType() == eXSAVE)
- {
- ByteOrder byte_order = GetByteOrder();
+ ::memcpy(&m_fpr.xstate.xsave, src, sizeof(m_fpr.xstate.xsave));
- // Assemble the YMM register content from the register halves.
- for (uint32_t reg = m_reg_info.first_ymm; success && reg <= m_reg_info.last_ymm; ++reg)
- success = CopyXSTATEtoYMM(reg, byte_order);
+ success = WriteFPR();
+ if (success) {
+ if (GetFPRType() == eXSAVE) {
+ ByteOrder byte_order = GetByteOrder();
- if (success)
- {
- // Copy the extended register state including the assembled ymm registers.
- ::memcpy (dst, &m_fpr, sizeof(m_fpr));
- }
+ // Parse the YMM register content from the register halves.
+ for (uint32_t reg = m_reg_info.first_ymm;
+ success && reg <= m_reg_info.last_ymm; ++reg)
+ success = CopyYMMtoXSTATE(reg, byte_order);
+ }
}
+ }
}
- return success;
+ }
+ return success;
}
-bool
-RegisterContextPOSIXProcessMonitor_x86_64::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_x86_64, src, GetGPRSize());
-
- if (WriteGPR())
- {
- src += GetGPRSize();
- if (GetFPRType() == eFXSAVE)
- ::memcpy (&m_fpr.xstate.fxsave, src, sizeof(m_fpr.xstate.fxsave));
- if (GetFPRType() == eXSAVE)
- ::memcpy (&m_fpr.xstate.xsave, src, sizeof(m_fpr.xstate.xsave));
-
- success = WriteFPR();
- if (success)
- {
- if (GetFPRType() == eXSAVE)
- {
- ByteOrder byte_order = GetByteOrder();
-
- // Parse the YMM register content from the register halves.
- for (uint32_t reg = m_reg_info.first_ymm; success && reg <= m_reg_info.last_ymm; ++reg)
- success = CopyYMMtoXSTATE(reg, byte_order);
- }
- }
- }
- }
- }
- return success;
-}
+uint32_t RegisterContextPOSIXProcessMonitor_x86_64::SetHardwareWatchpoint(
+ addr_t addr, size_t size, bool read, bool write) {
+ const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
+ uint32_t hw_index;
-uint32_t
-RegisterContextPOSIXProcessMonitor_x86_64::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);
- }
+ 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_x86_64::ClearHardwareWatchpoint(uint32_t hw_index)
-{
- if (hw_index < NumSupportedHardwareWatchpoints())
- {
- RegisterValue current_dr7_bits;
+bool RegisterContextPOSIXProcessMonitor_x86_64::ClearHardwareWatchpoint(
+ uint32_t hw_index) {
+ if (hw_index < NumSupportedHardwareWatchpoints()) {
+ RegisterValue current_dr7_bits;
- if (ReadRegister(m_reg_info.first_dr + 7, current_dr7_bits))
- {
- uint64_t new_dr7_bits = current_dr7_bits.GetAsUInt64() & ~(3 << (2*hw_index));
+ if (ReadRegister(m_reg_info.first_dr + 7, current_dr7_bits)) {
+ uint64_t new_dr7_bits =
+ current_dr7_bits.GetAsUInt64() & ~(3 << (2 * hw_index));
- if (WriteRegister(m_reg_info.first_dr + 7, RegisterValue(new_dr7_bits)))
- return true;
- }
+ if (WriteRegister(m_reg_info.first_dr + 7, RegisterValue(new_dr7_bits)))
+ return true;
}
+ }
- return false;
+ return false;
}
-bool
-RegisterContextPOSIXProcessMonitor_x86_64::HardwareSingleStep(bool enable)
-{
- enum { TRACE_BIT = 0x100 };
- uint64_t rflags;
+bool RegisterContextPOSIXProcessMonitor_x86_64::HardwareSingleStep(
+ bool enable) {
+ enum { TRACE_BIT = 0x100 };
+ uint64_t rflags;
- if ((rflags = ReadRegisterAsUnsigned(m_reg_info.gpr_flags, -1UL)) == -1UL)
- return false;
-
- if (enable)
- {
- if (rflags & TRACE_BIT)
- return true;
+ if ((rflags = ReadRegisterAsUnsigned(m_reg_info.gpr_flags, -1UL)) == -1UL)
+ return false;
- rflags |= TRACE_BIT;
- }
- else
- {
- if (!(rflags & TRACE_BIT))
- return false;
+ if (enable) {
+ if (rflags & TRACE_BIT)
+ return true;
- rflags &= ~TRACE_BIT;
- }
+ rflags |= TRACE_BIT;
+ } else {
+ if (!(rflags & TRACE_BIT))
+ return false;
+
+ rflags &= ~TRACE_BIT;
+ }
- return WriteRegisterFromUnsigned(m_reg_info.gpr_flags, rflags);
+ return WriteRegisterFromUnsigned(m_reg_info.gpr_flags, rflags);
}
-bool
-RegisterContextPOSIXProcessMonitor_x86_64::UpdateAfterBreakpoint()
-{
- // PC points one byte past the int3 responsible for the breakpoint.
- lldb::addr_t pc;
+bool RegisterContextPOSIXProcessMonitor_x86_64::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_x86_64::GetRegisterIndexFromOffset(unsigned offset)
-{
- unsigned reg;
- for (reg = 0; reg < m_reg_info.num_registers; reg++)
- {
- if (GetRegisterInfo()[reg].byte_offset == offset)
- break;
- }
- assert(reg < m_reg_info.num_registers && "Invalid register offset.");
- return reg;
+unsigned RegisterContextPOSIXProcessMonitor_x86_64::GetRegisterIndexFromOffset(
+ unsigned offset) {
+ unsigned reg;
+ for (reg = 0; reg < m_reg_info.num_registers; reg++) {
+ if (GetRegisterInfo()[reg].byte_offset == offset)
+ break;
+ }
+ assert(reg < m_reg_info.num_registers && "Invalid register offset.");
+ return reg;
}
-bool
-RegisterContextPOSIXProcessMonitor_x86_64::IsWatchpointHit(uint32_t hw_index)
-{
- bool is_hit = false;
-
- if (m_watchpoints_initialized == false)
- {
- // Reset the debug status and debug control registers
- RegisterValue zero_bits = RegisterValue(uint64_t(0));
- if (!WriteRegister(m_reg_info.first_dr + 6, zero_bits) || !WriteRegister(m_reg_info.first_dr + 7, zero_bits))
- assert(false && "Could not initialize watchpoint registers");
- m_watchpoints_initialized = true;
- }
-
- if (hw_index < NumSupportedHardwareWatchpoints())
- {
- RegisterValue value;
-
- if (ReadRegister(m_reg_info.first_dr + 6, value))
- {
- uint64_t val = value.GetAsUInt64();
- is_hit = val & (1 << hw_index);
- }
- }
-
- return is_hit;
+bool RegisterContextPOSIXProcessMonitor_x86_64::IsWatchpointHit(
+ uint32_t hw_index) {
+ bool is_hit = false;
+
+ if (m_watchpoints_initialized == false) {
+ // Reset the debug status and debug control registers
+ RegisterValue zero_bits = RegisterValue(uint64_t(0));
+ if (!WriteRegister(m_reg_info.first_dr + 6, zero_bits) ||
+ !WriteRegister(m_reg_info.first_dr + 7, zero_bits))
+ assert(false && "Could not initialize watchpoint registers");
+ m_watchpoints_initialized = true;
+ }
+
+ if (hw_index < NumSupportedHardwareWatchpoints()) {
+ RegisterValue value;
+
+ if (ReadRegister(m_reg_info.first_dr + 6, value)) {
+ uint64_t val = value.GetAsUInt64();
+ is_hit = val & (1 << hw_index);
+ }
+ }
+
+ return is_hit;
}
-bool
-RegisterContextPOSIXProcessMonitor_x86_64::ClearWatchpointHits()
-{
- return WriteRegister(m_reg_info.first_dr + 6, RegisterValue((uint64_t)0));
+bool RegisterContextPOSIXProcessMonitor_x86_64::ClearWatchpointHits() {
+ return WriteRegister(m_reg_info.first_dr + 6, RegisterValue((uint64_t)0));
}
-addr_t
-RegisterContextPOSIXProcessMonitor_x86_64::GetWatchpointAddress(uint32_t hw_index)
-{
- addr_t wp_monitor_addr = LLDB_INVALID_ADDRESS;
+addr_t RegisterContextPOSIXProcessMonitor_x86_64::GetWatchpointAddress(
+ uint32_t hw_index) {
+ addr_t wp_monitor_addr = LLDB_INVALID_ADDRESS;
- if (hw_index < NumSupportedHardwareWatchpoints())
- {
- if (!IsWatchpointVacant(hw_index))
- {
- RegisterValue value;
+ if (hw_index < NumSupportedHardwareWatchpoints()) {
+ if (!IsWatchpointVacant(hw_index)) {
+ RegisterValue value;
- if (ReadRegister(m_reg_info.first_dr + hw_index, value))
- wp_monitor_addr = value.GetAsUInt64();
- }
+ if (ReadRegister(m_reg_info.first_dr + hw_index, value))
+ wp_monitor_addr = value.GetAsUInt64();
}
+ }
- return wp_monitor_addr;
+ return wp_monitor_addr;
}
-bool
-RegisterContextPOSIXProcessMonitor_x86_64::IsWatchpointVacant(uint32_t hw_index)
-{
- bool is_vacant = false;
- RegisterValue value;
+bool RegisterContextPOSIXProcessMonitor_x86_64::IsWatchpointVacant(
+ uint32_t hw_index) {
+ bool is_vacant = false;
+ RegisterValue value;
- assert(hw_index < NumSupportedHardwareWatchpoints());
+ assert(hw_index < NumSupportedHardwareWatchpoints());
- if (m_watchpoints_initialized == false)
- {
- // Reset the debug status and debug control registers
- RegisterValue zero_bits = RegisterValue(uint64_t(0));
- if (!WriteRegister(m_reg_info.first_dr + 6, zero_bits) || !WriteRegister(m_reg_info.first_dr + 7, zero_bits))
- assert(false && "Could not initialize watchpoint registers");
- m_watchpoints_initialized = true;
- }
+ if (m_watchpoints_initialized == false) {
+ // Reset the debug status and debug control registers
+ RegisterValue zero_bits = RegisterValue(uint64_t(0));
+ if (!WriteRegister(m_reg_info.first_dr + 6, zero_bits) ||
+ !WriteRegister(m_reg_info.first_dr + 7, zero_bits))
+ assert(false && "Could not initialize watchpoint registers");
+ m_watchpoints_initialized = true;
+ }
- if (ReadRegister(m_reg_info.first_dr + 7, value))
- {
- uint64_t val = value.GetAsUInt64();
- is_vacant = (val & (3 << 2*hw_index)) == 0;
- }
+ if (ReadRegister(m_reg_info.first_dr + 7, value)) {
+ uint64_t val = value.GetAsUInt64();
+ is_vacant = (val & (3 << 2 * hw_index)) == 0;
+ }
- return is_vacant;
+ return is_vacant;
}
-bool
-RegisterContextPOSIXProcessMonitor_x86_64::SetHardwareWatchpointWithIndex(addr_t addr, size_t size,
- bool read, bool write,
- uint32_t hw_index)
-{
- const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
+bool RegisterContextPOSIXProcessMonitor_x86_64::SetHardwareWatchpointWithIndex(
+ addr_t addr, size_t size, bool read, bool write, uint32_t hw_index) {
+ const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
- if (num_hw_watchpoints == 0 || hw_index >= num_hw_watchpoints)
- return false;
+ if (num_hw_watchpoints == 0 || hw_index >= num_hw_watchpoints)
+ return false;
- if (!(size == 1 || size == 2 || size == 4 || size == 8))
- return false;
+ if (!(size == 1 || size == 2 || size == 4 || size == 8))
+ return false;
- if (read == false && write == false)
- return false;
+ if (read == false && write == false)
+ return false;
- if (!IsWatchpointVacant(hw_index))
- return false;
+ if (!IsWatchpointVacant(hw_index))
+ return false;
- // Set both dr7 (debug control register) and dri (debug address register).
-
- // dr7{7-0} encodes the local/global enable bits:
- // global enable --. .-- local enable
- // | |
- // v v
- // dr0 -> bits{1-0}
- // dr1 -> bits{3-2}
- // dr2 -> bits{5-4}
- // dr3 -> bits{7-6}
- //
- // dr7{31-16} encodes the rw/len bits:
- // b_x+3, b_x+2, b_x+1, b_x
- // where bits{x+1, x} => rw
- // 0b00: execute, 0b01: write, 0b11: read-or-write,
- // 0b10: io read-or-write (unused)
- // and bits{x+3, x+2} => len
- // 0b00: 1-byte, 0b01: 2-byte, 0b11: 4-byte, 0b10: 8-byte
- //
- // dr0 -> bits{19-16}
- // dr1 -> bits{23-20}
- // dr2 -> bits{27-24}
- // dr3 -> bits{31-28}
- if (hw_index < num_hw_watchpoints)
- {
- RegisterValue current_dr7_bits;
-
- if (ReadRegister(m_reg_info.first_dr + 7, current_dr7_bits))
- {
- uint64_t new_dr7_bits = current_dr7_bits.GetAsUInt64() |
- (1 << (2*hw_index) |
- size_and_rw_bits(size, read, write) <<
- (16+4*hw_index));
-
- if (WriteRegister(m_reg_info.first_dr + hw_index, RegisterValue(addr)) &&
- WriteRegister(m_reg_info.first_dr + 7, RegisterValue(new_dr7_bits)))
- return true;
- }
+ // Set both dr7 (debug control register) and dri (debug address register).
+
+ // dr7{7-0} encodes the local/global enable bits:
+ // global enable --. .-- local enable
+ // | |
+ // v v
+ // dr0 -> bits{1-0}
+ // dr1 -> bits{3-2}
+ // dr2 -> bits{5-4}
+ // dr3 -> bits{7-6}
+ //
+ // dr7{31-16} encodes the rw/len bits:
+ // b_x+3, b_x+2, b_x+1, b_x
+ // where bits{x+1, x} => rw
+ // 0b00: execute, 0b01: write, 0b11: read-or-write,
+ // 0b10: io read-or-write (unused)
+ // and bits{x+3, x+2} => len
+ // 0b00: 1-byte, 0b01: 2-byte, 0b11: 4-byte, 0b10: 8-byte
+ //
+ // dr0 -> bits{19-16}
+ // dr1 -> bits{23-20}
+ // dr2 -> bits{27-24}
+ // dr3 -> bits{31-28}
+ if (hw_index < num_hw_watchpoints) {
+ RegisterValue current_dr7_bits;
+
+ if (ReadRegister(m_reg_info.first_dr + 7, current_dr7_bits)) {
+ uint64_t new_dr7_bits =
+ current_dr7_bits.GetAsUInt64() |
+ (1 << (2 * hw_index) |
+ size_and_rw_bits(size, read, write) << (16 + 4 * hw_index));
+
+ if (WriteRegister(m_reg_info.first_dr + hw_index, RegisterValue(addr)) &&
+ WriteRegister(m_reg_info.first_dr + 7, RegisterValue(new_dr7_bits)))
+ return true;
}
+ }
- return false;
+ return false;
}
uint32_t
-RegisterContextPOSIXProcessMonitor_x86_64::NumSupportedHardwareWatchpoints()
-{
- // Available debug address registers: dr0, dr1, dr2, dr3
- return 4;
+RegisterContextPOSIXProcessMonitor_x86_64::NumSupportedHardwareWatchpoints() {
+ // Available debug address registers: dr0, dr1, dr2, dr3
+ return 4;
}
-
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.h b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.h
index f55d917ee75d..57e2d00e668f 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.h
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.h
@@ -10,88 +10,71 @@
#ifndef liblldb_RegisterContextPOSIXProcessMonitor_x86_H_
#define liblldb_RegisterContextPOSIXProcessMonitor_x86_H_
-#include "RegisterContextPOSIX.h"
#include "Plugins/Process/Utility/RegisterContextPOSIX_x86.h"
+#include "RegisterContextPOSIX.h"
-class RegisterContextPOSIXProcessMonitor_x86_64:
- public RegisterContextPOSIX_x86,
- public POSIXBreakpointProtocol
-{
+class RegisterContextPOSIXProcessMonitor_x86_64
+ : public RegisterContextPOSIX_x86,
+ public POSIXBreakpointProtocol {
public:
- RegisterContextPOSIXProcessMonitor_x86_64(lldb_private::Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info);
+ RegisterContextPOSIXProcessMonitor_x86_64(
+ 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();
- uint32_t m_fctrl_offset_in_userarea; // Offset of 'fctrl' in 'UserArea' Structure
+ ProcessMonitor &GetMonitor();
+ uint32_t
+ m_fctrl_offset_in_userarea; // Offset of 'fctrl' in 'UserArea' Structure
};
#endif
diff --git a/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/source/Plugins/Process/Linux/NativeProcessLinux.cpp
index 00f4010742b0..94b9efc2b2b0 100644
--- a/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ b/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -11,8 +11,8 @@
// C Includes
#include <errno.h>
-#include <string.h>
#include <stdint.h>
+#include <string.h>
#include <unistd.h>
// C++ Includes
@@ -29,9 +29,11 @@
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/State.h"
#include "lldb/Host/Host.h"
+#include "lldb/Host/HostProcess.h"
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Host/common/NativeBreakpoint.h"
#include "lldb/Host/common/NativeRegisterContext.h"
+#include "lldb/Host/linux/ProcessLauncherLinux.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/ProcessLaunchInfo.h"
@@ -40,12 +42,13 @@
#include "lldb/Utility/PseudoTerminal.h"
#include "lldb/Utility/StringExtractor.h"
-#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
#include "NativeThreadLinux.h"
+#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
#include "ProcFileReader.h"
#include "Procfs.h"
-// System includes - They have to be included after framework includes because they define some
+// System includes - They have to be included after framework includes because
+// they define some
// macros which collide with variable names in other modules
#include <linux/unistd.h>
#include <sys/socket.h>
@@ -55,15 +58,12 @@
#include <sys/user.h>
#include <sys/wait.h>
-#include "lldb/Host/linux/Personality.h"
#include "lldb/Host/linux/Ptrace.h"
#include "lldb/Host/linux/Uio.h"
-#define LLDB_PERSONALITY_GET_CURRENT_SETTINGS 0xffffffff
-
// Support hardware breakpoints in case it has not been defined
#ifndef TRAP_HWBKPT
- #define TRAP_HWBKPT 4
+#define TRAP_HWBKPT 4
#endif
using namespace lldb;
@@ -73,2113 +73,1911 @@ using namespace llvm;
// Private bits we only need internally.
-static bool ProcessVmReadvSupported()
-{
- static bool is_supported;
- static std::once_flag flag;
-
- std::call_once(flag, [] {
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
-
- uint32_t source = 0x47424742;
- uint32_t dest = 0;
-
- struct iovec local, remote;
- remote.iov_base = &source;
- local.iov_base = &dest;
- remote.iov_len = local.iov_len = sizeof source;
-
- // We shall try if cross-process-memory reads work by attempting to read a value from our own process.
- ssize_t res = process_vm_readv(getpid(), &local, 1, &remote, 1, 0);
- is_supported = (res == sizeof(source) && source == dest);
- if (log)
- {
- if (is_supported)
- log->Printf("%s: Detected kernel support for process_vm_readv syscall. Fast memory reads enabled.",
- __FUNCTION__);
- else
- log->Printf("%s: syscall process_vm_readv failed (error: %s). Fast memory reads disabled.",
- __FUNCTION__, strerror(errno));
- }
- });
+static bool ProcessVmReadvSupported() {
+ static bool is_supported;
+ static std::once_flag flag;
- return is_supported;
-}
-
-namespace
-{
-Error
-ResolveProcessArchitecture(lldb::pid_t pid, ArchSpec &arch)
-{
- // Grab process info for the running process.
- ProcessInstanceInfo process_info;
- if (!Host::GetProcessInfo(pid, process_info))
- return Error("failed to get process info");
-
- // Resolve the executable module.
- ModuleSpecList module_specs;
- if (!ObjectFile::GetModuleSpecifications(process_info.GetExecutableFile(), 0, 0, module_specs))
- return Error("failed to get module specifications");
- assert(module_specs.GetSize() == 1);
-
- arch = module_specs.GetModuleSpecRefAtIndex(0).GetArchitecture();
- if (arch.IsValid())
- return Error();
- else
- return Error("failed to retrieve a valid architecture from the exe module");
-}
-
-// Used to notify the parent about which part of the launch sequence failed.
-enum LaunchCallSpecifier
-{
- ePtraceFailed,
- eDupStdinFailed,
- eDupStdoutFailed,
- eDupStderrFailed,
- eChdirFailed,
- eExecFailed,
- eSetGidFailed,
- eSetSigMaskFailed,
- eLaunchCallMax = eSetSigMaskFailed
-};
-
-static uint8_t LLVM_ATTRIBUTE_NORETURN
-ExitChildAbnormally(LaunchCallSpecifier spec)
-{
- static_assert(eLaunchCallMax < 0x8, "Have more launch calls than we are able to represent");
- // This may truncate the topmost bits of the errno because the exit code is only 8 bits wide.
- // However, it should still give us a pretty good indication of what went wrong. (And the
- // most common errors have small numbers anyway).
- _exit(unsigned(spec) | (errno << 3));
-}
-
-// The second member is the errno (or its 5 lowermost bits anyway).
-inline std::pair<LaunchCallSpecifier, uint8_t>
-DecodeChildExitCode(int exit_code)
-{
- return std::make_pair(LaunchCallSpecifier(exit_code & 0x7), exit_code >> 3);
-}
-
-void
-MaybeLogLaunchInfo(const ProcessLaunchInfo &info)
-{
+ std::call_once(flag, [] {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (!log)
- return;
- if (const FileAction *action = info.GetFileActionForFD(STDIN_FILENO))
- log->Printf("%s: setting STDIN to '%s'", __FUNCTION__, action->GetFileSpec().GetCString());
- else
- log->Printf("%s leaving STDIN as is", __FUNCTION__);
-
- if (const FileAction *action = info.GetFileActionForFD(STDOUT_FILENO))
- log->Printf("%s setting STDOUT to '%s'", __FUNCTION__, action->GetFileSpec().GetCString());
- else
- log->Printf("%s leaving STDOUT as is", __FUNCTION__);
-
- if (const FileAction *action = info.GetFileActionForFD(STDERR_FILENO))
- log->Printf("%s setting STDERR to '%s'", __FUNCTION__, action->GetFileSpec().GetCString());
- else
- log->Printf("%s leaving STDERR as is", __FUNCTION__);
+ uint32_t source = 0x47424742;
+ uint32_t dest = 0;
- int i = 0;
- for (const char **args = info.GetArguments().GetConstArgumentVector(); *args; ++args, ++i)
- log->Printf("%s arg %d: \"%s\"", __FUNCTION__, i, *args ? *args : "nullptr");
-}
+ struct iovec local, remote;
+ remote.iov_base = &source;
+ local.iov_base = &dest;
+ remote.iov_len = local.iov_len = sizeof source;
-void
-DisplayBytes(StreamString &s, void *bytes, uint32_t count)
-{
- uint8_t *ptr = (uint8_t *)bytes;
- const uint32_t loop_count = std::min<uint32_t>(DEBUG_PTRACE_MAXBYTES, count);
- for (uint32_t i = 0; i < loop_count; i++)
- {
- s.Printf("[%x]", *ptr);
- ptr++;
+ // We shall try if cross-process-memory reads work by attempting to read a
+ // value from our own process.
+ ssize_t res = process_vm_readv(getpid(), &local, 1, &remote, 1, 0);
+ is_supported = (res == sizeof(source) && source == dest);
+ if (log) {
+ if (is_supported)
+ log->Printf("%s: Detected kernel support for process_vm_readv syscall. "
+ "Fast memory reads enabled.",
+ __FUNCTION__);
+ else
+ log->Printf("%s: syscall process_vm_readv failed (error: %s). Fast "
+ "memory reads disabled.",
+ __FUNCTION__, strerror(errno));
}
-}
+ });
- void
- PtraceDisplayBytes(int &req, void *data, size_t data_size)
- {
- StreamString buf;
- Log *verbose_log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (
- POSIX_LOG_PTRACE | POSIX_LOG_VERBOSE));
-
- if (verbose_log)
- {
- switch(req)
- {
- case PTRACE_POKETEXT:
- {
- DisplayBytes(buf, &data, 8);
- verbose_log->Printf("PTRACE_POKETEXT %s", buf.GetData());
- break;
- }
- case PTRACE_POKEDATA:
- {
- DisplayBytes(buf, &data, 8);
- verbose_log->Printf("PTRACE_POKEDATA %s", buf.GetData());
- break;
- }
- case PTRACE_POKEUSER:
- {
- DisplayBytes(buf, &data, 8);
- verbose_log->Printf("PTRACE_POKEUSER %s", buf.GetData());
- break;
- }
- case PTRACE_SETREGS:
- {
- DisplayBytes(buf, data, data_size);
- verbose_log->Printf("PTRACE_SETREGS %s", buf.GetData());
- break;
- }
- case PTRACE_SETFPREGS:
- {
- DisplayBytes(buf, data, data_size);
- verbose_log->Printf("PTRACE_SETFPREGS %s", buf.GetData());
- break;
- }
- case PTRACE_SETSIGINFO:
- {
- DisplayBytes(buf, data, sizeof(siginfo_t));
- verbose_log->Printf("PTRACE_SETSIGINFO %s", buf.GetData());
- break;
- }
- case PTRACE_SETREGSET:
- {
- // Extract iov_base from data, which is a pointer to the struct IOVEC
- DisplayBytes(buf, *(void **)data, data_size);
- verbose_log->Printf("PTRACE_SETREGSET %s", buf.GetData());
- break;
- }
- default:
- {
- }
- }
- }
- }
+ return is_supported;
+}
- static constexpr unsigned k_ptrace_word_size = sizeof(void*);
- static_assert(sizeof(long) >= k_ptrace_word_size, "Size of long must be larger than ptrace word size");
+namespace {
+void MaybeLogLaunchInfo(const ProcessLaunchInfo &info) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (!log)
+ return;
+
+ if (const FileAction *action = info.GetFileActionForFD(STDIN_FILENO))
+ log->Printf("%s: setting STDIN to '%s'", __FUNCTION__,
+ action->GetFileSpec().GetCString());
+ else
+ log->Printf("%s leaving STDIN as is", __FUNCTION__);
+
+ if (const FileAction *action = info.GetFileActionForFD(STDOUT_FILENO))
+ log->Printf("%s setting STDOUT to '%s'", __FUNCTION__,
+ action->GetFileSpec().GetCString());
+ else
+ log->Printf("%s leaving STDOUT as is", __FUNCTION__);
+
+ if (const FileAction *action = info.GetFileActionForFD(STDERR_FILENO))
+ log->Printf("%s setting STDERR to '%s'", __FUNCTION__,
+ action->GetFileSpec().GetCString());
+ else
+ log->Printf("%s leaving STDERR as is", __FUNCTION__);
+
+ int i = 0;
+ for (const char **args = info.GetArguments().GetConstArgumentVector(); *args;
+ ++args, ++i)
+ log->Printf("%s arg %d: \"%s\"", __FUNCTION__, i,
+ *args ? *args : "nullptr");
+}
+
+void DisplayBytes(StreamString &s, void *bytes, uint32_t count) {
+ uint8_t *ptr = (uint8_t *)bytes;
+ const uint32_t loop_count = std::min<uint32_t>(DEBUG_PTRACE_MAXBYTES, count);
+ for (uint32_t i = 0; i < loop_count; i++) {
+ s.Printf("[%x]", *ptr);
+ ptr++;
+ }
+}
+
+void PtraceDisplayBytes(int &req, void *data, size_t data_size) {
+ StreamString buf;
+ Log *verbose_log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(
+ POSIX_LOG_PTRACE | POSIX_LOG_VERBOSE));
+
+ if (verbose_log) {
+ switch (req) {
+ case PTRACE_POKETEXT: {
+ DisplayBytes(buf, &data, 8);
+ verbose_log->Printf("PTRACE_POKETEXT %s", buf.GetData());
+ break;
+ }
+ case PTRACE_POKEDATA: {
+ DisplayBytes(buf, &data, 8);
+ verbose_log->Printf("PTRACE_POKEDATA %s", buf.GetData());
+ break;
+ }
+ case PTRACE_POKEUSER: {
+ DisplayBytes(buf, &data, 8);
+ verbose_log->Printf("PTRACE_POKEUSER %s", buf.GetData());
+ break;
+ }
+ case PTRACE_SETREGS: {
+ DisplayBytes(buf, data, data_size);
+ verbose_log->Printf("PTRACE_SETREGS %s", buf.GetData());
+ break;
+ }
+ case PTRACE_SETFPREGS: {
+ DisplayBytes(buf, data, data_size);
+ verbose_log->Printf("PTRACE_SETFPREGS %s", buf.GetData());
+ break;
+ }
+ case PTRACE_SETSIGINFO: {
+ DisplayBytes(buf, data, sizeof(siginfo_t));
+ verbose_log->Printf("PTRACE_SETSIGINFO %s", buf.GetData());
+ break;
+ }
+ case PTRACE_SETREGSET: {
+ // Extract iov_base from data, which is a pointer to the struct IOVEC
+ DisplayBytes(buf, *(void **)data, data_size);
+ verbose_log->Printf("PTRACE_SETREGSET %s", buf.GetData());
+ break;
+ }
+ default: {}
+ }
+ }
+}
+
+static constexpr unsigned k_ptrace_word_size = sizeof(void *);
+static_assert(sizeof(long) >= k_ptrace_word_size,
+ "Size of long must be larger than ptrace word size");
} // end of anonymous namespace
// Simple helper function to ensure flags are enabled on the given file
// descriptor.
-static Error
-EnsureFDFlags(int fd, int flags)
-{
- Error error;
+static Error EnsureFDFlags(int fd, int flags) {
+ Error error;
- int status = fcntl(fd, F_GETFL);
- if (status == -1)
- {
- error.SetErrorToErrno();
- return error;
- }
-
- if (fcntl(fd, F_SETFL, status | flags) == -1)
- {
- error.SetErrorToErrno();
- return error;
- }
+ int status = fcntl(fd, F_GETFL);
+ if (status == -1) {
+ error.SetErrorToErrno();
+ return error;
+ }
+ if (fcntl(fd, F_SETFL, status | flags) == -1) {
+ error.SetErrorToErrno();
return error;
+ }
+
+ return error;
}
// -----------------------------------------------------------------------------
// Public Static Methods
// -----------------------------------------------------------------------------
-Error
-NativeProcessProtocol::Launch (
+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;
- }
+ 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;
+ }
- // Create the NativeProcessLinux in launch mode.
- native_process_sp.reset (new NativeProcessLinux ());
+ // Create the NativeProcessLinux in launch mode.
+ native_process_sp.reset(new NativeProcessLinux());
- if (!native_process_sp->RegisterNativeDelegate (native_delegate))
- {
- native_process_sp.reset ();
- error.SetErrorStringWithFormat ("failed to register the native delegate");
- return error;
- }
+ if (!native_process_sp->RegisterNativeDelegate(native_delegate)) {
+ native_process_sp.reset();
+ error.SetErrorStringWithFormat("failed to register the native delegate");
+ return error;
+ }
- error = std::static_pointer_cast<NativeProcessLinux>(native_process_sp)->LaunchInferior(mainloop, launch_info);
+ error = std::static_pointer_cast<NativeProcessLinux>(native_process_sp)
+ ->LaunchInferior(mainloop, launch_info);
- if (error.Fail ())
- {
- native_process_sp.reset ();
- if (log)
- log->Printf ("NativeProcessLinux::%s failed to launch process: %s", __FUNCTION__, error.AsCString ());
- return error;
- }
+ if (error.Fail()) {
+ native_process_sp.reset();
+ if (log)
+ log->Printf("NativeProcessLinux::%s failed to launch process: %s",
+ __FUNCTION__, error.AsCString());
+ return error;
+ }
- launch_info.SetProcessID (native_process_sp->GetID ());
+ launch_info.SetProcessID(native_process_sp->GetID());
- return error;
+ 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->GetMask ().Test (POSIX_LOG_VERBOSE))
- log->Printf ("NativeProcessLinux::%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;
+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->GetMask().Test(POSIX_LOG_VERBOSE))
+ log->Printf("NativeProcessLinux::%s(pid = %" PRIi64 ")", __FUNCTION__, pid);
- std::shared_ptr<NativeProcessLinux> native_process_linux_sp (new NativeProcessLinux ());
+ // Retrieve the architecture for the running process.
+ ArchSpec process_arch;
+ Error error = ResolveProcessArchitecture(pid, process_arch);
+ if (!error.Success())
+ return error;
- if (!native_process_linux_sp->RegisterNativeDelegate (native_delegate))
- {
- error.SetErrorStringWithFormat ("failed to register the native delegate");
- return error;
- }
+ std::shared_ptr<NativeProcessLinux> native_process_linux_sp(
+ new NativeProcessLinux());
- native_process_linux_sp->AttachToInferior (mainloop, pid, error);
- if (!error.Success ())
- return error;
+ if (!native_process_linux_sp->RegisterNativeDelegate(native_delegate)) {
+ error.SetErrorStringWithFormat("failed to register the native delegate");
+ return error;
+ }
- native_process_sp = native_process_linux_sp;
+ native_process_linux_sp->AttachToInferior(mainloop, pid, error);
+ if (!error.Success())
return error;
+
+ native_process_sp = native_process_linux_sp;
+ return error;
}
// -----------------------------------------------------------------------------
// Public Instance Methods
// -----------------------------------------------------------------------------
-NativeProcessLinux::NativeProcessLinux () :
- NativeProcessProtocol (LLDB_INVALID_PROCESS_ID),
- m_arch (),
- m_supports_mem_region (eLazyBoolCalculate),
- m_mem_region_cache (),
- m_pending_notification_tid(LLDB_INVALID_THREAD_ID)
-{
-}
-
-void
-NativeProcessLinux::AttachToInferior (MainLoop &mainloop, lldb::pid_t pid, Error &error)
-{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf ("NativeProcessLinux::%s (pid = %" PRIi64 ")", __FUNCTION__, pid);
-
- m_sigchld_handle = mainloop.RegisterSignal(SIGCHLD,
- [this] (MainLoopBase &) { SigchldHandler(); }, error);
- if (! m_sigchld_handle)
- return;
-
- error = ResolveProcessArchitecture(pid, m_arch);
- if (!error.Success())
- return;
-
- // Set the architecture to the exe architecture.
- if (log)
- log->Printf ("NativeProcessLinux::%s (pid = %" PRIi64 ") detected architecture %s", __FUNCTION__, pid, m_arch.GetArchitectureName ());
-
- m_pid = pid;
- SetState(eStateAttaching);
-
- Attach(pid, error);
-}
-
-void
-NativeProcessLinux::ChildFunc(const ProcessLaunchInfo &info)
-{
- // Start tracing this child that is about to exec.
- if (ptrace(PTRACE_TRACEME, 0, nullptr, nullptr) == -1)
- ExitChildAbnormally(ePtraceFailed);
-
- // Do not inherit setgid powers.
- if (setgid(getgid()) != 0)
- ExitChildAbnormally(eSetGidFailed);
-
- // Attempt to have our own process group.
- if (setpgid(0, 0) != 0)
- {
- // FIXME log that this failed. This is common.
- // Don't allow this to prevent an inferior exec.
- }
-
- // Dup file descriptors if needed.
- if (const FileAction *action = info.GetFileActionForFD(STDIN_FILENO))
- if (!DupDescriptor(action->GetFileSpec(), STDIN_FILENO, O_RDONLY))
- ExitChildAbnormally(eDupStdinFailed);
-
- if (const FileAction *action = info.GetFileActionForFD(STDOUT_FILENO))
- if (!DupDescriptor(action->GetFileSpec(), STDOUT_FILENO, O_WRONLY | O_CREAT | O_TRUNC))
- ExitChildAbnormally(eDupStdoutFailed);
-
- if (const FileAction *action = info.GetFileActionForFD(STDERR_FILENO))
- if (!DupDescriptor(action->GetFileSpec(), STDERR_FILENO, O_WRONLY | O_CREAT | O_TRUNC))
- ExitChildAbnormally(eDupStderrFailed);
+NativeProcessLinux::NativeProcessLinux()
+ : NativeProcessProtocol(LLDB_INVALID_PROCESS_ID), m_arch(),
+ m_supports_mem_region(eLazyBoolCalculate), m_mem_region_cache(),
+ m_pending_notification_tid(LLDB_INVALID_THREAD_ID) {}
+
+void NativeProcessLinux::AttachToInferior(MainLoop &mainloop, lldb::pid_t pid,
+ Error &error) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("NativeProcessLinux::%s (pid = %" PRIi64 ")", __FUNCTION__,
+ pid);
+
+ m_sigchld_handle = mainloop.RegisterSignal(
+ SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, error);
+ if (!m_sigchld_handle)
+ return;
+
+ error = ResolveProcessArchitecture(pid, m_arch);
+ if (!error.Success())
+ return;
+
+ // Set the architecture to the exe architecture.
+ if (log)
+ log->Printf("NativeProcessLinux::%s (pid = %" PRIi64
+ ") detected architecture %s",
+ __FUNCTION__, pid, m_arch.GetArchitectureName());
+
+ m_pid = pid;
+ SetState(eStateAttaching);
+
+ Attach(pid, error);
+}
+
+Error NativeProcessLinux::LaunchInferior(MainLoop &mainloop,
+ ProcessLaunchInfo &launch_info) {
+ Error error;
+ m_sigchld_handle = mainloop.RegisterSignal(
+ SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, error);
+ if (!m_sigchld_handle)
+ return error;
- // Close everything besides stdin, stdout, and stderr that has no file
- // action to avoid leaking
- for (int fd = 3; fd < sysconf(_SC_OPEN_MAX); ++fd)
- if (!info.GetFileActionForFD(fd))
- close(fd);
+ SetState(eStateLaunching);
- // Change working directory
- if (info.GetWorkingDirectory() && 0 != ::chdir(info.GetWorkingDirectory().GetCString()))
- ExitChildAbnormally(eChdirFailed);
+ MaybeLogLaunchInfo(launch_info);
- // Disable ASLR if requested.
- if (info.GetFlags().Test(lldb::eLaunchFlagDisableASLR))
- {
- const int old_personality = personality(LLDB_PERSONALITY_GET_CURRENT_SETTINGS);
- if (old_personality == -1)
- {
- // Can't retrieve Linux personality. Cannot disable ASLR.
- }
- else
- {
- const int new_personality = personality(ADDR_NO_RANDOMIZE | old_personality);
- if (new_personality == -1)
- {
- // Disabling ASLR failed.
- }
- else
- {
- // Disabling ASLR succeeded.
- }
- }
- }
-
- // Clear the signal mask to prevent the child from being affected by
- // any masking done by the parent.
- sigset_t set;
- if (sigemptyset(&set) != 0 || pthread_sigmask(SIG_SETMASK, &set, nullptr) != 0)
- ExitChildAbnormally(eSetSigMaskFailed);
+ ::pid_t pid =
+ ProcessLauncherLinux().LaunchProcess(launch_info, error).GetProcessId();
+ if (error.Fail())
+ return error;
- const char **argv = info.GetArguments().GetConstArgumentVector();
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- // Propagate the environment if one is not supplied.
- const char **envp = info.GetEnvironmentEntries().GetConstArgumentVector();
- if (envp == NULL || envp[0] == NULL)
- envp = const_cast<const char **>(environ);
+ // Wait for the child process to trap on its call to execve.
+ ::pid_t wpid;
+ int status;
+ if ((wpid = waitpid(pid, &status, 0)) < 0) {
+ error.SetErrorToErrno();
+ if (log)
+ log->Printf("NativeProcessLinux::%s waitpid for inferior failed with %s",
+ __FUNCTION__, error.AsCString());
- // Execute. We should never return...
- execve(argv[0], const_cast<char *const *>(argv), const_cast<char *const *>(envp));
+ // Mark the inferior as invalid.
+ // FIXME this could really use a new state - eStateLaunchFailure. For now,
+ // using eStateInvalid.
+ SetState(StateType::eStateInvalid);
- if (errno == ETXTBSY)
- {
- // On android M and earlier we can get this error because the adb deamon can hold a write
- // handle on the executable even after it has finished uploading it. This state lasts
- // only a short time and happens only when there are many concurrent adb commands being
- // issued, such as when running the test suite. (The file remains open when someone does
- // an "adb shell" command in the fork() child before it has had a chance to exec.) Since
- // this state should clear up quickly, wait a while and then give it one more go.
- usleep(50000);
- execve(argv[0], const_cast<char *const *>(argv), const_cast<char *const *>(envp));
- }
-
- // ...unless exec fails. In which case we definitely need to end the child here.
- ExitChildAbnormally(eExecFailed);
-}
+ return error;
+ }
+ assert(WIFSTOPPED(status) && (wpid == static_cast<::pid_t>(pid)) &&
+ "Could not sync with inferior process.");
-Error
-NativeProcessLinux::LaunchInferior(MainLoop &mainloop, ProcessLaunchInfo &launch_info)
-{
- Error error;
- m_sigchld_handle = mainloop.RegisterSignal(SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, error);
- if (!m_sigchld_handle)
- return error;
+ if (log)
+ log->Printf("NativeProcessLinux::%s inferior started, now in stopped state",
+ __FUNCTION__);
- SetState(eStateLaunching);
+ error = SetDefaultPtraceOpts(pid);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("NativeProcessLinux::%s inferior failed to set default "
+ "ptrace options: %s",
+ __FUNCTION__, error.AsCString());
- lldb_utility::PseudoTerminal terminal;
- const size_t err_len = 1024;
- char err_str[err_len];
- lldb::pid_t pid;
+ // Mark the inferior as invalid.
+ // FIXME this could really use a new state - eStateLaunchFailure. For now,
+ // using eStateInvalid.
+ SetState(StateType::eStateInvalid);
- MaybeLogLaunchInfo(launch_info);
+ return error;
+ }
- if ((pid = terminal.Fork(err_str, err_len)) == static_cast<lldb::pid_t> (-1))
- {
- error.SetErrorToGenericError();
- error.SetErrorStringWithFormat("Process fork failed: %s", err_str);
- return error;
- }
+ // Release the master terminal descriptor and pass it off to the
+ // NativeProcessLinux instance. Similarly stash the inferior pid.
+ m_terminal_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
+ m_pid = pid;
+ launch_info.SetProcessID(pid);
- // Child process.
- if (pid == 0)
- {
- // First, make sure we disable all logging. If we are logging to stdout, our logs can be
- // mistaken for inferior output.
- Log::DisableAllLogChannels(nullptr);
+ if (m_terminal_fd != -1) {
+ error = EnsureFDFlags(m_terminal_fd, O_NONBLOCK);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("NativeProcessLinux::%s inferior EnsureFDFlags failed for "
+ "ensuring terminal O_NONBLOCK setting: %s",
+ __FUNCTION__, error.AsCString());
- // 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();
+ // Mark the inferior as invalid.
+ // FIXME this could really use a new state - eStateLaunchFailure. For
+ // now, using eStateInvalid.
+ SetState(StateType::eStateInvalid);
- ChildFunc(launch_info);
+ return error;
}
+ }
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("NativeProcessLinux::%s() adding pid = %" PRIu64, __FUNCTION__,
+ uint64_t(pid));
- // Wait for the child process to trap on its call to execve.
- ::pid_t wpid;
- int status;
- if ((wpid = waitpid(pid, &status, 0)) < 0)
- {
- error.SetErrorToErrno();
- if (log)
- log->Printf ("NativeProcessLinux::%s waitpid for inferior failed with %s",
- __FUNCTION__, error.AsCString ());
+ ResolveProcessArchitecture(m_pid, m_arch);
+ NativeThreadLinuxSP thread_sp = AddThread(pid);
+ assert(thread_sp && "AddThread() returned a nullptr thread");
+ thread_sp->SetStoppedBySignal(SIGSTOP);
+ ThreadWasCreated(*thread_sp);
- // Mark the inferior as invalid.
- // FIXME this could really use a new state - eStateLaunchFailure. For now, using eStateInvalid.
- SetState (StateType::eStateInvalid);
+ // Let our process instance know the thread has stopped.
+ SetCurrentThreadID(thread_sp->GetID());
+ SetState(StateType::eStateStopped);
- return error;
- }
- else if (WIFEXITED(status))
- {
- auto p = DecodeChildExitCode(WEXITSTATUS(status));
- Error child_error(p.second, eErrorTypePOSIX);
- const char *failure_reason;
- switch (p.first)
- {
- case ePtraceFailed:
- failure_reason = "Child ptrace failed";
- break;
- case eDupStdinFailed:
- failure_reason = "Child open stdin failed";
- break;
- case eDupStdoutFailed:
- failure_reason = "Child open stdout failed";
- break;
- case eDupStderrFailed:
- failure_reason = "Child open stderr failed";
- break;
- case eChdirFailed:
- failure_reason = "Child failed to set working directory";
- break;
- case eExecFailed:
- failure_reason = "Child exec failed";
- break;
- case eSetGidFailed:
- failure_reason = "Child setgid failed";
- break;
- case eSetSigMaskFailed:
- failure_reason = "Child failed to set signal mask";
- break;
+ if (log) {
+ if (error.Success())
+ log->Printf("NativeProcessLinux::%s inferior launching succeeded",
+ __FUNCTION__);
+ else
+ log->Printf("NativeProcessLinux::%s inferior launching failed: %s",
+ __FUNCTION__, error.AsCString());
+ }
+ return error;
+}
+
+::pid_t NativeProcessLinux::Attach(lldb::pid_t pid, Error &error) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ // Use a map to keep track of the threads which we have attached/need to
+ // attach.
+ Host::TidMap tids_to_attach;
+ if (pid <= 1) {
+ error.SetErrorToGenericError();
+ error.SetErrorString("Attaching to process 1 is not allowed.");
+ return -1;
+ }
+
+ while (Host::FindProcessThreads(pid, tids_to_attach)) {
+ for (Host::TidMap::iterator it = tids_to_attach.begin();
+ it != tids_to_attach.end();) {
+ if (it->second == false) {
+ lldb::tid_t tid = it->first;
+
+ // Attach to the requested process.
+ // An attach will cause the thread to stop with a SIGSTOP.
+ error = PtraceWrapper(PTRACE_ATTACH, tid);
+ if (error.Fail()) {
+ // No such thread. The thread may have exited.
+ // More error handling may be needed.
+ if (error.GetError() == ESRCH) {
+ it = tids_to_attach.erase(it);
+ continue;
+ } else
+ return -1;
}
- error.SetErrorStringWithFormat("%s: %d - %s (error code truncated)", failure_reason, child_error.GetError(), child_error.AsCString());
- if (log)
- {
- log->Printf ("NativeProcessLinux::%s inferior exited with status %d before issuing a STOP",
- __FUNCTION__,
- WEXITSTATUS(status));
+ int status;
+ // Need to use __WALL otherwise we receive an error with errno=ECHLD
+ // At this point we should have a thread stopped if waitpid succeeds.
+ if ((status = waitpid(tid, NULL, __WALL)) < 0) {
+ // No such thread. The thread may have exited.
+ // More error handling may be needed.
+ if (errno == ESRCH) {
+ it = tids_to_attach.erase(it);
+ continue;
+ } else {
+ error.SetErrorToErrno();
+ return -1;
+ }
}
- // Mark the inferior as invalid.
- // FIXME this could really use a new state - eStateLaunchFailure. For now, using eStateInvalid.
- SetState (StateType::eStateInvalid);
-
- return error;
- }
- assert(WIFSTOPPED(status) && (wpid == static_cast< ::pid_t> (pid)) &&
- "Could not sync with inferior process.");
-
- if (log)
- log->Printf ("NativeProcessLinux::%s inferior started, now in stopped state", __FUNCTION__);
+ error = SetDefaultPtraceOpts(tid);
+ if (error.Fail())
+ return -1;
- error = SetDefaultPtraceOpts(pid);
- if (error.Fail())
- {
if (log)
- log->Printf ("NativeProcessLinux::%s inferior failed to set default ptrace options: %s",
- __FUNCTION__, error.AsCString ());
+ log->Printf("NativeProcessLinux::%s() adding tid = %" PRIu64,
+ __FUNCTION__, tid);
- // Mark the inferior as invalid.
- // FIXME this could really use a new state - eStateLaunchFailure. For now, using eStateInvalid.
- SetState (StateType::eStateInvalid);
+ it->second = true;
- return error;
- }
+ // Create the thread, mark it as stopped.
+ NativeThreadLinuxSP thread_sp(AddThread(static_cast<lldb::tid_t>(tid)));
+ assert(thread_sp && "AddThread() returned a nullptr");
- // Release the master terminal descriptor and pass it off to the
- // NativeProcessLinux instance. Similarly stash the inferior pid.
- m_terminal_fd = terminal.ReleaseMasterFileDescriptor();
- m_pid = pid;
- launch_info.SetProcessID(pid);
-
- // Set the terminal fd to be in non blocking mode (it simplifies the
- // implementation of ProcessLinux::GetSTDOUT to have a non-blocking
- // descriptor to read from).
- error = EnsureFDFlags(m_terminal_fd, O_NONBLOCK);
- if (error.Fail())
- {
- if (log)
- log->Printf ("NativeProcessLinux::%s inferior EnsureFDFlags failed for ensuring terminal O_NONBLOCK setting: %s",
- __FUNCTION__, error.AsCString ());
-
- // Mark the inferior as invalid.
- // FIXME this could really use a new state - eStateLaunchFailure. For now, using eStateInvalid.
- SetState (StateType::eStateInvalid);
+ // This will notify this is a new thread and tell the system it is
+ // stopped.
+ thread_sp->SetStoppedBySignal(SIGSTOP);
+ ThreadWasCreated(*thread_sp);
+ SetCurrentThreadID(thread_sp->GetID());
+ }
- return error;
+ // move the loop forward
+ ++it;
}
+ }
- if (log)
- log->Printf ("NativeProcessLinux::%s() adding pid = %" PRIu64, __FUNCTION__, pid);
-
- ResolveProcessArchitecture(m_pid, m_arch);
- NativeThreadLinuxSP thread_sp = AddThread(pid);
- assert (thread_sp && "AddThread() returned a nullptr thread");
- thread_sp->SetStoppedBySignal(SIGSTOP);
- ThreadWasCreated(*thread_sp);
-
+ if (tids_to_attach.size() > 0) {
+ m_pid = pid;
// Let our process instance know the thread has stopped.
- SetCurrentThreadID (thread_sp->GetID ());
- SetState (StateType::eStateStopped);
+ SetState(StateType::eStateStopped);
+ } else {
+ error.SetErrorToGenericError();
+ error.SetErrorString("No such process.");
+ return -1;
+ }
- if (log)
- {
- if (error.Success ())
- log->Printf("NativeProcessLinux::%s inferior launching succeeded", __FUNCTION__);
- else
- log->Printf("NativeProcessLinux::%s inferior launching failed: %s", __FUNCTION__, error.AsCString());
- }
- return error;
+ return pid;
}
-::pid_t
-NativeProcessLinux::Attach(lldb::pid_t pid, Error &error)
-{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+Error NativeProcessLinux::SetDefaultPtraceOpts(lldb::pid_t pid) {
+ long ptrace_opts = 0;
- // Use a map to keep track of the threads which we have attached/need to attach.
- Host::TidMap tids_to_attach;
- if (pid <= 1)
- {
- error.SetErrorToGenericError();
- error.SetErrorString("Attaching to process 1 is not allowed.");
- return -1;
- }
+ // Have the child raise an event on exit. This is used to keep the child in
+ // limbo until it is destroyed.
+ ptrace_opts |= PTRACE_O_TRACEEXIT;
- while (Host::FindProcessThreads(pid, tids_to_attach))
- {
- for (Host::TidMap::iterator it = tids_to_attach.begin();
- it != tids_to_attach.end();)
- {
- if (it->second == false)
- {
- lldb::tid_t tid = it->first;
-
- // Attach to the requested process.
- // An attach will cause the thread to stop with a SIGSTOP.
- error = PtraceWrapper(PTRACE_ATTACH, tid);
- if (error.Fail())
- {
- // No such thread. The thread may have exited.
- // More error handling may be needed.
- if (error.GetError() == ESRCH)
- {
- it = tids_to_attach.erase(it);
- continue;
- }
- else
- return -1;
- }
-
- int status;
- // Need to use __WALL otherwise we receive an error with errno=ECHLD
- // At this point we should have a thread stopped if waitpid succeeds.
- if ((status = waitpid(tid, NULL, __WALL)) < 0)
- {
- // No such thread. The thread may have exited.
- // More error handling may be needed.
- if (errno == ESRCH)
- {
- it = tids_to_attach.erase(it);
- continue;
- }
- else
- {
- error.SetErrorToErrno();
- return -1;
- }
- }
-
- error = SetDefaultPtraceOpts(tid);
- if (error.Fail())
- return -1;
-
- if (log)
- log->Printf ("NativeProcessLinux::%s() adding tid = %" PRIu64, __FUNCTION__, tid);
-
- it->second = true;
-
- // Create the thread, mark it as stopped.
- NativeThreadLinuxSP thread_sp (AddThread(static_cast<lldb::tid_t>(tid)));
- assert (thread_sp && "AddThread() returned a nullptr");
-
- // This will notify this is a new thread and tell the system it is stopped.
- thread_sp->SetStoppedBySignal(SIGSTOP);
- ThreadWasCreated(*thread_sp);
- SetCurrentThreadID (thread_sp->GetID ());
- }
-
- // move the loop forward
- ++it;
- }
- }
+ // Have the tracer trace threads which spawn in the inferior process.
+ // TODO: if we want to support tracing the inferiors' child, add the
+ // appropriate ptrace flags here (PTRACE_O_TRACEFORK, PTRACE_O_TRACEVFORK)
+ ptrace_opts |= PTRACE_O_TRACECLONE;
- if (tids_to_attach.size() > 0)
- {
- m_pid = pid;
- // Let our process instance know the thread has stopped.
- SetState (StateType::eStateStopped);
- }
- else
- {
- error.SetErrorToGenericError();
- error.SetErrorString("No such process.");
- return -1;
- }
+ // Have the tracer notify us before execve returns
+ // (needed to disable legacy SIGTRAP generation)
+ ptrace_opts |= PTRACE_O_TRACEEXEC;
- return pid;
+ return PtraceWrapper(PTRACE_SETOPTIONS, pid, nullptr, (void *)ptrace_opts);
}
-Error
-NativeProcessLinux::SetDefaultPtraceOpts(lldb::pid_t pid)
-{
- long ptrace_opts = 0;
-
- // Have the child raise an event on exit. This is used to keep the child in
- // limbo until it is destroyed.
- ptrace_opts |= PTRACE_O_TRACEEXIT;
-
- // Have the tracer trace threads which spawn in the inferior process.
- // TODO: if we want to support tracing the inferiors' child, add the
- // appropriate ptrace flags here (PTRACE_O_TRACEFORK, PTRACE_O_TRACEVFORK)
- ptrace_opts |= PTRACE_O_TRACECLONE;
-
- // Have the tracer notify us before execve returns
- // (needed to disable legacy SIGTRAP generation)
- ptrace_opts |= PTRACE_O_TRACEEXEC;
-
- return PtraceWrapper(PTRACE_SETOPTIONS, pid, nullptr, (void*)ptrace_opts);
-}
-
-static ExitType convert_pid_status_to_exit_type (int status)
-{
- if (WIFEXITED (status))
- return ExitType::eExitTypeExit;
- else if (WIFSIGNALED (status))
- return ExitType::eExitTypeSignal;
- else if (WIFSTOPPED (status))
- return ExitType::eExitTypeStop;
- else
- {
- // We don't know what this is.
- return ExitType::eExitTypeInvalid;
- }
+static ExitType convert_pid_status_to_exit_type(int status) {
+ if (WIFEXITED(status))
+ return ExitType::eExitTypeExit;
+ else if (WIFSIGNALED(status))
+ return ExitType::eExitTypeSignal;
+ else if (WIFSTOPPED(status))
+ return ExitType::eExitTypeStop;
+ else {
+ // We don't know what this is.
+ return ExitType::eExitTypeInvalid;
+ }
}
-static int convert_pid_status_to_return_code (int status)
-{
- if (WIFEXITED (status))
- return WEXITSTATUS (status);
- else if (WIFSIGNALED (status))
- return WTERMSIG (status);
- else if (WIFSTOPPED (status))
- return WSTOPSIG (status);
- else
- {
- // We don't know what this is.
- return ExitType::eExitTypeInvalid;
- }
+static int convert_pid_status_to_return_code(int status) {
+ if (WIFEXITED(status))
+ return WEXITSTATUS(status);
+ else if (WIFSIGNALED(status))
+ return WTERMSIG(status);
+ else if (WIFSTOPPED(status))
+ return WSTOPSIG(status);
+ else {
+ // We don't know what this is.
+ return ExitType::eExitTypeInvalid;
+ }
}
// Handles all waitpid events from the inferior process.
-void
-NativeProcessLinux::MonitorCallback(lldb::pid_t pid,
- bool exited,
- int signal,
- int status)
-{
- Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS));
+void NativeProcessLinux::MonitorCallback(lldb::pid_t pid, bool exited,
+ int signal, int status) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- // Certain activities differ based on whether the pid is the tid of the main thread.
- const bool is_main_thread = (pid == GetID ());
+ // Certain activities differ based on whether the pid is the tid of the main
+ // thread.
+ const bool is_main_thread = (pid == GetID());
- // Handle when the thread exits.
- if (exited)
- {
+ // Handle when the thread exits.
+ if (exited) {
+ if (log)
+ log->Printf(
+ "NativeProcessLinux::%s() got exit signal(%d) , tid = %" PRIu64
+ " (%s main thread)",
+ __FUNCTION__, signal, pid, is_main_thread ? "is" : "is not");
+
+ // This is a thread that exited. Ensure we're not tracking it anymore.
+ const bool thread_found = StopTrackingThread(pid);
+
+ if (is_main_thread) {
+ // We only set the exit status and notify the delegate if we haven't
+ // already set the process
+ // state to an exited state. We normally should have received a SIGTRAP |
+ // (PTRACE_EVENT_EXIT << 8)
+ // for the main thread.
+ const bool already_notified = (GetState() == StateType::eStateExited) ||
+ (GetState() == StateType::eStateCrashed);
+ if (!already_notified) {
if (log)
- log->Printf ("NativeProcessLinux::%s() got exit signal(%d) , tid = %" PRIu64 " (%s main thread)", __FUNCTION__, signal, pid, is_main_thread ? "is" : "is not");
-
- // This is a thread that exited. Ensure we're not tracking it anymore.
- const bool thread_found = StopTrackingThread (pid);
-
- if (is_main_thread)
- {
- // We only set the exit status and notify the delegate if we haven't already set the process
- // state to an exited state. We normally should have received a SIGTRAP | (PTRACE_EVENT_EXIT << 8)
- // for the main thread.
- const bool already_notified = (GetState() == StateType::eStateExited) || (GetState () == StateType::eStateCrashed);
- if (!already_notified)
- {
- if (log)
- log->Printf ("NativeProcessLinux::%s() tid = %" PRIu64 " handling main thread exit (%s), expected exit state already set but state was %s instead, setting exit state now", __FUNCTION__, pid, thread_found ? "stopped tracking thread metadata" : "thread metadata not found", StateAsCString (GetState ()));
- // The main thread exited. We're done monitoring. Report to delegate.
- SetExitStatus (convert_pid_status_to_exit_type (status), convert_pid_status_to_return_code (status), nullptr, true);
-
- // Notify delegate that our process has exited.
- SetState (StateType::eStateExited, true);
- }
- else
- {
- if (log)
- log->Printf ("NativeProcessLinux::%s() tid = %" PRIu64 " main thread now exited (%s)", __FUNCTION__, pid, thread_found ? "stopped tracking thread metadata" : "thread metadata not found");
- }
- }
- else
- {
- // Do we want to report to the delegate in this case? I think not. If this was an orderly
- // thread exit, we would already have received the SIGTRAP | (PTRACE_EVENT_EXIT << 8) signal,
- // and we would have done an all-stop then.
- if (log)
- log->Printf ("NativeProcessLinux::%s() tid = %" PRIu64 " handling non-main thread exit (%s)", __FUNCTION__, pid, thread_found ? "stopped tracking thread metadata" : "thread metadata not found");
- }
- return;
- }
-
- siginfo_t info;
- const auto info_err = GetSignalInfo(pid, &info);
- auto thread_sp = GetThreadByID(pid);
-
- if (! thread_sp)
- {
- // Normally, the only situation when we cannot find the thread is if we have just
- // received a new thread notification. This is indicated by GetSignalInfo() returning
- // si_code == SI_USER and si_pid == 0
+ log->Printf("NativeProcessLinux::%s() tid = %" PRIu64
+ " handling main thread exit (%s), expected exit state "
+ "already set but state was %s instead, setting exit "
+ "state now",
+ __FUNCTION__, pid,
+ thread_found ? "stopped tracking thread metadata"
+ : "thread metadata not found",
+ StateAsCString(GetState()));
+ // The main thread exited. We're done monitoring. Report to delegate.
+ SetExitStatus(convert_pid_status_to_exit_type(status),
+ convert_pid_status_to_return_code(status), nullptr, true);
+
+ // Notify delegate that our process has exited.
+ SetState(StateType::eStateExited, true);
+ } else {
if (log)
- log->Printf("NativeProcessLinux::%s received notification about an unknown tid %" PRIu64 ".", __FUNCTION__, pid);
-
- if (info_err.Fail())
- {
- if (log)
- log->Printf("NativeProcessLinux::%s (tid %" PRIu64 ") GetSignalInfo failed (%s). Ingoring this notification.", __FUNCTION__, pid, info_err.AsCString());
- return;
- }
-
- if (log && (info.si_code != SI_USER || info.si_pid != 0))
- log->Printf("NativeProcessLinux::%s (tid %" PRIu64 ") unexpected signal info (si_code: %d, si_pid: %d). Treating as a new thread notification anyway.", __FUNCTION__, pid, info.si_code, info.si_pid);
-
- auto thread_sp = AddThread(pid);
- // Resume the newly created thread.
- ResumeThread(*thread_sp, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER);
- ThreadWasCreated(*thread_sp);
- return;
- }
-
- // Get details on the signal raised.
- if (info_err.Success())
- {
- // We have retrieved the signal info. Dispatch appropriately.
- if (info.si_signo == SIGTRAP)
- MonitorSIGTRAP(info, *thread_sp);
- else
- MonitorSignal(info, *thread_sp, exited);
- }
+ log->Printf("NativeProcessLinux::%s() tid = %" PRIu64
+ " main thread now exited (%s)",
+ __FUNCTION__, pid,
+ thread_found ? "stopped tracking thread metadata"
+ : "thread metadata not found");
+ }
+ } else {
+ // Do we want to report to the delegate in this case? I think not. If
+ // this was an orderly
+ // thread exit, we would already have received the SIGTRAP |
+ // (PTRACE_EVENT_EXIT << 8) signal,
+ // and we would have done an all-stop then.
+ if (log)
+ log->Printf("NativeProcessLinux::%s() tid = %" PRIu64
+ " handling non-main thread exit (%s)",
+ __FUNCTION__, pid,
+ thread_found ? "stopped tracking thread metadata"
+ : "thread metadata not found");
+ }
+ return;
+ }
+
+ siginfo_t info;
+ const auto info_err = GetSignalInfo(pid, &info);
+ auto thread_sp = GetThreadByID(pid);
+
+ if (!thread_sp) {
+ // Normally, the only situation when we cannot find the thread is if we have
+ // just
+ // received a new thread notification. This is indicated by GetSignalInfo()
+ // returning
+ // si_code == SI_USER and si_pid == 0
+ if (log)
+ log->Printf("NativeProcessLinux::%s received notification about an "
+ "unknown tid %" PRIu64 ".",
+ __FUNCTION__, pid);
+
+ if (info_err.Fail()) {
+ if (log)
+ log->Printf("NativeProcessLinux::%s (tid %" PRIu64
+ ") GetSignalInfo failed (%s). Ingoring this notification.",
+ __FUNCTION__, pid, info_err.AsCString());
+ return;
+ }
+
+ if (log && (info.si_code != SI_USER || info.si_pid != 0))
+ log->Printf("NativeProcessLinux::%s (tid %" PRIu64
+ ") unexpected signal info (si_code: %d, si_pid: %d). "
+ "Treating as a new thread notification anyway.",
+ __FUNCTION__, pid, info.si_code, info.si_pid);
+
+ auto thread_sp = AddThread(pid);
+ // Resume the newly created thread.
+ ResumeThread(*thread_sp, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER);
+ ThreadWasCreated(*thread_sp);
+ return;
+ }
+
+ // Get details on the signal raised.
+ if (info_err.Success()) {
+ // We have retrieved the signal info. Dispatch appropriately.
+ if (info.si_signo == SIGTRAP)
+ MonitorSIGTRAP(info, *thread_sp);
else
- {
- if (info_err.GetError() == EINVAL)
- {
- // This is a group stop reception for this tid.
- // We can reach here if we reinject SIGSTOP, SIGSTP, SIGTTIN or SIGTTOU into the
- // tracee, triggering the group-stop mechanism. Normally receiving these would stop
- // the process, pending a SIGCONT. Simulating this state in a debugger is hard and is
- // generally not needed (one use case is debugging background task being managed by a
- // shell). For general use, it is sufficient to stop the process in a signal-delivery
- // stop which happens before the group stop. This done by MonitorSignal and works
- // correctly for all signals.
- if (log)
- log->Printf("NativeProcessLinux::%s received a group stop for pid %" PRIu64 " tid %" PRIu64 ". Transparent handling of group stops not supported, resuming the thread.", __FUNCTION__, GetID (), pid);
- ResumeThread(*thread_sp, thread_sp->GetState(), LLDB_INVALID_SIGNAL_NUMBER);
- }
- else
- {
- // ptrace(GETSIGINFO) failed (but not due to group-stop).
-
- // A return value of ESRCH means the thread/process is no longer on the system,
- // so it was killed somehow outside of our control. Either way, we can't do anything
- // with it anymore.
-
- // Stop tracking the metadata for the thread since it's entirely off the system now.
- const bool thread_found = StopTrackingThread (pid);
-
- if (log)
- log->Printf ("NativeProcessLinux::%s GetSignalInfo failed: %s, tid = %" PRIu64 ", signal = %d, status = %d (%s, %s, %s)",
- __FUNCTION__, info_err.AsCString(), pid, signal, status, info_err.GetError() == ESRCH ? "thread/process killed" : "unknown reason", is_main_thread ? "is main thread" : "is not main thread", thread_found ? "thread metadata removed" : "thread metadata not found");
-
- if (is_main_thread)
- {
- // Notify the delegate - our process is not available but appears to have been killed outside
- // our control. Is eStateExited the right exit state in this case?
- SetExitStatus (convert_pid_status_to_exit_type (status), convert_pid_status_to_return_code (status), nullptr, true);
- SetState (StateType::eStateExited, true);
- }
- else
- {
- // This thread was pulled out from underneath us. Anything to do here? Do we want to do an all stop?
- if (log)
- log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " tid %" PRIu64 " non-main thread exit occurred, didn't tell delegate anything since thread disappeared out from underneath us", __FUNCTION__, GetID (), pid);
- }
- }
- }
-}
-
-void
-NativeProcessLinux::WaitForNewThread(::pid_t tid)
-{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
-
- NativeThreadLinuxSP new_thread_sp = GetThreadByID(tid);
-
- if (new_thread_sp)
- {
- // We are already tracking the thread - we got the event on the new thread (see
- // MonitorSignal) before this one. We are done.
- return;
- }
-
- // The thread is not tracked yet, let's wait for it to appear.
- int status = -1;
- ::pid_t wait_pid;
- do
- {
- if (log)
- log->Printf ("NativeProcessLinux::%s() received thread creation event for tid %" PRIu32 ". tid not tracked yet, waiting for thread to appear...", __FUNCTION__, tid);
- wait_pid = waitpid(tid, &status, __WALL);
- }
- while (wait_pid == -1 && errno == EINTR);
- // Since we are waiting on a specific tid, this must be the creation event. But let's do
- // some checks just in case.
- if (wait_pid != tid) {
- if (log)
- log->Printf ("NativeProcessLinux::%s() waiting for tid %" PRIu32 " failed. Assuming the thread has disappeared in the meantime", __FUNCTION__, tid);
- // The only way I know of this could happen is if the whole process was
- // SIGKILLed in the mean time. In any case, we can't do anything about that now.
- return;
- }
- if (WIFEXITED(status))
- {
- if (log)
- log->Printf ("NativeProcessLinux::%s() waiting for tid %" PRIu32 " returned an 'exited' event. Not tracking the thread.", __FUNCTION__, tid);
- // Also a very improbable event.
- return;
- }
-
- siginfo_t info;
- Error error = GetSignalInfo(tid, &info);
- if (error.Fail())
- {
+ MonitorSignal(info, *thread_sp, exited);
+ } else {
+ if (info_err.GetError() == EINVAL) {
+ // This is a group stop reception for this tid.
+ // We can reach here if we reinject SIGSTOP, SIGSTP, SIGTTIN or SIGTTOU
+ // into the
+ // tracee, triggering the group-stop mechanism. Normally receiving these
+ // would stop
+ // the process, pending a SIGCONT. Simulating this state in a debugger is
+ // hard and is
+ // generally not needed (one use case is debugging background task being
+ // managed by a
+ // shell). For general use, it is sufficient to stop the process in a
+ // signal-delivery
+ // stop which happens before the group stop. This done by MonitorSignal
+ // and works
+ // correctly for all signals.
+ if (log)
+ log->Printf(
+ "NativeProcessLinux::%s received a group stop for pid %" PRIu64
+ " tid %" PRIu64 ". Transparent handling of group stops not "
+ "supported, resuming the thread.",
+ __FUNCTION__, GetID(), pid);
+ ResumeThread(*thread_sp, thread_sp->GetState(),
+ LLDB_INVALID_SIGNAL_NUMBER);
+ } else {
+ // ptrace(GETSIGINFO) failed (but not due to group-stop).
+
+ // A return value of ESRCH means the thread/process is no longer on the
+ // system,
+ // so it was killed somehow outside of our control. Either way, we can't
+ // do anything
+ // with it anymore.
+
+ // Stop tracking the metadata for the thread since it's entirely off the
+ // system now.
+ const bool thread_found = StopTrackingThread(pid);
+
+ if (log)
+ log->Printf(
+ "NativeProcessLinux::%s GetSignalInfo failed: %s, tid = %" PRIu64
+ ", signal = %d, status = %d (%s, %s, %s)",
+ __FUNCTION__, info_err.AsCString(), pid, signal, status,
+ info_err.GetError() == ESRCH ? "thread/process killed"
+ : "unknown reason",
+ is_main_thread ? "is main thread" : "is not main thread",
+ thread_found ? "thread metadata removed"
+ : "thread metadata not found");
+
+ if (is_main_thread) {
+ // Notify the delegate - our process is not available but appears to
+ // have been killed outside
+ // our control. Is eStateExited the right exit state in this case?
+ SetExitStatus(convert_pid_status_to_exit_type(status),
+ convert_pid_status_to_return_code(status), nullptr, true);
+ SetState(StateType::eStateExited, true);
+ } else {
+ // This thread was pulled out from underneath us. Anything to do here?
+ // Do we want to do an all stop?
if (log)
- log->Printf ("NativeProcessLinux::%s() GetSignalInfo for tid %" PRIu32 " failed. Assuming the thread has disappeared in the meantime.", __FUNCTION__, tid);
- return;
+ log->Printf("NativeProcessLinux::%s pid %" PRIu64 " tid %" PRIu64
+ " non-main thread exit occurred, didn't tell delegate "
+ "anything since thread disappeared out from underneath "
+ "us",
+ __FUNCTION__, GetID(), pid);
+ }
}
-
- if (((info.si_pid != 0) || (info.si_code != SI_USER)) && log)
- {
- // We should be getting a thread creation signal here, but we received something
- // else. There isn't much we can do about it now, so we will just log that. Since the
- // thread is alive and we are receiving events from it, we shall pretend that it was
- // created properly.
- log->Printf ("NativeProcessLinux::%s() GetSignalInfo for tid %" PRIu32 " received unexpected signal with code %d from pid %d.", __FUNCTION__, tid, info.si_code, info.si_pid);
- }
-
- if (log)
- log->Printf ("NativeProcessLinux::%s() pid = %" PRIu64 ": tracking new thread tid %" PRIu32,
- __FUNCTION__, GetID (), tid);
-
- new_thread_sp = AddThread(tid);
- ResumeThread(*new_thread_sp, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER);
- ThreadWasCreated(*new_thread_sp);
+ }
}
-void
-NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info, NativeThreadLinux &thread)
-{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
- const bool is_main_thread = (thread.GetID() == GetID ());
+void NativeProcessLinux::WaitForNewThread(::pid_t tid) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- assert(info.si_signo == SIGTRAP && "Unexpected child signal!");
+ NativeThreadLinuxSP new_thread_sp = GetThreadByID(tid);
- switch (info.si_code)
- {
- // TODO: these two cases are required if we want to support tracing of the inferiors' children. We'd need this to debug a monitor.
- // case (SIGTRAP | (PTRACE_EVENT_FORK << 8)):
- // case (SIGTRAP | (PTRACE_EVENT_VFORK << 8)):
+ if (new_thread_sp) {
+ // We are already tracking the thread - we got the event on the new thread
+ // (see
+ // MonitorSignal) before this one. We are done.
+ return;
+ }
- case (SIGTRAP | (PTRACE_EVENT_CLONE << 8)):
- {
- // This is the notification on the parent thread which informs us of new thread
- // creation.
- // We don't want to do anything with the parent thread so we just resume it. In case we
- // want to implement "break on thread creation" functionality, we would need to stop
- // here.
-
- unsigned long event_message = 0;
- if (GetEventMessage(thread.GetID(), &event_message).Fail())
- {
- if (log)
- log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " received thread creation event but GetEventMessage failed so we don't know the new tid", __FUNCTION__, thread.GetID());
- } else
- WaitForNewThread(event_message);
+ // The thread is not tracked yet, let's wait for it to appear.
+ int status = -1;
+ ::pid_t wait_pid;
+ do {
+ if (log)
+ log->Printf("NativeProcessLinux::%s() received thread creation event for "
+ "tid %" PRIu32
+ ". tid not tracked yet, waiting for thread to appear...",
+ __FUNCTION__, tid);
+ wait_pid = waitpid(tid, &status, __WALL);
+ } while (wait_pid == -1 && errno == EINTR);
+ // Since we are waiting on a specific tid, this must be the creation event.
+ // But let's do
+ // some checks just in case.
+ if (wait_pid != tid) {
+ if (log)
+ log->Printf(
+ "NativeProcessLinux::%s() waiting for tid %" PRIu32
+ " failed. Assuming the thread has disappeared in the meantime",
+ __FUNCTION__, tid);
+ // The only way I know of this could happen is if the whole process was
+ // SIGKILLed in the mean time. In any case, we can't do anything about that
+ // now.
+ return;
+ }
+ if (WIFEXITED(status)) {
+ if (log)
+ log->Printf("NativeProcessLinux::%s() waiting for tid %" PRIu32
+ " returned an 'exited' event. Not tracking the thread.",
+ __FUNCTION__, tid);
+ // Also a very improbable event.
+ return;
+ }
+
+ siginfo_t info;
+ Error error = GetSignalInfo(tid, &info);
+ if (error.Fail()) {
+ if (log)
+ log->Printf(
+ "NativeProcessLinux::%s() GetSignalInfo for tid %" PRIu32
+ " failed. Assuming the thread has disappeared in the meantime.",
+ __FUNCTION__, tid);
+ return;
+ }
+
+ if (((info.si_pid != 0) || (info.si_code != SI_USER)) && log) {
+ // We should be getting a thread creation signal here, but we received
+ // something
+ // else. There isn't much we can do about it now, so we will just log that.
+ // Since the
+ // thread is alive and we are receiving events from it, we shall pretend
+ // that it was
+ // created properly.
+ log->Printf("NativeProcessLinux::%s() GetSignalInfo for tid %" PRIu32
+ " received unexpected signal with code %d from pid %d.",
+ __FUNCTION__, tid, info.si_code, info.si_pid);
+ }
+
+ if (log)
+ log->Printf("NativeProcessLinux::%s() pid = %" PRIu64
+ ": tracking new thread tid %" PRIu32,
+ __FUNCTION__, GetID(), tid);
+
+ new_thread_sp = AddThread(tid);
+ ResumeThread(*new_thread_sp, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER);
+ ThreadWasCreated(*new_thread_sp);
+}
+
+void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info,
+ NativeThreadLinux &thread) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ const bool is_main_thread = (thread.GetID() == GetID());
+
+ assert(info.si_signo == SIGTRAP && "Unexpected child signal!");
+
+ switch (info.si_code) {
+ // TODO: these two cases are required if we want to support tracing of the
+ // inferiors' children. We'd need this to debug a monitor.
+ // case (SIGTRAP | (PTRACE_EVENT_FORK << 8)):
+ // case (SIGTRAP | (PTRACE_EVENT_VFORK << 8)):
+
+ case (SIGTRAP | (PTRACE_EVENT_CLONE << 8)): {
+ // This is the notification on the parent thread which informs us of new
+ // thread
+ // creation.
+ // We don't want to do anything with the parent thread so we just resume it.
+ // In case we
+ // want to implement "break on thread creation" functionality, we would need
+ // to stop
+ // here.
+
+ unsigned long event_message = 0;
+ if (GetEventMessage(thread.GetID(), &event_message).Fail()) {
+ if (log)
+ log->Printf("NativeProcessLinux::%s() pid %" PRIu64
+ " received thread creation event but GetEventMessage "
+ "failed so we don't know the new tid",
+ __FUNCTION__, thread.GetID());
+ } else
+ WaitForNewThread(event_message);
+
+ ResumeThread(thread, thread.GetState(), LLDB_INVALID_SIGNAL_NUMBER);
+ break;
+ }
+
+ case (SIGTRAP | (PTRACE_EVENT_EXEC << 8)): {
+ NativeThreadLinuxSP main_thread_sp;
+ if (log)
+ log->Printf("NativeProcessLinux::%s() received exec event, code = %d",
+ __FUNCTION__, info.si_code ^ SIGTRAP);
- ResumeThread(thread, thread.GetState(), LLDB_INVALID_SIGNAL_NUMBER);
- break;
- }
+ // Exec clears any pending notifications.
+ m_pending_notification_tid = LLDB_INVALID_THREAD_ID;
- case (SIGTRAP | (PTRACE_EVENT_EXEC << 8)):
- {
- NativeThreadLinuxSP main_thread_sp;
+ // Remove all but the main thread here. Linux fork creates a new process
+ // which only copies the main thread.
+ if (log)
+ log->Printf("NativeProcessLinux::%s exec received, stop tracking all but "
+ "main thread",
+ __FUNCTION__);
+
+ for (auto thread_sp : m_threads) {
+ const bool is_main_thread = thread_sp && thread_sp->GetID() == GetID();
+ if (is_main_thread) {
+ main_thread_sp = std::static_pointer_cast<NativeThreadLinux>(thread_sp);
if (log)
- log->Printf ("NativeProcessLinux::%s() received exec event, code = %d", __FUNCTION__, info.si_code ^ SIGTRAP);
-
- // Exec clears any pending notifications.
- m_pending_notification_tid = LLDB_INVALID_THREAD_ID;
-
- // Remove all but the main thread here. Linux fork creates a new process which only copies the main thread.
+ log->Printf(
+ "NativeProcessLinux::%s found main thread with tid %" PRIu64
+ ", keeping",
+ __FUNCTION__, main_thread_sp->GetID());
+ } else {
if (log)
- log->Printf ("NativeProcessLinux::%s exec received, stop tracking all but main thread", __FUNCTION__);
-
- for (auto thread_sp : m_threads)
- {
- const bool is_main_thread = thread_sp && thread_sp->GetID () == GetID ();
- if (is_main_thread)
- {
- main_thread_sp = std::static_pointer_cast<NativeThreadLinux>(thread_sp);
- if (log)
- log->Printf ("NativeProcessLinux::%s found main thread with tid %" PRIu64 ", keeping", __FUNCTION__, main_thread_sp->GetID ());
- }
- else
- {
- if (log)
- log->Printf ("NativeProcessLinux::%s discarding non-main-thread tid %" PRIu64 " due to exec", __FUNCTION__, thread_sp->GetID ());
- }
- }
-
- m_threads.clear ();
-
- if (main_thread_sp)
- {
- m_threads.push_back (main_thread_sp);
- SetCurrentThreadID (main_thread_sp->GetID ());
- main_thread_sp->SetStoppedByExec();
- }
- else
- {
- SetCurrentThreadID (LLDB_INVALID_THREAD_ID);
- if (log)
- log->Printf ("NativeProcessLinux::%s pid %" PRIu64 "no main thread found, discarded all threads, we're in a no-thread state!", __FUNCTION__, GetID ());
- }
-
- // Tell coordinator about about the "new" (since exec) stopped main thread.
- ThreadWasCreated(*main_thread_sp);
-
- // Let our delegate know we have just exec'd.
- NotifyDidExec ();
-
- // If we have a main thread, indicate we are stopped.
- assert (main_thread_sp && "exec called during ptraced process but no main thread metadata tracked");
-
- // Let the process know we're stopped.
- StopRunningThreads(main_thread_sp->GetID());
-
- break;
+ log->Printf(
+ "NativeProcessLinux::%s discarding non-main-thread tid %" PRIu64
+ " due to exec",
+ __FUNCTION__, thread_sp->GetID());
+ }
}
- case (SIGTRAP | (PTRACE_EVENT_EXIT << 8)):
- {
- // The inferior process or one of its threads is about to exit.
- // We don't want to do anything with the thread so we just resume it. In case we
- // want to implement "break on thread exit" functionality, we would need to stop
- // here.
-
- unsigned long data = 0;
- if (GetEventMessage(thread.GetID(), &data).Fail())
- data = -1;
-
- if (log)
- {
- log->Printf ("NativeProcessLinux::%s() received PTRACE_EVENT_EXIT, data = %lx (WIFEXITED=%s,WIFSIGNALED=%s), pid = %" PRIu64 " (%s)",
- __FUNCTION__,
- data, WIFEXITED (data) ? "true" : "false", WIFSIGNALED (data) ? "true" : "false",
- thread.GetID(),
- is_main_thread ? "is main thread" : "not main thread");
- }
+ m_threads.clear();
- if (is_main_thread)
- {
- SetExitStatus (convert_pid_status_to_exit_type (data), convert_pid_status_to_return_code (data), nullptr, true);
- }
-
- StateType state = thread.GetState();
- if (! StateIsRunningState(state))
- {
- // Due to a kernel bug, we may sometimes get this stop after the inferior gets a
- // SIGKILL. This confuses our state tracking logic in ResumeThread(), since normally,
- // we should not be receiving any ptrace events while the inferior is stopped. This
- // makes sure that the inferior is resumed and exits normally.
- state = eStateRunning;
- }
- ResumeThread(thread, state, LLDB_INVALID_SIGNAL_NUMBER);
-
- break;
- }
-
- case 0:
- case TRAP_TRACE: // We receive this on single stepping.
- case TRAP_HWBKPT: // We receive this on watchpoint hit
- {
- // If a watchpoint was hit, report it
- uint32_t wp_index;
- Error error = thread.GetRegisterContext()->GetWatchpointHitIndex(wp_index, (uintptr_t)info.si_addr);
- if (error.Fail() && log)
- log->Printf("NativeProcessLinux::%s() "
- "received error while checking for watchpoint hits, "
- "pid = %" PRIu64 " error = %s",
- __FUNCTION__, thread.GetID(), error.AsCString());
- if (wp_index != LLDB_INVALID_INDEX32)
- {
- MonitorWatchpoint(thread, wp_index);
- break;
- }
-
- // Otherwise, report step over
- MonitorTrace(thread);
- break;
- }
-
- case SI_KERNEL:
+ if (main_thread_sp) {
+ m_threads.push_back(main_thread_sp);
+ SetCurrentThreadID(main_thread_sp->GetID());
+ main_thread_sp->SetStoppedByExec();
+ } else {
+ SetCurrentThreadID(LLDB_INVALID_THREAD_ID);
+ if (log)
+ log->Printf("NativeProcessLinux::%s pid %" PRIu64
+ "no main thread found, discarded all threads, we're in a "
+ "no-thread state!",
+ __FUNCTION__, GetID());
+ }
+
+ // Tell coordinator about about the "new" (since exec) stopped main thread.
+ ThreadWasCreated(*main_thread_sp);
+
+ // Let our delegate know we have just exec'd.
+ NotifyDidExec();
+
+ // If we have a main thread, indicate we are stopped.
+ assert(main_thread_sp && "exec called during ptraced process but no main "
+ "thread metadata tracked");
+
+ // Let the process know we're stopped.
+ StopRunningThreads(main_thread_sp->GetID());
+
+ break;
+ }
+
+ case (SIGTRAP | (PTRACE_EVENT_EXIT << 8)): {
+ // The inferior process or one of its threads is about to exit.
+ // We don't want to do anything with the thread so we just resume it. In
+ // case we
+ // want to implement "break on thread exit" functionality, we would need to
+ // stop
+ // here.
+
+ unsigned long data = 0;
+ if (GetEventMessage(thread.GetID(), &data).Fail())
+ data = -1;
+
+ if (log) {
+ log->Printf("NativeProcessLinux::%s() received PTRACE_EVENT_EXIT, data = "
+ "%lx (WIFEXITED=%s,WIFSIGNALED=%s), pid = %" PRIu64 " (%s)",
+ __FUNCTION__, data, WIFEXITED(data) ? "true" : "false",
+ WIFSIGNALED(data) ? "true" : "false", thread.GetID(),
+ is_main_thread ? "is main thread" : "not main thread");
+ }
+
+ if (is_main_thread) {
+ SetExitStatus(convert_pid_status_to_exit_type(data),
+ convert_pid_status_to_return_code(data), nullptr, true);
+ }
+
+ StateType state = thread.GetState();
+ if (!StateIsRunningState(state)) {
+ // Due to a kernel bug, we may sometimes get this stop after the inferior
+ // gets a
+ // SIGKILL. This confuses our state tracking logic in ResumeThread(),
+ // since normally,
+ // we should not be receiving any ptrace events while the inferior is
+ // stopped. This
+ // makes sure that the inferior is resumed and exits normally.
+ state = eStateRunning;
+ }
+ ResumeThread(thread, state, LLDB_INVALID_SIGNAL_NUMBER);
+
+ break;
+ }
+
+ case 0:
+ case TRAP_TRACE: // We receive this on single stepping.
+ case TRAP_HWBKPT: // We receive this on watchpoint hit
+ {
+ // If a watchpoint was hit, report it
+ uint32_t wp_index;
+ Error error = thread.GetRegisterContext()->GetWatchpointHitIndex(
+ wp_index, (uintptr_t)info.si_addr);
+ if (error.Fail() && log)
+ log->Printf("NativeProcessLinux::%s() "
+ "received error while checking for watchpoint hits, "
+ "pid = %" PRIu64 " error = %s",
+ __FUNCTION__, thread.GetID(), error.AsCString());
+ if (wp_index != LLDB_INVALID_INDEX32) {
+ MonitorWatchpoint(thread, wp_index);
+ break;
+ }
+
+ // Otherwise, report step over
+ MonitorTrace(thread);
+ break;
+ }
+
+ case SI_KERNEL:
#if defined __mips__
- // For mips there is no special signal for watchpoint
- // So we check for watchpoint in kernel trap
- {
- // If a watchpoint was hit, report it
- uint32_t wp_index;
- Error error = thread.GetRegisterContext()->GetWatchpointHitIndex(wp_index, LLDB_INVALID_ADDRESS);
- if (error.Fail() && log)
- log->Printf("NativeProcessLinux::%s() "
- "received error while checking for watchpoint hits, "
- "pid = %" PRIu64 " error = %s",
- __FUNCTION__, thread.GetID(), error.AsCString());
- if (wp_index != LLDB_INVALID_INDEX32)
- {
- MonitorWatchpoint(thread, wp_index);
- break;
- }
+ // For mips there is no special signal for watchpoint
+ // So we check for watchpoint in kernel trap
+ {
+ // If a watchpoint was hit, report it
+ uint32_t wp_index;
+ Error error = thread.GetRegisterContext()->GetWatchpointHitIndex(
+ wp_index, LLDB_INVALID_ADDRESS);
+ if (error.Fail() && log)
+ log->Printf("NativeProcessLinux::%s() "
+ "received error while checking for watchpoint hits, "
+ "pid = %" PRIu64 " error = %s",
+ __FUNCTION__, thread.GetID(), error.AsCString());
+ if (wp_index != LLDB_INVALID_INDEX32) {
+ MonitorWatchpoint(thread, wp_index);
+ break;
+ }
}
- // NO BREAK
+// NO BREAK
#endif
- case TRAP_BRKPT:
- MonitorBreakpoint(thread);
- break;
+ case TRAP_BRKPT:
+ MonitorBreakpoint(thread);
+ break;
- case SIGTRAP:
- case (SIGTRAP | 0x80):
- if (log)
- log->Printf ("NativeProcessLinux::%s() received unknown SIGTRAP system call stop event, pid %" PRIu64 "tid %" PRIu64 ", resuming", __FUNCTION__, GetID (), thread.GetID());
+ case SIGTRAP:
+ case (SIGTRAP | 0x80):
+ if (log)
+ log->Printf("NativeProcessLinux::%s() received unknown SIGTRAP system "
+ "call stop event, pid %" PRIu64 "tid %" PRIu64 ", resuming",
+ __FUNCTION__, GetID(), thread.GetID());
- // Ignore these signals until we know more about them.
- ResumeThread(thread, thread.GetState(), LLDB_INVALID_SIGNAL_NUMBER);
- break;
+ // Ignore these signals until we know more about them.
+ ResumeThread(thread, thread.GetState(), LLDB_INVALID_SIGNAL_NUMBER);
+ break;
- default:
- assert(false && "Unexpected SIGTRAP code!");
- if (log)
- log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 "tid %" PRIu64 " received unhandled SIGTRAP code: 0x%d",
- __FUNCTION__, GetID(), thread.GetID(), info.si_code);
- break;
-
- }
-}
-
-void
-NativeProcessLinux::MonitorTrace(NativeThreadLinux &thread)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ default:
+ assert(false && "Unexpected SIGTRAP code!");
if (log)
- log->Printf("NativeProcessLinux::%s() received trace event, pid = %" PRIu64 " (single stepping)",
+ log->Printf("NativeProcessLinux::%s() pid %" PRIu64 "tid %" PRIu64
+ " received unhandled SIGTRAP code: 0x%d",
+ __FUNCTION__, GetID(), thread.GetID(), info.si_code);
+ break;
+ }
+}
+
+void NativeProcessLinux::MonitorTrace(NativeThreadLinux &thread) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("NativeProcessLinux::%s() received trace event, pid = %" PRIu64
+ " (single stepping)",
__FUNCTION__, thread.GetID());
- // This thread is currently stopped.
- thread.SetStoppedByTrace();
+ // This thread is currently stopped.
+ thread.SetStoppedByTrace();
- StopRunningThreads(thread.GetID());
+ StopRunningThreads(thread.GetID());
}
-void
-NativeProcessLinux::MonitorBreakpoint(NativeThreadLinux &thread)
-{
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_BREAKPOINTS));
- if (log)
- log->Printf("NativeProcessLinux::%s() received breakpoint event, pid = %" PRIu64,
- __FUNCTION__, thread.GetID());
+void NativeProcessLinux::MonitorBreakpoint(NativeThreadLinux &thread) {
+ Log *log(
+ GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_BREAKPOINTS));
+ if (log)
+ log->Printf(
+ "NativeProcessLinux::%s() received breakpoint event, pid = %" PRIu64,
+ __FUNCTION__, thread.GetID());
- // Mark the thread as stopped at breakpoint.
- thread.SetStoppedByBreakpoint();
- Error error = FixupBreakpointPCAsNeeded(thread);
- if (error.Fail())
- if (log)
- log->Printf("NativeProcessLinux::%s() pid = %" PRIu64 " fixup: %s",
- __FUNCTION__, thread.GetID(), error.AsCString());
+ // Mark the thread as stopped at breakpoint.
+ thread.SetStoppedByBreakpoint();
+ Error error = FixupBreakpointPCAsNeeded(thread);
+ if (error.Fail())
+ if (log)
+ log->Printf("NativeProcessLinux::%s() pid = %" PRIu64 " fixup: %s",
+ __FUNCTION__, thread.GetID(), error.AsCString());
- if (m_threads_stepping_with_breakpoint.find(thread.GetID()) != m_threads_stepping_with_breakpoint.end())
- thread.SetStoppedByTrace();
+ if (m_threads_stepping_with_breakpoint.find(thread.GetID()) !=
+ m_threads_stepping_with_breakpoint.end())
+ thread.SetStoppedByTrace();
- StopRunningThreads(thread.GetID());
+ StopRunningThreads(thread.GetID());
}
-void
-NativeProcessLinux::MonitorWatchpoint(NativeThreadLinux &thread, uint32_t wp_index)
-{
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf("NativeProcessLinux::%s() received watchpoint event, "
- "pid = %" PRIu64 ", wp_index = %" PRIu32,
- __FUNCTION__, thread.GetID(), wp_index);
+void NativeProcessLinux::MonitorWatchpoint(NativeThreadLinux &thread,
+ uint32_t wp_index) {
+ Log *log(
+ GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_WATCHPOINTS));
+ if (log)
+ log->Printf("NativeProcessLinux::%s() received watchpoint event, "
+ "pid = %" PRIu64 ", wp_index = %" PRIu32,
+ __FUNCTION__, thread.GetID(), wp_index);
- // Mark the thread as stopped at watchpoint.
- // The address is at (lldb::addr_t)info->si_addr if we need it.
- thread.SetStoppedByWatchpoint(wp_index);
+ // Mark the thread as stopped at watchpoint.
+ // The address is at (lldb::addr_t)info->si_addr if we need it.
+ thread.SetStoppedByWatchpoint(wp_index);
- // We need to tell all other running threads before we notify the delegate about this stop.
- StopRunningThreads(thread.GetID());
+ // We need to tell all other running threads before we notify the delegate
+ // about this stop.
+ StopRunningThreads(thread.GetID());
}
-void
-NativeProcessLinux::MonitorSignal(const siginfo_t &info, NativeThreadLinux &thread, bool exited)
-{
- const int signo = info.si_signo;
- const bool is_from_llgs = info.si_pid == getpid ();
-
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_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 Linux.
- //
- // IOW, user generated signals never generate what we consider to be a
- // "crash".
- //
- // Similarly, ACK signals generated by this monitor.
-
- // Handle the signal.
- if (info.si_code == SI_TKILL || info.si_code == SI_USER)
- {
- if (log)
- log->Printf ("NativeProcessLinux::%s() received signal %s (%d) with code %s, (siginfo pid = %d (%s), waitpid pid = %" PRIu64 ")",
- __FUNCTION__,
- Host::GetSignalAsCString(signo),
- signo,
- (info.si_code == SI_TKILL ? "SI_TKILL" : "SI_USER"),
- info.si_pid,
- is_from_llgs ? "from llgs" : "not from llgs",
- thread.GetID());
- }
+void NativeProcessLinux::MonitorSignal(const siginfo_t &info,
+ NativeThreadLinux &thread, bool exited) {
+ const int signo = info.si_signo;
+ const bool is_from_llgs = info.si_pid == getpid();
- // Check for thread stop notification.
- if (is_from_llgs && (info.si_code == SI_TKILL) && (signo == SIGSTOP))
- {
- // This is a tgkill()-based stop.
- if (log)
- log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " tid %" PRIu64 ", thread stopped",
- __FUNCTION__,
- GetID (),
- thread.GetID());
-
- // Check that we're not already marked with a stop reason.
- // Note this thread really shouldn't already be marked as stopped - if we were, that would imply that
- // the kernel signaled us with the thread stopping which we handled and marked as stopped,
- // and that, without an intervening resume, we received another stop. It is more likely
- // that we are missing the marking of a run state somewhere if we find that the thread was
- // marked as stopped.
- const StateType thread_state = thread.GetState();
- if (!StateIsStoppedState (thread_state, false))
- {
- // An inferior thread has stopped because of a SIGSTOP we have sent it.
- // Generally, these are not important stops and we don't want to report them as
- // they are just used to stop other threads when one thread (the one with the
- // *real* stop reason) hits a breakpoint (watchpoint, etc...). However, in the
- // case of an asynchronous Interrupt(), this *is* the real stop reason, so we
- // leave the signal intact if this is the thread that was chosen as the
- // triggering thread.
- if (m_pending_notification_tid != LLDB_INVALID_THREAD_ID)
- {
- if (m_pending_notification_tid == thread.GetID())
- thread.SetStoppedBySignal(SIGSTOP, &info);
- else
- thread.SetStoppedWithNoReason();
-
- SetCurrentThreadID (thread.GetID ());
- SignalIfAllThreadsStopped();
- }
- else
- {
- // We can end up here if stop was initiated by LLGS but by this time a
- // thread stop has occurred - maybe initiated by another event.
- Error error = ResumeThread(thread, thread.GetState(), 0);
- if (error.Fail() && log)
- {
- log->Printf("NativeProcessLinux::%s failed to resume thread tid %" PRIu64 ": %s",
- __FUNCTION__, thread.GetID(), error.AsCString());
- }
- }
- }
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_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 Linux.
+ //
+ // IOW, user generated signals never generate what we consider to be a
+ // "crash".
+ //
+ // Similarly, ACK signals generated by this monitor.
+
+ // Handle the signal.
+ if (info.si_code == SI_TKILL || info.si_code == SI_USER) {
+ if (log)
+ log->Printf("NativeProcessLinux::%s() received signal %s (%d) with code "
+ "%s, (siginfo pid = %d (%s), waitpid pid = %" PRIu64 ")",
+ __FUNCTION__, Host::GetSignalAsCString(signo), signo,
+ (info.si_code == SI_TKILL ? "SI_TKILL" : "SI_USER"),
+ info.si_pid, is_from_llgs ? "from llgs" : "not from llgs",
+ thread.GetID());
+ }
+
+ // Check for thread stop notification.
+ if (is_from_llgs && (info.si_code == SI_TKILL) && (signo == SIGSTOP)) {
+ // This is a tgkill()-based stop.
+ if (log)
+ log->Printf("NativeProcessLinux::%s() pid %" PRIu64 " tid %" PRIu64
+ ", thread stopped",
+ __FUNCTION__, GetID(), thread.GetID());
+
+ // Check that we're not already marked with a stop reason.
+ // Note this thread really shouldn't already be marked as stopped - if we
+ // were, that would imply that
+ // the kernel signaled us with the thread stopping which we handled and
+ // marked as stopped,
+ // and that, without an intervening resume, we received another stop. It is
+ // more likely
+ // that we are missing the marking of a run state somewhere if we find that
+ // the thread was
+ // marked as stopped.
+ const StateType thread_state = thread.GetState();
+ if (!StateIsStoppedState(thread_state, false)) {
+ // An inferior thread has stopped because of a SIGSTOP we have sent it.
+ // Generally, these are not important stops and we don't want to report
+ // them as
+ // they are just used to stop other threads when one thread (the one with
+ // the
+ // *real* stop reason) hits a breakpoint (watchpoint, etc...). However, in
+ // the
+ // case of an asynchronous Interrupt(), this *is* the real stop reason, so
+ // we
+ // leave the signal intact if this is the thread that was chosen as the
+ // triggering thread.
+ if (m_pending_notification_tid != LLDB_INVALID_THREAD_ID) {
+ if (m_pending_notification_tid == thread.GetID())
+ thread.SetStoppedBySignal(SIGSTOP, &info);
else
- {
- if (log)
- {
- // Retrieve the signal name if the thread was stopped by a signal.
- int stop_signo = 0;
- const bool stopped_by_signal = thread.IsStopped(&stop_signo);
- const char *signal_name = stopped_by_signal ? Host::GetSignalAsCString(stop_signo) : "<not stopped by signal>";
- if (!signal_name)
- signal_name = "<no-signal-name>";
-
- log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " tid %" PRIu64 ", thread was already marked as a stopped state (state=%s, signal=%d (%s)), leaving stop signal as is",
- __FUNCTION__,
- GetID (),
- thread.GetID(),
- StateAsCString (thread_state),
- stop_signo,
- signal_name);
- }
- SignalIfAllThreadsStopped();
+ thread.SetStoppedWithNoReason();
+
+ SetCurrentThreadID(thread.GetID());
+ SignalIfAllThreadsStopped();
+ } else {
+ // We can end up here if stop was initiated by LLGS but by this time a
+ // thread stop has occurred - maybe initiated by another event.
+ Error error = ResumeThread(thread, thread.GetState(), 0);
+ if (error.Fail() && log) {
+ log->Printf(
+ "NativeProcessLinux::%s failed to resume thread tid %" PRIu64
+ ": %s",
+ __FUNCTION__, thread.GetID(), error.AsCString());
}
+ }
+ } else {
+ if (log) {
+ // Retrieve the signal name if the thread was stopped by a signal.
+ int stop_signo = 0;
+ const bool stopped_by_signal = thread.IsStopped(&stop_signo);
+ const char *signal_name = stopped_by_signal
+ ? Host::GetSignalAsCString(stop_signo)
+ : "<not stopped by signal>";
+ if (!signal_name)
+ signal_name = "<no-signal-name>";
- // Done handling.
- return;
+ log->Printf("NativeProcessLinux::%s() pid %" PRIu64 " tid %" PRIu64
+ ", thread was already marked as a stopped state (state=%s, "
+ "signal=%d (%s)), leaving stop signal as is",
+ __FUNCTION__, GetID(), thread.GetID(),
+ StateAsCString(thread_state), stop_signo, signal_name);
+ }
+ SignalIfAllThreadsStopped();
}
- if (log)
- log->Printf ("NativeProcessLinux::%s() received signal %s", __FUNCTION__, Host::GetSignalAsCString(signo));
+ // Done handling.
+ return;
+ }
- // This thread is stopped.
- thread.SetStoppedBySignal(signo, &info);
+ if (log)
+ log->Printf("NativeProcessLinux::%s() received signal %s", __FUNCTION__,
+ Host::GetSignalAsCString(signo));
- // Send a stop to the debugger after we get all other threads to stop.
- StopRunningThreads(thread.GetID());
+ // This thread is stopped.
+ thread.SetStoppedBySignal(signo, &info);
+
+ // Send a stop to the debugger after we get all other threads to stop.
+ StopRunningThreads(thread.GetID());
}
namespace {
-struct EmulatorBaton
-{
- NativeProcessLinux* m_process;
- NativeRegisterContext* m_reg_context;
+struct EmulatorBaton {
+ NativeProcessLinux *m_process;
+ NativeRegisterContext *m_reg_context;
- // eRegisterKindDWARF -> RegsiterValue
- std::unordered_map<uint32_t, RegisterValue> m_register_values;
+ // eRegisterKindDWARF -> RegsiterValue
+ std::unordered_map<uint32_t, RegisterValue> m_register_values;
- EmulatorBaton(NativeProcessLinux* process, NativeRegisterContext* reg_context) :
- m_process(process), m_reg_context(reg_context) {}
+ EmulatorBaton(NativeProcessLinux *process, NativeRegisterContext *reg_context)
+ : m_process(process), m_reg_context(reg_context) {}
};
} // anonymous namespace
-static size_t
-ReadMemoryCallback (EmulateInstruction *instruction,
- void *baton,
- const EmulateInstruction::Context &context,
- lldb::addr_t addr,
- void *dst,
- size_t length)
-{
- EmulatorBaton* emulator_baton = static_cast<EmulatorBaton*>(baton);
+static size_t ReadMemoryCallback(EmulateInstruction *instruction, void *baton,
+ const EmulateInstruction::Context &context,
+ lldb::addr_t addr, void *dst, size_t length) {
+ EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
- size_t bytes_read;
- emulator_baton->m_process->ReadMemory(addr, dst, length, bytes_read);
- return bytes_read;
+ size_t bytes_read;
+ emulator_baton->m_process->ReadMemory(addr, dst, length, bytes_read);
+ return bytes_read;
}
-static bool
-ReadRegisterCallback (EmulateInstruction *instruction,
- void *baton,
- const RegisterInfo *reg_info,
- RegisterValue &reg_value)
-{
- EmulatorBaton* emulator_baton = static_cast<EmulatorBaton*>(baton);
-
- auto it = emulator_baton->m_register_values.find(reg_info->kinds[eRegisterKindDWARF]);
- if (it != emulator_baton->m_register_values.end())
- {
- reg_value = it->second;
- return true;
- }
+static bool ReadRegisterCallback(EmulateInstruction *instruction, void *baton,
+ const RegisterInfo *reg_info,
+ RegisterValue &reg_value) {
+ EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
- // The emulator only fill in the dwarf regsiter numbers (and in some case
- // the generic register numbers). Get the full register info from the
- // register context based on the dwarf register numbers.
- const RegisterInfo* full_reg_info = emulator_baton->m_reg_context->GetRegisterInfo(
- eRegisterKindDWARF, reg_info->kinds[eRegisterKindDWARF]);
-
- Error error = emulator_baton->m_reg_context->ReadRegister(full_reg_info, reg_value);
- if (error.Success())
- return true;
+ auto it = emulator_baton->m_register_values.find(
+ reg_info->kinds[eRegisterKindDWARF]);
+ if (it != emulator_baton->m_register_values.end()) {
+ reg_value = it->second;
+ return true;
+ }
+
+ // The emulator only fill in the dwarf regsiter numbers (and in some case
+ // the generic register numbers). Get the full register info from the
+ // register context based on the dwarf register numbers.
+ const RegisterInfo *full_reg_info =
+ emulator_baton->m_reg_context->GetRegisterInfo(
+ eRegisterKindDWARF, reg_info->kinds[eRegisterKindDWARF]);
+
+ Error error =
+ emulator_baton->m_reg_context->ReadRegister(full_reg_info, reg_value);
+ if (error.Success())
+ return true;
- return false;
+ return false;
}
-static bool
-WriteRegisterCallback (EmulateInstruction *instruction,
- void *baton,
- const EmulateInstruction::Context &context,
- const RegisterInfo *reg_info,
- const RegisterValue &reg_value)
-{
- EmulatorBaton* emulator_baton = static_cast<EmulatorBaton*>(baton);
- emulator_baton->m_register_values[reg_info->kinds[eRegisterKindDWARF]] = reg_value;
- return true;
+static bool WriteRegisterCallback(EmulateInstruction *instruction, void *baton,
+ const EmulateInstruction::Context &context,
+ const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) {
+ EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
+ emulator_baton->m_register_values[reg_info->kinds[eRegisterKindDWARF]] =
+ reg_value;
+ return true;
}
-static size_t
-WriteMemoryCallback (EmulateInstruction *instruction,
- void *baton,
- const EmulateInstruction::Context &context,
- lldb::addr_t addr,
- const void *dst,
- size_t length)
-{
- return length;
+static size_t WriteMemoryCallback(EmulateInstruction *instruction, void *baton,
+ const EmulateInstruction::Context &context,
+ lldb::addr_t addr, const void *dst,
+ size_t length) {
+ return length;
}
-static lldb::addr_t
-ReadFlags (NativeRegisterContext* regsiter_context)
-{
- const RegisterInfo* flags_info = regsiter_context->GetRegisterInfo(
- eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
- return regsiter_context->ReadRegisterAsUnsigned(flags_info, LLDB_INVALID_ADDRESS);
+static lldb::addr_t ReadFlags(NativeRegisterContext *regsiter_context) {
+ const RegisterInfo *flags_info = regsiter_context->GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
+ return regsiter_context->ReadRegisterAsUnsigned(flags_info,
+ LLDB_INVALID_ADDRESS);
}
-Error
-NativeProcessLinux::SetupSoftwareSingleStepping(NativeThreadLinux &thread)
-{
- Error error;
- NativeRegisterContextSP register_context_sp = thread.GetRegisterContext();
+Error NativeProcessLinux::SetupSoftwareSingleStepping(
+ NativeThreadLinux &thread) {
+ Error error;
+ NativeRegisterContextSP register_context_sp = thread.GetRegisterContext();
- std::unique_ptr<EmulateInstruction> emulator_ap(
- EmulateInstruction::FindPlugin(m_arch, eInstructionTypePCModifying, nullptr));
+ std::unique_ptr<EmulateInstruction> emulator_ap(
+ EmulateInstruction::FindPlugin(m_arch, eInstructionTypePCModifying,
+ nullptr));
- if (emulator_ap == nullptr)
- return Error("Instruction emulator not found!");
+ if (emulator_ap == nullptr)
+ return Error("Instruction emulator not found!");
- EmulatorBaton baton(this, register_context_sp.get());
- emulator_ap->SetBaton(&baton);
- emulator_ap->SetReadMemCallback(&ReadMemoryCallback);
- emulator_ap->SetReadRegCallback(&ReadRegisterCallback);
- emulator_ap->SetWriteMemCallback(&WriteMemoryCallback);
- emulator_ap->SetWriteRegCallback(&WriteRegisterCallback);
+ EmulatorBaton baton(this, register_context_sp.get());
+ emulator_ap->SetBaton(&baton);
+ emulator_ap->SetReadMemCallback(&ReadMemoryCallback);
+ emulator_ap->SetReadRegCallback(&ReadRegisterCallback);
+ emulator_ap->SetWriteMemCallback(&WriteMemoryCallback);
+ emulator_ap->SetWriteRegCallback(&WriteRegisterCallback);
- if (!emulator_ap->ReadInstruction())
- return Error("Read instruction failed!");
+ if (!emulator_ap->ReadInstruction())
+ return Error("Read instruction failed!");
- bool emulation_result = emulator_ap->EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC);
+ bool emulation_result =
+ emulator_ap->EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC);
- const RegisterInfo* reg_info_pc = register_context_sp->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
- const RegisterInfo* reg_info_flags = register_context_sp->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
+ const RegisterInfo *reg_info_pc = register_context_sp->GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+ const RegisterInfo *reg_info_flags = register_context_sp->GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
- auto pc_it = baton.m_register_values.find(reg_info_pc->kinds[eRegisterKindDWARF]);
- auto flags_it = baton.m_register_values.find(reg_info_flags->kinds[eRegisterKindDWARF]);
+ auto pc_it =
+ baton.m_register_values.find(reg_info_pc->kinds[eRegisterKindDWARF]);
+ auto flags_it =
+ baton.m_register_values.find(reg_info_flags->kinds[eRegisterKindDWARF]);
- lldb::addr_t next_pc;
- lldb::addr_t next_flags;
- if (emulation_result)
- {
- assert(pc_it != baton.m_register_values.end() && "Emulation was successfull but PC wasn't updated");
- next_pc = pc_it->second.GetAsUInt64();
+ lldb::addr_t next_pc;
+ lldb::addr_t next_flags;
+ if (emulation_result) {
+ assert(pc_it != baton.m_register_values.end() &&
+ "Emulation was successfull but PC wasn't updated");
+ next_pc = pc_it->second.GetAsUInt64();
- if (flags_it != baton.m_register_values.end())
- next_flags = flags_it->second.GetAsUInt64();
- else
- next_flags = ReadFlags (register_context_sp.get());
- }
- else if (pc_it == baton.m_register_values.end())
- {
- // Emulate instruction failed and it haven't changed PC. Advance PC
- // with the size of the current opcode because the emulation of all
- // PC modifying instruction should be successful. The failure most
- // likely caused by a not supported instruction which don't modify PC.
- next_pc = register_context_sp->GetPC() + emulator_ap->GetOpcode().GetByteSize();
- next_flags = ReadFlags (register_context_sp.get());
- }
+ if (flags_it != baton.m_register_values.end())
+ next_flags = flags_it->second.GetAsUInt64();
else
- {
- // The instruction emulation failed after it modified the PC. It is an
- // unknown error where we can't continue because the next instruction is
- // modifying the PC but we don't know how.
- return Error ("Instruction emulation failed unexpectedly.");
- }
-
- if (m_arch.GetMachine() == llvm::Triple::arm)
- {
- if (next_flags & 0x20)
- {
- // Thumb mode
- error = SetSoftwareBreakpoint(next_pc, 2);
- }
- else
- {
- // Arm mode
- error = SetSoftwareBreakpoint(next_pc, 4);
- }
- }
- else if (m_arch.GetMachine() == llvm::Triple::mips64
- || m_arch.GetMachine() == llvm::Triple::mips64el
- || m_arch.GetMachine() == llvm::Triple::mips
- || m_arch.GetMachine() == llvm::Triple::mipsel)
- error = SetSoftwareBreakpoint(next_pc, 4);
- else
- {
- // No size hint is given for the next breakpoint
- error = SetSoftwareBreakpoint(next_pc, 0);
- }
-
- if (error.Fail())
- return error;
+ next_flags = ReadFlags(register_context_sp.get());
+ } else if (pc_it == baton.m_register_values.end()) {
+ // Emulate instruction failed and it haven't changed PC. Advance PC
+ // with the size of the current opcode because the emulation of all
+ // PC modifying instruction should be successful. The failure most
+ // likely caused by a not supported instruction which don't modify PC.
+ next_pc =
+ register_context_sp->GetPC() + emulator_ap->GetOpcode().GetByteSize();
+ next_flags = ReadFlags(register_context_sp.get());
+ } else {
+ // The instruction emulation failed after it modified the PC. It is an
+ // unknown error where we can't continue because the next instruction is
+ // modifying the PC but we don't know how.
+ return Error("Instruction emulation failed unexpectedly.");
+ }
+
+ if (m_arch.GetMachine() == llvm::Triple::arm) {
+ if (next_flags & 0x20) {
+ // Thumb mode
+ error = SetSoftwareBreakpoint(next_pc, 2);
+ } else {
+ // Arm mode
+ error = SetSoftwareBreakpoint(next_pc, 4);
+ }
+ } else if (m_arch.GetMachine() == llvm::Triple::mips64 ||
+ m_arch.GetMachine() == llvm::Triple::mips64el ||
+ m_arch.GetMachine() == llvm::Triple::mips ||
+ m_arch.GetMachine() == llvm::Triple::mipsel)
+ error = SetSoftwareBreakpoint(next_pc, 4);
+ else {
+ // No size hint is given for the next breakpoint
+ error = SetSoftwareBreakpoint(next_pc, 0);
+ }
+
+ // If setting the breakpoint fails because next_pc is out of
+ // the address space, ignore it and let the debugee segfault.
+ if (error.GetError() == EIO || error.GetError() == EFAULT) {
+ return Error();
+ } else if (error.Fail())
+ return error;
- m_threads_stepping_with_breakpoint.insert({thread.GetID(), next_pc});
+ m_threads_stepping_with_breakpoint.insert({thread.GetID(), next_pc});
- return Error();
+ return Error();
}
-bool
-NativeProcessLinux::SupportHardwareSingleStepping() const
-{
- if (m_arch.GetMachine() == llvm::Triple::arm
- || m_arch.GetMachine() == llvm::Triple::mips64 || m_arch.GetMachine() == llvm::Triple::mips64el
- || m_arch.GetMachine() == llvm::Triple::mips || m_arch.GetMachine() == llvm::Triple::mipsel)
- return false;
- return true;
+bool NativeProcessLinux::SupportHardwareSingleStepping() const {
+ if (m_arch.GetMachine() == llvm::Triple::arm ||
+ m_arch.GetMachine() == llvm::Triple::mips64 ||
+ m_arch.GetMachine() == llvm::Triple::mips64el ||
+ m_arch.GetMachine() == llvm::Triple::mips ||
+ m_arch.GetMachine() == llvm::Triple::mipsel)
+ return false;
+ return true;
}
-Error
-NativeProcessLinux::Resume (const ResumeActionList &resume_actions)
-{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
- if (log)
- log->Printf ("NativeProcessLinux::%s called: pid %" PRIu64, __FUNCTION__, GetID ());
+Error NativeProcessLinux::Resume(const ResumeActionList &resume_actions) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+ if (log)
+ log->Printf("NativeProcessLinux::%s called: pid %" PRIu64, __FUNCTION__,
+ GetID());
- bool software_single_step = !SupportHardwareSingleStepping();
+ bool software_single_step = !SupportHardwareSingleStepping();
- if (software_single_step)
- {
- for (auto thread_sp : m_threads)
- {
- assert (thread_sp && "thread list should not contain NULL threads");
-
- const ResumeAction *const action = resume_actions.GetActionForThread (thread_sp->GetID (), true);
- if (action == nullptr)
- continue;
-
- if (action->state == eStateStepping)
- {
- Error error = SetupSoftwareSingleStepping(static_cast<NativeThreadLinux &>(*thread_sp));
- if (error.Fail())
- return error;
- }
- }
+ if (software_single_step) {
+ for (auto thread_sp : m_threads) {
+ assert(thread_sp && "thread list should not contain NULL threads");
+
+ const ResumeAction *const action =
+ resume_actions.GetActionForThread(thread_sp->GetID(), true);
+ if (action == nullptr)
+ continue;
+
+ if (action->state == eStateStepping) {
+ Error error = SetupSoftwareSingleStepping(
+ static_cast<NativeThreadLinux &>(*thread_sp));
+ if (error.Fail())
+ return error;
+ }
}
+ }
- for (auto thread_sp : m_threads)
- {
- assert (thread_sp && "thread list should not contain NULL threads");
+ for (auto thread_sp : m_threads) {
+ assert(thread_sp && "thread list should not contain NULL threads");
- const ResumeAction *const action = resume_actions.GetActionForThread (thread_sp->GetID (), true);
+ const ResumeAction *const action =
+ resume_actions.GetActionForThread(thread_sp->GetID(), true);
- if (action == nullptr)
- {
- if (log)
- log->Printf ("NativeProcessLinux::%s no action specified for pid %" PRIu64 " tid %" PRIu64,
- __FUNCTION__, GetID (), thread_sp->GetID ());
- continue;
- }
+ if (action == nullptr) {
+ if (log)
+ log->Printf(
+ "NativeProcessLinux::%s no action specified for pid %" PRIu64
+ " tid %" PRIu64,
+ __FUNCTION__, GetID(), thread_sp->GetID());
+ continue;
+ }
- if (log)
- {
- log->Printf ("NativeProcessLinux::%s processing resume action state %s for pid %" PRIu64 " tid %" PRIu64,
- __FUNCTION__, StateAsCString (action->state), GetID (), thread_sp->GetID ());
- }
+ if (log) {
+ log->Printf("NativeProcessLinux::%s processing resume action state %s "
+ "for pid %" PRIu64 " tid %" PRIu64,
+ __FUNCTION__, StateAsCString(action->state), GetID(),
+ thread_sp->GetID());
+ }
- switch (action->state)
- {
- case eStateRunning:
- case eStateStepping:
- {
- // Run the thread, possibly feeding it the signal.
- const int signo = action->signal;
- ResumeThread(static_cast<NativeThreadLinux &>(*thread_sp), action->state, signo);
- break;
- }
+ switch (action->state) {
+ case eStateRunning:
+ case eStateStepping: {
+ // Run the thread, possibly feeding it the signal.
+ const int signo = action->signal;
+ ResumeThread(static_cast<NativeThreadLinux &>(*thread_sp), action->state,
+ signo);
+ break;
+ }
- case eStateSuspended:
- case eStateStopped:
- lldbassert(0 && "Unexpected state");
+ case eStateSuspended:
+ case eStateStopped:
+ lldbassert(0 && "Unexpected state");
- default:
- return Error ("NativeProcessLinux::%s (): unexpected state %s specified for pid %" PRIu64 ", tid %" PRIu64,
- __FUNCTION__, StateAsCString (action->state), GetID (), thread_sp->GetID ());
- }
+ default:
+ return Error("NativeProcessLinux::%s (): unexpected state %s specified "
+ "for pid %" PRIu64 ", tid %" PRIu64,
+ __FUNCTION__, StateAsCString(action->state), GetID(),
+ thread_sp->GetID());
}
+ }
- return Error();
+ return Error();
}
-Error
-NativeProcessLinux::Halt ()
-{
- Error error;
+Error NativeProcessLinux::Halt() {
+ Error error;
- if (kill (GetID (), SIGSTOP) != 0)
- error.SetErrorToErrno ();
+ if (kill(GetID(), SIGSTOP) != 0)
+ error.SetErrorToErrno();
- return error;
+ return error;
}
-Error
-NativeProcessLinux::Detach ()
-{
- Error error;
+Error NativeProcessLinux::Detach() {
+ Error error;
- // Stop monitoring the inferior.
- m_sigchld_handle.reset();
+ // Stop monitoring the inferior.
+ m_sigchld_handle.reset();
- // Tell ptrace to detach from the process.
- if (GetID () == LLDB_INVALID_PROCESS_ID)
- return error;
+ // Tell ptrace to detach from the process.
+ if (GetID() == LLDB_INVALID_PROCESS_ID)
+ return error;
- for (auto thread_sp : m_threads)
- {
- Error e = Detach(thread_sp->GetID());
- if (e.Fail())
- error = e; // Save the error, but still attempt to detach from other threads.
- }
+ for (auto thread_sp : m_threads) {
+ Error e = Detach(thread_sp->GetID());
+ if (e.Fail())
+ error =
+ e; // Save the error, but still attempt to detach from other threads.
+ }
- return error;
+ return error;
}
-Error
-NativeProcessLinux::Signal (int signo)
-{
- Error error;
+Error NativeProcessLinux::Signal(int signo) {
+ Error error;
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf ("NativeProcessLinux::%s: sending signal %d (%s) to pid %" PRIu64,
- __FUNCTION__, signo, Host::GetSignalAsCString(signo), GetID());
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf(
+ "NativeProcessLinux::%s: sending signal %d (%s) to pid %" PRIu64,
+ __FUNCTION__, signo, Host::GetSignalAsCString(signo), GetID());
- if (kill(GetID(), signo))
- error.SetErrorToErrno();
+ if (kill(GetID(), signo))
+ error.SetErrorToErrno();
- return error;
+ return error;
}
-Error
-NativeProcessLinux::Interrupt ()
-{
- // Pick a running thread (or if none, a not-dead stopped thread) as
- // the chosen thread that will be the stop-reason thread.
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+Error NativeProcessLinux::Interrupt() {
+ // Pick a running thread (or if none, a not-dead stopped thread) as
+ // the chosen thread that will be the stop-reason thread.
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- NativeThreadProtocolSP running_thread_sp;
- NativeThreadProtocolSP stopped_thread_sp;
-
- if (log)
- log->Printf ("NativeProcessLinux::%s selecting running thread for interrupt target", __FUNCTION__);
+ NativeThreadProtocolSP running_thread_sp;
+ NativeThreadProtocolSP stopped_thread_sp;
- for (auto thread_sp : m_threads)
- {
- // The thread shouldn't be null but lets just cover that here.
- if (!thread_sp)
- continue;
+ if (log)
+ log->Printf(
+ "NativeProcessLinux::%s selecting running thread for interrupt target",
+ __FUNCTION__);
- // If we have a running or stepping thread, we'll call that the
- // target of the interrupt.
- const auto thread_state = thread_sp->GetState ();
- if (thread_state == eStateRunning ||
- thread_state == eStateStepping)
- {
- running_thread_sp = thread_sp;
- break;
- }
- else if (!stopped_thread_sp && StateIsStoppedState (thread_state, true))
- {
- // Remember the first non-dead stopped thread. We'll use that as a backup if there are no running threads.
- stopped_thread_sp = thread_sp;
- }
- }
+ for (auto thread_sp : m_threads) {
+ // The thread shouldn't be null but lets just cover that here.
+ if (!thread_sp)
+ continue;
- if (!running_thread_sp && !stopped_thread_sp)
- {
- Error error("found no running/stepping or live stopped threads as target for interrupt");
- if (log)
- log->Printf ("NativeProcessLinux::%s skipping due to error: %s", __FUNCTION__, error.AsCString ());
-
- return error;
+ // If we have a running or stepping thread, we'll call that the
+ // target of the interrupt.
+ const auto thread_state = thread_sp->GetState();
+ if (thread_state == eStateRunning || thread_state == eStateStepping) {
+ running_thread_sp = thread_sp;
+ break;
+ } else if (!stopped_thread_sp && StateIsStoppedState(thread_state, true)) {
+ // Remember the first non-dead stopped thread. We'll use that as a backup
+ // if there are no running threads.
+ stopped_thread_sp = thread_sp;
}
+ }
- NativeThreadProtocolSP deferred_signal_thread_sp = running_thread_sp ? running_thread_sp : stopped_thread_sp;
-
- if (log)
- log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " %s tid %" PRIu64 " chosen for interrupt target",
- __FUNCTION__,
- GetID (),
- running_thread_sp ? "running" : "stopped",
- deferred_signal_thread_sp->GetID ());
-
- StopRunningThreads(deferred_signal_thread_sp->GetID());
-
- return Error();
-}
-
-Error
-NativeProcessLinux::Kill ()
-{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+ if (!running_thread_sp && !stopped_thread_sp) {
+ Error error("found no running/stepping or live stopped threads as target "
+ "for interrupt");
if (log)
- log->Printf ("NativeProcessLinux::%s called for PID %" PRIu64, __FUNCTION__, GetID ());
-
- Error error;
-
- switch (m_state)
- {
- case StateType::eStateInvalid:
- case StateType::eStateExited:
- case StateType::eStateCrashed:
- case StateType::eStateDetached:
- case StateType::eStateUnloaded:
- // Nothing to do - the process is already dead.
- if (log)
- log->Printf ("NativeProcessLinux::%s ignored for PID %" PRIu64 " due to current state: %s", __FUNCTION__, GetID (), StateAsCString (m_state));
- return error;
-
- case StateType::eStateConnected:
- case StateType::eStateAttaching:
- case StateType::eStateLaunching:
- case StateType::eStateStopped:
- case StateType::eStateRunning:
- case StateType::eStateStepping:
- case StateType::eStateSuspended:
- // We can try to kill a process in these states.
- break;
- }
-
- if (kill (GetID (), SIGKILL) != 0)
- {
- error.SetErrorToErrno ();
- return error;
- }
+ log->Printf("NativeProcessLinux::%s skipping due to error: %s",
+ __FUNCTION__, error.AsCString());
return error;
-}
+ }
-static Error
-ParseMemoryRegionInfoFromProcMapsLine (const std::string &maps_line, MemoryRegionInfo &memory_region_info)
-{
- memory_region_info.Clear();
-
- StringExtractor line_extractor (maps_line.c_str ());
+ NativeThreadProtocolSP deferred_signal_thread_sp =
+ running_thread_sp ? running_thread_sp : stopped_thread_sp;
- // Format: {address_start_hex}-{address_end_hex} perms offset dev inode pathname
- // perms: rwxp (letter is present if set, '-' if not, final character is p=private, s=shared).
+ if (log)
+ log->Printf("NativeProcessLinux::%s pid %" PRIu64 " %s tid %" PRIu64
+ " chosen for interrupt target",
+ __FUNCTION__, GetID(),
+ running_thread_sp ? "running" : "stopped",
+ deferred_signal_thread_sp->GetID());
- // Parse out the starting address
- lldb::addr_t start_address = line_extractor.GetHexMaxU64 (false, 0);
+ StopRunningThreads(deferred_signal_thread_sp->GetID());
- // Parse out hyphen separating start and end address from range.
- if (!line_extractor.GetBytesLeft () || (line_extractor.GetChar () != '-'))
- return Error ("malformed /proc/{pid}/maps entry, missing dash between address range");
-
- // Parse out the ending address
- lldb::addr_t end_address = line_extractor.GetHexMaxU64 (false, start_address);
-
- // Parse out the space after the address.
- if (!line_extractor.GetBytesLeft () || (line_extractor.GetChar () != ' '))
- return Error ("malformed /proc/{pid}/maps entry, missing space after range");
+ return Error();
+}
- // Save the range.
- memory_region_info.GetRange ().SetRangeBase (start_address);
- memory_region_info.GetRange ().SetRangeEnd (end_address);
+Error NativeProcessLinux::Kill() {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("NativeProcessLinux::%s called for PID %" PRIu64, __FUNCTION__,
+ GetID());
- // Any memory region in /proc/{pid}/maps is by definition mapped into the process.
- memory_region_info.SetMapped(MemoryRegionInfo::OptionalBool::eYes);
+ Error error;
- // Parse out each permission entry.
- if (line_extractor.GetBytesLeft () < 4)
- return Error ("malformed /proc/{pid}/maps entry, missing some portion of permissions");
+ switch (m_state) {
+ case StateType::eStateInvalid:
+ case StateType::eStateExited:
+ case StateType::eStateCrashed:
+ case StateType::eStateDetached:
+ case StateType::eStateUnloaded:
+ // Nothing to do - the process is already dead.
+ if (log)
+ log->Printf("NativeProcessLinux::%s ignored for PID %" PRIu64
+ " due to current state: %s",
+ __FUNCTION__, GetID(), StateAsCString(m_state));
+ return error;
- // Handle read permission.
- const char read_perm_char = line_extractor.GetChar ();
- if (read_perm_char == 'r')
- memory_region_info.SetReadable (MemoryRegionInfo::OptionalBool::eYes);
- else if (read_perm_char == '-')
- memory_region_info.SetReadable (MemoryRegionInfo::OptionalBool::eNo);
- else
- return Error ("unexpected /proc/{pid}/maps read permission char");
-
- // Handle write permission.
- const char write_perm_char = line_extractor.GetChar ();
- if (write_perm_char == 'w')
- memory_region_info.SetWritable (MemoryRegionInfo::OptionalBool::eYes);
- else if (write_perm_char == '-')
- memory_region_info.SetWritable (MemoryRegionInfo::OptionalBool::eNo);
- else
- return Error ("unexpected /proc/{pid}/maps write permission char");
-
- // Handle execute permission.
- const char exec_perm_char = line_extractor.GetChar ();
- if (exec_perm_char == 'x')
- memory_region_info.SetExecutable (MemoryRegionInfo::OptionalBool::eYes);
- else if (exec_perm_char == '-')
- memory_region_info.SetExecutable (MemoryRegionInfo::OptionalBool::eNo);
- else
- return Error ("unexpected /proc/{pid}/maps exec permission char");
+ case StateType::eStateConnected:
+ case StateType::eStateAttaching:
+ case StateType::eStateLaunching:
+ case StateType::eStateStopped:
+ case StateType::eStateRunning:
+ case StateType::eStateStepping:
+ case StateType::eStateSuspended:
+ // We can try to kill a process in these states.
+ break;
+ }
+
+ if (kill(GetID(), SIGKILL) != 0) {
+ error.SetErrorToErrno();
+ return error;
+ }
- return Error ();
+ return error;
}
-Error
-NativeProcessLinux::GetMemoryRegionInfo (lldb::addr_t load_addr, MemoryRegionInfo &range_info)
-{
- // FIXME review that the final memory region returned extends to the end of the virtual address space,
- // with no perms if it is not mapped.
-
- // Use an approach that reads memory regions from /proc/{pid}/maps.
- // Assume proc maps entries are in ascending order.
- // FIXME assert if we find differently.
-
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
- Error error;
-
- if (m_supports_mem_region == LazyBool::eLazyBoolNo)
- {
- // We're done.
- error.SetErrorString ("unsupported");
- return error;
- }
-
- // If our cache is empty, pull the latest. There should always be at least one memory region
- // if memory region handling is supported.
- if (m_mem_region_cache.empty ())
- {
- error = ProcFileReader::ProcessLineByLine (GetID (), "maps",
- [&] (const std::string &line) -> bool
- {
- MemoryRegionInfo info;
- const Error parse_error = ParseMemoryRegionInfoFromProcMapsLine (line, info);
- if (parse_error.Success ())
- {
- m_mem_region_cache.push_back (info);
- return true;
- }
- else
- {
- if (log)
- log->Printf ("NativeProcessLinux::%s failed to parse proc maps line '%s': %s", __FUNCTION__, line.c_str (), error.AsCString ());
- return false;
- }
- });
-
- // If we had an error, we'll mark unsupported.
- if (error.Fail ())
- {
- m_supports_mem_region = LazyBool::eLazyBoolNo;
- return error;
- }
- else if (m_mem_region_cache.empty ())
- {
- // No entries after attempting to read them. This shouldn't happen if /proc/{pid}/maps
- // is supported. Assume we don't support map entries via procfs.
+static Error
+ParseMemoryRegionInfoFromProcMapsLine(const std::string &maps_line,
+ MemoryRegionInfo &memory_region_info) {
+ memory_region_info.Clear();
+
+ StringExtractor line_extractor(maps_line.c_str());
+
+ // Format: {address_start_hex}-{address_end_hex} perms offset dev inode
+ // pathname
+ // perms: rwxp (letter is present if set, '-' if not, final character is
+ // p=private, s=shared).
+
+ // Parse out the starting address
+ lldb::addr_t start_address = line_extractor.GetHexMaxU64(false, 0);
+
+ // Parse out hyphen separating start and end address from range.
+ if (!line_extractor.GetBytesLeft() || (line_extractor.GetChar() != '-'))
+ return Error(
+ "malformed /proc/{pid}/maps entry, missing dash between address range");
+
+ // Parse out the ending address
+ lldb::addr_t end_address = line_extractor.GetHexMaxU64(false, start_address);
+
+ // Parse out the space after the address.
+ if (!line_extractor.GetBytesLeft() || (line_extractor.GetChar() != ' '))
+ return Error("malformed /proc/{pid}/maps entry, missing space after range");
+
+ // Save the range.
+ memory_region_info.GetRange().SetRangeBase(start_address);
+ memory_region_info.GetRange().SetRangeEnd(end_address);
+
+ // Any memory region in /proc/{pid}/maps is by definition mapped into the
+ // process.
+ memory_region_info.SetMapped(MemoryRegionInfo::OptionalBool::eYes);
+
+ // Parse out each permission entry.
+ if (line_extractor.GetBytesLeft() < 4)
+ return Error("malformed /proc/{pid}/maps entry, missing some portion of "
+ "permissions");
+
+ // Handle read permission.
+ const char read_perm_char = line_extractor.GetChar();
+ if (read_perm_char == 'r')
+ memory_region_info.SetReadable(MemoryRegionInfo::OptionalBool::eYes);
+ else if (read_perm_char == '-')
+ memory_region_info.SetReadable(MemoryRegionInfo::OptionalBool::eNo);
+ else
+ return Error("unexpected /proc/{pid}/maps read permission char");
+
+ // Handle write permission.
+ const char write_perm_char = line_extractor.GetChar();
+ if (write_perm_char == 'w')
+ memory_region_info.SetWritable(MemoryRegionInfo::OptionalBool::eYes);
+ else if (write_perm_char == '-')
+ memory_region_info.SetWritable(MemoryRegionInfo::OptionalBool::eNo);
+ else
+ return Error("unexpected /proc/{pid}/maps write permission char");
+
+ // Handle execute permission.
+ const char exec_perm_char = line_extractor.GetChar();
+ if (exec_perm_char == 'x')
+ memory_region_info.SetExecutable(MemoryRegionInfo::OptionalBool::eYes);
+ else if (exec_perm_char == '-')
+ memory_region_info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo);
+ else
+ return Error("unexpected /proc/{pid}/maps exec permission char");
+
+ line_extractor.GetChar(); // Read the private bit
+ line_extractor.SkipSpaces(); // Skip the separator
+ line_extractor.GetHexMaxU64(false, 0); // Read the offset
+ line_extractor.GetHexMaxU64(false, 0); // Read the major device number
+ line_extractor.GetChar(); // Read the device id separator
+ line_extractor.GetHexMaxU64(false, 0); // Read the major device number
+ line_extractor.SkipSpaces(); // Skip the separator
+ line_extractor.GetU64(0, 10); // Read the inode number
+
+ line_extractor.SkipSpaces();
+ const char *name = line_extractor.Peek();
+ if (name)
+ memory_region_info.SetName(name);
+
+ return Error();
+}
+
+Error NativeProcessLinux::GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &range_info) {
+ // FIXME review that the final memory region returned extends to the end of
+ // the virtual address space,
+ // with no perms if it is not mapped.
+
+ // Use an approach that reads memory regions from /proc/{pid}/maps.
+ // Assume proc maps entries are in ascending order.
+ // FIXME assert if we find differently.
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Error error;
+
+ if (m_supports_mem_region == LazyBool::eLazyBoolNo) {
+ // We're done.
+ error.SetErrorString("unsupported");
+ return error;
+ }
+
+ // If our cache is empty, pull the latest. There should always be at least
+ // one memory region
+ // if memory region handling is supported.
+ if (m_mem_region_cache.empty()) {
+ error = ProcFileReader::ProcessLineByLine(
+ GetID(), "maps", [&](const std::string &line) -> bool {
+ MemoryRegionInfo info;
+ const Error parse_error =
+ ParseMemoryRegionInfoFromProcMapsLine(line, info);
+ if (parse_error.Success()) {
+ m_mem_region_cache.push_back(info);
+ return true;
+ } else {
if (log)
- log->Printf ("NativeProcessLinux::%s failed to find any procfs maps entries, assuming no support for memory region metadata retrieval", __FUNCTION__);
- m_supports_mem_region = LazyBool::eLazyBoolNo;
- error.SetErrorString ("not supported");
- return error;
- }
-
- if (log)
- log->Printf ("NativeProcessLinux::%s read %" PRIu64 " memory region entries from /proc/%" PRIu64 "/maps", __FUNCTION__, static_cast<uint64_t> (m_mem_region_cache.size ()), GetID ());
-
- // We support memory retrieval, remember that.
- m_supports_mem_region = LazyBool::eLazyBoolYes;
- }
- else
- {
- if (log)
- log->Printf ("NativeProcessLinux::%s reusing %" PRIu64 " cached memory region entries", __FUNCTION__, static_cast<uint64_t> (m_mem_region_cache.size ()));
- }
-
- lldb::addr_t prev_base_address = 0;
-
- // FIXME start by finding the last region that is <= target address using binary search. Data is sorted.
- // There can be a ton of regions on pthreads apps with lots of threads.
- for (auto it = m_mem_region_cache.begin(); it != m_mem_region_cache.end (); ++it)
- {
- MemoryRegionInfo &proc_entry_info = *it;
-
- // Sanity check assumption that /proc/{pid}/maps entries are ascending.
- assert ((proc_entry_info.GetRange ().GetRangeBase () >= prev_base_address) && "descending /proc/pid/maps entries detected, unexpected");
- prev_base_address = proc_entry_info.GetRange ().GetRangeBase ();
-
- // If the target address comes before this entry, indicate distance to next region.
- if (load_addr < proc_entry_info.GetRange ().GetRangeBase ())
- {
- range_info.GetRange ().SetRangeBase (load_addr);
- range_info.GetRange ().SetByteSize (proc_entry_info.GetRange ().GetRangeBase () - load_addr);
- range_info.SetReadable (MemoryRegionInfo::OptionalBool::eNo);
- range_info.SetWritable (MemoryRegionInfo::OptionalBool::eNo);
- range_info.SetExecutable (MemoryRegionInfo::OptionalBool::eNo);
- range_info.SetMapped(MemoryRegionInfo::OptionalBool::eNo);
-
- return error;
- }
- else if (proc_entry_info.GetRange ().Contains (load_addr))
- {
- // The target address is within the memory region we're processing here.
- range_info = proc_entry_info;
- return error;
- }
+ log->Printf("NativeProcessLinux::%s failed to parse proc maps "
+ "line '%s': %s",
+ __FUNCTION__, line.c_str(), error.AsCString());
+ return false;
+ }
+ });
- // The target memory address comes somewhere after the region we just parsed.
+ // If we had an error, we'll mark unsupported.
+ if (error.Fail()) {
+ m_supports_mem_region = LazyBool::eLazyBoolNo;
+ return error;
+ } else if (m_mem_region_cache.empty()) {
+ // No entries after attempting to read them. This shouldn't happen if
+ // /proc/{pid}/maps
+ // is supported. Assume we don't support map entries via procfs.
+ if (log)
+ log->Printf("NativeProcessLinux::%s failed to find any procfs maps "
+ "entries, assuming no support for memory region metadata "
+ "retrieval",
+ __FUNCTION__);
+ m_supports_mem_region = LazyBool::eLazyBoolNo;
+ error.SetErrorString("not supported");
+ return error;
}
- // If we made it here, we didn't find an entry that contained the given address. Return the
- // load_addr as start and the amount of bytes betwwen load address and the end of the memory as
- // size.
- range_info.GetRange ().SetRangeBase (load_addr);
- range_info.GetRange ().SetRangeEnd(LLDB_INVALID_ADDRESS);
- range_info.SetReadable (MemoryRegionInfo::OptionalBool::eNo);
- range_info.SetWritable (MemoryRegionInfo::OptionalBool::eNo);
- range_info.SetExecutable (MemoryRegionInfo::OptionalBool::eNo);
- range_info.SetMapped(MemoryRegionInfo::OptionalBool::eNo);
- return error;
-}
-
-void
-NativeProcessLinux::DoStopIDBumped (uint32_t newBumpId)
-{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
if (log)
- log->Printf ("NativeProcessLinux::%s(newBumpId=%" PRIu32 ") called", __FUNCTION__, newBumpId);
-
- if (log)
- log->Printf ("NativeProcessLinux::%s clearing %" PRIu64 " entries from the cache", __FUNCTION__, static_cast<uint64_t> (m_mem_region_cache.size ()));
- m_mem_region_cache.clear ();
-}
-
-Error
-NativeProcessLinux::AllocateMemory(size_t size, uint32_t permissions, lldb::addr_t &addr)
-{
- // FIXME implementing this requires the equivalent of
- // InferiorCallPOSIX::InferiorCallMmap, which depends on
- // functional ThreadPlans working with Native*Protocol.
+ log->Printf("NativeProcessLinux::%s read %" PRIu64
+ " memory region entries from /proc/%" PRIu64 "/maps",
+ __FUNCTION__,
+ static_cast<uint64_t>(m_mem_region_cache.size()), GetID());
+
+ // We support memory retrieval, remember that.
+ m_supports_mem_region = LazyBool::eLazyBoolYes;
+ } else {
+ if (log)
+ log->Printf("NativeProcessLinux::%s reusing %" PRIu64
+ " cached memory region entries",
+ __FUNCTION__,
+ static_cast<uint64_t>(m_mem_region_cache.size()));
+ }
+
+ lldb::addr_t prev_base_address = 0;
+
+ // FIXME start by finding the last region that is <= target address using
+ // binary search. Data is sorted.
+ // There can be a ton of regions on pthreads apps with lots of threads.
+ for (auto it = m_mem_region_cache.begin(); it != m_mem_region_cache.end();
+ ++it) {
+ MemoryRegionInfo &proc_entry_info = *it;
+
+ // Sanity check assumption that /proc/{pid}/maps entries are ascending.
+ assert((proc_entry_info.GetRange().GetRangeBase() >= prev_base_address) &&
+ "descending /proc/pid/maps entries detected, unexpected");
+ prev_base_address = proc_entry_info.GetRange().GetRangeBase();
+
+ // If the target address comes before this entry, indicate distance to next
+ // region.
+ if (load_addr < proc_entry_info.GetRange().GetRangeBase()) {
+ range_info.GetRange().SetRangeBase(load_addr);
+ range_info.GetRange().SetByteSize(
+ proc_entry_info.GetRange().GetRangeBase() - load_addr);
+ range_info.SetReadable(MemoryRegionInfo::OptionalBool::eNo);
+ range_info.SetWritable(MemoryRegionInfo::OptionalBool::eNo);
+ range_info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo);
+ range_info.SetMapped(MemoryRegionInfo::OptionalBool::eNo);
+
+ return error;
+ } else if (proc_entry_info.GetRange().Contains(load_addr)) {
+ // The target address is within the memory region we're processing here.
+ range_info = proc_entry_info;
+ return error;
+ }
+
+ // The target memory address comes somewhere after the region we just
+ // parsed.
+ }
+
+ // If we made it here, we didn't find an entry that contained the given
+ // address. Return the
+ // load_addr as start and the amount of bytes betwwen load address and the end
+ // of the memory as
+ // size.
+ range_info.GetRange().SetRangeBase(load_addr);
+ range_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
+ range_info.SetReadable(MemoryRegionInfo::OptionalBool::eNo);
+ range_info.SetWritable(MemoryRegionInfo::OptionalBool::eNo);
+ range_info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo);
+ range_info.SetMapped(MemoryRegionInfo::OptionalBool::eNo);
+ return error;
+}
+
+void NativeProcessLinux::DoStopIDBumped(uint32_t newBumpId) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("NativeProcessLinux::%s(newBumpId=%" PRIu32 ") called",
+ __FUNCTION__, newBumpId);
+
+ if (log)
+ log->Printf("NativeProcessLinux::%s clearing %" PRIu64
+ " entries from the cache",
+ __FUNCTION__, static_cast<uint64_t>(m_mem_region_cache.size()));
+ m_mem_region_cache.clear();
+}
+
+Error NativeProcessLinux::AllocateMemory(size_t size, uint32_t permissions,
+ lldb::addr_t &addr) {
+// FIXME implementing this requires the equivalent of
+// InferiorCallPOSIX::InferiorCallMmap, which depends on
+// functional ThreadPlans working with Native*Protocol.
#if 1
- return Error ("not implemented yet");
+ return Error("not implemented yet");
#else
+ 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;
+
+ // TODO implement this directly in NativeProcessLinux
+ // (and lift to NativeProcessPOSIX if/when that class is
+ // refactored out).
+ if (InferiorCallMmap(this, addr, 0, size, prot,
+ eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
+ m_addr_to_mmap_size[addr] = size;
+ return Error();
+ } else {
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;
-
- // TODO implement this directly in NativeProcessLinux
- // (and lift to NativeProcessPOSIX if/when that class is
- // refactored out).
- if (InferiorCallMmap(this, addr, 0, size, prot,
- eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
- m_addr_to_mmap_size[addr] = size;
- return Error ();
- } else {
- addr = LLDB_INVALID_ADDRESS;
- return Error("unable to allocate %" PRIu64 " bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions));
- }
+ return Error("unable to allocate %" PRIu64
+ " bytes of memory with permissions %s",
+ size, GetPermissionsAsCString(permissions));
+ }
#endif
}
-Error
-NativeProcessLinux::DeallocateMemory (lldb::addr_t addr)
-{
- // FIXME see comments in AllocateMemory - required lower-level
- // bits not in place yet (ThreadPlans)
- return Error ("not implemented");
+Error NativeProcessLinux::DeallocateMemory(lldb::addr_t addr) {
+ // FIXME see comments in AllocateMemory - required lower-level
+ // bits not in place yet (ThreadPlans)
+ return Error("not implemented");
}
-lldb::addr_t
-NativeProcessLinux::GetSharedLibraryInfoAddress ()
-{
- // punt on this for now
- return LLDB_INVALID_ADDRESS;
+lldb::addr_t NativeProcessLinux::GetSharedLibraryInfoAddress() {
+ // punt on this for now
+ return LLDB_INVALID_ADDRESS;
}
-size_t
-NativeProcessLinux::UpdateThreads ()
-{
- // The NativeProcessLinux monitoring threads are always up to date
- // with respect to thread state and they keep the thread list
- // populated properly. All this method needs to do is return the
- // thread count.
- return m_threads.size ();
+size_t NativeProcessLinux::UpdateThreads() {
+ // The NativeProcessLinux monitoring threads are always up to date
+ // with respect to thread state and they keep the thread list
+ // populated properly. All this method needs to do is return the
+ // thread count.
+ return m_threads.size();
}
-bool
-NativeProcessLinux::GetArchitecture (ArchSpec &arch) const
-{
- arch = m_arch;
- return true;
+bool NativeProcessLinux::GetArchitecture(ArchSpec &arch) const {
+ arch = m_arch;
+ return true;
}
-Error
-NativeProcessLinux::GetSoftwareBreakpointPCOffset(uint32_t &actual_opcode_size)
-{
- // FIXME put this behind a breakpoint protocol class that can be
- // set per architecture. Need ARM, MIPS support here.
- static const uint8_t g_i386_opcode [] = { 0xCC };
- static const uint8_t g_s390x_opcode[] = { 0x00, 0x01 };
+Error NativeProcessLinux::GetSoftwareBreakpointPCOffset(
+ uint32_t &actual_opcode_size) {
+ // FIXME put this behind a breakpoint protocol class that can be
+ // set per architecture. Need ARM, MIPS support here.
+ static const uint8_t g_i386_opcode[] = {0xCC};
+ static const uint8_t g_s390x_opcode[] = {0x00, 0x01};
- switch (m_arch.GetMachine ())
- {
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- actual_opcode_size = static_cast<uint32_t> (sizeof(g_i386_opcode));
- return Error ();
-
- case llvm::Triple::systemz:
- actual_opcode_size = static_cast<uint32_t> (sizeof(g_s390x_opcode));
- return Error ();
-
- case llvm::Triple::arm:
- case llvm::Triple::aarch64:
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el:
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- // On these architectures the PC don't get updated for breakpoint hits
- actual_opcode_size = 0;
- return Error ();
-
- default:
- assert(false && "CPU type not supported!");
- return Error ("CPU type not supported");
- }
-}
+ switch (m_arch.GetMachine()) {
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ actual_opcode_size = static_cast<uint32_t>(sizeof(g_i386_opcode));
+ return Error();
-Error
-NativeProcessLinux::SetBreakpoint (lldb::addr_t addr, uint32_t size, bool hardware)
-{
- if (hardware)
- return Error ("NativeProcessLinux does not support hardware breakpoints");
- else
- return SetSoftwareBreakpoint (addr, size);
-}
+ case llvm::Triple::systemz:
+ actual_opcode_size = static_cast<uint32_t>(sizeof(g_s390x_opcode));
+ return Error();
-Error
-NativeProcessLinux::GetSoftwareBreakpointTrapOpcode (size_t trap_opcode_size_hint,
- size_t &actual_opcode_size,
- const uint8_t *&trap_opcode_bytes)
-{
- // FIXME put this behind a breakpoint protocol class that can be set per
- // architecture. Need MIPS support here.
- static const uint8_t g_aarch64_opcode[] = { 0x00, 0x00, 0x20, 0xd4 };
- // 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_i386_opcode [] = { 0xCC };
- static const uint8_t g_mips64_opcode[] = { 0x00, 0x00, 0x00, 0x0d };
- static const uint8_t g_mips64el_opcode[] = { 0x0d, 0x00, 0x00, 0x00 };
- static const uint8_t g_s390x_opcode[] = { 0x00, 0x01 };
- static const uint8_t g_thumb_breakpoint_opcode[] = { 0x01, 0xde };
-
- switch (m_arch.GetMachine ())
- {
- case llvm::Triple::aarch64:
- trap_opcode_bytes = g_aarch64_opcode;
- actual_opcode_size = sizeof(g_aarch64_opcode);
- return Error ();
-
- case llvm::Triple::arm:
- switch (trap_opcode_size_hint)
- {
- case 2:
- trap_opcode_bytes = g_thumb_breakpoint_opcode;
- actual_opcode_size = sizeof(g_thumb_breakpoint_opcode);
- return Error ();
- case 4:
- trap_opcode_bytes = g_arm_breakpoint_opcode;
- actual_opcode_size = sizeof(g_arm_breakpoint_opcode);
- return Error ();
- default:
- assert(false && "Unrecognised trap opcode size hint!");
- return Error ("Unrecognised trap opcode size hint!");
- }
+ case llvm::Triple::arm:
+ case llvm::Triple::aarch64:
+ case llvm::Triple::mips64:
+ case llvm::Triple::mips64el:
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
+ // On these architectures the PC don't get updated for breakpoint hits
+ actual_opcode_size = 0;
+ return Error();
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- trap_opcode_bytes = g_i386_opcode;
- actual_opcode_size = sizeof(g_i386_opcode);
- return Error ();
-
- case llvm::Triple::mips:
- case llvm::Triple::mips64:
- trap_opcode_bytes = g_mips64_opcode;
- actual_opcode_size = sizeof(g_mips64_opcode);
- return Error ();
-
- case llvm::Triple::mipsel:
- case llvm::Triple::mips64el:
- trap_opcode_bytes = g_mips64el_opcode;
- actual_opcode_size = sizeof(g_mips64el_opcode);
- return Error ();
-
- case llvm::Triple::systemz:
- trap_opcode_bytes = g_s390x_opcode;
- actual_opcode_size = sizeof(g_s390x_opcode);
- return Error ();
+ default:
+ assert(false && "CPU type not supported!");
+ return Error("CPU type not supported");
+ }
+}
+
+Error NativeProcessLinux::SetBreakpoint(lldb::addr_t addr, uint32_t size,
+ bool hardware) {
+ if (hardware)
+ return Error("NativeProcessLinux does not support hardware breakpoints");
+ else
+ return SetSoftwareBreakpoint(addr, size);
+}
+
+Error NativeProcessLinux::GetSoftwareBreakpointTrapOpcode(
+ size_t trap_opcode_size_hint, size_t &actual_opcode_size,
+ const uint8_t *&trap_opcode_bytes) {
+ // FIXME put this behind a breakpoint protocol class that can be set per
+ // architecture. Need MIPS support here.
+ static const uint8_t g_aarch64_opcode[] = {0x00, 0x00, 0x20, 0xd4};
+ // 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_i386_opcode[] = {0xCC};
+ static const uint8_t g_mips64_opcode[] = {0x00, 0x00, 0x00, 0x0d};
+ static const uint8_t g_mips64el_opcode[] = {0x0d, 0x00, 0x00, 0x00};
+ static const uint8_t g_s390x_opcode[] = {0x00, 0x01};
+ static const uint8_t g_thumb_breakpoint_opcode[] = {0x01, 0xde};
+
+ switch (m_arch.GetMachine()) {
+ case llvm::Triple::aarch64:
+ trap_opcode_bytes = g_aarch64_opcode;
+ actual_opcode_size = sizeof(g_aarch64_opcode);
+ return Error();
+ case llvm::Triple::arm:
+ switch (trap_opcode_size_hint) {
+ case 2:
+ trap_opcode_bytes = g_thumb_breakpoint_opcode;
+ actual_opcode_size = sizeof(g_thumb_breakpoint_opcode);
+ return Error();
+ case 4:
+ trap_opcode_bytes = g_arm_breakpoint_opcode;
+ actual_opcode_size = sizeof(g_arm_breakpoint_opcode);
+ return Error();
default:
- assert(false && "CPU type not supported!");
- return Error ("CPU type not supported");
+ assert(false && "Unrecognised trap opcode size hint!");
+ return Error("Unrecognised trap opcode size hint!");
}
+
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ trap_opcode_bytes = g_i386_opcode;
+ actual_opcode_size = sizeof(g_i386_opcode);
+ return Error();
+
+ case llvm::Triple::mips:
+ case llvm::Triple::mips64:
+ trap_opcode_bytes = g_mips64_opcode;
+ actual_opcode_size = sizeof(g_mips64_opcode);
+ return Error();
+
+ case llvm::Triple::mipsel:
+ case llvm::Triple::mips64el:
+ trap_opcode_bytes = g_mips64el_opcode;
+ actual_opcode_size = sizeof(g_mips64el_opcode);
+ return Error();
+
+ case llvm::Triple::systemz:
+ trap_opcode_bytes = g_s390x_opcode;
+ actual_opcode_size = sizeof(g_s390x_opcode);
+ return Error();
+
+ default:
+ assert(false && "CPU type not supported!");
+ return Error("CPU type not supported");
+ }
}
#if 0
@@ -2214,7 +2012,6 @@ NativeProcessLinux::GetCrashReasonForSIGSEGV(const siginfo_t *info)
}
#endif
-
#if 0
ProcessMessage::CrashReason
NativeProcessLinux::GetCrashReasonForSIGILL(const siginfo_t *info)
@@ -2332,654 +2129,628 @@ NativeProcessLinux::GetCrashReasonForSIGBUS(const siginfo_t *info)
}
#endif
-Error
-NativeProcessLinux::ReadMemory (lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read)
-{
- if (ProcessVmReadvSupported()) {
- // The process_vm_readv path is about 50 times faster than ptrace api. We want to use
- // this syscall if it is supported.
+Error NativeProcessLinux::ReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ size_t &bytes_read) {
+ if (ProcessVmReadvSupported()) {
+ // The process_vm_readv path is about 50 times faster than ptrace api. We
+ // want to use
+ // this syscall if it is supported.
- const ::pid_t pid = GetID();
+ const ::pid_t pid = GetID();
- struct iovec local_iov, remote_iov;
- local_iov.iov_base = buf;
- local_iov.iov_len = size;
- remote_iov.iov_base = reinterpret_cast<void *>(addr);
- remote_iov.iov_len = size;
+ struct iovec local_iov, remote_iov;
+ local_iov.iov_base = buf;
+ local_iov.iov_len = size;
+ remote_iov.iov_base = reinterpret_cast<void *>(addr);
+ remote_iov.iov_len = size;
- bytes_read = process_vm_readv(pid, &local_iov, 1, &remote_iov, 1, 0);
- const bool success = bytes_read == size;
+ bytes_read = process_vm_readv(pid, &local_iov, 1, &remote_iov, 1, 0);
+ const bool success = bytes_read == size;
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf ("NativeProcessLinux::%s using process_vm_readv to read %zd bytes from inferior address 0x%" PRIx64": %s",
- __FUNCTION__, size, addr, success ? "Success" : strerror(errno));
-
- if (success)
- return Error();
- // else
- // the call failed for some reason, let's retry the read using ptrace api.
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("NativeProcessLinux::%s using process_vm_readv to read %zd "
+ "bytes from inferior address 0x%" PRIx64 ": %s",
+ __FUNCTION__, size, addr,
+ success ? "Success" : strerror(errno));
+
+ if (success)
+ return Error();
+ // else
+ // the call failed for some reason, let's retry the read using ptrace
+ // api.
+ }
+
+ unsigned char *dst = static_cast<unsigned char *>(buf);
+ size_t remainder;
+ long data;
+
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_ALL));
+ if (log)
+ ProcessPOSIXLog::IncNestLevel();
+ if (log && ProcessPOSIXLog::AtTopNestLevel() &&
+ log->GetMask().Test(POSIX_LOG_MEMORY))
+ log->Printf("NativeProcessLinux::%s(%p, %p, %zd, _)", __FUNCTION__,
+ (void *)addr, buf, size);
+
+ for (bytes_read = 0; bytes_read < size; bytes_read += remainder) {
+ Error error = NativeProcessLinux::PtraceWrapper(
+ PTRACE_PEEKDATA, GetID(), (void *)addr, nullptr, 0, &data);
+ if (error.Fail()) {
+ if (log)
+ ProcessPOSIXLog::DecNestLevel();
+ return error;
}
- unsigned char *dst = static_cast<unsigned char*>(buf);
- size_t remainder;
- long data;
+ remainder = size - bytes_read;
+ remainder = remainder > k_ptrace_word_size ? k_ptrace_word_size : remainder;
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_ALL));
- if (log)
- ProcessPOSIXLog::IncNestLevel();
- if (log && ProcessPOSIXLog::AtTopNestLevel() && log->GetMask().Test(POSIX_LOG_MEMORY))
- log->Printf ("NativeProcessLinux::%s(%p, %p, %zd, _)", __FUNCTION__, (void*)addr, buf, size);
-
- for (bytes_read = 0; bytes_read < size; bytes_read += remainder)
- {
- Error error = NativeProcessLinux::PtraceWrapper(PTRACE_PEEKDATA, GetID(), (void*)addr, nullptr, 0, &data);
- if (error.Fail())
- {
- if (log)
- ProcessPOSIXLog::DecNestLevel();
- return error;
- }
+ // Copy the data into our buffer
+ memcpy(dst, &data, remainder);
- remainder = size - bytes_read;
- remainder = remainder > k_ptrace_word_size ? k_ptrace_word_size : remainder;
-
- // Copy the data into our buffer
- memcpy(dst, &data, remainder);
-
- if (log && ProcessPOSIXLog::AtTopNestLevel() &&
- (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) ||
- (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) &&
- size <= POSIX_LOG_MEMORY_SHORT_BYTES)))
- {
- uintptr_t print_dst = 0;
- // Format bytes from data by moving into print_dst for log output
- for (unsigned i = 0; i < remainder; ++i)
- print_dst |= (((data >> i*8) & 0xFF) << i*8);
- log->Printf ("NativeProcessLinux::%s() [0x%" PRIx64 "]:0x%" PRIx64 " (0x%" PRIx64 ")",
- __FUNCTION__, addr, uint64_t(print_dst), uint64_t(data));
- }
- addr += k_ptrace_word_size;
- dst += k_ptrace_word_size;
+ if (log && ProcessPOSIXLog::AtTopNestLevel() &&
+ (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) ||
+ (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) &&
+ size <= POSIX_LOG_MEMORY_SHORT_BYTES))) {
+ uintptr_t print_dst = 0;
+ // Format bytes from data by moving into print_dst for log output
+ for (unsigned i = 0; i < remainder; ++i)
+ print_dst |= (((data >> i * 8) & 0xFF) << i * 8);
+ log->Printf("NativeProcessLinux::%s() [0x%" PRIx64 "]:0x%" PRIx64
+ " (0x%" PRIx64 ")",
+ __FUNCTION__, addr, uint64_t(print_dst), uint64_t(data));
}
+ addr += k_ptrace_word_size;
+ dst += k_ptrace_word_size;
+ }
- if (log)
- ProcessPOSIXLog::DecNestLevel();
- return Error();
+ if (log)
+ ProcessPOSIXLog::DecNestLevel();
+ return Error();
}
-Error
-NativeProcessLinux::ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read)
-{
- Error error = ReadMemory(addr, buf, size, bytes_read);
- if (error.Fail()) return error;
- return m_breakpoint_list.RemoveTrapsFromBuffer(addr, buf, size);
-}
-
-Error
-NativeProcessLinux::WriteMemory(lldb::addr_t addr, const void *buf, size_t size, size_t &bytes_written)
-{
- const unsigned char *src = static_cast<const unsigned char*>(buf);
- size_t remainder;
- Error error;
+Error NativeProcessLinux::ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf,
+ size_t size,
+ size_t &bytes_read) {
+ Error error = ReadMemory(addr, buf, size, bytes_read);
+ if (error.Fail())
+ return error;
+ return m_breakpoint_list.RemoveTrapsFromBuffer(addr, buf, size);
+}
+
+Error NativeProcessLinux::WriteMemory(lldb::addr_t addr, const void *buf,
+ size_t size, size_t &bytes_written) {
+ const unsigned char *src = static_cast<const unsigned char *>(buf);
+ size_t remainder;
+ Error error;
+
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_ALL));
+ if (log)
+ ProcessPOSIXLog::IncNestLevel();
+ if (log && ProcessPOSIXLog::AtTopNestLevel() &&
+ log->GetMask().Test(POSIX_LOG_MEMORY))
+ log->Printf("NativeProcessLinux::%s(0x%" PRIx64 ", %p, %zu)", __FUNCTION__,
+ addr, buf, size);
+
+ for (bytes_written = 0; bytes_written < size; bytes_written += remainder) {
+ remainder = size - bytes_written;
+ remainder = remainder > k_ptrace_word_size ? k_ptrace_word_size : remainder;
+
+ if (remainder == k_ptrace_word_size) {
+ unsigned long data = 0;
+ memcpy(&data, src, k_ptrace_word_size);
+
+ if (log && ProcessPOSIXLog::AtTopNestLevel() &&
+ (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) ||
+ (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) &&
+ size <= POSIX_LOG_MEMORY_SHORT_BYTES)))
+ log->Printf("NativeProcessLinux::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__,
+ (void *)addr, *(const unsigned long *)src, data);
+
+ error = NativeProcessLinux::PtraceWrapper(PTRACE_POKEDATA, GetID(),
+ (void *)addr, (void *)data);
+ if (error.Fail()) {
+ if (log)
+ ProcessPOSIXLog::DecNestLevel();
+ return error;
+ }
+ } else {
+ unsigned char buff[8];
+ size_t bytes_read;
+ error = ReadMemory(addr, buff, k_ptrace_word_size, bytes_read);
+ if (error.Fail()) {
+ if (log)
+ ProcessPOSIXLog::DecNestLevel();
+ return error;
+ }
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_ALL));
- if (log)
- ProcessPOSIXLog::IncNestLevel();
- if (log && ProcessPOSIXLog::AtTopNestLevel() && log->GetMask().Test(POSIX_LOG_MEMORY))
- log->Printf ("NativeProcessLinux::%s(0x%" PRIx64 ", %p, %zu)", __FUNCTION__, addr, buf, size);
+ memcpy(buff, src, remainder);
- for (bytes_written = 0; bytes_written < size; bytes_written += remainder)
- {
- remainder = size - bytes_written;
- remainder = remainder > k_ptrace_word_size ? k_ptrace_word_size : remainder;
-
- if (remainder == k_ptrace_word_size)
- {
- unsigned long data = 0;
- memcpy(&data, src, k_ptrace_word_size);
-
- if (log && ProcessPOSIXLog::AtTopNestLevel() &&
- (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) ||
- (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) &&
- size <= POSIX_LOG_MEMORY_SHORT_BYTES)))
- log->Printf ("NativeProcessLinux::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__,
- (void*)addr, *(const unsigned long*)src, data);
-
- error = NativeProcessLinux::PtraceWrapper(PTRACE_POKEDATA, GetID(), (void*)addr, (void*)data);
- if (error.Fail())
- {
- if (log)
- ProcessPOSIXLog::DecNestLevel();
- return error;
- }
- }
- else
- {
- unsigned char buff[8];
- size_t bytes_read;
- error = ReadMemory(addr, buff, k_ptrace_word_size, bytes_read);
- if (error.Fail())
- {
- if (log)
- ProcessPOSIXLog::DecNestLevel();
- return error;
- }
-
- memcpy(buff, src, remainder);
-
- size_t bytes_written_rec;
- error = WriteMemory(addr, buff, k_ptrace_word_size, bytes_written_rec);
- if (error.Fail())
- {
- if (log)
- ProcessPOSIXLog::DecNestLevel();
- return error;
- }
-
- if (log && ProcessPOSIXLog::AtTopNestLevel() &&
- (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) ||
- (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) &&
- size <= POSIX_LOG_MEMORY_SHORT_BYTES)))
- log->Printf ("NativeProcessLinux::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__,
- (void*)addr, *(const unsigned long*)src, *(unsigned long*)buff);
- }
+ size_t bytes_written_rec;
+ error = WriteMemory(addr, buff, k_ptrace_word_size, bytes_written_rec);
+ if (error.Fail()) {
+ if (log)
+ ProcessPOSIXLog::DecNestLevel();
+ return error;
+ }
- addr += k_ptrace_word_size;
- src += k_ptrace_word_size;
+ if (log && ProcessPOSIXLog::AtTopNestLevel() &&
+ (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) ||
+ (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) &&
+ size <= POSIX_LOG_MEMORY_SHORT_BYTES)))
+ log->Printf("NativeProcessLinux::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__,
+ (void *)addr, *(const unsigned long *)src,
+ *(unsigned long *)buff);
}
- if (log)
- ProcessPOSIXLog::DecNestLevel();
- return error;
-}
-Error
-NativeProcessLinux::GetSignalInfo(lldb::tid_t tid, void *siginfo)
-{
- return PtraceWrapper(PTRACE_GETSIGINFO, tid, nullptr, siginfo);
+ addr += k_ptrace_word_size;
+ src += k_ptrace_word_size;
+ }
+ if (log)
+ ProcessPOSIXLog::DecNestLevel();
+ return error;
}
-Error
-NativeProcessLinux::GetEventMessage(lldb::tid_t tid, unsigned long *message)
-{
- return PtraceWrapper(PTRACE_GETEVENTMSG, tid, nullptr, message);
+Error NativeProcessLinux::GetSignalInfo(lldb::tid_t tid, void *siginfo) {
+ return PtraceWrapper(PTRACE_GETSIGINFO, tid, nullptr, siginfo);
}
-Error
-NativeProcessLinux::Detach(lldb::tid_t tid)
-{
- if (tid == LLDB_INVALID_THREAD_ID)
- return Error();
-
- return PtraceWrapper(PTRACE_DETACH, tid);
+Error NativeProcessLinux::GetEventMessage(lldb::tid_t tid,
+ unsigned long *message) {
+ return PtraceWrapper(PTRACE_GETEVENTMSG, tid, nullptr, message);
}
-bool
-NativeProcessLinux::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 (dup2(target_fd, fd) == -1)
- return false;
+Error NativeProcessLinux::Detach(lldb::tid_t tid) {
+ if (tid == LLDB_INVALID_THREAD_ID)
+ return Error();
- return (close(target_fd) == -1) ? false : true;
+ return PtraceWrapper(PTRACE_DETACH, tid);
}
-bool
-NativeProcessLinux::HasThreadNoLock (lldb::tid_t thread_id)
-{
- for (auto thread_sp : m_threads)
- {
- assert (thread_sp && "thread list should not contain NULL threads");
- if (thread_sp->GetID () == thread_id)
- {
- // We have this thread.
- return true;
- }
+bool NativeProcessLinux::HasThreadNoLock(lldb::tid_t thread_id) {
+ for (auto thread_sp : m_threads) {
+ assert(thread_sp && "thread list should not contain NULL threads");
+ if (thread_sp->GetID() == thread_id) {
+ // We have this thread.
+ return true;
}
+ }
- // We don't have this thread.
- return false;
+ // We don't have this thread.
+ return false;
}
-bool
-NativeProcessLinux::StopTrackingThread (lldb::tid_t thread_id)
-{
- Log *const log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD);
+bool NativeProcessLinux::StopTrackingThread(lldb::tid_t thread_id) {
+ Log *const log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD);
- if (log)
- log->Printf("NativeProcessLinux::%s (tid: %" PRIu64 ")", __FUNCTION__, thread_id);
+ if (log)
+ log->Printf("NativeProcessLinux::%s (tid: %" PRIu64 ")", __FUNCTION__,
+ thread_id);
- bool found = false;
+ bool found = false;
- for (auto it = m_threads.begin (); it != m_threads.end (); ++it)
- {
- if (*it && ((*it)->GetID () == thread_id))
- {
- m_threads.erase (it);
- found = true;
- break;
- }
+ for (auto it = m_threads.begin(); it != m_threads.end(); ++it) {
+ if (*it && ((*it)->GetID() == thread_id)) {
+ m_threads.erase(it);
+ found = true;
+ break;
}
+ }
- SignalIfAllThreadsStopped();
+ SignalIfAllThreadsStopped();
- return found;
+ return found;
}
-NativeThreadLinuxSP
-NativeProcessLinux::AddThread (lldb::tid_t thread_id)
-{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
+NativeThreadLinuxSP NativeProcessLinux::AddThread(lldb::tid_t thread_id) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
- if (log)
- {
- log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " adding thread with tid %" PRIu64,
- __FUNCTION__,
- GetID (),
- thread_id);
- }
+ if (log) {
+ log->Printf("NativeProcessLinux::%s pid %" PRIu64
+ " adding thread with tid %" PRIu64,
+ __FUNCTION__, GetID(), thread_id);
+ }
- assert (!HasThreadNoLock (thread_id) && "attempted to add a thread by id that already exists");
+ assert(!HasThreadNoLock(thread_id) &&
+ "attempted to add a thread by id that already exists");
- // If this is the first thread, save it as the current thread
- if (m_threads.empty ())
- SetCurrentThreadID (thread_id);
+ // If this is the first thread, save it as the current thread
+ if (m_threads.empty())
+ SetCurrentThreadID(thread_id);
- auto thread_sp = std::make_shared<NativeThreadLinux>(this, thread_id);
- m_threads.push_back (thread_sp);
- return thread_sp;
+ auto thread_sp = std::make_shared<NativeThreadLinux>(this, thread_id);
+ m_threads.push_back(thread_sp);
+ return thread_sp;
}
-Error
-NativeProcessLinux::FixupBreakpointPCAsNeeded(NativeThreadLinux &thread)
-{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
+Error NativeProcessLinux::FixupBreakpointPCAsNeeded(NativeThreadLinux &thread) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- Error error;
+ Error error;
- // Find out the size of a breakpoint (might depend on where we are in the code).
- NativeRegisterContextSP context_sp = thread.GetRegisterContext();
- if (!context_sp)
- {
- error.SetErrorString ("cannot get a NativeRegisterContext for the thread");
- if (log)
- log->Printf ("NativeProcessLinux::%s failed: %s", __FUNCTION__, error.AsCString ());
- return error;
- }
-
- uint32_t breakpoint_size = 0;
- error = GetSoftwareBreakpointPCOffset(breakpoint_size);
- if (error.Fail ())
- {
- if (log)
- log->Printf ("NativeProcessLinux::%s GetBreakpointSize() failed: %s", __FUNCTION__, error.AsCString ());
- return error;
- }
- else
- {
- if (log)
- log->Printf ("NativeProcessLinux::%s breakpoint size: %" PRIu32, __FUNCTION__, breakpoint_size);
- }
-
- // First try probing for a breakpoint at a software breakpoint location: PC - breakpoint size.
- const lldb::addr_t initial_pc_addr = context_sp->GetPCfromBreakpointLocation ();
- lldb::addr_t breakpoint_addr = initial_pc_addr;
- if (breakpoint_size > 0)
- {
- // Do not allow breakpoint probe to wrap around.
- if (breakpoint_addr >= breakpoint_size)
- breakpoint_addr -= breakpoint_size;
- }
-
- // Check if we stopped because of a breakpoint.
- NativeBreakpointSP breakpoint_sp;
- error = m_breakpoint_list.GetBreakpoint (breakpoint_addr, breakpoint_sp);
- if (!error.Success () || !breakpoint_sp)
- {
- // We didn't find one at a software probe location. Nothing to do.
- if (log)
- log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " no lldb breakpoint found at current pc with adjustment: 0x%" PRIx64, __FUNCTION__, GetID (), breakpoint_addr);
- return Error ();
- }
-
- // If the breakpoint is not a software breakpoint, nothing to do.
- if (!breakpoint_sp->IsSoftwareBreakpoint ())
- {
- if (log)
- log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " breakpoint found at 0x%" PRIx64 ", not software, nothing to adjust", __FUNCTION__, GetID (), breakpoint_addr);
- return Error ();
- }
-
- //
- // We have a software breakpoint and need to adjust the PC.
- //
-
- // Sanity check.
- if (breakpoint_size == 0)
- {
- // Nothing to do! How did we get here?
- if (log)
- log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " breakpoint found at 0x%" PRIx64 ", it is software, but the size is zero, nothing to do (unexpected)", __FUNCTION__, GetID (), breakpoint_addr);
- return Error ();
- }
-
- // Change the program counter.
+ // Find out the size of a breakpoint (might depend on where we are in the
+ // code).
+ NativeRegisterContextSP context_sp = thread.GetRegisterContext();
+ if (!context_sp) {
+ error.SetErrorString("cannot get a NativeRegisterContext for the thread");
if (log)
- log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " tid %" PRIu64 ": changing PC from 0x%" PRIx64 " to 0x%" PRIx64, __FUNCTION__, GetID(), thread.GetID(), initial_pc_addr, breakpoint_addr);
-
- error = context_sp->SetPC (breakpoint_addr);
- if (error.Fail ())
- {
- if (log)
- log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " tid %" PRIu64 ": failed to set PC: %s", __FUNCTION__, GetID(), thread.GetID(), error.AsCString ());
- return error;
- }
-
+ log->Printf("NativeProcessLinux::%s failed: %s", __FUNCTION__,
+ error.AsCString());
return error;
-}
-
-Error
-NativeProcessLinux::GetLoadedModuleFileSpec(const char* module_path, FileSpec& file_spec)
-{
- FileSpec module_file_spec(module_path, true);
-
- bool found = false;
- file_spec.Clear();
- ProcFileReader::ProcessLineByLine(GetID(), "maps",
- [&] (const std::string &line)
- {
- SmallVector<StringRef, 16> columns;
- StringRef(line).split(columns, " ", -1, false);
- if (columns.size() < 6)
- return true; // continue searching
-
- FileSpec this_file_spec(columns[5].str().c_str(), false);
- if (this_file_spec.GetFilename() != module_file_spec.GetFilename())
- return true; // continue searching
-
- file_spec = this_file_spec;
- found = true;
- return false; // we are done
- });
+ }
- if (! found)
- return Error("Module file (%s) not found in /proc/%" PRIu64 "/maps file!",
- module_file_spec.GetFilename().AsCString(), GetID());
+ uint32_t breakpoint_size = 0;
+ error = GetSoftwareBreakpointPCOffset(breakpoint_size);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("NativeProcessLinux::%s GetBreakpointSize() failed: %s",
+ __FUNCTION__, error.AsCString());
+ return error;
+ } else {
+ if (log)
+ log->Printf("NativeProcessLinux::%s breakpoint size: %" PRIu32,
+ __FUNCTION__, breakpoint_size);
+ }
+
+ // First try probing for a breakpoint at a software breakpoint location: PC -
+ // breakpoint size.
+ const lldb::addr_t initial_pc_addr =
+ context_sp->GetPCfromBreakpointLocation();
+ lldb::addr_t breakpoint_addr = initial_pc_addr;
+ if (breakpoint_size > 0) {
+ // Do not allow breakpoint probe to wrap around.
+ if (breakpoint_addr >= breakpoint_size)
+ breakpoint_addr -= breakpoint_size;
+ }
+
+ // Check if we stopped because of a breakpoint.
+ NativeBreakpointSP breakpoint_sp;
+ error = m_breakpoint_list.GetBreakpoint(breakpoint_addr, breakpoint_sp);
+ if (!error.Success() || !breakpoint_sp) {
+ // We didn't find one at a software probe location. Nothing to do.
+ if (log)
+ log->Printf(
+ "NativeProcessLinux::%s pid %" PRIu64
+ " no lldb breakpoint found at current pc with adjustment: 0x%" PRIx64,
+ __FUNCTION__, GetID(), breakpoint_addr);
+ return Error();
+ }
+ // If the breakpoint is not a software breakpoint, nothing to do.
+ if (!breakpoint_sp->IsSoftwareBreakpoint()) {
+ if (log)
+ log->Printf("NativeProcessLinux::%s pid %" PRIu64
+ " breakpoint found at 0x%" PRIx64
+ ", not software, nothing to adjust",
+ __FUNCTION__, GetID(), breakpoint_addr);
return Error();
-}
+ }
-Error
-NativeProcessLinux::GetFileLoadAddress(const llvm::StringRef& file_name, lldb::addr_t& load_addr)
-{
- load_addr = LLDB_INVALID_ADDRESS;
- Error error = ProcFileReader::ProcessLineByLine (GetID (), "maps",
- [&] (const std::string &line) -> bool
- {
- StringRef maps_row(line);
-
- SmallVector<StringRef, 16> maps_columns;
- maps_row.split(maps_columns, StringRef(" "), -1, false);
-
- if (maps_columns.size() < 6)
- {
- // Return true to continue reading the proc file
- return true;
- }
-
- if (maps_columns[5] == file_name)
- {
- StringExtractor addr_extractor(maps_columns[0].str().c_str());
- load_addr = addr_extractor.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
-
- // Return false to stop reading the proc file further
- return false;
- }
-
- // Return true to continue reading the proc file
- return true;
- });
- return error;
-}
+ //
+ // We have a software breakpoint and need to adjust the PC.
+ //
-NativeThreadLinuxSP
-NativeProcessLinux::GetThreadByID(lldb::tid_t tid)
-{
- return std::static_pointer_cast<NativeThreadLinux>(NativeProcessProtocol::GetThreadByID(tid));
-}
+ // Sanity check.
+ if (breakpoint_size == 0) {
+ // Nothing to do! How did we get here?
+ if (log)
+ log->Printf(
+ "NativeProcessLinux::%s pid %" PRIu64
+ " breakpoint found at 0x%" PRIx64
+ ", it is software, but the size is zero, nothing to do (unexpected)",
+ __FUNCTION__, GetID(), breakpoint_addr);
+ return Error();
+ }
-Error
-NativeProcessLinux::ResumeThread(NativeThreadLinux &thread, lldb::StateType state, int signo)
-{
- Log *const log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD);
+ // Change the program counter.
+ if (log)
+ log->Printf("NativeProcessLinux::%s pid %" PRIu64 " tid %" PRIu64
+ ": changing PC from 0x%" PRIx64 " to 0x%" PRIx64,
+ __FUNCTION__, GetID(), thread.GetID(), initial_pc_addr,
+ breakpoint_addr);
+ error = context_sp->SetPC(breakpoint_addr);
+ if (error.Fail()) {
if (log)
- log->Printf("NativeProcessLinux::%s (tid: %" PRIu64 ")",
- __FUNCTION__, thread.GetID());
-
- // Before we do the resume below, first check if we have a pending
- // stop notification that is currently waiting for
- // all threads to stop. This is potentially a buggy situation since
- // we're ostensibly waiting for threads to stop before we send out the
- // pending notification, and here we are resuming one before we send
- // out the pending stop notification.
- if (m_pending_notification_tid != LLDB_INVALID_THREAD_ID && log)
- {
- log->Printf("NativeProcessLinux::%s about to resume tid %" PRIu64 " per explicit request but we have a pending stop notification (tid %" PRIu64 ") that is actively waiting for this thread to stop. Valid sequence of events?", __FUNCTION__, thread.GetID(), m_pending_notification_tid);
- }
+ log->Printf("NativeProcessLinux::%s pid %" PRIu64 " tid %" PRIu64
+ ": failed to set PC: %s",
+ __FUNCTION__, GetID(), thread.GetID(), error.AsCString());
+ return error;
+ }
- // Request a resume. We expect this to be synchronous and the system
- // to reflect it is running after this completes.
- switch (state)
- {
- case eStateRunning:
- {
- const auto resume_result = thread.Resume(signo);
- if (resume_result.Success())
- SetState(eStateRunning, true);
- return resume_result;
- }
- case eStateStepping:
- {
- const auto step_result = thread.SingleStep(signo);
- if (step_result.Success())
- SetState(eStateRunning, true);
- return step_result;
- }
- default:
- if (log)
- log->Printf("NativeProcessLinux::%s Unhandled state %s.",
- __FUNCTION__, StateAsCString(state));
- llvm_unreachable("Unhandled state for resume");
- }
+ return error;
}
-//===----------------------------------------------------------------------===//
+Error NativeProcessLinux::GetLoadedModuleFileSpec(const char *module_path,
+ FileSpec &file_spec) {
+ FileSpec module_file_spec(module_path, true);
-void
-NativeProcessLinux::StopRunningThreads(const lldb::tid_t triggering_tid)
-{
- Log *const log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD);
+ bool found = false;
+ file_spec.Clear();
+ ProcFileReader::ProcessLineByLine(
+ GetID(), "maps", [&](const std::string &line) {
+ SmallVector<StringRef, 16> columns;
+ StringRef(line).split(columns, " ", -1, false);
+ if (columns.size() < 6)
+ return true; // continue searching
- if (log)
- {
- log->Printf("NativeProcessLinux::%s about to process event: (triggering_tid: %" PRIu64 ")",
- __FUNCTION__, triggering_tid);
- }
+ FileSpec this_file_spec(columns[5].str(), false);
+ if (this_file_spec.GetFilename() != module_file_spec.GetFilename())
+ return true; // continue searching
- m_pending_notification_tid = triggering_tid;
+ file_spec = this_file_spec;
+ found = true;
+ return false; // we are done
+ });
- // Request a stop for all the thread stops that need to be stopped
- // and are not already known to be stopped.
- for (const auto &thread_sp: m_threads)
- {
- if (StateIsRunningState(thread_sp->GetState()))
- static_pointer_cast<NativeThreadLinux>(thread_sp)->RequestStop();
- }
-
- SignalIfAllThreadsStopped();
+ if (!found)
+ return Error("Module file (%s) not found in /proc/%" PRIu64 "/maps file!",
+ module_file_spec.GetFilename().AsCString(), GetID());
- if (log)
- {
- log->Printf("NativeProcessLinux::%s event processing done", __FUNCTION__);
- }
+ return Error();
}
-void
-NativeProcessLinux::SignalIfAllThreadsStopped()
-{
- if (m_pending_notification_tid == LLDB_INVALID_THREAD_ID)
- return; // No pending notification. Nothing to do.
-
- for (const auto &thread_sp: m_threads)
- {
- if (StateIsRunningState(thread_sp->GetState()))
- return; // Some threads are still running. Don't signal yet.
- }
+Error NativeProcessLinux::GetFileLoadAddress(const llvm::StringRef &file_name,
+ lldb::addr_t &load_addr) {
+ load_addr = LLDB_INVALID_ADDRESS;
+ Error error = ProcFileReader::ProcessLineByLine(
+ GetID(), "maps", [&](const std::string &line) -> bool {
+ StringRef maps_row(line);
- // We have a pending notification and all threads have stopped.
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_BREAKPOINTS));
+ SmallVector<StringRef, 16> maps_columns;
+ maps_row.split(maps_columns, StringRef(" "), -1, false);
- // Clear any temporary breakpoints we used to implement software single stepping.
- for (const auto &thread_info: m_threads_stepping_with_breakpoint)
- {
- Error error = RemoveBreakpoint (thread_info.second);
- if (error.Fail())
- if (log)
- log->Printf("NativeProcessLinux::%s() pid = %" PRIu64 " remove stepping breakpoint: %s",
- __FUNCTION__, thread_info.first, error.AsCString());
- }
- m_threads_stepping_with_breakpoint.clear();
+ if (maps_columns.size() < 6) {
+ // Return true to continue reading the proc file
+ return true;
+ }
- // Notify the delegate about the stop
- SetCurrentThreadID(m_pending_notification_tid);
- SetState(StateType::eStateStopped, true);
- m_pending_notification_tid = LLDB_INVALID_THREAD_ID;
-}
+ if (maps_columns[5] == file_name) {
+ StringExtractor addr_extractor(maps_columns[0].str().c_str());
+ load_addr = addr_extractor.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
-void
-NativeProcessLinux::ThreadWasCreated(NativeThreadLinux &thread)
-{
- Log *const log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD);
+ // Return false to stop reading the proc file further
+ return false;
+ }
+ // Return true to continue reading the proc file
+ return true;
+ });
+ return error;
+}
+
+NativeThreadLinuxSP NativeProcessLinux::GetThreadByID(lldb::tid_t tid) {
+ return std::static_pointer_cast<NativeThreadLinux>(
+ NativeProcessProtocol::GetThreadByID(tid));
+}
+
+Error NativeProcessLinux::ResumeThread(NativeThreadLinux &thread,
+ lldb::StateType state, int signo) {
+ Log *const log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD);
+
+ if (log)
+ log->Printf("NativeProcessLinux::%s (tid: %" PRIu64 ")", __FUNCTION__,
+ thread.GetID());
+
+ // Before we do the resume below, first check if we have a pending
+ // stop notification that is currently waiting for
+ // all threads to stop. This is potentially a buggy situation since
+ // we're ostensibly waiting for threads to stop before we send out the
+ // pending notification, and here we are resuming one before we send
+ // out the pending stop notification.
+ if (m_pending_notification_tid != LLDB_INVALID_THREAD_ID && log) {
+ log->Printf("NativeProcessLinux::%s about to resume tid %" PRIu64
+ " per explicit request but we have a pending stop notification "
+ "(tid %" PRIu64 ") that is actively waiting for this thread to "
+ "stop. Valid sequence of events?",
+ __FUNCTION__, thread.GetID(), m_pending_notification_tid);
+ }
+
+ // Request a resume. We expect this to be synchronous and the system
+ // to reflect it is running after this completes.
+ switch (state) {
+ case eStateRunning: {
+ const auto resume_result = thread.Resume(signo);
+ if (resume_result.Success())
+ SetState(eStateRunning, true);
+ return resume_result;
+ }
+ case eStateStepping: {
+ const auto step_result = thread.SingleStep(signo);
+ if (step_result.Success())
+ SetState(eStateRunning, true);
+ return step_result;
+ }
+ default:
if (log)
- log->Printf("NativeProcessLinux::%s (tid: %" PRIu64 ")", __FUNCTION__, thread.GetID());
-
- if (m_pending_notification_tid != LLDB_INVALID_THREAD_ID && StateIsRunningState(thread.GetState()))
- {
- // We will need to wait for this new thread to stop as well before firing the
- // notification.
- thread.RequestStop();
- }
+ log->Printf("NativeProcessLinux::%s Unhandled state %s.", __FUNCTION__,
+ StateAsCString(state));
+ llvm_unreachable("Unhandled state for resume");
+ }
}
-void
-NativeProcessLinux::SigchldHandler()
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- // Process all pending waitpid notifications.
- while (true)
- {
- int status = -1;
- ::pid_t wait_pid = waitpid(-1, &status, __WALL | __WNOTHREAD | WNOHANG);
+//===----------------------------------------------------------------------===//
- if (wait_pid == 0)
- break; // We are done.
+void NativeProcessLinux::StopRunningThreads(const lldb::tid_t triggering_tid) {
+ Log *const log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD);
- if (wait_pid == -1)
- {
- if (errno == EINTR)
- continue;
+ if (log) {
+ log->Printf("NativeProcessLinux::%s about to process event: "
+ "(triggering_tid: %" PRIu64 ")",
+ __FUNCTION__, triggering_tid);
+ }
- Error error(errno, eErrorTypePOSIX);
- if (log)
- log->Printf("NativeProcessLinux::%s waitpid (-1, &status, __WALL | __WNOTHREAD | WNOHANG) failed: %s",
- __FUNCTION__, error.AsCString());
- break;
- }
+ m_pending_notification_tid = triggering_tid;
- bool exited = false;
- int signal = 0;
- int exit_status = 0;
- const char *status_cstr = nullptr;
- if (WIFSTOPPED(status))
- {
- signal = WSTOPSIG(status);
- status_cstr = "STOPPED";
- }
- else if (WIFEXITED(status))
- {
- exit_status = WEXITSTATUS(status);
- status_cstr = "EXITED";
- exited = true;
- }
- else if (WIFSIGNALED(status))
- {
- signal = WTERMSIG(status);
- status_cstr = "SIGNALED";
- if (wait_pid == static_cast< ::pid_t>(GetID())) {
- exited = true;
- exit_status = -1;
- }
- }
- else
- status_cstr = "(\?\?\?)";
+ // Request a stop for all the thread stops that need to be stopped
+ // and are not already known to be stopped.
+ for (const auto &thread_sp : m_threads) {
+ if (StateIsRunningState(thread_sp->GetState()))
+ static_pointer_cast<NativeThreadLinux>(thread_sp)->RequestStop();
+ }
- if (log)
- log->Printf("NativeProcessLinux::%s: waitpid (-1, &status, __WALL | __WNOTHREAD | WNOHANG)"
- "=> pid = %" PRIi32 ", status = 0x%8.8x (%s), signal = %i, exit_state = %i",
- __FUNCTION__, wait_pid, status, status_cstr, signal, exit_status);
+ SignalIfAllThreadsStopped();
- MonitorCallback (wait_pid, exited, signal, exit_status);
- }
+ if (log) {
+ log->Printf("NativeProcessLinux::%s event processing done", __FUNCTION__);
+ }
}
-// Wrapper for ptrace to catch errors and log calls.
-// Note that ptrace sets errno on error because -1 can be a valid result (i.e. for PTRACE_PEEK*)
-Error
-NativeProcessLinux::PtraceWrapper(int req, lldb::pid_t pid, void *addr, void *data, size_t data_size, long *result)
-{
- Error error;
- long int ret;
-
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PTRACE));
-
- PtraceDisplayBytes(req, data, data_size);
+void NativeProcessLinux::SignalIfAllThreadsStopped() {
+ if (m_pending_notification_tid == LLDB_INVALID_THREAD_ID)
+ return; // No pending notification. Nothing to do.
- errno = 0;
- if (req == PTRACE_GETREGSET || req == PTRACE_SETREGSET)
- ret = ptrace(static_cast<__ptrace_request>(req), static_cast< ::pid_t>(pid), *(unsigned int *)addr, data);
- else
- ret = ptrace(static_cast<__ptrace_request>(req), static_cast< ::pid_t>(pid), addr, data);
+ for (const auto &thread_sp : m_threads) {
+ if (StateIsRunningState(thread_sp->GetState()))
+ return; // Some threads are still running. Don't signal yet.
+ }
- if (ret == -1)
- error.SetErrorToErrno();
+ // We have a pending notification and all threads have stopped.
+ Log *log(
+ GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_BREAKPOINTS));
- if (result)
- *result = ret;
+ // Clear any temporary breakpoints we used to implement software single
+ // stepping.
+ for (const auto &thread_info : m_threads_stepping_with_breakpoint) {
+ Error error = RemoveBreakpoint(thread_info.second);
+ if (error.Fail())
+ if (log)
+ log->Printf("NativeProcessLinux::%s() pid = %" PRIu64
+ " remove stepping breakpoint: %s",
+ __FUNCTION__, thread_info.first, error.AsCString());
+ }
+ m_threads_stepping_with_breakpoint.clear();
+
+ // Notify the delegate about the stop
+ SetCurrentThreadID(m_pending_notification_tid);
+ SetState(StateType::eStateStopped, true);
+ m_pending_notification_tid = LLDB_INVALID_THREAD_ID;
+}
+
+void NativeProcessLinux::ThreadWasCreated(NativeThreadLinux &thread) {
+ Log *const log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD);
+
+ if (log)
+ log->Printf("NativeProcessLinux::%s (tid: %" PRIu64 ")", __FUNCTION__,
+ thread.GetID());
+
+ if (m_pending_notification_tid != LLDB_INVALID_THREAD_ID &&
+ StateIsRunningState(thread.GetState())) {
+ // We will need to wait for this new thread to stop as well before firing
+ // the
+ // notification.
+ thread.RequestStop();
+ }
+}
+
+void NativeProcessLinux::SigchldHandler() {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ // Process all pending waitpid notifications.
+ while (true) {
+ int status = -1;
+ ::pid_t wait_pid = waitpid(-1, &status, __WALL | __WNOTHREAD | WNOHANG);
+
+ if (wait_pid == 0)
+ break; // We are done.
+
+ if (wait_pid == -1) {
+ if (errno == EINTR)
+ continue;
+
+ Error error(errno, eErrorTypePOSIX);
+ if (log)
+ log->Printf("NativeProcessLinux::%s waitpid (-1, &status, __WALL | "
+ "__WNOTHREAD | WNOHANG) failed: %s",
+ __FUNCTION__, error.AsCString());
+ break;
+ }
+
+ bool exited = false;
+ int signal = 0;
+ int exit_status = 0;
+ const char *status_cstr = nullptr;
+ if (WIFSTOPPED(status)) {
+ signal = WSTOPSIG(status);
+ status_cstr = "STOPPED";
+ } else if (WIFEXITED(status)) {
+ exit_status = WEXITSTATUS(status);
+ status_cstr = "EXITED";
+ exited = true;
+ } else if (WIFSIGNALED(status)) {
+ signal = WTERMSIG(status);
+ status_cstr = "SIGNALED";
+ if (wait_pid == static_cast<::pid_t>(GetID())) {
+ exited = true;
+ exit_status = -1;
+ }
+ } else
+ status_cstr = "(\?\?\?)";
if (log)
- log->Printf("ptrace(%d, %" PRIu64 ", %p, %p, %zu)=%lX", req, pid, addr, data, data_size, ret);
+ log->Printf("NativeProcessLinux::%s: waitpid (-1, &status, __WALL | "
+ "__WNOTHREAD | WNOHANG)"
+ "=> pid = %" PRIi32
+ ", status = 0x%8.8x (%s), signal = %i, exit_state = %i",
+ __FUNCTION__, wait_pid, status, status_cstr, signal,
+ exit_status);
- PtraceDisplayBytes(req, data, data_size);
+ MonitorCallback(wait_pid, exited, signal, exit_status);
+ }
+}
- if (log && error.GetError() != 0)
- {
- const char* str;
- switch (error.GetError())
- {
- case ESRCH: str = "ESRCH"; break;
- case EINVAL: str = "EINVAL"; break;
- case EBUSY: str = "EBUSY"; break;
- case EPERM: str = "EPERM"; break;
- default: str = error.AsCString();
- }
- log->Printf("ptrace() failed; errno=%d (%s)", error.GetError(), str);
+// Wrapper for ptrace to catch errors and log calls.
+// Note that ptrace sets errno on error because -1 can be a valid result (i.e.
+// for PTRACE_PEEK*)
+Error NativeProcessLinux::PtraceWrapper(int req, lldb::pid_t pid, void *addr,
+ void *data, size_t data_size,
+ long *result) {
+ Error error;
+ long int ret;
+
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
+
+ PtraceDisplayBytes(req, data, data_size);
+
+ errno = 0;
+ if (req == PTRACE_GETREGSET || req == PTRACE_SETREGSET)
+ ret = ptrace(static_cast<__ptrace_request>(req), static_cast<::pid_t>(pid),
+ *(unsigned int *)addr, data);
+ else
+ ret = ptrace(static_cast<__ptrace_request>(req), static_cast<::pid_t>(pid),
+ addr, data);
+
+ if (ret == -1)
+ error.SetErrorToErrno();
+
+ if (result)
+ *result = ret;
+
+ if (log)
+ log->Printf("ptrace(%d, %" PRIu64 ", %p, %p, %zu)=%lX", req, pid, addr,
+ data, data_size, ret);
+
+ PtraceDisplayBytes(req, data, data_size);
+
+ if (log && error.GetError() != 0) {
+ const char *str;
+ switch (error.GetError()) {
+ case ESRCH:
+ str = "ESRCH";
+ break;
+ case EINVAL:
+ str = "EINVAL";
+ break;
+ case EBUSY:
+ str = "EBUSY";
+ break;
+ case EPERM:
+ str = "EPERM";
+ break;
+ default:
+ str = error.AsCString();
}
+ log->Printf("ptrace() failed; errno=%d (%s)", error.GetError(), str);
+ }
- return error;
+ return error;
}
diff --git a/source/Plugins/Process/Linux/NativeProcessLinux.h b/source/Plugins/Process/Linux/NativeProcessLinux.h
index d5be06f0cb58..fcb13c8b016b 100644
--- a/source/Plugins/Process/Linux/NativeProcessLinux.h
+++ b/source/Plugins/Process/Linux/NativeProcessLinux.h
@@ -15,192 +15,151 @@
// Other libraries and framework includes
#include "lldb/Core/ArchSpec.h"
-#include "lldb/lldb-types.h"
#include "lldb/Host/Debug.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/HostThread.h"
#include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/lldb-types.h"
-#include "lldb/Host/common/NativeProcessProtocol.h"
#include "NativeThreadLinux.h"
+#include "lldb/Host/common/NativeProcessProtocol.h"
namespace lldb_private {
- class Error;
- class Scalar;
+class Error;
+class Scalar;
namespace process_linux {
- /// @class NativeProcessLinux
- /// @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 NativeProcessLinux: 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);
+/// @class NativeProcessLinux
+/// @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 NativeProcessLinux : public NativeProcessProtocol {
+ friend Error NativeProcessProtocol::Launch(
+ ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate,
+ MainLoop &mainloop, NativeProcessProtocolSP &process_sp);
- public:
- // ---------------------------------------------------------------------
- // NativeProcessProtocol Interface
- // ---------------------------------------------------------------------
- Error
- Resume (const ResumeActionList &resume_actions) override;
+ friend Error NativeProcessProtocol::Attach(
+ lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
+ MainLoop &mainloop, NativeProcessProtocolSP &process_sp);
- Error
- Halt () override;
+public:
+ // ---------------------------------------------------------------------
+ // NativeProcessProtocol Interface
+ // ---------------------------------------------------------------------
+ Error Resume(const ResumeActionList &resume_actions) override;
- Error
- Detach () override;
+ Error Halt() override;
- Error
- Signal (int signo) override;
+ Error Detach() override;
- Error
- Interrupt () override;
+ Error Signal(int signo) override;
- Error
- Kill () override;
+ Error Interrupt() override;
- Error
- GetMemoryRegionInfo (lldb::addr_t load_addr, MemoryRegionInfo &range_info) override;
+ Error Kill() override;
- Error
- ReadMemory(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read) override;
+ Error GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &range_info) override;
- Error
- ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read) override;
+ Error ReadMemory(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 ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size,
+ size_t &bytes_read) override;
- Error
- AllocateMemory(size_t size, uint32_t permissions, lldb::addr_t &addr) override;
+ Error WriteMemory(lldb::addr_t addr, const void *buf, size_t size,
+ size_t &bytes_written) override;
- Error
- DeallocateMemory (lldb::addr_t addr) override;
+ Error AllocateMemory(size_t size, uint32_t permissions,
+ lldb::addr_t &addr) override;
- lldb::addr_t
- GetSharedLibraryInfoAddress () override;
+ Error DeallocateMemory(lldb::addr_t addr) override;
- size_t
- UpdateThreads () override;
+ lldb::addr_t GetSharedLibraryInfoAddress() override;
- bool
- GetArchitecture (ArchSpec &arch) const override;
+ size_t UpdateThreads() override;
- Error
- SetBreakpoint (lldb::addr_t addr, uint32_t size, bool hardware) override;
+ bool GetArchitecture(ArchSpec &arch) const override;
- void
- DoStopIDBumped (uint32_t newBumpId) override;
+ Error SetBreakpoint(lldb::addr_t addr, uint32_t size, bool hardware) override;
- Error
- GetLoadedModuleFileSpec(const char* module_path, FileSpec& file_spec) override;
+ void DoStopIDBumped(uint32_t newBumpId) override;
- Error
- GetFileLoadAddress(const llvm::StringRef& file_name, lldb::addr_t& load_addr) override;
+ Error GetLoadedModuleFileSpec(const char *module_path,
+ FileSpec &file_spec) override;
- NativeThreadLinuxSP
- GetThreadByID(lldb::tid_t id);
+ Error GetFileLoadAddress(const llvm::StringRef &file_name,
+ lldb::addr_t &load_addr) override;
- // ---------------------------------------------------------------------
- // 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);
+ NativeThreadLinuxSP GetThreadByID(lldb::tid_t id);
- bool
- SupportHardwareSingleStepping() const;
+ // ---------------------------------------------------------------------
+ // 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);
- protected:
- // ---------------------------------------------------------------------
- // NativeProcessProtocol protected interface
- // ---------------------------------------------------------------------
- Error
- GetSoftwareBreakpointTrapOpcode (size_t trap_opcode_size_hint, size_t &actual_opcode_size, const uint8_t *&trap_opcode_bytes) override;
+ bool SupportHardwareSingleStepping() const;
- private:
+protected:
+ // ---------------------------------------------------------------------
+ // NativeProcessProtocol protected interface
+ // ---------------------------------------------------------------------
+ Error
+ GetSoftwareBreakpointTrapOpcode(size_t trap_opcode_size_hint,
+ size_t &actual_opcode_size,
+ const uint8_t *&trap_opcode_bytes) override;
- MainLoop::SignalHandleUP m_sigchld_handle;
- ArchSpec m_arch;
+private:
+ MainLoop::SignalHandleUP m_sigchld_handle;
+ ArchSpec m_arch;
- LazyBool m_supports_mem_region;
- std::vector<MemoryRegionInfo> m_mem_region_cache;
+ LazyBool m_supports_mem_region;
+ std::vector<MemoryRegionInfo> m_mem_region_cache;
- lldb::tid_t m_pending_notification_tid;
+ 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;
+ // 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;
+ // ---------------------------------------------------------------------
+ // Private Instance Methods
+ // ---------------------------------------------------------------------
+ NativeProcessLinux();
- // ---------------------------------------------------------------------
- // Private Instance Methods
- // ---------------------------------------------------------------------
- NativeProcessLinux ();
+ Error LaunchInferior(MainLoop &mainloop, ProcessLaunchInfo &launch_info);
- Error
- LaunchInferior(MainLoop &mainloop, ProcessLaunchInfo &launch_info);
+ /// Attaches to an existing process. Forms the
+ /// implementation of Process::DoAttach
+ void AttachToInferior(MainLoop &mainloop, lldb::pid_t pid, Error &error);
- /// 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);
- ::pid_t
- Attach(lldb::pid_t pid, Error &error);
+ static Error SetDefaultPtraceOpts(const lldb::pid_t);
- static void
- ChildFunc(const ProcessLaunchInfo &launch_info) LLVM_ATTRIBUTE_NORETURN;
+ static void *MonitorThread(void *baton);
- static Error
- SetDefaultPtraceOpts(const lldb::pid_t);
+ void MonitorCallback(lldb::pid_t pid, bool exited, int signal, int status);
- static bool
- DupDescriptor(const FileSpec &file_spec, int fd, int flags);
+ void WaitForNewThread(::pid_t tid);
- static void *
- MonitorThread(void *baton);
+ void MonitorSIGTRAP(const siginfo_t &info, NativeThreadLinux &thread);
- void
- MonitorCallback(lldb::pid_t pid, bool exited, int signal, int status);
+ void MonitorTrace(NativeThreadLinux &thread);
- void
- WaitForNewThread(::pid_t tid);
+ void MonitorBreakpoint(NativeThreadLinux &thread);
- void
- MonitorSIGTRAP(const siginfo_t &info, NativeThreadLinux &thread);
+ void MonitorWatchpoint(NativeThreadLinux &thread, uint32_t wp_index);
- void
- MonitorTrace(NativeThreadLinux &thread);
+ void MonitorSignal(const siginfo_t &info, NativeThreadLinux &thread,
+ bool exited);
- void
- MonitorBreakpoint(NativeThreadLinux &thread);
-
- void
- MonitorWatchpoint(NativeThreadLinux &thread, uint32_t wp_index);
-
- void
- MonitorSignal(const siginfo_t &info, NativeThreadLinux &thread, bool exited);
-
- Error
- SetupSoftwareSingleStepping(NativeThreadLinux &thread);
+ Error SetupSoftwareSingleStepping(NativeThreadLinux &thread);
#if 0
static ::ProcessMessage::CrashReason
@@ -216,59 +175,49 @@ namespace process_linux {
GetCrashReasonForSIGBUS(const siginfo_t *info);
#endif
- bool
- HasThreadNoLock (lldb::tid_t thread_id);
-
- bool
- StopTrackingThread (lldb::tid_t thread_id);
+ bool HasThreadNoLock(lldb::tid_t thread_id);
- NativeThreadLinuxSP
- AddThread (lldb::tid_t thread_id);
+ bool StopTrackingThread(lldb::tid_t thread_id);
- Error
- GetSoftwareBreakpointPCOffset(uint32_t &actual_opcode_size);
+ NativeThreadLinuxSP AddThread(lldb::tid_t thread_id);
- Error
- FixupBreakpointPCAsNeeded(NativeThreadLinux &thread);
+ Error GetSoftwareBreakpointPCOffset(uint32_t &actual_opcode_size);
- /// 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);
+ Error FixupBreakpointPCAsNeeded(NativeThreadLinux &thread);
- /// 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);
+ /// 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);
- void
- NotifyThreadDeath (lldb::tid_t tid);
+ /// 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);
- Error
- Detach(lldb::tid_t tid);
+ 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);
+ // 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();
+ // 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(NativeThreadLinux &thread, lldb::StateType state, int signo);
+ // 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(NativeThreadLinux &thread, lldb::StateType state,
+ int signo);
- void
- ThreadWasCreated(NativeThreadLinux &thread);
+ void ThreadWasCreated(NativeThreadLinux &thread);
- void
- SigchldHandler();
- };
+ void SigchldHandler();
+};
} // namespace process_linux
} // namespace lldb_private
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
index 0188c5d30724..580d2f952ad1 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
@@ -19,212 +19,195 @@
using namespace lldb_private;
using namespace lldb_private::process_linux;
-NativeRegisterContextLinux::NativeRegisterContextLinux(NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx,
- RegisterInfoInterface *reg_info_interface_p) :
- NativeRegisterContextRegisterInfo(native_thread, concrete_frame_idx, reg_info_interface_p)
-{}
-
-lldb::ByteOrder
-NativeRegisterContextLinux::GetByteOrder() const
-{
- // Get the target process whose privileged thread was used for the register read.
- lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
-
- NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
- if (!process_sp)
- return byte_order;
-
- if (!process_sp->GetByteOrder (byte_order))
- {
- // FIXME log here
- }
-
+NativeRegisterContextLinux::NativeRegisterContextLinux(
+ NativeThreadProtocol &native_thread, uint32_t concrete_frame_idx,
+ RegisterInfoInterface *reg_info_interface_p)
+ : NativeRegisterContextRegisterInfo(native_thread, concrete_frame_idx,
+ reg_info_interface_p) {}
+
+lldb::ByteOrder NativeRegisterContextLinux::GetByteOrder() const {
+ // Get the target process whose privileged thread was used for the register
+ // read.
+ lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
+
+ NativeProcessProtocolSP process_sp(m_thread.GetProcess());
+ if (!process_sp)
return byte_order;
-}
-Error
-NativeRegisterContextLinux::ReadRegisterRaw(uint32_t reg_index, RegisterValue &reg_value)
-{
- const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(reg_index);
- if (!reg_info)
- return Error("register %" PRIu32 " not found", reg_index);
+ if (!process_sp->GetByteOrder(byte_order)) {
+ // FIXME log here
+ }
- return DoReadRegisterValue(reg_info->byte_offset, reg_info->name, reg_info->byte_size, reg_value);
+ return byte_order;
}
-Error
-NativeRegisterContextLinux::WriteRegisterRaw(uint32_t reg_index, const RegisterValue &reg_value)
-{
- uint32_t reg_to_write = reg_index;
- RegisterValue value_to_write = reg_value;
-
- // Check if this is a subregister of a full register.
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_index);
- if (reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM))
- {
- Error error;
-
- RegisterValue full_value;
- uint32_t full_reg = reg_info->invalidate_regs[0];
- const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
-
- // Read the full register.
- error = ReadRegister(full_reg_info, full_value);
- if (error.Fail ())
- return error;
-
- lldb::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 = reg_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;
- }
- }
- }
+Error NativeRegisterContextLinux::ReadRegisterRaw(uint32_t reg_index,
+ RegisterValue &reg_value) {
+ const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(reg_index);
+ if (!reg_info)
+ return Error("register %" PRIu32 " not found", reg_index);
- const RegisterInfo *const register_to_write_info_p = GetRegisterInfoAtIndex (reg_to_write);
- assert (register_to_write_info_p && "register to write does not have valid RegisterInfo");
- if (!register_to_write_info_p)
- return Error("NativeRegisterContextLinux::%s failed to get RegisterInfo for write register index %" PRIu32, __FUNCTION__, reg_to_write);
+ return DoReadRegisterValue(reg_info->byte_offset, reg_info->name,
+ reg_info->byte_size, reg_value);
+}
- return DoWriteRegisterValue(reg_info->byte_offset, reg_info->name, reg_value);
+Error NativeRegisterContextLinux::WriteRegisterRaw(
+ uint32_t reg_index, const RegisterValue &reg_value) {
+ uint32_t reg_to_write = reg_index;
+ RegisterValue value_to_write = reg_value;
+
+ // Check if this is a subregister of a full register.
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_index);
+ if (reg_info->invalidate_regs &&
+ (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) {
+ Error error;
+
+ RegisterValue full_value;
+ uint32_t full_reg = reg_info->invalidate_regs[0];
+ const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
+
+ // Read the full register.
+ error = ReadRegister(full_reg_info, full_value);
+ if (error.Fail())
+ return error;
+
+ lldb::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 = reg_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;
+ }
+ }
+ }
+
+ const RegisterInfo *const register_to_write_info_p =
+ GetRegisterInfoAtIndex(reg_to_write);
+ assert(register_to_write_info_p &&
+ "register to write does not have valid RegisterInfo");
+ if (!register_to_write_info_p)
+ return Error("NativeRegisterContextLinux::%s failed to get RegisterInfo "
+ "for write register index %" PRIu32,
+ __FUNCTION__, reg_to_write);
+
+ return DoWriteRegisterValue(reg_info->byte_offset, reg_info->name, reg_value);
}
-Error
-NativeRegisterContextLinux::ReadGPR()
-{
- void* buf = GetGPRBuffer();
- if (!buf)
- return Error("GPR buffer is NULL");
- size_t buf_size = GetGPRSize();
+Error NativeRegisterContextLinux::ReadGPR() {
+ void *buf = GetGPRBuffer();
+ if (!buf)
+ return Error("GPR buffer is NULL");
+ size_t buf_size = GetGPRSize();
- return DoReadGPR(buf, buf_size);
+ return DoReadGPR(buf, buf_size);
}
-Error
-NativeRegisterContextLinux::WriteGPR()
-{
- void* buf = GetGPRBuffer();
- if (!buf)
- return Error("GPR buffer is NULL");
- size_t buf_size = GetGPRSize();
+Error NativeRegisterContextLinux::WriteGPR() {
+ void *buf = GetGPRBuffer();
+ if (!buf)
+ return Error("GPR buffer is NULL");
+ size_t buf_size = GetGPRSize();
- return DoWriteGPR(buf, buf_size);
+ return DoWriteGPR(buf, buf_size);
}
-Error
-NativeRegisterContextLinux::ReadFPR()
-{
- void* buf = GetFPRBuffer();
- if (!buf)
- return Error("FPR buffer is NULL");
- size_t buf_size = GetFPRSize();
+Error NativeRegisterContextLinux::ReadFPR() {
+ void *buf = GetFPRBuffer();
+ if (!buf)
+ return Error("FPR buffer is NULL");
+ size_t buf_size = GetFPRSize();
- return DoReadFPR(buf, buf_size);
+ return DoReadFPR(buf, buf_size);
}
-Error
-NativeRegisterContextLinux::WriteFPR()
-{
- void* buf = GetFPRBuffer();
- if (!buf)
- return Error("FPR buffer is NULL");
- size_t buf_size = GetFPRSize();
+Error NativeRegisterContextLinux::WriteFPR() {
+ void *buf = GetFPRBuffer();
+ if (!buf)
+ return Error("FPR buffer is NULL");
+ size_t buf_size = GetFPRSize();
- return DoWriteFPR(buf, buf_size);
+ return DoWriteFPR(buf, buf_size);
}
-Error
-NativeRegisterContextLinux::ReadRegisterSet(void *buf, size_t buf_size, unsigned int regset)
-{
- return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_thread.GetID(),
- static_cast<void *>(&regset), buf, buf_size);
+Error NativeRegisterContextLinux::ReadRegisterSet(void *buf, size_t buf_size,
+ unsigned int regset) {
+ return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_thread.GetID(),
+ static_cast<void *>(&regset), buf,
+ buf_size);
}
-Error
-NativeRegisterContextLinux::WriteRegisterSet(void *buf, size_t buf_size, unsigned int regset)
-{
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(),
- static_cast<void *>(&regset), buf, buf_size);
+Error NativeRegisterContextLinux::WriteRegisterSet(void *buf, size_t buf_size,
+ unsigned int regset) {
+ return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(),
+ static_cast<void *>(&regset), buf,
+ buf_size);
}
-Error
-NativeRegisterContextLinux::DoReadRegisterValue(uint32_t offset,
- const char* reg_name,
- uint32_t size,
- RegisterValue &value)
-{
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS));
+Error NativeRegisterContextLinux::DoReadRegisterValue(uint32_t offset,
+ const char *reg_name,
+ uint32_t size,
+ RegisterValue &value) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_REGISTERS));
- long data;
- Error error = NativeProcessLinux::PtraceWrapper(
- PTRACE_PEEKUSER, m_thread.GetID(), reinterpret_cast<void *>(offset), nullptr, 0, &data);
+ long data;
+ Error error = NativeProcessLinux::PtraceWrapper(
+ PTRACE_PEEKUSER, m_thread.GetID(), reinterpret_cast<void *>(offset),
+ nullptr, 0, &data);
- if (error.Success())
- // First cast to an unsigned of the same size to avoid sign extension.
- value.SetUInt(static_cast<unsigned long>(data), size);
+ if (error.Success())
+ // First cast to an unsigned of the same size to avoid sign extension.
+ value.SetUInt(static_cast<unsigned long>(data), size);
- if (log)
- log->Printf ("NativeRegisterContextLinux::%s() reg %s: 0x%lx", __FUNCTION__, reg_name, data);
+ if (log)
+ log->Printf("NativeRegisterContextLinux::%s() reg %s: 0x%lx", __FUNCTION__,
+ reg_name, data);
- return error;
+ return error;
}
-Error
-NativeRegisterContextLinux::DoWriteRegisterValue(uint32_t offset,
- const char* reg_name,
- const RegisterValue &value)
-{
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS));
+Error NativeRegisterContextLinux::DoWriteRegisterValue(
+ uint32_t offset, const char *reg_name, const RegisterValue &value) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_REGISTERS));
- void* buf = reinterpret_cast<void *>(value.GetAsUInt64());
+ void *buf = reinterpret_cast<void *>(value.GetAsUInt64());
- if (log)
- log->Printf ("NativeRegisterContextLinux::%s() reg %s: %p", __FUNCTION__, reg_name, buf);
+ if (log)
+ log->Printf("NativeRegisterContextLinux::%s() reg %s: %p", __FUNCTION__,
+ reg_name, buf);
- return NativeProcessLinux::PtraceWrapper(
- PTRACE_POKEUSER, m_thread.GetID(), reinterpret_cast<void *>(offset), buf);
+ return NativeProcessLinux::PtraceWrapper(
+ PTRACE_POKEUSER, m_thread.GetID(), reinterpret_cast<void *>(offset), buf);
}
-Error
-NativeRegisterContextLinux::DoReadGPR(void *buf, size_t buf_size)
-{
- return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGS, m_thread.GetID(), nullptr, buf, buf_size);
+Error NativeRegisterContextLinux::DoReadGPR(void *buf, size_t buf_size) {
+ return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGS, m_thread.GetID(),
+ nullptr, buf, buf_size);
}
-Error
-NativeRegisterContextLinux::DoWriteGPR(void *buf, size_t buf_size)
-{
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGS, m_thread.GetID(), nullptr, buf, buf_size);
+Error NativeRegisterContextLinux::DoWriteGPR(void *buf, size_t buf_size) {
+ return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGS, m_thread.GetID(),
+ nullptr, buf, buf_size);
}
-Error
-NativeRegisterContextLinux::DoReadFPR(void *buf, size_t buf_size)
-{
- return NativeProcessLinux::PtraceWrapper(PTRACE_GETFPREGS, m_thread.GetID(), nullptr, buf, buf_size);
+Error NativeRegisterContextLinux::DoReadFPR(void *buf, size_t buf_size) {
+ return NativeProcessLinux::PtraceWrapper(PTRACE_GETFPREGS, m_thread.GetID(),
+ nullptr, buf, buf_size);
}
-Error
-NativeRegisterContextLinux::DoWriteFPR(void *buf, size_t buf_size)
-{
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETFPREGS, m_thread.GetID(), nullptr, buf, buf_size);
+Error NativeRegisterContextLinux::DoWriteFPR(void *buf, size_t buf_size) {
+ return NativeProcessLinux::PtraceWrapper(PTRACE_SETFPREGS, m_thread.GetID(),
+ nullptr, buf, buf_size);
}
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
index 0b0b747984b4..a16c65b64a07 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
@@ -18,87 +18,72 @@
namespace lldb_private {
namespace process_linux {
-class NativeRegisterContextLinux : public NativeRegisterContextRegisterInfo
-{
+class NativeRegisterContextLinux : public NativeRegisterContextRegisterInfo {
public:
- NativeRegisterContextLinux(NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx,
- RegisterInfoInterface *reg_info_interface_p);
-
- // This function is implemented in the NativeRegisterContextLinux_* subclasses to create a new
- // instance of the host specific NativeRegisterContextLinux. The implementations can't collide
- // as only one NativeRegisterContextLinux_* variant should be compiled into the final
- // executable.
- static NativeRegisterContextLinux*
- CreateHostNativeRegisterContextLinux(const ArchSpec& target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx);
+ NativeRegisterContextLinux(NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx,
+ RegisterInfoInterface *reg_info_interface_p);
+
+ // This function is implemented in the NativeRegisterContextLinux_* subclasses
+ // to create a new
+ // instance of the host specific NativeRegisterContextLinux. The
+ // implementations can't collide
+ // as only one NativeRegisterContextLinux_* variant should be compiled into
+ // the final
+ // executable.
+ static NativeRegisterContextLinux *
+ CreateHostNativeRegisterContextLinux(const ArchSpec &target_arch,
+ NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx);
protected:
- lldb::ByteOrder
- GetByteOrder() const;
+ lldb::ByteOrder GetByteOrder() const;
- virtual Error
- ReadRegisterRaw(uint32_t reg_index, RegisterValue& reg_value);
+ virtual Error ReadRegisterRaw(uint32_t reg_index, RegisterValue &reg_value);
- virtual Error
- WriteRegisterRaw(uint32_t reg_index, const RegisterValue& reg_value);
+ virtual Error WriteRegisterRaw(uint32_t reg_index,
+ const RegisterValue &reg_value);
- virtual Error
- ReadRegisterSet(void *buf, size_t buf_size, unsigned int regset);
+ virtual Error ReadRegisterSet(void *buf, size_t buf_size,
+ unsigned int regset);
- virtual Error
- WriteRegisterSet(void *buf, size_t buf_size, unsigned int regset);
+ virtual Error WriteRegisterSet(void *buf, size_t buf_size,
+ unsigned int regset);
- virtual Error
- ReadGPR();
+ virtual Error ReadGPR();
- virtual Error
- WriteGPR();
+ virtual Error WriteGPR();
- virtual Error
- ReadFPR();
+ virtual Error ReadFPR();
- virtual Error
- WriteFPR();
+ virtual Error WriteFPR();
- virtual void*
- GetGPRBuffer() { return nullptr; }
+ virtual void *GetGPRBuffer() { return nullptr; }
- virtual size_t
- GetGPRSize() { return GetRegisterInfoInterface().GetGPRSize(); }
+ virtual size_t GetGPRSize() {
+ return GetRegisterInfoInterface().GetGPRSize();
+ }
- virtual void*
- GetFPRBuffer() { return nullptr; }
+ virtual void *GetFPRBuffer() { return nullptr; }
- virtual size_t
- GetFPRSize() { return 0; }
+ virtual size_t GetFPRSize() { return 0; }
+ // The Do*** functions are executed on the privileged thread and can perform
+ // ptrace
+ // operations directly.
+ virtual Error DoReadRegisterValue(uint32_t offset, const char *reg_name,
+ uint32_t size, RegisterValue &value);
- // The Do*** functions are executed on the privileged thread and can perform ptrace
- // operations directly.
- virtual Error
- DoReadRegisterValue(uint32_t offset,
- const char* reg_name,
- uint32_t size,
- RegisterValue &value);
+ virtual Error DoWriteRegisterValue(uint32_t offset, const char *reg_name,
+ const RegisterValue &value);
- virtual Error
- DoWriteRegisterValue(uint32_t offset,
- const char* reg_name,
- const RegisterValue &value);
+ virtual Error DoReadGPR(void *buf, size_t buf_size);
- virtual Error
- DoReadGPR(void *buf, size_t buf_size);
+ virtual Error DoWriteGPR(void *buf, size_t buf_size);
- virtual Error
- DoWriteGPR(void *buf, size_t buf_size);
+ virtual Error DoReadFPR(void *buf, size_t buf_size);
- virtual Error
- DoReadFPR(void *buf, size_t buf_size);
-
- virtual Error
- DoWriteFPR(void *buf, size_t buf_size);
+ virtual Error DoWriteFPR(void *buf, size_t buf_size);
};
} // namespace process_linux
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
index 5dfbaff90891..9e857139cfca 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
@@ -22,21 +22,21 @@
#include <elf.h>
#include <sys/socket.h>
-#define REG_CONTEXT_SIZE (GetGPRSize() + sizeof (m_fpr))
+#define REG_CONTEXT_SIZE (GetGPRSize() + sizeof(m_fpr))
#ifndef PTRACE_GETVFPREGS
- #define PTRACE_GETVFPREGS 27
- #define PTRACE_SETVFPREGS 28
+#define PTRACE_GETVFPREGS 27
+#define PTRACE_SETVFPREGS 28
#endif
#ifndef PTRACE_GETHBPREGS
- #define PTRACE_GETHBPREGS 29
- #define PTRACE_SETHBPREGS 30
+#define PTRACE_GETHBPREGS 29
+#define PTRACE_SETHBPREGS 30
#endif
#if !defined(PTRACE_TYPE_ARG3)
- #define PTRACE_TYPE_ARG3 void *
+#define PTRACE_TYPE_ARG3 void *
#endif
#if !defined(PTRACE_TYPE_ARG4)
- #define PTRACE_TYPE_ARG4 void *
+#define PTRACE_TYPE_ARG4 void *
#endif
using namespace lldb;
@@ -44,1084 +44,910 @@ using namespace lldb_private;
using namespace lldb_private::process_linux;
// arm general purpose registers.
-static const uint32_t g_gpr_regnums_arm[] =
-{
- gpr_r0_arm,
- gpr_r1_arm,
- gpr_r2_arm,
- gpr_r3_arm,
- gpr_r4_arm,
- gpr_r5_arm,
- gpr_r6_arm,
- gpr_r7_arm,
- gpr_r8_arm,
- gpr_r9_arm,
- gpr_r10_arm,
- gpr_r11_arm,
- gpr_r12_arm,
- gpr_sp_arm,
- gpr_lr_arm,
- gpr_pc_arm,
- gpr_cpsr_arm,
+static const uint32_t g_gpr_regnums_arm[] = {
+ gpr_r0_arm, gpr_r1_arm, gpr_r2_arm, gpr_r3_arm, gpr_r4_arm,
+ gpr_r5_arm, gpr_r6_arm, gpr_r7_arm, gpr_r8_arm, gpr_r9_arm,
+ gpr_r10_arm, gpr_r11_arm, gpr_r12_arm, gpr_sp_arm, gpr_lr_arm,
+ gpr_pc_arm, gpr_cpsr_arm,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
-static_assert(((sizeof g_gpr_regnums_arm / sizeof g_gpr_regnums_arm[0]) - 1) == k_num_gpr_registers_arm, \
+static_assert(((sizeof g_gpr_regnums_arm / sizeof g_gpr_regnums_arm[0]) - 1) ==
+ k_num_gpr_registers_arm,
"g_gpr_regnums_arm has wrong number of register infos");
// arm floating point registers.
-static const uint32_t g_fpu_regnums_arm[] =
-{
- fpu_s0_arm,
- fpu_s1_arm,
- fpu_s2_arm,
- fpu_s3_arm,
- fpu_s4_arm,
- fpu_s5_arm,
- fpu_s6_arm,
- fpu_s7_arm,
- fpu_s8_arm,
- fpu_s9_arm,
- fpu_s10_arm,
- fpu_s11_arm,
- fpu_s12_arm,
- fpu_s13_arm,
- fpu_s14_arm,
- fpu_s15_arm,
- fpu_s16_arm,
- fpu_s17_arm,
- fpu_s18_arm,
- fpu_s19_arm,
- fpu_s20_arm,
- fpu_s21_arm,
- fpu_s22_arm,
- fpu_s23_arm,
- fpu_s24_arm,
- fpu_s25_arm,
- fpu_s26_arm,
- fpu_s27_arm,
- fpu_s28_arm,
- fpu_s29_arm,
- fpu_s30_arm,
- fpu_s31_arm,
- fpu_fpscr_arm,
- fpu_d0_arm,
- fpu_d1_arm,
- fpu_d2_arm,
- fpu_d3_arm,
- fpu_d4_arm,
- fpu_d5_arm,
- fpu_d6_arm,
- fpu_d7_arm,
- fpu_d8_arm,
- fpu_d9_arm,
- fpu_d10_arm,
- fpu_d11_arm,
- fpu_d12_arm,
- fpu_d13_arm,
- fpu_d14_arm,
- fpu_d15_arm,
- fpu_d16_arm,
- fpu_d17_arm,
- fpu_d18_arm,
- fpu_d19_arm,
- fpu_d20_arm,
- fpu_d21_arm,
- fpu_d22_arm,
- fpu_d23_arm,
- fpu_d24_arm,
- fpu_d25_arm,
- fpu_d26_arm,
- fpu_d27_arm,
- fpu_d28_arm,
- fpu_d29_arm,
- fpu_d30_arm,
- fpu_d31_arm,
- fpu_q0_arm,
- fpu_q1_arm,
- fpu_q2_arm,
- fpu_q3_arm,
- fpu_q4_arm,
- fpu_q5_arm,
- fpu_q6_arm,
- fpu_q7_arm,
- fpu_q8_arm,
- fpu_q9_arm,
- fpu_q10_arm,
- fpu_q11_arm,
- fpu_q12_arm,
- fpu_q13_arm,
- fpu_q14_arm,
+static const uint32_t g_fpu_regnums_arm[] = {
+ fpu_s0_arm, fpu_s1_arm, fpu_s2_arm, fpu_s3_arm, fpu_s4_arm,
+ fpu_s5_arm, fpu_s6_arm, fpu_s7_arm, fpu_s8_arm, fpu_s9_arm,
+ fpu_s10_arm, fpu_s11_arm, fpu_s12_arm, fpu_s13_arm, fpu_s14_arm,
+ fpu_s15_arm, fpu_s16_arm, fpu_s17_arm, fpu_s18_arm, fpu_s19_arm,
+ fpu_s20_arm, fpu_s21_arm, fpu_s22_arm, fpu_s23_arm, fpu_s24_arm,
+ fpu_s25_arm, fpu_s26_arm, fpu_s27_arm, fpu_s28_arm, fpu_s29_arm,
+ fpu_s30_arm, fpu_s31_arm, fpu_fpscr_arm, fpu_d0_arm, fpu_d1_arm,
+ fpu_d2_arm, fpu_d3_arm, fpu_d4_arm, fpu_d5_arm, fpu_d6_arm,
+ fpu_d7_arm, fpu_d8_arm, fpu_d9_arm, fpu_d10_arm, fpu_d11_arm,
+ fpu_d12_arm, fpu_d13_arm, fpu_d14_arm, fpu_d15_arm, fpu_d16_arm,
+ fpu_d17_arm, fpu_d18_arm, fpu_d19_arm, fpu_d20_arm, fpu_d21_arm,
+ fpu_d22_arm, fpu_d23_arm, fpu_d24_arm, fpu_d25_arm, fpu_d26_arm,
+ fpu_d27_arm, fpu_d28_arm, fpu_d29_arm, fpu_d30_arm, fpu_d31_arm,
+ fpu_q0_arm, fpu_q1_arm, fpu_q2_arm, fpu_q3_arm, fpu_q4_arm,
+ fpu_q5_arm, fpu_q6_arm, fpu_q7_arm, fpu_q8_arm, fpu_q9_arm,
+ fpu_q10_arm, fpu_q11_arm, fpu_q12_arm, fpu_q13_arm, fpu_q14_arm,
fpu_q15_arm,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
-static_assert(((sizeof g_fpu_regnums_arm / sizeof g_fpu_regnums_arm[0]) - 1) == k_num_fpr_registers_arm, \
+static_assert(((sizeof g_fpu_regnums_arm / sizeof g_fpu_regnums_arm[0]) - 1) ==
+ k_num_fpr_registers_arm,
"g_fpu_regnums_arm has wrong number of register infos");
namespace {
- // Number of register sets provided by this context.
- enum
- {
- k_num_register_sets = 2
- };
+// Number of register sets provided by this context.
+enum { k_num_register_sets = 2 };
}
// Register sets for arm.
-static const RegisterSet
-g_reg_sets_arm[k_num_register_sets] =
-{
- { "General Purpose Registers", "gpr", k_num_gpr_registers_arm, g_gpr_regnums_arm },
- { "Floating Point Registers", "fpu", k_num_fpr_registers_arm, g_fpu_regnums_arm }
-};
+static const RegisterSet g_reg_sets_arm[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_arm,
+ g_gpr_regnums_arm},
+ {"Floating Point Registers", "fpu", k_num_fpr_registers_arm,
+ g_fpu_regnums_arm}};
#if defined(__arm__)
-NativeRegisterContextLinux*
-NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(const ArchSpec& target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx)
-{
- return new NativeRegisterContextLinux_arm(target_arch, native_thread, concrete_frame_idx);
+NativeRegisterContextLinux *
+NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx) {
+ return new NativeRegisterContextLinux_arm(target_arch, native_thread,
+ concrete_frame_idx);
}
#endif // defined(__arm__)
-NativeRegisterContextLinux_arm::NativeRegisterContextLinux_arm (const ArchSpec& target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx) :
- NativeRegisterContextLinux (native_thread, concrete_frame_idx, new RegisterContextLinux_arm(target_arch))
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::arm:
- m_reg_info.num_registers = k_num_registers_arm;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_arm;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_arm;
- m_reg_info.last_gpr = k_last_gpr_arm;
- m_reg_info.first_fpr = k_first_fpr_arm;
- m_reg_info.last_fpr = k_last_fpr_arm;
- m_reg_info.first_fpr_v = fpu_s0_arm;
- m_reg_info.last_fpr_v = fpu_s31_arm;
- m_reg_info.gpr_flags = gpr_cpsr_arm;
- break;
- default:
- assert(false && "Unhandled target architecture.");
- break;
- }
-
- ::memset(&m_fpr, 0, sizeof (m_fpr));
- ::memset(&m_gpr_arm, 0, sizeof (m_gpr_arm));
- ::memset(&m_hwp_regs, 0, sizeof (m_hwp_regs));
-
- // 16 is just a maximum value, query hardware for actual watchpoint count
- m_max_hwp_supported = 16;
- m_max_hbp_supported = 16;
- m_refresh_hwdebug_info = true;
+NativeRegisterContextLinux_arm::NativeRegisterContextLinux_arm(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx)
+ : NativeRegisterContextLinux(native_thread, concrete_frame_idx,
+ new RegisterContextLinux_arm(target_arch)) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::arm:
+ m_reg_info.num_registers = k_num_registers_arm;
+ m_reg_info.num_gpr_registers = k_num_gpr_registers_arm;
+ m_reg_info.num_fpr_registers = k_num_fpr_registers_arm;
+ m_reg_info.last_gpr = k_last_gpr_arm;
+ m_reg_info.first_fpr = k_first_fpr_arm;
+ m_reg_info.last_fpr = k_last_fpr_arm;
+ m_reg_info.first_fpr_v = fpu_s0_arm;
+ m_reg_info.last_fpr_v = fpu_s31_arm;
+ m_reg_info.gpr_flags = gpr_cpsr_arm;
+ break;
+ default:
+ assert(false && "Unhandled target architecture.");
+ break;
+ }
+
+ ::memset(&m_fpr, 0, sizeof(m_fpr));
+ ::memset(&m_gpr_arm, 0, sizeof(m_gpr_arm));
+ ::memset(&m_hwp_regs, 0, sizeof(m_hwp_regs));
+
+ // 16 is just a maximum value, query hardware for actual watchpoint count
+ m_max_hwp_supported = 16;
+ m_max_hbp_supported = 16;
+ m_refresh_hwdebug_info = true;
+}
+
+uint32_t NativeRegisterContextLinux_arm::GetRegisterSetCount() const {
+ return k_num_register_sets;
+}
+
+uint32_t NativeRegisterContextLinux_arm::GetUserRegisterCount() const {
+ uint32_t count = 0;
+ for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index)
+ count += g_reg_sets_arm[set_index].num_registers;
+ return count;
}
-uint32_t
-NativeRegisterContextLinux_arm::GetRegisterSetCount () const
-{
- return k_num_register_sets;
-}
+const RegisterSet *
+NativeRegisterContextLinux_arm::GetRegisterSet(uint32_t set_index) const {
+ if (set_index < k_num_register_sets)
+ return &g_reg_sets_arm[set_index];
-uint32_t
-NativeRegisterContextLinux_arm::GetUserRegisterCount() const
-{
- uint32_t count = 0;
- for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index)
- count += g_reg_sets_arm[set_index].num_registers;
- return count;
+ return nullptr;
}
-const RegisterSet *
-NativeRegisterContextLinux_arm::GetRegisterSet (uint32_t set_index) const
-{
- if (set_index < k_num_register_sets)
- return &g_reg_sets_arm[set_index];
+Error NativeRegisterContextLinux_arm::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) {
+ Error error;
- return nullptr;
-}
+ if (!reg_info) {
+ error.SetErrorString("reg_info NULL");
+ return error;
+ }
-Error
-NativeRegisterContextLinux_arm::ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value)
-{
- Error error;
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (!reg_info)
- {
- error.SetErrorString ("reg_info NULL");
- return error;
+ if (IsFPR(reg)) {
+ error = ReadFPR();
+ if (error.Fail())
+ return error;
+ } 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];
}
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ error = ReadRegisterRaw(full_reg, reg_value);
- if (IsFPR(reg))
- {
- error = ReadFPR();
- if (error.Fail())
- return error;
- }
- 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];
- }
-
- error = ReadRegisterRaw(full_reg, reg_value);
-
- if (error.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))
- reg_value.SetUInt64(reg_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 (reg_value.GetByteSize() > reg_info->byte_size)
- reg_value.SetType(reg_info);
- }
- return error;
- }
+ if (error.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))
+ reg_value.SetUInt64(reg_value.GetAsUInt64() >> 8);
- // Get pointer to m_fpr variable and set the data from it.
- uint32_t fpr_offset = CalculateFprOffset(reg_info);
- assert (fpr_offset < sizeof m_fpr);
- uint8_t *src = (uint8_t *)&m_fpr + fpr_offset;
- switch (reg_info->byte_size)
- {
- case 2:
- reg_value.SetUInt16(*(uint16_t *)src);
- break;
- case 4:
- reg_value.SetUInt32(*(uint32_t *)src);
- break;
- case 8:
- reg_value.SetUInt64(*(uint64_t *)src);
- break;
- case 16:
- reg_value.SetBytes(src, 16, GetByteOrder());
- break;
- default:
- assert(false && "Unhandled data size.");
- error.SetErrorStringWithFormat ("unhandled byte size: %" PRIu32, reg_info->byte_size);
- break;
+ // 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 (reg_value.GetByteSize() > reg_info->byte_size)
+ reg_value.SetType(reg_info);
}
-
return error;
-}
-
-Error
-NativeRegisterContextLinux_arm::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value)
-{
- if (!reg_info)
- return Error ("reg_info NULL");
-
- const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (reg_index == LLDB_INVALID_REGNUM)
- return Error ("no lldb regnum for %s", reg_info && reg_info->name ? reg_info->name : "<unknown register>");
-
- if (IsGPR(reg_index))
- return WriteRegisterRaw(reg_index, reg_value);
-
- if (IsFPR(reg_index))
- {
- // Get pointer to m_fpr variable and set the data to it.
- uint32_t fpr_offset = CalculateFprOffset(reg_info);
- assert (fpr_offset < sizeof m_fpr);
- uint8_t *dst = (uint8_t *)&m_fpr + fpr_offset;
- switch (reg_info->byte_size)
- {
- case 2:
- *(uint16_t *)dst = reg_value.GetAsUInt16();
- break;
- case 4:
- *(uint32_t *)dst = reg_value.GetAsUInt32();
- break;
- case 8:
- *(uint64_t *)dst = reg_value.GetAsUInt64();
- break;
- default:
- assert(false && "Unhandled data size.");
- return Error ("unhandled register data size %" PRIu32, reg_info->byte_size);
- }
-
- Error error = WriteFPR();
- if (error.Fail())
- return error;
-
- return Error ();
+ }
+
+ // Get pointer to m_fpr variable and set the data from it.
+ uint32_t fpr_offset = CalculateFprOffset(reg_info);
+ assert(fpr_offset < sizeof m_fpr);
+ uint8_t *src = (uint8_t *)&m_fpr + fpr_offset;
+ switch (reg_info->byte_size) {
+ case 2:
+ reg_value.SetUInt16(*(uint16_t *)src);
+ break;
+ case 4:
+ reg_value.SetUInt32(*(uint32_t *)src);
+ break;
+ case 8:
+ reg_value.SetUInt64(*(uint64_t *)src);
+ break;
+ case 16:
+ reg_value.SetBytes(src, 16, GetByteOrder());
+ break;
+ default:
+ assert(false && "Unhandled data size.");
+ error.SetErrorStringWithFormat("unhandled byte size: %" PRIu32,
+ reg_info->byte_size);
+ break;
+ }
+
+ return error;
+}
+
+Error NativeRegisterContextLinux_arm::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &reg_value) {
+ if (!reg_info)
+ return Error("reg_info NULL");
+
+ const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
+ if (reg_index == LLDB_INVALID_REGNUM)
+ return Error("no lldb regnum for %s", reg_info && reg_info->name
+ ? reg_info->name
+ : "<unknown register>");
+
+ if (IsGPR(reg_index))
+ return WriteRegisterRaw(reg_index, reg_value);
+
+ if (IsFPR(reg_index)) {
+ // Get pointer to m_fpr variable and set the data to it.
+ uint32_t fpr_offset = CalculateFprOffset(reg_info);
+ assert(fpr_offset < sizeof m_fpr);
+ uint8_t *dst = (uint8_t *)&m_fpr + fpr_offset;
+ switch (reg_info->byte_size) {
+ case 2:
+ *(uint16_t *)dst = reg_value.GetAsUInt16();
+ break;
+ case 4:
+ *(uint32_t *)dst = reg_value.GetAsUInt32();
+ break;
+ case 8:
+ *(uint64_t *)dst = reg_value.GetAsUInt64();
+ break;
+ default:
+ assert(false && "Unhandled data size.");
+ return Error("unhandled register data size %" PRIu32,
+ reg_info->byte_size);
}
- return Error ("failed - register wasn't recognized to be a GPR or an FPR, write strategy unknown");
-}
-
-Error
-NativeRegisterContextLinux_arm::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
-{
- Error error;
+ Error error = WriteFPR();
+ if (error.Fail())
+ return error;
- data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
- if (!data_sp)
- return Error ("failed to allocate DataBufferHeap instance of size %" PRIu64, (uint64_t)REG_CONTEXT_SIZE);
+ return Error();
+ }
- error = ReadGPR();
- if (error.Fail())
- return error;
+ return Error("failed - register wasn't recognized to be a GPR or an FPR, "
+ "write strategy unknown");
+}
- error = ReadFPR();
- if (error.Fail())
- return error;
+Error NativeRegisterContextLinux_arm::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ Error error;
- uint8_t *dst = data_sp->GetBytes ();
- if (dst == nullptr)
- {
- error.SetErrorStringWithFormat ("DataBufferHeap instance of size %" PRIu64 " returned a null pointer", (uint64_t)REG_CONTEXT_SIZE);
- return error;
- }
+ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (!data_sp)
+ return Error("failed to allocate DataBufferHeap instance of size %" PRIu64,
+ (uint64_t)REG_CONTEXT_SIZE);
- ::memcpy (dst, &m_gpr_arm, GetGPRSize());
- dst += GetGPRSize();
- ::memcpy (dst, &m_fpr, sizeof(m_fpr));
+ error = ReadGPR();
+ if (error.Fail())
+ return error;
+ error = ReadFPR();
+ if (error.Fail())
return error;
-}
-Error
-NativeRegisterContextLinux_arm::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
-{
- Error error;
+ uint8_t *dst = data_sp->GetBytes();
+ if (dst == nullptr) {
+ error.SetErrorStringWithFormat("DataBufferHeap instance of size %" PRIu64
+ " returned a null pointer",
+ (uint64_t)REG_CONTEXT_SIZE);
+ return error;
+ }
- if (!data_sp)
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s invalid data_sp provided", __FUNCTION__);
- return error;
- }
+ ::memcpy(dst, &m_gpr_arm, GetGPRSize());
+ dst += GetGPRSize();
+ ::memcpy(dst, &m_fpr, sizeof(m_fpr));
- if (data_sp->GetByteSize () != REG_CONTEXT_SIZE)
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s data_sp contained mismatched data size, expected %" PRIu64 ", actual %" PRIu64, __FUNCTION__, (uint64_t)REG_CONTEXT_SIZE, data_sp->GetByteSize ());
- return error;
- }
+ return error;
+}
+Error NativeRegisterContextLinux_arm::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ Error error;
- uint8_t *src = data_sp->GetBytes ();
- if (src == nullptr)
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s DataBuffer::GetBytes() returned a null pointer", __FUNCTION__);
- return error;
- }
- ::memcpy (&m_gpr_arm, src, GetRegisterInfoInterface ().GetGPRSize ());
+ if (!data_sp) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_x86_64::%s invalid data_sp provided",
+ __FUNCTION__);
+ return error;
+ }
- error = WriteGPR();
- if (error.Fail())
- return error;
+ if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_x86_64::%s data_sp contained mismatched "
+ "data size, expected %" PRIu64 ", actual %" PRIu64,
+ __FUNCTION__, (uint64_t)REG_CONTEXT_SIZE, data_sp->GetByteSize());
+ return error;
+ }
+
+ uint8_t *src = data_sp->GetBytes();
+ if (src == nullptr) {
+ error.SetErrorStringWithFormat("NativeRegisterContextLinux_x86_64::%s "
+ "DataBuffer::GetBytes() returned a null "
+ "pointer",
+ __FUNCTION__);
+ return error;
+ }
+ ::memcpy(&m_gpr_arm, src, GetRegisterInfoInterface().GetGPRSize());
- src += GetRegisterInfoInterface ().GetGPRSize ();
- ::memcpy (&m_fpr, src, sizeof(m_fpr));
+ error = WriteGPR();
+ if (error.Fail())
+ return error;
- error = WriteFPR();
- if (error.Fail())
- return error;
+ src += GetRegisterInfoInterface().GetGPRSize();
+ ::memcpy(&m_fpr, src, sizeof(m_fpr));
+ error = WriteFPR();
+ if (error.Fail())
return error;
+
+ return error;
}
-bool
-NativeRegisterContextLinux_arm::IsGPR(unsigned reg) const
-{
- return reg <= m_reg_info.last_gpr; // GPR's come first.
+bool NativeRegisterContextLinux_arm::IsGPR(unsigned reg) const {
+ return reg <= m_reg_info.last_gpr; // GPR's come first.
}
-bool
-NativeRegisterContextLinux_arm::IsFPR(unsigned reg) const
-{
- return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
+bool NativeRegisterContextLinux_arm::IsFPR(unsigned reg) const {
+ return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
}
uint32_t
-NativeRegisterContextLinux_arm::SetHardwareBreakpoint (lldb::addr_t addr, size_t size)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+NativeRegisterContextLinux_arm::SetHardwareBreakpoint(lldb::addr_t addr,
+ size_t size) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
- Error error;
+ Error error;
- // Read hardware breakpoint and watchpoint information.
- error = ReadHardwareDebugInfo ();
+ // Read hardware breakpoint and watchpoint information.
+ error = ReadHardwareDebugInfo();
- if (error.Fail())
- return LLDB_INVALID_INDEX32;
-
- uint32_t control_value = 0, bp_index = 0;
-
- // Check if size has a valid hardware breakpoint length.
- // Thumb instructions are 2-bytes but we have no way here to determine
- // if target address is a thumb or arm instruction.
- // TODO: Add support for setting thumb mode hardware breakpoints
- if (size != 4 && size != 2)
- return LLDB_INVALID_INDEX32;
-
- // Setup control value
- // Make the byte_mask into a valid Byte Address Select mask
- control_value = 0xfu << 5;
-
- // Enable this breakpoint and make it stop in privileged or user mode;
- control_value |= 7;
-
- // Make sure bits 1:0 are clear in our address
- // This should be different once we support thumb here.
- addr &= ~((lldb::addr_t)3);
-
- // Iterate over stored hardware breakpoints
- // Find a free bp_index or update reference count if duplicate.
- bp_index = LLDB_INVALID_INDEX32;
-
- for (uint32_t i = 0; i < m_max_hbp_supported; i++)
- {
- if ((m_hbr_regs[i].control & 1) == 0)
- {
- bp_index = i; // Mark last free slot
- }
- else if (m_hbr_regs[i].address == addr && m_hbr_regs[i].control == control_value)
- {
- bp_index = i; // Mark duplicate index
- break; // Stop searching here
- }
+ if (error.Fail())
+ return LLDB_INVALID_INDEX32;
+
+ uint32_t control_value = 0, bp_index = 0;
+
+ // Check if size has a valid hardware breakpoint length.
+ // Thumb instructions are 2-bytes but we have no way here to determine
+ // if target address is a thumb or arm instruction.
+ // TODO: Add support for setting thumb mode hardware breakpoints
+ if (size != 4 && size != 2)
+ return LLDB_INVALID_INDEX32;
+
+ // Setup control value
+ // Make the byte_mask into a valid Byte Address Select mask
+ control_value = 0xfu << 5;
+
+ // Enable this breakpoint and make it stop in privileged or user mode;
+ control_value |= 7;
+
+ // Make sure bits 1:0 are clear in our address
+ // This should be different once we support thumb here.
+ addr &= ~((lldb::addr_t)3);
+
+ // Iterate over stored hardware breakpoints
+ // Find a free bp_index or update reference count if duplicate.
+ bp_index = LLDB_INVALID_INDEX32;
+
+ for (uint32_t i = 0; i < m_max_hbp_supported; i++) {
+ if ((m_hbr_regs[i].control & 1) == 0) {
+ bp_index = i; // Mark last free slot
+ } else if (m_hbr_regs[i].address == addr &&
+ m_hbr_regs[i].control == control_value) {
+ bp_index = i; // Mark duplicate index
+ break; // Stop searching here
}
+ }
- if (bp_index == LLDB_INVALID_INDEX32)
- return LLDB_INVALID_INDEX32;
+ if (bp_index == LLDB_INVALID_INDEX32)
+ return LLDB_INVALID_INDEX32;
- // Add new or update existing breakpoint
- if ((m_hbr_regs[bp_index].control & 1) == 0)
- {
- m_hbr_regs[bp_index].address = addr;
- m_hbr_regs[bp_index].control = control_value;
- m_hbr_regs[bp_index].refcount = 1;
+ // Add new or update existing breakpoint
+ if ((m_hbr_regs[bp_index].control & 1) == 0) {
+ m_hbr_regs[bp_index].address = addr;
+ m_hbr_regs[bp_index].control = control_value;
+ m_hbr_regs[bp_index].refcount = 1;
- // PTRACE call to set corresponding hardware breakpoint register.
- error = WriteHardwareDebugRegs(eDREGTypeBREAK, bp_index);
+ // PTRACE call to set corresponding hardware breakpoint register.
+ error = WriteHardwareDebugRegs(eDREGTypeBREAK, bp_index);
- if (error.Fail())
- {
- m_hbr_regs[bp_index].address = 0;
- m_hbr_regs[bp_index].control &= ~1;
- m_hbr_regs[bp_index].refcount = 0;
+ if (error.Fail()) {
+ m_hbr_regs[bp_index].address = 0;
+ m_hbr_regs[bp_index].control &= ~1;
+ m_hbr_regs[bp_index].refcount = 0;
- return LLDB_INVALID_INDEX32;
- }
+ return LLDB_INVALID_INDEX32;
}
- else
- m_hbr_regs[bp_index].refcount++;
+ } else
+ m_hbr_regs[bp_index].refcount++;
- return bp_index;
+ return bp_index;
}
-bool
-NativeRegisterContextLinux_arm::ClearHardwareBreakpoint (uint32_t hw_idx)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+bool NativeRegisterContextLinux_arm::ClearHardwareBreakpoint(uint32_t hw_idx) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
- Error error;
+ Error error;
- // Read hardware breakpoint and watchpoint information.
- error = ReadHardwareDebugInfo ();
+ // Read hardware breakpoint and watchpoint information.
+ error = ReadHardwareDebugInfo();
- if (error.Fail())
- return false;
+ if (error.Fail())
+ return false;
- if (hw_idx >= m_max_hbp_supported)
- return false;
+ if (hw_idx >= m_max_hbp_supported)
+ return false;
- // Update reference count if multiple references.
- if (m_hbr_regs[hw_idx].refcount > 1)
- {
- m_hbr_regs[hw_idx].refcount--;
- return true;
- }
- else if (m_hbr_regs[hw_idx].refcount == 1)
- {
- // Create a backup we can revert to in case of failure.
- lldb::addr_t tempAddr = m_hbr_regs[hw_idx].address;
- uint32_t tempControl = m_hbr_regs[hw_idx].control;
- uint32_t tempRefCount = m_hbr_regs[hw_idx].refcount;
-
- m_hbr_regs[hw_idx].control &= ~1;
- m_hbr_regs[hw_idx].address = 0;
- m_hbr_regs[hw_idx].refcount = 0;
-
- // PTRACE call to clear corresponding hardware breakpoint register.
- WriteHardwareDebugRegs(eDREGTypeBREAK, hw_idx);
-
- if (error.Fail())
- {
- m_hbr_regs[hw_idx].control = tempControl;
- m_hbr_regs[hw_idx].address = tempAddr;
- m_hbr_regs[hw_idx].refcount = tempRefCount;
-
- return false;
- }
-
- return true;
+ // Update reference count if multiple references.
+ if (m_hbr_regs[hw_idx].refcount > 1) {
+ m_hbr_regs[hw_idx].refcount--;
+ return true;
+ } else if (m_hbr_regs[hw_idx].refcount == 1) {
+ // Create a backup we can revert to in case of failure.
+ lldb::addr_t tempAddr = m_hbr_regs[hw_idx].address;
+ uint32_t tempControl = m_hbr_regs[hw_idx].control;
+ uint32_t tempRefCount = m_hbr_regs[hw_idx].refcount;
+
+ m_hbr_regs[hw_idx].control &= ~1;
+ m_hbr_regs[hw_idx].address = 0;
+ m_hbr_regs[hw_idx].refcount = 0;
+
+ // PTRACE call to clear corresponding hardware breakpoint register.
+ WriteHardwareDebugRegs(eDREGTypeBREAK, hw_idx);
+
+ if (error.Fail()) {
+ m_hbr_regs[hw_idx].control = tempControl;
+ m_hbr_regs[hw_idx].address = tempAddr;
+ m_hbr_regs[hw_idx].refcount = tempRefCount;
+
+ return false;
}
- return false;
+ return true;
+ }
+
+ return false;
}
-uint32_t
-NativeRegisterContextLinux_arm::NumSupportedHardwareWatchpoints ()
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+uint32_t NativeRegisterContextLinux_arm::NumSupportedHardwareWatchpoints() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
- Error error;
+ Error error;
- // Read hardware breakpoint and watchpoint information.
- error = ReadHardwareDebugInfo ();
+ // Read hardware breakpoint and watchpoint information.
+ error = ReadHardwareDebugInfo();
- if (error.Fail())
- return 0;
+ if (error.Fail())
+ return 0;
- return m_max_hwp_supported;
+ return m_max_hwp_supported;
}
-uint32_t
-NativeRegisterContextLinux_arm::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+uint32_t NativeRegisterContextLinux_arm::SetHardwareWatchpoint(
+ lldb::addr_t addr, size_t size, uint32_t watch_flags) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
-
- Error error;
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
- // Read hardware breakpoint and watchpoint information.
- error = ReadHardwareDebugInfo ();
+ Error error;
- if (error.Fail())
- return LLDB_INVALID_INDEX32;
-
- uint32_t control_value = 0, wp_index = 0, addr_word_offset = 0, byte_mask = 0;
- lldb::addr_t real_addr = addr;
-
- // Check if we are setting watchpoint other than read/write/access
- // Also update watchpoint flag to match Arm write-read bit configuration.
- switch (watch_flags)
- {
- case 1:
- watch_flags = 2;
- break;
- case 2:
- watch_flags = 1;
- break;
- case 3:
- break;
- default:
- return LLDB_INVALID_INDEX32;
- }
+ // Read hardware breakpoint and watchpoint information.
+ error = ReadHardwareDebugInfo();
- // Can't watch zero bytes
- // Can't watch more than 4 bytes per WVR/WCR pair
+ if (error.Fail())
+ return LLDB_INVALID_INDEX32;
- if (size == 0 || size > 4)
- return LLDB_INVALID_INDEX32;
+ uint32_t control_value = 0, wp_index = 0, addr_word_offset = 0, byte_mask = 0;
+ lldb::addr_t real_addr = addr;
- // Check 4-byte alignment for hardware watchpoint target address.
- // Below is a hack to recalculate address and size in order to
- // make sure we can watch non 4-byte alligned addresses as well.
- if (addr & 0x03)
- {
- uint8_t watch_mask = (addr & 0x03) + size;
+ // Check if we are setting watchpoint other than read/write/access
+ // Also update watchpoint flag to match Arm write-read bit configuration.
+ switch (watch_flags) {
+ case 1:
+ watch_flags = 2;
+ break;
+ case 2:
+ watch_flags = 1;
+ break;
+ case 3:
+ break;
+ default:
+ return LLDB_INVALID_INDEX32;
+ }
- if (watch_mask > 0x04)
- return LLDB_INVALID_INDEX32;
- else if (watch_mask <= 0x02)
- size = 2;
- else if (watch_mask <= 0x04)
- size = 4;
+ // Can't watch zero bytes
+ // Can't watch more than 4 bytes per WVR/WCR pair
- addr = addr & (~0x03);
- }
+ if (size == 0 || size > 4)
+ return LLDB_INVALID_INDEX32;
- // We can only watch up to four bytes that follow a 4 byte aligned address
- // per watchpoint register pair, so make sure we can properly encode this.
- addr_word_offset = addr % 4;
- byte_mask = ((1u << size) - 1u) << addr_word_offset;
-
- // Check if we need multiple watchpoint register
- if (byte_mask > 0xfu)
- return LLDB_INVALID_INDEX32;
-
- // Setup control value
- // Make the byte_mask into a valid Byte Address Select mask
- control_value = byte_mask << 5;
-
- //Turn on appropriate watchpoint flags read or write
- control_value |= (watch_flags << 3);
-
- // Enable this watchpoint and make it stop in privileged or user mode;
- control_value |= 7;
-
- // Make sure bits 1:0 are clear in our address
- addr &= ~((lldb::addr_t)3);
-
- // Iterate over stored watchpoints
- // Find a free wp_index or update reference count if duplicate.
- wp_index = LLDB_INVALID_INDEX32;
- for (uint32_t i = 0; i < m_max_hwp_supported; i++)
- {
- if ((m_hwp_regs[i].control & 1) == 0)
- {
- wp_index = i; // Mark last free slot
- }
- else if (m_hwp_regs[i].address == addr && m_hwp_regs[i].control == control_value)
- {
- wp_index = i; // Mark duplicate index
- break; // Stop searching here
- }
- }
+ // Check 4-byte alignment for hardware watchpoint target address.
+ // Below is a hack to recalculate address and size in order to
+ // make sure we can watch non 4-byte alligned addresses as well.
+ if (addr & 0x03) {
+ uint8_t watch_mask = (addr & 0x03) + size;
- if (wp_index == LLDB_INVALID_INDEX32)
- return LLDB_INVALID_INDEX32;
-
- // Add new or update existing watchpoint
- if ((m_hwp_regs[wp_index].control & 1) == 0)
- {
- // Update watchpoint in local cache
- m_hwp_regs[wp_index].real_addr = real_addr;
- m_hwp_regs[wp_index].address = addr;
- m_hwp_regs[wp_index].control = control_value;
- m_hwp_regs[wp_index].refcount = 1;
-
- // PTRACE call to set corresponding watchpoint register.
- error = WriteHardwareDebugRegs(eDREGTypeWATCH, wp_index);
-
- if (error.Fail())
- {
- m_hwp_regs[wp_index].address = 0;
- m_hwp_regs[wp_index].control &= ~1;
- m_hwp_regs[wp_index].refcount = 0;
-
- return LLDB_INVALID_INDEX32;
- }
- }
- else
- m_hwp_regs[wp_index].refcount++;
+ if (watch_mask > 0x04)
+ return LLDB_INVALID_INDEX32;
+ else if (watch_mask <= 0x02)
+ size = 2;
+ else if (watch_mask <= 0x04)
+ size = 4;
- return wp_index;
-}
+ addr = addr & (~0x03);
+ }
-bool
-NativeRegisterContextLinux_arm::ClearHardwareWatchpoint (uint32_t wp_index)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+ // We can only watch up to four bytes that follow a 4 byte aligned address
+ // per watchpoint register pair, so make sure we can properly encode this.
+ addr_word_offset = addr % 4;
+ byte_mask = ((1u << size) - 1u) << addr_word_offset;
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
+ // Check if we need multiple watchpoint register
+ if (byte_mask > 0xfu)
+ return LLDB_INVALID_INDEX32;
- Error error;
+ // Setup control value
+ // Make the byte_mask into a valid Byte Address Select mask
+ control_value = byte_mask << 5;
- // Read hardware breakpoint and watchpoint information.
- error = ReadHardwareDebugInfo ();
+ // Turn on appropriate watchpoint flags read or write
+ control_value |= (watch_flags << 3);
- if (error.Fail())
- return false;
+ // Enable this watchpoint and make it stop in privileged or user mode;
+ control_value |= 7;
- if (wp_index >= m_max_hwp_supported)
- return false;
+ // Make sure bits 1:0 are clear in our address
+ addr &= ~((lldb::addr_t)3);
- // Update reference count if multiple references.
- if (m_hwp_regs[wp_index].refcount > 1)
- {
- m_hwp_regs[wp_index].refcount--;
- return true;
- }
- else if (m_hwp_regs[wp_index].refcount == 1)
- {
- // Create a backup we can revert to in case of failure.
- lldb::addr_t tempAddr = m_hwp_regs[wp_index].address;
- uint32_t tempControl = m_hwp_regs[wp_index].control;
- uint32_t tempRefCount = m_hwp_regs[wp_index].refcount;
-
- // Update watchpoint in local cache
- m_hwp_regs[wp_index].control &= ~1;
- m_hwp_regs[wp_index].address = 0;
- m_hwp_regs[wp_index].refcount = 0;
-
- // Ptrace call to update hardware debug registers
- error = WriteHardwareDebugRegs(eDREGTypeWATCH, wp_index);
-
- if (error.Fail())
- {
- m_hwp_regs[wp_index].control = tempControl;
- m_hwp_regs[wp_index].address = tempAddr;
- m_hwp_regs[wp_index].refcount = tempRefCount;
-
- return false;
- }
-
- return true;
+ // Iterate over stored watchpoints and find a free wp_index
+ wp_index = LLDB_INVALID_INDEX32;
+ for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
+ if ((m_hwp_regs[i].control & 1) == 0) {
+ wp_index = i; // Mark last free slot
+ } else if (m_hwp_regs[i].address == addr) {
+ return LLDB_INVALID_INDEX32; // We do not support duplicate watchpoints.
}
+ }
- return false;
+ if (wp_index == LLDB_INVALID_INDEX32)
+ return LLDB_INVALID_INDEX32;
+
+ // Update watchpoint in local cache
+ m_hwp_regs[wp_index].real_addr = real_addr;
+ m_hwp_regs[wp_index].address = addr;
+ m_hwp_regs[wp_index].control = control_value;
+
+ // PTRACE call to set corresponding watchpoint register.
+ error = WriteHardwareDebugRegs(eDREGTypeWATCH, wp_index);
+
+ if (error.Fail()) {
+ m_hwp_regs[wp_index].address = 0;
+ m_hwp_regs[wp_index].control &= ~1;
+
+ return LLDB_INVALID_INDEX32;
+ }
+
+ return wp_index;
}
-Error
-NativeRegisterContextLinux_arm::ClearAllHardwareWatchpoints ()
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+bool NativeRegisterContextLinux_arm::ClearHardwareWatchpoint(
+ uint32_t wp_index) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
- Error error;
+ Error error;
- // Read hardware breakpoint and watchpoint information.
- error = ReadHardwareDebugInfo ();
+ // Read hardware breakpoint and watchpoint information.
+ error = ReadHardwareDebugInfo();
- if (error.Fail())
- return error;
+ if (error.Fail())
+ return false;
- lldb::addr_t tempAddr = 0;
- uint32_t tempControl = 0, tempRefCount = 0;
-
- for (uint32_t i = 0; i < m_max_hwp_supported; i++)
- {
- if (m_hwp_regs[i].control & 0x01)
- {
- // Create a backup we can revert to in case of failure.
- tempAddr = m_hwp_regs[i].address;
- tempControl = m_hwp_regs[i].control;
- tempRefCount = m_hwp_regs[i].refcount;
-
- // Clear watchpoints in local cache
- m_hwp_regs[i].control &= ~1;
- m_hwp_regs[i].address = 0;
- m_hwp_regs[i].refcount = 0;
-
- // Ptrace call to update hardware debug registers
- error = WriteHardwareDebugRegs(eDREGTypeWATCH, i);
-
- if (error.Fail())
- {
- m_hwp_regs[i].control = tempControl;
- m_hwp_regs[i].address = tempAddr;
- m_hwp_regs[i].refcount = tempRefCount;
-
- return error;
- }
- }
- }
+ if (wp_index >= m_max_hwp_supported)
+ return false;
- return Error();
-}
+ // Create a backup we can revert to in case of failure.
+ lldb::addr_t tempAddr = m_hwp_regs[wp_index].address;
+ uint32_t tempControl = m_hwp_regs[wp_index].control;
-uint32_t
-NativeRegisterContextLinux_arm::GetWatchpointSize(uint32_t wp_index)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
-
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
-
- switch ((m_hwp_regs[wp_index].control >> 5) & 0x0f)
- {
- case 0x01:
- return 1;
- case 0x03:
- return 2;
- case 0x07:
- return 3;
- case 0x0f:
- return 4;
- default:
- return 0;
- }
-}
-bool
-NativeRegisterContextLinux_arm::WatchpointIsEnabled(uint32_t wp_index)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
-
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
-
- if ((m_hwp_regs[wp_index].control & 0x1) == 0x1)
- return true;
- else
- return false;
+ // Update watchpoint in local cache
+ m_hwp_regs[wp_index].control &= ~1;
+ m_hwp_regs[wp_index].address = 0;
+
+ // Ptrace call to update hardware debug registers
+ error = WriteHardwareDebugRegs(eDREGTypeWATCH, wp_index);
+
+ if (error.Fail()) {
+ m_hwp_regs[wp_index].control = tempControl;
+ m_hwp_regs[wp_index].address = tempAddr;
+
+ return false;
+ }
+
+ return true;
}
-Error
-NativeRegisterContextLinux_arm::GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+Error NativeRegisterContextLinux_arm::ClearAllHardwareWatchpoints() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
- uint32_t watch_size;
- lldb::addr_t watch_addr;
+ Error error;
- for (wp_index = 0; wp_index < m_max_hwp_supported; ++wp_index)
- {
- watch_size = GetWatchpointSize (wp_index);
- watch_addr = m_hwp_regs[wp_index].address;
+ // Read hardware breakpoint and watchpoint information.
+ error = ReadHardwareDebugInfo();
- if (m_hwp_regs[wp_index].refcount >= 1 && WatchpointIsEnabled(wp_index)
- && trap_addr >= watch_addr && trap_addr < watch_addr + watch_size)
- {
- m_hwp_regs[wp_index].hit_addr = trap_addr;
- return Error();
- }
- }
+ if (error.Fail())
+ return error;
- wp_index = LLDB_INVALID_INDEX32;
- return Error();
-}
+ lldb::addr_t tempAddr = 0;
+ uint32_t tempControl = 0;
-lldb::addr_t
-NativeRegisterContextLinux_arm::GetWatchpointAddress (uint32_t wp_index)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+ for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
+ if (m_hwp_regs[i].control & 0x01) {
+ // Create a backup we can revert to in case of failure.
+ tempAddr = m_hwp_regs[i].address;
+ tempControl = m_hwp_regs[i].control;
+
+ // Clear watchpoints in local cache
+ m_hwp_regs[i].control &= ~1;
+ m_hwp_regs[i].address = 0;
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
+ // Ptrace call to update hardware debug registers
+ error = WriteHardwareDebugRegs(eDREGTypeWATCH, i);
- if (wp_index >= m_max_hwp_supported)
- return LLDB_INVALID_ADDRESS;
+ if (error.Fail()) {
+ m_hwp_regs[i].control = tempControl;
+ m_hwp_regs[i].address = tempAddr;
- if (WatchpointIsEnabled(wp_index))
- return m_hwp_regs[wp_index].real_addr;
- else
- return LLDB_INVALID_ADDRESS;
+ return error;
+ }
+ }
+ }
+
+ return Error();
}
-lldb::addr_t
-NativeRegisterContextLinux_arm::GetWatchpointHitAddress (uint32_t wp_index)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+uint32_t NativeRegisterContextLinux_arm::GetWatchpointSize(uint32_t wp_index) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
- if (wp_index >= m_max_hwp_supported)
- return LLDB_INVALID_ADDRESS;
+ switch ((m_hwp_regs[wp_index].control >> 5) & 0x0f) {
+ case 0x01:
+ return 1;
+ case 0x03:
+ return 2;
+ case 0x07:
+ return 3;
+ case 0x0f:
+ return 4;
+ default:
+ return 0;
+ }
+}
+bool NativeRegisterContextLinux_arm::WatchpointIsEnabled(uint32_t wp_index) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (WatchpointIsEnabled(wp_index))
- return m_hwp_regs[wp_index].hit_addr;
- else
- return LLDB_INVALID_ADDRESS;
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
+
+ if ((m_hwp_regs[wp_index].control & 0x1) == 0x1)
+ return true;
+ else
+ return false;
}
-Error
-NativeRegisterContextLinux_arm::ReadHardwareDebugInfo()
-{
- Error error;
+Error NativeRegisterContextLinux_arm::GetWatchpointHitIndex(
+ uint32_t &wp_index, lldb::addr_t trap_addr) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
+
+ uint32_t watch_size;
+ lldb::addr_t watch_addr;
- if (!m_refresh_hwdebug_info)
- {
- return Error();
+ for (wp_index = 0; wp_index < m_max_hwp_supported; ++wp_index) {
+ watch_size = GetWatchpointSize(wp_index);
+ watch_addr = m_hwp_regs[wp_index].address;
+
+ if (WatchpointIsEnabled(wp_index) && trap_addr >= watch_addr &&
+ trap_addr < watch_addr + watch_size) {
+ m_hwp_regs[wp_index].hit_addr = trap_addr;
+ return Error();
}
+ }
- unsigned int cap_val;
+ wp_index = LLDB_INVALID_INDEX32;
+ return Error();
+}
- error = NativeProcessLinux::PtraceWrapper(PTRACE_GETHBPREGS, m_thread.GetID(), nullptr, &cap_val, sizeof(unsigned int));
+lldb::addr_t
+NativeRegisterContextLinux_arm::GetWatchpointAddress(uint32_t wp_index) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (error.Fail())
- return error;
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
- m_max_hwp_supported = (cap_val >> 8) & 0xff;
- m_max_hbp_supported = cap_val & 0xff;
- m_refresh_hwdebug_info = false;
+ if (wp_index >= m_max_hwp_supported)
+ return LLDB_INVALID_ADDRESS;
- return error;
+ if (WatchpointIsEnabled(wp_index))
+ return m_hwp_regs[wp_index].real_addr;
+ else
+ return LLDB_INVALID_ADDRESS;
}
-Error
-NativeRegisterContextLinux_arm::WriteHardwareDebugRegs(int hwbType, int hwb_index)
-{
- Error error;
+lldb::addr_t
+NativeRegisterContextLinux_arm::GetWatchpointHitAddress(uint32_t wp_index) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- lldb::addr_t *addr_buf;
- uint32_t *ctrl_buf;
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
- if (hwbType == eDREGTypeWATCH)
- {
- addr_buf = &m_hwp_regs[hwb_index].address;
- ctrl_buf = &m_hwp_regs[hwb_index].control;
+ if (wp_index >= m_max_hwp_supported)
+ return LLDB_INVALID_ADDRESS;
- error = NativeProcessLinux::PtraceWrapper(PTRACE_SETHBPREGS,
- m_thread.GetID(), (PTRACE_TYPE_ARG3)(intptr_t) -((hwb_index << 1) + 1),
- addr_buf, sizeof(unsigned int));
+ if (WatchpointIsEnabled(wp_index))
+ return m_hwp_regs[wp_index].hit_addr;
+ else
+ return LLDB_INVALID_ADDRESS;
+}
- if (error.Fail())
- return error;
+Error NativeRegisterContextLinux_arm::ReadHardwareDebugInfo() {
+ Error error;
- error = NativeProcessLinux::PtraceWrapper(PTRACE_SETHBPREGS,
- m_thread.GetID(), (PTRACE_TYPE_ARG3)(intptr_t) -((hwb_index << 1) + 2),
- ctrl_buf, sizeof(unsigned int));
- }
- else
- {
- addr_buf = &m_hwp_regs[hwb_index].address;
- ctrl_buf = &m_hwp_regs[hwb_index].control;
+ if (!m_refresh_hwdebug_info) {
+ return Error();
+ }
- error = NativeProcessLinux::PtraceWrapper(PTRACE_SETHBPREGS,
- m_thread.GetID(), (PTRACE_TYPE_ARG3)(intptr_t) ((hwb_index << 1) + 1),
- addr_buf, sizeof(unsigned int));
+ unsigned int cap_val;
- if (error.Fail())
- return error;
+ error = NativeProcessLinux::PtraceWrapper(PTRACE_GETHBPREGS, m_thread.GetID(),
+ nullptr, &cap_val,
+ sizeof(unsigned int));
- error = NativeProcessLinux::PtraceWrapper(PTRACE_SETHBPREGS,
- m_thread.GetID(), (PTRACE_TYPE_ARG3)(intptr_t) ((hwb_index << 1) + 2),
- ctrl_buf, sizeof(unsigned int));
+ if (error.Fail())
+ return error;
- }
+ m_max_hwp_supported = (cap_val >> 8) & 0xff;
+ m_max_hbp_supported = cap_val & 0xff;
+ m_refresh_hwdebug_info = false;
- return error;
+ return error;
}
-uint32_t
-NativeRegisterContextLinux_arm::CalculateFprOffset(const RegisterInfo* reg_info) const
-{
- return reg_info->byte_offset - GetRegisterInfoAtIndex(m_reg_info.first_fpr)->byte_offset;
-}
+Error NativeRegisterContextLinux_arm::WriteHardwareDebugRegs(int hwbType,
+ int hwb_index) {
+ Error error;
+
+ lldb::addr_t *addr_buf;
+ uint32_t *ctrl_buf;
+
+ if (hwbType == eDREGTypeWATCH) {
+ addr_buf = &m_hwp_regs[hwb_index].address;
+ ctrl_buf = &m_hwp_regs[hwb_index].control;
+
+ error = NativeProcessLinux::PtraceWrapper(
+ PTRACE_SETHBPREGS, m_thread.GetID(),
+ (PTRACE_TYPE_ARG3)(intptr_t) - ((hwb_index << 1) + 1), addr_buf,
+ sizeof(unsigned int));
-Error
-NativeRegisterContextLinux_arm::DoReadRegisterValue(uint32_t offset,
- const char* reg_name,
- uint32_t size,
- RegisterValue &value)
-{
- // PTRACE_PEEKUSER don't work in the aarch64 linux kernel used on android devices (always return
- // "Bad address"). To avoid using PTRACE_PEEKUSER we read out the full GPR register set instead.
- // This approach is about 4 times slower but the performance overhead is negligible in
- // comparision to processing time in lldb-server.
- assert(offset % 4 == 0 && "Try to write a register with unaligned offset");
- if (offset + sizeof(uint32_t) > sizeof(m_gpr_arm))
- return Error("Register isn't fit into the size of the GPR area");
-
- Error error = DoReadGPR(m_gpr_arm, sizeof(m_gpr_arm));
if (error.Fail())
- return error;
+ return error;
- value.SetUInt32(m_gpr_arm[offset / sizeof(uint32_t)]);
- return Error();
-}
+ error = NativeProcessLinux::PtraceWrapper(
+ PTRACE_SETHBPREGS, m_thread.GetID(),
+ (PTRACE_TYPE_ARG3)(intptr_t) - ((hwb_index << 1) + 2), ctrl_buf,
+ sizeof(unsigned int));
+ } else {
+ addr_buf = &m_hwp_regs[hwb_index].address;
+ ctrl_buf = &m_hwp_regs[hwb_index].control;
+
+ error = NativeProcessLinux::PtraceWrapper(
+ PTRACE_SETHBPREGS, m_thread.GetID(),
+ (PTRACE_TYPE_ARG3)(intptr_t)((hwb_index << 1) + 1), addr_buf,
+ sizeof(unsigned int));
-Error
-NativeRegisterContextLinux_arm::DoWriteRegisterValue(uint32_t offset,
- const char* reg_name,
- const RegisterValue &value)
-{
- // PTRACE_POKEUSER don't work in the aarch64 linux kernel used on android devices (always return
- // "Bad address"). To avoid using PTRACE_POKEUSER we read out the full GPR register set, modify
- // the requested register and write it back. This approach is about 4 times slower but the
- // performance overhead is negligible in comparision to processing time in lldb-server.
- assert(offset % 4 == 0 && "Try to write a register with unaligned offset");
- if (offset + sizeof(uint32_t) > sizeof(m_gpr_arm))
- return Error("Register isn't fit into the size of the GPR area");
-
- Error error = DoReadGPR(m_gpr_arm, sizeof(m_gpr_arm));
if (error.Fail())
- return error;
+ return error;
+
+ error = NativeProcessLinux::PtraceWrapper(
+ PTRACE_SETHBPREGS, m_thread.GetID(),
+ (PTRACE_TYPE_ARG3)(intptr_t)((hwb_index << 1) + 2), ctrl_buf,
+ sizeof(unsigned int));
+ }
+
+ return error;
+}
+
+uint32_t NativeRegisterContextLinux_arm::CalculateFprOffset(
+ const RegisterInfo *reg_info) const {
+ return reg_info->byte_offset -
+ GetRegisterInfoAtIndex(m_reg_info.first_fpr)->byte_offset;
+}
+
+Error NativeRegisterContextLinux_arm::DoReadRegisterValue(
+ uint32_t offset, const char *reg_name, uint32_t size,
+ RegisterValue &value) {
+ // PTRACE_PEEKUSER don't work in the aarch64 linux kernel used on android
+ // devices (always return
+ // "Bad address"). To avoid using PTRACE_PEEKUSER we read out the full GPR
+ // register set instead.
+ // This approach is about 4 times slower but the performance overhead is
+ // negligible in
+ // comparision to processing time in lldb-server.
+ assert(offset % 4 == 0 && "Try to write a register with unaligned offset");
+ if (offset + sizeof(uint32_t) > sizeof(m_gpr_arm))
+ return Error("Register isn't fit into the size of the GPR area");
+
+ Error error = DoReadGPR(m_gpr_arm, sizeof(m_gpr_arm));
+ if (error.Fail())
+ return error;
+
+ value.SetUInt32(m_gpr_arm[offset / sizeof(uint32_t)]);
+ return Error();
+}
+
+Error NativeRegisterContextLinux_arm::DoWriteRegisterValue(
+ uint32_t offset, const char *reg_name, const RegisterValue &value) {
+ // PTRACE_POKEUSER don't work in the aarch64 linux kernel used on android
+ // devices (always return
+ // "Bad address"). To avoid using PTRACE_POKEUSER we read out the full GPR
+ // register set, modify
+ // the requested register and write it back. This approach is about 4 times
+ // slower but the
+ // performance overhead is negligible in comparision to processing time in
+ // lldb-server.
+ assert(offset % 4 == 0 && "Try to write a register with unaligned offset");
+ if (offset + sizeof(uint32_t) > sizeof(m_gpr_arm))
+ return Error("Register isn't fit into the size of the GPR area");
+
+ Error error = DoReadGPR(m_gpr_arm, sizeof(m_gpr_arm));
+ if (error.Fail())
+ return error;
- uint32_t reg_value = value.GetAsUInt32();
- // As precaution for an undefined behavior encountered while setting PC we
- // will clear thumb bit of new PC if we are already in thumb mode; that is
- // CPSR thumb mode bit is set.
- if (offset / sizeof(uint32_t) == gpr_pc_arm)
- {
- // Check if we are already in thumb mode and
- // thumb bit of current PC is read out to be zero and
- // thumb bit of next PC is read out to be one.
- if ((m_gpr_arm[gpr_cpsr_arm] & 0x20) &&
- !(m_gpr_arm[gpr_pc_arm] & 0x01) &&
- (value.GetAsUInt32() & 0x01))
- {
- reg_value &= (~1ull);
- }
+ uint32_t reg_value = value.GetAsUInt32();
+ // As precaution for an undefined behavior encountered while setting PC we
+ // will clear thumb bit of new PC if we are already in thumb mode; that is
+ // CPSR thumb mode bit is set.
+ if (offset / sizeof(uint32_t) == gpr_pc_arm) {
+ // Check if we are already in thumb mode and
+ // thumb bit of current PC is read out to be zero and
+ // thumb bit of next PC is read out to be one.
+ if ((m_gpr_arm[gpr_cpsr_arm] & 0x20) && !(m_gpr_arm[gpr_pc_arm] & 0x01) &&
+ (value.GetAsUInt32() & 0x01)) {
+ reg_value &= (~1ull);
}
+ }
- m_gpr_arm[offset / sizeof(uint32_t)] = reg_value;
- return DoWriteGPR(m_gpr_arm, sizeof(m_gpr_arm));
+ m_gpr_arm[offset / sizeof(uint32_t)] = reg_value;
+ return DoWriteGPR(m_gpr_arm, sizeof(m_gpr_arm));
}
-Error
-NativeRegisterContextLinux_arm::DoReadGPR(void *buf, size_t buf_size)
-{
+Error NativeRegisterContextLinux_arm::DoReadGPR(void *buf, size_t buf_size) {
#ifdef __arm__
- return NativeRegisterContextLinux::DoReadGPR(buf, buf_size);
-#else // __aarch64__
- struct iovec ioVec;
- ioVec.iov_base = buf;
- ioVec.iov_len = buf_size;
+ return NativeRegisterContextLinux::DoReadGPR(buf, buf_size);
+#else // __aarch64__
+ struct iovec ioVec;
+ ioVec.iov_base = buf;
+ ioVec.iov_len = buf_size;
- return ReadRegisterSet(&ioVec, buf_size, NT_PRSTATUS);
+ return ReadRegisterSet(&ioVec, buf_size, NT_PRSTATUS);
#endif // __arm__
}
-Error
-NativeRegisterContextLinux_arm::DoWriteGPR(void *buf, size_t buf_size)
-{
+Error NativeRegisterContextLinux_arm::DoWriteGPR(void *buf, size_t buf_size) {
#ifdef __arm__
- return NativeRegisterContextLinux::DoWriteGPR(buf, buf_size);
-#else // __aarch64__
- struct iovec ioVec;
- ioVec.iov_base = buf;
- ioVec.iov_len = buf_size;
+ return NativeRegisterContextLinux::DoWriteGPR(buf, buf_size);
+#else // __aarch64__
+ struct iovec ioVec;
+ ioVec.iov_base = buf;
+ ioVec.iov_len = buf_size;
- return WriteRegisterSet(&ioVec, buf_size, NT_PRSTATUS);
+ return WriteRegisterSet(&ioVec, buf_size, NT_PRSTATUS);
#endif // __arm__
}
-Error
-NativeRegisterContextLinux_arm::DoReadFPR(void *buf, size_t buf_size)
-{
+Error NativeRegisterContextLinux_arm::DoReadFPR(void *buf, size_t buf_size) {
#ifdef __arm__
- return NativeProcessLinux::PtraceWrapper(PTRACE_GETVFPREGS,
- m_thread.GetID(),
- nullptr,
- buf,
- buf_size);
-#else // __aarch64__
- struct iovec ioVec;
- ioVec.iov_base = buf;
- ioVec.iov_len = buf_size;
-
- return ReadRegisterSet(&ioVec, buf_size, NT_ARM_VFP);
+ return NativeProcessLinux::PtraceWrapper(PTRACE_GETVFPREGS, m_thread.GetID(),
+ nullptr, buf, buf_size);
+#else // __aarch64__
+ struct iovec ioVec;
+ ioVec.iov_base = buf;
+ ioVec.iov_len = buf_size;
+
+ return ReadRegisterSet(&ioVec, buf_size, NT_ARM_VFP);
#endif // __arm__
}
-Error
-NativeRegisterContextLinux_arm::DoWriteFPR(void *buf, size_t buf_size)
-{
+Error NativeRegisterContextLinux_arm::DoWriteFPR(void *buf, size_t buf_size) {
#ifdef __arm__
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETVFPREGS,
- m_thread.GetID(),
- nullptr,
- buf,
- buf_size);
-#else // __aarch64__
- struct iovec ioVec;
- ioVec.iov_base = buf;
- ioVec.iov_len = buf_size;
-
- return WriteRegisterSet(&ioVec, buf_size, NT_ARM_VFP);
+ return NativeProcessLinux::PtraceWrapper(PTRACE_SETVFPREGS, m_thread.GetID(),
+ nullptr, buf, buf_size);
+#else // __aarch64__
+ struct iovec ioVec;
+ ioVec.iov_base = buf;
+ ioVec.iov_len = buf_size;
+
+ return WriteRegisterSet(&ioVec, buf_size, NT_ARM_VFP);
#endif // __arm__
}
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
index 452f13258c2b..f979811216dc 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
@@ -18,181 +18,142 @@
namespace lldb_private {
namespace process_linux {
- class NativeProcessLinux;
+class NativeProcessLinux;
- class NativeRegisterContextLinux_arm : public NativeRegisterContextLinux
- {
- public:
- NativeRegisterContextLinux_arm (const ArchSpec& target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx);
+class NativeRegisterContextLinux_arm : public NativeRegisterContextLinux {
+public:
+ NativeRegisterContextLinux_arm(const ArchSpec &target_arch,
+ NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx);
- uint32_t
- GetRegisterSetCount () const override;
+ uint32_t GetRegisterSetCount() const override;
- const RegisterSet *
- GetRegisterSet (uint32_t set_index) const override;
+ const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
- uint32_t
- GetUserRegisterCount() const override;
+ uint32_t GetUserRegisterCount() const override;
- Error
- ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value) override;
+ Error ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) override;
- Error
- WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value) override;
+ Error WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) override;
- Error
- ReadAllRegisterValues (lldb::DataBufferSP &data_sp) override;
+ Error ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
- Error
- WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) override;
+ Error WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- //------------------------------------------------------------------
- // Hardware breakpoints/watchpoint mangement functions
- //------------------------------------------------------------------
+ //------------------------------------------------------------------
+ // Hardware breakpoints/watchpoint mangement functions
+ //------------------------------------------------------------------
- uint32_t
- SetHardwareBreakpoint (lldb::addr_t addr, size_t size) override;
+ uint32_t SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override;
- bool
- ClearHardwareBreakpoint (uint32_t hw_idx) override;
+ bool ClearHardwareBreakpoint(uint32_t hw_idx) override;
- uint32_t
- NumSupportedHardwareWatchpoints () override;
+ uint32_t NumSupportedHardwareWatchpoints() override;
- uint32_t
- SetHardwareWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags) override;
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
+ uint32_t watch_flags) override;
- bool
- ClearHardwareWatchpoint (uint32_t hw_index) override;
+ bool ClearHardwareWatchpoint(uint32_t hw_index) override;
- Error
- ClearAllHardwareWatchpoints () override;
+ Error ClearAllHardwareWatchpoints() override;
- Error
- GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr) override;
+ Error GetWatchpointHitIndex(uint32_t &wp_index,
+ lldb::addr_t trap_addr) override;
- lldb::addr_t
- GetWatchpointHitAddress (uint32_t wp_index) override;
+ lldb::addr_t GetWatchpointHitAddress(uint32_t wp_index) override;
- lldb::addr_t
- GetWatchpointAddress (uint32_t wp_index) override;
+ lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
- uint32_t
- GetWatchpointSize(uint32_t wp_index);
+ uint32_t GetWatchpointSize(uint32_t wp_index);
- bool
- WatchpointIsEnabled(uint32_t wp_index);
+ bool WatchpointIsEnabled(uint32_t wp_index);
- // Debug register type select
- enum DREGType
- {
- eDREGTypeWATCH = 0,
- eDREGTypeBREAK
- };
+ // Debug register type select
+ enum DREGType { eDREGTypeWATCH = 0, eDREGTypeBREAK };
- protected:
- Error
- DoReadRegisterValue(uint32_t offset,
- const char* reg_name,
- uint32_t size,
- RegisterValue &value) override;
+protected:
+ Error DoReadRegisterValue(uint32_t offset, const char *reg_name,
+ uint32_t size, RegisterValue &value) override;
- Error
- DoWriteRegisterValue(uint32_t offset,
- const char* reg_name,
+ Error DoWriteRegisterValue(uint32_t offset, const char *reg_name,
const RegisterValue &value) override;
- Error
- DoReadGPR(void *buf, size_t buf_size) override;
+ Error DoReadGPR(void *buf, size_t buf_size) override;
- Error
- DoWriteGPR(void *buf, size_t buf_size) override;
+ Error DoWriteGPR(void *buf, size_t buf_size) override;
- Error
- DoReadFPR(void *buf, size_t buf_size) override;
+ Error DoReadFPR(void *buf, size_t buf_size) override;
- Error
- DoWriteFPR(void *buf, size_t buf_size) override;
+ Error DoWriteFPR(void *buf, size_t buf_size) override;
- void*
- GetGPRBuffer() override { return &m_gpr_arm; }
+ void *GetGPRBuffer() override { return &m_gpr_arm; }
- void*
- GetFPRBuffer() override { return &m_fpr; }
+ void *GetFPRBuffer() override { return &m_fpr; }
- size_t
- GetFPRSize() override { return sizeof(m_fpr); }
+ size_t GetFPRSize() override { return sizeof(m_fpr); }
- private:
- struct RegInfo
- {
- uint32_t num_registers;
- uint32_t num_gpr_registers;
- uint32_t num_fpr_registers;
+private:
+ struct RegInfo {
+ uint32_t num_registers;
+ uint32_t num_gpr_registers;
+ uint32_t num_fpr_registers;
- uint32_t last_gpr;
- uint32_t first_fpr;
- uint32_t last_fpr;
+ uint32_t last_gpr;
+ uint32_t first_fpr;
+ uint32_t last_fpr;
- uint32_t first_fpr_v;
- uint32_t last_fpr_v;
+ uint32_t first_fpr_v;
+ uint32_t last_fpr_v;
- uint32_t gpr_flags;
- };
+ uint32_t gpr_flags;
+ };
- struct QReg
- {
- uint8_t bytes[16];
- };
+ struct QReg {
+ uint8_t bytes[16];
+ };
- struct FPU
- {
- union {
- uint32_t s[32];
- uint64_t d[32];
- QReg q[16]; // the 128-bit NEON registers
- } floats;
- uint32_t fpscr;
- };
+ struct FPU {
+ union {
+ uint32_t s[32];
+ uint64_t d[32];
+ QReg q[16]; // the 128-bit NEON registers
+ } floats;
+ uint32_t fpscr;
+ };
- uint32_t m_gpr_arm[k_num_gpr_registers_arm];
- RegInfo m_reg_info;
- FPU m_fpr;
+ uint32_t m_gpr_arm[k_num_gpr_registers_arm];
+ RegInfo m_reg_info;
+ FPU m_fpr;
- // Debug register info for hardware breakpoints and watchpoints management.
- struct DREG
- {
- lldb::addr_t address; // Breakpoint/watchpoint address value.
- lldb::addr_t hit_addr; // Address at which last watchpoint trigger exception occurred.
- lldb::addr_t real_addr; // Address value that should cause target to stop.
- uint32_t control; // Breakpoint/watchpoint control value.
- uint32_t refcount; // Serves as enable/disable and refernce counter.
- };
+ // Debug register info for hardware breakpoints and watchpoints management.
+ struct DREG {
+ lldb::addr_t address; // Breakpoint/watchpoint address value.
+ lldb::addr_t hit_addr; // Address at which last watchpoint trigger exception
+ // occurred.
+ lldb::addr_t real_addr; // Address value that should cause target to stop.
+ uint32_t control; // Breakpoint/watchpoint control value.
+ uint32_t refcount; // Serves as enable/disable and refernce counter.
+ };
- struct DREG m_hbr_regs[16]; // Arm native linux hardware breakpoints
- struct DREG m_hwp_regs[16]; // Arm native linux hardware watchpoints
+ struct DREG m_hbr_regs[16]; // Arm native linux hardware breakpoints
+ struct DREG m_hwp_regs[16]; // Arm native linux hardware watchpoints
- uint32_t m_max_hwp_supported;
- uint32_t m_max_hbp_supported;
- bool m_refresh_hwdebug_info;
+ uint32_t m_max_hwp_supported;
+ uint32_t m_max_hbp_supported;
+ bool m_refresh_hwdebug_info;
- bool
- IsGPR(unsigned reg) const;
+ bool IsGPR(unsigned reg) const;
- bool
- IsFPR(unsigned reg) const;
+ bool IsFPR(unsigned reg) const;
- Error
- ReadHardwareDebugInfo();
+ Error ReadHardwareDebugInfo();
- Error
- WriteHardwareDebugRegs(int hwbType, int hwb_index);
+ Error WriteHardwareDebugRegs(int hwbType, int hwb_index);
- uint32_t
- CalculateFprOffset(const RegisterInfo* reg_info) const;
- };
+ uint32_t CalculateFprOffset(const RegisterInfo *reg_info) const;
+};
} // namespace process_linux
} // namespace lldb_private
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
index 9489f00c1afe..786778e25a24 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-#if defined (__arm64__) || defined (__aarch64__)
+#if defined(__arm64__) || defined(__aarch64__)
#include "NativeRegisterContextLinux_arm.h"
#include "NativeRegisterContextLinux_arm64.h"
@@ -25,9 +25,10 @@
#include "Plugins/Process/Linux/NativeProcessLinux.h"
#include "Plugins/Process/Linux/Procfs.h"
#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_arm64.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
-// System includes - They have to be included after framework includes because they define some
+// System includes - They have to be included after framework includes because
+// they define some
// macros which collide with variable names in other modules
#include <sys/socket.h>
// NT_PRSTATUS and NT_FPREGSET definition
@@ -42,1051 +43,931 @@ using namespace lldb_private;
using namespace lldb_private::process_linux;
// ARM64 general purpose registers.
-static const uint32_t g_gpr_regnums_arm64[] =
-{
- gpr_x0_arm64,
- gpr_x1_arm64,
- gpr_x2_arm64,
- gpr_x3_arm64,
- gpr_x4_arm64,
- gpr_x5_arm64,
- gpr_x6_arm64,
- gpr_x7_arm64,
- gpr_x8_arm64,
- gpr_x9_arm64,
- gpr_x10_arm64,
- gpr_x11_arm64,
- gpr_x12_arm64,
- gpr_x13_arm64,
- gpr_x14_arm64,
- gpr_x15_arm64,
- gpr_x16_arm64,
- gpr_x17_arm64,
- gpr_x18_arm64,
- gpr_x19_arm64,
- gpr_x20_arm64,
- gpr_x21_arm64,
- gpr_x22_arm64,
- gpr_x23_arm64,
- gpr_x24_arm64,
- gpr_x25_arm64,
- gpr_x26_arm64,
- gpr_x27_arm64,
- gpr_x28_arm64,
- gpr_fp_arm64,
- gpr_lr_arm64,
- gpr_sp_arm64,
- gpr_pc_arm64,
- gpr_cpsr_arm64,
+static const uint32_t g_gpr_regnums_arm64[] = {
+ gpr_x0_arm64, gpr_x1_arm64, gpr_x2_arm64, gpr_x3_arm64,
+ gpr_x4_arm64, gpr_x5_arm64, gpr_x6_arm64, gpr_x7_arm64,
+ gpr_x8_arm64, gpr_x9_arm64, gpr_x10_arm64, gpr_x11_arm64,
+ gpr_x12_arm64, gpr_x13_arm64, gpr_x14_arm64, gpr_x15_arm64,
+ gpr_x16_arm64, gpr_x17_arm64, gpr_x18_arm64, gpr_x19_arm64,
+ gpr_x20_arm64, gpr_x21_arm64, gpr_x22_arm64, gpr_x23_arm64,
+ gpr_x24_arm64, gpr_x25_arm64, gpr_x26_arm64, gpr_x27_arm64,
+ gpr_x28_arm64, gpr_fp_arm64, gpr_lr_arm64, gpr_sp_arm64,
+ gpr_pc_arm64, gpr_cpsr_arm64, gpr_w0_arm64, gpr_w1_arm64,
+ gpr_w2_arm64, gpr_w3_arm64, gpr_w4_arm64, gpr_w5_arm64,
+ gpr_w6_arm64, gpr_w7_arm64, gpr_w8_arm64, gpr_w9_arm64,
+ gpr_w10_arm64, gpr_w11_arm64, gpr_w12_arm64, gpr_w13_arm64,
+ gpr_w14_arm64, gpr_w15_arm64, gpr_w16_arm64, gpr_w17_arm64,
+ gpr_w18_arm64, gpr_w19_arm64, gpr_w20_arm64, gpr_w21_arm64,
+ gpr_w22_arm64, gpr_w23_arm64, gpr_w24_arm64, gpr_w25_arm64,
+ gpr_w26_arm64, gpr_w27_arm64, gpr_w28_arm64,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
-static_assert(((sizeof g_gpr_regnums_arm64 / sizeof g_gpr_regnums_arm64[0]) - 1) == k_num_gpr_registers_arm64, \
+static_assert(((sizeof g_gpr_regnums_arm64 / sizeof g_gpr_regnums_arm64[0]) -
+ 1) == k_num_gpr_registers_arm64,
"g_gpr_regnums_arm64 has wrong number of register infos");
// ARM64 floating point registers.
-static const uint32_t g_fpu_regnums_arm64[] =
-{
- fpu_v0_arm64,
- fpu_v1_arm64,
- fpu_v2_arm64,
- fpu_v3_arm64,
- fpu_v4_arm64,
- fpu_v5_arm64,
- fpu_v6_arm64,
- fpu_v7_arm64,
- fpu_v8_arm64,
- fpu_v9_arm64,
- fpu_v10_arm64,
- fpu_v11_arm64,
- fpu_v12_arm64,
- fpu_v13_arm64,
- fpu_v14_arm64,
- fpu_v15_arm64,
- fpu_v16_arm64,
- fpu_v17_arm64,
- fpu_v18_arm64,
- fpu_v19_arm64,
- fpu_v20_arm64,
- fpu_v21_arm64,
- fpu_v22_arm64,
- fpu_v23_arm64,
- fpu_v24_arm64,
- fpu_v25_arm64,
- fpu_v26_arm64,
- fpu_v27_arm64,
- fpu_v28_arm64,
- fpu_v29_arm64,
- fpu_v30_arm64,
- fpu_v31_arm64,
- fpu_fpsr_arm64,
- fpu_fpcr_arm64,
+static const uint32_t g_fpu_regnums_arm64[] = {
+ fpu_v0_arm64, fpu_v1_arm64, fpu_v2_arm64, fpu_v3_arm64,
+ fpu_v4_arm64, fpu_v5_arm64, fpu_v6_arm64, fpu_v7_arm64,
+ fpu_v8_arm64, fpu_v9_arm64, fpu_v10_arm64, fpu_v11_arm64,
+ fpu_v12_arm64, fpu_v13_arm64, fpu_v14_arm64, fpu_v15_arm64,
+ fpu_v16_arm64, fpu_v17_arm64, fpu_v18_arm64, fpu_v19_arm64,
+ fpu_v20_arm64, fpu_v21_arm64, fpu_v22_arm64, fpu_v23_arm64,
+ fpu_v24_arm64, fpu_v25_arm64, fpu_v26_arm64, fpu_v27_arm64,
+ fpu_v28_arm64, fpu_v29_arm64, fpu_v30_arm64, fpu_v31_arm64,
+ fpu_s0_arm64, fpu_s1_arm64, fpu_s2_arm64, fpu_s3_arm64,
+ fpu_s4_arm64, fpu_s5_arm64, fpu_s6_arm64, fpu_s7_arm64,
+ fpu_s8_arm64, fpu_s9_arm64, fpu_s10_arm64, fpu_s11_arm64,
+ fpu_s12_arm64, fpu_s13_arm64, fpu_s14_arm64, fpu_s15_arm64,
+ fpu_s16_arm64, fpu_s17_arm64, fpu_s18_arm64, fpu_s19_arm64,
+ fpu_s20_arm64, fpu_s21_arm64, fpu_s22_arm64, fpu_s23_arm64,
+ fpu_s24_arm64, fpu_s25_arm64, fpu_s26_arm64, fpu_s27_arm64,
+ fpu_s28_arm64, fpu_s29_arm64, fpu_s30_arm64, fpu_s31_arm64,
+
+ fpu_d0_arm64, fpu_d1_arm64, fpu_d2_arm64, fpu_d3_arm64,
+ fpu_d4_arm64, fpu_d5_arm64, fpu_d6_arm64, fpu_d7_arm64,
+ fpu_d8_arm64, fpu_d9_arm64, fpu_d10_arm64, fpu_d11_arm64,
+ fpu_d12_arm64, fpu_d13_arm64, fpu_d14_arm64, fpu_d15_arm64,
+ fpu_d16_arm64, fpu_d17_arm64, fpu_d18_arm64, fpu_d19_arm64,
+ fpu_d20_arm64, fpu_d21_arm64, fpu_d22_arm64, fpu_d23_arm64,
+ fpu_d24_arm64, fpu_d25_arm64, fpu_d26_arm64, fpu_d27_arm64,
+ fpu_d28_arm64, fpu_d29_arm64, fpu_d30_arm64, fpu_d31_arm64,
+ fpu_fpsr_arm64, fpu_fpcr_arm64,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
-static_assert(((sizeof g_fpu_regnums_arm64 / sizeof g_fpu_regnums_arm64[0]) - 1) == k_num_fpr_registers_arm64, \
+static_assert(((sizeof g_fpu_regnums_arm64 / sizeof g_fpu_regnums_arm64[0]) -
+ 1) == k_num_fpr_registers_arm64,
"g_fpu_regnums_arm64 has wrong number of register infos");
namespace {
- // Number of register sets provided by this context.
- enum
- {
- k_num_register_sets = 2
- };
+// Number of register sets provided by this context.
+enum { k_num_register_sets = 2 };
}
// Register sets for ARM64.
-static const RegisterSet
-g_reg_sets_arm64[k_num_register_sets] =
-{
- { "General Purpose Registers", "gpr", k_num_gpr_registers_arm64, g_gpr_regnums_arm64 },
- { "Floating Point Registers", "fpu", k_num_fpr_registers_arm64, g_fpu_regnums_arm64 }
-};
-
-NativeRegisterContextLinux*
-NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(const ArchSpec& target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx)
-{
- Log *log = ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_REGISTERS);
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::arm:
- return new NativeRegisterContextLinux_arm(target_arch, native_thread, concrete_frame_idx);
- case llvm::Triple::aarch64:
- return new NativeRegisterContextLinux_arm64(target_arch, native_thread, concrete_frame_idx);
- default:
- if (log)
- log->Printf("NativeRegisterContextLinux::%s() have no register context for architecture: %s\n", __FUNCTION__,
- target_arch.GetTriple().getArchName().str().c_str());
- return nullptr;
- }
+static const RegisterSet g_reg_sets_arm64[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_arm64,
+ g_gpr_regnums_arm64},
+ {"Floating Point Registers", "fpu", k_num_fpr_registers_arm64,
+ g_fpu_regnums_arm64}};
+
+NativeRegisterContextLinux *
+NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx) {
+ Log *log = ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_REGISTERS);
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::arm:
+ return new NativeRegisterContextLinux_arm(target_arch, native_thread,
+ concrete_frame_idx);
+ case llvm::Triple::aarch64:
+ return new NativeRegisterContextLinux_arm64(target_arch, native_thread,
+ concrete_frame_idx);
+ default:
+ if (log)
+ log->Printf("NativeRegisterContextLinux::%s() have no register context "
+ "for architecture: %s\n",
+ __FUNCTION__,
+ target_arch.GetTriple().getArchName().str().c_str());
+ return nullptr;
+ }
+}
+
+NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx)
+ : NativeRegisterContextLinux(native_thread, concrete_frame_idx,
+ new RegisterInfoPOSIX_arm64(target_arch)) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::aarch64:
+ m_reg_info.num_registers = k_num_registers_arm64;
+ m_reg_info.num_gpr_registers = k_num_gpr_registers_arm64;
+ m_reg_info.num_fpr_registers = k_num_fpr_registers_arm64;
+ m_reg_info.last_gpr = k_last_gpr_arm64;
+ m_reg_info.first_fpr = k_first_fpr_arm64;
+ m_reg_info.last_fpr = k_last_fpr_arm64;
+ m_reg_info.first_fpr_v = fpu_v0_arm64;
+ m_reg_info.last_fpr_v = fpu_v31_arm64;
+ m_reg_info.gpr_flags = gpr_cpsr_arm64;
+ break;
+ default:
+ assert(false && "Unhandled target architecture.");
+ break;
+ }
+
+ ::memset(&m_fpr, 0, sizeof(m_fpr));
+ ::memset(&m_gpr_arm64, 0, sizeof(m_gpr_arm64));
+ ::memset(&m_hwp_regs, 0, sizeof(m_hwp_regs));
+
+ // 16 is just a maximum value, query hardware for actual watchpoint count
+ m_max_hwp_supported = 16;
+ m_max_hbp_supported = 16;
+ m_refresh_hwdebug_info = true;
+}
+
+uint32_t NativeRegisterContextLinux_arm64::GetRegisterSetCount() const {
+ return k_num_register_sets;
}
-NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64 (const ArchSpec& target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx) :
- NativeRegisterContextLinux (native_thread, concrete_frame_idx, new RegisterContextLinux_arm64(target_arch))
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::aarch64:
- m_reg_info.num_registers = k_num_registers_arm64;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_arm64;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_arm64;
- m_reg_info.last_gpr = k_last_gpr_arm64;
- m_reg_info.first_fpr = k_first_fpr_arm64;
- m_reg_info.last_fpr = k_last_fpr_arm64;
- m_reg_info.first_fpr_v = fpu_v0_arm64;
- m_reg_info.last_fpr_v = fpu_v31_arm64;
- m_reg_info.gpr_flags = gpr_cpsr_arm64;
- break;
- default:
- assert(false && "Unhandled target architecture.");
- break;
- }
-
- ::memset(&m_fpr, 0, sizeof (m_fpr));
- ::memset(&m_gpr_arm64, 0, sizeof (m_gpr_arm64));
- ::memset(&m_hwp_regs, 0, sizeof (m_hwp_regs));
+const RegisterSet *
+NativeRegisterContextLinux_arm64::GetRegisterSet(uint32_t set_index) const {
+ if (set_index < k_num_register_sets)
+ return &g_reg_sets_arm64[set_index];
- // 16 is just a maximum value, query hardware for actual watchpoint count
- m_max_hwp_supported = 16;
- m_max_hbp_supported = 16;
- m_refresh_hwdebug_info = true;
+ return nullptr;
}
-uint32_t
-NativeRegisterContextLinux_arm64::GetRegisterSetCount () const
-{
- return k_num_register_sets;
+uint32_t NativeRegisterContextLinux_arm64::GetUserRegisterCount() const {
+ uint32_t count = 0;
+ for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index)
+ count += g_reg_sets_arm64[set_index].num_registers;
+ return count;
}
-const RegisterSet *
-NativeRegisterContextLinux_arm64::GetRegisterSet (uint32_t set_index) const
-{
- if (set_index < k_num_register_sets)
- return &g_reg_sets_arm64[set_index];
-
- return nullptr;
-}
+Error NativeRegisterContextLinux_arm64::ReadRegister(
+ const RegisterInfo *reg_info, RegisterValue &reg_value) {
+ Error error;
-uint32_t
-NativeRegisterContextLinux_arm64::GetUserRegisterCount() const
-{
- uint32_t count = 0;
- for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index)
- count += g_reg_sets_arm64[set_index].num_registers;
- return count;
-}
+ if (!reg_info) {
+ error.SetErrorString("reg_info NULL");
+ return error;
+ }
-Error
-NativeRegisterContextLinux_arm64::ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value)
-{
- Error error;
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (!reg_info)
- {
- error.SetErrorString ("reg_info NULL");
- return error;
+ if (IsFPR(reg)) {
+ error = ReadFPR();
+ if (error.Fail())
+ return error;
+ } 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];
}
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ error = ReadRegisterRaw(full_reg, reg_value);
- if (IsFPR(reg))
- {
- error = ReadFPR();
- if (error.Fail())
- return error;
- }
- 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];
- }
-
- error = ReadRegisterRaw(full_reg, reg_value);
-
- if (error.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))
- reg_value.SetUInt64(reg_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 (reg_value.GetByteSize() > reg_info->byte_size)
- reg_value.SetType(reg_info);
- }
- return error;
+ if (error.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))
+ reg_value.SetUInt64(reg_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 (reg_value.GetByteSize() > reg_info->byte_size)
+ reg_value.SetType(reg_info);
}
+ return error;
+ }
- // Get pointer to m_fpr variable and set the data from it.
- uint32_t fpr_offset = CalculateFprOffset(reg_info);
- assert (fpr_offset < sizeof m_fpr);
- uint8_t *src = (uint8_t *)&m_fpr + fpr_offset;
- reg_value.SetFromMemoryData(reg_info, src, reg_info->byte_size, eByteOrderLittle, error);
+ // Get pointer to m_fpr variable and set the data from it.
+ uint32_t fpr_offset = CalculateFprOffset(reg_info);
+ assert(fpr_offset < sizeof m_fpr);
+ uint8_t *src = (uint8_t *)&m_fpr + fpr_offset;
+ reg_value.SetFromMemoryData(reg_info, src, reg_info->byte_size,
+ eByteOrderLittle, error);
- return error;
+ return error;
}
-Error
-NativeRegisterContextLinux_arm64::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value)
-{
- if (!reg_info)
- return Error ("reg_info NULL");
-
- const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (reg_index == LLDB_INVALID_REGNUM)
- return Error ("no lldb regnum for %s", reg_info && reg_info->name ? reg_info->name : "<unknown register>");
-
- if (IsGPR(reg_index))
- return WriteRegisterRaw(reg_index, reg_value);
-
- if (IsFPR(reg_index))
- {
- // Get pointer to m_fpr variable and set the data to it.
- uint32_t fpr_offset = CalculateFprOffset(reg_info);
- assert (fpr_offset < sizeof m_fpr);
- uint8_t *dst = (uint8_t *)&m_fpr + fpr_offset;
- switch (reg_info->byte_size)
- {
- case 2:
- *(uint16_t *)dst = reg_value.GetAsUInt16();
- break;
- case 4:
- *(uint32_t *)dst = reg_value.GetAsUInt32();
- break;
- case 8:
- *(uint64_t *)dst = reg_value.GetAsUInt64();
- break;
- default:
- assert(false && "Unhandled data size.");
- return Error ("unhandled register data size %" PRIu32, reg_info->byte_size);
- }
-
- Error error = WriteFPR();
- if (error.Fail())
- return error;
-
- return Error ();
- }
+Error NativeRegisterContextLinux_arm64::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &reg_value) {
+ if (!reg_info)
+ return Error("reg_info NULL");
- return Error ("failed - register wasn't recognized to be a GPR or an FPR, write strategy unknown");
-}
+ const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
+ if (reg_index == LLDB_INVALID_REGNUM)
+ return Error("no lldb regnum for %s", reg_info && reg_info->name
+ ? reg_info->name
+ : "<unknown register>");
-Error
-NativeRegisterContextLinux_arm64::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
-{
- Error error;
+ if (IsGPR(reg_index))
+ return WriteRegisterRaw(reg_index, reg_value);
- data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
- if (!data_sp)
- return Error ("failed to allocate DataBufferHeap instance of size %" PRIu64, REG_CONTEXT_SIZE);
+ if (IsFPR(reg_index)) {
+ // Get pointer to m_fpr variable and set the data to it.
+ uint32_t fpr_offset = CalculateFprOffset(reg_info);
+ assert(fpr_offset < sizeof m_fpr);
+ uint8_t *dst = (uint8_t *)&m_fpr + fpr_offset;
+ switch (reg_info->byte_size) {
+ case 2:
+ *(uint16_t *)dst = reg_value.GetAsUInt16();
+ break;
+ case 4:
+ *(uint32_t *)dst = reg_value.GetAsUInt32();
+ break;
+ case 8:
+ *(uint64_t *)dst = reg_value.GetAsUInt64();
+ break;
+ default:
+ assert(false && "Unhandled data size.");
+ return Error("unhandled register data size %" PRIu32,
+ reg_info->byte_size);
+ }
- error = ReadGPR();
+ Error error = WriteFPR();
if (error.Fail())
- return error;
+ return error;
- error = ReadFPR();
- if (error.Fail())
- return error;
+ return Error();
+ }
- uint8_t *dst = data_sp->GetBytes ();
- if (dst == nullptr)
- {
- error.SetErrorStringWithFormat ("DataBufferHeap instance of size %" PRIu64 " returned a null pointer", REG_CONTEXT_SIZE);
- return error;
- }
+ return Error("failed - register wasn't recognized to be a GPR or an FPR, "
+ "write strategy unknown");
+}
- ::memcpy (dst, &m_gpr_arm64, GetGPRSize());
- dst += GetGPRSize();
- ::memcpy (dst, &m_fpr, sizeof(m_fpr));
+Error NativeRegisterContextLinux_arm64::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ Error error;
+ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (!data_sp)
+ return Error("failed to allocate DataBufferHeap instance of size %" PRIu64,
+ REG_CONTEXT_SIZE);
+
+ error = ReadGPR();
+ if (error.Fail())
return error;
-}
-Error
-NativeRegisterContextLinux_arm64::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
-{
- Error error;
+ error = ReadFPR();
+ if (error.Fail())
+ return error;
- if (!data_sp)
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s invalid data_sp provided", __FUNCTION__);
- return error;
- }
+ uint8_t *dst = data_sp->GetBytes();
+ if (dst == nullptr) {
+ error.SetErrorStringWithFormat("DataBufferHeap instance of size %" PRIu64
+ " returned a null pointer",
+ REG_CONTEXT_SIZE);
+ return error;
+ }
- if (data_sp->GetByteSize () != REG_CONTEXT_SIZE)
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s data_sp contained mismatched data size, expected %" PRIu64 ", actual %" PRIu64, __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize ());
- return error;
- }
+ ::memcpy(dst, &m_gpr_arm64, GetGPRSize());
+ dst += GetGPRSize();
+ ::memcpy(dst, &m_fpr, sizeof(m_fpr));
+ return error;
+}
- uint8_t *src = data_sp->GetBytes ();
- if (src == nullptr)
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s DataBuffer::GetBytes() returned a null pointer", __FUNCTION__);
- return error;
- }
- ::memcpy (&m_gpr_arm64, src, GetRegisterInfoInterface ().GetGPRSize ());
+Error NativeRegisterContextLinux_arm64::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ Error error;
- error = WriteGPR();
- if (error.Fail())
- return error;
+ if (!data_sp) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_x86_64::%s invalid data_sp provided",
+ __FUNCTION__);
+ return error;
+ }
- src += GetRegisterInfoInterface ().GetGPRSize ();
- ::memcpy (&m_fpr, src, sizeof(m_fpr));
+ if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_x86_64::%s data_sp contained mismatched "
+ "data size, expected %" PRIu64 ", actual %" PRIu64,
+ __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize());
+ return error;
+ }
+
+ uint8_t *src = data_sp->GetBytes();
+ if (src == nullptr) {
+ error.SetErrorStringWithFormat("NativeRegisterContextLinux_x86_64::%s "
+ "DataBuffer::GetBytes() returned a null "
+ "pointer",
+ __FUNCTION__);
+ return error;
+ }
+ ::memcpy(&m_gpr_arm64, src, GetRegisterInfoInterface().GetGPRSize());
- error = WriteFPR();
- if (error.Fail())
- return error;
+ error = WriteGPR();
+ if (error.Fail())
+ return error;
+ src += GetRegisterInfoInterface().GetGPRSize();
+ ::memcpy(&m_fpr, src, sizeof(m_fpr));
+
+ error = WriteFPR();
+ if (error.Fail())
return error;
+
+ return error;
}
-bool
-NativeRegisterContextLinux_arm64::IsGPR(unsigned reg) const
-{
- return reg <= m_reg_info.last_gpr; // GPR's come first.
+bool NativeRegisterContextLinux_arm64::IsGPR(unsigned reg) const {
+ return reg <= m_reg_info.last_gpr; // GPR's come first.
}
-bool
-NativeRegisterContextLinux_arm64::IsFPR(unsigned reg) const
-{
- return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
+bool NativeRegisterContextLinux_arm64::IsFPR(unsigned reg) const {
+ return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
}
uint32_t
-NativeRegisterContextLinux_arm64::SetHardwareBreakpoint (lldb::addr_t addr, size_t size)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
-
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
-
- Error error;
-
- // Read hardware breakpoint and watchpoint information.
- error = ReadHardwareDebugInfo ();
-
- if (error.Fail())
- return LLDB_INVALID_INDEX32;
-
- uint32_t control_value = 0, bp_index = 0;
-
- // Check if size has a valid hardware breakpoint length.
- if (size != 4)
- return LLDB_INVALID_INDEX32; // Invalid size for a AArch64 hardware breakpoint
-
- // Check 4-byte alignment for hardware breakpoint target address.
- if (addr & 0x03)
- return LLDB_INVALID_INDEX32; // Invalid address, should be 4-byte aligned.
-
- // Setup control value
- control_value = 0;
- control_value |= ((1 << size) - 1) << 5;
- control_value |= (2 << 1) | 1;
-
- // Iterate over stored hardware breakpoints
- // Find a free bp_index or update reference count if duplicate.
- bp_index = LLDB_INVALID_INDEX32;
- for (uint32_t i = 0; i < m_max_hbp_supported; i++)
- {
- if ((m_hbr_regs[i].control & 1) == 0)
- {
- bp_index = i; // Mark last free slot
- }
- else if (m_hbr_regs[i].address == addr && m_hbr_regs[i].control == control_value)
- {
- bp_index = i; // Mark duplicate index
- break; // Stop searching here
- }
+NativeRegisterContextLinux_arm64::SetHardwareBreakpoint(lldb::addr_t addr,
+ size_t size) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
+
+ Error error;
+
+ // Read hardware breakpoint and watchpoint information.
+ error = ReadHardwareDebugInfo();
+
+ if (error.Fail())
+ return LLDB_INVALID_INDEX32;
+
+ uint32_t control_value = 0, bp_index = 0;
+
+ // Check if size has a valid hardware breakpoint length.
+ if (size != 4)
+ return LLDB_INVALID_INDEX32; // Invalid size for a AArch64 hardware
+ // breakpoint
+
+ // Check 4-byte alignment for hardware breakpoint target address.
+ if (addr & 0x03)
+ return LLDB_INVALID_INDEX32; // Invalid address, should be 4-byte aligned.
+
+ // Setup control value
+ control_value = 0;
+ control_value |= ((1 << size) - 1) << 5;
+ control_value |= (2 << 1) | 1;
+
+ // Iterate over stored hardware breakpoints
+ // Find a free bp_index or update reference count if duplicate.
+ bp_index = LLDB_INVALID_INDEX32;
+ for (uint32_t i = 0; i < m_max_hbp_supported; i++) {
+ if ((m_hbr_regs[i].control & 1) == 0) {
+ bp_index = i; // Mark last free slot
+ } else if (m_hbr_regs[i].address == addr &&
+ m_hbr_regs[i].control == control_value) {
+ bp_index = i; // Mark duplicate index
+ break; // Stop searching here
}
+ }
- if (bp_index == LLDB_INVALID_INDEX32)
- return LLDB_INVALID_INDEX32;
+ if (bp_index == LLDB_INVALID_INDEX32)
+ return LLDB_INVALID_INDEX32;
- // Add new or update existing breakpoint
- if ((m_hbr_regs[bp_index].control & 1) == 0)
- {
- m_hbr_regs[bp_index].address = addr;
- m_hbr_regs[bp_index].control = control_value;
- m_hbr_regs[bp_index].refcount = 1;
+ // Add new or update existing breakpoint
+ if ((m_hbr_regs[bp_index].control & 1) == 0) {
+ m_hbr_regs[bp_index].address = addr;
+ m_hbr_regs[bp_index].control = control_value;
+ m_hbr_regs[bp_index].refcount = 1;
- // PTRACE call to set corresponding hardware breakpoint register.
- error = WriteHardwareDebugRegs(eDREGTypeBREAK);
+ // PTRACE call to set corresponding hardware breakpoint register.
+ error = WriteHardwareDebugRegs(eDREGTypeBREAK);
- if (error.Fail())
- {
- m_hbr_regs[bp_index].address = 0;
- m_hbr_regs[bp_index].control &= ~1;
- m_hbr_regs[bp_index].refcount = 0;
+ if (error.Fail()) {
+ m_hbr_regs[bp_index].address = 0;
+ m_hbr_regs[bp_index].control &= ~1;
+ m_hbr_regs[bp_index].refcount = 0;
- return LLDB_INVALID_INDEX32;
- }
+ return LLDB_INVALID_INDEX32;
}
- else
- m_hbr_regs[bp_index].refcount++;
+ } else
+ m_hbr_regs[bp_index].refcount++;
- return bp_index;
+ return bp_index;
}
-bool
-NativeRegisterContextLinux_arm64::ClearHardwareBreakpoint (uint32_t hw_idx)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+bool NativeRegisterContextLinux_arm64::ClearHardwareBreakpoint(
+ uint32_t hw_idx) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
- Error error;
+ Error error;
- // Read hardware breakpoint and watchpoint information.
- error = ReadHardwareDebugInfo ();
+ // Read hardware breakpoint and watchpoint information.
+ error = ReadHardwareDebugInfo();
- if (error.Fail())
- return false;
+ if (error.Fail())
+ return false;
- if (hw_idx >= m_max_hbp_supported)
- return false;
+ if (hw_idx >= m_max_hbp_supported)
+ return false;
- // Update reference count if multiple references.
- if (m_hbr_regs[hw_idx].refcount > 1)
- {
- m_hbr_regs[hw_idx].refcount--;
- return true;
- }
- else if (m_hbr_regs[hw_idx].refcount == 1)
- {
- // Create a backup we can revert to in case of failure.
- lldb::addr_t tempAddr = m_hbr_regs[hw_idx].address;
- uint32_t tempControl = m_hbr_regs[hw_idx].control;
- uint32_t tempRefCount = m_hbr_regs[hw_idx].refcount;
-
- m_hbr_regs[hw_idx].control &= ~1;
- m_hbr_regs[hw_idx].address = 0;
- m_hbr_regs[hw_idx].refcount = 0;
-
- // PTRACE call to clear corresponding hardware breakpoint register.
- WriteHardwareDebugRegs(eDREGTypeBREAK);
-
- if (error.Fail())
- {
- m_hbr_regs[hw_idx].control = tempControl;
- m_hbr_regs[hw_idx].address = tempAddr;
- m_hbr_regs[hw_idx].refcount = tempRefCount;
-
- return false;
- }
-
- return true;
+ // Update reference count if multiple references.
+ if (m_hbr_regs[hw_idx].refcount > 1) {
+ m_hbr_regs[hw_idx].refcount--;
+ return true;
+ } else if (m_hbr_regs[hw_idx].refcount == 1) {
+ // Create a backup we can revert to in case of failure.
+ lldb::addr_t tempAddr = m_hbr_regs[hw_idx].address;
+ uint32_t tempControl = m_hbr_regs[hw_idx].control;
+ uint32_t tempRefCount = m_hbr_regs[hw_idx].refcount;
+
+ m_hbr_regs[hw_idx].control &= ~1;
+ m_hbr_regs[hw_idx].address = 0;
+ m_hbr_regs[hw_idx].refcount = 0;
+
+ // PTRACE call to clear corresponding hardware breakpoint register.
+ WriteHardwareDebugRegs(eDREGTypeBREAK);
+
+ if (error.Fail()) {
+ m_hbr_regs[hw_idx].control = tempControl;
+ m_hbr_regs[hw_idx].address = tempAddr;
+ m_hbr_regs[hw_idx].refcount = tempRefCount;
+
+ return false;
}
- return false;
+ return true;
+ }
+
+ return false;
}
-uint32_t
-NativeRegisterContextLinux_arm64::NumSupportedHardwareWatchpoints ()
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+uint32_t NativeRegisterContextLinux_arm64::NumSupportedHardwareWatchpoints() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
- Error error;
+ Error error;
- // Read hardware breakpoint and watchpoint information.
- error = ReadHardwareDebugInfo ();
+ // Read hardware breakpoint and watchpoint information.
+ error = ReadHardwareDebugInfo();
- if (error.Fail())
- return 0;
+ if (error.Fail())
+ return 0;
- return m_max_hwp_supported;
+ return m_max_hwp_supported;
}
-uint32_t
-NativeRegisterContextLinux_arm64::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+uint32_t NativeRegisterContextLinux_arm64::SetHardwareWatchpoint(
+ lldb::addr_t addr, size_t size, uint32_t watch_flags) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
-
- Error error;
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
- // Read hardware breakpoint and watchpoint information.
- error = ReadHardwareDebugInfo ();
+ Error error;
- if (error.Fail())
- return LLDB_INVALID_INDEX32;
-
- uint32_t control_value = 0, wp_index = 0;
- lldb::addr_t real_addr = addr;
-
- // Check if we are setting watchpoint other than read/write/access
- // Also update watchpoint flag to match AArch64 write-read bit configuration.
- switch (watch_flags)
- {
- case 1:
- watch_flags = 2;
- break;
- case 2:
- watch_flags = 1;
- break;
- case 3:
- break;
- default:
- return LLDB_INVALID_INDEX32;
- }
+ // Read hardware breakpoint and watchpoint information.
+ error = ReadHardwareDebugInfo();
- // Check if size has a valid hardware watchpoint length.
- if (size != 1 && size != 2 && size != 4 && size != 8)
- return LLDB_INVALID_INDEX32;
-
- // Check 8-byte alignment for hardware watchpoint target address.
- // Below is a hack to recalculate address and size in order to
- // make sure we can watch non 8-byte alligned addresses as well.
- if (addr & 0x07)
- {
- uint8_t watch_mask = (addr & 0x07) + size;
-
- if (watch_mask > 0x08)
- return LLDB_INVALID_INDEX32;
- else if (watch_mask <= 0x02)
- size = 2;
- else if (watch_mask <= 0x04)
- size = 4;
- else
- size = 8;
-
- addr = addr & (~0x07);
- }
+ if (error.Fail())
+ return LLDB_INVALID_INDEX32;
- // Setup control value
- control_value = watch_flags << 3;
- control_value |= ((1 << size) - 1) << 5;
- control_value |= (2 << 1) | 1;
-
- // Iterate over stored watchpoints
- // Find a free wp_index or update reference count if duplicate.
- wp_index = LLDB_INVALID_INDEX32;
- for (uint32_t i = 0; i < m_max_hwp_supported; i++)
- {
- if ((m_hwp_regs[i].control & 1) == 0)
- {
- wp_index = i; // Mark last free slot
- }
- else if (m_hwp_regs[i].address == addr && m_hwp_regs[i].control == control_value)
- {
- wp_index = i; // Mark duplicate index
- break; // Stop searching here
- }
- }
+ uint32_t control_value = 0, wp_index = 0;
+ lldb::addr_t real_addr = addr;
- if (wp_index == LLDB_INVALID_INDEX32)
- return LLDB_INVALID_INDEX32;
-
- // Add new or update existing watchpoint
- if ((m_hwp_regs[wp_index].control & 1) == 0)
- {
- // Update watchpoint in local cache
- m_hwp_regs[wp_index].real_addr = real_addr;
- m_hwp_regs[wp_index].address = addr;
- m_hwp_regs[wp_index].control = control_value;
- m_hwp_regs[wp_index].refcount = 1;
-
- // PTRACE call to set corresponding watchpoint register.
- error = WriteHardwareDebugRegs(eDREGTypeWATCH);
-
- if (error.Fail())
- {
- m_hwp_regs[wp_index].address = 0;
- m_hwp_regs[wp_index].control &= ~1;
- m_hwp_regs[wp_index].refcount = 0;
-
- return LLDB_INVALID_INDEX32;
- }
- }
+ // Check if we are setting watchpoint other than read/write/access
+ // Also update watchpoint flag to match AArch64 write-read bit configuration.
+ switch (watch_flags) {
+ case 1:
+ watch_flags = 2;
+ break;
+ case 2:
+ watch_flags = 1;
+ break;
+ case 3:
+ break;
+ default:
+ return LLDB_INVALID_INDEX32;
+ }
+
+ // Check if size has a valid hardware watchpoint length.
+ if (size != 1 && size != 2 && size != 4 && size != 8)
+ return LLDB_INVALID_INDEX32;
+
+ // Check 8-byte alignment for hardware watchpoint target address.
+ // Below is a hack to recalculate address and size in order to
+ // make sure we can watch non 8-byte alligned addresses as well.
+ if (addr & 0x07) {
+ uint8_t watch_mask = (addr & 0x07) + size;
+
+ if (watch_mask > 0x08)
+ return LLDB_INVALID_INDEX32;
+ else if (watch_mask <= 0x02)
+ size = 2;
+ else if (watch_mask <= 0x04)
+ size = 4;
else
- m_hwp_regs[wp_index].refcount++;
+ size = 8;
+
+ addr = addr & (~0x07);
+ }
+
+ // Setup control value
+ control_value = watch_flags << 3;
+ control_value |= ((1 << size) - 1) << 5;
+ control_value |= (2 << 1) | 1;
+
+ // Iterate over stored watchpoints and find a free wp_index
+ wp_index = LLDB_INVALID_INDEX32;
+ for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
+ if ((m_hwp_regs[i].control & 1) == 0) {
+ wp_index = i; // Mark last free slot
+ } else if (m_hwp_regs[i].address == addr) {
+ return LLDB_INVALID_INDEX32; // We do not support duplicate watchpoints.
+ }
+ }
+
+ if (wp_index == LLDB_INVALID_INDEX32)
+ return LLDB_INVALID_INDEX32;
+
+ // Update watchpoint in local cache
+ m_hwp_regs[wp_index].real_addr = real_addr;
+ m_hwp_regs[wp_index].address = addr;
+ m_hwp_regs[wp_index].control = control_value;
+
+ // PTRACE call to set corresponding watchpoint register.
+ error = WriteHardwareDebugRegs(eDREGTypeWATCH);
+
+ if (error.Fail()) {
+ m_hwp_regs[wp_index].address = 0;
+ m_hwp_regs[wp_index].control &= ~1;
- return wp_index;
+ return LLDB_INVALID_INDEX32;
+ }
+
+ return wp_index;
}
-bool
-NativeRegisterContextLinux_arm64::ClearHardwareWatchpoint (uint32_t wp_index)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+bool NativeRegisterContextLinux_arm64::ClearHardwareWatchpoint(
+ uint32_t wp_index) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
- Error error;
+ Error error;
- // Read hardware breakpoint and watchpoint information.
- error = ReadHardwareDebugInfo ();
+ // Read hardware breakpoint and watchpoint information.
+ error = ReadHardwareDebugInfo();
- if (error.Fail())
- return false;
+ if (error.Fail())
+ return false;
- if (wp_index >= m_max_hwp_supported)
- return false;
+ if (wp_index >= m_max_hwp_supported)
+ return false;
- // Update reference count if multiple references.
- if (m_hwp_regs[wp_index].refcount > 1)
- {
- m_hwp_regs[wp_index].refcount--;
- return true;
- }
- else if (m_hwp_regs[wp_index].refcount == 1)
- {
- // Create a backup we can revert to in case of failure.
- lldb::addr_t tempAddr = m_hwp_regs[wp_index].address;
- uint32_t tempControl = m_hwp_regs[wp_index].control;
- uint32_t tempRefCount = m_hwp_regs[wp_index].refcount;
-
- // Update watchpoint in local cache
- m_hwp_regs[wp_index].control &= ~1;
- m_hwp_regs[wp_index].address = 0;
- m_hwp_regs[wp_index].refcount = 0;
-
- // Ptrace call to update hardware debug registers
- error = WriteHardwareDebugRegs(eDREGTypeWATCH);
-
- if (error.Fail())
- {
- m_hwp_regs[wp_index].control = tempControl;
- m_hwp_regs[wp_index].address = tempAddr;
- m_hwp_regs[wp_index].refcount = tempRefCount;
-
- return false;
- }
-
- return true;
- }
+ // Create a backup we can revert to in case of failure.
+ lldb::addr_t tempAddr = m_hwp_regs[wp_index].address;
+ uint32_t tempControl = m_hwp_regs[wp_index].control;
+
+ // Update watchpoint in local cache
+ m_hwp_regs[wp_index].control &= ~1;
+ m_hwp_regs[wp_index].address = 0;
+
+ // Ptrace call to update hardware debug registers
+ error = WriteHardwareDebugRegs(eDREGTypeWATCH);
+
+ if (error.Fail()) {
+ m_hwp_regs[wp_index].control = tempControl;
+ m_hwp_regs[wp_index].address = tempAddr;
return false;
+ }
+
+ return true;
}
-Error
-NativeRegisterContextLinux_arm64::ClearAllHardwareWatchpoints ()
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+Error NativeRegisterContextLinux_arm64::ClearAllHardwareWatchpoints() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
- Error error;
+ Error error;
- // Read hardware breakpoint and watchpoint information.
- error = ReadHardwareDebugInfo ();
+ // Read hardware breakpoint and watchpoint information.
+ error = ReadHardwareDebugInfo();
- if (error.Fail())
- return error;
+ if (error.Fail())
+ return error;
- lldb::addr_t tempAddr = 0;
- uint32_t tempControl = 0, tempRefCount = 0;
-
- for (uint32_t i = 0; i < m_max_hwp_supported; i++)
- {
- if (m_hwp_regs[i].control & 0x01)
- {
- // Create a backup we can revert to in case of failure.
- tempAddr = m_hwp_regs[i].address;
- tempControl = m_hwp_regs[i].control;
- tempRefCount = m_hwp_regs[i].refcount;
-
- // Clear watchpoints in local cache
- m_hwp_regs[i].control &= ~1;
- m_hwp_regs[i].address = 0;
- m_hwp_regs[i].refcount = 0;
-
- // Ptrace call to update hardware debug registers
- error = WriteHardwareDebugRegs(eDREGTypeWATCH);
-
- if (error.Fail())
- {
- m_hwp_regs[i].control = tempControl;
- m_hwp_regs[i].address = tempAddr;
- m_hwp_regs[i].refcount = tempRefCount;
-
- return error;
- }
- }
+ lldb::addr_t tempAddr = 0;
+ uint32_t tempControl = 0, tempRefCount = 0;
+
+ for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
+ if (m_hwp_regs[i].control & 0x01) {
+ // Create a backup we can revert to in case of failure.
+ tempAddr = m_hwp_regs[i].address;
+ tempControl = m_hwp_regs[i].control;
+
+ // Clear watchpoints in local cache
+ m_hwp_regs[i].control &= ~1;
+ m_hwp_regs[i].address = 0;
+
+ // Ptrace call to update hardware debug registers
+ error = WriteHardwareDebugRegs(eDREGTypeWATCH);
+
+ if (error.Fail()) {
+ m_hwp_regs[i].control = tempControl;
+ m_hwp_regs[i].address = tempAddr;
+
+ return error;
+ }
}
+ }
- return Error();
+ return Error();
}
uint32_t
-NativeRegisterContextLinux_arm64::GetWatchpointSize(uint32_t wp_index)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
-
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
- switch ((m_hwp_regs[wp_index].control >> 5) & 0xff)
- {
- case 0x01:
- return 1;
- case 0x03:
- return 2;
- case 0x0f:
- return 4;
- case 0xff:
- return 8;
- default:
- return 0;
- }
+NativeRegisterContextLinux_arm64::GetWatchpointSize(uint32_t wp_index) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
+ switch ((m_hwp_regs[wp_index].control >> 5) & 0xff) {
+ case 0x01:
+ return 1;
+ case 0x03:
+ return 2;
+ case 0x0f:
+ return 4;
+ case 0xff:
+ return 8;
+ default:
+ return 0;
+ }
+}
+bool NativeRegisterContextLinux_arm64::WatchpointIsEnabled(uint32_t wp_index) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
+
+ if ((m_hwp_regs[wp_index].control & 0x1) == 0x1)
+ return true;
+ else
+ return false;
}
-bool
-NativeRegisterContextLinux_arm64::WatchpointIsEnabled(uint32_t wp_index)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
+Error NativeRegisterContextLinux_arm64::GetWatchpointHitIndex(
+ uint32_t &wp_index, lldb::addr_t trap_addr) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if ((m_hwp_regs[wp_index].control & 0x1) == 0x1)
- return true;
- else
- return false;
-}
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
-Error
-NativeRegisterContextLinux_arm64::GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+ uint32_t watch_size;
+ lldb::addr_t watch_addr;
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
-
- uint32_t watch_size;
- lldb::addr_t watch_addr;
-
- for (wp_index = 0; wp_index < m_max_hwp_supported; ++wp_index)
- {
- watch_size = GetWatchpointSize (wp_index);
- watch_addr = m_hwp_regs[wp_index].address;
-
- if (m_hwp_regs[wp_index].refcount >= 1 && WatchpointIsEnabled(wp_index)
- && trap_addr >= watch_addr && trap_addr < watch_addr + watch_size)
- {
- m_hwp_regs[wp_index].hit_addr = trap_addr;
- return Error();
- }
+ for (wp_index = 0; wp_index < m_max_hwp_supported; ++wp_index) {
+ watch_size = GetWatchpointSize(wp_index);
+ watch_addr = m_hwp_regs[wp_index].address;
+
+ if (WatchpointIsEnabled(wp_index) && trap_addr >= watch_addr &&
+ trap_addr < watch_addr + watch_size) {
+ m_hwp_regs[wp_index].hit_addr = trap_addr;
+ return Error();
}
+ }
- wp_index = LLDB_INVALID_INDEX32;
- return Error();
+ wp_index = LLDB_INVALID_INDEX32;
+ return Error();
}
lldb::addr_t
-NativeRegisterContextLinux_arm64::GetWatchpointAddress (uint32_t wp_index)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+NativeRegisterContextLinux_arm64::GetWatchpointAddress(uint32_t wp_index) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
- if (wp_index >= m_max_hwp_supported)
- return LLDB_INVALID_ADDRESS;
+ if (wp_index >= m_max_hwp_supported)
+ return LLDB_INVALID_ADDRESS;
- if (WatchpointIsEnabled(wp_index))
- return m_hwp_regs[wp_index].real_addr;
- else
- return LLDB_INVALID_ADDRESS;
+ if (WatchpointIsEnabled(wp_index))
+ return m_hwp_regs[wp_index].real_addr;
+ else
+ return LLDB_INVALID_ADDRESS;
}
lldb::addr_t
-NativeRegisterContextLinux_arm64::GetWatchpointHitAddress (uint32_t wp_index)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+NativeRegisterContextLinux_arm64::GetWatchpointHitAddress(uint32_t wp_index) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
+ if (log)
+ log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
- if (wp_index >= m_max_hwp_supported)
- return LLDB_INVALID_ADDRESS;
+ if (wp_index >= m_max_hwp_supported)
+ return LLDB_INVALID_ADDRESS;
- if (WatchpointIsEnabled(wp_index))
- return m_hwp_regs[wp_index].hit_addr;
- else
- return LLDB_INVALID_ADDRESS;
+ if (WatchpointIsEnabled(wp_index))
+ return m_hwp_regs[wp_index].hit_addr;
+ else
+ return LLDB_INVALID_ADDRESS;
}
-Error
-NativeRegisterContextLinux_arm64::ReadHardwareDebugInfo()
-{
- if (!m_refresh_hwdebug_info)
- {
- return Error();
- }
-
- ::pid_t tid = m_thread.GetID();
+Error NativeRegisterContextLinux_arm64::ReadHardwareDebugInfo() {
+ if (!m_refresh_hwdebug_info) {
+ return Error();
+ }
- int regset = NT_ARM_HW_WATCH;
- struct iovec ioVec;
- struct user_hwdebug_state dreg_state;
- Error error;
+ ::pid_t tid = m_thread.GetID();
- ioVec.iov_base = &dreg_state;
- ioVec.iov_len = sizeof (dreg_state);
- error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, &regset, &ioVec, ioVec.iov_len);
+ int regset = NT_ARM_HW_WATCH;
+ struct iovec ioVec;
+ struct user_hwdebug_state dreg_state;
+ Error error;
- if (error.Fail())
- return error;
+ ioVec.iov_base = &dreg_state;
+ ioVec.iov_len = sizeof(dreg_state);
+ error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, &regset,
+ &ioVec, ioVec.iov_len);
- m_max_hwp_supported = dreg_state.dbg_info & 0xff;
+ if (error.Fail())
+ return error;
- regset = NT_ARM_HW_BREAK;
- error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, &regset, &ioVec, ioVec.iov_len);
+ m_max_hwp_supported = dreg_state.dbg_info & 0xff;
- if (error.Fail())
- return error;
-
- m_max_hbp_supported = dreg_state.dbg_info & 0xff;
- m_refresh_hwdebug_info = false;
+ regset = NT_ARM_HW_BREAK;
+ error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, &regset,
+ &ioVec, ioVec.iov_len);
+ if (error.Fail())
return error;
+
+ m_max_hbp_supported = dreg_state.dbg_info & 0xff;
+ m_refresh_hwdebug_info = false;
+
+ return error;
}
-Error
-NativeRegisterContextLinux_arm64::WriteHardwareDebugRegs(int hwbType)
-{
- struct iovec ioVec;
- struct user_hwdebug_state dreg_state;
- Error error;
-
- memset (&dreg_state, 0, sizeof (dreg_state));
- ioVec.iov_base = &dreg_state;
-
- if (hwbType == eDREGTypeWATCH)
- {
- hwbType = NT_ARM_HW_WATCH;
- ioVec.iov_len = sizeof (dreg_state.dbg_info) + sizeof (dreg_state.pad)
- + (sizeof (dreg_state.dbg_regs [0]) * m_max_hwp_supported);
-
- for (uint32_t i = 0; i < m_max_hwp_supported; i++)
- {
- dreg_state.dbg_regs[i].addr = m_hwp_regs[i].address;
- dreg_state.dbg_regs[i].ctrl = m_hwp_regs[i].control;
- }
+Error NativeRegisterContextLinux_arm64::WriteHardwareDebugRegs(int hwbType) {
+ struct iovec ioVec;
+ struct user_hwdebug_state dreg_state;
+ Error error;
+
+ memset(&dreg_state, 0, sizeof(dreg_state));
+ ioVec.iov_base = &dreg_state;
+
+ if (hwbType == eDREGTypeWATCH) {
+ hwbType = NT_ARM_HW_WATCH;
+ ioVec.iov_len = sizeof(dreg_state.dbg_info) + sizeof(dreg_state.pad) +
+ (sizeof(dreg_state.dbg_regs[0]) * m_max_hwp_supported);
+
+ for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
+ dreg_state.dbg_regs[i].addr = m_hwp_regs[i].address;
+ dreg_state.dbg_regs[i].ctrl = m_hwp_regs[i].control;
}
- else
- {
- hwbType = NT_ARM_HW_BREAK;
- ioVec.iov_len = sizeof (dreg_state.dbg_info) + sizeof (dreg_state.pad)
- + (sizeof (dreg_state.dbg_regs [0]) * m_max_hbp_supported);
-
- for (uint32_t i = 0; i < m_max_hbp_supported; i++)
- {
- dreg_state.dbg_regs[i].addr = m_hbr_regs[i].address;
- dreg_state.dbg_regs[i].ctrl = m_hbr_regs[i].control;
- }
+ } else {
+ hwbType = NT_ARM_HW_BREAK;
+ ioVec.iov_len = sizeof(dreg_state.dbg_info) + sizeof(dreg_state.pad) +
+ (sizeof(dreg_state.dbg_regs[0]) * m_max_hbp_supported);
+
+ for (uint32_t i = 0; i < m_max_hbp_supported; i++) {
+ dreg_state.dbg_regs[i].addr = m_hbr_regs[i].address;
+ dreg_state.dbg_regs[i].ctrl = m_hbr_regs[i].control;
}
+ }
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(), &hwbType, &ioVec, ioVec.iov_len);
+ return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(),
+ &hwbType, &ioVec, ioVec.iov_len);
}
-Error
-NativeRegisterContextLinux_arm64::DoReadRegisterValue(uint32_t offset,
- const char* reg_name,
- uint32_t size,
- RegisterValue &value)
-{
- Error error;
- if (offset > sizeof(struct user_pt_regs))
- {
- uintptr_t offset = offset - sizeof(struct user_pt_regs);
- if (offset > sizeof(struct user_fpsimd_state))
- {
- error.SetErrorString("invalid offset value");
- return error;
- }
- elf_fpregset_t regs;
- int regset = NT_FPREGSET;
- struct iovec ioVec;
-
- ioVec.iov_base = &regs;
- ioVec.iov_len = sizeof regs;
- error = NativeProcessLinux::PtraceWrapper(
- PTRACE_GETREGSET, m_thread.GetID(), &regset, &ioVec, sizeof regs);
- if (error.Success())
- {
- ArchSpec arch;
- if (m_thread.GetProcess()->GetArchitecture(arch))
- value.SetBytes((void *)(((unsigned char *)(&regs)) + offset), 16, arch.GetByteOrder());
- else
- error.SetErrorString("failed to get architecture");
- }
+Error NativeRegisterContextLinux_arm64::DoReadRegisterValue(
+ uint32_t offset, const char *reg_name, uint32_t size,
+ RegisterValue &value) {
+ Error error;
+ if (offset > sizeof(struct user_pt_regs)) {
+ uintptr_t offset = offset - sizeof(struct user_pt_regs);
+ if (offset > sizeof(struct user_fpsimd_state)) {
+ error.SetErrorString("invalid offset value");
+ return error;
}
- else
- {
- elf_gregset_t regs;
- int regset = NT_PRSTATUS;
- struct iovec ioVec;
-
- ioVec.iov_base = &regs;
- ioVec.iov_len = sizeof regs;
- error = NativeProcessLinux::PtraceWrapper(
- PTRACE_GETREGSET, m_thread.GetID(), &regset, &ioVec, sizeof regs);
- if (error.Success())
- {
- ArchSpec arch;
- if (m_thread.GetProcess()->GetArchitecture(arch))
- value.SetBytes((void *)(((unsigned char *)(regs)) + offset), 8, arch.GetByteOrder());
- else
- error.SetErrorString("failed to get architecture");
- }
+ elf_fpregset_t regs;
+ int regset = NT_FPREGSET;
+ struct iovec ioVec;
+
+ ioVec.iov_base = &regs;
+ ioVec.iov_len = sizeof regs;
+ error = NativeProcessLinux::PtraceWrapper(
+ PTRACE_GETREGSET, m_thread.GetID(), &regset, &ioVec, sizeof regs);
+ if (error.Success()) {
+ ArchSpec arch;
+ if (m_thread.GetProcess()->GetArchitecture(arch))
+ value.SetBytes((void *)(((unsigned char *)(&regs)) + offset), 16,
+ arch.GetByteOrder());
+ else
+ error.SetErrorString("failed to get architecture");
}
- return error;
-}
+ } else {
+ elf_gregset_t regs;
+ int regset = NT_PRSTATUS;
+ struct iovec ioVec;
-Error
-NativeRegisterContextLinux_arm64::DoWriteRegisterValue(uint32_t offset,
- const char* reg_name,
- const RegisterValue &value)
-{
- Error error;
- ::pid_t tid = m_thread.GetID();
- if (offset > sizeof(struct user_pt_regs))
- {
- uintptr_t offset = offset - sizeof(struct user_pt_regs);
- if (offset > sizeof(struct user_fpsimd_state))
- {
- error.SetErrorString("invalid offset value");
- return error;
- }
- elf_fpregset_t regs;
- int regset = NT_FPREGSET;
- struct iovec ioVec;
-
- ioVec.iov_base = &regs;
- ioVec.iov_len = sizeof regs;
- error = NativeProcessLinux::PtraceWrapper( PTRACE_GETREGSET, tid, &regset, &ioVec, sizeof regs);
-
- if (error.Success())
- {
- ::memcpy((void *)(((unsigned char *)(&regs)) + offset), value.GetBytes(), 16);
- error = NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, tid, &regset, &ioVec, sizeof regs);
- }
+ ioVec.iov_base = &regs;
+ ioVec.iov_len = sizeof regs;
+ error = NativeProcessLinux::PtraceWrapper(
+ PTRACE_GETREGSET, m_thread.GetID(), &regset, &ioVec, sizeof regs);
+ if (error.Success()) {
+ ArchSpec arch;
+ if (m_thread.GetProcess()->GetArchitecture(arch))
+ value.SetBytes((void *)(((unsigned char *)(regs)) + offset), 8,
+ arch.GetByteOrder());
+ else
+ error.SetErrorString("failed to get architecture");
}
- else
- {
- elf_gregset_t regs;
- int regset = NT_PRSTATUS;
- struct iovec ioVec;
-
- ioVec.iov_base = &regs;
- ioVec.iov_len = sizeof regs;
- error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, &regset, &ioVec, sizeof regs);
- if (error.Success())
- {
- ::memcpy((void *)(((unsigned char *)(&regs)) + offset), value.GetBytes(), 8);
- error = NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, tid, &regset, &ioVec, sizeof regs);
- }
+ }
+ return error;
+}
+
+Error NativeRegisterContextLinux_arm64::DoWriteRegisterValue(
+ uint32_t offset, const char *reg_name, const RegisterValue &value) {
+ Error error;
+ ::pid_t tid = m_thread.GetID();
+ if (offset > sizeof(struct user_pt_regs)) {
+ uintptr_t offset = offset - sizeof(struct user_pt_regs);
+ if (offset > sizeof(struct user_fpsimd_state)) {
+ error.SetErrorString("invalid offset value");
+ return error;
}
- return error;
-}
+ elf_fpregset_t regs;
+ int regset = NT_FPREGSET;
+ struct iovec ioVec;
+
+ ioVec.iov_base = &regs;
+ ioVec.iov_len = sizeof regs;
+ error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, &regset,
+ &ioVec, sizeof regs);
-Error
-NativeRegisterContextLinux_arm64::DoReadGPR(void *buf, size_t buf_size)
-{
+ if (error.Success()) {
+ ::memcpy((void *)(((unsigned char *)(&regs)) + offset), value.GetBytes(),
+ 16);
+ error = NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, tid, &regset,
+ &ioVec, sizeof regs);
+ }
+ } else {
+ elf_gregset_t regs;
int regset = NT_PRSTATUS;
struct iovec ioVec;
- Error error;
- ioVec.iov_base = buf;
- ioVec.iov_len = buf_size;
- return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_thread.GetID(), &regset, &ioVec, buf_size);
+ ioVec.iov_base = &regs;
+ ioVec.iov_len = sizeof regs;
+ error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, &regset,
+ &ioVec, sizeof regs);
+ if (error.Success()) {
+ ::memcpy((void *)(((unsigned char *)(&regs)) + offset), value.GetBytes(),
+ 8);
+ error = NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, tid, &regset,
+ &ioVec, sizeof regs);
+ }
+ }
+ return error;
}
-Error
-NativeRegisterContextLinux_arm64::DoWriteGPR(void *buf, size_t buf_size)
-{
- int regset = NT_PRSTATUS;
- struct iovec ioVec;
- Error error;
+Error NativeRegisterContextLinux_arm64::DoReadGPR(void *buf, size_t buf_size) {
+ int regset = NT_PRSTATUS;
+ struct iovec ioVec;
+ Error error;
- ioVec.iov_base = buf;
- ioVec.iov_len = buf_size;
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(), &regset, &ioVec, buf_size);
+ ioVec.iov_base = buf;
+ ioVec.iov_len = buf_size;
+ return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_thread.GetID(),
+ &regset, &ioVec, buf_size);
}
-Error
-NativeRegisterContextLinux_arm64::DoReadFPR(void *buf, size_t buf_size)
-{
- int regset = NT_FPREGSET;
- struct iovec ioVec;
- Error error;
+Error NativeRegisterContextLinux_arm64::DoWriteGPR(void *buf, size_t buf_size) {
+ int regset = NT_PRSTATUS;
+ struct iovec ioVec;
+ Error error;
- ioVec.iov_base = buf;
- ioVec.iov_len = buf_size;
- return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_thread.GetID(), &regset, &ioVec, buf_size);
+ ioVec.iov_base = buf;
+ ioVec.iov_len = buf_size;
+ return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(),
+ &regset, &ioVec, buf_size);
}
-Error
-NativeRegisterContextLinux_arm64::DoWriteFPR(void *buf, size_t buf_size)
-{
- int regset = NT_FPREGSET;
- struct iovec ioVec;
- Error error;
+Error NativeRegisterContextLinux_arm64::DoReadFPR(void *buf, size_t buf_size) {
+ int regset = NT_FPREGSET;
+ struct iovec ioVec;
+ Error error;
- ioVec.iov_base = buf;
- ioVec.iov_len = buf_size;
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(), &regset, &ioVec, buf_size);
+ ioVec.iov_base = buf;
+ ioVec.iov_len = buf_size;
+ return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_thread.GetID(),
+ &regset, &ioVec, buf_size);
}
-uint32_t
-NativeRegisterContextLinux_arm64::CalculateFprOffset(const RegisterInfo* reg_info) const
-{
- return reg_info->byte_offset - GetRegisterInfoAtIndex(m_reg_info.first_fpr)->byte_offset;
+Error NativeRegisterContextLinux_arm64::DoWriteFPR(void *buf, size_t buf_size) {
+ int regset = NT_FPREGSET;
+ struct iovec ioVec;
+ Error error;
+
+ ioVec.iov_base = buf;
+ ioVec.iov_len = buf_size;
+ return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(),
+ &regset, &ioVec, buf_size);
+}
+
+uint32_t NativeRegisterContextLinux_arm64::CalculateFprOffset(
+ const RegisterInfo *reg_info) const {
+ return reg_info->byte_offset -
+ GetRegisterInfoAtIndex(m_reg_info.first_fpr)->byte_offset;
}
#endif // defined (__arm64__) || defined (__aarch64__)
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
index 4d9a9902ac3c..c46c375acfe7 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-#if defined (__arm64__) || defined (__aarch64__)
+#if defined(__arm64__) || defined(__aarch64__)
#ifndef lldb_NativeRegisterContextLinux_arm64_h
#define lldb_NativeRegisterContextLinux_arm64_h
@@ -18,180 +18,142 @@
namespace lldb_private {
namespace process_linux {
- class NativeProcessLinux;
+class NativeProcessLinux;
- class NativeRegisterContextLinux_arm64 : public NativeRegisterContextLinux
- {
- public:
- NativeRegisterContextLinux_arm64 (const ArchSpec& target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx);
+class NativeRegisterContextLinux_arm64 : public NativeRegisterContextLinux {
+public:
+ NativeRegisterContextLinux_arm64(const ArchSpec &target_arch,
+ NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx);
- uint32_t
- GetRegisterSetCount () const override;
+ uint32_t GetRegisterSetCount() const override;
- uint32_t
- GetUserRegisterCount() const override;
+ uint32_t GetUserRegisterCount() const override;
- const RegisterSet *
- GetRegisterSet (uint32_t set_index) const override;
+ const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
- Error
- ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value) override;
+ Error ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) override;
- Error
- WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value) override;
+ Error WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) override;
- Error
- ReadAllRegisterValues (lldb::DataBufferSP &data_sp) override;
+ Error ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
- Error
- WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) override;
+ Error WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- //------------------------------------------------------------------
- // Hardware breakpoints/watchpoint mangement functions
- //------------------------------------------------------------------
+ //------------------------------------------------------------------
+ // Hardware breakpoints/watchpoint mangement functions
+ //------------------------------------------------------------------
- uint32_t
- SetHardwareBreakpoint (lldb::addr_t addr, size_t size) override;
+ uint32_t SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override;
- bool
- ClearHardwareBreakpoint (uint32_t hw_idx) override;
+ bool ClearHardwareBreakpoint(uint32_t hw_idx) override;
- uint32_t
- NumSupportedHardwareWatchpoints () override;
+ uint32_t NumSupportedHardwareWatchpoints() override;
- uint32_t
- SetHardwareWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags) override;
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
+ uint32_t watch_flags) override;
- bool
- ClearHardwareWatchpoint (uint32_t hw_index) override;
+ bool ClearHardwareWatchpoint(uint32_t hw_index) override;
- Error
- ClearAllHardwareWatchpoints () override;
+ Error ClearAllHardwareWatchpoints() override;
- Error
- GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr) override;
+ Error GetWatchpointHitIndex(uint32_t &wp_index,
+ lldb::addr_t trap_addr) override;
- lldb::addr_t
- GetWatchpointHitAddress (uint32_t wp_index) override;
+ lldb::addr_t GetWatchpointHitAddress(uint32_t wp_index) override;
- lldb::addr_t
- GetWatchpointAddress (uint32_t wp_index) override;
+ lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
- uint32_t
- GetWatchpointSize(uint32_t wp_index);
+ uint32_t GetWatchpointSize(uint32_t wp_index);
- bool
- WatchpointIsEnabled(uint32_t wp_index);
+ bool WatchpointIsEnabled(uint32_t wp_index);
- // Debug register type select
- enum DREGType
- {
- eDREGTypeWATCH = 0,
- eDREGTypeBREAK
- };
+ // Debug register type select
+ enum DREGType { eDREGTypeWATCH = 0, eDREGTypeBREAK };
- protected:
- Error
- DoReadRegisterValue(uint32_t offset,
- const char* reg_name,
- uint32_t size,
- RegisterValue &value) override;
+protected:
+ Error DoReadRegisterValue(uint32_t offset, const char *reg_name,
+ uint32_t size, RegisterValue &value) override;
- Error
- DoWriteRegisterValue(uint32_t offset,
- const char* reg_name,
+ Error DoWriteRegisterValue(uint32_t offset, const char *reg_name,
const RegisterValue &value) override;
- Error
- DoReadGPR(void *buf, size_t buf_size) override;
+ Error DoReadGPR(void *buf, size_t buf_size) override;
- Error
- DoWriteGPR(void *buf, size_t buf_size) override;
+ Error DoWriteGPR(void *buf, size_t buf_size) override;
- Error
- DoReadFPR(void *buf, size_t buf_size) override;
+ Error DoReadFPR(void *buf, size_t buf_size) override;
- Error
- DoWriteFPR(void *buf, size_t buf_size) override;
+ Error DoWriteFPR(void *buf, size_t buf_size) override;
- void*
- GetGPRBuffer() override { return &m_gpr_arm64; }
+ void *GetGPRBuffer() override { return &m_gpr_arm64; }
- void*
- GetFPRBuffer() override { return &m_fpr; }
+ void *GetFPRBuffer() override { return &m_fpr; }
- size_t
- GetFPRSize() override { return sizeof(m_fpr); }
+ size_t GetFPRSize() override { return sizeof(m_fpr); }
- private:
- struct RegInfo
- {
- uint32_t num_registers;
- uint32_t num_gpr_registers;
- uint32_t num_fpr_registers;
+private:
+ struct RegInfo {
+ uint32_t num_registers;
+ uint32_t num_gpr_registers;
+ uint32_t num_fpr_registers;
- uint32_t last_gpr;
- uint32_t first_fpr;
- uint32_t last_fpr;
+ uint32_t last_gpr;
+ uint32_t first_fpr;
+ uint32_t last_fpr;
- uint32_t first_fpr_v;
- uint32_t last_fpr_v;
+ uint32_t first_fpr_v;
+ uint32_t last_fpr_v;
- uint32_t gpr_flags;
- };
+ uint32_t gpr_flags;
+ };
- // based on RegisterContextDarwin_arm64.h
- struct VReg
- {
- uint8_t bytes[16];
- };
+ // based on RegisterContextDarwin_arm64.h
+ struct VReg {
+ uint8_t bytes[16];
+ };
- // based on RegisterContextDarwin_arm64.h
- struct FPU
- {
- VReg v[32];
- uint32_t fpsr;
- uint32_t fpcr;
- };
+ // based on RegisterContextDarwin_arm64.h
+ struct FPU {
+ VReg v[32];
+ uint32_t fpsr;
+ uint32_t fpcr;
+ };
- uint64_t m_gpr_arm64[k_num_gpr_registers_arm64]; // 64-bit general purpose registers.
- RegInfo m_reg_info;
- FPU m_fpr; // floating-point registers including extended register sets.
+ uint64_t m_gpr_arm64[k_num_gpr_registers_arm64]; // 64-bit general purpose
+ // registers.
+ RegInfo m_reg_info;
+ FPU m_fpr; // floating-point registers including extended register sets.
- // Debug register info for hardware breakpoints and watchpoints management.
- struct DREG
- {
- lldb::addr_t address; // Breakpoint/watchpoint address value.
- lldb::addr_t hit_addr; // Address at which last watchpoint trigger exception occurred.
- lldb::addr_t real_addr; // Address value that should cause target to stop.
- uint32_t control; // Breakpoint/watchpoint control value.
- uint32_t refcount; // Serves as enable/disable and refernce counter.
- };
+ // Debug register info for hardware breakpoints and watchpoints management.
+ struct DREG {
+ lldb::addr_t address; // Breakpoint/watchpoint address value.
+ lldb::addr_t hit_addr; // Address at which last watchpoint trigger exception
+ // occurred.
+ lldb::addr_t real_addr; // Address value that should cause target to stop.
+ uint32_t control; // Breakpoint/watchpoint control value.
+ uint32_t refcount; // Serves as enable/disable and refernce counter.
+ };
- struct DREG m_hbr_regs[16]; // Arm native linux hardware breakpoints
- struct DREG m_hwp_regs[16]; // Arm native linux hardware watchpoints
+ struct DREG m_hbr_regs[16]; // Arm native linux hardware breakpoints
+ struct DREG m_hwp_regs[16]; // Arm native linux hardware watchpoints
- uint32_t m_max_hwp_supported;
- uint32_t m_max_hbp_supported;
- bool m_refresh_hwdebug_info;
+ uint32_t m_max_hwp_supported;
+ uint32_t m_max_hbp_supported;
+ bool m_refresh_hwdebug_info;
- bool
- IsGPR(unsigned reg) const;
+ bool IsGPR(unsigned reg) const;
- bool
- IsFPR(unsigned reg) const;
+ bool IsFPR(unsigned reg) const;
- Error
- ReadHardwareDebugInfo();
+ Error ReadHardwareDebugInfo();
- Error
- WriteHardwareDebugRegs(int hwbType);
+ Error WriteHardwareDebugRegs(int hwbType);
- uint32_t
- CalculateFprOffset(const RegisterInfo* reg_info) const;
- };
+ uint32_t CalculateFprOffset(const RegisterInfo *reg_info) const;
+};
} // namespace process_linux
} // namespace lldb_private
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
index 892ce4e24afc..c050a2ec0cc6 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-#if defined (__mips__)
+#if defined(__mips__)
#include "NativeRegisterContextLinux_mips64.h"
@@ -15,58 +15,50 @@
// C++ Includes
// Other libraries and framework includes
+#include "Plugins/Process/Linux/NativeProcessLinux.h"
+#include "Plugins/Process/Linux/Procfs.h"
+#include "Plugins/Process/Utility/RegisterContextLinux_mips.h"
+#include "Plugins/Process/Utility/RegisterContextLinux_mips64.h"
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/EmulateInstruction.h"
#include "lldb/Core/Error.h"
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Log.h"
-#include "lldb/Core/DataBufferHeap.h"
-#include "lldb/Host/HostInfo.h"
+#include "lldb/Core/RegisterValue.h"
#include "lldb/Host/Host.h"
-#include "lldb/Core/EmulateInstruction.h"
+#include "lldb/Host/HostInfo.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-private-enumerations.h"
-#include "Plugins/Process/Linux/NativeProcessLinux.h"
-#include "Plugins/Process/Linux/Procfs.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_mips64.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_mips.h"
#define NT_MIPS_MSA 0x600
#define CONFIG5_FRE (1 << 8)
#define SR_FR (1 << 26)
#define NUM_REGISTERS 32
-#include <sys/ptrace.h>
#include <asm/ptrace.h>
+#include <sys/ptrace.h>
#ifndef PTRACE_GET_WATCH_REGS
-enum pt_watch_style
-{
- pt_watch_style_mips32,
- pt_watch_style_mips64
-};
-struct mips32_watch_regs
-{
- uint32_t watchlo[8];
- uint16_t watchhi[8];
- uint16_t watch_masks[8];
- uint32_t num_valid;
+enum pt_watch_style { pt_watch_style_mips32, pt_watch_style_mips64 };
+struct mips32_watch_regs {
+ uint32_t watchlo[8];
+ uint16_t watchhi[8];
+ uint16_t watch_masks[8];
+ uint32_t num_valid;
} __attribute__((aligned(8)));
-struct mips64_watch_regs
-{
- uint64_t watchlo[8];
- uint16_t watchhi[8];
- uint16_t watch_masks[8];
- uint32_t num_valid;
+struct mips64_watch_regs {
+ uint64_t watchlo[8];
+ uint16_t watchhi[8];
+ uint16_t watch_masks[8];
+ uint32_t num_valid;
} __attribute__((aligned(8)));
-struct pt_watch_regs
-{
- enum pt_watch_style style;
- union
- {
- struct mips32_watch_regs mips32;
- struct mips64_watch_regs mips64;
- };
+struct pt_watch_regs {
+ enum pt_watch_style style;
+ union {
+ struct mips32_watch_regs mips32;
+ struct mips64_watch_regs mips64;
+ };
};
#define PTRACE_GET_WATCH_REGS 0xd0
@@ -77,7 +69,7 @@ struct pt_watch_regs
#define R (1 << 1)
#define I (1 << 2)
-#define IRW (I | R | W)
+#define IRW (I | R | W)
struct pt_watch_regs default_watch_regs;
@@ -88,1240 +80,998 @@ using namespace lldb_private::process_linux;
// Private namespace.
// ----------------------------------------------------------------------------
-namespace
-{
- // mips general purpose registers.
- const uint32_t
- g_gp_regnums_mips[] =
- {
- gpr_zero_mips,
- gpr_r1_mips,
- gpr_r2_mips,
- gpr_r3_mips,
- gpr_r4_mips,
- gpr_r5_mips,
- gpr_r6_mips,
- gpr_r7_mips,
- gpr_r8_mips,
- gpr_r9_mips,
- gpr_r10_mips,
- gpr_r11_mips,
- gpr_r12_mips,
- gpr_r13_mips,
- gpr_r14_mips,
- gpr_r15_mips,
- gpr_r16_mips,
- gpr_r17_mips,
- gpr_r18_mips,
- gpr_r19_mips,
- gpr_r20_mips,
- gpr_r21_mips,
- gpr_r22_mips,
- gpr_r23_mips,
- gpr_r24_mips,
- gpr_r25_mips,
- gpr_r26_mips,
- gpr_r27_mips,
- gpr_gp_mips,
- gpr_sp_mips,
- gpr_r30_mips,
- gpr_ra_mips,
- gpr_sr_mips,
- gpr_mullo_mips,
- gpr_mulhi_mips,
- gpr_badvaddr_mips,
- gpr_cause_mips,
- gpr_pc_mips,
- gpr_config5_mips,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
- };
-
- static_assert((sizeof(g_gp_regnums_mips) / sizeof(g_gp_regnums_mips[0])) - 1 == k_num_gpr_registers_mips,
- "g_gp_regnums_mips has wrong number of register infos");
-
- // mips floating point registers.
- const uint32_t
- g_fp_regnums_mips[] =
- {
- fpr_f0_mips,
- fpr_f1_mips,
- fpr_f2_mips,
- fpr_f3_mips,
- fpr_f4_mips,
- fpr_f5_mips,
- fpr_f6_mips,
- fpr_f7_mips,
- fpr_f8_mips,
- fpr_f9_mips,
- fpr_f10_mips,
- fpr_f11_mips,
- fpr_f12_mips,
- fpr_f13_mips,
- fpr_f14_mips,
- fpr_f15_mips,
- fpr_f16_mips,
- fpr_f17_mips,
- fpr_f18_mips,
- fpr_f19_mips,
- fpr_f20_mips,
- fpr_f21_mips,
- fpr_f22_mips,
- fpr_f23_mips,
- fpr_f24_mips,
- fpr_f25_mips,
- fpr_f26_mips,
- fpr_f27_mips,
- fpr_f28_mips,
- fpr_f29_mips,
- fpr_f30_mips,
- fpr_f31_mips,
- fpr_fcsr_mips,
- fpr_fir_mips,
- fpr_config5_mips,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
- };
-
- static_assert((sizeof(g_fp_regnums_mips) / sizeof(g_fp_regnums_mips[0])) - 1 == k_num_fpr_registers_mips,
- "g_fp_regnums_mips has wrong number of register infos");
-
- // mips MSA registers.
- const uint32_t
- g_msa_regnums_mips[] =
- {
- msa_w0_mips,
- msa_w1_mips,
- msa_w2_mips,
- msa_w3_mips,
- msa_w4_mips,
- msa_w5_mips,
- msa_w6_mips,
- msa_w7_mips,
- msa_w8_mips,
- msa_w9_mips,
- msa_w10_mips,
- msa_w11_mips,
- msa_w12_mips,
- msa_w13_mips,
- msa_w14_mips,
- msa_w15_mips,
- msa_w16_mips,
- msa_w17_mips,
- msa_w18_mips,
- msa_w19_mips,
- msa_w20_mips,
- msa_w21_mips,
- msa_w22_mips,
- msa_w23_mips,
- msa_w24_mips,
- msa_w25_mips,
- msa_w26_mips,
- msa_w27_mips,
- msa_w28_mips,
- msa_w29_mips,
- msa_w30_mips,
- msa_w31_mips,
- msa_fcsr_mips,
- msa_fir_mips,
- msa_mcsr_mips,
- msa_mir_mips,
- msa_config5_mips,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
- };
-
- static_assert((sizeof(g_msa_regnums_mips) / sizeof(g_msa_regnums_mips[0])) - 1 == k_num_msa_registers_mips,
- "g_msa_regnums_mips has wrong number of register infos");
-
- // mips64 general purpose registers.
- const uint32_t
- g_gp_regnums_mips64[] =
- {
- gpr_zero_mips64,
- gpr_r1_mips64,
- gpr_r2_mips64,
- gpr_r3_mips64,
- gpr_r4_mips64,
- gpr_r5_mips64,
- gpr_r6_mips64,
- gpr_r7_mips64,
- gpr_r8_mips64,
- gpr_r9_mips64,
- gpr_r10_mips64,
- gpr_r11_mips64,
- gpr_r12_mips64,
- gpr_r13_mips64,
- gpr_r14_mips64,
- gpr_r15_mips64,
- gpr_r16_mips64,
- gpr_r17_mips64,
- gpr_r18_mips64,
- gpr_r19_mips64,
- gpr_r20_mips64,
- gpr_r21_mips64,
- gpr_r22_mips64,
- gpr_r23_mips64,
- gpr_r24_mips64,
- gpr_r25_mips64,
- gpr_r26_mips64,
- gpr_r27_mips64,
- gpr_gp_mips64,
- gpr_sp_mips64,
- gpr_r30_mips64,
- gpr_ra_mips64,
- gpr_sr_mips64,
- gpr_mullo_mips64,
- gpr_mulhi_mips64,
- gpr_badvaddr_mips64,
- gpr_cause_mips64,
- gpr_pc_mips64,
- gpr_config5_mips64,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
- };
-
- static_assert((sizeof(g_gp_regnums_mips64) / sizeof(g_gp_regnums_mips64[0])) - 1 == k_num_gpr_registers_mips64,
- "g_gp_regnums_mips64 has wrong number of register infos");
-
- // mips64 floating point registers.
- const uint32_t
- g_fp_regnums_mips64[] =
- {
- fpr_f0_mips64,
- fpr_f1_mips64,
- fpr_f2_mips64,
- fpr_f3_mips64,
- fpr_f4_mips64,
- fpr_f5_mips64,
- fpr_f6_mips64,
- fpr_f7_mips64,
- fpr_f8_mips64,
- fpr_f9_mips64,
- fpr_f10_mips64,
- fpr_f11_mips64,
- fpr_f12_mips64,
- fpr_f13_mips64,
- fpr_f14_mips64,
- fpr_f15_mips64,
- fpr_f16_mips64,
- fpr_f17_mips64,
- fpr_f18_mips64,
- fpr_f19_mips64,
- fpr_f20_mips64,
- fpr_f21_mips64,
- fpr_f22_mips64,
- fpr_f23_mips64,
- fpr_f24_mips64,
- fpr_f25_mips64,
- fpr_f26_mips64,
- fpr_f27_mips64,
- fpr_f28_mips64,
- fpr_f29_mips64,
- fpr_f30_mips64,
- fpr_f31_mips64,
- fpr_fcsr_mips64,
- fpr_fir_mips64,
- fpr_config5_mips64,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
- };
-
- static_assert((sizeof(g_fp_regnums_mips64) / sizeof(g_fp_regnums_mips64[0])) - 1 == k_num_fpr_registers_mips64,
- "g_fp_regnums_mips64 has wrong number of register infos");
-
- // mips64 MSA registers.
- const uint32_t
- g_msa_regnums_mips64[] =
- {
- msa_w0_mips64,
- msa_w1_mips64,
- msa_w2_mips64,
- msa_w3_mips64,
- msa_w4_mips64,
- msa_w5_mips64,
- msa_w6_mips64,
- msa_w7_mips64,
- msa_w8_mips64,
- msa_w9_mips64,
- msa_w10_mips64,
- msa_w11_mips64,
- msa_w12_mips64,
- msa_w13_mips64,
- msa_w14_mips64,
- msa_w15_mips64,
- msa_w16_mips64,
- msa_w17_mips64,
- msa_w18_mips64,
- msa_w19_mips64,
- msa_w20_mips64,
- msa_w21_mips64,
- msa_w22_mips64,
- msa_w23_mips64,
- msa_w24_mips64,
- msa_w25_mips64,
- msa_w26_mips64,
- msa_w27_mips64,
- msa_w28_mips64,
- msa_w29_mips64,
- msa_w30_mips64,
- msa_w31_mips64,
- msa_fcsr_mips64,
- msa_fir_mips64,
- msa_mcsr_mips64,
- msa_mir_mips64,
- msa_config5_mips64,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
- };
-
- static_assert((sizeof(g_msa_regnums_mips64) / sizeof(g_msa_regnums_mips64[0])) - 1 == k_num_msa_registers_mips64,
- "g_msa_regnums_mips64 has wrong number of register infos");
-
- // Number of register sets provided by this context.
- enum
- {
- k_num_register_sets = 3
- };
-
- // Register sets for mips.
- static const RegisterSet
- g_reg_sets_mips[k_num_register_sets] =
- {
- { "General Purpose Registers", "gpr", k_num_gpr_registers_mips, g_gp_regnums_mips },
- { "Floating Point Registers", "fpu", k_num_fpr_registers_mips, g_fp_regnums_mips },
- { "MSA Registers", "msa", k_num_msa_registers_mips, g_msa_regnums_mips }
- };
-
- // Register sets for mips64.
- static const RegisterSet
- g_reg_sets_mips64[k_num_register_sets] =
- {
- { "General Purpose Registers", "gpr", k_num_gpr_registers_mips64, g_gp_regnums_mips64 },
- { "Floating Point Registers", "fpu", k_num_fpr_registers_mips64, g_fp_regnums_mips64 },
- { "MSA Registers", "msa", k_num_msa_registers_mips64, g_msa_regnums_mips64 },
- };
+namespace {
+// mips general purpose registers.
+const uint32_t g_gp_regnums_mips[] = {
+ gpr_zero_mips, gpr_r1_mips, gpr_r2_mips, gpr_r3_mips,
+ gpr_r4_mips, gpr_r5_mips, gpr_r6_mips, gpr_r7_mips,
+ gpr_r8_mips, gpr_r9_mips, gpr_r10_mips, gpr_r11_mips,
+ gpr_r12_mips, gpr_r13_mips, gpr_r14_mips, gpr_r15_mips,
+ gpr_r16_mips, gpr_r17_mips, gpr_r18_mips, gpr_r19_mips,
+ gpr_r20_mips, gpr_r21_mips, gpr_r22_mips, gpr_r23_mips,
+ gpr_r24_mips, gpr_r25_mips, gpr_r26_mips, gpr_r27_mips,
+ gpr_gp_mips, gpr_sp_mips, gpr_r30_mips, gpr_ra_mips,
+ gpr_sr_mips, gpr_mullo_mips, gpr_mulhi_mips, gpr_badvaddr_mips,
+ gpr_cause_mips, gpr_pc_mips, gpr_config5_mips,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+
+static_assert((sizeof(g_gp_regnums_mips) / sizeof(g_gp_regnums_mips[0])) - 1 ==
+ k_num_gpr_registers_mips,
+ "g_gp_regnums_mips has wrong number of register infos");
+
+// mips floating point registers.
+const uint32_t g_fp_regnums_mips[] = {
+ fpr_f0_mips, fpr_f1_mips, fpr_f2_mips, fpr_f3_mips,
+ fpr_f4_mips, fpr_f5_mips, fpr_f6_mips, fpr_f7_mips,
+ fpr_f8_mips, fpr_f9_mips, fpr_f10_mips, fpr_f11_mips,
+ fpr_f12_mips, fpr_f13_mips, fpr_f14_mips, fpr_f15_mips,
+ fpr_f16_mips, fpr_f17_mips, fpr_f18_mips, fpr_f19_mips,
+ fpr_f20_mips, fpr_f21_mips, fpr_f22_mips, fpr_f23_mips,
+ fpr_f24_mips, fpr_f25_mips, fpr_f26_mips, fpr_f27_mips,
+ fpr_f28_mips, fpr_f29_mips, fpr_f30_mips, fpr_f31_mips,
+ fpr_fcsr_mips, fpr_fir_mips, fpr_config5_mips,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+
+static_assert((sizeof(g_fp_regnums_mips) / sizeof(g_fp_regnums_mips[0])) - 1 ==
+ k_num_fpr_registers_mips,
+ "g_fp_regnums_mips has wrong number of register infos");
+
+// mips MSA registers.
+const uint32_t g_msa_regnums_mips[] = {
+ msa_w0_mips, msa_w1_mips, msa_w2_mips, msa_w3_mips,
+ msa_w4_mips, msa_w5_mips, msa_w6_mips, msa_w7_mips,
+ msa_w8_mips, msa_w9_mips, msa_w10_mips, msa_w11_mips,
+ msa_w12_mips, msa_w13_mips, msa_w14_mips, msa_w15_mips,
+ msa_w16_mips, msa_w17_mips, msa_w18_mips, msa_w19_mips,
+ msa_w20_mips, msa_w21_mips, msa_w22_mips, msa_w23_mips,
+ msa_w24_mips, msa_w25_mips, msa_w26_mips, msa_w27_mips,
+ msa_w28_mips, msa_w29_mips, msa_w30_mips, msa_w31_mips,
+ msa_fcsr_mips, msa_fir_mips, msa_mcsr_mips, msa_mir_mips,
+ msa_config5_mips,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+
+static_assert((sizeof(g_msa_regnums_mips) / sizeof(g_msa_regnums_mips[0])) -
+ 1 ==
+ k_num_msa_registers_mips,
+ "g_msa_regnums_mips has wrong number of register infos");
+
+// mips64 general purpose registers.
+const uint32_t g_gp_regnums_mips64[] = {
+ gpr_zero_mips64, gpr_r1_mips64, gpr_r2_mips64,
+ gpr_r3_mips64, gpr_r4_mips64, gpr_r5_mips64,
+ gpr_r6_mips64, gpr_r7_mips64, gpr_r8_mips64,
+ gpr_r9_mips64, gpr_r10_mips64, gpr_r11_mips64,
+ gpr_r12_mips64, gpr_r13_mips64, gpr_r14_mips64,
+ gpr_r15_mips64, gpr_r16_mips64, gpr_r17_mips64,
+ gpr_r18_mips64, gpr_r19_mips64, gpr_r20_mips64,
+ gpr_r21_mips64, gpr_r22_mips64, gpr_r23_mips64,
+ gpr_r24_mips64, gpr_r25_mips64, gpr_r26_mips64,
+ gpr_r27_mips64, gpr_gp_mips64, gpr_sp_mips64,
+ gpr_r30_mips64, gpr_ra_mips64, gpr_sr_mips64,
+ gpr_mullo_mips64, gpr_mulhi_mips64, gpr_badvaddr_mips64,
+ gpr_cause_mips64, gpr_pc_mips64, gpr_config5_mips64,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+
+static_assert((sizeof(g_gp_regnums_mips64) / sizeof(g_gp_regnums_mips64[0])) -
+ 1 ==
+ k_num_gpr_registers_mips64,
+ "g_gp_regnums_mips64 has wrong number of register infos");
+
+// mips64 floating point registers.
+const uint32_t g_fp_regnums_mips64[] = {
+ fpr_f0_mips64, fpr_f1_mips64, fpr_f2_mips64, fpr_f3_mips64,
+ fpr_f4_mips64, fpr_f5_mips64, fpr_f6_mips64, fpr_f7_mips64,
+ fpr_f8_mips64, fpr_f9_mips64, fpr_f10_mips64, fpr_f11_mips64,
+ fpr_f12_mips64, fpr_f13_mips64, fpr_f14_mips64, fpr_f15_mips64,
+ fpr_f16_mips64, fpr_f17_mips64, fpr_f18_mips64, fpr_f19_mips64,
+ fpr_f20_mips64, fpr_f21_mips64, fpr_f22_mips64, fpr_f23_mips64,
+ fpr_f24_mips64, fpr_f25_mips64, fpr_f26_mips64, fpr_f27_mips64,
+ fpr_f28_mips64, fpr_f29_mips64, fpr_f30_mips64, fpr_f31_mips64,
+ fpr_fcsr_mips64, fpr_fir_mips64, fpr_config5_mips64,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+
+static_assert((sizeof(g_fp_regnums_mips64) / sizeof(g_fp_regnums_mips64[0])) -
+ 1 ==
+ k_num_fpr_registers_mips64,
+ "g_fp_regnums_mips64 has wrong number of register infos");
+
+// mips64 MSA registers.
+const uint32_t g_msa_regnums_mips64[] = {
+ msa_w0_mips64, msa_w1_mips64, msa_w2_mips64, msa_w3_mips64,
+ msa_w4_mips64, msa_w5_mips64, msa_w6_mips64, msa_w7_mips64,
+ msa_w8_mips64, msa_w9_mips64, msa_w10_mips64, msa_w11_mips64,
+ msa_w12_mips64, msa_w13_mips64, msa_w14_mips64, msa_w15_mips64,
+ msa_w16_mips64, msa_w17_mips64, msa_w18_mips64, msa_w19_mips64,
+ msa_w20_mips64, msa_w21_mips64, msa_w22_mips64, msa_w23_mips64,
+ msa_w24_mips64, msa_w25_mips64, msa_w26_mips64, msa_w27_mips64,
+ msa_w28_mips64, msa_w29_mips64, msa_w30_mips64, msa_w31_mips64,
+ msa_fcsr_mips64, msa_fir_mips64, msa_mcsr_mips64, msa_mir_mips64,
+ msa_config5_mips64,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+
+static_assert((sizeof(g_msa_regnums_mips64) / sizeof(g_msa_regnums_mips64[0])) -
+ 1 ==
+ k_num_msa_registers_mips64,
+ "g_msa_regnums_mips64 has wrong number of register infos");
+
+// Number of register sets provided by this context.
+enum { k_num_register_sets = 3 };
+
+// Register sets for mips.
+static const RegisterSet g_reg_sets_mips[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_mips,
+ g_gp_regnums_mips},
+ {"Floating Point Registers", "fpu", k_num_fpr_registers_mips,
+ g_fp_regnums_mips},
+ {"MSA Registers", "msa", k_num_msa_registers_mips, g_msa_regnums_mips}};
+
+// Register sets for mips64.
+static const RegisterSet g_reg_sets_mips64[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_mips64,
+ g_gp_regnums_mips64},
+ {"Floating Point Registers", "fpu", k_num_fpr_registers_mips64,
+ g_fp_regnums_mips64},
+ {"MSA Registers", "msa", k_num_msa_registers_mips64, g_msa_regnums_mips64},
+};
} // end of anonymous namespace
-NativeRegisterContextLinux*
-NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(const ArchSpec& target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx)
-{
- return new NativeRegisterContextLinux_mips64(target_arch, native_thread, concrete_frame_idx);
+NativeRegisterContextLinux *
+NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx) {
+ return new NativeRegisterContextLinux_mips64(target_arch, native_thread,
+ concrete_frame_idx);
}
-#define REG_CONTEXT_SIZE (GetRegisterInfoInterface ().GetGPRSize () + sizeof(FPR_linux_mips) + sizeof(MSA_linux_mips))
+#define REG_CONTEXT_SIZE \
+ (GetRegisterInfoInterface().GetGPRSize() + sizeof(FPR_linux_mips) + \
+ sizeof(MSA_linux_mips))
// ----------------------------------------------------------------------------
// NativeRegisterContextLinux_mips64 members.
// ----------------------------------------------------------------------------
-static RegisterInfoInterface*
-CreateRegisterInfoInterface(const ArchSpec& target_arch)
-{
- if (HostInfo::GetArchitecture().GetAddressByteSize() == 4)
- {
- // 32-bit hosts run with a RegisterContextLinux_mips context.
- return new RegisterContextLinux_mips(target_arch, NativeRegisterContextLinux_mips64::IsMSAAvailable());
- }
- else
- {
- assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
- "Register setting path assumes this is a 64-bit host");
- // mips64 hosts know how to work with 64-bit and 32-bit EXEs using the mips64 register context.
- return new RegisterContextLinux_mips64 (target_arch, NativeRegisterContextLinux_mips64::IsMSAAvailable());
- }
+static RegisterInfoInterface *
+CreateRegisterInfoInterface(const ArchSpec &target_arch) {
+ if (HostInfo::GetArchitecture().GetAddressByteSize() == 4) {
+ // 32-bit hosts run with a RegisterContextLinux_mips context.
+ return new RegisterContextLinux_mips(
+ target_arch, NativeRegisterContextLinux_mips64::IsMSAAvailable());
+ } else {
+ assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
+ "Register setting path assumes this is a 64-bit host");
+ // mips64 hosts know how to work with 64-bit and 32-bit EXEs using the
+ // mips64 register context.
+ return new RegisterContextLinux_mips64(
+ target_arch, NativeRegisterContextLinux_mips64::IsMSAAvailable());
+ }
}
-NativeRegisterContextLinux_mips64::NativeRegisterContextLinux_mips64 (const ArchSpec& target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx) :
- NativeRegisterContextLinux (native_thread, concrete_frame_idx, CreateRegisterInfoInterface(target_arch))
-{
- switch (target_arch.GetMachine ())
- {
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- m_reg_info.num_registers = k_num_registers_mips;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_mips;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_mips;
- m_reg_info.last_gpr = k_last_gpr_mips;
- m_reg_info.first_fpr = k_first_fpr_mips;
- m_reg_info.last_fpr = k_last_fpr_mips;
- m_reg_info.first_msa = k_first_msa_mips;
- m_reg_info.last_msa = k_last_msa_mips;
- break;
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el:
- m_reg_info.num_registers = k_num_registers_mips64;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_mips64;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_mips64;
- m_reg_info.last_gpr = k_last_gpr_mips64;
- m_reg_info.first_fpr = k_first_fpr_mips64;
- m_reg_info.last_fpr = k_last_fpr_mips64;
- m_reg_info.first_msa = k_first_msa_mips64;
- m_reg_info.last_msa = k_last_msa_mips64;
- break;
- default:
- assert(false && "Unhandled target architecture.");
- break;
- }
+NativeRegisterContextLinux_mips64::NativeRegisterContextLinux_mips64(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx)
+ : NativeRegisterContextLinux(native_thread, concrete_frame_idx,
+ CreateRegisterInfoInterface(target_arch)) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
+ m_reg_info.num_registers = k_num_registers_mips;
+ m_reg_info.num_gpr_registers = k_num_gpr_registers_mips;
+ m_reg_info.num_fpr_registers = k_num_fpr_registers_mips;
+ m_reg_info.last_gpr = k_last_gpr_mips;
+ m_reg_info.first_fpr = k_first_fpr_mips;
+ m_reg_info.last_fpr = k_last_fpr_mips;
+ m_reg_info.first_msa = k_first_msa_mips;
+ m_reg_info.last_msa = k_last_msa_mips;
+ break;
+ case llvm::Triple::mips64:
+ case llvm::Triple::mips64el:
+ m_reg_info.num_registers = k_num_registers_mips64;
+ m_reg_info.num_gpr_registers = k_num_gpr_registers_mips64;
+ m_reg_info.num_fpr_registers = k_num_fpr_registers_mips64;
+ m_reg_info.last_gpr = k_last_gpr_mips64;
+ m_reg_info.first_fpr = k_first_fpr_mips64;
+ m_reg_info.last_fpr = k_last_fpr_mips64;
+ m_reg_info.first_msa = k_first_msa_mips64;
+ m_reg_info.last_msa = k_last_msa_mips64;
+ break;
+ default:
+ assert(false && "Unhandled target architecture.");
+ break;
+ }
+
+ // Initialize m_iovec to point to the buffer and buffer size
+ // using the conventions of Berkeley style UIO structures, as required
+ // by PTRACE extensions.
+ m_iovec.iov_base = &m_msa;
+ m_iovec.iov_len = sizeof(MSA_linux_mips);
+
+ // init h/w watchpoint addr map
+ for (int index = 0; index <= MAX_NUM_WP; index++)
+ hw_addr_map[index] = LLDB_INVALID_ADDRESS;
+
+ ::memset(&m_gpr, 0, sizeof(GPR_linux_mips));
+ ::memset(&m_fpr, 0, sizeof(FPR_linux_mips));
+ ::memset(&m_msa, 0, sizeof(MSA_linux_mips));
+}
- // Initialize m_iovec to point to the buffer and buffer size
- // using the conventions of Berkeley style UIO structures, as required
- // by PTRACE extensions.
- m_iovec.iov_base = &m_msa;
- m_iovec.iov_len = sizeof(MSA_linux_mips);
+uint32_t NativeRegisterContextLinux_mips64::GetRegisterSetCount() const {
+ return k_num_register_sets;
+}
- // init h/w watchpoint addr map
- for (int index = 0;index <= MAX_NUM_WP; index++)
- hw_addr_map[index] = LLDB_INVALID_ADDRESS;
+lldb::addr_t NativeRegisterContextLinux_mips64::GetPCfromBreakpointLocation(
+ lldb::addr_t fail_value) {
+ Error error;
+ RegisterValue pc_value;
+ lldb::addr_t pc = fail_value;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- ::memset(&m_gpr, 0, sizeof(GPR_linux_mips));
- ::memset(&m_fpr, 0, sizeof(FPR_linux_mips));
- ::memset(&m_msa, 0, sizeof(MSA_linux_mips));
-}
+ if (log)
+ log->Printf("NativeRegisterContextLinux_mips64::%s Reading PC from "
+ "breakpoint location",
+ __FUNCTION__);
-uint32_t
-NativeRegisterContextLinux_mips64::GetRegisterSetCount () const
-{
- return k_num_register_sets;
-}
+ // PC register is at index 34 of the register array
+ const RegisterInfo *const pc_info_p = GetRegisterInfoAtIndex(gpr_pc_mips64);
+
+ error = ReadRegister(pc_info_p, pc_value);
+ if (error.Success()) {
+ pc = pc_value.GetAsUInt64();
+
+ // CAUSE register is at index 37 of the register array
+ const RegisterInfo *const cause_info_p =
+ GetRegisterInfoAtIndex(gpr_cause_mips64);
+ RegisterValue cause_value;
+
+ ReadRegister(cause_info_p, cause_value);
+
+ uint64_t cause = cause_value.GetAsUInt64();
-lldb::addr_t
-NativeRegisterContextLinux_mips64::GetPCfromBreakpointLocation (lldb::addr_t fail_value)
-{
- Error error;
- RegisterValue pc_value;
- lldb::addr_t pc = fail_value;
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
-
if (log)
- log->Printf ("NativeRegisterContextLinux_mips64::%s Reading PC from breakpoint location", __FUNCTION__);
-
- // PC register is at index 34 of the register array
- const RegisterInfo *const pc_info_p = GetRegisterInfoAtIndex (gpr_pc_mips64);
-
- error = ReadRegister (pc_info_p, pc_value);
- if (error.Success ())
- {
- pc = pc_value.GetAsUInt64 ();
-
- // CAUSE register is at index 37 of the register array
- const RegisterInfo *const cause_info_p = GetRegisterInfoAtIndex (gpr_cause_mips64);
- RegisterValue cause_value;
-
- ReadRegister (cause_info_p, cause_value);
-
- uint64_t cause = cause_value.GetAsUInt64 ();
-
- if (log)
- log->Printf ("NativeRegisterContextLinux_mips64::%s PC 0x%" PRIx64 " Cause 0x%" PRIx64, __FUNCTION__, pc, cause);
-
- /*
- * The breakpoint might be in a delay slot. In this case PC points
- * to the delayed branch instruction rather then the instruction
- * in the delay slot. If the CAUSE.BD flag is set then adjust the
- * PC based on the size of the branch instruction.
- */
- if ((cause & (1 << 31)) != 0)
- {
- lldb::addr_t branch_delay = 0;
- branch_delay = 4; // FIXME - Adjust according to size of branch instruction at PC
- pc = pc + branch_delay;
- pc_value.SetUInt64 (pc);
- WriteRegister (pc_info_p, pc_value);
-
- if (log)
- log->Printf ("NativeRegisterContextLinux_mips64::%s New PC 0x%" PRIx64, __FUNCTION__, pc);
- }
+ log->Printf("NativeRegisterContextLinux_mips64::%s PC 0x%" PRIx64
+ " Cause 0x%" PRIx64,
+ __FUNCTION__, pc, cause);
+
+ /*
+ * The breakpoint might be in a delay slot. In this case PC points
+ * to the delayed branch instruction rather then the instruction
+ * in the delay slot. If the CAUSE.BD flag is set then adjust the
+ * PC based on the size of the branch instruction.
+ */
+ if ((cause & (1 << 31)) != 0) {
+ lldb::addr_t branch_delay = 0;
+ branch_delay =
+ 4; // FIXME - Adjust according to size of branch instruction at PC
+ pc = pc + branch_delay;
+ pc_value.SetUInt64(pc);
+ WriteRegister(pc_info_p, pc_value);
+
+ if (log)
+ log->Printf("NativeRegisterContextLinux_mips64::%s New PC 0x%" PRIx64,
+ __FUNCTION__, pc);
}
+ }
- return pc;
+ return pc;
}
const RegisterSet *
-NativeRegisterContextLinux_mips64::GetRegisterSet (uint32_t set_index) const
-{
- if (set_index >= k_num_register_sets)
- return nullptr;
-
- switch (GetRegisterInfoInterface ().GetTargetArchitecture ().GetMachine ())
- {
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el:
- return &g_reg_sets_mips64[set_index];
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- return &g_reg_sets_mips[set_index];
- default:
- assert (false && "Unhandled target architecture.");
- return nullptr;
- }
+NativeRegisterContextLinux_mips64::GetRegisterSet(uint32_t set_index) const {
+ if (set_index >= k_num_register_sets)
+ return nullptr;
+ switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
+ case llvm::Triple::mips64:
+ case llvm::Triple::mips64el:
+ return &g_reg_sets_mips64[set_index];
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
+ return &g_reg_sets_mips[set_index];
+ default:
+ assert(false && "Unhandled target architecture.");
return nullptr;
+ }
+
+ return nullptr;
}
lldb_private::Error
-NativeRegisterContextLinux_mips64::ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value)
-{
- Error error;
-
- if (!reg_info)
- {
- error.SetErrorString ("reg_info NULL");
- return error;
- }
-
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
- uint8_t byte_size = reg_info->byte_size;
- if (reg == LLDB_INVALID_REGNUM)
- {
- // This is likely an internal register for lldb use only and should not be
- // directly queried.
- error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb "
- "register, cannot read directly",
- reg_info->name);
- return error;
- }
+NativeRegisterContextLinux_mips64::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) {
+ Error error;
- if (IsMSA(reg) && !IsMSAAvailable())
- {
- error.SetErrorString ("MSA not available on this processor");
- return error;
- }
+ if (!reg_info) {
+ error.SetErrorString("reg_info NULL");
+ return error;
+ }
+
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ uint8_t byte_size = reg_info->byte_size;
+ if (reg == LLDB_INVALID_REGNUM) {
+ // This is likely an internal register for lldb use only and should not be
+ // directly queried.
+ error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb "
+ "register, cannot read directly",
+ reg_info->name);
+ return error;
+ }
- if (IsMSA(reg) || IsFPR(reg))
- {
- uint8_t *src = nullptr;
- lldbassert(reg_info->byte_offset < sizeof(UserArea));
+ if (IsMSA(reg) && !IsMSAAvailable()) {
+ error.SetErrorString("MSA not available on this processor");
+ return error;
+ }
- error = ReadCP1();
+ if (IsMSA(reg) || IsFPR(reg)) {
+ uint8_t *src = nullptr;
+ lldbassert(reg_info->byte_offset < sizeof(UserArea));
- if (!error.Success())
- {
- error.SetErrorString ("failed to read co-processor 1 register");
- return error;
- }
+ error = ReadCP1();
- if (IsFPR(reg))
- {
- if (IsFR0() && (byte_size != 4))
- {
- byte_size = 4;
- uint8_t ptrace_index;
- ptrace_index = reg_info->kinds[lldb::eRegisterKindProcessPlugin];
- src = ReturnFPOffset(ptrace_index, reg_info->byte_offset);
- }
- else
- src = (uint8_t *)&m_fpr + reg_info->byte_offset - sizeof(m_gpr);
- }
- else
- src = (uint8_t *)&m_msa + reg_info->byte_offset -
- (sizeof(m_gpr) + sizeof(m_fpr));
- switch (byte_size)
- {
- case 4:
- reg_value.SetUInt32(*(uint32_t *)src);
- break;
- case 8:
- reg_value.SetUInt64(*(uint64_t *)src);
- break;
- case 16:
- reg_value.SetBytes((const void *)src, 16, GetByteOrder());
- break;
- default:
- assert(false && "Unhandled data size.");
- error.SetErrorStringWithFormat("unhandled byte size: %" PRIu32,
- reg_info->byte_size);
- break;
- }
+ if (!error.Success()) {
+ error.SetErrorString("failed to read co-processor 1 register");
+ return error;
}
- else
- {
- error = ReadRegisterRaw(reg, reg_value);
+
+ if (IsFPR(reg)) {
+ if (IsFR0() && (byte_size != 4)) {
+ byte_size = 4;
+ uint8_t ptrace_index;
+ ptrace_index = reg_info->kinds[lldb::eRegisterKindProcessPlugin];
+ src = ReturnFPOffset(ptrace_index, reg_info->byte_offset);
+ } else
+ src = (uint8_t *)&m_fpr + reg_info->byte_offset - sizeof(m_gpr);
+ } else
+ src = (uint8_t *)&m_msa + reg_info->byte_offset -
+ (sizeof(m_gpr) + sizeof(m_fpr));
+ switch (byte_size) {
+ case 4:
+ reg_value.SetUInt32(*(uint32_t *)src);
+ break;
+ case 8:
+ reg_value.SetUInt64(*(uint64_t *)src);
+ break;
+ case 16:
+ reg_value.SetBytes((const void *)src, 16, GetByteOrder());
+ break;
+ default:
+ assert(false && "Unhandled data size.");
+ error.SetErrorStringWithFormat("unhandled byte size: %" PRIu32,
+ reg_info->byte_size);
+ break;
}
+ } else {
+ error = ReadRegisterRaw(reg, reg_value);
+ }
- return error;
+ return error;
}
-lldb_private::Error
-NativeRegisterContextLinux_mips64::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value)
-{
- Error error;
+lldb_private::Error NativeRegisterContextLinux_mips64::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &reg_value) {
+ Error error;
- assert (reg_info && "reg_info is null");
+ assert(reg_info && "reg_info is null");
- const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
+ const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (reg_index == LLDB_INVALID_REGNUM)
- return Error ("no lldb regnum for %s", reg_info && reg_info->name ? reg_info->name : "<unknown register>");
+ if (reg_index == LLDB_INVALID_REGNUM)
+ return Error("no lldb regnum for %s", reg_info && reg_info->name
+ ? reg_info->name
+ : "<unknown register>");
- if (IsMSA(reg_index) && !IsMSAAvailable())
- {
- error.SetErrorString ("MSA not available on this processor");
- return error;
- }
+ if (IsMSA(reg_index) && !IsMSAAvailable()) {
+ error.SetErrorString("MSA not available on this processor");
+ return error;
+ }
- if (IsFPR(reg_index) || IsMSA(reg_index))
- {
- uint8_t *dst = nullptr;
- uint64_t *src = nullptr;
- uint8_t byte_size = reg_info->byte_size;
- lldbassert(reg_info->byte_offset < sizeof(UserArea));
-
- // Initialise the FP and MSA buffers by reading all co-processor 1 registers
- ReadCP1();
-
- if (IsFPR(reg_index))
- {
- if (IsFR0() && (byte_size != 4))
- {
- byte_size = 4;
- uint8_t ptrace_index;
- ptrace_index = reg_info->kinds[lldb::eRegisterKindProcessPlugin];
- dst = ReturnFPOffset(ptrace_index, reg_info->byte_offset);
- }
- else
- dst = (uint8_t *)&m_fpr + reg_info->byte_offset - sizeof(m_gpr);
- }
- else
- dst = (uint8_t *)&m_msa + reg_info->byte_offset -
- (sizeof(m_gpr) + sizeof(m_fpr));
- switch (byte_size)
- {
- case 4:
- *(uint32_t *)dst = reg_value.GetAsUInt32();
- break;
- case 8:
- *(uint64_t *)dst = reg_value.GetAsUInt64();
- break;
- case 16:
- src = (uint64_t *)reg_value.GetBytes();
- *(uint64_t *)dst = *src;
- *(uint64_t *)(dst + 8) = *(src + 1);
- break;
- default:
- assert(false && "Unhandled data size.");
- error.SetErrorStringWithFormat("unhandled byte size: %" PRIu32,
- reg_info->byte_size);
- break;
- }
- error = WriteCP1();
- if (!error.Success())
- {
- error.SetErrorString("failed to write co-processor 1 register");
- return error;
- }
+ if (IsFPR(reg_index) || IsMSA(reg_index)) {
+ uint8_t *dst = nullptr;
+ uint64_t *src = nullptr;
+ uint8_t byte_size = reg_info->byte_size;
+ lldbassert(reg_info->byte_offset < sizeof(UserArea));
+
+ // Initialise the FP and MSA buffers by reading all co-processor 1 registers
+ ReadCP1();
+
+ if (IsFPR(reg_index)) {
+ if (IsFR0() && (byte_size != 4)) {
+ byte_size = 4;
+ uint8_t ptrace_index;
+ ptrace_index = reg_info->kinds[lldb::eRegisterKindProcessPlugin];
+ dst = ReturnFPOffset(ptrace_index, reg_info->byte_offset);
+ } else
+ dst = (uint8_t *)&m_fpr + reg_info->byte_offset - sizeof(m_gpr);
+ } else
+ dst = (uint8_t *)&m_msa + reg_info->byte_offset -
+ (sizeof(m_gpr) + sizeof(m_fpr));
+ switch (byte_size) {
+ case 4:
+ *(uint32_t *)dst = reg_value.GetAsUInt32();
+ break;
+ case 8:
+ *(uint64_t *)dst = reg_value.GetAsUInt64();
+ break;
+ case 16:
+ src = (uint64_t *)reg_value.GetBytes();
+ *(uint64_t *)dst = *src;
+ *(uint64_t *)(dst + 8) = *(src + 1);
+ break;
+ default:
+ assert(false && "Unhandled data size.");
+ error.SetErrorStringWithFormat("unhandled byte size: %" PRIu32,
+ reg_info->byte_size);
+ break;
}
- else
- {
- error = WriteRegisterRaw(reg_index, reg_value);
+ error = WriteCP1();
+ if (!error.Success()) {
+ error.SetErrorString("failed to write co-processor 1 register");
+ return error;
}
+ } else {
+ error = WriteRegisterRaw(reg_index, reg_value);
+ }
- return error;
+ return error;
}
-Error
-NativeRegisterContextLinux_mips64::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
-{
- Error error;
+Error NativeRegisterContextLinux_mips64::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ Error error;
- data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
- if (!data_sp)
- {
- error.SetErrorStringWithFormat ("failed to allocate DataBufferHeap instance of size %" PRIu64, REG_CONTEXT_SIZE);
- return error;
- }
+ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (!data_sp) {
+ error.SetErrorStringWithFormat(
+ "failed to allocate DataBufferHeap instance of size %" PRIu64,
+ REG_CONTEXT_SIZE);
+ return error;
+ }
- error = ReadGPR();
- if (!error.Success())
- {
- error.SetErrorString ("ReadGPR() failed");
- return error;
- }
+ error = ReadGPR();
+ if (!error.Success()) {
+ error.SetErrorString("ReadGPR() failed");
+ return error;
+ }
- error = ReadCP1();
- if (!error.Success())
- {
- error.SetErrorString ("ReadCP1() failed");
- return error;
- }
+ error = ReadCP1();
+ if (!error.Success()) {
+ error.SetErrorString("ReadCP1() failed");
+ return error;
+ }
- uint8_t *dst = data_sp->GetBytes ();
- if (dst == nullptr)
- {
- error.SetErrorStringWithFormat ("DataBufferHeap instance of size %" PRIu64 " returned a null pointer", REG_CONTEXT_SIZE);
- return error;
- }
+ uint8_t *dst = data_sp->GetBytes();
+ if (dst == nullptr) {
+ error.SetErrorStringWithFormat("DataBufferHeap instance of size %" PRIu64
+ " returned a null pointer",
+ REG_CONTEXT_SIZE);
+ return error;
+ }
- ::memcpy (dst, &m_gpr, GetRegisterInfoInterface ().GetGPRSize ());
- dst += GetRegisterInfoInterface ().GetGPRSize ();
+ ::memcpy(dst, &m_gpr, GetRegisterInfoInterface().GetGPRSize());
+ dst += GetRegisterInfoInterface().GetGPRSize();
- ::memcpy (dst, &m_fpr, GetFPRSize ());
- dst += GetFPRSize ();
+ ::memcpy(dst, &m_fpr, GetFPRSize());
+ dst += GetFPRSize();
- ::memcpy (dst, &m_msa, sizeof(MSA_linux_mips));
+ ::memcpy(dst, &m_msa, sizeof(MSA_linux_mips));
- return error;
+ return error;
}
-Error
-NativeRegisterContextLinux_mips64::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
-{
- Error error;
+Error NativeRegisterContextLinux_mips64::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ Error error;
- if (!data_sp)
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_mips64::%s invalid data_sp provided", __FUNCTION__);
- return error;
- }
+ if (!data_sp) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_mips64::%s invalid data_sp provided",
+ __FUNCTION__);
+ return error;
+ }
- if (data_sp->GetByteSize () != REG_CONTEXT_SIZE)
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_mips64::%s data_sp contained mismatched data size, expected %" PRIu64 ", actual %" PRIu64, __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize ());
- return error;
- }
+ if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_mips64::%s data_sp contained mismatched "
+ "data size, expected %" PRIu64 ", actual %" PRIu64,
+ __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize());
+ return error;
+ }
+
+ uint8_t *src = data_sp->GetBytes();
+ if (src == nullptr) {
+ error.SetErrorStringWithFormat("NativeRegisterContextLinux_mips64::%s "
+ "DataBuffer::GetBytes() returned a null "
+ "pointer",
+ __FUNCTION__);
+ return error;
+ }
+ ::memcpy(&m_gpr, src, GetRegisterInfoInterface().GetGPRSize());
+ src += GetRegisterInfoInterface().GetGPRSize();
- uint8_t *src = data_sp->GetBytes ();
- if (src == nullptr)
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_mips64::%s DataBuffer::GetBytes() returned a null pointer", __FUNCTION__);
- return error;
- }
+ ::memcpy(&m_fpr, src, GetFPRSize());
+ src += GetFPRSize();
- ::memcpy (&m_gpr, src, GetRegisterInfoInterface ().GetGPRSize ());
- src += GetRegisterInfoInterface ().GetGPRSize ();
+ ::memcpy(&m_msa, src, sizeof(MSA_linux_mips));
- ::memcpy (&m_fpr, src, GetFPRSize ());
- src += GetFPRSize ();
+ error = WriteGPR();
+ if (!error.Success()) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_mips64::%s WriteGPR() failed",
+ __FUNCTION__);
+ return error;
+ }
- ::memcpy (&m_msa, src, sizeof(MSA_linux_mips));
+ error = WriteCP1();
+ if (!error.Success()) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_mips64::%s WriteCP1() failed",
+ __FUNCTION__);
+ return error;
+ }
- error = WriteGPR();
- if (!error.Success())
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_mips64::%s WriteGPR() failed", __FUNCTION__);
- return error;
- }
+ return error;
+}
- error = WriteCP1();
- if (!error.Success())
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_mips64::%s WriteCP1() failed", __FUNCTION__);
- return error;
- }
+Error NativeRegisterContextLinux_mips64::ReadCP1() {
+ Error error;
- return error;
-}
+ uint8_t *src = nullptr;
+ uint8_t *dst = nullptr;
-Error
-NativeRegisterContextLinux_mips64::ReadCP1()
-{
- Error error;
+ lldb::ByteOrder byte_order = GetByteOrder();
- uint8_t *src = nullptr;
- uint8_t *dst = nullptr;
+ bool IsBigEndian = (byte_order == lldb::eByteOrderBig);
- lldb::ByteOrder byte_order = GetByteOrder();
-
- bool IsBigEndian = (byte_order == lldb::eByteOrderBig);
-
- if (IsMSAAvailable())
- {
- error = NativeRegisterContextLinux::ReadRegisterSet(&m_iovec, sizeof(MSA_linux_mips), NT_MIPS_MSA);
- src = (uint8_t *)&m_msa + (IsBigEndian * 8);
- dst = (uint8_t *)&m_fpr;
- for ( int i = 0; i < NUM_REGISTERS; i++)
- {
- // Copy fp values from msa buffer fetched via ptrace
- *(uint64_t *) dst = *(uint64_t *) src;
- src = src + 16;
- dst = dst + 8;
- }
- m_fpr.fir = m_msa.fir;
- m_fpr.fcsr = m_msa.fcsr;
- m_fpr.config5 = m_msa.config5;
- }
- else
- {
- error = NativeRegisterContextLinux::ReadFPR();
+ if (IsMSAAvailable()) {
+ error = NativeRegisterContextLinux::ReadRegisterSet(
+ &m_iovec, sizeof(MSA_linux_mips), NT_MIPS_MSA);
+ src = (uint8_t *)&m_msa + (IsBigEndian * 8);
+ dst = (uint8_t *)&m_fpr;
+ for (int i = 0; i < NUM_REGISTERS; i++) {
+ // Copy fp values from msa buffer fetched via ptrace
+ *(uint64_t *)dst = *(uint64_t *)src;
+ src = src + 16;
+ dst = dst + 8;
}
+ m_fpr.fir = m_msa.fir;
+ m_fpr.fcsr = m_msa.fcsr;
+ m_fpr.config5 = m_msa.config5;
+ } else {
+ error = NativeRegisterContextLinux::ReadFPR();
+ }
return error;
}
uint8_t *
NativeRegisterContextLinux_mips64::ReturnFPOffset(uint8_t reg_index,
- uint32_t byte_offset)
-{
- uint8_t *fp_buffer_ptr = nullptr;
- lldb::ByteOrder byte_order = GetByteOrder();
- bool IsBigEndian = (byte_order == lldb::eByteOrderBig);
- if (reg_index % 2)
- {
- uint8_t offset_diff = (IsBigEndian) ? 8 : 4;
- fp_buffer_ptr = (uint8_t *)&m_fpr + byte_offset
- - offset_diff - sizeof(m_gpr);
- }
- else
- {
- fp_buffer_ptr = (uint8_t *)&m_fpr + byte_offset +
- 4 * (IsBigEndian) - sizeof(m_gpr);
- }
- return fp_buffer_ptr;
+ uint32_t byte_offset) {
+
+ uint8_t *fp_buffer_ptr = nullptr;
+ lldb::ByteOrder byte_order = GetByteOrder();
+ bool IsBigEndian = (byte_order == lldb::eByteOrderBig);
+ if (reg_index % 2) {
+ uint8_t offset_diff = (IsBigEndian) ? 8 : 4;
+ fp_buffer_ptr =
+ (uint8_t *)&m_fpr + byte_offset - offset_diff - sizeof(m_gpr);
+ } else {
+ fp_buffer_ptr =
+ (uint8_t *)&m_fpr + byte_offset + 4 * (IsBigEndian) - sizeof(m_gpr);
+ }
+ return fp_buffer_ptr;
}
-Error
-NativeRegisterContextLinux_mips64::WriteCP1()
-{
- Error error;
+Error NativeRegisterContextLinux_mips64::WriteCP1() {
+ Error error;
- uint8_t *src = nullptr;
- uint8_t *dst = nullptr;
+ uint8_t *src = nullptr;
+ uint8_t *dst = nullptr;
- lldb::ByteOrder byte_order = GetByteOrder();
+ lldb::ByteOrder byte_order = GetByteOrder();
- bool IsBigEndian = (byte_order == lldb::eByteOrderBig);
+ bool IsBigEndian = (byte_order == lldb::eByteOrderBig);
- if (IsMSAAvailable())
- {
- dst = (uint8_t *)&m_msa + (IsBigEndian * 8);
- src = (uint8_t *)&m_fpr;
- for (int i = 0; i < NUM_REGISTERS; i++)
- {
- // Copy fp values to msa buffer for ptrace
- *(uint64_t *) dst = *(uint64_t *) src;
- dst = dst + 16;
- src = src + 8;
- }
- m_msa.fir = m_fpr.fir;
- m_msa.fcsr = m_fpr.fcsr;
- m_msa.config5 = m_fpr.config5;
- error = NativeRegisterContextLinux::WriteRegisterSet(&m_iovec, sizeof(MSA_linux_mips), NT_MIPS_MSA);
- }
- else
- {
- error = NativeRegisterContextLinux::WriteFPR();
+ if (IsMSAAvailable()) {
+ dst = (uint8_t *)&m_msa + (IsBigEndian * 8);
+ src = (uint8_t *)&m_fpr;
+ for (int i = 0; i < NUM_REGISTERS; i++) {
+ // Copy fp values to msa buffer for ptrace
+ *(uint64_t *)dst = *(uint64_t *)src;
+ dst = dst + 16;
+ src = src + 8;
}
+ m_msa.fir = m_fpr.fir;
+ m_msa.fcsr = m_fpr.fcsr;
+ m_msa.config5 = m_fpr.config5;
+ error = NativeRegisterContextLinux::WriteRegisterSet(
+ &m_iovec, sizeof(MSA_linux_mips), NT_MIPS_MSA);
+ } else {
+ error = NativeRegisterContextLinux::WriteFPR();
+ }
- return error;
+ return error;
}
-bool
-NativeRegisterContextLinux_mips64::IsFR0()
-{
- const RegisterInfo *const reg_info_p = GetRegisterInfoAtIndex (gpr_sr_mips64);
+bool NativeRegisterContextLinux_mips64::IsFR0() {
+ const RegisterInfo *const reg_info_p = GetRegisterInfoAtIndex(gpr_sr_mips64);
- RegisterValue reg_value;
- ReadRegister (reg_info_p, reg_value);
+ RegisterValue reg_value;
+ ReadRegister(reg_info_p, reg_value);
- uint64_t value = reg_value.GetAsUInt64();
+ uint64_t value = reg_value.GetAsUInt64();
- return (!(value & SR_FR));
+ return (!(value & SR_FR));
}
-bool
-NativeRegisterContextLinux_mips64::IsFRE()
-{
- const RegisterInfo *const reg_info_p = GetRegisterInfoAtIndex (gpr_config5_mips64);
+bool NativeRegisterContextLinux_mips64::IsFRE() {
+ const RegisterInfo *const reg_info_p =
+ GetRegisterInfoAtIndex(gpr_config5_mips64);
- RegisterValue reg_value;
- ReadRegister (reg_info_p, reg_value);
+ RegisterValue reg_value;
+ ReadRegister(reg_info_p, reg_value);
- uint64_t config5 = reg_value.GetAsUInt64();
+ uint64_t config5 = reg_value.GetAsUInt64();
- return (config5 & CONFIG5_FRE);
+ return (config5 & CONFIG5_FRE);
}
-bool
-NativeRegisterContextLinux_mips64::IsFPR(uint32_t reg_index) const
-{
- return (m_reg_info.first_fpr <= reg_index && reg_index <= m_reg_info.last_fpr);
+bool NativeRegisterContextLinux_mips64::IsFPR(uint32_t reg_index) const {
+ return (m_reg_info.first_fpr <= reg_index &&
+ reg_index <= m_reg_info.last_fpr);
}
-static uint32_t
-GetWatchHi (struct pt_watch_regs *regs, uint32_t index)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (regs->style == pt_watch_style_mips32)
- return regs->mips32.watchhi[index];
- else if (regs->style == pt_watch_style_mips64)
- return regs->mips64.watchhi[index];
- if(log)
- log->Printf("Invalid watch register style");
- return 0;
+static uint32_t GetWatchHi(struct pt_watch_regs *regs, uint32_t index) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ if (regs->style == pt_watch_style_mips32)
+ return regs->mips32.watchhi[index];
+ else if (regs->style == pt_watch_style_mips64)
+ return regs->mips64.watchhi[index];
+ if (log)
+ log->Printf("Invalid watch register style");
+ return 0;
}
-static void
-SetWatchHi (struct pt_watch_regs *regs, uint32_t index, uint16_t value)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (regs->style == pt_watch_style_mips32)
- regs->mips32.watchhi[index] = value;
- else if (regs->style == pt_watch_style_mips64)
- regs->mips64.watchhi[index] = value;
- if(log)
- log->Printf("Invalid watch register style");
- return;
+static void SetWatchHi(struct pt_watch_regs *regs, uint32_t index,
+ uint16_t value) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ if (regs->style == pt_watch_style_mips32)
+ regs->mips32.watchhi[index] = value;
+ else if (regs->style == pt_watch_style_mips64)
+ regs->mips64.watchhi[index] = value;
+ if (log)
+ log->Printf("Invalid watch register style");
+ return;
}
-static lldb::addr_t
-GetWatchLo (struct pt_watch_regs *regs, uint32_t index)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (regs->style == pt_watch_style_mips32)
- return regs->mips32.watchlo[index];
- else if (regs->style == pt_watch_style_mips64)
- return regs->mips64.watchlo[index];
- if(log)
- log->Printf("Invalid watch register style");
- return LLDB_INVALID_ADDRESS;
+static lldb::addr_t GetWatchLo(struct pt_watch_regs *regs, uint32_t index) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ if (regs->style == pt_watch_style_mips32)
+ return regs->mips32.watchlo[index];
+ else if (regs->style == pt_watch_style_mips64)
+ return regs->mips64.watchlo[index];
+ if (log)
+ log->Printf("Invalid watch register style");
+ return LLDB_INVALID_ADDRESS;
}
-static void
-SetWatchLo (struct pt_watch_regs *regs, uint32_t index, uint64_t value)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (regs->style == pt_watch_style_mips32)
- regs->mips32.watchlo[index] = (uint32_t) value;
- else if (regs->style == pt_watch_style_mips64)
- regs->mips64.watchlo[index] = value;
- if(log)
- log->Printf("Invalid watch register style");
- return;
+static void SetWatchLo(struct pt_watch_regs *regs, uint32_t index,
+ uint64_t value) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ if (regs->style == pt_watch_style_mips32)
+ regs->mips32.watchlo[index] = (uint32_t)value;
+ else if (regs->style == pt_watch_style_mips64)
+ regs->mips64.watchlo[index] = value;
+ if (log)
+ log->Printf("Invalid watch register style");
+ return;
}
-static uint32_t
-GetIRWMask (struct pt_watch_regs *regs, uint32_t index)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (regs->style == pt_watch_style_mips32)
- return regs->mips32.watch_masks[index] & IRW;
- else if (regs->style == pt_watch_style_mips64)
- return regs->mips64.watch_masks[index] & IRW;
- if(log)
- log->Printf("Invalid watch register style");
- return 0;
+static uint32_t GetIRWMask(struct pt_watch_regs *regs, uint32_t index) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ if (regs->style == pt_watch_style_mips32)
+ return regs->mips32.watch_masks[index] & IRW;
+ else if (regs->style == pt_watch_style_mips64)
+ return regs->mips64.watch_masks[index] & IRW;
+ if (log)
+ log->Printf("Invalid watch register style");
+ return 0;
}
-static uint32_t
-GetRegMask (struct pt_watch_regs *regs, uint32_t index)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (regs->style == pt_watch_style_mips32)
- return regs->mips32.watch_masks[index] & ~IRW;
- else if (regs->style == pt_watch_style_mips64)
- return regs->mips64.watch_masks[index] & ~IRW;
- if(log)
- log->Printf("Invalid watch register style");
- return 0;
+static uint32_t GetRegMask(struct pt_watch_regs *regs, uint32_t index) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ if (regs->style == pt_watch_style_mips32)
+ return regs->mips32.watch_masks[index] & ~IRW;
+ else if (regs->style == pt_watch_style_mips64)
+ return regs->mips64.watch_masks[index] & ~IRW;
+ if (log)
+ log->Printf("Invalid watch register style");
+ return 0;
}
-static lldb::addr_t
-GetRangeMask (lldb::addr_t mask)
-{
- lldb::addr_t mask_bit = 1;
- while (mask_bit < mask)
- {
- mask = mask | mask_bit;
- mask_bit <<= 1;
- }
- return mask;
+static lldb::addr_t GetRangeMask(lldb::addr_t mask) {
+ lldb::addr_t mask_bit = 1;
+ while (mask_bit < mask) {
+ mask = mask | mask_bit;
+ mask_bit <<= 1;
+ }
+ return mask;
}
-static int
-GetVacantWatchIndex (struct pt_watch_regs *regs, lldb::addr_t addr, uint32_t size, uint32_t irw, uint32_t num_valid)
-{
- lldb::addr_t last_byte = addr + size - 1;
- lldb::addr_t mask = GetRangeMask (addr ^ last_byte) | IRW;
- lldb::addr_t base_addr = addr & ~mask;
-
- // Check if this address is already watched by previous watch points.
- lldb::addr_t lo;
- uint16_t hi;
- uint32_t vacant_watches = 0;
- for (uint32_t index = 0; index < num_valid; index++)
- {
- lo = GetWatchLo (regs, index);
- if (lo != 0 && irw == ((uint32_t) lo & irw))
- {
- hi = GetWatchHi (regs, index) | IRW;
- lo &= ~(lldb::addr_t) hi;
- if (addr >= lo && last_byte <= (lo + hi))
- return index;
+static int GetVacantWatchIndex(struct pt_watch_regs *regs, lldb::addr_t addr,
+ uint32_t size, uint32_t irw,
+ uint32_t num_valid) {
+ lldb::addr_t last_byte = addr + size - 1;
+ lldb::addr_t mask = GetRangeMask(addr ^ last_byte) | IRW;
+ lldb::addr_t base_addr = addr & ~mask;
+
+ // Check if this address is already watched by previous watch points.
+ lldb::addr_t lo;
+ uint16_t hi;
+ uint32_t vacant_watches = 0;
+ for (uint32_t index = 0; index < num_valid; index++) {
+ lo = GetWatchLo(regs, index);
+ if (lo != 0 && irw == ((uint32_t)lo & irw)) {
+ hi = GetWatchHi(regs, index) | IRW;
+ lo &= ~(lldb::addr_t)hi;
+ if (addr >= lo && last_byte <= (lo + hi))
+ return index;
+ } else
+ vacant_watches++;
+ }
+
+ // Now try to find a vacant index
+ if (vacant_watches > 0) {
+ vacant_watches = 0;
+ for (uint32_t index = 0; index < num_valid; index++) {
+ lo = GetWatchLo(regs, index);
+ if (lo == 0 && irw == (GetIRWMask(regs, index) & irw)) {
+ if (mask <= (GetRegMask(regs, index) | IRW)) {
+ // It fits, we can use it.
+ SetWatchLo(regs, index, base_addr | irw);
+ SetWatchHi(regs, index, mask & ~IRW);
+ return index;
+ } else {
+ // It doesn't fit, but has the proper IRW capabilities
+ vacant_watches++;
}
- else
- vacant_watches++;
+ }
}
- // Now try to find a vacant index
- if(vacant_watches > 0)
- {
- vacant_watches = 0;
- for (uint32_t index = 0; index < num_valid; index++)
- {
- lo = GetWatchLo (regs, index);
- if (lo == 0
- && irw == (GetIRWMask (regs, index) & irw))
- {
- if (mask <= (GetRegMask (regs, index) | IRW))
- {
- // It fits, we can use it.
- SetWatchLo (regs, index, base_addr | irw);
- SetWatchHi (regs, index, mask & ~IRW);
- return index;
- }
- else
- {
- // It doesn't fit, but has the proper IRW capabilities
- vacant_watches++;
- }
- }
- }
-
- if (vacant_watches > 1)
- {
- // Split this watchpoint accross several registers
- struct pt_watch_regs regs_copy;
- regs_copy = *regs;
- lldb::addr_t break_addr;
- uint32_t segment_size;
- for (uint32_t index = 0; index < num_valid; index++)
- {
- lo = GetWatchLo (&regs_copy, index);
- hi = GetRegMask (&regs_copy, index) | IRW;
- if (lo == 0 && irw == (hi & irw))
- {
- lo = addr & ~(lldb::addr_t) hi;
- break_addr = lo + hi + 1;
- if (break_addr >= addr + size)
- segment_size = size;
- else
- segment_size = break_addr - addr;
- mask = GetRangeMask (addr ^ (addr + segment_size - 1));
- SetWatchLo (&regs_copy, index, (addr & ~mask) | irw);
- SetWatchHi (&regs_copy, index, mask & ~IRW);
- if (break_addr >= addr + size)
- {
- *regs = regs_copy;
- return index;
- }
- size = addr + size - break_addr;
- addr = break_addr;
- }
- }
+ if (vacant_watches > 1) {
+ // Split this watchpoint accross several registers
+ struct pt_watch_regs regs_copy;
+ regs_copy = *regs;
+ lldb::addr_t break_addr;
+ uint32_t segment_size;
+ for (uint32_t index = 0; index < num_valid; index++) {
+ lo = GetWatchLo(&regs_copy, index);
+ hi = GetRegMask(&regs_copy, index) | IRW;
+ if (lo == 0 && irw == (hi & irw)) {
+ lo = addr & ~(lldb::addr_t)hi;
+ break_addr = lo + hi + 1;
+ if (break_addr >= addr + size)
+ segment_size = size;
+ else
+ segment_size = break_addr - addr;
+ mask = GetRangeMask(addr ^ (addr + segment_size - 1));
+ SetWatchLo(&regs_copy, index, (addr & ~mask) | irw);
+ SetWatchHi(&regs_copy, index, mask & ~IRW);
+ if (break_addr >= addr + size) {
+ *regs = regs_copy;
+ return index;
+ }
+ size = addr + size - break_addr;
+ addr = break_addr;
}
+ }
}
- return LLDB_INVALID_INDEX32;
+ }
+ return LLDB_INVALID_INDEX32;
}
-bool
-NativeRegisterContextLinux_mips64::IsMSA(uint32_t reg_index) const
-{
- return (m_reg_info.first_msa <= reg_index && reg_index <= m_reg_info.last_msa);
+bool NativeRegisterContextLinux_mips64::IsMSA(uint32_t reg_index) const {
+ return (m_reg_info.first_msa <= reg_index &&
+ reg_index <= m_reg_info.last_msa);
}
-bool
-NativeRegisterContextLinux_mips64::IsMSAAvailable()
-{
- MSA_linux_mips msa_buf;
- unsigned int regset = NT_MIPS_MSA;
+bool NativeRegisterContextLinux_mips64::IsMSAAvailable() {
+ MSA_linux_mips msa_buf;
+ unsigned int regset = NT_MIPS_MSA;
- Error error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, Host::GetCurrentProcessID(), static_cast<void *>(&regset), &msa_buf, sizeof(MSA_linux_mips));
+ Error error = NativeProcessLinux::PtraceWrapper(
+ PTRACE_GETREGSET, Host::GetCurrentProcessID(),
+ static_cast<void *>(&regset), &msa_buf, sizeof(MSA_linux_mips));
- if (error.Success() && msa_buf.mir)
- {
- return true;
- }
+ if (error.Success() && msa_buf.mir) {
+ return true;
+ }
- return false;
+ return false;
}
-Error
-NativeRegisterContextLinux_mips64::IsWatchpointHit (uint32_t wp_index, bool &is_hit)
-{
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return Error("Watchpoint index out of range");
-
- // reading the current state of watch regs
- struct pt_watch_regs watch_readback;
- Error error = DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&watch_readback));
-
- if (GetWatchHi (&watch_readback, wp_index) & (IRW))
- {
- // clear hit flag in watchhi
- SetWatchHi (&watch_readback, wp_index, (GetWatchHi (&watch_readback, wp_index) & ~(IRW)));
- DoWriteWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&watch_readback));
-
- is_hit = true;
- return error;
- }
- is_hit = false;
+Error NativeRegisterContextLinux_mips64::IsWatchpointHit(uint32_t wp_index,
+ bool &is_hit) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return Error("Watchpoint index out of range");
+
+ // reading the current state of watch regs
+ struct pt_watch_regs watch_readback;
+ Error error = DoReadWatchPointRegisterValue(
+ m_thread.GetID(), static_cast<void *>(&watch_readback));
+
+ if (GetWatchHi(&watch_readback, wp_index) & (IRW)) {
+ // clear hit flag in watchhi
+ SetWatchHi(&watch_readback, wp_index,
+ (GetWatchHi(&watch_readback, wp_index) & ~(IRW)));
+ DoWriteWatchPointRegisterValue(m_thread.GetID(),
+ static_cast<void *>(&watch_readback));
+
+ is_hit = true;
return error;
+ }
+ is_hit = false;
+ return error;
}
-Error
-NativeRegisterContextLinux_mips64::GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr) {
- uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
- for (wp_index = 0; wp_index < num_hw_wps; ++wp_index)
- {
- bool is_hit;
- Error error = IsWatchpointHit(wp_index, is_hit);
- if (error.Fail()) {
- wp_index = LLDB_INVALID_INDEX32;
- } else if (is_hit) {
- return error;
- }
+Error NativeRegisterContextLinux_mips64::GetWatchpointHitIndex(
+ uint32_t &wp_index, lldb::addr_t trap_addr) {
+ uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
+ for (wp_index = 0; wp_index < num_hw_wps; ++wp_index) {
+ bool is_hit;
+ Error error = IsWatchpointHit(wp_index, is_hit);
+ if (error.Fail()) {
+ wp_index = LLDB_INVALID_INDEX32;
+ } else if (is_hit) {
+ return error;
}
- wp_index = LLDB_INVALID_INDEX32;
- return Error();
+ }
+ wp_index = LLDB_INVALID_INDEX32;
+ return Error();
}
-Error
-NativeRegisterContextLinux_mips64::IsWatchpointVacant (uint32_t wp_index, bool &is_vacant)
-{
- is_vacant = false;
- return Error("MIPS TODO: NativeRegisterContextLinux_mips64::IsWatchpointVacant not implemented");
+Error NativeRegisterContextLinux_mips64::IsWatchpointVacant(uint32_t wp_index,
+ bool &is_vacant) {
+ is_vacant = false;
+ return Error("MIPS TODO: "
+ "NativeRegisterContextLinux_mips64::IsWatchpointVacant not "
+ "implemented");
}
-bool
-NativeRegisterContextLinux_mips64::ClearHardwareWatchpoint(uint32_t wp_index)
-{
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return false;
-
- struct pt_watch_regs regs;
- // First reading the current state of watch regs
- DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast<void*>(&regs));
-
- if (regs.style == pt_watch_style_mips32)
- {
- regs.mips32.watchlo[wp_index] = default_watch_regs.mips32.watchlo[wp_index];
- regs.mips32.watchhi[wp_index] = default_watch_regs.mips32.watchhi[wp_index];
- regs.mips32.watch_masks[wp_index] = default_watch_regs.mips32.watch_masks[wp_index];
- }
- else // pt_watch_style_mips64
- {
- regs.mips64.watchlo[wp_index] = default_watch_regs.mips64.watchlo[wp_index];
- regs.mips64.watchhi[wp_index] = default_watch_regs.mips64.watchhi[wp_index];
- regs.mips64.watch_masks[wp_index] = default_watch_regs.mips64.watch_masks[wp_index];
- }
-
- Error error = DoWriteWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&regs));
- if(!error.Fail())
- {
- hw_addr_map[wp_index] = LLDB_INVALID_ADDRESS;
- return true;
- }
+bool NativeRegisterContextLinux_mips64::ClearHardwareWatchpoint(
+ uint32_t wp_index) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
return false;
+
+ struct pt_watch_regs regs;
+ // First reading the current state of watch regs
+ DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&regs));
+
+ if (regs.style == pt_watch_style_mips32) {
+ regs.mips32.watchlo[wp_index] = default_watch_regs.mips32.watchlo[wp_index];
+ regs.mips32.watchhi[wp_index] = default_watch_regs.mips32.watchhi[wp_index];
+ regs.mips32.watch_masks[wp_index] =
+ default_watch_regs.mips32.watch_masks[wp_index];
+ } else // pt_watch_style_mips64
+ {
+ regs.mips64.watchlo[wp_index] = default_watch_regs.mips64.watchlo[wp_index];
+ regs.mips64.watchhi[wp_index] = default_watch_regs.mips64.watchhi[wp_index];
+ regs.mips64.watch_masks[wp_index] =
+ default_watch_regs.mips64.watch_masks[wp_index];
+ }
+
+ Error error = DoWriteWatchPointRegisterValue(m_thread.GetID(),
+ static_cast<void *>(&regs));
+ if (!error.Fail()) {
+ hw_addr_map[wp_index] = LLDB_INVALID_ADDRESS;
+ return true;
+ }
+ return false;
}
-Error
-NativeRegisterContextLinux_mips64::ClearAllHardwareWatchpoints()
-{
- return DoWriteWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&default_watch_regs));
+Error NativeRegisterContextLinux_mips64::ClearAllHardwareWatchpoints() {
+ return DoWriteWatchPointRegisterValue(
+ m_thread.GetID(), static_cast<void *>(&default_watch_regs));
}
-Error
-NativeRegisterContextLinux_mips64::SetHardwareWatchpointWithIndex (
- lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index)
-{
- Error error;
- error.SetErrorString ("MIPS TODO: NativeRegisterContextLinux_mips64::SetHardwareWatchpointWithIndex not implemented");
- return error;
+Error NativeRegisterContextLinux_mips64::SetHardwareWatchpointWithIndex(
+ lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index) {
+ Error error;
+ error.SetErrorString("MIPS TODO: "
+ "NativeRegisterContextLinux_mips64::"
+ "SetHardwareWatchpointWithIndex not implemented");
+ return error;
}
-uint32_t
-NativeRegisterContextLinux_mips64::SetHardwareWatchpoint (
- lldb::addr_t addr, size_t size, uint32_t watch_flags)
-{
- struct pt_watch_regs regs;
+uint32_t NativeRegisterContextLinux_mips64::SetHardwareWatchpoint(
+ lldb::addr_t addr, size_t size, uint32_t watch_flags) {
+ struct pt_watch_regs regs;
- // First reading the current state of watch regs
- DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&regs));
+ // First reading the current state of watch regs
+ DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&regs));
- // Try if a new watch point fits in this state
- int index = GetVacantWatchIndex (&regs, addr, size, watch_flags, NumSupportedHardwareWatchpoints());
+ // Try if a new watch point fits in this state
+ int index = GetVacantWatchIndex(&regs, addr, size, watch_flags,
+ NumSupportedHardwareWatchpoints());
- // New watchpoint doesn't fit
- if (index == LLDB_INVALID_INDEX32)
+ // New watchpoint doesn't fit
+ if (index == LLDB_INVALID_INDEX32)
return LLDB_INVALID_INDEX32;
+ // It fits, so we go ahead with updating the state of watch regs
+ DoWriteWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&regs));
- // It fits, so we go ahead with updating the state of watch regs
- DoWriteWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&regs));
-
- // Storing exact address
- hw_addr_map[index] = addr;
- return index;
+ // Storing exact address
+ hw_addr_map[index] = addr;
+ return index;
}
lldb::addr_t
-NativeRegisterContextLinux_mips64::GetWatchpointAddress (uint32_t wp_index)
-{
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return LLDB_INVALID_ADDRESS;
+NativeRegisterContextLinux_mips64::GetWatchpointAddress(uint32_t wp_index) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return LLDB_INVALID_ADDRESS;
- return hw_addr_map[wp_index];
+ return hw_addr_map[wp_index];
}
-struct EmulatorBaton
-{
- lldb::addr_t m_watch_hit_addr;
- NativeProcessLinux* m_process;
- NativeRegisterContext* m_reg_context;
-
- EmulatorBaton(NativeProcessLinux* process, NativeRegisterContext* reg_context) :
- m_watch_hit_addr(LLDB_INVALID_ADDRESS),
- m_process(process),
- m_reg_context(reg_context)
- {}
+struct EmulatorBaton {
+ lldb::addr_t m_watch_hit_addr;
+ NativeProcessLinux *m_process;
+ NativeRegisterContext *m_reg_context;
+
+ EmulatorBaton(NativeProcessLinux *process, NativeRegisterContext *reg_context)
+ : m_watch_hit_addr(LLDB_INVALID_ADDRESS), m_process(process),
+ m_reg_context(reg_context) {}
};
-static size_t
-ReadMemoryCallback (EmulateInstruction *instruction, void *baton,
- const EmulateInstruction::Context &context, lldb::addr_t addr,
- void *dst, size_t length)
-{
- size_t bytes_read;
- EmulatorBaton* emulator_baton = static_cast<EmulatorBaton*>(baton);
- emulator_baton->m_process->ReadMemory(addr, dst, length, bytes_read);
- return bytes_read;
+static size_t ReadMemoryCallback(EmulateInstruction *instruction, void *baton,
+ const EmulateInstruction::Context &context,
+ lldb::addr_t addr, void *dst, size_t length) {
+ size_t bytes_read;
+ EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
+ emulator_baton->m_process->ReadMemory(addr, dst, length, bytes_read);
+ return bytes_read;
}
-static size_t
-WriteMemoryCallback (EmulateInstruction *instruction, void *baton,
- const EmulateInstruction::Context &context,
- lldb::addr_t addr, const void *dst, size_t length)
-{
- return length;
+static size_t WriteMemoryCallback(EmulateInstruction *instruction, void *baton,
+ const EmulateInstruction::Context &context,
+ lldb::addr_t addr, const void *dst,
+ size_t length) {
+ return length;
}
-static bool
-ReadRegisterCallback (EmulateInstruction *instruction, void *baton,
- const RegisterInfo *reg_info, RegisterValue &reg_value)
-{
- EmulatorBaton* emulator_baton = static_cast<EmulatorBaton*>(baton);
+static bool ReadRegisterCallback(EmulateInstruction *instruction, void *baton,
+ const RegisterInfo *reg_info,
+ RegisterValue &reg_value) {
+ EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
- const RegisterInfo* full_reg_info = emulator_baton->m_reg_context->GetRegisterInfo(
- lldb::eRegisterKindDWARF, reg_info->kinds[lldb::eRegisterKindDWARF]);
+ const RegisterInfo *full_reg_info =
+ emulator_baton->m_reg_context->GetRegisterInfo(
+ lldb::eRegisterKindDWARF, reg_info->kinds[lldb::eRegisterKindDWARF]);
- Error error = emulator_baton->m_reg_context->ReadRegister(full_reg_info, reg_value);
- if (error.Success())
- return true;
+ Error error =
+ emulator_baton->m_reg_context->ReadRegister(full_reg_info, reg_value);
+ if (error.Success())
+ return true;
- return false;
+ return false;
}
-static bool
-WriteRegisterCallback (EmulateInstruction *instruction, void *baton,
- const EmulateInstruction::Context &context,
- const RegisterInfo *reg_info, const RegisterValue &reg_value)
-{
- if (reg_info->kinds[lldb::eRegisterKindDWARF] == dwarf_bad_mips64)
- {
- EmulatorBaton* emulator_baton = static_cast<EmulatorBaton*>(baton);
- emulator_baton->m_watch_hit_addr = reg_value.GetAsUInt64 ();
- }
+static bool WriteRegisterCallback(EmulateInstruction *instruction, void *baton,
+ const EmulateInstruction::Context &context,
+ const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) {
+ if (reg_info->kinds[lldb::eRegisterKindDWARF] == dwarf_bad_mips64) {
+ EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
+ emulator_baton->m_watch_hit_addr = reg_value.GetAsUInt64();
+ }
- return true;
+ return true;
}
/*
@@ -1333,130 +1083,124 @@ WriteRegisterCallback (EmulateInstruction *instruction, void *baton,
* it can decide to stop or continue the thread.
*/
lldb::addr_t
-NativeRegisterContextLinux_mips64::GetWatchpointHitAddress (uint32_t wp_index)
-{
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return LLDB_INVALID_ADDRESS;
+NativeRegisterContextLinux_mips64::GetWatchpointHitAddress(uint32_t wp_index) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return LLDB_INVALID_ADDRESS;
- lldb_private::ArchSpec arch;
- arch = GetRegisterInfoInterface().GetTargetArchitecture();
- std::unique_ptr<EmulateInstruction> emulator_ap(
- EmulateInstruction::FindPlugin(arch, lldb_private::eInstructionTypeAny, nullptr));
-
- if (emulator_ap == nullptr)
- return LLDB_INVALID_ADDRESS;
-
- EmulatorBaton baton(static_cast<NativeProcessLinux*>(m_thread.GetProcess().get()), this);
- emulator_ap->SetBaton (&baton);
- emulator_ap->SetReadMemCallback (&ReadMemoryCallback);
- emulator_ap->SetReadRegCallback (&ReadRegisterCallback);
- emulator_ap->SetWriteMemCallback (&WriteMemoryCallback);
- emulator_ap->SetWriteRegCallback (&WriteRegisterCallback);
-
- if (!emulator_ap->ReadInstruction())
- return LLDB_INVALID_ADDRESS;
-
- if (emulator_ap->EvaluateInstruction(lldb::eEmulateInstructionOptionNone))
- return baton.m_watch_hit_addr;
+ lldb_private::ArchSpec arch;
+ arch = GetRegisterInfoInterface().GetTargetArchitecture();
+ std::unique_ptr<EmulateInstruction> emulator_ap(
+ EmulateInstruction::FindPlugin(arch, lldb_private::eInstructionTypeAny,
+ nullptr));
+ if (emulator_ap == nullptr)
return LLDB_INVALID_ADDRESS;
+
+ EmulatorBaton baton(
+ static_cast<NativeProcessLinux *>(m_thread.GetProcess().get()), this);
+ emulator_ap->SetBaton(&baton);
+ emulator_ap->SetReadMemCallback(&ReadMemoryCallback);
+ emulator_ap->SetReadRegCallback(&ReadRegisterCallback);
+ emulator_ap->SetWriteMemCallback(&WriteMemoryCallback);
+ emulator_ap->SetWriteRegCallback(&WriteRegisterCallback);
+
+ if (!emulator_ap->ReadInstruction())
+ return LLDB_INVALID_ADDRESS;
+
+ if (emulator_ap->EvaluateInstruction(lldb::eEmulateInstructionOptionNone))
+ return baton.m_watch_hit_addr;
+
+ return LLDB_INVALID_ADDRESS;
}
-uint32_t
-NativeRegisterContextLinux_mips64::NumSupportedHardwareWatchpoints ()
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- struct pt_watch_regs regs;
- static int num_valid = 0;
- if (!num_valid)
- {
- DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&regs));
- default_watch_regs = regs; // Keeping default watch regs values for future use
- switch (regs.style)
- {
- case pt_watch_style_mips32:
- num_valid = regs.mips32.num_valid; // Using num_valid as cache
- return num_valid;
- case pt_watch_style_mips64:
- num_valid = regs.mips64.num_valid;
- return num_valid;
- default:
- if(log)
- log->Printf("NativeRegisterContextLinux_mips64::%s Error: Unrecognized watch register style", __FUNCTION__);
- }
- return 0;
+uint32_t NativeRegisterContextLinux_mips64::NumSupportedHardwareWatchpoints() {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ struct pt_watch_regs regs;
+ static int num_valid = 0;
+ if (!num_valid) {
+ DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&regs));
+ default_watch_regs =
+ regs; // Keeping default watch regs values for future use
+ switch (regs.style) {
+ case pt_watch_style_mips32:
+ num_valid = regs.mips32.num_valid; // Using num_valid as cache
+ return num_valid;
+ case pt_watch_style_mips64:
+ num_valid = regs.mips64.num_valid;
+ return num_valid;
+ default:
+ if (log)
+ log->Printf("NativeRegisterContextLinux_mips64::%s Error: Unrecognized "
+ "watch register style",
+ __FUNCTION__);
}
- return num_valid;
+ return 0;
+ }
+ return num_valid;
}
Error NativeRegisterContextLinux_mips64::ReadRegisterRaw(uint32_t reg_index,
- RegisterValue &value)
-{
- const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(reg_index);
+ RegisterValue &value) {
+ const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(reg_index);
- if (!reg_info)
- return Error("register %" PRIu32 " not found", reg_index);
+ if (!reg_info)
+ return Error("register %" PRIu32 " not found", reg_index);
- uint32_t offset = reg_info->kinds[lldb::eRegisterKindProcessPlugin];
+ uint32_t offset = reg_info->kinds[lldb::eRegisterKindProcessPlugin];
- if ((offset == ptrace_sr_mips) || (offset == ptrace_config5_mips))
- return Read_SR_Config(reg_info->byte_offset, reg_info->name,
- reg_info->byte_size, value);
+ if ((offset == ptrace_sr_mips) || (offset == ptrace_config5_mips))
+ return Read_SR_Config(reg_info->byte_offset, reg_info->name,
+ reg_info->byte_size, value);
- return DoReadRegisterValue(offset, reg_info->name, reg_info->byte_size,
- value);
+ return DoReadRegisterValue(offset, reg_info->name, reg_info->byte_size,
+ value);
}
Error NativeRegisterContextLinux_mips64::WriteRegisterRaw(
- uint32_t reg_index, const RegisterValue &value)
-{
- const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(reg_index);
+ uint32_t reg_index, const RegisterValue &value) {
+ const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(reg_index);
- if (!reg_info)
- return Error("register %" PRIu32 " not found", reg_index);
+ if (!reg_info)
+ return Error("register %" PRIu32 " not found", reg_index);
- if (reg_info->invalidate_regs)
- lldbassert(false && "reg_info->invalidate_regs is unhandled");
+ if (reg_info->invalidate_regs)
+ lldbassert(false && "reg_info->invalidate_regs is unhandled");
- uint32_t offset = reg_info->kinds[lldb::eRegisterKindProcessPlugin];
- return DoWriteRegisterValue(offset, reg_info->name, value);
+ uint32_t offset = reg_info->kinds[lldb::eRegisterKindProcessPlugin];
+ return DoWriteRegisterValue(offset, reg_info->name, value);
}
Error NativeRegisterContextLinux_mips64::Read_SR_Config(uint32_t offset,
const char *reg_name,
uint32_t size,
- RegisterValue &value)
-{
- GPR_linux_mips regs;
- ::memset(&regs, 0, sizeof(GPR_linux_mips));
-
- Error error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGS, m_thread.GetID(),
- NULL, &regs, sizeof regs);
- if (error.Success())
- {
- lldb_private::ArchSpec arch;
- if (m_thread.GetProcess()->GetArchitecture(arch))
- {
- void *target_address = ((uint8_t *)&regs) + offset +
- 4 * (arch.GetMachine() == llvm::Triple::mips);
- value.SetUInt(*(uint32_t *)target_address, size);
- }
- else
- error.SetErrorString("failed to get architecture");
- }
- return error;
+ RegisterValue &value) {
+ GPR_linux_mips regs;
+ ::memset(&regs, 0, sizeof(GPR_linux_mips));
+
+ Error error = NativeProcessLinux::PtraceWrapper(
+ PTRACE_GETREGS, m_thread.GetID(), NULL, &regs, sizeof regs);
+ if (error.Success()) {
+ lldb_private::ArchSpec arch;
+ if (m_thread.GetProcess()->GetArchitecture(arch)) {
+ void *target_address = ((uint8_t *)&regs) + offset +
+ 4 * (arch.GetMachine() == llvm::Triple::mips);
+ value.SetUInt(*(uint32_t *)target_address, size);
+ } else
+ error.SetErrorString("failed to get architecture");
+ }
+ return error;
}
-Error
-NativeRegisterContextLinux_mips64::DoReadWatchPointRegisterValue(lldb::tid_t tid, void* watch_readback)
-{
- return NativeProcessLinux::PtraceWrapper( PTRACE_GET_WATCH_REGS, m_thread.GetID(), watch_readback);
+Error NativeRegisterContextLinux_mips64::DoReadWatchPointRegisterValue(
+ lldb::tid_t tid, void *watch_readback) {
+ return NativeProcessLinux::PtraceWrapper(PTRACE_GET_WATCH_REGS,
+ m_thread.GetID(), watch_readback);
}
-Error
-NativeRegisterContextLinux_mips64::DoWriteWatchPointRegisterValue(lldb::tid_t tid, void* watch_reg_value)
-{
- return NativeProcessLinux::PtraceWrapper(PTRACE_SET_WATCH_REGS, m_thread.GetID(), watch_reg_value);
+Error NativeRegisterContextLinux_mips64::DoWriteWatchPointRegisterValue(
+ lldb::tid_t tid, void *watch_reg_value) {
+ return NativeProcessLinux::PtraceWrapper(PTRACE_SET_WATCH_REGS,
+ m_thread.GetID(), watch_reg_value);
}
#endif // defined (__mips__)
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h
index 20c32075379c..1b25609205df 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-#if defined (__mips__)
+#if defined(__mips__)
#ifndef lldb_NativeRegisterContextLinux_mips64_h
#define lldb_NativeRegisterContextLinux_mips64_h
@@ -21,147 +21,115 @@
namespace lldb_private {
namespace process_linux {
- class NativeProcessLinux;
+class NativeProcessLinux;
- class NativeRegisterContextLinux_mips64 : public NativeRegisterContextLinux
- {
- public:
- NativeRegisterContextLinux_mips64 (const ArchSpec& target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx);
+class NativeRegisterContextLinux_mips64 : public NativeRegisterContextLinux {
+public:
+ NativeRegisterContextLinux_mips64(const ArchSpec &target_arch,
+ NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx);
- uint32_t
- GetRegisterSetCount () const override;
+ uint32_t GetRegisterSetCount() const override;
- lldb::addr_t
- GetPCfromBreakpointLocation (lldb::addr_t fail_value = LLDB_INVALID_ADDRESS) override;
+ lldb::addr_t GetPCfromBreakpointLocation(
+ lldb::addr_t fail_value = LLDB_INVALID_ADDRESS) override;
- lldb::addr_t
- GetWatchpointHitAddress (uint32_t wp_index) override;
+ lldb::addr_t GetWatchpointHitAddress(uint32_t wp_index) override;
- const RegisterSet *
- GetRegisterSet (uint32_t set_index) const override;
+ const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
- Error
- ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value) override;
+ Error ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) override;
- Error
- WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value) override;
+ Error WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) override;
- Error
- ReadAllRegisterValues (lldb::DataBufferSP &data_sp) override;
+ Error ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
- Error
- WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) override;
+ Error WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- Error
- ReadCP1();
+ Error ReadCP1();
- Error
- WriteCP1();
+ Error WriteCP1();
- Error
- IsWatchpointHit (uint32_t wp_index, bool &is_hit) override;
+ uint8_t *ReturnFPOffset(uint8_t reg_index, uint32_t byte_offset);
- uint8_t *ReturnFPOffset(uint8_t reg_index, uint32_t byte_offset);
+ Error IsWatchpointHit(uint32_t wp_index, bool &is_hit) override;
+ Error GetWatchpointHitIndex(uint32_t &wp_index,
+ lldb::addr_t trap_addr) override;
- Error
- GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr) override;
+ Error IsWatchpointVacant(uint32_t wp_index, bool &is_vacant) override;
- Error
- IsWatchpointVacant (uint32_t wp_index, bool &is_vacant) override;
+ bool ClearHardwareWatchpoint(uint32_t wp_index) override;
- bool
- ClearHardwareWatchpoint (uint32_t wp_index) override;
+ Error ClearAllHardwareWatchpoints() override;
- Error
- ClearAllHardwareWatchpoints () override;
+ Error SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size,
+ uint32_t watch_flags, uint32_t wp_index);
- Error
- SetHardwareWatchpointWithIndex (lldb::addr_t addr, size_t size,
- uint32_t watch_flags, uint32_t wp_index);
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
+ uint32_t watch_flags) override;
- uint32_t
- SetHardwareWatchpoint (lldb::addr_t addr, size_t size,
- uint32_t watch_flags) override;
+ lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
- lldb::addr_t
- GetWatchpointAddress (uint32_t wp_index) override;
+ uint32_t NumSupportedHardwareWatchpoints() override;
- uint32_t
- NumSupportedHardwareWatchpoints () override;
+ static bool IsMSAAvailable();
- static bool
- IsMSAAvailable();
-
- protected:
-
- Error
- Read_SR_Config(uint32_t offset, const char *reg_name, uint32_t size,
+protected:
+ Error Read_SR_Config(uint32_t offset, const char *reg_name, uint32_t size,
RegisterValue &value);
- Error
- ReadRegisterRaw(uint32_t reg_index, RegisterValue &value) override;
+ Error ReadRegisterRaw(uint32_t reg_index, RegisterValue &value) override;
- Error
- DoReadWatchPointRegisterValue(lldb::tid_t tid, void* watch_readback);
-
- Error
- WriteRegisterRaw(uint32_t reg_index,
+ Error WriteRegisterRaw(uint32_t reg_index,
const RegisterValue &value) override;
- Error
- DoWriteWatchPointRegisterValue(lldb::tid_t tid, void* watch_readback);
+ Error DoReadWatchPointRegisterValue(lldb::tid_t tid, void *watch_readback);
+
+ Error DoWriteWatchPointRegisterValue(lldb::tid_t tid, void *watch_readback);
- bool
- IsFR0();
+ bool IsFR0();
- bool
- IsFRE();
+ bool IsFRE();
- bool
- IsFPR(uint32_t reg_index) const;
+ bool IsFPR(uint32_t reg_index) const;
- bool
- IsMSA(uint32_t reg_index) const;
+ bool IsMSA(uint32_t reg_index) const;
- void*
- GetGPRBuffer() override { return &m_gpr; }
+ void *GetGPRBuffer() override { return &m_gpr; }
- void*
- GetFPRBuffer() override { return &m_fpr; }
+ void *GetFPRBuffer() override { return &m_fpr; }
- size_t
- GetFPRSize() override { return sizeof(FPR_linux_mips); }
+ size_t GetFPRSize() override { return sizeof(FPR_linux_mips); }
- private:
- // Info about register ranges.
- struct RegInfo
- {
- uint32_t num_registers;
- uint32_t num_gpr_registers;
- uint32_t num_fpr_registers;
+private:
+ // Info about register ranges.
+ struct RegInfo {
+ uint32_t num_registers;
+ uint32_t num_gpr_registers;
+ uint32_t num_fpr_registers;
- uint32_t last_gpr;
- uint32_t first_fpr;
- uint32_t last_fpr;
- uint32_t first_msa;
- uint32_t last_msa;
- };
+ uint32_t last_gpr;
+ uint32_t first_fpr;
+ uint32_t last_fpr;
+ uint32_t first_msa;
+ uint32_t last_msa;
+ };
- RegInfo m_reg_info;
+ RegInfo m_reg_info;
- GPR_linux_mips m_gpr;
+ GPR_linux_mips m_gpr;
- FPR_linux_mips m_fpr;
+ FPR_linux_mips m_fpr;
- MSA_linux_mips m_msa;
+ MSA_linux_mips m_msa;
- lldb::addr_t hw_addr_map[MAX_NUM_WP];
+ lldb::addr_t hw_addr_map[MAX_NUM_WP];
- IOVEC_mips m_iovec;
- };
+ IOVEC_mips m_iovec;
+};
} // namespace process_linux
} // namespace lldb_private
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp
index b09ad400d909..7ec4dc551fac 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp
@@ -30,99 +30,62 @@ using namespace lldb_private::process_linux;
// Private namespace.
// ----------------------------------------------------------------------------
-namespace
-{
- // s390x 64-bit general purpose registers.
- static const uint32_t g_gpr_regnums_s390x[] =
- {
- lldb_r0_s390x,
- lldb_r1_s390x,
- lldb_r2_s390x,
- lldb_r3_s390x,
- lldb_r4_s390x,
- lldb_r5_s390x,
- lldb_r6_s390x,
- lldb_r7_s390x,
- lldb_r8_s390x,
- lldb_r9_s390x,
- lldb_r10_s390x,
- lldb_r11_s390x,
- lldb_r12_s390x,
- lldb_r13_s390x,
- lldb_r14_s390x,
- lldb_r15_s390x,
- lldb_acr0_s390x,
- lldb_acr1_s390x,
- lldb_acr2_s390x,
- lldb_acr3_s390x,
- lldb_acr4_s390x,
- lldb_acr5_s390x,
- lldb_acr6_s390x,
- lldb_acr7_s390x,
- lldb_acr8_s390x,
- lldb_acr9_s390x,
- lldb_acr10_s390x,
- lldb_acr11_s390x,
- lldb_acr12_s390x,
- lldb_acr13_s390x,
- lldb_acr14_s390x,
- lldb_acr15_s390x,
- lldb_pswm_s390x,
- lldb_pswa_s390x,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
- };
- static_assert((sizeof(g_gpr_regnums_s390x) / sizeof(g_gpr_regnums_s390x[0])) - 1 == k_num_gpr_registers_s390x,
- "g_gpr_regnums_s390x has wrong number of register infos");
-
- // s390x 64-bit floating point registers.
- static const uint32_t g_fpu_regnums_s390x[] =
- {
- lldb_f0_s390x,
- lldb_f1_s390x,
- lldb_f2_s390x,
- lldb_f3_s390x,
- lldb_f4_s390x,
- lldb_f5_s390x,
- lldb_f6_s390x,
- lldb_f7_s390x,
- lldb_f8_s390x,
- lldb_f9_s390x,
- lldb_f10_s390x,
- lldb_f11_s390x,
- lldb_f12_s390x,
- lldb_f13_s390x,
- lldb_f14_s390x,
- lldb_f15_s390x,
- lldb_fpc_s390x,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
- };
- static_assert((sizeof(g_fpu_regnums_s390x) / sizeof(g_fpu_regnums_s390x[0])) - 1 == k_num_fpr_registers_s390x,
- "g_fpu_regnums_s390x has wrong number of register infos");
-
- // s390x Linux operating-system information.
- static const uint32_t g_linux_regnums_s390x[] =
- {
- lldb_orig_r2_s390x,
- lldb_last_break_s390x,
- lldb_system_call_s390x,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
- };
- static_assert((sizeof(g_linux_regnums_s390x) / sizeof(g_linux_regnums_s390x[0])) - 1 == k_num_linux_registers_s390x,
- "g_linux_regnums_s390x has wrong number of register infos");
-
- // Number of register sets provided by this context.
- enum
- {
- k_num_register_sets = 3
- };
-
- // Register sets for s390x 64-bit.
- static const RegisterSet g_reg_sets_s390x[k_num_register_sets] =
- {
- { "General Purpose Registers", "gpr", k_num_gpr_registers_s390x, g_gpr_regnums_s390x },
- { "Floating Point Registers", "fpr", k_num_fpr_registers_s390x, g_fpu_regnums_s390x },
- { "Linux Operating System Data", "linux", k_num_linux_registers_s390x, g_linux_regnums_s390x },
- };
+namespace {
+// s390x 64-bit general purpose registers.
+static const uint32_t g_gpr_regnums_s390x[] = {
+ lldb_r0_s390x, lldb_r1_s390x, lldb_r2_s390x, lldb_r3_s390x,
+ lldb_r4_s390x, lldb_r5_s390x, lldb_r6_s390x, lldb_r7_s390x,
+ lldb_r8_s390x, lldb_r9_s390x, lldb_r10_s390x, lldb_r11_s390x,
+ lldb_r12_s390x, lldb_r13_s390x, lldb_r14_s390x, lldb_r15_s390x,
+ lldb_acr0_s390x, lldb_acr1_s390x, lldb_acr2_s390x, lldb_acr3_s390x,
+ lldb_acr4_s390x, lldb_acr5_s390x, lldb_acr6_s390x, lldb_acr7_s390x,
+ lldb_acr8_s390x, lldb_acr9_s390x, lldb_acr10_s390x, lldb_acr11_s390x,
+ lldb_acr12_s390x, lldb_acr13_s390x, lldb_acr14_s390x, lldb_acr15_s390x,
+ lldb_pswm_s390x, lldb_pswa_s390x,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_gpr_regnums_s390x) / sizeof(g_gpr_regnums_s390x[0])) -
+ 1 ==
+ k_num_gpr_registers_s390x,
+ "g_gpr_regnums_s390x has wrong number of register infos");
+
+// s390x 64-bit floating point registers.
+static const uint32_t g_fpu_regnums_s390x[] = {
+ lldb_f0_s390x, lldb_f1_s390x, lldb_f2_s390x, lldb_f3_s390x,
+ lldb_f4_s390x, lldb_f5_s390x, lldb_f6_s390x, lldb_f7_s390x,
+ lldb_f8_s390x, lldb_f9_s390x, lldb_f10_s390x, lldb_f11_s390x,
+ lldb_f12_s390x, lldb_f13_s390x, lldb_f14_s390x, lldb_f15_s390x,
+ lldb_fpc_s390x,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_fpu_regnums_s390x) / sizeof(g_fpu_regnums_s390x[0])) -
+ 1 ==
+ k_num_fpr_registers_s390x,
+ "g_fpu_regnums_s390x has wrong number of register infos");
+
+// s390x Linux operating-system information.
+static const uint32_t g_linux_regnums_s390x[] = {
+ lldb_orig_r2_s390x, lldb_last_break_s390x, lldb_system_call_s390x,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_linux_regnums_s390x) /
+ sizeof(g_linux_regnums_s390x[0])) -
+ 1 ==
+ k_num_linux_registers_s390x,
+ "g_linux_regnums_s390x has wrong number of register infos");
+
+// Number of register sets provided by this context.
+enum { k_num_register_sets = 3 };
+
+// Register sets for s390x 64-bit.
+static const RegisterSet g_reg_sets_s390x[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_s390x,
+ g_gpr_regnums_s390x},
+ {"Floating Point Registers", "fpr", k_num_fpr_registers_s390x,
+ g_fpu_regnums_s390x},
+ {"Linux Operating System Data", "linux", k_num_linux_registers_s390x,
+ g_linux_regnums_s390x},
+};
}
#define REG_CONTEXT_SIZE (sizeof(s390_regs) + sizeof(s390_fp_regs) + 4)
@@ -131,15 +94,15 @@ namespace
// Required ptrace defines.
// ----------------------------------------------------------------------------
-#define NT_S390_LAST_BREAK 0x306 /* s390 breaking event address */
+#define NT_S390_LAST_BREAK 0x306 /* s390 breaking event address */
#define NT_S390_SYSTEM_CALL 0x307 /* s390 system call restart data */
NativeRegisterContextLinux *
-NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx)
-{
- return new NativeRegisterContextLinux_s390x(target_arch, native_thread, concrete_frame_idx);
+NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx) {
+ return new NativeRegisterContextLinux_s390x(target_arch, native_thread,
+ concrete_frame_idx);
}
// ----------------------------------------------------------------------------
@@ -147,570 +110,527 @@ NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(const ArchSpec
// ----------------------------------------------------------------------------
static RegisterInfoInterface *
-CreateRegisterInfoInterface(const ArchSpec &target_arch)
-{
- assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
- "Register setting path assumes this is a 64-bit host");
- return new RegisterContextLinux_s390x(target_arch);
-}
-
-NativeRegisterContextLinux_s390x::NativeRegisterContextLinux_s390x(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx)
- : NativeRegisterContextLinux(native_thread, concrete_frame_idx, CreateRegisterInfoInterface(target_arch))
-{
- // Set up data about ranges of valid registers.
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::systemz:
- m_reg_info.num_registers = k_num_registers_s390x;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_s390x;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_s390x;
- m_reg_info.last_gpr = k_last_gpr_s390x;
- m_reg_info.first_fpr = k_first_fpr_s390x;
- m_reg_info.last_fpr = k_last_fpr_s390x;
- break;
- default:
- assert(false && "Unhandled target architecture.");
- break;
- }
-
- // Clear out the watchpoint state.
- m_watchpoint_addr = LLDB_INVALID_ADDRESS;
+CreateRegisterInfoInterface(const ArchSpec &target_arch) {
+ assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
+ "Register setting path assumes this is a 64-bit host");
+ return new RegisterContextLinux_s390x(target_arch);
+}
+
+NativeRegisterContextLinux_s390x::NativeRegisterContextLinux_s390x(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx)
+ : NativeRegisterContextLinux(native_thread, concrete_frame_idx,
+ CreateRegisterInfoInterface(target_arch)) {
+ // Set up data about ranges of valid registers.
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::systemz:
+ m_reg_info.num_registers = k_num_registers_s390x;
+ m_reg_info.num_gpr_registers = k_num_gpr_registers_s390x;
+ m_reg_info.num_fpr_registers = k_num_fpr_registers_s390x;
+ m_reg_info.last_gpr = k_last_gpr_s390x;
+ m_reg_info.first_fpr = k_first_fpr_s390x;
+ m_reg_info.last_fpr = k_last_fpr_s390x;
+ break;
+ default:
+ assert(false && "Unhandled target architecture.");
+ break;
+ }
+
+ // Clear out the watchpoint state.
+ m_watchpoint_addr = LLDB_INVALID_ADDRESS;
+}
+
+uint32_t NativeRegisterContextLinux_s390x::GetRegisterSetCount() const {
+ uint32_t sets = 0;
+ for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) {
+ if (IsRegisterSetAvailable(set_index))
+ ++sets;
+ }
+
+ return sets;
+}
+
+uint32_t NativeRegisterContextLinux_s390x::GetUserRegisterCount() const {
+ uint32_t count = 0;
+ for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) {
+ const RegisterSet *set = GetRegisterSet(set_index);
+ if (set)
+ count += set->num_registers;
+ }
+ return count;
}
-uint32_t
-NativeRegisterContextLinux_s390x::GetRegisterSetCount() const
-{
- uint32_t sets = 0;
- for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index)
- {
- if (IsRegisterSetAvailable(set_index))
- ++sets;
- }
+const RegisterSet *
+NativeRegisterContextLinux_s390x::GetRegisterSet(uint32_t set_index) const {
+ if (!IsRegisterSetAvailable(set_index))
+ return nullptr;
- return sets;
-}
+ switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
+ case llvm::Triple::systemz:
+ return &g_reg_sets_s390x[set_index];
+ default:
+ assert(false && "Unhandled target architecture.");
+ return nullptr;
+ }
-uint32_t
-NativeRegisterContextLinux_s390x::GetUserRegisterCount() const
-{
- uint32_t count = 0;
- for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index)
- {
- const RegisterSet *set = GetRegisterSet(set_index);
- if (set)
- count += set->num_registers;
- }
- return count;
+ return nullptr;
}
-const RegisterSet *
-NativeRegisterContextLinux_s390x::GetRegisterSet(uint32_t set_index) const
-{
- if (!IsRegisterSetAvailable(set_index))
- return nullptr;
-
- switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine())
- {
- case llvm::Triple::systemz:
- return &g_reg_sets_s390x[set_index];
- default:
- assert(false && "Unhandled target architecture.");
- return nullptr;
- }
+bool NativeRegisterContextLinux_s390x::IsRegisterSetAvailable(
+ uint32_t set_index) const {
+ return set_index < k_num_register_sets;
+}
- return nullptr;
+bool NativeRegisterContextLinux_s390x::IsGPR(uint32_t reg_index) const {
+ // GPRs come first. "orig_r2" counts as GPR since it is part of the GPR
+ // register area.
+ return reg_index <= m_reg_info.last_gpr || reg_index == lldb_orig_r2_s390x;
}
-bool
-NativeRegisterContextLinux_s390x::IsRegisterSetAvailable(uint32_t set_index) const
-{
- return set_index < k_num_register_sets;
-}
-
-bool
-NativeRegisterContextLinux_s390x::IsGPR(uint32_t reg_index) const
-{
- // GPRs come first. "orig_r2" counts as GPR since it is part of the GPR register area.
- return reg_index <= m_reg_info.last_gpr || reg_index == lldb_orig_r2_s390x;
-}
-
-bool
-NativeRegisterContextLinux_s390x::IsFPR(uint32_t reg_index) const
-{
- return (m_reg_info.first_fpr <= reg_index && reg_index <= m_reg_info.last_fpr);
-}
-
-Error
-NativeRegisterContextLinux_s390x::ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value)
-{
- if (!reg_info)
- return Error("reg_info NULL");
-
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (reg == LLDB_INVALID_REGNUM)
- return Error("register \"%s\" is an internal-only lldb register, cannot read directly", reg_info->name);
-
- if (IsGPR(reg))
- {
- s390_regs regs;
- Error error = DoReadGPR(&regs, sizeof(regs));
- if (error.Fail())
- return error;
-
- uint8_t *src = (uint8_t *)&regs + reg_info->byte_offset;
- assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(regs));
- switch (reg_info->byte_size)
- {
- case 4:
- reg_value.SetUInt32(*(uint32_t *)src);
- break;
- case 8:
- reg_value.SetUInt64(*(uint64_t *)src);
- break;
- default:
- assert(false && "Unhandled data size.");
- return Error("unhandled byte size: %" PRIu32, reg_info->byte_size);
- }
- return Error();
- }
+bool NativeRegisterContextLinux_s390x::IsFPR(uint32_t reg_index) const {
+ return (m_reg_info.first_fpr <= reg_index &&
+ reg_index <= m_reg_info.last_fpr);
+}
- if (IsFPR(reg))
- {
- s390_fp_regs fp_regs;
- Error error = DoReadFPR(&fp_regs, sizeof(fp_regs));
- if (error.Fail())
- return error;
-
- // byte_offset is just the offset within FPR, not the whole user area.
- uint8_t *src = (uint8_t *)&fp_regs + reg_info->byte_offset;
- assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(fp_regs));
- switch (reg_info->byte_size)
- {
- case 4:
- reg_value.SetUInt32(*(uint32_t *)src);
- break;
- case 8:
- reg_value.SetUInt64(*(uint64_t *)src);
- break;
- default:
- assert(false && "Unhandled data size.");
- return Error("unhandled byte size: %" PRIu32, reg_info->byte_size);
- }
- return Error();
- }
+Error NativeRegisterContextLinux_s390x::ReadRegister(
+ const RegisterInfo *reg_info, RegisterValue &reg_value) {
+ if (!reg_info)
+ return Error("reg_info NULL");
- if (reg == lldb_last_break_s390x)
- {
- uint64_t last_break;
- Error error = DoReadRegisterSet(NT_S390_LAST_BREAK, &last_break, 8);
- if (error.Fail())
- return error;
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ if (reg == LLDB_INVALID_REGNUM)
+ return Error("register \"%s\" is an internal-only lldb register, cannot "
+ "read directly",
+ reg_info->name);
- reg_value.SetUInt64(last_break);
- return Error();
+ if (IsGPR(reg)) {
+ s390_regs regs;
+ Error error = DoReadGPR(&regs, sizeof(regs));
+ if (error.Fail())
+ return error;
+
+ uint8_t *src = (uint8_t *)&regs + reg_info->byte_offset;
+ assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(regs));
+ switch (reg_info->byte_size) {
+ case 4:
+ reg_value.SetUInt32(*(uint32_t *)src);
+ break;
+ case 8:
+ reg_value.SetUInt64(*(uint64_t *)src);
+ break;
+ default:
+ assert(false && "Unhandled data size.");
+ return Error("unhandled byte size: %" PRIu32, reg_info->byte_size);
}
+ return Error();
+ }
- if (reg == lldb_system_call_s390x)
- {
- uint32_t system_call;
- Error error = DoReadRegisterSet(NT_S390_SYSTEM_CALL, &system_call, 4);
- if (error.Fail())
- return error;
-
- reg_value.SetUInt32(system_call);
- return Error();
+ if (IsFPR(reg)) {
+ s390_fp_regs fp_regs;
+ Error error = DoReadFPR(&fp_regs, sizeof(fp_regs));
+ if (error.Fail())
+ return error;
+
+ // byte_offset is just the offset within FPR, not the whole user area.
+ uint8_t *src = (uint8_t *)&fp_regs + reg_info->byte_offset;
+ assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(fp_regs));
+ switch (reg_info->byte_size) {
+ case 4:
+ reg_value.SetUInt32(*(uint32_t *)src);
+ break;
+ case 8:
+ reg_value.SetUInt64(*(uint64_t *)src);
+ break;
+ default:
+ assert(false && "Unhandled data size.");
+ return Error("unhandled byte size: %" PRIu32, reg_info->byte_size);
}
+ return Error();
+ }
- return Error("failed - register wasn't recognized");
-}
-
-Error
-NativeRegisterContextLinux_s390x::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value)
-{
- if (!reg_info)
- return Error("reg_info NULL");
-
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (reg == LLDB_INVALID_REGNUM)
- return Error("register \"%s\" is an internal-only lldb register, cannot write directly", reg_info->name);
-
- if (IsGPR(reg))
- {
- s390_regs regs;
- Error error = DoReadGPR(&regs, sizeof(regs));
- if (error.Fail())
- return error;
-
- uint8_t *dst = (uint8_t *)&regs + reg_info->byte_offset;
- assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(regs));
- switch (reg_info->byte_size)
- {
- case 4:
- *(uint32_t *)dst = reg_value.GetAsUInt32();
- break;
- case 8:
- *(uint64_t *)dst = reg_value.GetAsUInt64();
- break;
- default:
- assert(false && "Unhandled data size.");
- return Error("unhandled byte size: %" PRIu32, reg_info->byte_size);
- }
- return DoWriteGPR(&regs, sizeof(regs));
- }
+ if (reg == lldb_last_break_s390x) {
+ uint64_t last_break;
+ Error error = DoReadRegisterSet(NT_S390_LAST_BREAK, &last_break, 8);
+ if (error.Fail())
+ return error;
- if (IsFPR(reg))
- {
- s390_fp_regs fp_regs;
- Error error = DoReadFPR(&fp_regs, sizeof(fp_regs));
- if (error.Fail())
- return error;
-
- // byte_offset is just the offset within fp_regs, not the whole user area.
- uint8_t *dst = (uint8_t *)&fp_regs + reg_info->byte_offset;
- assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(fp_regs));
- switch (reg_info->byte_size)
- {
- case 4:
- *(uint32_t *)dst = reg_value.GetAsUInt32();
- break;
- case 8:
- *(uint64_t *)dst = reg_value.GetAsUInt64();
- break;
- default:
- assert(false && "Unhandled data size.");
- return Error("unhandled byte size: %" PRIu32, reg_info->byte_size);
- }
- return DoWriteFPR(&fp_regs, sizeof(fp_regs));
- }
+ reg_value.SetUInt64(last_break);
+ return Error();
+ }
- if (reg == lldb_last_break_s390x)
- {
- return Error("The last break address is read-only");
- }
+ if (reg == lldb_system_call_s390x) {
+ uint32_t system_call;
+ Error error = DoReadRegisterSet(NT_S390_SYSTEM_CALL, &system_call, 4);
+ if (error.Fail())
+ return error;
- if (reg == lldb_system_call_s390x)
- {
- uint32_t system_call = reg_value.GetAsUInt32();
- return DoWriteRegisterSet(NT_S390_SYSTEM_CALL, &system_call, 4);
- }
+ reg_value.SetUInt32(system_call);
+ return Error();
+ }
- return Error("failed - register wasn't recognized");
+ return Error("failed - register wasn't recognized");
}
-Error
-NativeRegisterContextLinux_s390x::ReadAllRegisterValues(lldb::DataBufferSP &data_sp)
-{
- Error error;
+Error NativeRegisterContextLinux_s390x::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &reg_value) {
+ if (!reg_info)
+ return Error("reg_info NULL");
- data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
- if (!data_sp)
- {
- error.SetErrorStringWithFormat("failed to allocate DataBufferHeap instance of size %" PRIu64, REG_CONTEXT_SIZE);
- return error;
- }
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ if (reg == LLDB_INVALID_REGNUM)
+ return Error("register \"%s\" is an internal-only lldb register, cannot "
+ "write directly",
+ reg_info->name);
- uint8_t *dst = data_sp->GetBytes();
- if (dst == nullptr)
- {
- error.SetErrorStringWithFormat("DataBufferHeap instance of size %" PRIu64 " returned a null pointer",
- REG_CONTEXT_SIZE);
- return error;
+ if (IsGPR(reg)) {
+ s390_regs regs;
+ Error error = DoReadGPR(&regs, sizeof(regs));
+ if (error.Fail())
+ return error;
+
+ uint8_t *dst = (uint8_t *)&regs + reg_info->byte_offset;
+ assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(regs));
+ switch (reg_info->byte_size) {
+ case 4:
+ *(uint32_t *)dst = reg_value.GetAsUInt32();
+ break;
+ case 8:
+ *(uint64_t *)dst = reg_value.GetAsUInt64();
+ break;
+ default:
+ assert(false && "Unhandled data size.");
+ return Error("unhandled byte size: %" PRIu32, reg_info->byte_size);
}
+ return DoWriteGPR(&regs, sizeof(regs));
+ }
- error = DoReadGPR(dst, sizeof(s390_regs));
- dst += sizeof(s390_regs);
+ if (IsFPR(reg)) {
+ s390_fp_regs fp_regs;
+ Error error = DoReadFPR(&fp_regs, sizeof(fp_regs));
if (error.Fail())
- return error;
+ return error;
+
+ // byte_offset is just the offset within fp_regs, not the whole user area.
+ uint8_t *dst = (uint8_t *)&fp_regs + reg_info->byte_offset;
+ assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(fp_regs));
+ switch (reg_info->byte_size) {
+ case 4:
+ *(uint32_t *)dst = reg_value.GetAsUInt32();
+ break;
+ case 8:
+ *(uint64_t *)dst = reg_value.GetAsUInt64();
+ break;
+ default:
+ assert(false && "Unhandled data size.");
+ return Error("unhandled byte size: %" PRIu32, reg_info->byte_size);
+ }
+ return DoWriteFPR(&fp_regs, sizeof(fp_regs));
+ }
- error = DoReadFPR(dst, sizeof(s390_fp_regs));
- dst += sizeof(s390_fp_regs);
- if (error.Fail())
- return error;
+ if (reg == lldb_last_break_s390x) {
+ return Error("The last break address is read-only");
+ }
+
+ if (reg == lldb_system_call_s390x) {
+ uint32_t system_call = reg_value.GetAsUInt32();
+ return DoWriteRegisterSet(NT_S390_SYSTEM_CALL, &system_call, 4);
+ }
- // Ignore errors if the regset is unsupported (happens on older kernels).
- DoReadRegisterSet(NT_S390_SYSTEM_CALL, dst, 4);
- dst += 4;
+ return Error("failed - register wasn't recognized");
+}
- // To enable inferior function calls while the process is stopped in
- // an interrupted system call, we need to clear the system call flag.
- // It will be restored to its original value by WriteAllRegisterValues.
- // Again we ignore error if the regset is unsupported.
- uint32_t system_call = 0;
- DoWriteRegisterSet(NT_S390_SYSTEM_CALL, &system_call, 4);
+Error NativeRegisterContextLinux_s390x::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ Error error;
+ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (!data_sp) {
+ error.SetErrorStringWithFormat(
+ "failed to allocate DataBufferHeap instance of size %" PRIu64,
+ REG_CONTEXT_SIZE);
return error;
-}
+ }
-Error
-NativeRegisterContextLinux_s390x::WriteAllRegisterValues(const lldb::DataBufferSP &data_sp)
-{
- Error error;
+ uint8_t *dst = data_sp->GetBytes();
+ if (dst == nullptr) {
+ error.SetErrorStringWithFormat("DataBufferHeap instance of size %" PRIu64
+ " returned a null pointer",
+ REG_CONTEXT_SIZE);
+ return error;
+ }
- if (!data_sp)
- {
- error.SetErrorStringWithFormat("NativeRegisterContextLinux_s390x::%s invalid data_sp provided", __FUNCTION__);
- return error;
- }
+ error = DoReadGPR(dst, sizeof(s390_regs));
+ dst += sizeof(s390_regs);
+ if (error.Fail())
+ return error;
- if (data_sp->GetByteSize() != REG_CONTEXT_SIZE)
- {
- error.SetErrorStringWithFormat(
- "NativeRegisterContextLinux_s390x::%s data_sp contained mismatched data size, expected %" PRIu64
- ", actual %" PRIu64,
- __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize());
- return error;
- }
+ error = DoReadFPR(dst, sizeof(s390_fp_regs));
+ dst += sizeof(s390_fp_regs);
+ if (error.Fail())
+ return error;
- uint8_t *src = data_sp->GetBytes();
- if (src == nullptr)
- {
- error.SetErrorStringWithFormat(
- "NativeRegisterContextLinux_s390x::%s DataBuffer::GetBytes() returned a null pointer", __FUNCTION__);
- return error;
- }
+ // Ignore errors if the regset is unsupported (happens on older kernels).
+ DoReadRegisterSet(NT_S390_SYSTEM_CALL, dst, 4);
+ dst += 4;
- error = DoWriteGPR(src, sizeof(s390_regs));
- src += sizeof(s390_regs);
- if (error.Fail())
- return error;
+ // To enable inferior function calls while the process is stopped in
+ // an interrupted system call, we need to clear the system call flag.
+ // It will be restored to its original value by WriteAllRegisterValues.
+ // Again we ignore error if the regset is unsupported.
+ uint32_t system_call = 0;
+ DoWriteRegisterSet(NT_S390_SYSTEM_CALL, &system_call, 4);
- error = DoWriteFPR(src, sizeof(s390_fp_regs));
- src += sizeof(s390_fp_regs);
- if (error.Fail())
- return error;
+ return error;
+}
- // Ignore errors if the regset is unsupported (happens on older kernels).
- DoWriteRegisterSet(NT_S390_SYSTEM_CALL, src, 4);
- src += 4;
+Error NativeRegisterContextLinux_s390x::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ Error error;
+ if (!data_sp) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_s390x::%s invalid data_sp provided",
+ __FUNCTION__);
return error;
+ }
+
+ if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_s390x::%s data_sp contained mismatched "
+ "data size, expected %" PRIu64 ", actual %" PRIu64,
+ __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize());
+ return error;
+ }
+
+ uint8_t *src = data_sp->GetBytes();
+ if (src == nullptr) {
+ error.SetErrorStringWithFormat("NativeRegisterContextLinux_s390x::%s "
+ "DataBuffer::GetBytes() returned a null "
+ "pointer",
+ __FUNCTION__);
+ return error;
+ }
+
+ error = DoWriteGPR(src, sizeof(s390_regs));
+ src += sizeof(s390_regs);
+ if (error.Fail())
+ return error;
+
+ error = DoWriteFPR(src, sizeof(s390_fp_regs));
+ src += sizeof(s390_fp_regs);
+ if (error.Fail())
+ return error;
+
+ // Ignore errors if the regset is unsupported (happens on older kernels).
+ DoWriteRegisterSet(NT_S390_SYSTEM_CALL, src, 4);
+ src += 4;
+
+ return error;
}
-Error
-NativeRegisterContextLinux_s390x::DoReadRegisterValue(uint32_t offset, const char *reg_name, uint32_t size,
- RegisterValue &value)
-{
- return Error("DoReadRegisterValue unsupported");
+Error NativeRegisterContextLinux_s390x::DoReadRegisterValue(
+ uint32_t offset, const char *reg_name, uint32_t size,
+ RegisterValue &value) {
+ return Error("DoReadRegisterValue unsupported");
}
-Error
-NativeRegisterContextLinux_s390x::DoWriteRegisterValue(uint32_t offset, const char *reg_name,
- const RegisterValue &value)
-{
- return Error("DoWriteRegisterValue unsupported");
+Error NativeRegisterContextLinux_s390x::DoWriteRegisterValue(
+ uint32_t offset, const char *reg_name, const RegisterValue &value) {
+ return Error("DoWriteRegisterValue unsupported");
}
-Error
-NativeRegisterContextLinux_s390x::PeekUserArea(uint32_t offset, void *buf, size_t buf_size)
-{
- ptrace_area parea;
- parea.len = buf_size;
- parea.process_addr = (addr_t)buf;
- parea.kernel_addr = offset;
+Error NativeRegisterContextLinux_s390x::PeekUserArea(uint32_t offset, void *buf,
+ size_t buf_size) {
+ ptrace_area parea;
+ parea.len = buf_size;
+ parea.process_addr = (addr_t)buf;
+ parea.kernel_addr = offset;
- return NativeProcessLinux::PtraceWrapper(PTRACE_PEEKUSR_AREA, m_thread.GetID(), &parea);
+ return NativeProcessLinux::PtraceWrapper(PTRACE_PEEKUSR_AREA,
+ m_thread.GetID(), &parea);
}
-Error
-NativeRegisterContextLinux_s390x::PokeUserArea(uint32_t offset, const void *buf, size_t buf_size)
-{
- ptrace_area parea;
- parea.len = buf_size;
- parea.process_addr = (addr_t)buf;
- parea.kernel_addr = offset;
+Error NativeRegisterContextLinux_s390x::PokeUserArea(uint32_t offset,
+ const void *buf,
+ size_t buf_size) {
+ ptrace_area parea;
+ parea.len = buf_size;
+ parea.process_addr = (addr_t)buf;
+ parea.kernel_addr = offset;
- return NativeProcessLinux::PtraceWrapper(PTRACE_POKEUSR_AREA, m_thread.GetID(), &parea);
+ return NativeProcessLinux::PtraceWrapper(PTRACE_POKEUSR_AREA,
+ m_thread.GetID(), &parea);
}
-Error
-NativeRegisterContextLinux_s390x::DoReadGPR(void *buf, size_t buf_size)
-{
- assert(buf_size == sizeof(s390_regs));
- return PeekUserArea(offsetof(user_regs_struct, psw), buf, buf_size);
+Error NativeRegisterContextLinux_s390x::DoReadGPR(void *buf, size_t buf_size) {
+ assert(buf_size == sizeof(s390_regs));
+ return PeekUserArea(offsetof(user_regs_struct, psw), buf, buf_size);
}
-Error
-NativeRegisterContextLinux_s390x::DoWriteGPR(void *buf, size_t buf_size)
-{
- assert(buf_size == sizeof(s390_regs));
- return PokeUserArea(offsetof(user_regs_struct, psw), buf, buf_size);
+Error NativeRegisterContextLinux_s390x::DoWriteGPR(void *buf, size_t buf_size) {
+ assert(buf_size == sizeof(s390_regs));
+ return PokeUserArea(offsetof(user_regs_struct, psw), buf, buf_size);
}
-Error
-NativeRegisterContextLinux_s390x::DoReadFPR(void *buf, size_t buf_size)
-{
- assert(buf_size == sizeof(s390_fp_regs));
- return PeekUserArea(offsetof(user_regs_struct, fp_regs), buf, buf_size);
+Error NativeRegisterContextLinux_s390x::DoReadFPR(void *buf, size_t buf_size) {
+ assert(buf_size == sizeof(s390_fp_regs));
+ return PeekUserArea(offsetof(user_regs_struct, fp_regs), buf, buf_size);
}
-Error
-NativeRegisterContextLinux_s390x::DoWriteFPR(void *buf, size_t buf_size)
-{
- assert(buf_size == sizeof(s390_fp_regs));
- return PokeUserArea(offsetof(user_regs_struct, fp_regs), buf, buf_size);
+Error NativeRegisterContextLinux_s390x::DoWriteFPR(void *buf, size_t buf_size) {
+ assert(buf_size == sizeof(s390_fp_regs));
+ return PokeUserArea(offsetof(user_regs_struct, fp_regs), buf, buf_size);
}
-Error
-NativeRegisterContextLinux_s390x::DoReadRegisterSet(uint32_t regset, void *buf, size_t buf_size)
-{
- struct iovec iov;
- iov.iov_base = buf;
- iov.iov_len = buf_size;
+Error NativeRegisterContextLinux_s390x::DoReadRegisterSet(uint32_t regset,
+ void *buf,
+ size_t buf_size) {
+ struct iovec iov;
+ iov.iov_base = buf;
+ iov.iov_len = buf_size;
- return ReadRegisterSet(&iov, buf_size, regset);
+ return ReadRegisterSet(&iov, buf_size, regset);
}
-Error
-NativeRegisterContextLinux_s390x::DoWriteRegisterSet(uint32_t regset, const void *buf, size_t buf_size)
-{
- struct iovec iov;
- iov.iov_base = const_cast<void *>(buf);
- iov.iov_len = buf_size;
+Error NativeRegisterContextLinux_s390x::DoWriteRegisterSet(uint32_t regset,
+ const void *buf,
+ size_t buf_size) {
+ struct iovec iov;
+ iov.iov_base = const_cast<void *>(buf);
+ iov.iov_len = buf_size;
- return WriteRegisterSet(&iov, buf_size, regset);
+ return WriteRegisterSet(&iov, buf_size, regset);
}
-Error
-NativeRegisterContextLinux_s390x::IsWatchpointHit(uint32_t wp_index, bool &is_hit)
-{
- per_lowcore_bits per_lowcore;
+Error NativeRegisterContextLinux_s390x::IsWatchpointHit(uint32_t wp_index,
+ bool &is_hit) {
+ per_lowcore_bits per_lowcore;
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return Error("Watchpoint index out of range");
-
- if (m_watchpoint_addr == LLDB_INVALID_ADDRESS)
- {
- is_hit = false;
- return Error();
- }
-
- Error error = PeekUserArea(offsetof(user_regs_struct, per_info.lowcore), &per_lowcore, sizeof(per_lowcore));
- if (error.Fail())
- {
- is_hit = false;
- return error;
- }
-
- is_hit = (per_lowcore.perc_storage_alteration == 1 && per_lowcore.perc_store_real_address == 0);
-
- if (is_hit)
- {
- // Do not report this watchpoint again.
- memset(&per_lowcore, 0, sizeof(per_lowcore));
- PokeUserArea(offsetof(user_regs_struct, per_info.lowcore), &per_lowcore, sizeof(per_lowcore));
- }
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return Error("Watchpoint index out of range");
+ if (m_watchpoint_addr == LLDB_INVALID_ADDRESS) {
+ is_hit = false;
return Error();
-}
+ }
-Error
-NativeRegisterContextLinux_s390x::GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr)
-{
- uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
- for (wp_index = 0; wp_index < num_hw_wps; ++wp_index)
- {
- bool is_hit;
- Error error = IsWatchpointHit(wp_index, is_hit);
- if (error.Fail())
- {
- wp_index = LLDB_INVALID_INDEX32;
- return error;
- }
- else if (is_hit)
- {
- return error;
- }
+ Error error = PeekUserArea(offsetof(user_regs_struct, per_info.lowcore),
+ &per_lowcore, sizeof(per_lowcore));
+ if (error.Fail()) {
+ is_hit = false;
+ return error;
+ }
+
+ is_hit = (per_lowcore.perc_storage_alteration == 1 &&
+ per_lowcore.perc_store_real_address == 0);
+
+ if (is_hit) {
+ // Do not report this watchpoint again.
+ memset(&per_lowcore, 0, sizeof(per_lowcore));
+ PokeUserArea(offsetof(user_regs_struct, per_info.lowcore), &per_lowcore,
+ sizeof(per_lowcore));
+ }
+
+ return Error();
+}
+
+Error NativeRegisterContextLinux_s390x::GetWatchpointHitIndex(
+ uint32_t &wp_index, lldb::addr_t trap_addr) {
+ uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
+ for (wp_index = 0; wp_index < num_hw_wps; ++wp_index) {
+ bool is_hit;
+ Error error = IsWatchpointHit(wp_index, is_hit);
+ if (error.Fail()) {
+ wp_index = LLDB_INVALID_INDEX32;
+ return error;
+ } else if (is_hit) {
+ return error;
}
- wp_index = LLDB_INVALID_INDEX32;
- return Error();
+ }
+ wp_index = LLDB_INVALID_INDEX32;
+ return Error();
}
-Error
-NativeRegisterContextLinux_s390x::IsWatchpointVacant(uint32_t wp_index, bool &is_vacant)
-{
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return Error("Watchpoint index out of range");
+Error NativeRegisterContextLinux_s390x::IsWatchpointVacant(uint32_t wp_index,
+ bool &is_vacant) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return Error("Watchpoint index out of range");
- is_vacant = m_watchpoint_addr == LLDB_INVALID_ADDRESS;
+ is_vacant = m_watchpoint_addr == LLDB_INVALID_ADDRESS;
- return Error();
+ return Error();
}
-bool
-NativeRegisterContextLinux_s390x::ClearHardwareWatchpoint(uint32_t wp_index)
-{
- per_struct per_info;
+bool NativeRegisterContextLinux_s390x::ClearHardwareWatchpoint(
+ uint32_t wp_index) {
+ per_struct per_info;
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return false;
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return false;
- Error error = PeekUserArea(offsetof(user_regs_struct, per_info), &per_info, sizeof(per_info));
- if (error.Fail())
- return false;
+ Error error = PeekUserArea(offsetof(user_regs_struct, per_info), &per_info,
+ sizeof(per_info));
+ if (error.Fail())
+ return false;
- per_info.control_regs.bits.em_storage_alteration = 0;
- per_info.control_regs.bits.storage_alt_space_ctl = 0;
- per_info.starting_addr = 0;
- per_info.ending_addr = 0;
+ per_info.control_regs.bits.em_storage_alteration = 0;
+ per_info.control_regs.bits.storage_alt_space_ctl = 0;
+ per_info.starting_addr = 0;
+ per_info.ending_addr = 0;
- error = PokeUserArea(offsetof(user_regs_struct, per_info), &per_info, sizeof(per_info));
- if (error.Fail())
- return false;
+ error = PokeUserArea(offsetof(user_regs_struct, per_info), &per_info,
+ sizeof(per_info));
+ if (error.Fail())
+ return false;
- m_watchpoint_addr = LLDB_INVALID_ADDRESS;
- return true;
+ m_watchpoint_addr = LLDB_INVALID_ADDRESS;
+ return true;
}
-Error
-NativeRegisterContextLinux_s390x::ClearAllHardwareWatchpoints()
-{
- if (ClearHardwareWatchpoint(0))
- return Error();
- return Error("Clearing all hardware watchpoints failed.");
+Error NativeRegisterContextLinux_s390x::ClearAllHardwareWatchpoints() {
+ if (ClearHardwareWatchpoint(0))
+ return Error();
+ return Error("Clearing all hardware watchpoints failed.");
}
-uint32_t
-NativeRegisterContextLinux_s390x::SetHardwareWatchpoint(lldb::addr_t addr, size_t size, uint32_t watch_flags)
-{
- per_struct per_info;
+uint32_t NativeRegisterContextLinux_s390x::SetHardwareWatchpoint(
+ lldb::addr_t addr, size_t size, uint32_t watch_flags) {
+ per_struct per_info;
- if (watch_flags != 0x1)
- return LLDB_INVALID_INDEX32;
+ if (watch_flags != 0x1)
+ return LLDB_INVALID_INDEX32;
- if (m_watchpoint_addr != LLDB_INVALID_ADDRESS)
- return LLDB_INVALID_INDEX32;
+ if (m_watchpoint_addr != LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_INDEX32;
- Error error = PeekUserArea(offsetof(user_regs_struct, per_info), &per_info, sizeof(per_info));
- if (error.Fail())
- return LLDB_INVALID_INDEX32;
+ Error error = PeekUserArea(offsetof(user_regs_struct, per_info), &per_info,
+ sizeof(per_info));
+ if (error.Fail())
+ return LLDB_INVALID_INDEX32;
- per_info.control_regs.bits.em_storage_alteration = 1;
- per_info.control_regs.bits.storage_alt_space_ctl = 1;
- per_info.starting_addr = addr;
- per_info.ending_addr = addr + size - 1;
+ per_info.control_regs.bits.em_storage_alteration = 1;
+ per_info.control_regs.bits.storage_alt_space_ctl = 1;
+ per_info.starting_addr = addr;
+ per_info.ending_addr = addr + size - 1;
- error = PokeUserArea(offsetof(user_regs_struct, per_info), &per_info, sizeof(per_info));
- if (error.Fail())
- return LLDB_INVALID_INDEX32;
+ error = PokeUserArea(offsetof(user_regs_struct, per_info), &per_info,
+ sizeof(per_info));
+ if (error.Fail())
+ return LLDB_INVALID_INDEX32;
- m_watchpoint_addr = addr;
- return 0;
+ m_watchpoint_addr = addr;
+ return 0;
}
lldb::addr_t
-NativeRegisterContextLinux_s390x::GetWatchpointAddress(uint32_t wp_index)
-{
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return LLDB_INVALID_ADDRESS;
- return m_watchpoint_addr;
+NativeRegisterContextLinux_s390x::GetWatchpointAddress(uint32_t wp_index) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return LLDB_INVALID_ADDRESS;
+ return m_watchpoint_addr;
}
-uint32_t
-NativeRegisterContextLinux_s390x::NumSupportedHardwareWatchpoints()
-{
- return 1;
+uint32_t NativeRegisterContextLinux_s390x::NumSupportedHardwareWatchpoints() {
+ return 1;
}
#endif // defined(__s390x__) && defined(__linux__)
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h
index 8cd4ab7f1242..4bd737767fa4 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h
@@ -16,121 +16,96 @@
#include "Plugins/Process/Utility/RegisterContext_s390x.h"
#include "Plugins/Process/Utility/lldb-s390x-register-enums.h"
-namespace lldb_private
-{
-namespace process_linux
-{
+namespace lldb_private {
+namespace process_linux {
class NativeProcessLinux;
-class NativeRegisterContextLinux_s390x : public NativeRegisterContextLinux
-{
+class NativeRegisterContextLinux_s390x : public NativeRegisterContextLinux {
public:
- NativeRegisterContextLinux_s390x(const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx);
+ NativeRegisterContextLinux_s390x(const ArchSpec &target_arch,
+ NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx);
- uint32_t
- GetRegisterSetCount() const override;
+ uint32_t GetRegisterSetCount() const override;
- const RegisterSet *
- GetRegisterSet(uint32_t set_index) const override;
+ const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
- uint32_t
- GetUserRegisterCount() const override;
+ uint32_t GetUserRegisterCount() const override;
- Error
- ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value) override;
+ Error ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) override;
- Error
- WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value) override;
+ Error WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) override;
- Error
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+ Error ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
- Error
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+ Error WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- Error
- IsWatchpointHit(uint32_t wp_index, bool &is_hit) override;
+ Error IsWatchpointHit(uint32_t wp_index, bool &is_hit) override;
- Error
- GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr) override;
+ Error GetWatchpointHitIndex(uint32_t &wp_index,
+ lldb::addr_t trap_addr) override;
- Error
- IsWatchpointVacant(uint32_t wp_index, bool &is_vacant) override;
+ Error IsWatchpointVacant(uint32_t wp_index, bool &is_vacant) override;
- bool
- ClearHardwareWatchpoint(uint32_t wp_index) override;
+ bool ClearHardwareWatchpoint(uint32_t wp_index) override;
- Error
- ClearAllHardwareWatchpoints() override;
+ Error ClearAllHardwareWatchpoints() override;
- uint32_t
- SetHardwareWatchpoint(lldb::addr_t addr, size_t size, uint32_t watch_flags) override;
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
+ uint32_t watch_flags) override;
- lldb::addr_t
- GetWatchpointAddress(uint32_t wp_index) override;
+ lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
- uint32_t
- NumSupportedHardwareWatchpoints() override;
+ uint32_t NumSupportedHardwareWatchpoints() override;
protected:
- Error
- DoReadRegisterValue(uint32_t offset, const char *reg_name, uint32_t size, RegisterValue &value) override;
+ Error DoReadRegisterValue(uint32_t offset, const char *reg_name,
+ uint32_t size, RegisterValue &value) override;
- Error
- DoWriteRegisterValue(uint32_t offset, const char *reg_name, const RegisterValue &value) override;
+ Error DoWriteRegisterValue(uint32_t offset, const char *reg_name,
+ const RegisterValue &value) override;
- Error
- DoReadGPR(void *buf, size_t buf_size) override;
+ Error DoReadGPR(void *buf, size_t buf_size) override;
- Error
- DoWriteGPR(void *buf, size_t buf_size) override;
+ Error DoWriteGPR(void *buf, size_t buf_size) override;
- Error
- DoReadFPR(void *buf, size_t buf_size) override;
+ Error DoReadFPR(void *buf, size_t buf_size) override;
- Error
- DoWriteFPR(void *buf, size_t buf_size) override;
+ Error DoWriteFPR(void *buf, size_t buf_size) override;
private:
- // Info about register ranges.
- struct RegInfo
- {
- uint32_t num_registers;
- uint32_t num_gpr_registers;
- uint32_t num_fpr_registers;
+ // Info about register ranges.
+ struct RegInfo {
+ uint32_t num_registers;
+ uint32_t num_gpr_registers;
+ uint32_t num_fpr_registers;
- uint32_t last_gpr;
- uint32_t first_fpr;
- uint32_t last_fpr;
- };
+ uint32_t last_gpr;
+ uint32_t first_fpr;
+ uint32_t last_fpr;
+ };
- // Private member variables.
- RegInfo m_reg_info;
- lldb::addr_t m_watchpoint_addr;
+ // Private member variables.
+ RegInfo m_reg_info;
+ lldb::addr_t m_watchpoint_addr;
- // Private member methods.
- bool
- IsRegisterSetAvailable(uint32_t set_index) const;
+ // Private member methods.
+ bool IsRegisterSetAvailable(uint32_t set_index) const;
- bool
- IsGPR(uint32_t reg_index) const;
+ bool IsGPR(uint32_t reg_index) const;
- bool
- IsFPR(uint32_t reg_index) const;
+ bool IsFPR(uint32_t reg_index) const;
- Error
- PeekUserArea(uint32_t offset, void *buf, size_t buf_size);
+ Error PeekUserArea(uint32_t offset, void *buf, size_t buf_size);
- Error
- PokeUserArea(uint32_t offset, const void *buf, size_t buf_size);
+ Error PokeUserArea(uint32_t offset, const void *buf, size_t buf_size);
- Error
- DoReadRegisterSet(uint32_t regset, void *buf, size_t buf_size);
+ Error DoReadRegisterSet(uint32_t regset, void *buf, size_t buf_size);
- Error
- DoWriteRegisterSet(uint32_t regset, const void *buf, size_t buf_size);
+ Error DoWriteRegisterSet(uint32_t regset, const void *buf, size_t buf_size);
};
} // namespace process_linux
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
index 2080d2ede372..2bd819b456ab 100755
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
@@ -11,15 +11,17 @@
#include "NativeRegisterContextLinux_x86_64.h"
-#include "lldb/Core/Log.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Error.h"
+#include "lldb/Core/Log.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Host/HostInfo.h"
#include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
+#include <linux/elf.h>
+
using namespace lldb_private;
using namespace lldb_private::process_linux;
@@ -27,297 +29,184 @@ using namespace lldb_private::process_linux;
// Private namespace.
// ----------------------------------------------------------------------------
-namespace
-{
- // x86 32-bit general purpose registers.
- const uint32_t
- g_gpr_regnums_i386[] =
- {
- lldb_eax_i386,
- lldb_ebx_i386,
- lldb_ecx_i386,
- lldb_edx_i386,
- lldb_edi_i386,
- lldb_esi_i386,
- lldb_ebp_i386,
- lldb_esp_i386,
- lldb_eip_i386,
- lldb_eflags_i386,
- lldb_cs_i386,
- lldb_fs_i386,
- lldb_gs_i386,
- lldb_ss_i386,
- lldb_ds_i386,
- lldb_es_i386,
- lldb_ax_i386,
- lldb_bx_i386,
- lldb_cx_i386,
- lldb_dx_i386,
- lldb_di_i386,
- lldb_si_i386,
- lldb_bp_i386,
- lldb_sp_i386,
- lldb_ah_i386,
- lldb_bh_i386,
- lldb_ch_i386,
- lldb_dh_i386,
- lldb_al_i386,
- lldb_bl_i386,
- lldb_cl_i386,
- lldb_dl_i386,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
- };
- static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) - 1 == k_num_gpr_registers_i386,
- "g_gpr_regnums_i386 has wrong number of register infos");
-
- // x86 32-bit floating point registers.
- const uint32_t
- g_fpu_regnums_i386[] =
- {
- lldb_fctrl_i386,
- lldb_fstat_i386,
- lldb_ftag_i386,
- lldb_fop_i386,
- lldb_fiseg_i386,
- lldb_fioff_i386,
- lldb_foseg_i386,
- lldb_fooff_i386,
- lldb_mxcsr_i386,
- lldb_mxcsrmask_i386,
- lldb_st0_i386,
- lldb_st1_i386,
- lldb_st2_i386,
- lldb_st3_i386,
- lldb_st4_i386,
- lldb_st5_i386,
- lldb_st6_i386,
- lldb_st7_i386,
- lldb_mm0_i386,
- lldb_mm1_i386,
- lldb_mm2_i386,
- lldb_mm3_i386,
- lldb_mm4_i386,
- lldb_mm5_i386,
- lldb_mm6_i386,
- lldb_mm7_i386,
- lldb_xmm0_i386,
- lldb_xmm1_i386,
- lldb_xmm2_i386,
- lldb_xmm3_i386,
- lldb_xmm4_i386,
- lldb_xmm5_i386,
- lldb_xmm6_i386,
- lldb_xmm7_i386,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
- };
- static_assert((sizeof(g_fpu_regnums_i386) / sizeof(g_fpu_regnums_i386[0])) - 1 == k_num_fpr_registers_i386,
- "g_fpu_regnums_i386 has wrong number of register infos");
-
- // x86 32-bit AVX registers.
- const uint32_t
- g_avx_regnums_i386[] =
- {
- lldb_ymm0_i386,
- lldb_ymm1_i386,
- lldb_ymm2_i386,
- lldb_ymm3_i386,
- lldb_ymm4_i386,
- lldb_ymm5_i386,
- lldb_ymm6_i386,
- lldb_ymm7_i386,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
- };
- static_assert((sizeof(g_avx_regnums_i386) / sizeof(g_avx_regnums_i386[0])) - 1 == k_num_avx_registers_i386,
- " g_avx_regnums_i386 has wrong number of register infos");
-
- // x86 64-bit general purpose registers.
- static const
- uint32_t g_gpr_regnums_x86_64[] =
- {
- lldb_rax_x86_64,
- lldb_rbx_x86_64,
- lldb_rcx_x86_64,
- lldb_rdx_x86_64,
- lldb_rdi_x86_64,
- lldb_rsi_x86_64,
- lldb_rbp_x86_64,
- lldb_rsp_x86_64,
- lldb_r8_x86_64,
- lldb_r9_x86_64,
- lldb_r10_x86_64,
- lldb_r11_x86_64,
- lldb_r12_x86_64,
- lldb_r13_x86_64,
- lldb_r14_x86_64,
- lldb_r15_x86_64,
- lldb_rip_x86_64,
- lldb_rflags_x86_64,
- lldb_cs_x86_64,
- lldb_fs_x86_64,
- lldb_gs_x86_64,
- lldb_ss_x86_64,
- lldb_ds_x86_64,
- lldb_es_x86_64,
- lldb_eax_x86_64,
- lldb_ebx_x86_64,
- lldb_ecx_x86_64,
- lldb_edx_x86_64,
- lldb_edi_x86_64,
- lldb_esi_x86_64,
- lldb_ebp_x86_64,
- lldb_esp_x86_64,
- lldb_r8d_x86_64, // Low 32 bits or r8
- lldb_r9d_x86_64, // Low 32 bits or r9
- lldb_r10d_x86_64, // Low 32 bits or r10
- lldb_r11d_x86_64, // Low 32 bits or r11
- lldb_r12d_x86_64, // Low 32 bits or r12
- lldb_r13d_x86_64, // Low 32 bits or r13
- lldb_r14d_x86_64, // Low 32 bits or r14
- lldb_r15d_x86_64, // Low 32 bits or r15
- lldb_ax_x86_64,
- lldb_bx_x86_64,
- lldb_cx_x86_64,
- lldb_dx_x86_64,
- lldb_di_x86_64,
- lldb_si_x86_64,
- lldb_bp_x86_64,
- lldb_sp_x86_64,
- lldb_r8w_x86_64, // Low 16 bits or r8
- lldb_r9w_x86_64, // Low 16 bits or r9
- lldb_r10w_x86_64, // Low 16 bits or r10
- lldb_r11w_x86_64, // Low 16 bits or r11
- lldb_r12w_x86_64, // Low 16 bits or r12
- lldb_r13w_x86_64, // Low 16 bits or r13
- lldb_r14w_x86_64, // Low 16 bits or r14
- lldb_r15w_x86_64, // Low 16 bits or r15
- lldb_ah_x86_64,
- lldb_bh_x86_64,
- lldb_ch_x86_64,
- lldb_dh_x86_64,
- lldb_al_x86_64,
- lldb_bl_x86_64,
- lldb_cl_x86_64,
- lldb_dl_x86_64,
- lldb_dil_x86_64,
- lldb_sil_x86_64,
- lldb_bpl_x86_64,
- lldb_spl_x86_64,
- lldb_r8l_x86_64, // Low 8 bits or r8
- lldb_r9l_x86_64, // Low 8 bits or r9
- lldb_r10l_x86_64, // Low 8 bits or r10
- lldb_r11l_x86_64, // Low 8 bits or r11
- lldb_r12l_x86_64, // Low 8 bits or r12
- lldb_r13l_x86_64, // Low 8 bits or r13
- lldb_r14l_x86_64, // Low 8 bits or r14
- lldb_r15l_x86_64, // Low 8 bits or r15
- LLDB_INVALID_REGNUM // register sets need to end with this flag
- };
- static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) - 1 == k_num_gpr_registers_x86_64,
- "g_gpr_regnums_x86_64 has wrong number of register infos");
-
- // x86 64-bit floating point registers.
- static const uint32_t
- g_fpu_regnums_x86_64[] =
- {
- lldb_fctrl_x86_64,
- lldb_fstat_x86_64,
- lldb_ftag_x86_64,
- lldb_fop_x86_64,
- lldb_fiseg_x86_64,
- lldb_fioff_x86_64,
- lldb_foseg_x86_64,
- lldb_fooff_x86_64,
- lldb_mxcsr_x86_64,
- lldb_mxcsrmask_x86_64,
- lldb_st0_x86_64,
- lldb_st1_x86_64,
- lldb_st2_x86_64,
- lldb_st3_x86_64,
- lldb_st4_x86_64,
- lldb_st5_x86_64,
- lldb_st6_x86_64,
- lldb_st7_x86_64,
- lldb_mm0_x86_64,
- lldb_mm1_x86_64,
- lldb_mm2_x86_64,
- lldb_mm3_x86_64,
- lldb_mm4_x86_64,
- lldb_mm5_x86_64,
- lldb_mm6_x86_64,
- lldb_mm7_x86_64,
- lldb_xmm0_x86_64,
- lldb_xmm1_x86_64,
- lldb_xmm2_x86_64,
- lldb_xmm3_x86_64,
- lldb_xmm4_x86_64,
- lldb_xmm5_x86_64,
- lldb_xmm6_x86_64,
- lldb_xmm7_x86_64,
- lldb_xmm8_x86_64,
- lldb_xmm9_x86_64,
- lldb_xmm10_x86_64,
- lldb_xmm11_x86_64,
- lldb_xmm12_x86_64,
- lldb_xmm13_x86_64,
- lldb_xmm14_x86_64,
- lldb_xmm15_x86_64,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
- };
- static_assert((sizeof(g_fpu_regnums_x86_64) / sizeof(g_fpu_regnums_x86_64[0])) - 1 == k_num_fpr_registers_x86_64,
- "g_fpu_regnums_x86_64 has wrong number of register infos");
-
- // x86 64-bit AVX registers.
- static const uint32_t
- g_avx_regnums_x86_64[] =
- {
- lldb_ymm0_x86_64,
- lldb_ymm1_x86_64,
- lldb_ymm2_x86_64,
- lldb_ymm3_x86_64,
- lldb_ymm4_x86_64,
- lldb_ymm5_x86_64,
- lldb_ymm6_x86_64,
- lldb_ymm7_x86_64,
- lldb_ymm8_x86_64,
- lldb_ymm9_x86_64,
- lldb_ymm10_x86_64,
- lldb_ymm11_x86_64,
- lldb_ymm12_x86_64,
- lldb_ymm13_x86_64,
- lldb_ymm14_x86_64,
- lldb_ymm15_x86_64,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
- };
- static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) - 1 == k_num_avx_registers_x86_64,
- "g_avx_regnums_x86_64 has wrong number of register infos");
-
- // Number of register sets provided by this context.
- enum
- {
- k_num_extended_register_sets = 1,
- k_num_register_sets = 3
- };
-
- // Register sets for x86 32-bit.
- static const RegisterSet
- g_reg_sets_i386[k_num_register_sets] =
- {
- { "General Purpose Registers", "gpr", k_num_gpr_registers_i386, g_gpr_regnums_i386 },
- { "Floating Point Registers", "fpu", k_num_fpr_registers_i386, g_fpu_regnums_i386 },
- { "Advanced Vector Extensions", "avx", k_num_avx_registers_i386, g_avx_regnums_i386 }
- };
-
- // Register sets for x86 64-bit.
- static const RegisterSet
- g_reg_sets_x86_64[k_num_register_sets] =
- {
- { "General Purpose Registers", "gpr", k_num_gpr_registers_x86_64, g_gpr_regnums_x86_64 },
- { "Floating Point Registers", "fpu", k_num_fpr_registers_x86_64, g_fpu_regnums_x86_64 },
- { "Advanced Vector Extensions", "avx", k_num_avx_registers_x86_64, g_avx_regnums_x86_64 }
- };
+namespace {
+// x86 32-bit general purpose registers.
+const uint32_t g_gpr_regnums_i386[] = {
+ lldb_eax_i386, lldb_ebx_i386, lldb_ecx_i386, lldb_edx_i386,
+ lldb_edi_i386, lldb_esi_i386, lldb_ebp_i386, lldb_esp_i386,
+ lldb_eip_i386, lldb_eflags_i386, lldb_cs_i386, lldb_fs_i386,
+ lldb_gs_i386, lldb_ss_i386, lldb_ds_i386, lldb_es_i386,
+ lldb_ax_i386, lldb_bx_i386, lldb_cx_i386, lldb_dx_i386,
+ lldb_di_i386, lldb_si_i386, lldb_bp_i386, lldb_sp_i386,
+ lldb_ah_i386, lldb_bh_i386, lldb_ch_i386, lldb_dh_i386,
+ lldb_al_i386, lldb_bl_i386, lldb_cl_i386, lldb_dl_i386,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) -
+ 1 ==
+ k_num_gpr_registers_i386,
+ "g_gpr_regnums_i386 has wrong number of register infos");
+
+// x86 32-bit floating point registers.
+const uint32_t g_fpu_regnums_i386[] = {
+ lldb_fctrl_i386, lldb_fstat_i386, lldb_ftag_i386, lldb_fop_i386,
+ lldb_fiseg_i386, lldb_fioff_i386, lldb_foseg_i386, lldb_fooff_i386,
+ lldb_mxcsr_i386, lldb_mxcsrmask_i386, lldb_st0_i386, lldb_st1_i386,
+ lldb_st2_i386, lldb_st3_i386, lldb_st4_i386, lldb_st5_i386,
+ lldb_st6_i386, lldb_st7_i386, lldb_mm0_i386, lldb_mm1_i386,
+ lldb_mm2_i386, lldb_mm3_i386, lldb_mm4_i386, lldb_mm5_i386,
+ lldb_mm6_i386, lldb_mm7_i386, lldb_xmm0_i386, lldb_xmm1_i386,
+ lldb_xmm2_i386, lldb_xmm3_i386, lldb_xmm4_i386, lldb_xmm5_i386,
+ lldb_xmm6_i386, lldb_xmm7_i386,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_fpu_regnums_i386) / sizeof(g_fpu_regnums_i386[0])) -
+ 1 ==
+ k_num_fpr_registers_i386,
+ "g_fpu_regnums_i386 has wrong number of register infos");
+
+// x86 32-bit AVX registers.
+const uint32_t g_avx_regnums_i386[] = {
+ lldb_ymm0_i386, lldb_ymm1_i386, lldb_ymm2_i386, lldb_ymm3_i386,
+ lldb_ymm4_i386, lldb_ymm5_i386, lldb_ymm6_i386, lldb_ymm7_i386,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_avx_regnums_i386) / sizeof(g_avx_regnums_i386[0])) -
+ 1 ==
+ k_num_avx_registers_i386,
+ " g_avx_regnums_i386 has wrong number of register infos");
+
+// x64 32-bit MPX registers.
+static const uint32_t g_mpx_regnums_i386[] = {
+ lldb_bnd0_i386, lldb_bnd1_i386, lldb_bnd2_i386, lldb_bnd3_i386,
+ lldb_bndcfgu_i386, lldb_bndstatus_i386,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_mpx_regnums_i386) / sizeof(g_mpx_regnums_i386[0])) -
+ 1 ==
+ k_num_mpx_registers_i386,
+ "g_mpx_regnums_x86_64 has wrong number of register infos");
+
+// x86 64-bit general purpose registers.
+static const uint32_t g_gpr_regnums_x86_64[] = {
+ lldb_rax_x86_64, lldb_rbx_x86_64, lldb_rcx_x86_64, lldb_rdx_x86_64,
+ lldb_rdi_x86_64, lldb_rsi_x86_64, lldb_rbp_x86_64, lldb_rsp_x86_64,
+ lldb_r8_x86_64, lldb_r9_x86_64, lldb_r10_x86_64, lldb_r11_x86_64,
+ lldb_r12_x86_64, lldb_r13_x86_64, lldb_r14_x86_64, lldb_r15_x86_64,
+ lldb_rip_x86_64, lldb_rflags_x86_64, lldb_cs_x86_64, lldb_fs_x86_64,
+ lldb_gs_x86_64, lldb_ss_x86_64, lldb_ds_x86_64, lldb_es_x86_64,
+ lldb_eax_x86_64, lldb_ebx_x86_64, lldb_ecx_x86_64, lldb_edx_x86_64,
+ lldb_edi_x86_64, lldb_esi_x86_64, lldb_ebp_x86_64, lldb_esp_x86_64,
+ lldb_r8d_x86_64, // Low 32 bits or r8
+ lldb_r9d_x86_64, // Low 32 bits or r9
+ lldb_r10d_x86_64, // Low 32 bits or r10
+ lldb_r11d_x86_64, // Low 32 bits or r11
+ lldb_r12d_x86_64, // Low 32 bits or r12
+ lldb_r13d_x86_64, // Low 32 bits or r13
+ lldb_r14d_x86_64, // Low 32 bits or r14
+ lldb_r15d_x86_64, // Low 32 bits or r15
+ lldb_ax_x86_64, lldb_bx_x86_64, lldb_cx_x86_64, lldb_dx_x86_64,
+ lldb_di_x86_64, lldb_si_x86_64, lldb_bp_x86_64, lldb_sp_x86_64,
+ lldb_r8w_x86_64, // Low 16 bits or r8
+ lldb_r9w_x86_64, // Low 16 bits or r9
+ lldb_r10w_x86_64, // Low 16 bits or r10
+ lldb_r11w_x86_64, // Low 16 bits or r11
+ lldb_r12w_x86_64, // Low 16 bits or r12
+ lldb_r13w_x86_64, // Low 16 bits or r13
+ lldb_r14w_x86_64, // Low 16 bits or r14
+ lldb_r15w_x86_64, // Low 16 bits or r15
+ lldb_ah_x86_64, lldb_bh_x86_64, lldb_ch_x86_64, lldb_dh_x86_64,
+ lldb_al_x86_64, lldb_bl_x86_64, lldb_cl_x86_64, lldb_dl_x86_64,
+ lldb_dil_x86_64, lldb_sil_x86_64, lldb_bpl_x86_64, lldb_spl_x86_64,
+ lldb_r8l_x86_64, // Low 8 bits or r8
+ lldb_r9l_x86_64, // Low 8 bits or r9
+ lldb_r10l_x86_64, // Low 8 bits or r10
+ lldb_r11l_x86_64, // Low 8 bits or r11
+ lldb_r12l_x86_64, // Low 8 bits or r12
+ lldb_r13l_x86_64, // Low 8 bits or r13
+ lldb_r14l_x86_64, // Low 8 bits or r14
+ lldb_r15l_x86_64, // Low 8 bits or r15
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) -
+ 1 ==
+ k_num_gpr_registers_x86_64,
+ "g_gpr_regnums_x86_64 has wrong number of register infos");
+
+// x86 64-bit floating point registers.
+static const uint32_t g_fpu_regnums_x86_64[] = {
+ lldb_fctrl_x86_64, lldb_fstat_x86_64, lldb_ftag_x86_64,
+ lldb_fop_x86_64, lldb_fiseg_x86_64, lldb_fioff_x86_64,
+ lldb_foseg_x86_64, lldb_fooff_x86_64, lldb_mxcsr_x86_64,
+ lldb_mxcsrmask_x86_64, lldb_st0_x86_64, lldb_st1_x86_64,
+ lldb_st2_x86_64, lldb_st3_x86_64, lldb_st4_x86_64,
+ lldb_st5_x86_64, lldb_st6_x86_64, lldb_st7_x86_64,
+ lldb_mm0_x86_64, lldb_mm1_x86_64, lldb_mm2_x86_64,
+ lldb_mm3_x86_64, lldb_mm4_x86_64, lldb_mm5_x86_64,
+ lldb_mm6_x86_64, lldb_mm7_x86_64, lldb_xmm0_x86_64,
+ lldb_xmm1_x86_64, lldb_xmm2_x86_64, lldb_xmm3_x86_64,
+ lldb_xmm4_x86_64, lldb_xmm5_x86_64, lldb_xmm6_x86_64,
+ lldb_xmm7_x86_64, lldb_xmm8_x86_64, lldb_xmm9_x86_64,
+ lldb_xmm10_x86_64, lldb_xmm11_x86_64, lldb_xmm12_x86_64,
+ lldb_xmm13_x86_64, lldb_xmm14_x86_64, lldb_xmm15_x86_64,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_fpu_regnums_x86_64) / sizeof(g_fpu_regnums_x86_64[0])) -
+ 1 ==
+ k_num_fpr_registers_x86_64,
+ "g_fpu_regnums_x86_64 has wrong number of register infos");
+
+// x86 64-bit AVX registers.
+static const uint32_t g_avx_regnums_x86_64[] = {
+ lldb_ymm0_x86_64, lldb_ymm1_x86_64, lldb_ymm2_x86_64, lldb_ymm3_x86_64,
+ lldb_ymm4_x86_64, lldb_ymm5_x86_64, lldb_ymm6_x86_64, lldb_ymm7_x86_64,
+ lldb_ymm8_x86_64, lldb_ymm9_x86_64, lldb_ymm10_x86_64, lldb_ymm11_x86_64,
+ lldb_ymm12_x86_64, lldb_ymm13_x86_64, lldb_ymm14_x86_64, lldb_ymm15_x86_64,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) -
+ 1 ==
+ k_num_avx_registers_x86_64,
+ "g_avx_regnums_x86_64 has wrong number of register infos");
+
+// x86 64-bit MPX registers.
+static const uint32_t g_mpx_regnums_x86_64[] = {
+ lldb_bnd0_x86_64, lldb_bnd1_x86_64, lldb_bnd2_x86_64,
+ lldb_bnd3_x86_64, lldb_bndcfgu_x86_64, lldb_bndstatus_x86_64,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_mpx_regnums_x86_64) / sizeof(g_mpx_regnums_x86_64[0])) -
+ 1 ==
+ k_num_mpx_registers_x86_64,
+ "g_mpx_regnums_x86_64 has wrong number of register infos");
+
+// Number of register sets provided by this context.
+enum { k_num_extended_register_sets = 2, k_num_register_sets = 4 };
+
+// Register sets for x86 32-bit.
+static const RegisterSet g_reg_sets_i386[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_i386,
+ g_gpr_regnums_i386},
+ {"Floating Point Registers", "fpu", k_num_fpr_registers_i386,
+ g_fpu_regnums_i386},
+ {"Advanced Vector Extensions", "avx", k_num_avx_registers_i386,
+ g_avx_regnums_i386},
+ { "Memory Protection Extensions", "mpx", k_num_mpx_registers_i386,
+ g_mpx_regnums_i386}};
+
+// Register sets for x86 64-bit.
+static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_x86_64,
+ g_gpr_regnums_x86_64},
+ {"Floating Point Registers", "fpu", k_num_fpr_registers_x86_64,
+ g_fpu_regnums_x86_64},
+ {"Advanced Vector Extensions", "avx", k_num_avx_registers_x86_64,
+ g_avx_regnums_x86_64},
+ { "Memory Protection Extensions", "mpx", k_num_mpx_registers_x86_64,
+ g_mpx_regnums_x86_64}};
}
-#define REG_CONTEXT_SIZE (GetRegisterInfoInterface ().GetGPRSize () + sizeof(FPR))
+#define REG_CONTEXT_SIZE (GetRegisterInfoInterface().GetGPRSize() + sizeof(FPR))
// ----------------------------------------------------------------------------
// Required ptrace defines.
@@ -331,909 +220,1002 @@ namespace
#define NT_PRXFPREG 0x46e62b7f
#endif
-NativeRegisterContextLinux*
-NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(const ArchSpec& target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx)
-{
- return new NativeRegisterContextLinux_x86_64(target_arch, native_thread, concrete_frame_idx);
+// On x86_64 NT_PRFPREG is used to access the FXSAVE area. On i386, we need to
+// use NT_PRXFPREG.
+static inline unsigned int fxsr_regset(const ArchSpec &arch) {
+ return arch.GetAddressByteSize() == 8 ? NT_PRFPREG : NT_PRXFPREG;
}
// ----------------------------------------------------------------------------
-// NativeRegisterContextLinux_x86_64 members.
+// Required MPX define.
// ----------------------------------------------------------------------------
-static RegisterInfoInterface*
-CreateRegisterInfoInterface(const ArchSpec& target_arch)
-{
- if (HostInfo::GetArchitecture().GetAddressByteSize() == 4)
- {
- // 32-bit hosts run with a RegisterContextLinux_i386 context.
- return new RegisterContextLinux_i386(target_arch);
- }
- else
- {
- assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
- "Register setting path assumes this is a 64-bit host");
- // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the x86_64 register context.
- return new RegisterContextLinux_x86_64 (target_arch);
- }
-}
+// Support MPX extensions also if compiled with compiler without MPX support.
+#ifndef bit_MPX
+#define bit_MPX 0x4000
+#endif
-NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64 (const ArchSpec& target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx) :
- NativeRegisterContextLinux (native_thread, concrete_frame_idx, CreateRegisterInfoInterface(target_arch)),
- m_fpr_type (eFPRTypeNotValid),
- m_fpr (),
- m_iovec (),
- m_ymm_set (),
- m_reg_info (),
- m_gpr_x86_64 ()
-{
- // Set up data about ranges of valid registers.
- switch (target_arch.GetMachine ())
- {
- case llvm::Triple::x86:
- m_reg_info.num_registers = k_num_registers_i386;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_i386;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_i386;
- m_reg_info.num_avx_registers = k_num_avx_registers_i386;
- m_reg_info.last_gpr = k_last_gpr_i386;
- m_reg_info.first_fpr = k_first_fpr_i386;
- m_reg_info.last_fpr = k_last_fpr_i386;
- m_reg_info.first_st = lldb_st0_i386;
- m_reg_info.last_st = lldb_st7_i386;
- m_reg_info.first_mm = lldb_mm0_i386;
- m_reg_info.last_mm = lldb_mm7_i386;
- m_reg_info.first_xmm = lldb_xmm0_i386;
- m_reg_info.last_xmm = lldb_xmm7_i386;
- m_reg_info.first_ymm = lldb_ymm0_i386;
- m_reg_info.last_ymm = lldb_ymm7_i386;
- m_reg_info.first_dr = lldb_dr0_i386;
- m_reg_info.gpr_flags = lldb_eflags_i386;
- break;
- case llvm::Triple::x86_64:
- m_reg_info.num_registers = k_num_registers_x86_64;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_x86_64;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_x86_64;
- m_reg_info.num_avx_registers = k_num_avx_registers_x86_64;
- m_reg_info.last_gpr = k_last_gpr_x86_64;
- m_reg_info.first_fpr = k_first_fpr_x86_64;
- m_reg_info.last_fpr = k_last_fpr_x86_64;
- m_reg_info.first_st = lldb_st0_x86_64;
- m_reg_info.last_st = lldb_st7_x86_64;
- m_reg_info.first_mm = lldb_mm0_x86_64;
- m_reg_info.last_mm = lldb_mm7_x86_64;
- m_reg_info.first_xmm = lldb_xmm0_x86_64;
- m_reg_info.last_xmm = lldb_xmm15_x86_64;
- m_reg_info.first_ymm = lldb_ymm0_x86_64;
- m_reg_info.last_ymm = lldb_ymm15_x86_64;
- m_reg_info.first_dr = lldb_dr0_x86_64;
- m_reg_info.gpr_flags = lldb_rflags_x86_64;
- break;
- default:
- assert(false && "Unhandled target architecture.");
- break;
- }
+// ----------------------------------------------------------------------------
+// XCR0 extended register sets masks.
+// ----------------------------------------------------------------------------
+#define mask_XSTATE_AVX (1ULL << 2)
+#define mask_XSTATE_BNDREGS (1ULL << 3)
+#define mask_XSTATE_BNDCFG (1ULL << 4)
+#define mask_XSTATE_MPX (mask_XSTATE_BNDREGS | mask_XSTATE_BNDCFG)
+
+NativeRegisterContextLinux *
+NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx) {
+ return new NativeRegisterContextLinux_x86_64(target_arch, native_thread,
+ concrete_frame_idx);
+}
- // Initialize m_iovec to point to the buffer and buffer size
- // using the conventions of Berkeley style UIO structures, as required
- // by PTRACE extensions.
- m_iovec.iov_base = &m_fpr.xstate.xsave;
- m_iovec.iov_len = sizeof(m_fpr.xstate.xsave);
+// ----------------------------------------------------------------------------
+// NativeRegisterContextLinux_x86_64 members.
+// ----------------------------------------------------------------------------
- // Clear out the FPR state.
- ::memset(&m_fpr, 0, sizeof(FPR));
+static RegisterInfoInterface *
+CreateRegisterInfoInterface(const ArchSpec &target_arch) {
+ if (HostInfo::GetArchitecture().GetAddressByteSize() == 4) {
+ // 32-bit hosts run with a RegisterContextLinux_i386 context.
+ return new RegisterContextLinux_i386(target_arch);
+ } else {
+ assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
+ "Register setting path assumes this is a 64-bit host");
+ // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the
+ // x86_64 register context.
+ return new RegisterContextLinux_x86_64(target_arch);
+ }
+}
- // Store byte offset of fctrl (i.e. first register of FPR)
- const RegisterInfo *reg_info_fctrl = GetRegisterInfoByName("fctrl");
- m_fctrl_offset_in_userarea = reg_info_fctrl->byte_offset;
+NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx)
+ : NativeRegisterContextLinux(native_thread, concrete_frame_idx,
+ CreateRegisterInfoInterface(target_arch)),
+ m_xstate_type(XStateType::Invalid), m_fpr(), m_iovec(), m_ymm_set(),
+ m_mpx_set(), m_reg_info(), m_gpr_x86_64() {
+ // Set up data about ranges of valid registers.
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::x86:
+ m_reg_info.num_registers = k_num_registers_i386;
+ m_reg_info.num_gpr_registers = k_num_gpr_registers_i386;
+ m_reg_info.num_fpr_registers = k_num_fpr_registers_i386;
+ m_reg_info.num_avx_registers = k_num_avx_registers_i386;
+ m_reg_info.num_mpx_registers = k_num_mpx_registers_i386;
+ m_reg_info.last_gpr = k_last_gpr_i386;
+ m_reg_info.first_fpr = k_first_fpr_i386;
+ m_reg_info.last_fpr = k_last_fpr_i386;
+ m_reg_info.first_st = lldb_st0_i386;
+ m_reg_info.last_st = lldb_st7_i386;
+ m_reg_info.first_mm = lldb_mm0_i386;
+ m_reg_info.last_mm = lldb_mm7_i386;
+ m_reg_info.first_xmm = lldb_xmm0_i386;
+ m_reg_info.last_xmm = lldb_xmm7_i386;
+ m_reg_info.first_ymm = lldb_ymm0_i386;
+ m_reg_info.last_ymm = lldb_ymm7_i386;
+ m_reg_info.first_mpxr = lldb_bnd0_i386;
+ m_reg_info.last_mpxr = lldb_bnd3_i386;
+ m_reg_info.first_mpxc = lldb_bndcfgu_i386;
+ m_reg_info.last_mpxc = lldb_bndstatus_i386;
+ m_reg_info.first_dr = lldb_dr0_i386;
+ m_reg_info.gpr_flags = lldb_eflags_i386;
+ break;
+ case llvm::Triple::x86_64:
+ m_reg_info.num_registers = k_num_registers_x86_64;
+ m_reg_info.num_gpr_registers = k_num_gpr_registers_x86_64;
+ m_reg_info.num_fpr_registers = k_num_fpr_registers_x86_64;
+ m_reg_info.num_avx_registers = k_num_avx_registers_x86_64;
+ m_reg_info.num_mpx_registers = k_num_mpx_registers_x86_64;
+ m_reg_info.last_gpr = k_last_gpr_x86_64;
+ m_reg_info.first_fpr = k_first_fpr_x86_64;
+ m_reg_info.last_fpr = k_last_fpr_x86_64;
+ m_reg_info.first_st = lldb_st0_x86_64;
+ m_reg_info.last_st = lldb_st7_x86_64;
+ m_reg_info.first_mm = lldb_mm0_x86_64;
+ m_reg_info.last_mm = lldb_mm7_x86_64;
+ m_reg_info.first_xmm = lldb_xmm0_x86_64;
+ m_reg_info.last_xmm = lldb_xmm15_x86_64;
+ m_reg_info.first_ymm = lldb_ymm0_x86_64;
+ m_reg_info.last_ymm = lldb_ymm15_x86_64;
+ m_reg_info.first_mpxr = lldb_bnd0_x86_64;
+ m_reg_info.last_mpxr = lldb_bnd3_x86_64;
+ m_reg_info.first_mpxc = lldb_bndcfgu_x86_64;
+ m_reg_info.last_mpxc = lldb_bndstatus_x86_64;
+ m_reg_info.first_dr = lldb_dr0_x86_64;
+ m_reg_info.gpr_flags = lldb_rflags_x86_64;
+ break;
+ default:
+ assert(false && "Unhandled target architecture.");
+ break;
+ }
+
+ // Initialize m_iovec to point to the buffer and buffer size
+ // using the conventions of Berkeley style UIO structures, as required
+ // by PTRACE extensions.
+ m_iovec.iov_base = &m_fpr.xstate.xsave;
+ m_iovec.iov_len = sizeof(m_fpr.xstate.xsave);
+
+ // Clear out the FPR state.
+ ::memset(&m_fpr, 0, sizeof(FPR));
+
+ // Store byte offset of fctrl (i.e. first register of FPR)
+ const RegisterInfo *reg_info_fctrl = GetRegisterInfoByName("fctrl");
+ m_fctrl_offset_in_userarea = reg_info_fctrl->byte_offset;
}
// CONSIDER after local and llgs debugging are merged, register set support can
// be moved into a base x86-64 class with IsRegisterSetAvailable made virtual.
-uint32_t
-NativeRegisterContextLinux_x86_64::GetRegisterSetCount () const
-{
- uint32_t sets = 0;
- for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index)
- {
- if (IsRegisterSetAvailable (set_index))
- ++sets;
- }
-
- return sets;
+uint32_t NativeRegisterContextLinux_x86_64::GetRegisterSetCount() const {
+ uint32_t sets = 0;
+ for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) {
+ if (IsRegisterSetAvailable(set_index))
+ ++sets;
+ }
+
+ return sets;
}
-uint32_t
-NativeRegisterContextLinux_x86_64::GetUserRegisterCount() const
-{
- uint32_t count = 0;
- for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index)
- {
- const RegisterSet* set = GetRegisterSet(set_index);
- if (set)
- count += set->num_registers;
- }
- return count;
+uint32_t NativeRegisterContextLinux_x86_64::GetUserRegisterCount() const {
+ uint32_t count = 0;
+ for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) {
+ const RegisterSet *set = GetRegisterSet(set_index);
+ if (set)
+ count += set->num_registers;
+ }
+ return count;
}
const RegisterSet *
-NativeRegisterContextLinux_x86_64::GetRegisterSet (uint32_t set_index) const
-{
- if (!IsRegisterSetAvailable (set_index))
- return nullptr;
-
- switch (GetRegisterInfoInterface ().GetTargetArchitecture ().GetMachine ())
- {
- case llvm::Triple::x86:
- return &g_reg_sets_i386[set_index];
- case llvm::Triple::x86_64:
- return &g_reg_sets_x86_64[set_index];
- default:
- assert (false && "Unhandled target architecture.");
- return nullptr;
- }
+NativeRegisterContextLinux_x86_64::GetRegisterSet(uint32_t set_index) const {
+ if (!IsRegisterSetAvailable(set_index))
+ return nullptr;
+ switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
+ case llvm::Triple::x86:
+ return &g_reg_sets_i386[set_index];
+ case llvm::Triple::x86_64:
+ return &g_reg_sets_x86_64[set_index];
+ default:
+ assert(false && "Unhandled target architecture.");
return nullptr;
-}
+ }
-Error
-NativeRegisterContextLinux_x86_64::ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value)
-{
- Error error;
+ return nullptr;
+}
- if (!reg_info)
- {
- error.SetErrorString ("reg_info NULL");
- return error;
- }
+Error NativeRegisterContextLinux_x86_64::ReadRegister(
+ const RegisterInfo *reg_info, RegisterValue &reg_value) {
+ Error error;
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (reg == LLDB_INVALID_REGNUM)
- {
- // This is likely an internal register for lldb use only and should not be directly queried.
- error.SetErrorStringWithFormat ("register \"%s\" is an internal-only lldb register, cannot read directly", reg_info->name);
- return error;
- }
+ if (!reg_info) {
+ error.SetErrorString("reg_info NULL");
+ return error;
+ }
+
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ if (reg == LLDB_INVALID_REGNUM) {
+ // This is likely an internal register for lldb use only and should not be
+ // directly queried.
+ error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb "
+ "register, cannot read directly",
+ reg_info->name);
+ return error;
+ }
- if (IsFPR(reg, GetFPRType()))
- {
- error = ReadFPR();
- if (error.Fail())
- return error;
+ if (IsFPR(reg) || IsAVX(reg) || IsMPX(reg)) {
+ error = ReadFPR();
+ if (error.Fail())
+ return error;
+ } 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];
- }
- error = ReadRegisterRaw(full_reg, reg_value);
+ error = ReadRegisterRaw(full_reg, reg_value);
- if (error.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))
- reg_value.SetUInt64(reg_value.GetAsUInt64() >> 8);
+ if (error.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))
+ reg_value.SetUInt64(reg_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 (reg_value.GetByteSize() > reg_info->byte_size)
- reg_value.SetType(reg_info);
- }
- return error;
+ // 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 (reg_value.GetByteSize() > reg_info->byte_size)
+ reg_value.SetType(reg_info);
}
-
- if (reg_info->encoding == lldb::eEncodingVector)
- {
- lldb::ByteOrder byte_order = GetByteOrder();
-
- if (byte_order != lldb::eByteOrderInvalid)
- {
- if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
- reg_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)
- reg_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)
- reg_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() == eFPRTypeXSAVE && CopyXSTATEtoYMM(reg, byte_order))
- reg_value.SetBytes(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, reg_info->byte_size, byte_order);
- else
- {
- error.SetErrorString ("failed to copy ymm register value");
- return error;
- }
- }
-
- if (reg_value.GetType() != RegisterValue::eTypeBytes)
- error.SetErrorString ("write failed - type was expected to be RegisterValue::eTypeBytes");
-
- return error;
+ return error;
+ }
+
+ if (reg_info->encoding == lldb::eEncodingVector) {
+ lldb::ByteOrder byte_order = GetByteOrder();
+
+ if (byte_order != lldb::eByteOrderInvalid) {
+ if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
+ reg_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)
+ reg_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)
+ reg_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 (CopyXSTATEtoYMM(reg, byte_order))
+ reg_value.SetBytes(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
+ reg_info->byte_size, byte_order);
+ else {
+ error.SetErrorString("failed to copy ymm register value");
+ return error;
}
+ }
+ if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
+ if (CopyXSTATEtoMPX(reg))
+ reg_value.SetBytes(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes,
+ reg_info->byte_size, byte_order);
+ else {
+ error.SetErrorString("failed to copy mpx register value");
+ return error;
+ }
+ }
+ if (reg >= m_reg_info.first_mpxc && reg <= m_reg_info.last_mpxc) {
+ if (CopyXSTATEtoMPX(reg))
+ reg_value.SetBytes(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes,
+ reg_info->byte_size, byte_order);
+ else {
+ error.SetErrorString("failed to copy mpx register value");
+ return error;
+ }
+ }
- error.SetErrorString ("byte order is invalid");
- return error;
- }
+ if (reg_value.GetType() != RegisterValue::eTypeBytes)
+ error.SetErrorString(
+ "write failed - type was expected to be RegisterValue::eTypeBytes");
- // 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(PTRACE_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:
- reg_value.SetUInt8(*(uint8_t *)src);
- break;
- case 2:
- reg_value.SetUInt16(*(uint16_t *)src);
- break;
- case 4:
- reg_value.SetUInt32(*(uint32_t *)src);
- break;
- case 8:
- reg_value.SetUInt64(*(uint64_t *)src);
- break;
- default:
- assert(false && "Unhandled data size.");
- error.SetErrorStringWithFormat ("unhandled byte size: %" PRIu32, reg_info->byte_size);
- break;
+ return error;
}
+ error.SetErrorString("byte order is invalid");
return error;
+ }
+
+ // 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(PTRACE_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:
+ reg_value.SetUInt8(*(uint8_t *)src);
+ break;
+ case 2:
+ reg_value.SetUInt16(*(uint16_t *)src);
+ break;
+ case 4:
+ reg_value.SetUInt32(*(uint32_t *)src);
+ break;
+ case 8:
+ reg_value.SetUInt64(*(uint64_t *)src);
+ break;
+ default:
+ assert(false && "Unhandled data size.");
+ error.SetErrorStringWithFormat("unhandled byte size: %" PRIu32,
+ reg_info->byte_size);
+ break;
+ }
+
+ return error;
}
-Error
-NativeRegisterContextLinux_x86_64::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value)
-{
- assert (reg_info && "reg_info is null");
-
- const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (reg_index == LLDB_INVALID_REGNUM)
- return Error ("no lldb regnum for %s", reg_info && reg_info->name ? reg_info->name : "<unknown register>");
-
- if (IsGPR(reg_index))
- return WriteRegisterRaw(reg_index, reg_value);
-
- if (IsFPR(reg_index, GetFPRType()))
- {
- if (reg_info->encoding == lldb::eEncodingVector)
- {
- if (reg_index >= m_reg_info.first_st && reg_index <= m_reg_info.last_st)
- ::memcpy (m_fpr.xstate.fxsave.stmm[reg_index - m_reg_info.first_st].bytes, reg_value.GetBytes(), reg_value.GetByteSize());
-
- if (reg_index >= m_reg_info.first_mm && reg_index <= m_reg_info.last_mm)
- ::memcpy (m_fpr.xstate.fxsave.stmm[reg_index - m_reg_info.first_mm].bytes, reg_value.GetBytes(), reg_value.GetByteSize());
-
- if (reg_index >= m_reg_info.first_xmm && reg_index <= m_reg_info.last_xmm)
- ::memcpy (m_fpr.xstate.fxsave.xmm[reg_index - m_reg_info.first_xmm].bytes, reg_value.GetBytes(), reg_value.GetByteSize());
-
- if (reg_index >= m_reg_info.first_ymm && reg_index <= m_reg_info.last_ymm)
- {
- if (GetFPRType() != eFPRTypeXSAVE)
- return Error ("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_index - m_reg_info.first_ymm].bytes, reg_value.GetBytes(), reg_value.GetByteSize());
- if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
- return Error ("CopyYMMtoXSTATE() failed");
- }
- }
- 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(PTRACE_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 = reg_value.GetAsUInt8();
- break;
- case 2:
- *(uint16_t *)dst = reg_value.GetAsUInt16();
- break;
- case 4:
- *(uint32_t *)dst = reg_value.GetAsUInt32();
- break;
- case 8:
- *(uint64_t *)dst = reg_value.GetAsUInt64();
- break;
- default:
- assert(false && "Unhandled data size.");
- return Error ("unhandled register data size %" PRIu32, reg_info->byte_size);
- }
- }
+Error NativeRegisterContextLinux_x86_64::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &reg_value) {
+ assert(reg_info && "reg_info is null");
+
+ const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
+ if (reg_index == LLDB_INVALID_REGNUM)
+ return Error("no lldb regnum for %s", reg_info && reg_info->name
+ ? reg_info->name
+ : "<unknown register>");
+
+ if (IsGPR(reg_index))
+ return WriteRegisterRaw(reg_index, reg_value);
+
+ if (IsFPR(reg_index) || IsAVX(reg_index) || IsMPX(reg_index)) {
+ if (reg_info->encoding == lldb::eEncodingVector) {
+ if (reg_index >= m_reg_info.first_st && reg_index <= m_reg_info.last_st)
+ ::memcpy(
+ m_fpr.xstate.fxsave.stmm[reg_index - m_reg_info.first_st].bytes,
+ reg_value.GetBytes(), reg_value.GetByteSize());
+
+ if (reg_index >= m_reg_info.first_mm && reg_index <= m_reg_info.last_mm)
+ ::memcpy(
+ m_fpr.xstate.fxsave.stmm[reg_index - m_reg_info.first_mm].bytes,
+ reg_value.GetBytes(), reg_value.GetByteSize());
+
+ if (reg_index >= m_reg_info.first_xmm && reg_index <= m_reg_info.last_xmm)
+ ::memcpy(
+ m_fpr.xstate.fxsave.xmm[reg_index - m_reg_info.first_xmm].bytes,
+ reg_value.GetBytes(), reg_value.GetByteSize());
+
+ if (reg_index >= m_reg_info.first_ymm &&
+ reg_index <= m_reg_info.last_ymm) {
+ // Store ymm register content, and split into the register halves in
+ // xmm.bytes and ymmh.bytes
+ ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
+ reg_value.GetBytes(), reg_value.GetByteSize());
+ if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
+ return Error("CopyYMMtoXSTATE() failed");
+ }
+
+ if (reg_index >= m_reg_info.first_mpxr &&
+ reg_index <= m_reg_info.last_mpxr) {
+ ::memcpy(m_mpx_set.mpxr[reg_index - m_reg_info.first_mpxr].bytes,
+ reg_value.GetBytes(), reg_value.GetByteSize());
+ if (!CopyMPXtoXSTATE(reg_index))
+ return Error("CopyMPXtoXSTATE() failed");
+ }
+
+ if (reg_index >= m_reg_info.first_mpxc &&
+ reg_index <= m_reg_info.last_mpxc) {
+ ::memcpy(m_mpx_set.mpxc[reg_index - m_reg_info.first_mpxc].bytes,
+ reg_value.GetBytes(), reg_value.GetByteSize());
+ if (!CopyMPXtoXSTATE(reg_index))
+ return Error("CopyMPXtoXSTATE() failed");
+ }
+ } 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(PTRACE_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 = reg_value.GetAsUInt8();
+ break;
+ case 2:
+ *(uint16_t *)dst = reg_value.GetAsUInt16();
+ break;
+ case 4:
+ *(uint32_t *)dst = reg_value.GetAsUInt32();
+ break;
+ case 8:
+ *(uint64_t *)dst = reg_value.GetAsUInt64();
+ break;
+ default:
+ assert(false && "Unhandled data size.");
+ return Error("unhandled register data size %" PRIu32,
+ reg_info->byte_size);
+ }
+ }
- Error error = WriteFPR();
- if (error.Fail())
- return error;
+ Error error = WriteFPR();
+ if (error.Fail())
+ return error;
- if (IsAVX(reg_index))
- {
- if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
- return Error ("CopyYMMtoXSTATE() failed");
- }
- return Error ();
+ if (IsAVX(reg_index)) {
+ if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
+ return Error("CopyYMMtoXSTATE() failed");
+ }
+
+ if (IsMPX(reg_index)) {
+ if (!CopyMPXtoXSTATE(reg_index))
+ return Error("CopyMPXtoXSTATE() failed");
}
- return Error ("failed - register wasn't recognized to be a GPR or an FPR, write strategy unknown");
+ return Error();
+ }
+ return Error("failed - register wasn't recognized to be a GPR or an FPR, "
+ "write strategy unknown");
}
-Error
-NativeRegisterContextLinux_x86_64::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
-{
- Error error;
+Error NativeRegisterContextLinux_x86_64::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ Error error;
- data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
- if (!data_sp)
- {
- error.SetErrorStringWithFormat ("failed to allocate DataBufferHeap instance of size %" PRIu64, REG_CONTEXT_SIZE);
- return error;
- }
+ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (!data_sp) {
+ error.SetErrorStringWithFormat(
+ "failed to allocate DataBufferHeap instance of size %" PRIu64,
+ REG_CONTEXT_SIZE);
+ return error;
+ }
- error = ReadGPR();
- if (error.Fail())
- return error;
+ error = ReadGPR();
+ if (error.Fail())
+ return error;
- error = ReadFPR();
- if (error.Fail())
- return error;
+ error = ReadFPR();
+ if (error.Fail())
+ return error;
- uint8_t *dst = data_sp->GetBytes ();
- if (dst == nullptr)
- {
- error.SetErrorStringWithFormat ("DataBufferHeap instance of size %" PRIu64 " returned a null pointer", REG_CONTEXT_SIZE);
- return error;
+ uint8_t *dst = data_sp->GetBytes();
+ if (dst == nullptr) {
+ error.SetErrorStringWithFormat("DataBufferHeap instance of size %" PRIu64
+ " returned a null pointer",
+ REG_CONTEXT_SIZE);
+ return error;
+ }
+
+ ::memcpy(dst, &m_gpr_x86_64, GetRegisterInfoInterface().GetGPRSize());
+ dst += GetRegisterInfoInterface().GetGPRSize();
+ if (m_xstate_type == XStateType::FXSAVE)
+ ::memcpy(dst, &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave));
+ else if (m_xstate_type == XStateType::XSAVE) {
+ lldb::ByteOrder byte_order = GetByteOrder();
+
+ if (IsCPUFeatureAvailable(RegSet::avx)) {
+ // Assemble the YMM register content from the register halves.
+ for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm;
+ ++reg) {
+ if (!CopyXSTATEtoYMM(reg, byte_order)) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_x86_64::%s "
+ "CopyXSTATEtoYMM() failed for reg num "
+ "%" PRIu32,
+ __FUNCTION__, reg);
+ return error;
+ }
+ }
}
- ::memcpy (dst, &m_gpr_x86_64, GetRegisterInfoInterface ().GetGPRSize ());
- dst += GetRegisterInfoInterface ().GetGPRSize ();
- if (GetFPRType () == eFPRTypeFXSAVE)
- ::memcpy (dst, &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave));
- else if (GetFPRType () == eFPRTypeXSAVE)
- {
- lldb::ByteOrder byte_order = GetByteOrder ();
-
- // Assemble the YMM register content from the register halves.
- for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm; ++reg)
- {
- if (!CopyXSTATEtoYMM (reg, byte_order))
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s CopyXSTATEtoYMM() failed for reg num %" PRIu32, __FUNCTION__, reg);
- return error;
- }
+ if (IsCPUFeatureAvailable(RegSet::mpx)) {
+ for (uint32_t reg = m_reg_info.first_mpxr; reg <= m_reg_info.last_mpxc;
+ ++reg) {
+ if (!CopyXSTATEtoMPX(reg)) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_x86_64::%s "
+ "CopyXSTATEtoMPX() failed for reg num "
+ "%" PRIu32,
+ __FUNCTION__, reg);
+ return error;
}
-
- // Copy the extended register state including the assembled ymm registers.
- ::memcpy (dst, &m_fpr, sizeof (m_fpr));
+ }
}
- else
- {
- assert (false && "how do we save the floating point registers?");
- error.SetErrorString ("unsure how to save the floating point registers");
- }
- /** The following code is specific to Linux x86 based architectures,
- * where the register orig_eax (32 bit)/orig_rax (64 bit) is set to
- * -1 to solve the bug 23659, such a setting prevents the automatic
- * decrement of the instruction pointer which was causing the SIGILL
- * exception.
- * **/
-
- RegisterValue value((uint64_t) -1);
- const RegisterInfo *reg_info = GetRegisterInfoInterface().GetDynamicRegisterInfo("orig_eax");
- if (reg_info == nullptr)
- reg_info = GetRegisterInfoInterface().GetDynamicRegisterInfo("orig_rax");
+ // Copy the extended register state including the assembled ymm registers.
+ ::memcpy(dst, &m_fpr, sizeof(m_fpr));
+ } else {
+ assert(false && "how do we save the floating point registers?");
+ error.SetErrorString("unsure how to save the floating point registers");
+ }
+ /** The following code is specific to Linux x86 based architectures,
+ * where the register orig_eax (32 bit)/orig_rax (64 bit) is set to
+ * -1 to solve the bug 23659, such a setting prevents the automatic
+ * decrement of the instruction pointer which was causing the SIGILL
+ * exception.
+ * **/
+
+ RegisterValue value((uint64_t)-1);
+ const RegisterInfo *reg_info =
+ GetRegisterInfoInterface().GetDynamicRegisterInfo("orig_eax");
+ if (reg_info == nullptr)
+ reg_info = GetRegisterInfoInterface().GetDynamicRegisterInfo("orig_rax");
+
+ if (reg_info != nullptr)
+ return DoWriteRegisterValue(reg_info->byte_offset, reg_info->name, value);
+
+ return error;
+}
- if (reg_info != nullptr)
- return DoWriteRegisterValue(reg_info->byte_offset,reg_info->name,value);
+Error NativeRegisterContextLinux_x86_64::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ Error error;
+ if (!data_sp) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_x86_64::%s invalid data_sp provided",
+ __FUNCTION__);
return error;
-}
+ }
-Error
-NativeRegisterContextLinux_x86_64::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
-{
- Error error;
+ if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_x86_64::%s data_sp contained mismatched "
+ "data size, expected %" PRIu64 ", actual %" PRIu64,
+ __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize());
+ return error;
+ }
+
+ uint8_t *src = data_sp->GetBytes();
+ if (src == nullptr) {
+ error.SetErrorStringWithFormat("NativeRegisterContextLinux_x86_64::%s "
+ "DataBuffer::GetBytes() returned a null "
+ "pointer",
+ __FUNCTION__);
+ return error;
+ }
+ ::memcpy(&m_gpr_x86_64, src, GetRegisterInfoInterface().GetGPRSize());
- if (!data_sp)
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s invalid data_sp provided", __FUNCTION__);
- return error;
- }
+ error = WriteGPR();
+ if (error.Fail())
+ return error;
- if (data_sp->GetByteSize () != REG_CONTEXT_SIZE)
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s data_sp contained mismatched data size, expected %" PRIu64 ", actual %" PRIu64, __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize ());
- return error;
- }
+ src += GetRegisterInfoInterface().GetGPRSize();
+ if (m_xstate_type == XStateType::FXSAVE)
+ ::memcpy(&m_fpr.xstate.fxsave, src, sizeof(m_fpr.xstate.fxsave));
+ else if (m_xstate_type == XStateType::XSAVE)
+ ::memcpy(&m_fpr.xstate.xsave, src, sizeof(m_fpr.xstate.xsave));
+ error = WriteFPR();
+ if (error.Fail())
+ return error;
- uint8_t *src = data_sp->GetBytes ();
- if (src == nullptr)
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s DataBuffer::GetBytes() returned a null pointer", __FUNCTION__);
- return error;
+ if (m_xstate_type == XStateType::XSAVE) {
+ lldb::ByteOrder byte_order = GetByteOrder();
+
+ if (IsCPUFeatureAvailable(RegSet::avx)) {
+ // Parse the YMM register content from the register halves.
+ for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm;
+ ++reg) {
+ if (!CopyYMMtoXSTATE(reg, byte_order)) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_x86_64::%s "
+ "CopyYMMtoXSTATE() failed for reg num "
+ "%" PRIu32,
+ __FUNCTION__, reg);
+ return error;
+ }
+ }
}
- ::memcpy (&m_gpr_x86_64, src, GetRegisterInfoInterface ().GetGPRSize ());
- error = WriteGPR();
- if (error.Fail())
- return error;
-
- src += GetRegisterInfoInterface ().GetGPRSize ();
- if (GetFPRType () == eFPRTypeFXSAVE)
- ::memcpy (&m_fpr.xstate.fxsave, src, sizeof(m_fpr.xstate.fxsave));
- else if (GetFPRType () == eFPRTypeXSAVE)
- ::memcpy (&m_fpr.xstate.xsave, src, sizeof(m_fpr.xstate.xsave));
-
- error = WriteFPR();
- if (error.Fail())
- return error;
-
- if (GetFPRType() == eFPRTypeXSAVE)
- {
- lldb::ByteOrder byte_order = GetByteOrder();
-
- // Parse the YMM register content from the register halves.
- for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm; ++reg)
- {
- if (!CopyYMMtoXSTATE (reg, byte_order))
- {
- error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s CopyYMMtoXSTATE() failed for reg num %" PRIu32, __FUNCTION__, reg);
- return error;
- }
+ if (IsCPUFeatureAvailable(RegSet::mpx)) {
+ for (uint32_t reg = m_reg_info.first_mpxr; reg <= m_reg_info.last_mpxc;
+ ++reg) {
+ if (!CopyMPXtoXSTATE(reg)) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_x86_64::%s "
+ "CopyMPXtoXSTATE() failed for reg num "
+ "%" PRIu32,
+ __FUNCTION__, reg);
+ return error;
}
+ }
}
+ }
- return error;
+ return error;
}
-bool
-NativeRegisterContextLinux_x86_64::IsRegisterSetAvailable (uint32_t set_index) const
-{
- // Note: Extended register sets are assumed to be at the end of g_reg_sets.
- uint32_t num_sets = k_num_register_sets - k_num_extended_register_sets;
+bool NativeRegisterContextLinux_x86_64::IsCPUFeatureAvailable(
+ RegSet feature_code) const {
+ if (m_xstate_type == XStateType::Invalid) {
+ if (const_cast<NativeRegisterContextLinux_x86_64 *>(this)->ReadFPR().Fail())
+ return false;
+ }
+ switch (feature_code) {
+ case RegSet::gpr:
+ case RegSet::fpu:
+ return true;
+ case RegSet::avx: // Check if CPU has AVX and if there is kernel support, by
+ // reading in the XCR0 area of XSAVE.
+ if ((m_fpr.xstate.xsave.i387.xcr0 & mask_XSTATE_AVX) == mask_XSTATE_AVX)
+ return true;
+ break;
+ case RegSet::mpx: // Check if CPU has MPX and if there is kernel support, by
+ // reading in the XCR0 area of XSAVE.
+ if ((m_fpr.xstate.xsave.i387.xcr0 & mask_XSTATE_MPX) == mask_XSTATE_MPX)
+ return true;
+ break;
+ }
+ return false;
+}
- if (GetFPRType () == eFPRTypeXSAVE)
- {
- // AVX is the first extended register set.
- ++num_sets;
- }
+bool NativeRegisterContextLinux_x86_64::IsRegisterSetAvailable(
+ uint32_t set_index) const {
+ uint32_t num_sets = k_num_register_sets - k_num_extended_register_sets;
+
+ switch (static_cast<RegSet>(set_index)) {
+ case RegSet::gpr:
+ case RegSet::fpu:
return (set_index < num_sets);
+ case RegSet::avx:
+ return IsCPUFeatureAvailable(RegSet::avx);
+ case RegSet::mpx:
+ return IsCPUFeatureAvailable(RegSet::mpx);
+ }
+ return false;
}
-bool
-NativeRegisterContextLinux_x86_64::IsGPR(uint32_t reg_index) const
-{
- // GPRs come first.
- return reg_index <= m_reg_info.last_gpr;
+bool NativeRegisterContextLinux_x86_64::IsGPR(uint32_t reg_index) const {
+ // GPRs come first.
+ return reg_index <= m_reg_info.last_gpr;
}
-NativeRegisterContextLinux_x86_64::FPRType
-NativeRegisterContextLinux_x86_64::GetFPRType () const
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (m_fpr_type == eFPRTypeNotValid)
- {
- // TODO: Use assembly to call cpuid on the inferior and query ebx or ecx.
-
- // Try and see if AVX register retrieval works.
- m_fpr_type = eFPRTypeXSAVE;
- if (const_cast<NativeRegisterContextLinux_x86_64*>(this)->ReadFPR().Fail())
- {
- // Fall back to general floating point with no AVX support.
- m_fpr_type = eFPRTypeFXSAVE;
-
- // Check if FXSAVE area can be read.
- if (const_cast<NativeRegisterContextLinux_x86_64*>(this)->ReadFPR().Fail())
- {
- if (log)
- log->Printf("NativeRegisterContextLinux_x86_64::%s ptrace APIs failed to read XSAVE/FXSAVE area", __FUNCTION__);
- }
- }
- }
- return m_fpr_type;
+bool NativeRegisterContextLinux_x86_64::IsFPR(uint32_t reg_index) const {
+ return (m_reg_info.first_fpr <= reg_index &&
+ reg_index <= m_reg_info.last_fpr);
}
-bool
-NativeRegisterContextLinux_x86_64::IsFPR(uint32_t reg_index) const
-{
- return (m_reg_info.first_fpr <= reg_index && reg_index <= m_reg_info.last_fpr);
+Error NativeRegisterContextLinux_x86_64::WriteFPR() {
+ switch (m_xstate_type) {
+ case XStateType::FXSAVE:
+ return WriteRegisterSet(
+ &m_iovec, sizeof(m_fpr.xstate.xsave),
+ fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture()));
+ case XStateType::XSAVE:
+ return WriteRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave),
+ NT_X86_XSTATE);
+ default:
+ return Error("Unrecognized FPR type.");
+ }
}
-bool
-NativeRegisterContextLinux_x86_64::IsFPR(uint32_t reg_index, FPRType fpr_type) const
-{
- bool generic_fpr = IsFPR(reg_index);
-
- if (fpr_type == eFPRTypeXSAVE)
- return generic_fpr || IsAVX(reg_index);
- return generic_fpr;
+bool NativeRegisterContextLinux_x86_64::IsAVX(uint32_t reg_index) const {
+ if (!IsCPUFeatureAvailable(RegSet::avx))
+ return false;
+ return (m_reg_info.first_ymm <= reg_index &&
+ reg_index <= m_reg_info.last_ymm);
}
-Error
-NativeRegisterContextLinux_x86_64::WriteFPR()
-{
- const FPRType fpr_type = GetFPRType ();
- const lldb_private::ArchSpec& target_arch = GetRegisterInfoInterface().GetTargetArchitecture();
- switch (fpr_type)
- {
- case FPRType::eFPRTypeFXSAVE:
- // For 32-bit inferiors on x86_32/x86_64 architectures,
- // FXSAVE area can be written using PTRACE_SETREGSET ptrace api
- // For 64-bit inferiors on x86_64 architectures,
- // FXSAVE area can be written using PTRACE_SETFPREGS ptrace api
- switch (target_arch.GetMachine ())
- {
- case llvm::Triple::x86:
- return WriteRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), NT_PRXFPREG);
- case llvm::Triple::x86_64:
- return NativeRegisterContextLinux::WriteFPR();
- default:
- assert(false && "Unhandled target architecture.");
- break;
- }
- case FPRType::eFPRTypeXSAVE:
- return WriteRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
- default:
- return Error("Unrecognized FPR type");
- }
+bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoYMM(
+ uint32_t reg_index, lldb::ByteOrder byte_order) {
+ if (!IsAVX(reg_index))
+ return false;
+
+ if (byte_order == lldb::eByteOrderLittle) {
+ ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
+ m_fpr.xstate.fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes,
+ sizeof(XMMReg));
+ ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes +
+ sizeof(XMMReg),
+ m_fpr.xstate.xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes,
+ sizeof(YMMHReg));
+ return true;
+ }
+
+ if (byte_order == lldb::eByteOrderBig) {
+ ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes +
+ sizeof(XMMReg),
+ m_fpr.xstate.fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes,
+ sizeof(XMMReg));
+ ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
+ m_fpr.xstate.xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes,
+ sizeof(YMMHReg));
+ return true;
+ }
+ return false; // unsupported or invalid byte order
}
-bool
-NativeRegisterContextLinux_x86_64::IsAVX(uint32_t reg_index) const
-{
- return (m_reg_info.first_ymm <= reg_index && reg_index <= m_reg_info.last_ymm);
+bool NativeRegisterContextLinux_x86_64::CopyYMMtoXSTATE(
+ uint32_t reg, lldb::ByteOrder byte_order) {
+ if (!IsAVX(reg))
+ return false;
+
+ if (byte_order == lldb::eByteOrderLittle) {
+ ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
+ m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(XMMReg));
+ ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
+ m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
+ sizeof(YMMHReg));
+ return true;
+ }
+
+ if (byte_order == lldb::eByteOrderBig) {
+ ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
+ m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
+ sizeof(XMMReg));
+ ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
+ m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(YMMHReg));
+ return true;
+ }
+ return false; // unsupported or invalid byte order
}
-bool
-NativeRegisterContextLinux_x86_64::CopyXSTATEtoYMM (uint32_t reg_index, lldb::ByteOrder byte_order)
-{
- if (!IsAVX (reg_index))
- return false;
-
- if (byte_order == lldb::eByteOrderLittle)
- {
- ::memcpy (m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
- m_fpr.xstate.fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes,
- sizeof (XMMReg));
- ::memcpy (m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes + sizeof (XMMReg),
- m_fpr.xstate.xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes,
- sizeof (YMMHReg));
- return true;
- }
-
- if (byte_order == lldb::eByteOrderBig)
- {
- ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes + sizeof (XMMReg),
- m_fpr.xstate.fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes,
- sizeof (XMMReg));
- ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
- m_fpr.xstate.xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes,
- sizeof (YMMHReg));
- return true;
- }
- return false; // unsupported or invalid byte order
+void *NativeRegisterContextLinux_x86_64::GetFPRBuffer() {
+ switch (m_xstate_type) {
+ case XStateType::FXSAVE:
+ return &m_fpr.xstate.fxsave;
+ case XStateType::XSAVE:
+ return &m_iovec;
+ default:
+ return nullptr;
+ }
+}
+size_t NativeRegisterContextLinux_x86_64::GetFPRSize() {
+ switch (m_xstate_type) {
+ case XStateType::FXSAVE:
+ return sizeof(m_fpr.xstate.fxsave);
+ case XStateType::XSAVE:
+ return sizeof(m_iovec);
+ default:
+ return 0;
+ }
}
-bool
-NativeRegisterContextLinux_x86_64::CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder byte_order)
-{
- if (!IsAVX(reg))
- return false;
-
- if (byte_order == lldb::eByteOrderLittle)
- {
- ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
- m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
- sizeof(XMMReg));
- ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
- m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
- sizeof(YMMHReg));
- return true;
- }
+Error NativeRegisterContextLinux_x86_64::ReadFPR() {
+ Error error;
- if (byte_order == lldb::eByteOrderBig)
- {
- ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
- m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
- sizeof(XMMReg));
- ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
- m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
- sizeof(YMMHReg));
- return true;
+ // Probe XSAVE and if it is not supported fall back to FXSAVE.
+ if (m_xstate_type != XStateType::FXSAVE) {
+ error =
+ ReadRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
+ if (!error.Fail()) {
+ m_xstate_type = XStateType::XSAVE;
+ return error;
}
- return false; // unsupported or invalid byte order
+ }
+ error = ReadRegisterSet(
+ &m_iovec, sizeof(m_fpr.xstate.xsave),
+ fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture()));
+ if (!error.Fail()) {
+ m_xstate_type = XStateType::FXSAVE;
+ return error;
+ }
+ return Error("Unrecognized FPR type.");
}
-void*
-NativeRegisterContextLinux_x86_64::GetFPRBuffer()
-{
- const FPRType fpr_type = GetFPRType ();
- switch (fpr_type)
- {
- case FPRType::eFPRTypeFXSAVE:
- return &m_fpr.xstate.fxsave;
- case FPRType::eFPRTypeXSAVE:
- return &m_iovec;
- default:
- return nullptr;
- }
+bool NativeRegisterContextLinux_x86_64::IsMPX(uint32_t reg_index) const {
+ if (!IsCPUFeatureAvailable(RegSet::mpx))
+ return false;
+ return (m_reg_info.first_mpxr <= reg_index &&
+ reg_index <= m_reg_info.last_mpxc);
}
-size_t
-NativeRegisterContextLinux_x86_64::GetFPRSize()
-{
- const FPRType fpr_type = GetFPRType ();
- switch (fpr_type)
- {
- case FPRType::eFPRTypeFXSAVE:
- return sizeof(m_fpr.xstate.fxsave);
- case FPRType::eFPRTypeXSAVE:
- return sizeof(m_iovec);
- default:
- return 0;
- }
+bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoMPX(uint32_t reg) {
+ if (!IsMPX(reg))
+ return false;
+
+ if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
+ ::memcpy(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes,
+ m_fpr.xstate.xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,
+ sizeof(MPXReg));
+ } else {
+ ::memcpy(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes,
+ m_fpr.xstate.xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
+ sizeof(MPXCsr));
+ }
+ return true;
}
-Error
-NativeRegisterContextLinux_x86_64::ReadFPR ()
-{
- const FPRType fpr_type = GetFPRType ();
- const lldb_private::ArchSpec& target_arch = GetRegisterInfoInterface().GetTargetArchitecture();
- switch (fpr_type)
- {
- case FPRType::eFPRTypeFXSAVE:
- // For 32-bit inferiors on x86_32/x86_64 architectures,
- // FXSAVE area can be read using PTRACE_GETREGSET ptrace api
- // For 64-bit inferiors on x86_64 architectures,
- // FXSAVE area can be read using PTRACE_GETFPREGS ptrace api
- switch (target_arch.GetMachine ())
- {
- case llvm::Triple::x86:
- return ReadRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), NT_PRXFPREG);
- case llvm::Triple::x86_64:
- return NativeRegisterContextLinux::ReadFPR();
- default:
- assert(false && "Unhandled target architecture.");
- break;
- }
- case FPRType::eFPRTypeXSAVE:
- return ReadRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
- default:
- return Error("Unrecognized FPR type");
- }
+bool NativeRegisterContextLinux_x86_64::CopyMPXtoXSTATE(uint32_t reg) {
+ if (!IsMPX(reg))
+ return false;
+
+ if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
+ ::memcpy(m_fpr.xstate.xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,
+ m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes, sizeof(MPXReg));
+ } else {
+ ::memcpy(m_fpr.xstate.xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
+ m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes, sizeof(MPXCsr));
+ }
+ return true;
}
-Error
-NativeRegisterContextLinux_x86_64::IsWatchpointHit(uint32_t wp_index, bool &is_hit)
-{
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return Error("Watchpoint index out of range");
+Error NativeRegisterContextLinux_x86_64::IsWatchpointHit(uint32_t wp_index,
+ bool &is_hit) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return Error("Watchpoint index out of range");
- RegisterValue reg_value;
- Error error = ReadRegisterRaw(m_reg_info.first_dr + 6, reg_value);
- if (error.Fail())
- {
- is_hit = false;
- return error;
- }
+ RegisterValue reg_value;
+ Error error = ReadRegisterRaw(m_reg_info.first_dr + 6, reg_value);
+ if (error.Fail()) {
+ is_hit = false;
+ return error;
+ }
- uint64_t status_bits = reg_value.GetAsUInt64();
+ uint64_t status_bits = reg_value.GetAsUInt64();
- is_hit = status_bits & (1 << wp_index);
+ is_hit = status_bits & (1 << wp_index);
- return error;
+ return error;
}
-Error
-NativeRegisterContextLinux_x86_64::GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr) {
- uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
- for (wp_index = 0; wp_index < num_hw_wps; ++wp_index)
- {
- bool is_hit;
- Error error = IsWatchpointHit(wp_index, is_hit);
- if (error.Fail()) {
- wp_index = LLDB_INVALID_INDEX32;
- return error;
- } else if (is_hit) {
- return error;
- }
+Error NativeRegisterContextLinux_x86_64::GetWatchpointHitIndex(
+ uint32_t &wp_index, lldb::addr_t trap_addr) {
+ uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
+ for (wp_index = 0; wp_index < num_hw_wps; ++wp_index) {
+ bool is_hit;
+ Error error = IsWatchpointHit(wp_index, is_hit);
+ if (error.Fail()) {
+ wp_index = LLDB_INVALID_INDEX32;
+ return error;
+ } else if (is_hit) {
+ return error;
}
- wp_index = LLDB_INVALID_INDEX32;
- return Error();
+ }
+ wp_index = LLDB_INVALID_INDEX32;
+ return Error();
}
-Error
-NativeRegisterContextLinux_x86_64::IsWatchpointVacant(uint32_t wp_index, bool &is_vacant)
-{
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return Error ("Watchpoint index out of range");
+Error NativeRegisterContextLinux_x86_64::IsWatchpointVacant(uint32_t wp_index,
+ bool &is_vacant) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return Error("Watchpoint index out of range");
- RegisterValue reg_value;
- Error error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
- if (error.Fail())
- {
- is_vacant = false;
- return error;
- }
+ RegisterValue reg_value;
+ Error error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
+ if (error.Fail()) {
+ is_vacant = false;
+ return error;
+ }
- uint64_t control_bits = reg_value.GetAsUInt64();
+ uint64_t control_bits = reg_value.GetAsUInt64();
- is_vacant = !(control_bits & (1 << (2 * wp_index)));
+ is_vacant = !(control_bits & (1 << (2 * wp_index)));
- return error;
+ return error;
}
-Error
-NativeRegisterContextLinux_x86_64::SetHardwareWatchpointWithIndex(
- lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index) {
+Error NativeRegisterContextLinux_x86_64::SetHardwareWatchpointWithIndex(
+ lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index) {
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return Error ("Watchpoint index out of range");
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return Error("Watchpoint index out of range");
- // Read only watchpoints aren't supported on x86_64. Fall back to read/write waitchpoints instead.
- // TODO: Add logic to detect when a write happens and ignore that watchpoint hit.
- if (watch_flags == 0x2)
- watch_flags = 0x3;
+ // Read only watchpoints aren't supported on x86_64. Fall back to read/write
+ // waitchpoints instead.
+ // TODO: Add logic to detect when a write happens and ignore that watchpoint
+ // hit.
+ if (watch_flags == 0x2)
+ watch_flags = 0x3;
- if (watch_flags != 0x1 && watch_flags != 0x3)
- return Error ("Invalid read/write bits for watchpoint");
+ if (watch_flags != 0x1 && watch_flags != 0x3)
+ return Error("Invalid read/write bits for watchpoint");
- if (size != 1 && size != 2 && size != 4 && size != 8)
- return Error ("Invalid size for watchpoint");
+ if (size != 1 && size != 2 && size != 4 && size != 8)
+ return Error("Invalid size for watchpoint");
- bool is_vacant;
- Error error = IsWatchpointVacant (wp_index, is_vacant);
- if (error.Fail()) return error;
- if (!is_vacant) return Error("Watchpoint index not vacant");
-
- RegisterValue reg_value;
- error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
- if (error.Fail()) return error;
+ bool is_vacant;
+ Error error = IsWatchpointVacant(wp_index, is_vacant);
+ if (error.Fail())
+ return error;
+ if (!is_vacant)
+ return Error("Watchpoint index not vacant");
- // for watchpoints 0, 1, 2, or 3, respectively,
- // set bits 1, 3, 5, or 7
- uint64_t enable_bit = 1 << (2 * wp_index);
+ RegisterValue reg_value;
+ error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
+ if (error.Fail())
+ return error;
- // set bits 16-17, 20-21, 24-25, or 28-29
- // with 0b01 for write, and 0b11 for read/write
- uint64_t rw_bits = watch_flags << (16 + 4 * wp_index);
+ // for watchpoints 0, 1, 2, or 3, respectively,
+ // set bits 1, 3, 5, or 7
+ uint64_t enable_bit = 1 << (2 * wp_index);
- // set bits 18-19, 22-23, 26-27, or 30-31
- // with 0b00, 0b01, 0b10, or 0b11
- // for 1, 2, 8 (if supported), or 4 bytes, respectively
- uint64_t size_bits = (size == 8 ? 0x2 : size - 1) << (18 + 4 * wp_index);
+ // set bits 16-17, 20-21, 24-25, or 28-29
+ // with 0b01 for write, and 0b11 for read/write
+ uint64_t rw_bits = watch_flags << (16 + 4 * wp_index);
- uint64_t bit_mask = (0x3 << (2 * wp_index)) | (0xF << (16 + 4 * wp_index));
+ // set bits 18-19, 22-23, 26-27, or 30-31
+ // with 0b00, 0b01, 0b10, or 0b11
+ // for 1, 2, 8 (if supported), or 4 bytes, respectively
+ uint64_t size_bits = (size == 8 ? 0x2 : size - 1) << (18 + 4 * wp_index);
- uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
+ uint64_t bit_mask = (0x3 << (2 * wp_index)) | (0xF << (16 + 4 * wp_index));
- control_bits |= enable_bit | rw_bits | size_bits;
+ uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
- error = WriteRegisterRaw(m_reg_info.first_dr + wp_index, RegisterValue(addr));
- if (error.Fail()) return error;
+ control_bits |= enable_bit | rw_bits | size_bits;
- error = WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits));
- if (error.Fail()) return error;
+ error = WriteRegisterRaw(m_reg_info.first_dr + wp_index, RegisterValue(addr));
+ if (error.Fail())
+ return error;
- error.Clear();
+ error =
+ WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits));
+ if (error.Fail())
return error;
+
+ error.Clear();
+ return error;
}
-bool
-NativeRegisterContextLinux_x86_64::ClearHardwareWatchpoint(uint32_t wp_index)
-{
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return false;
-
- RegisterValue reg_value;
-
- // for watchpoints 0, 1, 2, or 3, respectively,
- // clear bits 0, 1, 2, or 3 of the debug status register (DR6)
- Error error = ReadRegisterRaw(m_reg_info.first_dr + 6, reg_value);
- if (error.Fail()) return false;
- uint64_t bit_mask = 1 << wp_index;
- uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
- error = WriteRegisterRaw(m_reg_info.first_dr + 6, RegisterValue(status_bits));
- if (error.Fail()) return false;
-
- // for watchpoints 0, 1, 2, or 3, respectively,
- // clear bits {0-1,16-19}, {2-3,20-23}, {4-5,24-27}, or {6-7,28-31}
- // of the debug control register (DR7)
- error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
- if (error.Fail()) return false;
- bit_mask = (0x3 << (2 * wp_index)) | (0xF << (16 + 4 * wp_index));
- uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
- return WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits)).Success();
+bool NativeRegisterContextLinux_x86_64::ClearHardwareWatchpoint(
+ uint32_t wp_index) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return false;
+
+ RegisterValue reg_value;
+
+ // for watchpoints 0, 1, 2, or 3, respectively,
+ // clear bits 0, 1, 2, or 3 of the debug status register (DR6)
+ Error error = ReadRegisterRaw(m_reg_info.first_dr + 6, reg_value);
+ if (error.Fail())
+ return false;
+ uint64_t bit_mask = 1 << wp_index;
+ uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
+ error = WriteRegisterRaw(m_reg_info.first_dr + 6, RegisterValue(status_bits));
+ if (error.Fail())
+ return false;
+
+ // for watchpoints 0, 1, 2, or 3, respectively,
+ // clear bits {0-1,16-19}, {2-3,20-23}, {4-5,24-27}, or {6-7,28-31}
+ // of the debug control register (DR7)
+ error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
+ if (error.Fail())
+ return false;
+ bit_mask = (0x3 << (2 * wp_index)) | (0xF << (16 + 4 * wp_index));
+ uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
+ return WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits))
+ .Success();
}
-Error
-NativeRegisterContextLinux_x86_64::ClearAllHardwareWatchpoints()
-{
- RegisterValue reg_value;
-
- // clear bits {0-4} of the debug status register (DR6)
- Error error = ReadRegisterRaw(m_reg_info.first_dr + 6, reg_value);
- if (error.Fail()) return error;
- uint64_t bit_mask = 0xF;
- uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
- error = WriteRegisterRaw(m_reg_info.first_dr + 6, RegisterValue(status_bits));
- if (error.Fail()) return error;
-
- // clear bits {0-7,16-31} of the debug control register (DR7)
- error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
- if (error.Fail()) return error;
- bit_mask = 0xFF | (0xFFFF << 16);
- uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
- return WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits));
+Error NativeRegisterContextLinux_x86_64::ClearAllHardwareWatchpoints() {
+ RegisterValue reg_value;
+
+ // clear bits {0-4} of the debug status register (DR6)
+ Error error = ReadRegisterRaw(m_reg_info.first_dr + 6, reg_value);
+ if (error.Fail())
+ return error;
+ uint64_t bit_mask = 0xF;
+ uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
+ error = WriteRegisterRaw(m_reg_info.first_dr + 6, RegisterValue(status_bits));
+ if (error.Fail())
+ return error;
+
+ // clear bits {0-7,16-31} of the debug control register (DR7)
+ error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
+ if (error.Fail())
+ return error;
+ bit_mask = 0xFF | (0xFFFF << 16);
+ uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
+ return WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits));
}
-uint32_t
-NativeRegisterContextLinux_x86_64::SetHardwareWatchpoint(
- lldb::addr_t addr, size_t size, uint32_t watch_flags)
-{
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
- for (uint32_t wp_index = 0; wp_index < num_hw_watchpoints; ++wp_index)
- {
- bool is_vacant;
- Error error = IsWatchpointVacant(wp_index, is_vacant);
- if (is_vacant)
- {
- error = SetHardwareWatchpointWithIndex(addr, size, watch_flags, wp_index);
- if (error.Success())
- return wp_index;
- }
- if (error.Fail() && log)
- {
- log->Printf("NativeRegisterContextLinux_x86_64::%s Error: %s",
- __FUNCTION__, error.AsCString());
- }
+uint32_t NativeRegisterContextLinux_x86_64::SetHardwareWatchpoint(
+ lldb::addr_t addr, size_t size, uint32_t watch_flags) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
+ for (uint32_t wp_index = 0; wp_index < num_hw_watchpoints; ++wp_index) {
+ bool is_vacant;
+ Error error = IsWatchpointVacant(wp_index, is_vacant);
+ if (is_vacant) {
+ error = SetHardwareWatchpointWithIndex(addr, size, watch_flags, wp_index);
+ if (error.Success())
+ return wp_index;
+ }
+ if (error.Fail() && log) {
+ log->Printf("NativeRegisterContextLinux_x86_64::%s Error: %s",
+ __FUNCTION__, error.AsCString());
}
- return LLDB_INVALID_INDEX32;
+ }
+ return LLDB_INVALID_INDEX32;
}
lldb::addr_t
-NativeRegisterContextLinux_x86_64::GetWatchpointAddress(uint32_t wp_index)
-{
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return LLDB_INVALID_ADDRESS;
- RegisterValue reg_value;
- if (ReadRegisterRaw(m_reg_info.first_dr + wp_index, reg_value).Fail())
- return LLDB_INVALID_ADDRESS;
- return reg_value.GetAsUInt64();
+NativeRegisterContextLinux_x86_64::GetWatchpointAddress(uint32_t wp_index) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return LLDB_INVALID_ADDRESS;
+ RegisterValue reg_value;
+ if (ReadRegisterRaw(m_reg_info.first_dr + wp_index, reg_value).Fail())
+ return LLDB_INVALID_ADDRESS;
+ return reg_value.GetAsUInt64();
}
-uint32_t
-NativeRegisterContextLinux_x86_64::NumSupportedHardwareWatchpoints ()
-{
- // Available debug address registers: dr0, dr1, dr2, dr3
- return 4;
+uint32_t NativeRegisterContextLinux_x86_64::NumSupportedHardwareWatchpoints() {
+ // Available debug address registers: dr0, dr1, dr2, dr3
+ return 4;
}
#endif // defined(__i386__) || defined(__x86_64__)
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
index b04be4bb7688..cc05ec06b297 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
@@ -19,149 +19,124 @@
namespace lldb_private {
namespace process_linux {
- class NativeProcessLinux;
+class NativeProcessLinux;
- class NativeRegisterContextLinux_x86_64 : public NativeRegisterContextLinux
- {
- public:
- NativeRegisterContextLinux_x86_64 (const ArchSpec& target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx);
+class NativeRegisterContextLinux_x86_64 : public NativeRegisterContextLinux {
+public:
+ NativeRegisterContextLinux_x86_64(const ArchSpec &target_arch,
+ NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx);
- uint32_t
- GetRegisterSetCount () const override;
+ uint32_t GetRegisterSetCount() const override;
- const RegisterSet *
- GetRegisterSet (uint32_t set_index) const override;
+ const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
- uint32_t
- GetUserRegisterCount() const override;
+ uint32_t GetUserRegisterCount() const override;
- Error
- ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value) override;
+ Error ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) override;
- Error
- WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value) override;
+ Error WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) override;
- Error
- ReadAllRegisterValues (lldb::DataBufferSP &data_sp) override;
+ Error ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
- Error
- WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) override;
+ Error WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- Error
- IsWatchpointHit(uint32_t wp_index, bool &is_hit) override;
+ Error IsWatchpointHit(uint32_t wp_index, bool &is_hit) override;
- Error
- GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr) override;
+ Error GetWatchpointHitIndex(uint32_t &wp_index,
+ lldb::addr_t trap_addr) override;
- Error
- IsWatchpointVacant(uint32_t wp_index, bool &is_vacant) override;
+ Error IsWatchpointVacant(uint32_t wp_index, bool &is_vacant) override;
- bool
- ClearHardwareWatchpoint(uint32_t wp_index) override;
+ bool ClearHardwareWatchpoint(uint32_t wp_index) override;
- Error
- ClearAllHardwareWatchpoints () override;
+ Error ClearAllHardwareWatchpoints() override;
- Error
- SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size,
- uint32_t watch_flags, uint32_t wp_index);
+ Error SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size,
+ uint32_t watch_flags, uint32_t wp_index);
- uint32_t
- SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
- uint32_t watch_flags) override;
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
+ uint32_t watch_flags) override;
- lldb::addr_t
- GetWatchpointAddress(uint32_t wp_index) override;
+ lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
- uint32_t
- NumSupportedHardwareWatchpoints() override;
+ uint32_t NumSupportedHardwareWatchpoints() override;
- protected:
- void*
- GetGPRBuffer() override { return &m_gpr_x86_64; }
+protected:
+ void *GetGPRBuffer() override { return &m_gpr_x86_64; }
- void*
- GetFPRBuffer() override;
+ void *GetFPRBuffer() override;
- size_t
- GetFPRSize() override;
+ size_t GetFPRSize() override;
- Error
- ReadFPR() override;
+ Error ReadFPR() override;
- Error
- WriteFPR() override;
+ Error WriteFPR() override;
- private:
+private:
+ // Private member types.
+ enum class XStateType { Invalid, FXSAVE, XSAVE };
+ enum class RegSet { gpr, fpu, avx, mpx };
- // Private member types.
- enum FPRType
- {
- eFPRTypeNotValid = 0,
- eFPRTypeFXSAVE,
- eFPRTypeXSAVE
- };
+ // Info about register ranges.
+ struct RegInfo {
+ uint32_t num_registers;
+ uint32_t num_gpr_registers;
+ uint32_t num_fpr_registers;
+ uint32_t num_avx_registers;
+ uint32_t num_mpx_registers;
+ uint32_t last_gpr;
+ uint32_t first_fpr;
+ uint32_t last_fpr;
+ uint32_t first_st;
+ uint32_t last_st;
+ uint32_t first_mm;
+ uint32_t last_mm;
+ uint32_t first_xmm;
+ uint32_t last_xmm;
+ uint32_t first_ymm;
+ uint32_t last_ymm;
+ uint32_t first_mpxr;
+ uint32_t last_mpxr;
+ uint32_t first_mpxc;
+ uint32_t last_mpxc;
+ uint32_t first_dr;
+ uint32_t gpr_flags;
+ };
- // Info about register ranges.
- struct RegInfo
- {
- uint32_t num_registers;
- uint32_t num_gpr_registers;
- uint32_t num_fpr_registers;
- uint32_t num_avx_registers;
+ // Private member variables.
+ mutable XStateType m_xstate_type;
+ FPR m_fpr; // Extended States Area, named FPR for historical reasons.
+ IOVEC m_iovec;
+ YMM m_ymm_set;
+ MPX m_mpx_set;
+ RegInfo m_reg_info;
+ uint64_t m_gpr_x86_64[k_num_gpr_registers_x86_64];
+ uint32_t m_fctrl_offset_in_userarea;
- uint32_t last_gpr;
- uint32_t first_fpr;
- uint32_t last_fpr;
+ // Private member methods.
+ bool IsCPUFeatureAvailable(RegSet feature_code) const;
- uint32_t first_st;
- uint32_t last_st;
- uint32_t first_mm;
- uint32_t last_mm;
- uint32_t first_xmm;
- uint32_t last_xmm;
- uint32_t first_ymm;
- uint32_t last_ymm;
+ bool IsRegisterSetAvailable(uint32_t set_index) const;
- uint32_t first_dr;
- uint32_t gpr_flags;
- };
+ bool IsGPR(uint32_t reg_index) const;
- // Private member variables.
- mutable FPRType m_fpr_type;
- FPR m_fpr;
- IOVEC m_iovec;
- YMM m_ymm_set;
- RegInfo m_reg_info;
- uint64_t m_gpr_x86_64[k_num_gpr_registers_x86_64];
- uint32_t m_fctrl_offset_in_userarea;
+ bool IsFPR(uint32_t reg_index) const;
- // Private member methods.
- bool IsRegisterSetAvailable (uint32_t set_index) const;
+ bool CopyXSTATEtoYMM(uint32_t reg_index, lldb::ByteOrder byte_order);
- bool
- IsGPR(uint32_t reg_index) const;
+ bool CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder byte_order);
- FPRType
- GetFPRType () const;
+ bool IsAVX(uint32_t reg_index) const;
- bool
- IsFPR(uint32_t reg_index) const;
+ bool CopyXSTATEtoMPX(uint32_t reg);
- bool
- IsFPR(uint32_t reg_index, FPRType fpr_type) const;
+ bool CopyMPXtoXSTATE(uint32_t reg);
- bool
- CopyXSTATEtoYMM (uint32_t reg_index, lldb::ByteOrder byte_order);
-
- bool
- CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder byte_order);
-
- bool
- IsAVX (uint32_t reg_index) const;
- };
+ bool IsMPX(uint32_t reg_index) const;
+};
} // namespace process_linux
} // namespace lldb_private
diff --git a/source/Plugins/Process/Linux/NativeThreadLinux.cpp b/source/Plugins/Process/Linux/NativeThreadLinux.cpp
index 6509022b6c6e..d18d3c16d2c9 100644
--- a/source/Plugins/Process/Linux/NativeThreadLinux.cpp
+++ b/source/Plugins/Process/Linux/NativeThreadLinux.cpp
@@ -29,481 +29,453 @@
#include <sys/syscall.h>
// Try to define a macro to encapsulate the tgkill syscall
-#define tgkill(pid, tid, sig) \
- syscall(__NR_tgkill, static_cast< ::pid_t>(pid), static_cast< ::pid_t>(tid), sig)
+#define tgkill(pid, tid, sig) \
+ syscall(__NR_tgkill, static_cast<::pid_t>(pid), static_cast<::pid_t>(tid), \
+ sig)
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_linux;
-namespace
-{
- void LogThreadStopInfo (Log &log, const ThreadStopInfo &stop_info, const char *const header)
- {
- switch (stop_info.reason)
- {
- case eStopReasonNone:
- log.Printf ("%s: %s no stop reason", __FUNCTION__, header);
- return;
- case eStopReasonTrace:
- log.Printf ("%s: %s trace, stopping signal 0x%" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo);
- return;
- case eStopReasonBreakpoint:
- log.Printf ("%s: %s breakpoint, stopping signal 0x%" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo);
- return;
- case eStopReasonWatchpoint:
- log.Printf ("%s: %s watchpoint, stopping signal 0x%" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo);
- return;
- case eStopReasonSignal:
- log.Printf ("%s: %s signal 0x%02" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo);
- return;
- case eStopReasonException:
- log.Printf ("%s: %s exception type 0x%02" PRIx64, __FUNCTION__, header, stop_info.details.exception.type);
- return;
- case eStopReasonExec:
- log.Printf ("%s: %s exec, stopping signal 0x%" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo);
- return;
- case eStopReasonPlanComplete:
- log.Printf ("%s: %s plan complete", __FUNCTION__, header);
- return;
- case eStopReasonThreadExiting:
- log.Printf ("%s: %s thread exiting", __FUNCTION__, header);
- return;
- case eStopReasonInstrumentation:
- log.Printf ("%s: %s instrumentation", __FUNCTION__, header);
- return;
- default:
- log.Printf ("%s: %s invalid stop reason %" PRIu32, __FUNCTION__, header, static_cast<uint32_t> (stop_info.reason));
- }
- }
+namespace {
+void LogThreadStopInfo(Log &log, const ThreadStopInfo &stop_info,
+ const char *const header) {
+ switch (stop_info.reason) {
+ case eStopReasonNone:
+ log.Printf("%s: %s no stop reason", __FUNCTION__, header);
+ return;
+ case eStopReasonTrace:
+ log.Printf("%s: %s trace, stopping signal 0x%" PRIx32, __FUNCTION__, header,
+ stop_info.details.signal.signo);
+ return;
+ case eStopReasonBreakpoint:
+ log.Printf("%s: %s breakpoint, stopping signal 0x%" PRIx32, __FUNCTION__,
+ header, stop_info.details.signal.signo);
+ return;
+ case eStopReasonWatchpoint:
+ log.Printf("%s: %s watchpoint, stopping signal 0x%" PRIx32, __FUNCTION__,
+ header, stop_info.details.signal.signo);
+ return;
+ case eStopReasonSignal:
+ log.Printf("%s: %s signal 0x%02" PRIx32, __FUNCTION__, header,
+ stop_info.details.signal.signo);
+ return;
+ case eStopReasonException:
+ log.Printf("%s: %s exception type 0x%02" PRIx64, __FUNCTION__, header,
+ stop_info.details.exception.type);
+ return;
+ case eStopReasonExec:
+ log.Printf("%s: %s exec, stopping signal 0x%" PRIx32, __FUNCTION__, header,
+ stop_info.details.signal.signo);
+ return;
+ case eStopReasonPlanComplete:
+ log.Printf("%s: %s plan complete", __FUNCTION__, header);
+ return;
+ case eStopReasonThreadExiting:
+ log.Printf("%s: %s thread exiting", __FUNCTION__, header);
+ return;
+ case eStopReasonInstrumentation:
+ log.Printf("%s: %s instrumentation", __FUNCTION__, header);
+ return;
+ default:
+ log.Printf("%s: %s invalid stop reason %" PRIu32, __FUNCTION__, header,
+ static_cast<uint32_t>(stop_info.reason));
+ }
}
-
-NativeThreadLinux::NativeThreadLinux (NativeProcessLinux *process, lldb::tid_t tid) :
- NativeThreadProtocol (process, tid),
- m_state (StateType::eStateInvalid),
- m_stop_info (),
- m_reg_context_sp (),
- m_stop_description ()
-{
}
-std::string
-NativeThreadLinux::GetName()
-{
- NativeProcessProtocolSP process_sp = m_process_wp.lock ();
- if (!process_sp)
- return "<unknown: no process>";
-
- // const NativeProcessLinux *const process = reinterpret_cast<NativeProcessLinux*> (process_sp->get ());
- llvm::SmallString<32> thread_name;
- HostNativeThread::GetName(GetID(), thread_name);
- return thread_name.c_str();
+NativeThreadLinux::NativeThreadLinux(NativeProcessLinux *process,
+ lldb::tid_t tid)
+ : NativeThreadProtocol(process, tid), m_state(StateType::eStateInvalid),
+ m_stop_info(), m_reg_context_sp(), m_stop_description() {}
+
+std::string NativeThreadLinux::GetName() {
+ NativeProcessProtocolSP process_sp = m_process_wp.lock();
+ if (!process_sp)
+ return "<unknown: no process>";
+
+ // const NativeProcessLinux *const process =
+ // reinterpret_cast<NativeProcessLinux*> (process_sp->get ());
+ llvm::SmallString<32> thread_name;
+ HostNativeThread::GetName(GetID(), thread_name);
+ return thread_name.c_str();
}
-lldb::StateType
-NativeThreadLinux::GetState ()
-{
- return m_state;
-}
+lldb::StateType NativeThreadLinux::GetState() { return m_state; }
+
+bool NativeThreadLinux::GetStopReason(ThreadStopInfo &stop_info,
+ std::string &description) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
+
+ description.clear();
+
+ switch (m_state) {
+ case eStateStopped:
+ case eStateCrashed:
+ case eStateExited:
+ case eStateSuspended:
+ case eStateUnloaded:
+ if (log)
+ LogThreadStopInfo(*log, m_stop_info, "m_stop_info in thread:");
+ stop_info = m_stop_info;
+ description = m_stop_description;
+ if (log)
+ LogThreadStopInfo(*log, stop_info, "returned stop_info:");
+ return true;
-bool
-NativeThreadLinux::GetStopReason (ThreadStopInfo &stop_info, std::string& description)
-{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
-
- description.clear();
-
- switch (m_state)
- {
- case eStateStopped:
- case eStateCrashed:
- case eStateExited:
- case eStateSuspended:
- case eStateUnloaded:
- if (log)
- LogThreadStopInfo (*log, m_stop_info, "m_stop_info in thread:");
- stop_info = m_stop_info;
- description = m_stop_description;
- if (log)
- LogThreadStopInfo (*log, stop_info, "returned stop_info:");
-
- return true;
-
- case eStateInvalid:
- case eStateConnected:
- case eStateAttaching:
- case eStateLaunching:
- case eStateRunning:
- case eStateStepping:
- case eStateDetached:
- if (log)
- {
- log->Printf ("NativeThreadLinux::%s tid %" PRIu64 " in state %s cannot answer stop reason",
- __FUNCTION__, GetID (), StateAsCString (m_state));
- }
- return false;
+ case eStateInvalid:
+ case eStateConnected:
+ case eStateAttaching:
+ case eStateLaunching:
+ case eStateRunning:
+ case eStateStepping:
+ case eStateDetached:
+ if (log) {
+ log->Printf("NativeThreadLinux::%s tid %" PRIu64
+ " in state %s cannot answer stop reason",
+ __FUNCTION__, GetID(), StateAsCString(m_state));
}
- llvm_unreachable("unhandled StateType!");
+ return false;
+ }
+ llvm_unreachable("unhandled StateType!");
}
-NativeRegisterContextSP
-NativeThreadLinux::GetRegisterContext ()
-{
- // Return the register context if we already created it.
- if (m_reg_context_sp)
- return m_reg_context_sp;
+NativeRegisterContextSP NativeThreadLinux::GetRegisterContext() {
+ // Return the register context if we already created it.
+ if (m_reg_context_sp)
+ return m_reg_context_sp;
- NativeProcessProtocolSP m_process_sp = m_process_wp.lock ();
- if (!m_process_sp)
- return NativeRegisterContextSP ();
+ NativeProcessProtocolSP m_process_sp = m_process_wp.lock();
+ if (!m_process_sp)
+ return NativeRegisterContextSP();
- ArchSpec target_arch;
- if (!m_process_sp->GetArchitecture (target_arch))
- return NativeRegisterContextSP ();
+ ArchSpec target_arch;
+ if (!m_process_sp->GetArchitecture(target_arch))
+ return NativeRegisterContextSP();
- const uint32_t concrete_frame_idx = 0;
- m_reg_context_sp.reset (NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(target_arch,
- *this,
- concrete_frame_idx));
+ const uint32_t concrete_frame_idx = 0;
+ m_reg_context_sp.reset(
+ NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
+ target_arch, *this, concrete_frame_idx));
- return m_reg_context_sp;
+ return m_reg_context_sp;
}
-Error
-NativeThreadLinux::SetWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware)
-{
- if (!hardware)
- return Error ("not implemented");
- if (m_state == eStateLaunching)
- return Error ();
- Error error = RemoveWatchpoint(addr);
- if (error.Fail()) return error;
- NativeRegisterContextSP reg_ctx = GetRegisterContext ();
- uint32_t wp_index =
- reg_ctx->SetHardwareWatchpoint (addr, size, watch_flags);
- if (wp_index == LLDB_INVALID_INDEX32)
- return Error ("Setting hardware watchpoint failed.");
- m_watchpoint_index_map.insert({addr, wp_index});
- return Error ();
+Error NativeThreadLinux::SetWatchpoint(lldb::addr_t addr, size_t size,
+ uint32_t watch_flags, bool hardware) {
+ if (!hardware)
+ return Error("not implemented");
+ if (m_state == eStateLaunching)
+ return Error();
+ Error error = RemoveWatchpoint(addr);
+ if (error.Fail())
+ return error;
+ NativeRegisterContextSP reg_ctx = GetRegisterContext();
+ uint32_t wp_index = reg_ctx->SetHardwareWatchpoint(addr, size, watch_flags);
+ if (wp_index == LLDB_INVALID_INDEX32)
+ return Error("Setting hardware watchpoint failed.");
+ m_watchpoint_index_map.insert({addr, wp_index});
+ return Error();
}
-Error
-NativeThreadLinux::RemoveWatchpoint (lldb::addr_t addr)
-{
- auto wp = m_watchpoint_index_map.find(addr);
- if (wp == m_watchpoint_index_map.end())
- return Error ();
- uint32_t wp_index = wp->second;
- m_watchpoint_index_map.erase(wp);
- if (GetRegisterContext()->ClearHardwareWatchpoint(wp_index))
- return Error ();
- return Error ("Clearing hardware watchpoint failed.");
+Error NativeThreadLinux::RemoveWatchpoint(lldb::addr_t addr) {
+ auto wp = m_watchpoint_index_map.find(addr);
+ if (wp == m_watchpoint_index_map.end())
+ return Error();
+ uint32_t wp_index = wp->second;
+ m_watchpoint_index_map.erase(wp);
+ if (GetRegisterContext()->ClearHardwareWatchpoint(wp_index))
+ return Error();
+ return Error("Clearing hardware watchpoint failed.");
}
-Error
-NativeThreadLinux::Resume(uint32_t signo)
-{
- const StateType new_state = StateType::eStateRunning;
- MaybeLogStateChange (new_state);
- m_state = new_state;
-
- m_stop_info.reason = StopReason::eStopReasonNone;
- m_stop_description.clear();
-
- // If watchpoints have been set, but none on this thread,
- // then this is a new thread. So set all existing watchpoints.
- if (m_watchpoint_index_map.empty())
- {
- NativeProcessLinux &process = GetProcess();
-
- const auto &watchpoint_map = process.GetWatchpointMap();
- GetRegisterContext()->ClearAllHardwareWatchpoints();
- for (const auto &pair : watchpoint_map)
- {
- const auto &wp = pair.second;
- SetWatchpoint(wp.m_addr, wp.m_size, wp.m_watch_flags, wp.m_hardware);
- }
- }
+Error NativeThreadLinux::Resume(uint32_t signo) {
+ const StateType new_state = StateType::eStateRunning;
+ MaybeLogStateChange(new_state);
+ m_state = new_state;
- intptr_t data = 0;
+ m_stop_info.reason = StopReason::eStopReasonNone;
+ m_stop_description.clear();
- if (signo != LLDB_INVALID_SIGNAL_NUMBER)
- data = signo;
+ // If watchpoints have been set, but none on this thread,
+ // then this is a new thread. So set all existing watchpoints.
+ if (m_watchpoint_index_map.empty()) {
+ NativeProcessLinux &process = GetProcess();
- return NativeProcessLinux::PtraceWrapper(PTRACE_CONT, GetID(), nullptr, reinterpret_cast<void *>(data));
-}
+ const auto &watchpoint_map = process.GetWatchpointMap();
+ GetRegisterContext()->ClearAllHardwareWatchpoints();
+ for (const auto &pair : watchpoint_map) {
+ const auto &wp = pair.second;
+ SetWatchpoint(wp.m_addr, wp.m_size, wp.m_watch_flags, wp.m_hardware);
+ }
+ }
-void
-NativeThreadLinux::MaybePrepareSingleStepWorkaround()
-{
- if (!SingleStepWorkaroundNeeded())
- return;
+ intptr_t data = 0;
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
+ if (signo != LLDB_INVALID_SIGNAL_NUMBER)
+ data = signo;
- if (sched_getaffinity(static_cast<::pid_t>(m_tid), sizeof m_original_cpu_set, &m_original_cpu_set) != 0)
- {
- // This should really not fail. But, just in case...
- if (log)
- {
- Error error(errno, eErrorTypePOSIX);
- log->Printf("NativeThreadLinux::%s Unable to get cpu affinity for thread %" PRIx64 ": %s", __FUNCTION__,
- m_tid, error.AsCString());
- }
- return;
- }
+ return NativeProcessLinux::PtraceWrapper(PTRACE_CONT, GetID(), nullptr,
+ reinterpret_cast<void *>(data));
+}
- cpu_set_t set;
- CPU_ZERO(&set);
- CPU_SET(0, &set);
- if (sched_setaffinity(static_cast<::pid_t>(m_tid), sizeof set, &set) != 0 && log)
- {
- // This may fail in very locked down systems, if the thread is not allowed to run on
- // cpu 0. If that happens, only thing we can do is it log it and continue...
- Error error(errno, eErrorTypePOSIX);
- log->Printf("NativeThreadLinux::%s Unable to set cpu affinity for thread %" PRIx64 ": %s", __FUNCTION__, m_tid,
- error.AsCString());
+void NativeThreadLinux::MaybePrepareSingleStepWorkaround() {
+ if (!SingleStepWorkaroundNeeded())
+ return;
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
+
+ if (sched_getaffinity(static_cast<::pid_t>(m_tid), sizeof m_original_cpu_set,
+ &m_original_cpu_set) != 0) {
+ // This should really not fail. But, just in case...
+ if (log) {
+ Error error(errno, eErrorTypePOSIX);
+ log->Printf(
+ "NativeThreadLinux::%s Unable to get cpu affinity for thread %" PRIx64
+ ": %s",
+ __FUNCTION__, m_tid, error.AsCString());
}
+ return;
+ }
+
+ cpu_set_t set;
+ CPU_ZERO(&set);
+ CPU_SET(0, &set);
+ if (sched_setaffinity(static_cast<::pid_t>(m_tid), sizeof set, &set) != 0 &&
+ log) {
+ // This may fail in very locked down systems, if the thread is not allowed
+ // to run on
+ // cpu 0. If that happens, only thing we can do is it log it and continue...
+ Error error(errno, eErrorTypePOSIX);
+ log->Printf(
+ "NativeThreadLinux::%s Unable to set cpu affinity for thread %" PRIx64
+ ": %s",
+ __FUNCTION__, m_tid, error.AsCString());
+ }
}
-void
-NativeThreadLinux::MaybeCleanupSingleStepWorkaround()
-{
- if (!SingleStepWorkaroundNeeded())
- return;
-
- if (sched_setaffinity(static_cast<::pid_t>(m_tid), sizeof m_original_cpu_set, &m_original_cpu_set) != 0)
- {
- Error error(errno, eErrorTypePOSIX);
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
- log->Printf("NativeThreadLinux::%s Unable to reset cpu affinity for thread %" PRIx64 ": %s", __FUNCTION__,
- m_tid, error.AsCString());
- }
+void NativeThreadLinux::MaybeCleanupSingleStepWorkaround() {
+ if (!SingleStepWorkaroundNeeded())
+ return;
+
+ if (sched_setaffinity(static_cast<::pid_t>(m_tid), sizeof m_original_cpu_set,
+ &m_original_cpu_set) != 0) {
+ Error error(errno, eErrorTypePOSIX);
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
+ log->Printf(
+ "NativeThreadLinux::%s Unable to reset cpu affinity for thread %" PRIx64
+ ": %s",
+ __FUNCTION__, m_tid, error.AsCString());
+ }
}
-Error
-NativeThreadLinux::SingleStep(uint32_t signo)
-{
- const StateType new_state = StateType::eStateStepping;
- MaybeLogStateChange (new_state);
- m_state = new_state;
- m_stop_info.reason = StopReason::eStopReasonNone;
-
- MaybePrepareSingleStepWorkaround();
-
- intptr_t data = 0;
- if (signo != LLDB_INVALID_SIGNAL_NUMBER)
- data = signo;
-
- // If hardware single-stepping is not supported, we just do a continue. The breakpoint on the
- // next instruction has been setup in NativeProcessLinux::Resume.
- return NativeProcessLinux::PtraceWrapper(GetProcess().SupportHardwareSingleStepping() ? PTRACE_SINGLESTEP
- : PTRACE_CONT,
- m_tid, nullptr, reinterpret_cast<void *>(data));
+Error NativeThreadLinux::SingleStep(uint32_t signo) {
+ const StateType new_state = StateType::eStateStepping;
+ MaybeLogStateChange(new_state);
+ m_state = new_state;
+ m_stop_info.reason = StopReason::eStopReasonNone;
+
+ MaybePrepareSingleStepWorkaround();
+
+ intptr_t data = 0;
+ if (signo != LLDB_INVALID_SIGNAL_NUMBER)
+ data = signo;
+
+ // If hardware single-stepping is not supported, we just do a continue. The
+ // breakpoint on the
+ // next instruction has been setup in NativeProcessLinux::Resume.
+ return NativeProcessLinux::PtraceWrapper(
+ GetProcess().SupportHardwareSingleStepping() ? PTRACE_SINGLESTEP
+ : PTRACE_CONT,
+ m_tid, nullptr, reinterpret_cast<void *>(data));
}
-void
-NativeThreadLinux::SetStoppedBySignal(uint32_t signo, const siginfo_t *info)
-{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
- if (log)
- log->Printf ("NativeThreadLinux::%s called with signal 0x%02" PRIx32, __FUNCTION__, signo);
-
- SetStopped();
-
- m_stop_info.reason = StopReason::eStopReasonSignal;
- m_stop_info.details.signal.signo = signo;
-
- m_stop_description.clear();
- if (info)
- {
- switch (signo)
- {
- case SIGSEGV:
- case SIGBUS:
- case SIGFPE:
- case SIGILL:
- //In case of MIPS64 target, SI_KERNEL is generated for invalid 64bit address.
- const auto reason = (info->si_signo == SIGBUS && info->si_code == SI_KERNEL) ?
- CrashReason::eInvalidAddress : GetCrashReason(*info);
- m_stop_description = GetCrashReasonString(reason, reinterpret_cast<uintptr_t>(info->si_addr));
- break;
- }
+void NativeThreadLinux::SetStoppedBySignal(uint32_t signo,
+ const siginfo_t *info) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
+ if (log)
+ log->Printf("NativeThreadLinux::%s called with signal 0x%02" PRIx32,
+ __FUNCTION__, signo);
+
+ SetStopped();
+
+ m_stop_info.reason = StopReason::eStopReasonSignal;
+ m_stop_info.details.signal.signo = signo;
+
+ m_stop_description.clear();
+ if (info) {
+ switch (signo) {
+ case SIGSEGV:
+ case SIGBUS:
+ case SIGFPE:
+ case SIGILL:
+ // In case of MIPS64 target, SI_KERNEL is generated for invalid 64bit
+ // address.
+ const auto reason =
+ (info->si_signo == SIGBUS && info->si_code == SI_KERNEL)
+ ? CrashReason::eInvalidAddress
+ : GetCrashReason(*info);
+ m_stop_description = GetCrashReasonString(reason, *info);
+ break;
}
+ }
}
-bool
-NativeThreadLinux::IsStopped (int *signo)
-{
- if (!StateIsStoppedState (m_state, false))
- return false;
-
- // If we are stopped by a signal, return the signo.
- if (signo &&
- m_state == StateType::eStateStopped &&
- m_stop_info.reason == StopReason::eStopReasonSignal)
- {
- *signo = m_stop_info.details.signal.signo;
- }
+bool NativeThreadLinux::IsStopped(int *signo) {
+ if (!StateIsStoppedState(m_state, false))
+ return false;
- // Regardless, we are stopped.
- return true;
+ // If we are stopped by a signal, return the signo.
+ if (signo && m_state == StateType::eStateStopped &&
+ m_stop_info.reason == StopReason::eStopReasonSignal) {
+ *signo = m_stop_info.details.signal.signo;
+ }
+
+ // Regardless, we are stopped.
+ return true;
}
-void
-NativeThreadLinux::SetStopped()
-{
- if (m_state == StateType::eStateStepping)
- MaybeCleanupSingleStepWorkaround();
+void NativeThreadLinux::SetStopped() {
+ if (m_state == StateType::eStateStepping)
+ MaybeCleanupSingleStepWorkaround();
- const StateType new_state = StateType::eStateStopped;
- MaybeLogStateChange(new_state);
- m_state = new_state;
- m_stop_description.clear();
+ const StateType new_state = StateType::eStateStopped;
+ MaybeLogStateChange(new_state);
+ m_state = new_state;
+ m_stop_description.clear();
}
-void
-NativeThreadLinux::SetStoppedByExec ()
-{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
- if (log)
- log->Printf ("NativeThreadLinux::%s()", __FUNCTION__);
+void NativeThreadLinux::SetStoppedByExec() {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
+ if (log)
+ log->Printf("NativeThreadLinux::%s()", __FUNCTION__);
- SetStopped();
+ SetStopped();
- m_stop_info.reason = StopReason::eStopReasonExec;
- m_stop_info.details.signal.signo = SIGSTOP;
+ m_stop_info.reason = StopReason::eStopReasonExec;
+ m_stop_info.details.signal.signo = SIGSTOP;
}
-void
-NativeThreadLinux::SetStoppedByBreakpoint ()
-{
- SetStopped();
+void NativeThreadLinux::SetStoppedByBreakpoint() {
+ SetStopped();
- m_stop_info.reason = StopReason::eStopReasonBreakpoint;
- m_stop_info.details.signal.signo = SIGTRAP;
- m_stop_description.clear();
+ m_stop_info.reason = StopReason::eStopReasonBreakpoint;
+ m_stop_info.details.signal.signo = SIGTRAP;
+ m_stop_description.clear();
}
-void
-NativeThreadLinux::SetStoppedByWatchpoint (uint32_t wp_index)
-{
- SetStopped();
+void NativeThreadLinux::SetStoppedByWatchpoint(uint32_t wp_index) {
+ SetStopped();
- lldbassert(wp_index != LLDB_INVALID_INDEX32 &&
- "wp_index cannot be invalid");
+ lldbassert(wp_index != LLDB_INVALID_INDEX32 && "wp_index cannot be invalid");
- std::ostringstream ostr;
- ostr << GetRegisterContext()->GetWatchpointAddress(wp_index) << " ";
- ostr << wp_index;
+ std::ostringstream ostr;
+ ostr << GetRegisterContext()->GetWatchpointAddress(wp_index) << " ";
+ ostr << wp_index;
- /*
- * MIPS: Last 3bits of the watchpoint address are masked by the kernel. For example:
- * 'n' is at 0x120010d00 and 'm' is 0x120010d04. When a watchpoint is set at 'm', then
- * watch exception is generated even when 'n' is read/written. To handle this case,
- * find the base address of the load/store instruction and append it in the stop-info
- * packet.
- */
- ostr << " " << GetRegisterContext()->GetWatchpointHitAddress(wp_index);
+ /*
+ * MIPS: Last 3bits of the watchpoint address are masked by the kernel. For
+ * example:
+ * 'n' is at 0x120010d00 and 'm' is 0x120010d04. When a watchpoint is set at
+ * 'm', then
+ * watch exception is generated even when 'n' is read/written. To handle this
+ * case,
+ * find the base address of the load/store instruction and append it in the
+ * stop-info
+ * packet.
+ */
+ ostr << " " << GetRegisterContext()->GetWatchpointHitAddress(wp_index);
- m_stop_description = ostr.str();
+ m_stop_description = ostr.str();
- m_stop_info.reason = StopReason::eStopReasonWatchpoint;
- m_stop_info.details.signal.signo = SIGTRAP;
+ m_stop_info.reason = StopReason::eStopReasonWatchpoint;
+ m_stop_info.details.signal.signo = SIGTRAP;
}
-bool
-NativeThreadLinux::IsStoppedAtBreakpoint ()
-{
- return GetState () == StateType::eStateStopped &&
- m_stop_info.reason == StopReason::eStopReasonBreakpoint;
+bool NativeThreadLinux::IsStoppedAtBreakpoint() {
+ return GetState() == StateType::eStateStopped &&
+ m_stop_info.reason == StopReason::eStopReasonBreakpoint;
}
-bool
-NativeThreadLinux::IsStoppedAtWatchpoint ()
-{
- return GetState () == StateType::eStateStopped &&
- m_stop_info.reason == StopReason::eStopReasonWatchpoint;
+bool NativeThreadLinux::IsStoppedAtWatchpoint() {
+ return GetState() == StateType::eStateStopped &&
+ m_stop_info.reason == StopReason::eStopReasonWatchpoint;
}
-void
-NativeThreadLinux::SetStoppedByTrace ()
-{
- SetStopped();
+void NativeThreadLinux::SetStoppedByTrace() {
+ SetStopped();
- m_stop_info.reason = StopReason::eStopReasonTrace;
- m_stop_info.details.signal.signo = SIGTRAP;
+ m_stop_info.reason = StopReason::eStopReasonTrace;
+ m_stop_info.details.signal.signo = SIGTRAP;
}
-void
-NativeThreadLinux::SetStoppedWithNoReason ()
-{
- SetStopped();
+void NativeThreadLinux::SetStoppedWithNoReason() {
+ SetStopped();
- m_stop_info.reason = StopReason::eStopReasonNone;
- m_stop_info.details.signal.signo = 0;
+ m_stop_info.reason = StopReason::eStopReasonNone;
+ m_stop_info.details.signal.signo = 0;
}
-void
-NativeThreadLinux::SetExited ()
-{
- const StateType new_state = StateType::eStateExited;
- MaybeLogStateChange (new_state);
- m_state = new_state;
+void NativeThreadLinux::SetExited() {
+ const StateType new_state = StateType::eStateExited;
+ MaybeLogStateChange(new_state);
+ m_state = new_state;
- m_stop_info.reason = StopReason::eStopReasonThreadExiting;
+ m_stop_info.reason = StopReason::eStopReasonThreadExiting;
}
-Error
-NativeThreadLinux::RequestStop ()
-{
- Log* log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
+Error NativeThreadLinux::RequestStop() {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
- NativeProcessLinux &process = GetProcess();
+ NativeProcessLinux &process = GetProcess();
+
+ lldb::pid_t pid = process.GetID();
+ lldb::tid_t tid = GetID();
- lldb::pid_t pid = process.GetID();
- lldb::tid_t tid = GetID();
+ if (log)
+ log->Printf("NativeThreadLinux::%s requesting thread stop(pid: %" PRIu64
+ ", tid: %" PRIu64 ")",
+ __FUNCTION__, pid, tid);
+ Error err;
+ errno = 0;
+ if (::tgkill(pid, tid, SIGSTOP) != 0) {
+ err.SetErrorToErrno();
if (log)
- log->Printf ("NativeThreadLinux::%s requesting thread stop(pid: %" PRIu64 ", tid: %" PRIu64 ")", __FUNCTION__, pid, tid);
-
- Error err;
- errno = 0;
- if (::tgkill (pid, tid, SIGSTOP) != 0)
- {
- err.SetErrorToErrno ();
- if (log)
- log->Printf ("NativeThreadLinux::%s tgkill(%" PRIu64 ", %" PRIu64 ", SIGSTOP) failed: %s", __FUNCTION__, pid, tid, err.AsCString ());
- }
+ log->Printf("NativeThreadLinux::%s tgkill(%" PRIu64 ", %" PRIu64
+ ", SIGSTOP) failed: %s",
+ __FUNCTION__, pid, tid, err.AsCString());
+ }
- return err;
+ return err;
}
-void
-NativeThreadLinux::MaybeLogStateChange (lldb::StateType new_state)
-{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
- // If we're not logging, we're done.
- if (!log)
- return;
-
- // If this is a state change to the same state, we're done.
- lldb::StateType old_state = m_state;
- if (new_state == old_state)
- return;
-
- NativeProcessProtocolSP m_process_sp = m_process_wp.lock ();
- lldb::pid_t pid = m_process_sp ? m_process_sp->GetID () : LLDB_INVALID_PROCESS_ID;
-
- // Log it.
- log->Printf ("NativeThreadLinux: thread (pid=%" PRIu64 ", tid=%" PRIu64 ") changing from state %s to %s", pid, GetID (), StateAsCString (old_state), StateAsCString (new_state));
+void NativeThreadLinux::MaybeLogStateChange(lldb::StateType new_state) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
+ // If we're not logging, we're done.
+ if (!log)
+ return;
+
+ // If this is a state change to the same state, we're done.
+ lldb::StateType old_state = m_state;
+ if (new_state == old_state)
+ return;
+
+ NativeProcessProtocolSP m_process_sp = m_process_wp.lock();
+ lldb::pid_t pid =
+ m_process_sp ? m_process_sp->GetID() : LLDB_INVALID_PROCESS_ID;
+
+ // Log it.
+ log->Printf("NativeThreadLinux: thread (pid=%" PRIu64 ", tid=%" PRIu64
+ ") changing from state %s to %s",
+ pid, GetID(), StateAsCString(old_state),
+ StateAsCString(new_state));
}
-NativeProcessLinux &
-NativeThreadLinux::GetProcess()
-{
- auto process_sp = std::static_pointer_cast<NativeProcessLinux>(NativeThreadProtocol::GetProcess());
- assert(process_sp);
- return *process_sp;
+NativeProcessLinux &NativeThreadLinux::GetProcess() {
+ auto process_sp = std::static_pointer_cast<NativeProcessLinux>(
+ NativeThreadProtocol::GetProcess());
+ assert(process_sp);
+ return *process_sp;
}
diff --git a/source/Plugins/Process/Linux/NativeThreadLinux.h b/source/Plugins/Process/Linux/NativeThreadLinux.h
index f1b6a6e44782..f170bb1e8508 100644
--- a/source/Plugins/Process/Linux/NativeThreadLinux.h
+++ b/source/Plugins/Process/Linux/NativeThreadLinux.h
@@ -10,8 +10,8 @@
#ifndef liblldb_NativeThreadLinux_H_
#define liblldb_NativeThreadLinux_H_
-#include "lldb/lldb-private-forward.h"
#include "lldb/Host/common/NativeThreadProtocol.h"
+#include "lldb/lldb-private-forward.h"
#include <sched.h>
@@ -22,118 +22,95 @@
namespace lldb_private {
namespace process_linux {
- class NativeProcessLinux;
+class NativeProcessLinux;
- class NativeThreadLinux : public NativeThreadProtocol
- {
- friend class NativeProcessLinux;
+class NativeThreadLinux : public NativeThreadProtocol {
+ friend class NativeProcessLinux;
- public:
- NativeThreadLinux (NativeProcessLinux *process, lldb::tid_t tid);
+public:
+ NativeThreadLinux(NativeProcessLinux *process, lldb::tid_t tid);
- // ---------------------------------------------------------------------
- // NativeThreadProtocol Interface
- // ---------------------------------------------------------------------
- std::string
- GetName() override;
+ // ---------------------------------------------------------------------
+ // NativeThreadProtocol Interface
+ // ---------------------------------------------------------------------
+ std::string GetName() override;
- lldb::StateType
- GetState () override;
+ lldb::StateType GetState() override;
- bool
- GetStopReason (ThreadStopInfo &stop_info, std::string& description) override;
+ bool GetStopReason(ThreadStopInfo &stop_info,
+ std::string &description) override;
- NativeRegisterContextSP
- GetRegisterContext () override;
+ NativeRegisterContextSP GetRegisterContext() override;
- Error
- SetWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware) override;
+ Error SetWatchpoint(lldb::addr_t addr, size_t size, uint32_t watch_flags,
+ bool hardware) override;
- Error
- RemoveWatchpoint (lldb::addr_t addr) override;
+ Error RemoveWatchpoint(lldb::addr_t addr) override;
- private:
- // ---------------------------------------------------------------------
- // Interface for friend classes
- // ---------------------------------------------------------------------
+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);
+ /// 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);
+ /// 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);
- void
- SetStoppedBySignal(uint32_t signo, const siginfo_t *info = nullptr);
+ 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);
+ /// 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);
- void
- SetStoppedByExec ();
+ void SetStoppedByExec();
- void
- SetStoppedByBreakpoint ();
+ void SetStoppedByBreakpoint();
- void
- SetStoppedByWatchpoint (uint32_t wp_index);
+ void SetStoppedByWatchpoint(uint32_t wp_index);
- bool
- IsStoppedAtBreakpoint ();
+ bool IsStoppedAtBreakpoint();
- bool
- IsStoppedAtWatchpoint ();
+ bool IsStoppedAtWatchpoint();
- void
- SetStoppedByTrace ();
+ void SetStoppedByTrace();
- void
- SetStoppedWithNoReason ();
+ void SetStoppedWithNoReason();
- void
- SetExited ();
+ void SetExited();
- Error
- RequestStop ();
+ Error RequestStop();
- // ---------------------------------------------------------------------
- // Private interface
- // ---------------------------------------------------------------------
- void
- MaybeLogStateChange (lldb::StateType new_state);
+ // ---------------------------------------------------------------------
+ // Private interface
+ // ---------------------------------------------------------------------
+ void MaybeLogStateChange(lldb::StateType new_state);
- NativeProcessLinux &
- GetProcess();
+ NativeProcessLinux &GetProcess();
- void
- SetStopped();
+ void SetStopped();
- inline void
- MaybePrepareSingleStepWorkaround();
+ inline void MaybePrepareSingleStepWorkaround();
- inline void
- MaybeCleanupSingleStepWorkaround();
+ inline void MaybeCleanupSingleStepWorkaround();
- // ---------------------------------------------------------------------
- // Member Variables
- // ---------------------------------------------------------------------
- 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.
- };
+ // ---------------------------------------------------------------------
+ // Member Variables
+ // ---------------------------------------------------------------------
+ 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.
+};
- typedef std::shared_ptr<NativeThreadLinux> NativeThreadLinuxSP;
+typedef std::shared_ptr<NativeThreadLinux> NativeThreadLinuxSP;
} // namespace process_linux
} // namespace lldb_private
diff --git a/source/Plugins/Process/Linux/ProcFileReader.cpp b/source/Plugins/Process/Linux/ProcFileReader.cpp
index 4d1f231f4f9b..a1bb7a6e09d5 100644
--- a/source/Plugins/Process/Linux/ProcFileReader.cpp
+++ b/source/Plugins/Process/Linux/ProcFileReader.cpp
@@ -26,83 +26,78 @@
using namespace lldb_private;
using namespace lldb_private::process_linux;
-lldb::DataBufferSP
-ProcFileReader::ReadIntoDataBuffer (lldb::pid_t pid, const char *name)
-{
- int fd;
- char path[PATH_MAX];
-
- // Make sure we've got a nil terminated buffer for all the folks calling
- // GetBytes() directly off our returned DataBufferSP if we hit an error.
- lldb::DataBufferSP buf_sp (new DataBufferHeap(1, 0));
-
- // Ideally, we would simply create a FileSpec and call ReadFileContents.
- // However, files in procfs have zero size (since they are, in general,
- // dynamically generated by the kernel) which is incompatible with the
- // current ReadFileContents implementation. Therefore we simply stream the
- // data into a DataBuffer ourselves.
- if (snprintf (path, PATH_MAX, "/proc/%" PRIu64 "/%s", pid, name) > 0)
- {
- if ((fd = open (path, O_RDONLY, 0)) >= 0)
- {
- size_t bytes_read = 0;
- std::unique_ptr<DataBufferHeap> buf_ap(new DataBufferHeap(1024, 0));
-
- for (;;)
- {
- size_t avail = buf_ap->GetByteSize() - bytes_read;
- ssize_t status = read (fd, buf_ap->GetBytes() + bytes_read, avail);
-
- if (status < 0)
- break;
-
- if (status == 0)
- {
- buf_ap->SetByteSize (bytes_read);
- buf_sp.reset (buf_ap.release());
- break;
- }
-
- bytes_read += status;
-
- if (avail - status == 0)
- buf_ap->SetByteSize (2 * buf_ap->GetByteSize());
- }
-
- close (fd);
+lldb::DataBufferSP ProcFileReader::ReadIntoDataBuffer(lldb::pid_t pid,
+ const char *name) {
+ int fd;
+ char path[PATH_MAX];
+
+ // Make sure we've got a nil terminated buffer for all the folks calling
+ // GetBytes() directly off our returned DataBufferSP if we hit an error.
+ lldb::DataBufferSP buf_sp(new DataBufferHeap(1, 0));
+
+ // Ideally, we would simply create a FileSpec and call ReadFileContents.
+ // However, files in procfs have zero size (since they are, in general,
+ // dynamically generated by the kernel) which is incompatible with the
+ // current ReadFileContents implementation. Therefore we simply stream the
+ // data into a DataBuffer ourselves.
+ if (snprintf(path, PATH_MAX, "/proc/%" PRIu64 "/%s", pid, name) > 0) {
+ if ((fd = open(path, O_RDONLY, 0)) >= 0) {
+ size_t bytes_read = 0;
+ std::unique_ptr<DataBufferHeap> buf_ap(new DataBufferHeap(1024, 0));
+
+ for (;;) {
+ size_t avail = buf_ap->GetByteSize() - bytes_read;
+ ssize_t status = read(fd, buf_ap->GetBytes() + bytes_read, avail);
+
+ if (status < 0)
+ break;
+
+ if (status == 0) {
+ buf_ap->SetByteSize(bytes_read);
+ buf_sp.reset(buf_ap.release());
+ break;
}
- }
-
- return buf_sp;
-}
-Error
-ProcFileReader::ProcessLineByLine (lldb::pid_t pid, const char *name, std::function<bool (const std::string &line)> line_parser)
-{
- Error error;
-
- // Try to open the /proc/{pid}/maps entry.
- char filename [PATH_MAX];
- snprintf (filename, sizeof(filename), "/proc/%" PRIu64 "/%s", pid, name);
- filename[sizeof (filename) - 1] = '\0';
-
- std::ifstream proc_file (filename);
- if (proc_file.fail ())
- {
- error.SetErrorStringWithFormat ("failed to open file '%s'", filename);
- return error;
- }
+ bytes_read += status;
- // Read the file line by line, processing until either end of file or when the line_parser returns false.
- std::string line;
- bool should_continue = true;
+ if (avail - status == 0)
+ buf_ap->SetByteSize(2 * buf_ap->GetByteSize());
+ }
- while (should_continue && std::getline (proc_file, line))
- {
- // Pass the line over to the line_parser for processing. If the line_parser returns false, we
- // stop processing.
- should_continue = line_parser (line);
+ close(fd);
}
+ }
+
+ return buf_sp;
+}
+Error ProcFileReader::ProcessLineByLine(
+ lldb::pid_t pid, const char *name,
+ std::function<bool(const std::string &line)> line_parser) {
+ Error error;
+
+ // Try to open the /proc/{pid}/maps entry.
+ char filename[PATH_MAX];
+ snprintf(filename, sizeof(filename), "/proc/%" PRIu64 "/%s", pid, name);
+ filename[sizeof(filename) - 1] = '\0';
+
+ std::ifstream proc_file(filename);
+ if (proc_file.fail()) {
+ error.SetErrorStringWithFormat("failed to open file '%s'", filename);
return error;
+ }
+
+ // Read the file line by line, processing until either end of file or when the
+ // line_parser returns false.
+ std::string line;
+ bool should_continue = true;
+
+ while (should_continue && std::getline(proc_file, line)) {
+ // Pass the line over to the line_parser for processing. If the line_parser
+ // returns false, we
+ // stop processing.
+ should_continue = line_parser(line);
+ }
+
+ return error;
}
diff --git a/source/Plugins/Process/Linux/ProcFileReader.h b/source/Plugins/Process/Linux/ProcFileReader.h
index 7b3812433068..dcdb3553d8c3 100644
--- a/source/Plugins/Process/Linux/ProcFileReader.h
+++ b/source/Plugins/Process/Linux/ProcFileReader.h
@@ -18,18 +18,18 @@
namespace lldb_private {
namespace process_linux {
- class ProcFileReader
- {
- public:
-
- static lldb::DataBufferSP
- ReadIntoDataBuffer (lldb::pid_t pid, const char *name);
-
- /// Parse the /proc/{@a pid}/{@a name} file line by line, passing each line to line_parser, until
- /// either end of file or until line_parser returns false.
- static Error
- ProcessLineByLine (lldb::pid_t pid, const char *name, std::function<bool (const std::string &line)> line_parser);
- };
+class ProcFileReader {
+public:
+ static lldb::DataBufferSP ReadIntoDataBuffer(lldb::pid_t pid,
+ const char *name);
+
+ /// Parse the /proc/{@a pid}/{@a name} file line by line, passing each line to
+ /// line_parser, until
+ /// either end of file or until line_parser returns false.
+ static Error
+ ProcessLineByLine(lldb::pid_t pid, const char *name,
+ std::function<bool(const std::string &line)> line_parser);
+};
} // namespace process_linux
} // namespace lldb_private
diff --git a/source/Plugins/Process/Linux/Procfs.h b/source/Plugins/Process/Linux/Procfs.h
index cad433fb095d..1d9c9dbe273f 100644
--- a/source/Plugins/Process/Linux/Procfs.h
+++ b/source/Plugins/Process/Linux/Procfs.h
@@ -13,19 +13,19 @@
#include <sys/ptrace.h>
#ifdef __ANDROID__
-#if defined (__arm64__) || defined (__aarch64__)
+#if defined(__arm64__) || defined(__aarch64__)
typedef unsigned long elf_greg_t;
-typedef elf_greg_t elf_gregset_t[(sizeof (struct user_pt_regs) / sizeof(elf_greg_t))];
+typedef elf_greg_t
+ elf_gregset_t[(sizeof(struct user_pt_regs) / sizeof(elf_greg_t))];
typedef struct user_fpsimd_state elf_fpregset_t;
#ifndef NT_FPREGSET
- #define NT_FPREGSET NT_PRFPREG
+#define NT_FPREGSET NT_PRFPREG
#endif // NT_FPREGSET
-#elif defined (__mips__)
+#elif defined(__mips__)
#ifndef NT_FPREGSET
- #define NT_FPREGSET NT_PRFPREG
+#define NT_FPREGSET NT_PRFPREG
#endif // NT_FPREGSET
#endif
-#else // __ANDROID__
+#else // __ANDROID__
#include <sys/procfs.h>
#endif // __ANDROID__
-
diff --git a/source/Plugins/Process/Linux/SingleStepCheck.cpp b/source/Plugins/Process/Linux/SingleStepCheck.cpp
index 8c557d4b6ff8..b23c1bd245d5 100644
--- a/source/Plugins/Process/Linux/SingleStepCheck.cpp
+++ b/source/Plugins/Process/Linux/SingleStepCheck.cpp
@@ -25,153 +25,142 @@
using namespace lldb_private::process_linux;
#if defined(__arm64__) || defined(__aarch64__)
-namespace
-{
-
-void LLVM_ATTRIBUTE_NORETURN
-Child()
-{
- if (ptrace(PTRACE_TRACEME, 0, nullptr, nullptr) == -1)
- _exit(1);
-
- // We just do an endless loop SIGSTOPPING ourselves until killed. The tracer will fiddle with our cpu
- // affinities and monitor the behaviour.
- for (;;)
- {
- raise(SIGSTOP);
-
- // Generate a bunch of instructions here, so that a single-step does not land in the
- // raise() accidentally. If single-stepping works, we will be spinning in this loop. If
- // it doesn't, we'll land in the raise() call above.
- for (volatile unsigned i = 0; i < CPU_SETSIZE; ++i)
- ;
- }
+namespace {
+
+void LLVM_ATTRIBUTE_NORETURN Child() {
+ if (ptrace(PTRACE_TRACEME, 0, nullptr, nullptr) == -1)
+ _exit(1);
+
+ // We just do an endless loop SIGSTOPPING ourselves until killed. The tracer
+ // will fiddle with our cpu
+ // affinities and monitor the behaviour.
+ for (;;) {
+ raise(SIGSTOP);
+
+ // Generate a bunch of instructions here, so that a single-step does not
+ // land in the
+ // raise() accidentally. If single-stepping works, we will be spinning in
+ // this loop. If
+ // it doesn't, we'll land in the raise() call above.
+ for (volatile unsigned i = 0; i < CPU_SETSIZE; ++i)
+ ;
+ }
}
-struct ChildDeleter
-{
- ::pid_t pid;
+struct ChildDeleter {
+ ::pid_t pid;
- ~ChildDeleter()
- {
- int status;
- kill(pid, SIGKILL); // Kill the child.
- waitpid(pid, &status, __WALL); // Pick up the remains.
- }
+ ~ChildDeleter() {
+ int status;
+ kill(pid, SIGKILL); // Kill the child.
+ waitpid(pid, &status, __WALL); // Pick up the remains.
+ }
};
} // end anonymous namespace
-bool
-impl::SingleStepWorkaroundNeeded()
-{
- // We shall spawn a child, and use it to verify the debug capabilities of the cpu. We shall
- // iterate through the cpus, bind the child to each one in turn, and verify that
- // single-stepping works on that cpu. A workaround is needed if we find at least one broken
- // cpu.
-
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
- Error error;
- ::pid_t child_pid = fork();
- if (child_pid == -1)
- {
- if (log)
- {
- error.SetErrorToErrno();
- log->Printf("%s failed to fork(): %s", __FUNCTION__, error.AsCString());
- }
- return false;
+bool impl::SingleStepWorkaroundNeeded() {
+ // We shall spawn a child, and use it to verify the debug capabilities of the
+ // cpu. We shall
+ // iterate through the cpus, bind the child to each one in turn, and verify
+ // that
+ // single-stepping works on that cpu. A workaround is needed if we find at
+ // least one broken
+ // cpu.
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
+ Error error;
+ ::pid_t child_pid = fork();
+ if (child_pid == -1) {
+ if (log) {
+ error.SetErrorToErrno();
+ log->Printf("%s failed to fork(): %s", __FUNCTION__, error.AsCString());
+ }
+ return false;
+ }
+ if (child_pid == 0)
+ Child();
+
+ ChildDeleter child_deleter{child_pid};
+ cpu_set_t available_cpus;
+ if (sched_getaffinity(child_pid, sizeof available_cpus, &available_cpus) ==
+ -1) {
+ if (log) {
+ error.SetErrorToErrno();
+ log->Printf("%s failed to get available cpus: %s", __FUNCTION__,
+ error.AsCString());
+ }
+ return false;
+ }
+
+ int status;
+ ::pid_t wpid = waitpid(child_pid, &status, __WALL);
+ if (wpid != child_pid || !WIFSTOPPED(status)) {
+ if (log) {
+ error.SetErrorToErrno();
+ log->Printf("%s waitpid() failed (status = %x): %s", __FUNCTION__, status,
+ error.AsCString());
}
- if (child_pid == 0)
- Child();
-
- ChildDeleter child_deleter{child_pid};
- cpu_set_t available_cpus;
- if (sched_getaffinity(child_pid, sizeof available_cpus, &available_cpus) == -1)
- {
- if (log)
- {
- error.SetErrorToErrno();
- log->Printf("%s failed to get available cpus: %s", __FUNCTION__, error.AsCString());
- }
- return false;
+ return false;
+ }
+
+ unsigned cpu;
+ for (cpu = 0; cpu < CPU_SETSIZE; ++cpu) {
+ if (!CPU_ISSET(cpu, &available_cpus))
+ continue;
+
+ cpu_set_t cpus;
+ CPU_ZERO(&cpus);
+ CPU_SET(cpu, &cpus);
+ if (sched_setaffinity(child_pid, sizeof cpus, &cpus) == -1) {
+ if (log) {
+ error.SetErrorToErrno();
+ log->Printf("%s failed to switch to cpu %u: %s", __FUNCTION__, cpu,
+ error.AsCString());
+ }
+ continue;
}
int status;
- ::pid_t wpid = waitpid(child_pid, &status, __WALL);
- if (wpid != child_pid || !WIFSTOPPED(status))
- {
- if (log)
- {
- error.SetErrorToErrno();
- log->Printf("%s waitpid() failed (status = %x): %s", __FUNCTION__, status, error.AsCString());
- }
- return false;
+ error = NativeProcessLinux::PtraceWrapper(PTRACE_SINGLESTEP, child_pid);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("%s single step failed: %s", __FUNCTION__,
+ error.AsCString());
+ break;
}
- unsigned cpu;
- for (cpu = 0; cpu < CPU_SETSIZE; ++cpu)
- {
- if (!CPU_ISSET(cpu, &available_cpus))
- continue;
-
- cpu_set_t cpus;
- CPU_ZERO(&cpus);
- CPU_SET(cpu, &cpus);
- if (sched_setaffinity(child_pid, sizeof cpus, &cpus) == -1)
- {
- if (log)
- {
- error.SetErrorToErrno();
- log->Printf("%s failed to switch to cpu %u: %s", __FUNCTION__, cpu, error.AsCString());
- }
- continue;
- }
-
- int status;
- error = NativeProcessLinux::PtraceWrapper(PTRACE_SINGLESTEP, child_pid);
- if (error.Fail())
- {
- if (log)
- log->Printf("%s single step failed: %s", __FUNCTION__, error.AsCString());
- break;
- }
-
- wpid = waitpid(child_pid, &status, __WALL);
- if (wpid != child_pid || !WIFSTOPPED(status))
- {
- if (log)
- {
- error.SetErrorToErrno();
- log->Printf("%s waitpid() failed (status = %x): %s", __FUNCTION__, status, error.AsCString());
- }
- break;
- }
- if (WSTOPSIG(status) != SIGTRAP)
- {
- if (log)
- log->Printf("%s single stepping on cpu %d failed with status %x", __FUNCTION__, cpu, status);
- break;
- }
+ wpid = waitpid(child_pid, &status, __WALL);
+ if (wpid != child_pid || !WIFSTOPPED(status)) {
+ if (log) {
+ error.SetErrorToErrno();
+ log->Printf("%s waitpid() failed (status = %x): %s", __FUNCTION__,
+ status, error.AsCString());
+ }
+ break;
}
-
- // cpu is either the index of the first broken cpu, or CPU_SETSIZE.
- if (cpu == 0)
- {
- if (log)
- log->Printf("%s SINGLE STEPPING ON FIRST CPU IS NOT WORKING. DEBUGGING LIKELY TO BE UNRELIABLE.",
- __FUNCTION__);
- // No point in trying to fiddle with the affinities, just give it our best shot and see how it goes.
- return false;
+ if (WSTOPSIG(status) != SIGTRAP) {
+ if (log)
+ log->Printf("%s single stepping on cpu %d failed with status %x",
+ __FUNCTION__, cpu, status);
+ break;
}
+ }
+
+ // cpu is either the index of the first broken cpu, or CPU_SETSIZE.
+ if (cpu == 0) {
+ if (log)
+ log->Printf("%s SINGLE STEPPING ON FIRST CPU IS NOT WORKING. DEBUGGING "
+ "LIKELY TO BE UNRELIABLE.",
+ __FUNCTION__);
+ // No point in trying to fiddle with the affinities, just give it our best
+ // shot and see how it goes.
+ return false;
+ }
- return cpu != CPU_SETSIZE;
+ return cpu != CPU_SETSIZE;
}
#else // !arm64
-bool
-impl::SingleStepWorkaroundNeeded()
-{
- return false;
-}
+bool impl::SingleStepWorkaroundNeeded() { return false; }
#endif
diff --git a/source/Plugins/Process/Linux/SingleStepCheck.h b/source/Plugins/Process/Linux/SingleStepCheck.h
index f83f7c973f8d..6e3310da840b 100644
--- a/source/Plugins/Process/Linux/SingleStepCheck.h
+++ b/source/Plugins/Process/Linux/SingleStepCheck.h
@@ -10,30 +10,29 @@
#ifndef liblldb_SingleStepCheck_H_
#define liblldb_SingleStepCheck_H_
-namespace lldb_private
-{
-namespace process_linux
-{
+namespace lldb_private {
+namespace process_linux {
-namespace impl
-{
-extern bool
-SingleStepWorkaroundNeeded();
+namespace impl {
+extern bool SingleStepWorkaroundNeeded();
}
-// arm64 linux had a bug which prevented single-stepping and watchpoints from working on non-boot
-// cpus, due to them being incorrectly initialized after coming out of suspend. This issue is
-// particularly affecting android M, which uses suspend ("doze mode") quite aggressively. This
-// code detects that situation and makes single-stepping work by doing all the step operations on
+// arm64 linux had a bug which prevented single-stepping and watchpoints from
+// working on non-boot
+// cpus, due to them being incorrectly initialized after coming out of suspend.
+// This issue is
+// particularly affecting android M, which uses suspend ("doze mode") quite
+// aggressively. This
+// code detects that situation and makes single-stepping work by doing all the
+// step operations on
// the boot cpu.
//
-// The underlying issue has been fixed in android N and linux 4.4. This code can be removed once
+// The underlying issue has been fixed in android N and linux 4.4. This code can
+// be removed once
// these systems become obsolete.
-inline bool
-SingleStepWorkaroundNeeded()
-{
- static bool value = impl::SingleStepWorkaroundNeeded();
- return value;
+inline bool SingleStepWorkaroundNeeded() {
+ static bool value = impl::SingleStepWorkaroundNeeded();
+ return value;
}
} // end namespace process_linux
} // end namespace lldb_private
diff --git a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
index 29a0d58f7080..43e4617feafc 100644
--- a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-
#include "CommunicationKDP.h"
// C Includes
@@ -25,7 +24,6 @@
#include "lldb/Core/UUID.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/Host.h"
-#include "lldb/Host/TimeValue.h"
#include "lldb/Target/Process.h"
// Project includes
@@ -38,39 +36,26 @@ using namespace lldb_private;
// CommunicationKDP constructor
//----------------------------------------------------------------------
CommunicationKDP::CommunicationKDP(const char *comm_name)
- : Communication(comm_name),
- m_addr_byte_size(4),
- m_byte_order(eByteOrderLittle),
- m_packet_timeout(5),
- m_sequence_mutex(),
- m_is_running(false),
- m_session_key(0u),
- m_request_sequence_id(0u),
- m_exception_sequence_id(0u),
- m_kdp_version_version(0u),
- m_kdp_version_feature(0u),
- m_kdp_hostinfo_cpu_mask(0u),
- m_kdp_hostinfo_cpu_type(0u),
- m_kdp_hostinfo_cpu_subtype(0u)
-{
-}
+ : Communication(comm_name), m_addr_byte_size(4),
+ m_byte_order(eByteOrderLittle), m_packet_timeout(5), m_sequence_mutex(),
+ m_is_running(false), m_session_key(0u), m_request_sequence_id(0u),
+ m_exception_sequence_id(0u), m_kdp_version_version(0u),
+ m_kdp_version_feature(0u), m_kdp_hostinfo_cpu_mask(0u),
+ m_kdp_hostinfo_cpu_type(0u), m_kdp_hostinfo_cpu_subtype(0u) {}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-CommunicationKDP::~CommunicationKDP()
-{
- if (IsConnected())
- {
- Disconnect();
- }
+CommunicationKDP::~CommunicationKDP() {
+ if (IsConnected()) {
+ Disconnect();
+ }
}
-bool
-CommunicationKDP::SendRequestPacket (const PacketStreamType &request_packet)
-{
- std::lock_guard<std::recursive_mutex> guard(m_sequence_mutex);
- return SendRequestPacketNoLock (request_packet);
+bool CommunicationKDP::SendRequestPacket(
+ const PacketStreamType &request_packet) {
+ std::lock_guard<std::recursive_mutex> guard(m_sequence_mutex);
+ return SendRequestPacketNoLock(request_packet);
}
#if 0
@@ -82,409 +67,374 @@ typedef struct {
} kdp_hdr_t;
#endif
-void
-CommunicationKDP::MakeRequestPacketHeader (CommandType request_type,
- PacketStreamType &request_packet,
- uint16_t request_length)
-{
- request_packet.Clear();
- request_packet.PutHex8 (request_type | ePacketTypeRequest); // Set the request type
- request_packet.PutHex8 (m_request_sequence_id++); // Sequence number
- request_packet.PutHex16 (request_length); // Length of the packet including this header
- request_packet.PutHex32 (m_session_key); // Session key
+void CommunicationKDP::MakeRequestPacketHeader(CommandType request_type,
+ PacketStreamType &request_packet,
+ uint16_t request_length) {
+ request_packet.Clear();
+ request_packet.PutHex8(request_type |
+ ePacketTypeRequest); // Set the request type
+ request_packet.PutHex8(m_request_sequence_id++); // Sequence number
+ request_packet.PutHex16(
+ request_length); // Length of the packet including this header
+ request_packet.PutHex32(m_session_key); // Session key
}
-bool
-CommunicationKDP::SendRequestAndGetReply (const CommandType command,
- const PacketStreamType &request_packet,
- DataExtractor &reply_packet)
-{
- if (IsRunning())
- {
- Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
- if (log)
- {
- PacketStreamType log_strm;
- DumpPacket (log_strm, request_packet.GetData(), request_packet.GetSize());
- log->Printf("error: kdp running, not sending packet: %.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData());
- }
- return false;
+bool CommunicationKDP::SendRequestAndGetReply(
+ const CommandType command, const PacketStreamType &request_packet,
+ DataExtractor &reply_packet) {
+ if (IsRunning()) {
+ Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PACKETS));
+ if (log) {
+ PacketStreamType log_strm;
+ DumpPacket(log_strm, request_packet.GetData(), request_packet.GetSize());
+ log->Printf("error: kdp running, not sending packet: %.*s",
+ (uint32_t)log_strm.GetSize(), log_strm.GetData());
}
+ return false;
+ }
- std::lock_guard<std::recursive_mutex> guard(m_sequence_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_sequence_mutex);
#ifdef LLDB_CONFIGURATION_DEBUG
- // NOTE: this only works for packets that are in native endian byte order
- assert (request_packet.GetSize() == *((uint16_t *)(request_packet.GetData() + 2)));
+ // NOTE: this only works for packets that are in native endian byte order
+ assert(request_packet.GetSize() ==
+ *((uint16_t *)(request_packet.GetData() + 2)));
#endif
- lldb::offset_t offset = 1;
- const uint32_t num_retries = 3;
- for (uint32_t i=0; i<num_retries; ++i)
- {
- if (SendRequestPacketNoLock(request_packet))
- {
- const uint8_t request_sequence_id = (uint8_t)request_packet.GetData()[1];
- while (1)
- {
- if (WaitForPacketWithTimeoutMicroSecondsNoLock (reply_packet, GetPacketTimeoutInMicroSeconds ()))
- {
- offset = 0;
- const uint8_t reply_command = reply_packet.GetU8 (&offset);
- const uint8_t reply_sequence_id = reply_packet.GetU8 (&offset);
- if (request_sequence_id == reply_sequence_id)
- {
- // The sequent ID was correct, now verify we got the response we were looking for
- if ((reply_command & eCommandTypeMask) == command)
- {
- // Success
- if (command == KDP_RESUMECPUS)
- m_is_running.SetValue(true, eBroadcastAlways);
- return true;
- }
- else
- {
- // Failed to get the correct response, bail
- reply_packet.Clear();
- return false;
- }
- }
- else if (reply_sequence_id > request_sequence_id)
- {
- // Sequence ID was greater than the sequence ID of the packet we sent, something
- // is really wrong...
- reply_packet.Clear();
- return false;
- }
- else
- {
- // The reply sequence ID was less than our current packet's sequence ID
- // so we should keep trying to get a response because this was a response
- // for a previous packet that we must have retried.
- }
- }
- else
- {
- // Break and retry sending the packet as we didn't get a response due to timeout
- break;
- }
+ lldb::offset_t offset = 1;
+ const uint32_t num_retries = 3;
+ for (uint32_t i = 0; i < num_retries; ++i) {
+ if (SendRequestPacketNoLock(request_packet)) {
+ const uint8_t request_sequence_id = (uint8_t)request_packet.GetData()[1];
+ while (1) {
+ if (WaitForPacketWithTimeoutMicroSecondsNoLock(
+ reply_packet,
+ std::chrono::microseconds(GetPacketTimeout()).count())) {
+ offset = 0;
+ const uint8_t reply_command = reply_packet.GetU8(&offset);
+ const uint8_t reply_sequence_id = reply_packet.GetU8(&offset);
+ if (request_sequence_id == reply_sequence_id) {
+ // The sequent ID was correct, now verify we got the response we
+ // were looking for
+ if ((reply_command & eCommandTypeMask) == command) {
+ // Success
+ if (command == KDP_RESUMECPUS)
+ m_is_running.SetValue(true, eBroadcastAlways);
+ return true;
+ } else {
+ // Failed to get the correct response, bail
+ reply_packet.Clear();
+ return false;
}
+ } else if (reply_sequence_id > request_sequence_id) {
+ // Sequence ID was greater than the sequence ID of the packet we
+ // sent, something
+ // is really wrong...
+ reply_packet.Clear();
+ return false;
+ } else {
+ // The reply sequence ID was less than our current packet's sequence
+ // ID
+ // so we should keep trying to get a response because this was a
+ // response
+ // for a previous packet that we must have retried.
+ }
+ } else {
+ // Break and retry sending the packet as we didn't get a response due
+ // to timeout
+ break;
}
+ }
}
- reply_packet.Clear();
- return false;
+ }
+ reply_packet.Clear();
+ return false;
}
-bool
-CommunicationKDP::SendRequestPacketNoLock (const PacketStreamType &request_packet)
-{
- if (IsConnected())
- {
- const char *packet_data = request_packet.GetData();
- const size_t packet_size = request_packet.GetSize();
-
- Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
- if (log)
- {
- PacketStreamType log_strm;
- DumpPacket (log_strm, packet_data, packet_size);
- log->Printf("%.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData());
- }
- ConnectionStatus status = eConnectionStatusSuccess;
-
- size_t bytes_written = Write (packet_data,
- packet_size,
- status,
- NULL);
-
- if (bytes_written == packet_size)
- return true;
-
- if (log)
- log->Printf ("error: failed to send packet entire packet %" PRIu64 " of %" PRIu64 " bytes sent", (uint64_t)bytes_written, (uint64_t)packet_size);
+bool CommunicationKDP::SendRequestPacketNoLock(
+ const PacketStreamType &request_packet) {
+ if (IsConnected()) {
+ const char *packet_data = request_packet.GetData();
+ const size_t packet_size = request_packet.GetSize();
+
+ Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PACKETS));
+ if (log) {
+ PacketStreamType log_strm;
+ DumpPacket(log_strm, packet_data, packet_size);
+ log->Printf("%.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData());
}
- return false;
-}
+ ConnectionStatus status = eConnectionStatusSuccess;
-bool
-CommunicationKDP::GetSequenceMutex(std::unique_lock<std::recursive_mutex> &lock)
-{
- return (lock = std::unique_lock<std::recursive_mutex>(m_sequence_mutex, std::try_to_lock)).owns_lock();
-}
+ size_t bytes_written = Write(packet_data, packet_size, status, NULL);
+ if (bytes_written == packet_size)
+ return true;
-bool
-CommunicationKDP::WaitForNotRunningPrivate (const TimeValue *timeout_ptr)
-{
- return m_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
+ if (log)
+ log->Printf("error: failed to send packet entire packet %" PRIu64
+ " of %" PRIu64 " bytes sent",
+ (uint64_t)bytes_written, (uint64_t)packet_size);
+ }
+ return false;
}
-size_t
-CommunicationKDP::WaitForPacketWithTimeoutMicroSeconds (DataExtractor &packet, uint32_t timeout_usec)
-{
- std::lock_guard<std::recursive_mutex> guard(m_sequence_mutex);
- return WaitForPacketWithTimeoutMicroSecondsNoLock (packet, timeout_usec);
+bool CommunicationKDP::GetSequenceMutex(
+ std::unique_lock<std::recursive_mutex> &lock) {
+ return (lock = std::unique_lock<std::recursive_mutex>(m_sequence_mutex,
+ std::try_to_lock))
+ .owns_lock();
}
-size_t
-CommunicationKDP::WaitForPacketWithTimeoutMicroSecondsNoLock (DataExtractor &packet, uint32_t timeout_usec)
-{
- uint8_t buffer[8192];
- Error error;
+bool CommunicationKDP::WaitForNotRunningPrivate(
+ const std::chrono::microseconds &timeout) {
+ return m_is_running.WaitForValueEqualTo(false, timeout, NULL);
+}
- Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS | KDP_LOG_VERBOSE));
+size_t
+CommunicationKDP::WaitForPacketWithTimeoutMicroSeconds(DataExtractor &packet,
+ uint32_t timeout_usec) {
+ std::lock_guard<std::recursive_mutex> guard(m_sequence_mutex);
+ return WaitForPacketWithTimeoutMicroSecondsNoLock(packet, timeout_usec);
+}
- // Check for a packet from our cache first without trying any reading...
- if (CheckForPacket (NULL, 0, packet))
+size_t CommunicationKDP::WaitForPacketWithTimeoutMicroSecondsNoLock(
+ DataExtractor &packet, uint32_t timeout_usec) {
+ uint8_t buffer[8192];
+ Error error;
+
+ Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PACKETS |
+ KDP_LOG_VERBOSE));
+
+ // Check for a packet from our cache first without trying any reading...
+ if (CheckForPacket(NULL, 0, packet))
+ return packet.GetByteSize();
+
+ bool timed_out = false;
+ while (IsConnected() && !timed_out) {
+ lldb::ConnectionStatus status = eConnectionStatusNoConnection;
+ size_t bytes_read = Read(buffer, sizeof(buffer),
+ timeout_usec == UINT32_MAX
+ ? Timeout<std::micro>(llvm::None)
+ : std::chrono::microseconds(timeout_usec),
+ status, &error);
+
+ if (log)
+ log->Printf("%s: Read (buffer, (sizeof(buffer), timeout_usec = 0x%x, "
+ "status = %s, error = %s) => bytes_read = %" PRIu64,
+ LLVM_PRETTY_FUNCTION, timeout_usec,
+ Communication::ConnectionStatusAsCString(status),
+ error.AsCString(), (uint64_t)bytes_read);
+
+ if (bytes_read > 0) {
+ if (CheckForPacket(buffer, bytes_read, packet))
return packet.GetByteSize();
-
- bool timed_out = false;
- while (IsConnected() && !timed_out)
- {
- lldb::ConnectionStatus status = eConnectionStatusNoConnection;
- size_t bytes_read = Read (buffer, sizeof(buffer), timeout_usec, status, &error);
-
- if (log)
- log->Printf ("%s: Read (buffer, (sizeof(buffer), timeout_usec = 0x%x, status = %s, error = %s) => bytes_read = %" PRIu64,
- __PRETTY_FUNCTION__,
- timeout_usec,
- Communication::ConnectionStatusAsCString (status),
- error.AsCString(),
- (uint64_t)bytes_read);
-
- if (bytes_read > 0)
- {
- if (CheckForPacket (buffer, bytes_read, packet))
- return packet.GetByteSize();
- }
- else
- {
- switch (status)
- {
- case eConnectionStatusInterrupted:
- case eConnectionStatusTimedOut:
- timed_out = true;
- break;
- case eConnectionStatusSuccess:
- //printf ("status = success but error = %s\n", error.AsCString("<invalid>"));
- break;
-
- case eConnectionStatusEndOfFile:
- case eConnectionStatusNoConnection:
- case eConnectionStatusLostConnection:
- case eConnectionStatusError:
- Disconnect();
- break;
- }
- }
+ } else {
+ switch (status) {
+ case eConnectionStatusInterrupted:
+ case eConnectionStatusTimedOut:
+ timed_out = true;
+ break;
+ case eConnectionStatusSuccess:
+ // printf ("status = success but error = %s\n",
+ // error.AsCString("<invalid>"));
+ break;
+
+ case eConnectionStatusEndOfFile:
+ case eConnectionStatusNoConnection:
+ case eConnectionStatusLostConnection:
+ case eConnectionStatusError:
+ Disconnect();
+ break;
+ }
}
- packet.Clear ();
- return 0;
+ }
+ packet.Clear();
+ return 0;
}
-bool
-CommunicationKDP::CheckForPacket (const uint8_t *src, size_t src_len, DataExtractor &packet)
-{
- // Put the packet data into the buffer in a thread safe fashion
- std::lock_guard<std::recursive_mutex> guard(m_bytes_mutex);
+bool CommunicationKDP::CheckForPacket(const uint8_t *src, size_t src_len,
+ DataExtractor &packet) {
+ // Put the packet data into the buffer in a thread safe fashion
+ std::lock_guard<std::recursive_mutex> guard(m_bytes_mutex);
- Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
+ Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PACKETS));
- if (src && src_len > 0)
- {
- if (log && log->GetVerbose())
- {
- PacketStreamType log_strm;
- DataExtractor::DumpHexBytes (&log_strm, src, src_len, UINT32_MAX, LLDB_INVALID_ADDRESS);
- log->Printf ("CommunicationKDP::%s adding %u bytes: %s",
- __FUNCTION__,
- (uint32_t)src_len,
- log_strm.GetData());
- }
- m_bytes.append ((const char *)src, src_len);
+ if (src && src_len > 0) {
+ if (log && log->GetVerbose()) {
+ PacketStreamType log_strm;
+ DataExtractor::DumpHexBytes(&log_strm, src, src_len, UINT32_MAX,
+ LLDB_INVALID_ADDRESS);
+ log->Printf("CommunicationKDP::%s adding %u bytes: %s", __FUNCTION__,
+ (uint32_t)src_len, log_strm.GetData());
}
-
- // Make sure we at least have enough bytes for a packet header
- const size_t bytes_available = m_bytes.size();
- if (bytes_available >= 8)
- {
- packet.SetData (&m_bytes[0], bytes_available, m_byte_order);
- lldb::offset_t offset = 0;
- uint8_t reply_command = packet.GetU8(&offset);
- switch (reply_command)
- {
- case ePacketTypeRequest | KDP_EXCEPTION:
- case ePacketTypeRequest | KDP_TERMINATION:
- // We got an exception request, so be sure to send an ACK
- {
- PacketStreamType request_ack_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
- // Set the reply but and make the ACK packet
- request_ack_packet.PutHex8 (reply_command | ePacketTypeReply);
- request_ack_packet.PutHex8 (packet.GetU8(&offset));
- request_ack_packet.PutHex16 (packet.GetU16(&offset));
- request_ack_packet.PutHex32 (packet.GetU32(&offset));
- m_is_running.SetValue(false, eBroadcastAlways);
- // Ack to the exception or termination
- SendRequestPacketNoLock (request_ack_packet);
- }
- // Fall through to case below to get packet contents
- LLVM_FALLTHROUGH;
- case ePacketTypeReply | KDP_CONNECT:
- case ePacketTypeReply | KDP_DISCONNECT:
- case ePacketTypeReply | KDP_HOSTINFO:
- case ePacketTypeReply | KDP_VERSION:
- case ePacketTypeReply | KDP_MAXBYTES:
- case ePacketTypeReply | KDP_READMEM:
- case ePacketTypeReply | KDP_WRITEMEM:
- case ePacketTypeReply | KDP_READREGS:
- case ePacketTypeReply | KDP_WRITEREGS:
- case ePacketTypeReply | KDP_LOAD:
- case ePacketTypeReply | KDP_IMAGEPATH:
- case ePacketTypeReply | KDP_SUSPEND:
- case ePacketTypeReply | KDP_RESUMECPUS:
- case ePacketTypeReply | KDP_BREAKPOINT_SET:
- case ePacketTypeReply | KDP_BREAKPOINT_REMOVE:
- case ePacketTypeReply | KDP_REGIONS:
- case ePacketTypeReply | KDP_REATTACH:
- case ePacketTypeReply | KDP_HOSTREBOOT:
- case ePacketTypeReply | KDP_READMEM64:
- case ePacketTypeReply | KDP_WRITEMEM64:
- case ePacketTypeReply | KDP_BREAKPOINT_SET64:
- case ePacketTypeReply | KDP_BREAKPOINT_REMOVE64:
- case ePacketTypeReply | KDP_KERNELVERSION:
- case ePacketTypeReply | KDP_READPHYSMEM64:
- case ePacketTypeReply | KDP_WRITEPHYSMEM64:
- case ePacketTypeReply | KDP_READIOPORT:
- case ePacketTypeReply | KDP_WRITEIOPORT:
- case ePacketTypeReply | KDP_READMSR64:
- case ePacketTypeReply | KDP_WRITEMSR64:
- case ePacketTypeReply | KDP_DUMPINFO:
- {
- offset = 2;
- const uint16_t length = packet.GetU16 (&offset);
- if (length <= bytes_available)
- {
- // We have an entire packet ready, we need to copy the data
- // bytes into a buffer that will be owned by the packet and
- // erase the bytes from our communcation buffer "m_bytes"
- packet.SetData (DataBufferSP (new DataBufferHeap (&m_bytes[0], length)));
- m_bytes.erase (0, length);
-
- if (log)
- {
- PacketStreamType log_strm;
- DumpPacket (log_strm, packet);
-
- log->Printf("%.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData());
- }
- return true;
- }
- }
- break;
-
- default:
- // Unrecognized reply command byte, erase this byte and try to get back on track
- if (log)
- log->Printf ("CommunicationKDP::%s: tossing junk byte: 0x%2.2x",
- __FUNCTION__,
- (uint8_t)m_bytes[0]);
- m_bytes.erase(0, 1);
- break;
+ m_bytes.append((const char *)src, src_len);
+ }
+
+ // Make sure we at least have enough bytes for a packet header
+ const size_t bytes_available = m_bytes.size();
+ if (bytes_available >= 8) {
+ packet.SetData(&m_bytes[0], bytes_available, m_byte_order);
+ lldb::offset_t offset = 0;
+ uint8_t reply_command = packet.GetU8(&offset);
+ switch (reply_command) {
+ case ePacketTypeRequest | KDP_EXCEPTION:
+ case ePacketTypeRequest | KDP_TERMINATION:
+ // We got an exception request, so be sure to send an ACK
+ {
+ PacketStreamType request_ack_packet(Stream::eBinary, m_addr_byte_size,
+ m_byte_order);
+ // Set the reply but and make the ACK packet
+ request_ack_packet.PutHex8(reply_command | ePacketTypeReply);
+ request_ack_packet.PutHex8(packet.GetU8(&offset));
+ request_ack_packet.PutHex16(packet.GetU16(&offset));
+ request_ack_packet.PutHex32(packet.GetU32(&offset));
+ m_is_running.SetValue(false, eBroadcastAlways);
+ // Ack to the exception or termination
+ SendRequestPacketNoLock(request_ack_packet);
+ }
+ // Fall through to case below to get packet contents
+ LLVM_FALLTHROUGH;
+ case ePacketTypeReply | KDP_CONNECT:
+ case ePacketTypeReply | KDP_DISCONNECT:
+ case ePacketTypeReply | KDP_HOSTINFO:
+ case ePacketTypeReply | KDP_VERSION:
+ case ePacketTypeReply | KDP_MAXBYTES:
+ case ePacketTypeReply | KDP_READMEM:
+ case ePacketTypeReply | KDP_WRITEMEM:
+ case ePacketTypeReply | KDP_READREGS:
+ case ePacketTypeReply | KDP_WRITEREGS:
+ case ePacketTypeReply | KDP_LOAD:
+ case ePacketTypeReply | KDP_IMAGEPATH:
+ case ePacketTypeReply | KDP_SUSPEND:
+ case ePacketTypeReply | KDP_RESUMECPUS:
+ case ePacketTypeReply | KDP_BREAKPOINT_SET:
+ case ePacketTypeReply | KDP_BREAKPOINT_REMOVE:
+ case ePacketTypeReply | KDP_REGIONS:
+ case ePacketTypeReply | KDP_REATTACH:
+ case ePacketTypeReply | KDP_HOSTREBOOT:
+ case ePacketTypeReply | KDP_READMEM64:
+ case ePacketTypeReply | KDP_WRITEMEM64:
+ case ePacketTypeReply | KDP_BREAKPOINT_SET64:
+ case ePacketTypeReply | KDP_BREAKPOINT_REMOVE64:
+ case ePacketTypeReply | KDP_KERNELVERSION:
+ case ePacketTypeReply | KDP_READPHYSMEM64:
+ case ePacketTypeReply | KDP_WRITEPHYSMEM64:
+ case ePacketTypeReply | KDP_READIOPORT:
+ case ePacketTypeReply | KDP_WRITEIOPORT:
+ case ePacketTypeReply | KDP_READMSR64:
+ case ePacketTypeReply | KDP_WRITEMSR64:
+ case ePacketTypeReply | KDP_DUMPINFO: {
+ offset = 2;
+ const uint16_t length = packet.GetU16(&offset);
+ if (length <= bytes_available) {
+ // We have an entire packet ready, we need to copy the data
+ // bytes into a buffer that will be owned by the packet and
+ // erase the bytes from our communcation buffer "m_bytes"
+ packet.SetData(DataBufferSP(new DataBufferHeap(&m_bytes[0], length)));
+ m_bytes.erase(0, length);
+
+ if (log) {
+ PacketStreamType log_strm;
+ DumpPacket(log_strm, packet);
+
+ log->Printf("%.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData());
}
+ return true;
+ }
+ } break;
+
+ default:
+ // Unrecognized reply command byte, erase this byte and try to get back on
+ // track
+ if (log)
+ log->Printf("CommunicationKDP::%s: tossing junk byte: 0x%2.2x",
+ __FUNCTION__, (uint8_t)m_bytes[0]);
+ m_bytes.erase(0, 1);
+ break;
}
- packet.Clear();
- return false;
+ }
+ packet.Clear();
+ return false;
}
-
-bool
-CommunicationKDP::SendRequestConnect (uint16_t reply_port,
- uint16_t exc_port,
- const char *greeting)
-{
- PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
- if (greeting == NULL)
- greeting = "";
-
- const CommandType command = KDP_CONNECT;
- // Length is 82 uint16_t and the length of the greeting C string with the terminating NULL
- const uint32_t command_length = 8 + 2 + 2 + ::strlen(greeting) + 1;
- MakeRequestPacketHeader (command, request_packet, command_length);
- // Always send connect ports as little endian
- request_packet.SetByteOrder (eByteOrderLittle);
- request_packet.PutHex16 (htons(reply_port));
- request_packet.PutHex16 (htons(exc_port));
- request_packet.SetByteOrder (m_byte_order);
- request_packet.PutCString (greeting);
- DataExtractor reply_packet;
- return SendRequestAndGetReply (command, request_packet, reply_packet);
+bool CommunicationKDP::SendRequestConnect(uint16_t reply_port,
+ uint16_t exc_port,
+ const char *greeting) {
+ PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
+ m_byte_order);
+ if (greeting == NULL)
+ greeting = "";
+
+ const CommandType command = KDP_CONNECT;
+ // Length is 82 uint16_t and the length of the greeting C string with the
+ // terminating NULL
+ const uint32_t command_length = 8 + 2 + 2 + ::strlen(greeting) + 1;
+ MakeRequestPacketHeader(command, request_packet, command_length);
+ // Always send connect ports as little endian
+ request_packet.SetByteOrder(eByteOrderLittle);
+ request_packet.PutHex16(htons(reply_port));
+ request_packet.PutHex16(htons(exc_port));
+ request_packet.SetByteOrder(m_byte_order);
+ request_packet.PutCString(greeting);
+ DataExtractor reply_packet;
+ return SendRequestAndGetReply(command, request_packet, reply_packet);
}
-void
-CommunicationKDP::ClearKDPSettings ()
-{
- m_request_sequence_id = 0;
- m_kdp_version_version = 0;
- m_kdp_version_feature = 0;
- m_kdp_hostinfo_cpu_mask = 0;
- m_kdp_hostinfo_cpu_type = 0;
- m_kdp_hostinfo_cpu_subtype = 0;
+void CommunicationKDP::ClearKDPSettings() {
+ m_request_sequence_id = 0;
+ m_kdp_version_version = 0;
+ m_kdp_version_feature = 0;
+ m_kdp_hostinfo_cpu_mask = 0;
+ m_kdp_hostinfo_cpu_type = 0;
+ m_kdp_hostinfo_cpu_subtype = 0;
}
-bool
-CommunicationKDP::SendRequestReattach (uint16_t reply_port)
-{
- PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
- const CommandType command = KDP_REATTACH;
- // Length is 8 bytes for the header plus 2 bytes for the reply UDP port
- const uint32_t command_length = 8 + 2;
- MakeRequestPacketHeader (command, request_packet, command_length);
- // Always send connect ports as little endian
- request_packet.SetByteOrder (eByteOrderLittle);
- request_packet.PutHex16(htons(reply_port));
- request_packet.SetByteOrder (m_byte_order);
- DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_packet, reply_packet))
- {
- // Reset the sequence ID to zero for reattach
- ClearKDPSettings ();
- lldb::offset_t offset = 4;
- m_session_key = reply_packet.GetU32 (&offset);
- return true;
- }
- return false;
+bool CommunicationKDP::SendRequestReattach(uint16_t reply_port) {
+ PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
+ m_byte_order);
+ const CommandType command = KDP_REATTACH;
+ // Length is 8 bytes for the header plus 2 bytes for the reply UDP port
+ const uint32_t command_length = 8 + 2;
+ MakeRequestPacketHeader(command, request_packet, command_length);
+ // Always send connect ports as little endian
+ request_packet.SetByteOrder(eByteOrderLittle);
+ request_packet.PutHex16(htons(reply_port));
+ request_packet.SetByteOrder(m_byte_order);
+ DataExtractor reply_packet;
+ if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
+ // Reset the sequence ID to zero for reattach
+ ClearKDPSettings();
+ lldb::offset_t offset = 4;
+ m_session_key = reply_packet.GetU32(&offset);
+ return true;
+ }
+ return false;
}
-uint32_t
-CommunicationKDP::GetVersion ()
-{
- if (!VersionIsValid())
- SendRequestVersion();
- return m_kdp_version_version;
+uint32_t CommunicationKDP::GetVersion() {
+ if (!VersionIsValid())
+ SendRequestVersion();
+ return m_kdp_version_version;
}
-uint32_t
-CommunicationKDP::GetFeatureFlags ()
-{
- if (!VersionIsValid())
- SendRequestVersion();
- return m_kdp_version_feature;
+uint32_t CommunicationKDP::GetFeatureFlags() {
+ if (!VersionIsValid())
+ SendRequestVersion();
+ return m_kdp_version_feature;
}
-bool
-CommunicationKDP::SendRequestVersion ()
-{
- PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
- const CommandType command = KDP_VERSION;
- const uint32_t command_length = 8;
- MakeRequestPacketHeader (command, request_packet, command_length);
- DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_packet, reply_packet))
- {
- lldb::offset_t offset = 8;
- m_kdp_version_version = reply_packet.GetU32 (&offset);
- m_kdp_version_feature = reply_packet.GetU32 (&offset);
- return true;
- }
- return false;
+bool CommunicationKDP::SendRequestVersion() {
+ PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
+ m_byte_order);
+ const CommandType command = KDP_VERSION;
+ const uint32_t command_length = 8;
+ MakeRequestPacketHeader(command, request_packet, command_length);
+ DataExtractor reply_packet;
+ if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
+ lldb::offset_t offset = 8;
+ m_kdp_version_version = reply_packet.GetU32(&offset);
+ m_kdp_version_feature = reply_packet.GetU32(&offset);
+ return true;
+ }
+ return false;
}
#if 0 // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
@@ -515,932 +465,863 @@ CommunicationKDP::SendRequestImagePath ()
}
#endif
-uint32_t
-CommunicationKDP::GetCPUMask ()
-{
- if (!HostInfoIsValid())
- SendRequestHostInfo();
- return m_kdp_hostinfo_cpu_mask;
+uint32_t CommunicationKDP::GetCPUMask() {
+ if (!HostInfoIsValid())
+ SendRequestHostInfo();
+ return m_kdp_hostinfo_cpu_mask;
}
-uint32_t
-CommunicationKDP::GetCPUType ()
-{
- if (!HostInfoIsValid())
- SendRequestHostInfo();
- return m_kdp_hostinfo_cpu_type;
+uint32_t CommunicationKDP::GetCPUType() {
+ if (!HostInfoIsValid())
+ SendRequestHostInfo();
+ return m_kdp_hostinfo_cpu_type;
}
-uint32_t
-CommunicationKDP::GetCPUSubtype ()
-{
- if (!HostInfoIsValid())
- SendRequestHostInfo();
- return m_kdp_hostinfo_cpu_subtype;
+uint32_t CommunicationKDP::GetCPUSubtype() {
+ if (!HostInfoIsValid())
+ SendRequestHostInfo();
+ return m_kdp_hostinfo_cpu_subtype;
}
-lldb_private::UUID
-CommunicationKDP::GetUUID ()
-{
- UUID uuid;
- if (GetKernelVersion() == NULL)
- return uuid;
-
- if (m_kernel_version.find("UUID=") == std::string::npos)
- return uuid;
-
- size_t p = m_kernel_version.find("UUID=") + strlen ("UUID=");
- std::string uuid_str = m_kernel_version.substr(p, 36);
- if (uuid_str.size() < 32)
- return uuid;
+lldb_private::UUID CommunicationKDP::GetUUID() {
+ UUID uuid;
+ if (GetKernelVersion() == NULL)
+ return uuid;
- if (uuid.SetFromCString (uuid_str.c_str()) == 0)
- {
- UUID invalid_uuid;
- return invalid_uuid;
- }
+ if (m_kernel_version.find("UUID=") == std::string::npos)
+ return uuid;
+ size_t p = m_kernel_version.find("UUID=") + strlen("UUID=");
+ std::string uuid_str = m_kernel_version.substr(p, 36);
+ if (uuid_str.size() < 32)
return uuid;
-}
-bool
-CommunicationKDP::RemoteIsEFI ()
-{
- if (GetKernelVersion() == NULL)
- return false;
- if (strncmp (m_kernel_version.c_str(), "EFI", 3) == 0)
- return true;
- else
- return false;
-}
+ if (uuid.SetFromCString(uuid_str.c_str()) == 0) {
+ UUID invalid_uuid;
+ return invalid_uuid;
+ }
-bool
-CommunicationKDP::RemoteIsDarwinKernel ()
-{
- if (GetKernelVersion() == NULL)
- return false;
- if (m_kernel_version.find("Darwin Kernel") != std::string::npos)
- return true;
- else
- return false;
+ return uuid;
}
-lldb::addr_t
-CommunicationKDP::GetLoadAddress ()
-{
- if (GetKernelVersion() == NULL)
- return LLDB_INVALID_ADDRESS;
-
- if (m_kernel_version.find("stext=") == std::string::npos)
- return LLDB_INVALID_ADDRESS;
- size_t p = m_kernel_version.find("stext=") + strlen ("stext=");
- if (m_kernel_version[p] != '0' || m_kernel_version[p + 1] != 'x')
- return LLDB_INVALID_ADDRESS;
-
- addr_t kernel_load_address;
- errno = 0;
- kernel_load_address = ::strtoul (m_kernel_version.c_str() + p, NULL, 16);
- if (errno != 0 || kernel_load_address == 0)
- return LLDB_INVALID_ADDRESS;
-
- return kernel_load_address;
+bool CommunicationKDP::RemoteIsEFI() {
+ if (GetKernelVersion() == NULL)
+ return false;
+ if (strncmp(m_kernel_version.c_str(), "EFI", 3) == 0)
+ return true;
+ else
+ return false;
}
-bool
-CommunicationKDP::SendRequestHostInfo ()
-{
- PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
- const CommandType command = KDP_HOSTINFO;
- const uint32_t command_length = 8;
- MakeRequestPacketHeader (command, request_packet, command_length);
- DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_packet, reply_packet))
- {
- lldb::offset_t offset = 8;
- m_kdp_hostinfo_cpu_mask = reply_packet.GetU32 (&offset);
- m_kdp_hostinfo_cpu_type = reply_packet.GetU32 (&offset);
- m_kdp_hostinfo_cpu_subtype = reply_packet.GetU32 (&offset);
-
- ArchSpec kernel_arch;
- kernel_arch.SetArchitecture (eArchTypeMachO,
- m_kdp_hostinfo_cpu_type,
- m_kdp_hostinfo_cpu_subtype);
-
- m_addr_byte_size = kernel_arch.GetAddressByteSize();
- m_byte_order = kernel_arch.GetByteOrder();
- return true;
- }
+bool CommunicationKDP::RemoteIsDarwinKernel() {
+ if (GetKernelVersion() == NULL)
+ return false;
+ if (m_kernel_version.find("Darwin Kernel") != std::string::npos)
+ return true;
+ else
return false;
}
-const char *
-CommunicationKDP::GetKernelVersion ()
-{
- if (m_kernel_version.empty())
- SendRequestKernelVersion ();
- return m_kernel_version.c_str();
-}
+lldb::addr_t CommunicationKDP::GetLoadAddress() {
+ if (GetKernelVersion() == NULL)
+ return LLDB_INVALID_ADDRESS;
-bool
-CommunicationKDP::SendRequestKernelVersion ()
-{
- PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
- const CommandType command = KDP_KERNELVERSION;
- const uint32_t command_length = 8;
- MakeRequestPacketHeader (command, request_packet, command_length);
- DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_packet, reply_packet))
- {
- const char *kernel_version_cstr = reply_packet.PeekCStr(8);
- if (kernel_version_cstr && kernel_version_cstr[0])
- m_kernel_version.assign (kernel_version_cstr);
- return true;
- }
- return false;
+ if (m_kernel_version.find("stext=") == std::string::npos)
+ return LLDB_INVALID_ADDRESS;
+ size_t p = m_kernel_version.find("stext=") + strlen("stext=");
+ if (m_kernel_version[p] != '0' || m_kernel_version[p + 1] != 'x')
+ return LLDB_INVALID_ADDRESS;
+
+ addr_t kernel_load_address;
+ errno = 0;
+ kernel_load_address = ::strtoul(m_kernel_version.c_str() + p, NULL, 16);
+ if (errno != 0 || kernel_load_address == 0)
+ return LLDB_INVALID_ADDRESS;
+
+ return kernel_load_address;
}
-bool
-CommunicationKDP::SendRequestDisconnect ()
-{
- PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
- const CommandType command = KDP_DISCONNECT;
- const uint32_t command_length = 8;
- MakeRequestPacketHeader (command, request_packet, command_length);
- DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_packet, reply_packet))
- {
- // Are we supposed to get a reply for disconnect?
- }
- ClearKDPSettings ();
+bool CommunicationKDP::SendRequestHostInfo() {
+ PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
+ m_byte_order);
+ const CommandType command = KDP_HOSTINFO;
+ const uint32_t command_length = 8;
+ MakeRequestPacketHeader(command, request_packet, command_length);
+ DataExtractor reply_packet;
+ if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
+ lldb::offset_t offset = 8;
+ m_kdp_hostinfo_cpu_mask = reply_packet.GetU32(&offset);
+ m_kdp_hostinfo_cpu_type = reply_packet.GetU32(&offset);
+ m_kdp_hostinfo_cpu_subtype = reply_packet.GetU32(&offset);
+
+ ArchSpec kernel_arch;
+ kernel_arch.SetArchitecture(eArchTypeMachO, m_kdp_hostinfo_cpu_type,
+ m_kdp_hostinfo_cpu_subtype);
+
+ m_addr_byte_size = kernel_arch.GetAddressByteSize();
+ m_byte_order = kernel_arch.GetByteOrder();
return true;
+ }
+ return false;
}
-uint32_t
-CommunicationKDP::SendRequestReadMemory (lldb::addr_t addr,
- void *dst,
- uint32_t dst_len,
- Error &error)
-{
- PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
- bool use_64 = (GetVersion() >= 11);
- uint32_t command_addr_byte_size = use_64 ? 8 : 4;
- const CommandType command = use_64 ? KDP_READMEM64 : KDP_READMEM;
- // Size is header + address size + uint32_t length
- const uint32_t command_length = 8 + command_addr_byte_size + 4;
- MakeRequestPacketHeader (command, request_packet, command_length);
- request_packet.PutMaxHex64 (addr, command_addr_byte_size);
- request_packet.PutHex32 (dst_len);
- DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_packet, reply_packet))
- {
- lldb::offset_t offset = 8;
- uint32_t kdp_error = reply_packet.GetU32 (&offset);
- uint32_t src_len = reply_packet.GetByteSize() - 12;
-
- if (src_len > 0)
- {
- const void *src = reply_packet.GetData(&offset, src_len);
- if (src)
- {
- ::memcpy (dst, src, src_len);
- error.Clear();
- return src_len;
- }
- }
- if (kdp_error)
- error.SetErrorStringWithFormat ("kdp read memory failed (error %u)", kdp_error);
- else
- error.SetErrorString ("kdp read memory failed");
- }
- else
- {
- error.SetErrorString ("failed to send packet");
- }
- return 0;
+const char *CommunicationKDP::GetKernelVersion() {
+ if (m_kernel_version.empty())
+ SendRequestKernelVersion();
+ return m_kernel_version.c_str();
}
+bool CommunicationKDP::SendRequestKernelVersion() {
+ PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
+ m_byte_order);
+ const CommandType command = KDP_KERNELVERSION;
+ const uint32_t command_length = 8;
+ MakeRequestPacketHeader(command, request_packet, command_length);
+ DataExtractor reply_packet;
+ if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
+ const char *kernel_version_cstr = reply_packet.PeekCStr(8);
+ if (kernel_version_cstr && kernel_version_cstr[0])
+ m_kernel_version.assign(kernel_version_cstr);
+ return true;
+ }
+ return false;
+}
-uint32_t
-CommunicationKDP::SendRequestWriteMemory (lldb::addr_t addr,
- const void *src,
- uint32_t src_len,
- Error &error)
-{
- PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
- bool use_64 = (GetVersion() >= 11);
- uint32_t command_addr_byte_size = use_64 ? 8 : 4;
- const CommandType command = use_64 ? KDP_WRITEMEM64 : KDP_WRITEMEM;
- // Size is header + address size + uint32_t length
- const uint32_t command_length = 8 + command_addr_byte_size + 4 + src_len;
- MakeRequestPacketHeader (command, request_packet, command_length);
- request_packet.PutMaxHex64 (addr, command_addr_byte_size);
- request_packet.PutHex32 (src_len);
- request_packet.PutRawBytes(src, src_len);
+bool CommunicationKDP::SendRequestDisconnect() {
+ PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
+ m_byte_order);
+ const CommandType command = KDP_DISCONNECT;
+ const uint32_t command_length = 8;
+ MakeRequestPacketHeader(command, request_packet, command_length);
+ DataExtractor reply_packet;
+ if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
+ // Are we supposed to get a reply for disconnect?
+ }
+ ClearKDPSettings();
+ return true;
+}
- DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_packet, reply_packet))
- {
- lldb::offset_t offset = 8;
- uint32_t kdp_error = reply_packet.GetU32 (&offset);
- if (kdp_error)
- error.SetErrorStringWithFormat ("kdp write memory failed (error %u)", kdp_error);
- else
- {
- error.Clear();
- return src_len;
- }
+uint32_t CommunicationKDP::SendRequestReadMemory(lldb::addr_t addr, void *dst,
+ uint32_t dst_len,
+ Error &error) {
+ PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
+ m_byte_order);
+ bool use_64 = (GetVersion() >= 11);
+ uint32_t command_addr_byte_size = use_64 ? 8 : 4;
+ const CommandType command = use_64 ? KDP_READMEM64 : KDP_READMEM;
+ // Size is header + address size + uint32_t length
+ const uint32_t command_length = 8 + command_addr_byte_size + 4;
+ MakeRequestPacketHeader(command, request_packet, command_length);
+ request_packet.PutMaxHex64(addr, command_addr_byte_size);
+ request_packet.PutHex32(dst_len);
+ DataExtractor reply_packet;
+ if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
+ lldb::offset_t offset = 8;
+ uint32_t kdp_error = reply_packet.GetU32(&offset);
+ uint32_t src_len = reply_packet.GetByteSize() - 12;
+
+ if (src_len > 0) {
+ const void *src = reply_packet.GetData(&offset, src_len);
+ if (src) {
+ ::memcpy(dst, src, src_len);
+ error.Clear();
+ return src_len;
+ }
}
+ if (kdp_error)
+ error.SetErrorStringWithFormat("kdp read memory failed (error %u)",
+ kdp_error);
else
- {
- error.SetErrorString ("failed to send packet");
- }
- return 0;
+ error.SetErrorString("kdp read memory failed");
+ } else {
+ error.SetErrorString("failed to send packet");
+ }
+ return 0;
}
-bool
-CommunicationKDP::SendRawRequest (uint8_t command_byte,
- const void *src, // Raw packet payload bytes
- uint32_t src_len, // Raw packet payload length
- DataExtractor &reply_packet,
- Error &error)
-{
- PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
- // Size is header + address size + uint32_t length
- const uint32_t command_length = 8 + src_len;
- const CommandType command = (CommandType)command_byte;
- MakeRequestPacketHeader (command, request_packet, command_length);
- request_packet.PutRawBytes(src, src_len);
-
- if (SendRequestAndGetReply (command, request_packet, reply_packet))
- {
- lldb::offset_t offset = 8;
- uint32_t kdp_error = reply_packet.GetU32 (&offset);
- if (kdp_error && (command_byte != KDP_DUMPINFO))
- error.SetErrorStringWithFormat ("request packet 0x%8.8x failed (error %u)", command_byte, kdp_error);
- else
- {
- error.Clear();
- return true;
- }
+uint32_t CommunicationKDP::SendRequestWriteMemory(lldb::addr_t addr,
+ const void *src,
+ uint32_t src_len,
+ Error &error) {
+ PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
+ m_byte_order);
+ bool use_64 = (GetVersion() >= 11);
+ uint32_t command_addr_byte_size = use_64 ? 8 : 4;
+ const CommandType command = use_64 ? KDP_WRITEMEM64 : KDP_WRITEMEM;
+ // Size is header + address size + uint32_t length
+ const uint32_t command_length = 8 + command_addr_byte_size + 4 + src_len;
+ MakeRequestPacketHeader(command, request_packet, command_length);
+ request_packet.PutMaxHex64(addr, command_addr_byte_size);
+ request_packet.PutHex32(src_len);
+ request_packet.PutRawBytes(src, src_len);
+
+ DataExtractor reply_packet;
+ if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
+ lldb::offset_t offset = 8;
+ uint32_t kdp_error = reply_packet.GetU32(&offset);
+ if (kdp_error)
+ error.SetErrorStringWithFormat("kdp write memory failed (error %u)",
+ kdp_error);
+ else {
+ error.Clear();
+ return src_len;
}
- else
- {
- error.SetErrorString ("failed to send packet");
- }
- return false;
+ } else {
+ error.SetErrorString("failed to send packet");
+ }
+ return 0;
}
-
-const char *
-CommunicationKDP::GetCommandAsCString (uint8_t command)
-{
- switch (command)
- {
- case KDP_CONNECT: return "KDP_CONNECT";
- case KDP_DISCONNECT: return "KDP_DISCONNECT";
- case KDP_HOSTINFO: return "KDP_HOSTINFO";
- case KDP_VERSION: return "KDP_VERSION";
- case KDP_MAXBYTES: return "KDP_MAXBYTES";
- case KDP_READMEM: return "KDP_READMEM";
- case KDP_WRITEMEM: return "KDP_WRITEMEM";
- case KDP_READREGS: return "KDP_READREGS";
- case KDP_WRITEREGS: return "KDP_WRITEREGS";
- case KDP_LOAD: return "KDP_LOAD";
- case KDP_IMAGEPATH: return "KDP_IMAGEPATH";
- case KDP_SUSPEND: return "KDP_SUSPEND";
- case KDP_RESUMECPUS: return "KDP_RESUMECPUS";
- case KDP_EXCEPTION: return "KDP_EXCEPTION";
- case KDP_TERMINATION: return "KDP_TERMINATION";
- case KDP_BREAKPOINT_SET: return "KDP_BREAKPOINT_SET";
- case KDP_BREAKPOINT_REMOVE: return "KDP_BREAKPOINT_REMOVE";
- case KDP_REGIONS: return "KDP_REGIONS";
- case KDP_REATTACH: return "KDP_REATTACH";
- case KDP_HOSTREBOOT: return "KDP_HOSTREBOOT";
- case KDP_READMEM64: return "KDP_READMEM64";
- case KDP_WRITEMEM64: return "KDP_WRITEMEM64";
- case KDP_BREAKPOINT_SET64: return "KDP_BREAKPOINT64_SET";
- case KDP_BREAKPOINT_REMOVE64: return "KDP_BREAKPOINT64_REMOVE";
- case KDP_KERNELVERSION: return "KDP_KERNELVERSION";
- case KDP_READPHYSMEM64: return "KDP_READPHYSMEM64";
- case KDP_WRITEPHYSMEM64: return "KDP_WRITEPHYSMEM64";
- case KDP_READIOPORT: return "KDP_READIOPORT";
- case KDP_WRITEIOPORT: return "KDP_WRITEIOPORT";
- case KDP_READMSR64: return "KDP_READMSR64";
- case KDP_WRITEMSR64: return "KDP_WRITEMSR64";
- case KDP_DUMPINFO: return "KDP_DUMPINFO";
+bool CommunicationKDP::SendRawRequest(
+ uint8_t command_byte,
+ const void *src, // Raw packet payload bytes
+ uint32_t src_len, // Raw packet payload length
+ DataExtractor &reply_packet, Error &error) {
+ PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
+ m_byte_order);
+ // Size is header + address size + uint32_t length
+ const uint32_t command_length = 8 + src_len;
+ const CommandType command = (CommandType)command_byte;
+ MakeRequestPacketHeader(command, request_packet, command_length);
+ request_packet.PutRawBytes(src, src_len);
+
+ if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
+ lldb::offset_t offset = 8;
+ uint32_t kdp_error = reply_packet.GetU32(&offset);
+ if (kdp_error && (command_byte != KDP_DUMPINFO))
+ error.SetErrorStringWithFormat("request packet 0x%8.8x failed (error %u)",
+ command_byte, kdp_error);
+ else {
+ error.Clear();
+ return true;
}
- return NULL;
+ } else {
+ error.SetErrorString("failed to send packet");
+ }
+ return false;
}
-void
-CommunicationKDP::DumpPacket (Stream &s, const void *data, uint32_t data_len)
-{
- DataExtractor extractor (data, data_len, m_byte_order, m_addr_byte_size);
- DumpPacket (s, extractor);
+const char *CommunicationKDP::GetCommandAsCString(uint8_t command) {
+ switch (command) {
+ case KDP_CONNECT:
+ return "KDP_CONNECT";
+ case KDP_DISCONNECT:
+ return "KDP_DISCONNECT";
+ case KDP_HOSTINFO:
+ return "KDP_HOSTINFO";
+ case KDP_VERSION:
+ return "KDP_VERSION";
+ case KDP_MAXBYTES:
+ return "KDP_MAXBYTES";
+ case KDP_READMEM:
+ return "KDP_READMEM";
+ case KDP_WRITEMEM:
+ return "KDP_WRITEMEM";
+ case KDP_READREGS:
+ return "KDP_READREGS";
+ case KDP_WRITEREGS:
+ return "KDP_WRITEREGS";
+ case KDP_LOAD:
+ return "KDP_LOAD";
+ case KDP_IMAGEPATH:
+ return "KDP_IMAGEPATH";
+ case KDP_SUSPEND:
+ return "KDP_SUSPEND";
+ case KDP_RESUMECPUS:
+ return "KDP_RESUMECPUS";
+ case KDP_EXCEPTION:
+ return "KDP_EXCEPTION";
+ case KDP_TERMINATION:
+ return "KDP_TERMINATION";
+ case KDP_BREAKPOINT_SET:
+ return "KDP_BREAKPOINT_SET";
+ case KDP_BREAKPOINT_REMOVE:
+ return "KDP_BREAKPOINT_REMOVE";
+ case KDP_REGIONS:
+ return "KDP_REGIONS";
+ case KDP_REATTACH:
+ return "KDP_REATTACH";
+ case KDP_HOSTREBOOT:
+ return "KDP_HOSTREBOOT";
+ case KDP_READMEM64:
+ return "KDP_READMEM64";
+ case KDP_WRITEMEM64:
+ return "KDP_WRITEMEM64";
+ case KDP_BREAKPOINT_SET64:
+ return "KDP_BREAKPOINT64_SET";
+ case KDP_BREAKPOINT_REMOVE64:
+ return "KDP_BREAKPOINT64_REMOVE";
+ case KDP_KERNELVERSION:
+ return "KDP_KERNELVERSION";
+ case KDP_READPHYSMEM64:
+ return "KDP_READPHYSMEM64";
+ case KDP_WRITEPHYSMEM64:
+ return "KDP_WRITEPHYSMEM64";
+ case KDP_READIOPORT:
+ return "KDP_READIOPORT";
+ case KDP_WRITEIOPORT:
+ return "KDP_WRITEIOPORT";
+ case KDP_READMSR64:
+ return "KDP_READMSR64";
+ case KDP_WRITEMSR64:
+ return "KDP_WRITEMSR64";
+ case KDP_DUMPINFO:
+ return "KDP_DUMPINFO";
+ }
+ return NULL;
}
-void
-CommunicationKDP::DumpPacket (Stream &s, const DataExtractor& packet)
-{
- const char *error_desc = NULL;
- if (packet.GetByteSize() < 8)
- {
- error_desc = "error: invalid packet (too short): ";
- }
- else
- {
- lldb::offset_t offset = 0;
- const uint8_t first_packet_byte = packet.GetU8 (&offset);
- const uint8_t sequence_id = packet.GetU8 (&offset);
- const uint16_t length = packet.GetU16 (&offset);
- const uint32_t key = packet.GetU32 (&offset);
- const CommandType command = ExtractCommand (first_packet_byte);
- const char *command_name = GetCommandAsCString (command);
- if (command_name)
- {
- const bool is_reply = ExtractIsReply(first_packet_byte);
- s.Printf ("(running=%i) %s %24s: 0x%2.2x 0x%2.2x 0x%4.4x 0x%8.8x ",
- IsRunning(),
- is_reply ? "<--" : "-->",
- command_name,
- first_packet_byte,
- sequence_id,
- length,
- key);
-
- if (is_reply)
- {
- // Dump request reply packets
- switch (command)
- {
- // Commands that return a single 32 bit error
- case KDP_CONNECT:
- case KDP_WRITEMEM:
- case KDP_WRITEMEM64:
- case KDP_BREAKPOINT_SET:
- case KDP_BREAKPOINT_REMOVE:
- case KDP_BREAKPOINT_SET64:
- case KDP_BREAKPOINT_REMOVE64:
- case KDP_WRITEREGS:
- case KDP_LOAD:
- case KDP_WRITEIOPORT:
- case KDP_WRITEMSR64:
- {
- const uint32_t error = packet.GetU32 (&offset);
- s.Printf(" (error=0x%8.8x)", error);
- }
- break;
-
- case KDP_DISCONNECT:
- case KDP_REATTACH:
- case KDP_HOSTREBOOT:
- case KDP_SUSPEND:
- case KDP_RESUMECPUS:
- case KDP_EXCEPTION:
- case KDP_TERMINATION:
- // No return value for the reply, just the header to ack
- s.PutCString(" ()");
- break;
-
- case KDP_HOSTINFO:
- {
- const uint32_t cpu_mask = packet.GetU32 (&offset);
- const uint32_t cpu_type = packet.GetU32 (&offset);
- const uint32_t cpu_subtype = packet.GetU32 (&offset);
- s.Printf(" (cpu_mask=0x%8.8x, cpu_type=0x%8.8x, cpu_subtype=0x%8.8x)", cpu_mask, cpu_type, cpu_subtype);
- }
- break;
-
- case KDP_VERSION:
- {
- const uint32_t version = packet.GetU32 (&offset);
- const uint32_t feature = packet.GetU32 (&offset);
- s.Printf(" (version=0x%8.8x, feature=0x%8.8x)", version, feature);
- }
- break;
-
- case KDP_REGIONS:
- {
- const uint32_t region_count = packet.GetU32 (&offset);
- s.Printf(" (count = %u", region_count);
- for (uint32_t i=0; i<region_count; ++i)
- {
- const addr_t region_addr = packet.GetPointer (&offset);
- const uint32_t region_size = packet.GetU32 (&offset);
- const uint32_t region_prot = packet.GetU32 (&offset);
- s.Printf("\n\tregion[%" PRIu64 "] = { range = [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), size = 0x%8.8x, prot = %s }", region_addr, region_addr, region_addr + region_size, region_size, GetPermissionsAsCString (region_prot));
- }
- }
- break;
-
- case KDP_READMEM:
- case KDP_READMEM64:
- case KDP_READPHYSMEM64:
- {
- const uint32_t error = packet.GetU32 (&offset);
- const uint32_t count = packet.GetByteSize() - offset;
- s.Printf(" (error = 0x%8.8x:\n", error);
- if (count > 0)
- packet.Dump (&s, // Stream to dump to
- offset, // Offset within "packet"
- eFormatBytesWithASCII, // Format to use
- 1, // Size of each item in bytes
- count, // Number of items
- 16, // Number per line
- m_last_read_memory_addr, // Don't show addresses before each line
- 0, 0); // No bitfields
- }
- break;
-
- case KDP_READREGS:
- {
- const uint32_t error = packet.GetU32 (&offset);
- const uint32_t count = packet.GetByteSize() - offset;
- s.Printf(" (error = 0x%8.8x regs:\n", error);
- if (count > 0)
- packet.Dump (&s, // Stream to dump to
- offset, // Offset within "packet"
- eFormatHex, // Format to use
- m_addr_byte_size, // Size of each item in bytes
- count / m_addr_byte_size, // Number of items
- 16 / m_addr_byte_size, // Number per line
- LLDB_INVALID_ADDRESS, // Don't show addresses before each line
- 0, 0); // No bitfields
- }
- break;
-
- case KDP_KERNELVERSION:
- {
- const char *kernel_version = packet.PeekCStr(8);
- s.Printf(" (version = \"%s\")", kernel_version);
- }
- break;
-
- case KDP_MAXBYTES:
- {
- const uint32_t max_bytes = packet.GetU32 (&offset);
- s.Printf(" (max_bytes = 0x%8.8x (%u))", max_bytes, max_bytes);
- }
- break;
- case KDP_IMAGEPATH:
- {
- const char *path = packet.GetCStr(&offset);
- s.Printf(" (path = \"%s\")", path);
- }
- break;
-
- case KDP_READIOPORT:
- case KDP_READMSR64:
- {
- const uint32_t error = packet.GetU32 (&offset);
- const uint32_t count = packet.GetByteSize() - offset;
- s.Printf(" (error = 0x%8.8x io:\n", error);
- if (count > 0)
- packet.Dump (&s, // Stream to dump to
- offset, // Offset within "packet"
- eFormatHex, // Format to use
- 1, // Size of each item in bytes
- count, // Number of items
- 16, // Number per line
- LLDB_INVALID_ADDRESS, // Don't show addresses before each line
- 0, 0); // No bitfields
- }
- break;
- case KDP_DUMPINFO:
- {
- const uint32_t count = packet.GetByteSize() - offset;
- s.Printf(" (count = %u, bytes = \n", count);
- if (count > 0)
- packet.Dump (&s, // Stream to dump to
- offset, // Offset within "packet"
- eFormatHex, // Format to use
- 1, // Size of each item in bytes
- count, // Number of items
- 16, // Number per line
- LLDB_INVALID_ADDRESS, // Don't show addresses before each line
- 0, 0); // No bitfields
-
- }
- break;
-
- default:
- s.Printf(" (add support for dumping this packet reply!!!");
- break;
-
- }
- }
- else
- {
- // Dump request packets
- switch (command)
- {
- case KDP_CONNECT:
- {
- const uint16_t reply_port = ntohs(packet.GetU16 (&offset));
- const uint16_t exc_port = ntohs(packet.GetU16 (&offset));
- s.Printf(" (reply_port = %u, exc_port = %u, greeting = \"%s\")", reply_port, exc_port, packet.GetCStr(&offset));
- }
- break;
-
- case KDP_DISCONNECT:
- case KDP_HOSTREBOOT:
- case KDP_HOSTINFO:
- case KDP_VERSION:
- case KDP_REGIONS:
- case KDP_KERNELVERSION:
- case KDP_MAXBYTES:
- case KDP_IMAGEPATH:
- case KDP_SUSPEND:
- // No args, just the header in the request...
- s.PutCString(" ()");
- break;
-
- case KDP_RESUMECPUS:
- {
- const uint32_t cpu_mask = packet.GetU32 (&offset);
- s.Printf(" (cpu_mask = 0x%8.8x)", cpu_mask);
- }
- break;
-
- case KDP_READMEM:
- {
- const uint32_t addr = packet.GetU32 (&offset);
- const uint32_t size = packet.GetU32 (&offset);
- s.Printf(" (addr = 0x%8.8x, size = %u)", addr, size);
- m_last_read_memory_addr = addr;
- }
- break;
-
- case KDP_WRITEMEM:
- {
- const uint32_t addr = packet.GetU32 (&offset);
- const uint32_t size = packet.GetU32 (&offset);
- s.Printf(" (addr = 0x%8.8x, size = %u, bytes = \n", addr, size);
- if (size > 0)
- DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size, 32, addr);
- }
- break;
-
- case KDP_READMEM64:
- {
- const uint64_t addr = packet.GetU64 (&offset);
- const uint32_t size = packet.GetU32 (&offset);
- s.Printf(" (addr = 0x%16.16" PRIx64 ", size = %u)", addr, size);
- m_last_read_memory_addr = addr;
- }
- break;
-
- case KDP_READPHYSMEM64:
- {
- const uint64_t addr = packet.GetU64 (&offset);
- const uint32_t size = packet.GetU32 (&offset);
- const uint32_t lcpu = packet.GetU16 (&offset);
- s.Printf(" (addr = 0x%16.16llx, size = %u, lcpu = %u)", addr, size, lcpu);
- m_last_read_memory_addr = addr;
- }
- break;
-
- case KDP_WRITEMEM64:
- {
- const uint64_t addr = packet.GetU64 (&offset);
- const uint32_t size = packet.GetU32 (&offset);
- s.Printf(" (addr = 0x%16.16" PRIx64 ", size = %u, bytes = \n", addr, size);
- if (size > 0)
- DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size, 32, addr);
- }
- break;
-
- case KDP_WRITEPHYSMEM64:
- {
- const uint64_t addr = packet.GetU64 (&offset);
- const uint32_t size = packet.GetU32 (&offset);
- const uint32_t lcpu = packet.GetU16 (&offset);
- s.Printf(" (addr = 0x%16.16llx, size = %u, lcpu = %u, bytes = \n", addr, size, lcpu);
- if (size > 0)
- DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size, 32, addr);
- }
- break;
-
- case KDP_READREGS:
- {
- const uint32_t cpu = packet.GetU32 (&offset);
- const uint32_t flavor = packet.GetU32 (&offset);
- s.Printf(" (cpu = %u, flavor = %u)", cpu, flavor);
- }
- break;
-
- case KDP_WRITEREGS:
- {
- const uint32_t cpu = packet.GetU32 (&offset);
- const uint32_t flavor = packet.GetU32 (&offset);
- const uint32_t nbytes = packet.GetByteSize() - offset;
- s.Printf(" (cpu = %u, flavor = %u, regs = \n", cpu, flavor);
- if (nbytes > 0)
- packet.Dump (&s, // Stream to dump to
- offset, // Offset within "packet"
- eFormatHex, // Format to use
- m_addr_byte_size, // Size of each item in bytes
- nbytes / m_addr_byte_size, // Number of items
- 16 / m_addr_byte_size, // Number per line
- LLDB_INVALID_ADDRESS, // Don't show addresses before each line
- 0, 0); // No bitfields
- }
- break;
-
-
- case KDP_BREAKPOINT_SET:
- case KDP_BREAKPOINT_REMOVE:
- {
- const uint32_t addr = packet.GetU32 (&offset);
- s.Printf(" (addr = 0x%8.8x)", addr);
- }
- break;
-
- case KDP_BREAKPOINT_SET64:
- case KDP_BREAKPOINT_REMOVE64:
- {
- const uint64_t addr = packet.GetU64 (&offset);
- s.Printf(" (addr = 0x%16.16" PRIx64 ")", addr);
- }
- break;
-
-
- case KDP_LOAD:
- {
- const char *path = packet.GetCStr(&offset);
- s.Printf(" (path = \"%s\")", path);
- }
- break;
-
- case KDP_EXCEPTION:
- {
- const uint32_t count = packet.GetU32 (&offset);
-
- for (uint32_t i=0; i<count; ++i)
- {
- const uint32_t cpu = packet.GetU32 (&offset);
- const uint32_t exc = packet.GetU32 (&offset);
- const uint32_t code = packet.GetU32 (&offset);
- const uint32_t subcode = packet.GetU32 (&offset);
- const char *exc_cstr = NULL;
- switch (exc)
- {
- case 1: exc_cstr = "EXC_BAD_ACCESS"; break;
- case 2: exc_cstr = "EXC_BAD_INSTRUCTION"; break;
- case 3: exc_cstr = "EXC_ARITHMETIC"; break;
- case 4: exc_cstr = "EXC_EMULATION"; break;
- case 5: exc_cstr = "EXC_SOFTWARE"; break;
- case 6: exc_cstr = "EXC_BREAKPOINT"; break;
- case 7: exc_cstr = "EXC_SYSCALL"; break;
- case 8: exc_cstr = "EXC_MACH_SYSCALL"; break;
- case 9: exc_cstr = "EXC_RPC_ALERT"; break;
- case 10: exc_cstr = "EXC_CRASH"; break;
- default:
- break;
- }
-
- s.Printf ("{ cpu = 0x%8.8x, exc = %s (%u), code = %u (0x%8.8x), subcode = %u (0x%8.8x)} ",
- cpu, exc_cstr, exc, code, code, subcode, subcode);
- }
- }
- break;
-
- case KDP_TERMINATION:
- {
- const uint32_t term_code = packet.GetU32 (&offset);
- const uint32_t exit_code = packet.GetU32 (&offset);
- s.Printf(" (term_code = 0x%8.8x (%u), exit_code = 0x%8.8x (%u))", term_code, term_code, exit_code, exit_code);
- }
- break;
-
- case KDP_REATTACH:
- {
- const uint16_t reply_port = ntohs(packet.GetU16 (&offset));
- s.Printf(" (reply_port = %u)", reply_port);
- }
- break;
-
- case KDP_READMSR64:
- {
- const uint32_t address = packet.GetU32 (&offset);
- const uint16_t lcpu = packet.GetU16 (&offset);
- s.Printf(" (address=0x%8.8x, lcpu=0x%4.4x)", address, lcpu);
- }
- break;
-
- case KDP_WRITEMSR64:
- {
- const uint32_t address = packet.GetU32 (&offset);
- const uint16_t lcpu = packet.GetU16 (&offset);
- const uint32_t nbytes = packet.GetByteSize() - offset;
- s.Printf(" (address=0x%8.8x, lcpu=0x%4.4x, nbytes=0x%8.8x)", lcpu, address, nbytes);
- if (nbytes > 0)
- packet.Dump (&s, // Stream to dump to
- offset, // Offset within "packet"
- eFormatHex, // Format to use
- 1, // Size of each item in bytes
- nbytes, // Number of items
- 16, // Number per line
- LLDB_INVALID_ADDRESS, // Don't show addresses before each line
- 0, 0); // No bitfields
- }
- break;
-
- case KDP_READIOPORT:
- {
- const uint16_t lcpu = packet.GetU16 (&offset);
- const uint16_t address = packet.GetU16 (&offset);
- const uint16_t nbytes = packet.GetU16 (&offset);
- s.Printf(" (lcpu=0x%4.4x, address=0x%4.4x, nbytes=%u)", lcpu, address, nbytes);
- }
- break;
-
- case KDP_WRITEIOPORT:
- {
- const uint16_t lcpu = packet.GetU16 (&offset);
- const uint16_t address = packet.GetU16 (&offset);
- const uint16_t nbytes = packet.GetU16 (&offset);
- s.Printf(" (lcpu = %u, addr = 0x%4.4x, nbytes = %u, bytes = \n", lcpu, address, nbytes);
- if (nbytes > 0)
- packet.Dump (&s, // Stream to dump to
- offset, // Offset within "packet"
- eFormatHex, // Format to use
- 1, // Size of each item in bytes
- nbytes, // Number of items
- 16, // Number per line
- LLDB_INVALID_ADDRESS, // Don't show addresses before each line
- 0, 0); // No bitfields
- }
- break;
-
- case KDP_DUMPINFO:
- {
- const uint32_t count = packet.GetByteSize() - offset;
- s.Printf(" (count = %u, bytes = \n", count);
- if (count > 0)
- packet.Dump (&s, // Stream to dump to
- offset, // Offset within "packet"
- eFormatHex, // Format to use
- 1, // Size of each item in bytes
- count, // Number of items
- 16, // Number per line
- LLDB_INVALID_ADDRESS, // Don't show addresses before each line
- 0, 0); // No bitfields
-
- }
- break;
-
- }
- }
- }
- else
- {
- error_desc = "error: invalid packet command: ";
- }
- }
-
- if (error_desc)
- {
- s.PutCString (error_desc);
-
- packet.Dump (&s, // Stream to dump to
- 0, // Offset into "packet"
- eFormatBytes, // Dump as hex bytes
- 1, // Size of each item is 1 for single bytes
- packet.GetByteSize(), // Number of bytes
- UINT32_MAX, // Num bytes per line
- LLDB_INVALID_ADDRESS, // Base address
- 0, 0); // Bitfield info set to not do anything bitfield related
- }
+void CommunicationKDP::DumpPacket(Stream &s, const void *data,
+ uint32_t data_len) {
+ DataExtractor extractor(data, data_len, m_byte_order, m_addr_byte_size);
+ DumpPacket(s, extractor);
}
-uint32_t
-CommunicationKDP::SendRequestReadRegisters (uint32_t cpu,
- uint32_t flavor,
- void *dst,
- uint32_t dst_len,
- Error &error)
-{
- PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
- const CommandType command = KDP_READREGS;
- // Size is header + 4 byte cpu and 4 byte flavor
- const uint32_t command_length = 8 + 4 + 4;
- MakeRequestPacketHeader (command, request_packet, command_length);
- request_packet.PutHex32 (cpu);
- request_packet.PutHex32 (flavor);
- DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_packet, reply_packet))
- {
- lldb::offset_t offset = 8;
- uint32_t kdp_error = reply_packet.GetU32 (&offset);
- uint32_t src_len = reply_packet.GetByteSize() - 12;
-
- if (src_len > 0)
- {
- const uint32_t bytes_to_copy = std::min<uint32_t>(src_len, dst_len);
- const void *src = reply_packet.GetData(&offset, bytes_to_copy);
- if (src)
- {
- ::memcpy (dst, src, bytes_to_copy);
- error.Clear();
- // Return the number of bytes we could have returned regardless if
- // we copied them or not, just so we know when things don't match up
- return src_len;
+void CommunicationKDP::DumpPacket(Stream &s, const DataExtractor &packet) {
+ const char *error_desc = NULL;
+ if (packet.GetByteSize() < 8) {
+ error_desc = "error: invalid packet (too short): ";
+ } else {
+ lldb::offset_t offset = 0;
+ const uint8_t first_packet_byte = packet.GetU8(&offset);
+ const uint8_t sequence_id = packet.GetU8(&offset);
+ const uint16_t length = packet.GetU16(&offset);
+ const uint32_t key = packet.GetU32(&offset);
+ const CommandType command = ExtractCommand(first_packet_byte);
+ const char *command_name = GetCommandAsCString(command);
+ if (command_name) {
+ const bool is_reply = ExtractIsReply(first_packet_byte);
+ s.Printf("(running=%i) %s %24s: 0x%2.2x 0x%2.2x 0x%4.4x 0x%8.8x ",
+ IsRunning(), is_reply ? "<--" : "-->", command_name,
+ first_packet_byte, sequence_id, length, key);
+
+ if (is_reply) {
+ // Dump request reply packets
+ switch (command) {
+ // Commands that return a single 32 bit error
+ case KDP_CONNECT:
+ case KDP_WRITEMEM:
+ case KDP_WRITEMEM64:
+ case KDP_BREAKPOINT_SET:
+ case KDP_BREAKPOINT_REMOVE:
+ case KDP_BREAKPOINT_SET64:
+ case KDP_BREAKPOINT_REMOVE64:
+ case KDP_WRITEREGS:
+ case KDP_LOAD:
+ case KDP_WRITEIOPORT:
+ case KDP_WRITEMSR64: {
+ const uint32_t error = packet.GetU32(&offset);
+ s.Printf(" (error=0x%8.8x)", error);
+ } break;
+
+ case KDP_DISCONNECT:
+ case KDP_REATTACH:
+ case KDP_HOSTREBOOT:
+ case KDP_SUSPEND:
+ case KDP_RESUMECPUS:
+ case KDP_EXCEPTION:
+ case KDP_TERMINATION:
+ // No return value for the reply, just the header to ack
+ s.PutCString(" ()");
+ break;
+
+ case KDP_HOSTINFO: {
+ const uint32_t cpu_mask = packet.GetU32(&offset);
+ const uint32_t cpu_type = packet.GetU32(&offset);
+ const uint32_t cpu_subtype = packet.GetU32(&offset);
+ s.Printf(" (cpu_mask=0x%8.8x, cpu_type=0x%8.8x, cpu_subtype=0x%8.8x)",
+ cpu_mask, cpu_type, cpu_subtype);
+ } break;
+
+ case KDP_VERSION: {
+ const uint32_t version = packet.GetU32(&offset);
+ const uint32_t feature = packet.GetU32(&offset);
+ s.Printf(" (version=0x%8.8x, feature=0x%8.8x)", version, feature);
+ } break;
+
+ case KDP_REGIONS: {
+ const uint32_t region_count = packet.GetU32(&offset);
+ s.Printf(" (count = %u", region_count);
+ for (uint32_t i = 0; i < region_count; ++i) {
+ const addr_t region_addr = packet.GetPointer(&offset);
+ const uint32_t region_size = packet.GetU32(&offset);
+ const uint32_t region_prot = packet.GetU32(&offset);
+ s.Printf("\n\tregion[%" PRIu64 "] = { range = [0x%16.16" PRIx64
+ " - 0x%16.16" PRIx64 "), size = 0x%8.8x, prot = %s }",
+ region_addr, region_addr, region_addr + region_size,
+ region_size, GetPermissionsAsCString(region_prot));
+ }
+ } break;
+
+ case KDP_READMEM:
+ case KDP_READMEM64:
+ case KDP_READPHYSMEM64: {
+ const uint32_t error = packet.GetU32(&offset);
+ const uint32_t count = packet.GetByteSize() - offset;
+ s.Printf(" (error = 0x%8.8x:\n", error);
+ if (count > 0)
+ packet.Dump(&s, // Stream to dump to
+ offset, // Offset within "packet"
+ eFormatBytesWithASCII, // Format to use
+ 1, // Size of each item in bytes
+ count, // Number of items
+ 16, // Number per line
+ m_last_read_memory_addr, // Don't show addresses before
+ // each line
+ 0, 0); // No bitfields
+ } break;
+
+ case KDP_READREGS: {
+ const uint32_t error = packet.GetU32(&offset);
+ const uint32_t count = packet.GetByteSize() - offset;
+ s.Printf(" (error = 0x%8.8x regs:\n", error);
+ if (count > 0)
+ packet.Dump(
+ &s, // Stream to dump to
+ offset, // Offset within "packet"
+ eFormatHex, // Format to use
+ m_addr_byte_size, // Size of each item in bytes
+ count / m_addr_byte_size, // Number of items
+ 16 / m_addr_byte_size, // Number per line
+ LLDB_INVALID_ADDRESS, // Don't show addresses before each line
+ 0, 0); // No bitfields
+ } break;
+
+ case KDP_KERNELVERSION: {
+ const char *kernel_version = packet.PeekCStr(8);
+ s.Printf(" (version = \"%s\")", kernel_version);
+ } break;
+
+ case KDP_MAXBYTES: {
+ const uint32_t max_bytes = packet.GetU32(&offset);
+ s.Printf(" (max_bytes = 0x%8.8x (%u))", max_bytes, max_bytes);
+ } break;
+ case KDP_IMAGEPATH: {
+ const char *path = packet.GetCStr(&offset);
+ s.Printf(" (path = \"%s\")", path);
+ } break;
+
+ case KDP_READIOPORT:
+ case KDP_READMSR64: {
+ const uint32_t error = packet.GetU32(&offset);
+ const uint32_t count = packet.GetByteSize() - offset;
+ s.Printf(" (error = 0x%8.8x io:\n", error);
+ if (count > 0)
+ packet.Dump(
+ &s, // Stream to dump to
+ offset, // Offset within "packet"
+ eFormatHex, // Format to use
+ 1, // Size of each item in bytes
+ count, // Number of items
+ 16, // Number per line
+ LLDB_INVALID_ADDRESS, // Don't show addresses before each line
+ 0, 0); // No bitfields
+ } break;
+ case KDP_DUMPINFO: {
+ const uint32_t count = packet.GetByteSize() - offset;
+ s.Printf(" (count = %u, bytes = \n", count);
+ if (count > 0)
+ packet.Dump(
+ &s, // Stream to dump to
+ offset, // Offset within "packet"
+ eFormatHex, // Format to use
+ 1, // Size of each item in bytes
+ count, // Number of items
+ 16, // Number per line
+ LLDB_INVALID_ADDRESS, // Don't show addresses before each line
+ 0, 0); // No bitfields
+
+ } break;
+
+ default:
+ s.Printf(" (add support for dumping this packet reply!!!");
+ break;
+ }
+ } else {
+ // Dump request packets
+ switch (command) {
+ case KDP_CONNECT: {
+ const uint16_t reply_port = ntohs(packet.GetU16(&offset));
+ const uint16_t exc_port = ntohs(packet.GetU16(&offset));
+ s.Printf(" (reply_port = %u, exc_port = %u, greeting = \"%s\")",
+ reply_port, exc_port, packet.GetCStr(&offset));
+ } break;
+
+ case KDP_DISCONNECT:
+ case KDP_HOSTREBOOT:
+ case KDP_HOSTINFO:
+ case KDP_VERSION:
+ case KDP_REGIONS:
+ case KDP_KERNELVERSION:
+ case KDP_MAXBYTES:
+ case KDP_IMAGEPATH:
+ case KDP_SUSPEND:
+ // No args, just the header in the request...
+ s.PutCString(" ()");
+ break;
+
+ case KDP_RESUMECPUS: {
+ const uint32_t cpu_mask = packet.GetU32(&offset);
+ s.Printf(" (cpu_mask = 0x%8.8x)", cpu_mask);
+ } break;
+
+ case KDP_READMEM: {
+ const uint32_t addr = packet.GetU32(&offset);
+ const uint32_t size = packet.GetU32(&offset);
+ s.Printf(" (addr = 0x%8.8x, size = %u)", addr, size);
+ m_last_read_memory_addr = addr;
+ } break;
+
+ case KDP_WRITEMEM: {
+ const uint32_t addr = packet.GetU32(&offset);
+ const uint32_t size = packet.GetU32(&offset);
+ s.Printf(" (addr = 0x%8.8x, size = %u, bytes = \n", addr, size);
+ if (size > 0)
+ DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size,
+ 32, addr);
+ } break;
+
+ case KDP_READMEM64: {
+ const uint64_t addr = packet.GetU64(&offset);
+ const uint32_t size = packet.GetU32(&offset);
+ s.Printf(" (addr = 0x%16.16" PRIx64 ", size = %u)", addr, size);
+ m_last_read_memory_addr = addr;
+ } break;
+
+ case KDP_READPHYSMEM64: {
+ const uint64_t addr = packet.GetU64(&offset);
+ const uint32_t size = packet.GetU32(&offset);
+ const uint32_t lcpu = packet.GetU16(&offset);
+ s.Printf(" (addr = 0x%16.16llx, size = %u, lcpu = %u)", addr, size,
+ lcpu);
+ m_last_read_memory_addr = addr;
+ } break;
+
+ case KDP_WRITEMEM64: {
+ const uint64_t addr = packet.GetU64(&offset);
+ const uint32_t size = packet.GetU32(&offset);
+ s.Printf(" (addr = 0x%16.16" PRIx64 ", size = %u, bytes = \n", addr,
+ size);
+ if (size > 0)
+ DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size,
+ 32, addr);
+ } break;
+
+ case KDP_WRITEPHYSMEM64: {
+ const uint64_t addr = packet.GetU64(&offset);
+ const uint32_t size = packet.GetU32(&offset);
+ const uint32_t lcpu = packet.GetU16(&offset);
+ s.Printf(" (addr = 0x%16.16llx, size = %u, lcpu = %u, bytes = \n",
+ addr, size, lcpu);
+ if (size > 0)
+ DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size,
+ 32, addr);
+ } break;
+
+ case KDP_READREGS: {
+ const uint32_t cpu = packet.GetU32(&offset);
+ const uint32_t flavor = packet.GetU32(&offset);
+ s.Printf(" (cpu = %u, flavor = %u)", cpu, flavor);
+ } break;
+
+ case KDP_WRITEREGS: {
+ const uint32_t cpu = packet.GetU32(&offset);
+ const uint32_t flavor = packet.GetU32(&offset);
+ const uint32_t nbytes = packet.GetByteSize() - offset;
+ s.Printf(" (cpu = %u, flavor = %u, regs = \n", cpu, flavor);
+ if (nbytes > 0)
+ packet.Dump(
+ &s, // Stream to dump to
+ offset, // Offset within "packet"
+ eFormatHex, // Format to use
+ m_addr_byte_size, // Size of each item in bytes
+ nbytes / m_addr_byte_size, // Number of items
+ 16 / m_addr_byte_size, // Number per line
+ LLDB_INVALID_ADDRESS, // Don't show addresses before each line
+ 0, 0); // No bitfields
+ } break;
+
+ case KDP_BREAKPOINT_SET:
+ case KDP_BREAKPOINT_REMOVE: {
+ const uint32_t addr = packet.GetU32(&offset);
+ s.Printf(" (addr = 0x%8.8x)", addr);
+ } break;
+
+ case KDP_BREAKPOINT_SET64:
+ case KDP_BREAKPOINT_REMOVE64: {
+ const uint64_t addr = packet.GetU64(&offset);
+ s.Printf(" (addr = 0x%16.16" PRIx64 ")", addr);
+ } break;
+
+ case KDP_LOAD: {
+ const char *path = packet.GetCStr(&offset);
+ s.Printf(" (path = \"%s\")", path);
+ } break;
+
+ case KDP_EXCEPTION: {
+ const uint32_t count = packet.GetU32(&offset);
+
+ for (uint32_t i = 0; i < count; ++i) {
+ const uint32_t cpu = packet.GetU32(&offset);
+ const uint32_t exc = packet.GetU32(&offset);
+ const uint32_t code = packet.GetU32(&offset);
+ const uint32_t subcode = packet.GetU32(&offset);
+ const char *exc_cstr = NULL;
+ switch (exc) {
+ case 1:
+ exc_cstr = "EXC_BAD_ACCESS";
+ break;
+ case 2:
+ exc_cstr = "EXC_BAD_INSTRUCTION";
+ break;
+ case 3:
+ exc_cstr = "EXC_ARITHMETIC";
+ break;
+ case 4:
+ exc_cstr = "EXC_EMULATION";
+ break;
+ case 5:
+ exc_cstr = "EXC_SOFTWARE";
+ break;
+ case 6:
+ exc_cstr = "EXC_BREAKPOINT";
+ break;
+ case 7:
+ exc_cstr = "EXC_SYSCALL";
+ break;
+ case 8:
+ exc_cstr = "EXC_MACH_SYSCALL";
+ break;
+ case 9:
+ exc_cstr = "EXC_RPC_ALERT";
+ break;
+ case 10:
+ exc_cstr = "EXC_CRASH";
+ break;
+ default:
+ break;
}
+
+ s.Printf("{ cpu = 0x%8.8x, exc = %s (%u), code = %u (0x%8.8x), "
+ "subcode = %u (0x%8.8x)} ",
+ cpu, exc_cstr, exc, code, code, subcode, subcode);
+ }
+ } break;
+
+ case KDP_TERMINATION: {
+ const uint32_t term_code = packet.GetU32(&offset);
+ const uint32_t exit_code = packet.GetU32(&offset);
+ s.Printf(" (term_code = 0x%8.8x (%u), exit_code = 0x%8.8x (%u))",
+ term_code, term_code, exit_code, exit_code);
+ } break;
+
+ case KDP_REATTACH: {
+ const uint16_t reply_port = ntohs(packet.GetU16(&offset));
+ s.Printf(" (reply_port = %u)", reply_port);
+ } break;
+
+ case KDP_READMSR64: {
+ const uint32_t address = packet.GetU32(&offset);
+ const uint16_t lcpu = packet.GetU16(&offset);
+ s.Printf(" (address=0x%8.8x, lcpu=0x%4.4x)", address, lcpu);
+ } break;
+
+ case KDP_WRITEMSR64: {
+ const uint32_t address = packet.GetU32(&offset);
+ const uint16_t lcpu = packet.GetU16(&offset);
+ const uint32_t nbytes = packet.GetByteSize() - offset;
+ s.Printf(" (address=0x%8.8x, lcpu=0x%4.4x, nbytes=0x%8.8x)", lcpu,
+ address, nbytes);
+ if (nbytes > 0)
+ packet.Dump(
+ &s, // Stream to dump to
+ offset, // Offset within "packet"
+ eFormatHex, // Format to use
+ 1, // Size of each item in bytes
+ nbytes, // Number of items
+ 16, // Number per line
+ LLDB_INVALID_ADDRESS, // Don't show addresses before each line
+ 0, 0); // No bitfields
+ } break;
+
+ case KDP_READIOPORT: {
+ const uint16_t lcpu = packet.GetU16(&offset);
+ const uint16_t address = packet.GetU16(&offset);
+ const uint16_t nbytes = packet.GetU16(&offset);
+ s.Printf(" (lcpu=0x%4.4x, address=0x%4.4x, nbytes=%u)", lcpu, address,
+ nbytes);
+ } break;
+
+ case KDP_WRITEIOPORT: {
+ const uint16_t lcpu = packet.GetU16(&offset);
+ const uint16_t address = packet.GetU16(&offset);
+ const uint16_t nbytes = packet.GetU16(&offset);
+ s.Printf(" (lcpu = %u, addr = 0x%4.4x, nbytes = %u, bytes = \n", lcpu,
+ address, nbytes);
+ if (nbytes > 0)
+ packet.Dump(
+ &s, // Stream to dump to
+ offset, // Offset within "packet"
+ eFormatHex, // Format to use
+ 1, // Size of each item in bytes
+ nbytes, // Number of items
+ 16, // Number per line
+ LLDB_INVALID_ADDRESS, // Don't show addresses before each line
+ 0, 0); // No bitfields
+ } break;
+
+ case KDP_DUMPINFO: {
+ const uint32_t count = packet.GetByteSize() - offset;
+ s.Printf(" (count = %u, bytes = \n", count);
+ if (count > 0)
+ packet.Dump(
+ &s, // Stream to dump to
+ offset, // Offset within "packet"
+ eFormatHex, // Format to use
+ 1, // Size of each item in bytes
+ count, // Number of items
+ 16, // Number per line
+ LLDB_INVALID_ADDRESS, // Don't show addresses before each line
+ 0, 0); // No bitfields
+
+ } break;
}
- if (kdp_error)
- error.SetErrorStringWithFormat("failed to read kdp registers for cpu %u flavor %u (error %u)", cpu, flavor, kdp_error);
- else
- error.SetErrorStringWithFormat("failed to read kdp registers for cpu %u flavor %u", cpu, flavor);
- }
- else
- {
- error.SetErrorString ("failed to send packet");
+ }
+ } else {
+ error_desc = "error: invalid packet command: ";
}
- return 0;
+ }
+
+ if (error_desc) {
+ s.PutCString(error_desc);
+
+ packet.Dump(&s, // Stream to dump to
+ 0, // Offset into "packet"
+ eFormatBytes, // Dump as hex bytes
+ 1, // Size of each item is 1 for single bytes
+ packet.GetByteSize(), // Number of bytes
+ UINT32_MAX, // Num bytes per line
+ LLDB_INVALID_ADDRESS, // Base address
+ 0, 0); // Bitfield info set to not do anything bitfield related
+ }
}
-uint32_t
-CommunicationKDP::SendRequestWriteRegisters (uint32_t cpu,
- uint32_t flavor,
- const void *src,
- uint32_t src_len,
- Error &error)
-{
- PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
- const CommandType command = KDP_WRITEREGS;
- // Size is header + 4 byte cpu and 4 byte flavor
- const uint32_t command_length = 8 + 4 + 4 + src_len;
- MakeRequestPacketHeader (command, request_packet, command_length);
- request_packet.PutHex32 (cpu);
- request_packet.PutHex32 (flavor);
- request_packet.Write(src, src_len);
- DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_packet, reply_packet))
- {
- lldb::offset_t offset = 8;
- uint32_t kdp_error = reply_packet.GetU32 (&offset);
- if (kdp_error == 0)
- return src_len;
- error.SetErrorStringWithFormat("failed to read kdp registers for cpu %u flavor %u (error %u)", cpu, flavor, kdp_error);
+uint32_t CommunicationKDP::SendRequestReadRegisters(uint32_t cpu,
+ uint32_t flavor, void *dst,
+ uint32_t dst_len,
+ Error &error) {
+ PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
+ m_byte_order);
+ const CommandType command = KDP_READREGS;
+ // Size is header + 4 byte cpu and 4 byte flavor
+ const uint32_t command_length = 8 + 4 + 4;
+ MakeRequestPacketHeader(command, request_packet, command_length);
+ request_packet.PutHex32(cpu);
+ request_packet.PutHex32(flavor);
+ DataExtractor reply_packet;
+ if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
+ lldb::offset_t offset = 8;
+ uint32_t kdp_error = reply_packet.GetU32(&offset);
+ uint32_t src_len = reply_packet.GetByteSize() - 12;
+
+ if (src_len > 0) {
+ const uint32_t bytes_to_copy = std::min<uint32_t>(src_len, dst_len);
+ const void *src = reply_packet.GetData(&offset, bytes_to_copy);
+ if (src) {
+ ::memcpy(dst, src, bytes_to_copy);
+ error.Clear();
+ // Return the number of bytes we could have returned regardless if
+ // we copied them or not, just so we know when things don't match up
+ return src_len;
+ }
}
+ if (kdp_error)
+ error.SetErrorStringWithFormat(
+ "failed to read kdp registers for cpu %u flavor %u (error %u)", cpu,
+ flavor, kdp_error);
else
- {
- error.SetErrorString ("failed to send packet");
- }
- return 0;
+ error.SetErrorStringWithFormat(
+ "failed to read kdp registers for cpu %u flavor %u", cpu, flavor);
+ } else {
+ error.SetErrorString("failed to send packet");
+ }
+ return 0;
}
-
-bool
-CommunicationKDP::SendRequestResume ()
-{
- PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
- const CommandType command = KDP_RESUMECPUS;
- const uint32_t command_length = 12;
- MakeRequestPacketHeader (command, request_packet, command_length);
- request_packet.PutHex32(GetCPUMask());
-
- DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_packet, reply_packet))
- return true;
- return false;
+uint32_t CommunicationKDP::SendRequestWriteRegisters(uint32_t cpu,
+ uint32_t flavor,
+ const void *src,
+ uint32_t src_len,
+ Error &error) {
+ PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
+ m_byte_order);
+ const CommandType command = KDP_WRITEREGS;
+ // Size is header + 4 byte cpu and 4 byte flavor
+ const uint32_t command_length = 8 + 4 + 4 + src_len;
+ MakeRequestPacketHeader(command, request_packet, command_length);
+ request_packet.PutHex32(cpu);
+ request_packet.PutHex32(flavor);
+ request_packet.Write(src, src_len);
+ DataExtractor reply_packet;
+ if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
+ lldb::offset_t offset = 8;
+ uint32_t kdp_error = reply_packet.GetU32(&offset);
+ if (kdp_error == 0)
+ return src_len;
+ error.SetErrorStringWithFormat(
+ "failed to read kdp registers for cpu %u flavor %u (error %u)", cpu,
+ flavor, kdp_error);
+ } else {
+ error.SetErrorString("failed to send packet");
+ }
+ return 0;
}
-bool
-CommunicationKDP::SendRequestBreakpoint (bool set, addr_t addr)
-{
- PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
- bool use_64 = (GetVersion() >= 11);
- uint32_t command_addr_byte_size = use_64 ? 8 : 4;
- const CommandType command = set ? (use_64 ? KDP_BREAKPOINT_SET64 : KDP_BREAKPOINT_SET ):
- (use_64 ? KDP_BREAKPOINT_REMOVE64 : KDP_BREAKPOINT_REMOVE);
+bool CommunicationKDP::SendRequestResume() {
+ PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
+ m_byte_order);
+ const CommandType command = KDP_RESUMECPUS;
+ const uint32_t command_length = 12;
+ MakeRequestPacketHeader(command, request_packet, command_length);
+ request_packet.PutHex32(GetCPUMask());
- const uint32_t command_length = 8 + command_addr_byte_size;
- MakeRequestPacketHeader (command, request_packet, command_length);
- request_packet.PutMaxHex64 (addr, command_addr_byte_size);
-
- DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_packet, reply_packet))
- {
- lldb::offset_t offset = 8;
- uint32_t kdp_error = reply_packet.GetU32 (&offset);
- if (kdp_error == 0)
- return true;
- }
- return false;
+ DataExtractor reply_packet;
+ if (SendRequestAndGetReply(command, request_packet, reply_packet))
+ return true;
+ return false;
}
-bool
-CommunicationKDP::SendRequestSuspend ()
-{
- PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
- const CommandType command = KDP_SUSPEND;
- const uint32_t command_length = 8;
- MakeRequestPacketHeader (command, request_packet, command_length);
- DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_packet, reply_packet))
- return true;
- return false;
+bool CommunicationKDP::SendRequestBreakpoint(bool set, addr_t addr) {
+ PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
+ m_byte_order);
+ bool use_64 = (GetVersion() >= 11);
+ uint32_t command_addr_byte_size = use_64 ? 8 : 4;
+ const CommandType command =
+ set ? (use_64 ? KDP_BREAKPOINT_SET64 : KDP_BREAKPOINT_SET)
+ : (use_64 ? KDP_BREAKPOINT_REMOVE64 : KDP_BREAKPOINT_REMOVE);
+
+ const uint32_t command_length = 8 + command_addr_byte_size;
+ MakeRequestPacketHeader(command, request_packet, command_length);
+ request_packet.PutMaxHex64(addr, command_addr_byte_size);
+
+ DataExtractor reply_packet;
+ if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
+ lldb::offset_t offset = 8;
+ uint32_t kdp_error = reply_packet.GetU32(&offset);
+ if (kdp_error == 0)
+ return true;
+ }
+ return false;
}
+bool CommunicationKDP::SendRequestSuspend() {
+ PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
+ m_byte_order);
+ const CommandType command = KDP_SUSPEND;
+ const uint32_t command_length = 8;
+ MakeRequestPacketHeader(command, request_packet, command_length);
+ DataExtractor reply_packet;
+ if (SendRequestAndGetReply(command, request_packet, reply_packet))
+ return true;
+ return false;
+}
diff --git a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
index 89e55a561e74..eed3daa4647e 100644
--- a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
+++ b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
@@ -18,330 +18,245 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Core/Communication.h"
#include "lldb/Core/Listener.h"
#include "lldb/Core/StreamBuffer.h"
#include "lldb/Host/Predicate.h"
-#include "lldb/Host/TimeValue.h"
+#include "lldb/lldb-private.h"
-class CommunicationKDP : public lldb_private::Communication
-{
+class CommunicationKDP : public lldb_private::Communication {
public:
- enum
- {
- eBroadcastBitRunPacketSent = kLoUserBroadcastBit
- };
-
- const static uint32_t kMaxPacketSize = 1200;
- const static uint32_t kMaxDataSize = 1024;
- typedef lldb_private::StreamBuffer<1024> PacketStreamType;
- typedef enum
- {
- KDP_CONNECT = 0u,
- KDP_DISCONNECT,
- KDP_HOSTINFO,
- KDP_VERSION,
- KDP_MAXBYTES,
- KDP_READMEM,
- KDP_WRITEMEM,
- KDP_READREGS,
- KDP_WRITEREGS,
- KDP_LOAD,
- KDP_IMAGEPATH,
- KDP_SUSPEND,
- KDP_RESUMECPUS,
- KDP_EXCEPTION,
- KDP_TERMINATION,
- KDP_BREAKPOINT_SET,
- KDP_BREAKPOINT_REMOVE,
- KDP_REGIONS,
- KDP_REATTACH,
- KDP_HOSTREBOOT,
- KDP_READMEM64,
- KDP_WRITEMEM64,
- KDP_BREAKPOINT_SET64,
- KDP_BREAKPOINT_REMOVE64,
- KDP_KERNELVERSION,
- KDP_READPHYSMEM64,
- KDP_WRITEPHYSMEM64,
- KDP_READIOPORT,
- KDP_WRITEIOPORT,
- KDP_READMSR64,
- KDP_WRITEMSR64,
- KDP_DUMPINFO
- } CommandType;
-
- enum
- {
- KDP_FEATURE_BP = (1u << 0)
- };
-
- typedef enum
- {
- KDP_PROTERR_SUCCESS = 0,
- KDP_PROTERR_ALREADY_CONNECTED,
- KDP_PROTERR_BAD_NBYTES,
- KDP_PROTERR_BADFLAVOR
- } KDPError;
-
- typedef enum
- {
- ePacketTypeRequest = 0x00u,
- ePacketTypeReply = 0x80u,
- ePacketTypeMask = 0x80u,
- eCommandTypeMask = 0x7fu
- } PacketType;
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- CommunicationKDP (const char *comm_name);
-
- virtual
- ~CommunicationKDP();
-
- bool
- SendRequestPacket (const PacketStreamType &request_packet);
-
- // Wait for a packet within 'nsec' seconds
- size_t
- WaitForPacketWithTimeoutMicroSeconds (lldb_private::DataExtractor &response,
- uint32_t usec);
-
- bool
- GetSequenceMutex(std::unique_lock<std::recursive_mutex> &lock);
-
- bool
- CheckForPacket (const uint8_t *src,
- size_t src_len,
- lldb_private::DataExtractor &packet);
- bool
- IsRunning() const
- {
- return m_is_running.GetValue();
- }
-
- //------------------------------------------------------------------
- // Set the global packet timeout.
- //
- // For clients, this is the timeout that gets used when sending
- // packets and waiting for responses. For servers, this might not
- // get used, and if it doesn't this should be moved to the
- // CommunicationKDPClient.
- //------------------------------------------------------------------
- uint32_t
- SetPacketTimeout (uint32_t packet_timeout)
- {
- const uint32_t old_packet_timeout = m_packet_timeout;
- m_packet_timeout = packet_timeout;
- return old_packet_timeout;
- }
-
- uint32_t
- GetPacketTimeoutInMicroSeconds () const
- {
- return m_packet_timeout * lldb_private::TimeValue::MicroSecPerSec;
- }
-
- //------------------------------------------------------------------
- // Public Request Packets
- //------------------------------------------------------------------
- bool
- SendRequestConnect (uint16_t reply_port,
- uint16_t exc_port,
- const char *greeting);
-
- bool
- SendRequestReattach (uint16_t reply_port);
-
- bool
- SendRequestDisconnect ();
-
- uint32_t
- SendRequestReadMemory (lldb::addr_t addr,
- void *dst,
- uint32_t dst_size,
- lldb_private::Error &error);
-
- uint32_t
- SendRequestWriteMemory (lldb::addr_t addr,
- const void *src,
- uint32_t src_len,
- lldb_private::Error &error);
-
- bool
- SendRawRequest (uint8_t command_byte,
- const void *src,
- uint32_t src_len,
- lldb_private::DataExtractor &reply,
- lldb_private::Error &error);
-
- uint32_t
- SendRequestReadRegisters (uint32_t cpu,
- uint32_t flavor,
- void *dst,
- uint32_t dst_size,
- lldb_private::Error &error);
-
- uint32_t
- SendRequestWriteRegisters (uint32_t cpu,
- uint32_t flavor,
- const void *src,
- uint32_t src_size,
- lldb_private::Error &error);
-
- const char *
- GetKernelVersion ();
-
- // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
- // const char *
- // GetImagePath ();
-
- uint32_t
- GetVersion ();
-
- uint32_t
- GetFeatureFlags ();
-
- bool
- LocalBreakpointsAreSupported ()
- {
- return (GetFeatureFlags() & KDP_FEATURE_BP) != 0;
- }
-
- uint32_t
- GetCPUMask ();
-
- uint32_t
- GetCPUType ();
-
- uint32_t
- GetCPUSubtype ();
-
- lldb_private::UUID
- GetUUID ();
-
- bool
- RemoteIsEFI ();
-
- bool
- RemoteIsDarwinKernel ();
-
- lldb::addr_t
- GetLoadAddress ();
-
- bool
- SendRequestResume ();
-
- bool
- SendRequestSuspend ();
-
- bool
- SendRequestBreakpoint (bool set, lldb::addr_t addr);
+ enum { eBroadcastBitRunPacketSent = kLoUserBroadcastBit };
+
+ const static uint32_t kMaxPacketSize = 1200;
+ const static uint32_t kMaxDataSize = 1024;
+ typedef lldb_private::StreamBuffer<1024> PacketStreamType;
+ typedef enum {
+ KDP_CONNECT = 0u,
+ KDP_DISCONNECT,
+ KDP_HOSTINFO,
+ KDP_VERSION,
+ KDP_MAXBYTES,
+ KDP_READMEM,
+ KDP_WRITEMEM,
+ KDP_READREGS,
+ KDP_WRITEREGS,
+ KDP_LOAD,
+ KDP_IMAGEPATH,
+ KDP_SUSPEND,
+ KDP_RESUMECPUS,
+ KDP_EXCEPTION,
+ KDP_TERMINATION,
+ KDP_BREAKPOINT_SET,
+ KDP_BREAKPOINT_REMOVE,
+ KDP_REGIONS,
+ KDP_REATTACH,
+ KDP_HOSTREBOOT,
+ KDP_READMEM64,
+ KDP_WRITEMEM64,
+ KDP_BREAKPOINT_SET64,
+ KDP_BREAKPOINT_REMOVE64,
+ KDP_KERNELVERSION,
+ KDP_READPHYSMEM64,
+ KDP_WRITEPHYSMEM64,
+ KDP_READIOPORT,
+ KDP_WRITEIOPORT,
+ KDP_READMSR64,
+ KDP_WRITEMSR64,
+ KDP_DUMPINFO
+ } CommandType;
+
+ enum { KDP_FEATURE_BP = (1u << 0) };
+
+ typedef enum {
+ KDP_PROTERR_SUCCESS = 0,
+ KDP_PROTERR_ALREADY_CONNECTED,
+ KDP_PROTERR_BAD_NBYTES,
+ KDP_PROTERR_BADFLAVOR
+ } KDPError;
+
+ typedef enum {
+ ePacketTypeRequest = 0x00u,
+ ePacketTypeReply = 0x80u,
+ ePacketTypeMask = 0x80u,
+ eCommandTypeMask = 0x7fu
+ } PacketType;
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ CommunicationKDP(const char *comm_name);
+
+ virtual ~CommunicationKDP();
+
+ bool SendRequestPacket(const PacketStreamType &request_packet);
+
+ // Wait for a packet within 'nsec' seconds
+ size_t
+ WaitForPacketWithTimeoutMicroSeconds(lldb_private::DataExtractor &response,
+ uint32_t usec);
+
+ bool GetSequenceMutex(std::unique_lock<std::recursive_mutex> &lock);
+
+ bool CheckForPacket(const uint8_t *src, size_t src_len,
+ lldb_private::DataExtractor &packet);
+ bool IsRunning() const { return m_is_running.GetValue(); }
+
+ //------------------------------------------------------------------
+ // Set the global packet timeout.
+ //
+ // For clients, this is the timeout that gets used when sending
+ // packets and waiting for responses. For servers, this might not
+ // get used, and if it doesn't this should be moved to the
+ // CommunicationKDPClient.
+ //------------------------------------------------------------------
+ std::chrono::seconds SetPacketTimeout(std::chrono::seconds packet_timeout) {
+ const auto old_packet_timeout = m_packet_timeout;
+ m_packet_timeout = packet_timeout;
+ return old_packet_timeout;
+ }
+
+ std::chrono::seconds GetPacketTimeout() const { return m_packet_timeout; }
+
+ //------------------------------------------------------------------
+ // Public Request Packets
+ //------------------------------------------------------------------
+ bool SendRequestConnect(uint16_t reply_port, uint16_t exc_port,
+ const char *greeting);
+
+ bool SendRequestReattach(uint16_t reply_port);
+
+ bool SendRequestDisconnect();
+
+ uint32_t SendRequestReadMemory(lldb::addr_t addr, void *dst,
+ uint32_t dst_size, lldb_private::Error &error);
+
+ uint32_t SendRequestWriteMemory(lldb::addr_t addr, const void *src,
+ uint32_t src_len, lldb_private::Error &error);
+
+ bool SendRawRequest(uint8_t command_byte, const void *src, uint32_t src_len,
+ lldb_private::DataExtractor &reply,
+ lldb_private::Error &error);
+
+ uint32_t SendRequestReadRegisters(uint32_t cpu, uint32_t flavor, void *dst,
+ uint32_t dst_size,
+ lldb_private::Error &error);
-protected:
+ uint32_t SendRequestWriteRegisters(uint32_t cpu, uint32_t flavor,
+ const void *src, uint32_t src_size,
+ lldb_private::Error &error);
+
+ const char *GetKernelVersion();
+
+ // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
+ // const char *
+ // GetImagePath ();
+
+ uint32_t GetVersion();
+
+ uint32_t GetFeatureFlags();
+
+ bool LocalBreakpointsAreSupported() {
+ return (GetFeatureFlags() & KDP_FEATURE_BP) != 0;
+ }
+
+ uint32_t GetCPUMask();
+
+ uint32_t GetCPUType();
- bool
- SendRequestPacketNoLock (const PacketStreamType &request_packet);
-
- size_t
- WaitForPacketWithTimeoutMicroSecondsNoLock (lldb_private::DataExtractor &response,
- uint32_t timeout_usec);
-
- bool
- WaitForNotRunningPrivate (const lldb_private::TimeValue *timeout_ptr);
-
- void
- MakeRequestPacketHeader (CommandType request_type,
- PacketStreamType &request_packet,
- uint16_t request_length);
-
- //------------------------------------------------------------------
- // Protected Request Packets (use public accessors which will cache
- // results.
- //------------------------------------------------------------------
- bool
- SendRequestVersion ();
-
- bool
- SendRequestHostInfo ();
-
- bool
- SendRequestKernelVersion ();
-
- // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
- //bool
- //SendRequestImagePath ();
-
- void
- DumpPacket (lldb_private::Stream &s,
- const void *data,
- uint32_t data_len);
-
- void
- DumpPacket (lldb_private::Stream &s,
- const lldb_private::DataExtractor& extractor);
-
- bool
- VersionIsValid() const
- {
- return m_kdp_version_version != 0;
- }
-
- bool
- HostInfoIsValid() const
- {
- return m_kdp_hostinfo_cpu_type != 0;
- }
-
- bool
- ExtractIsReply (uint8_t first_packet_byte) const
- {
- // TODO: handle big endian...
- return (first_packet_byte & ePacketTypeMask) != 0;
- }
-
- CommandType
- ExtractCommand (uint8_t first_packet_byte) const
- {
- // TODO: handle big endian...
- return (CommandType)(first_packet_byte & eCommandTypeMask);
- }
-
- static const char *
- GetCommandAsCString (uint8_t command);
-
- void
- ClearKDPSettings ();
-
- bool
- SendRequestAndGetReply (const CommandType command,
- const PacketStreamType &request_packet,
- lldb_private::DataExtractor &reply_packet);
- //------------------------------------------------------------------
- // Classes that inherit from CommunicationKDP can see and modify these
- //------------------------------------------------------------------
- uint32_t m_addr_byte_size;
- lldb::ByteOrder m_byte_order;
- uint32_t m_packet_timeout;
- std::recursive_mutex m_sequence_mutex; // Restrict access to sending/receiving packets to a single thread at a time
- lldb_private::Predicate<bool> m_is_running;
- uint32_t m_session_key;
- uint8_t m_request_sequence_id;
- uint8_t m_exception_sequence_id;
- uint32_t m_kdp_version_version;
- uint32_t m_kdp_version_feature;
- uint32_t m_kdp_hostinfo_cpu_mask;
- uint32_t m_kdp_hostinfo_cpu_type;
- uint32_t m_kdp_hostinfo_cpu_subtype;
- std::string m_kernel_version;
- //std::string m_image_path; // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
- lldb::addr_t m_last_read_memory_addr; // Last memory read address for logging
+ uint32_t GetCPUSubtype();
+
+ lldb_private::UUID GetUUID();
+
+ bool RemoteIsEFI();
+
+ bool RemoteIsDarwinKernel();
+
+ lldb::addr_t GetLoadAddress();
+
+ bool SendRequestResume();
+
+ bool SendRequestSuspend();
+
+ bool SendRequestBreakpoint(bool set, lldb::addr_t addr);
+
+protected:
+ bool SendRequestPacketNoLock(const PacketStreamType &request_packet);
+
+ size_t WaitForPacketWithTimeoutMicroSecondsNoLock(
+ lldb_private::DataExtractor &response, uint32_t timeout_usec);
+
+ bool WaitForNotRunningPrivate(const std::chrono::microseconds &timeout);
+
+ void MakeRequestPacketHeader(CommandType request_type,
+ PacketStreamType &request_packet,
+ uint16_t request_length);
+
+ //------------------------------------------------------------------
+ // Protected Request Packets (use public accessors which will cache
+ // results.
+ //------------------------------------------------------------------
+ bool SendRequestVersion();
+
+ bool SendRequestHostInfo();
+
+ bool SendRequestKernelVersion();
+
+ // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
+ // bool
+ // SendRequestImagePath ();
+
+ void DumpPacket(lldb_private::Stream &s, const void *data, uint32_t data_len);
+
+ void DumpPacket(lldb_private::Stream &s,
+ const lldb_private::DataExtractor &extractor);
+
+ bool VersionIsValid() const { return m_kdp_version_version != 0; }
+
+ bool HostInfoIsValid() const { return m_kdp_hostinfo_cpu_type != 0; }
+
+ bool ExtractIsReply(uint8_t first_packet_byte) const {
+ // TODO: handle big endian...
+ return (first_packet_byte & ePacketTypeMask) != 0;
+ }
+
+ CommandType ExtractCommand(uint8_t first_packet_byte) const {
+ // TODO: handle big endian...
+ return (CommandType)(first_packet_byte & eCommandTypeMask);
+ }
+
+ static const char *GetCommandAsCString(uint8_t command);
+
+ void ClearKDPSettings();
+
+ bool SendRequestAndGetReply(const CommandType command,
+ const PacketStreamType &request_packet,
+ lldb_private::DataExtractor &reply_packet);
+ //------------------------------------------------------------------
+ // Classes that inherit from CommunicationKDP can see and modify these
+ //------------------------------------------------------------------
+ uint32_t m_addr_byte_size;
+ lldb::ByteOrder m_byte_order;
+ std::chrono::seconds m_packet_timeout;
+ std::recursive_mutex m_sequence_mutex; // Restrict access to sending/receiving
+ // packets to a single thread at a time
+ lldb_private::Predicate<bool> m_is_running;
+ uint32_t m_session_key;
+ uint8_t m_request_sequence_id;
+ uint8_t m_exception_sequence_id;
+ uint32_t m_kdp_version_version;
+ uint32_t m_kdp_version_feature;
+ uint32_t m_kdp_hostinfo_cpu_mask;
+ uint32_t m_kdp_hostinfo_cpu_type;
+ uint32_t m_kdp_hostinfo_cpu_subtype;
+ std::string m_kernel_version;
+ // std::string m_image_path; // Disable KDP_IMAGEPATH for now, it seems to
+ // hang the KDP connection...
+ lldb::addr_t m_last_read_memory_addr; // Last memory read address for logging
private:
- //------------------------------------------------------------------
- // For CommunicationKDP only
- //------------------------------------------------------------------
- DISALLOW_COPY_AND_ASSIGN (CommunicationKDP);
+ //------------------------------------------------------------------
+ // For CommunicationKDP only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN(CommunicationKDP);
};
-#endif // liblldb_CommunicationKDP_h_
+#endif // liblldb_CommunicationKDP_h_
diff --git a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
index 898677df616b..dae33f6257d1 100644
--- a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
@@ -16,9 +16,9 @@
// Other libraries and framework includes
#include "lldb/Core/Debugger.h"
-#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/PluginManager.h"
#include "lldb/Core/State.h"
#include "lldb/Core/UUID.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
@@ -42,1168 +42,1002 @@
#define USEC_PER_SEC 1000000
// Project includes
+#include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h"
+#include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h"
#include "ProcessKDP.h"
#include "ProcessKDPLog.h"
#include "ThreadKDP.h"
-#include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h"
-#include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h"
using namespace lldb;
using namespace lldb_private;
namespace {
- static PropertyDefinition
- g_properties[] =
- {
- { "packet-timeout" , OptionValue::eTypeUInt64 , true , 5, NULL, NULL, "Specify the default packet timeout in seconds." },
- { NULL , OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL }
- };
-
- enum
- {
- ePropertyPacketTimeout
- };
-
- class PluginProperties : public Properties
- {
- public:
-
- static ConstString
- GetSettingName ()
- {
- return ProcessKDP::GetPluginNameStatic();
- }
+static PropertyDefinition g_properties[] = {
+ {"packet-timeout", OptionValue::eTypeUInt64, true, 5, NULL, NULL,
+ "Specify the default packet timeout in seconds."},
+ {NULL, OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL}};
- PluginProperties() :
- Properties ()
- {
- m_collection_sp.reset (new OptionValueProperties(GetSettingName()));
- m_collection_sp->Initialize(g_properties);
- }
-
- virtual
- ~PluginProperties()
- {
- }
-
- uint64_t
- GetPacketTimeout()
- {
- const uint32_t idx = ePropertyPacketTimeout;
- return m_collection_sp->GetPropertyAtIndexAsUInt64(NULL, idx, g_properties[idx].default_uint_value);
- }
- };
+enum { ePropertyPacketTimeout };
- typedef std::shared_ptr<PluginProperties> ProcessKDPPropertiesSP;
+class PluginProperties : public Properties {
+public:
+ static ConstString GetSettingName() {
+ return ProcessKDP::GetPluginNameStatic();
+ }
+
+ PluginProperties() : Properties() {
+ m_collection_sp.reset(new OptionValueProperties(GetSettingName()));
+ m_collection_sp->Initialize(g_properties);
+ }
+
+ virtual ~PluginProperties() {}
+
+ uint64_t GetPacketTimeout() {
+ const uint32_t idx = ePropertyPacketTimeout;
+ return m_collection_sp->GetPropertyAtIndexAsUInt64(
+ NULL, idx, g_properties[idx].default_uint_value);
+ }
+};
+
+typedef std::shared_ptr<PluginProperties> ProcessKDPPropertiesSP;
+
+static const ProcessKDPPropertiesSP &GetGlobalPluginProperties() {
+ static ProcessKDPPropertiesSP g_settings_sp;
+ if (!g_settings_sp)
+ g_settings_sp.reset(new PluginProperties());
+ return g_settings_sp;
+}
- static const ProcessKDPPropertiesSP &
- GetGlobalPluginProperties()
- {
- static ProcessKDPPropertiesSP g_settings_sp;
- if (!g_settings_sp)
- g_settings_sp.reset (new PluginProperties ());
- return g_settings_sp;
- }
-
} // anonymous namespace end
static const lldb::tid_t g_kernel_tid = 1;
-ConstString
-ProcessKDP::GetPluginNameStatic()
-{
- static ConstString g_name("kdp-remote");
- return g_name;
+ConstString ProcessKDP::GetPluginNameStatic() {
+ static ConstString g_name("kdp-remote");
+ return g_name;
}
-const char *
-ProcessKDP::GetPluginDescriptionStatic()
-{
- return "KDP Remote protocol based debugging plug-in for darwin kernel debugging.";
+const char *ProcessKDP::GetPluginDescriptionStatic() {
+ return "KDP Remote protocol based debugging plug-in for darwin kernel "
+ "debugging.";
}
-void
-ProcessKDP::Terminate()
-{
- PluginManager::UnregisterPlugin (ProcessKDP::CreateInstance);
+void ProcessKDP::Terminate() {
+ PluginManager::UnregisterPlugin(ProcessKDP::CreateInstance);
}
-
-lldb::ProcessSP
-ProcessKDP::CreateInstance (TargetSP target_sp,
- ListenerSP listener_sp,
- const FileSpec *crash_file_path)
-{
- lldb::ProcessSP process_sp;
- if (crash_file_path == NULL)
- process_sp.reset(new ProcessKDP (target_sp, listener_sp));
- return process_sp;
+lldb::ProcessSP ProcessKDP::CreateInstance(TargetSP target_sp,
+ ListenerSP listener_sp,
+ const FileSpec *crash_file_path) {
+ lldb::ProcessSP process_sp;
+ if (crash_file_path == NULL)
+ process_sp.reset(new ProcessKDP(target_sp, listener_sp));
+ return process_sp;
}
-bool
-ProcessKDP::CanDebug(TargetSP target_sp, bool plugin_specified_by_name)
-{
- if (plugin_specified_by_name)
- return true;
-
- // For now we are just making sure the file exists for a given module
- Module *exe_module = target_sp->GetExecutableModulePointer();
- if (exe_module)
- {
- const llvm::Triple &triple_ref = target_sp->GetArchitecture().GetTriple();
- switch (triple_ref.getOS())
- {
- case llvm::Triple::Darwin: // Should use "macosx" for desktop and "ios" for iOS, but accept darwin just in case
- case llvm::Triple::MacOSX: // For desktop targets
- case llvm::Triple::IOS: // For arm targets
- case llvm::Triple::TvOS:
- case llvm::Triple::WatchOS:
- if (triple_ref.getVendor() == llvm::Triple::Apple)
- {
- ObjectFile *exe_objfile = exe_module->GetObjectFile();
- if (exe_objfile->GetType() == ObjectFile::eTypeExecutable &&
- exe_objfile->GetStrata() == ObjectFile::eStrataKernel)
- return true;
- }
- break;
-
- default:
- break;
- }
+bool ProcessKDP::CanDebug(TargetSP target_sp, bool plugin_specified_by_name) {
+ if (plugin_specified_by_name)
+ return true;
+
+ // For now we are just making sure the file exists for a given module
+ Module *exe_module = target_sp->GetExecutableModulePointer();
+ if (exe_module) {
+ const llvm::Triple &triple_ref = target_sp->GetArchitecture().GetTriple();
+ switch (triple_ref.getOS()) {
+ case llvm::Triple::Darwin: // Should use "macosx" for desktop and "ios" for
+ // iOS, but accept darwin just in case
+ case llvm::Triple::MacOSX: // For desktop targets
+ case llvm::Triple::IOS: // For arm targets
+ case llvm::Triple::TvOS:
+ case llvm::Triple::WatchOS:
+ if (triple_ref.getVendor() == llvm::Triple::Apple) {
+ ObjectFile *exe_objfile = exe_module->GetObjectFile();
+ if (exe_objfile->GetType() == ObjectFile::eTypeExecutable &&
+ exe_objfile->GetStrata() == ObjectFile::eStrataKernel)
+ return true;
+ }
+ break;
+
+ default:
+ break;
}
- return false;
+ }
+ return false;
}
//----------------------------------------------------------------------
// ProcessKDP constructor
//----------------------------------------------------------------------
-ProcessKDP::ProcessKDP(TargetSP target_sp, ListenerSP listener_sp) :
- Process (target_sp, listener_sp),
- m_comm("lldb.process.kdp-remote.communication"),
- m_async_broadcaster (NULL, "lldb.process.kdp-remote.async-broadcaster"),
- m_dyld_plugin_name (),
- m_kernel_load_addr (LLDB_INVALID_ADDRESS),
- m_command_sp(),
- m_kernel_thread_wp()
-{
- m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadShouldExit, "async thread should exit");
- m_async_broadcaster.SetEventName (eBroadcastBitAsyncContinue, "async thread continue");
- const uint64_t timeout_seconds = GetGlobalPluginProperties()->GetPacketTimeout();
- if (timeout_seconds > 0)
- m_comm.SetPacketTimeout(timeout_seconds);
+ProcessKDP::ProcessKDP(TargetSP target_sp, ListenerSP listener_sp)
+ : Process(target_sp, listener_sp),
+ m_comm("lldb.process.kdp-remote.communication"),
+ m_async_broadcaster(NULL, "lldb.process.kdp-remote.async-broadcaster"),
+ m_dyld_plugin_name(), m_kernel_load_addr(LLDB_INVALID_ADDRESS),
+ m_command_sp(), m_kernel_thread_wp() {
+ m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit,
+ "async thread should exit");
+ m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue,
+ "async thread continue");
+ const uint64_t timeout_seconds =
+ GetGlobalPluginProperties()->GetPacketTimeout();
+ if (timeout_seconds > 0)
+ m_comm.SetPacketTimeout(std::chrono::seconds(timeout_seconds));
}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-ProcessKDP::~ProcessKDP()
-{
- Clear();
- // We need to call finalize on the process before destroying ourselves
- // to make sure all of the broadcaster cleanup goes as planned. If we
- // destruct this class, then Process::~Process() might have problems
- // trying to fully destroy the broadcaster.
- Finalize();
+ProcessKDP::~ProcessKDP() {
+ Clear();
+ // We need to call finalize on the process before destroying ourselves
+ // to make sure all of the broadcaster cleanup goes as planned. If we
+ // destruct this class, then Process::~Process() might have problems
+ // trying to fully destroy the broadcaster.
+ Finalize();
}
//----------------------------------------------------------------------
// PluginInterface
//----------------------------------------------------------------------
-lldb_private::ConstString
-ProcessKDP::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString ProcessKDP::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-ProcessKDP::GetPluginVersion()
-{
- return 1;
-}
+uint32_t ProcessKDP::GetPluginVersion() { return 1; }
-Error
-ProcessKDP::WillLaunch (Module* module)
-{
- Error error;
- error.SetErrorString ("launching not supported in kdp-remote plug-in");
- return error;
+Error ProcessKDP::WillLaunch(Module *module) {
+ Error error;
+ error.SetErrorString("launching not supported in kdp-remote plug-in");
+ return error;
}
-Error
-ProcessKDP::WillAttachToProcessWithID (lldb::pid_t pid)
-{
- Error error;
- error.SetErrorString ("attaching to a by process ID not supported in kdp-remote plug-in");
- return error;
+Error ProcessKDP::WillAttachToProcessWithID(lldb::pid_t pid) {
+ Error error;
+ error.SetErrorString(
+ "attaching to a by process ID not supported in kdp-remote plug-in");
+ return error;
}
-Error
-ProcessKDP::WillAttachToProcessWithName (const char *process_name, bool wait_for_launch)
-{
- Error error;
- error.SetErrorString ("attaching to a by process name not supported in kdp-remote plug-in");
- return error;
+Error ProcessKDP::WillAttachToProcessWithName(const char *process_name,
+ bool wait_for_launch) {
+ Error error;
+ error.SetErrorString(
+ "attaching to a by process name not supported in kdp-remote plug-in");
+ return error;
}
-bool
-ProcessKDP::GetHostArchitecture(ArchSpec &arch)
-{
- uint32_t cpu = m_comm.GetCPUType();
- if (cpu)
- {
- uint32_t sub = m_comm.GetCPUSubtype();
- arch.SetArchitecture(eArchTypeMachO, cpu, sub);
- // Leave architecture vendor as unspecified unknown
- arch.GetTriple().setVendor(llvm::Triple::UnknownVendor);
- arch.GetTriple().setVendorName(llvm::StringRef());
- return true;
- }
- arch.Clear();
- return false;
+bool ProcessKDP::GetHostArchitecture(ArchSpec &arch) {
+ uint32_t cpu = m_comm.GetCPUType();
+ if (cpu) {
+ uint32_t sub = m_comm.GetCPUSubtype();
+ arch.SetArchitecture(eArchTypeMachO, cpu, sub);
+ // Leave architecture vendor as unspecified unknown
+ arch.GetTriple().setVendor(llvm::Triple::UnknownVendor);
+ arch.GetTriple().setVendorName(llvm::StringRef());
+ return true;
+ }
+ arch.Clear();
+ return false;
}
-Error
-ProcessKDP::DoConnectRemote (Stream *strm, const char *remote_url)
-{
- Error error;
-
- // Don't let any JIT happen when doing KDP as we can't allocate
- // memory and we don't want to be mucking with threads that might
- // already be handling exceptions
- SetCanJIT(false);
+Error ProcessKDP::DoConnectRemote(Stream *strm, llvm::StringRef remote_url) {
+ Error error;
- if (remote_url == NULL || remote_url[0] == '\0')
- {
- error.SetErrorStringWithFormat ("invalid connection URL '%s'", remote_url);
- return error;
- }
+ // Don't let any JIT happen when doing KDP as we can't allocate
+ // memory and we don't want to be mucking with threads that might
+ // already be handling exceptions
+ SetCanJIT(false);
- std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
- if (conn_ap.get())
- {
- // Only try once for now.
- // TODO: check if we should be retrying?
- const uint32_t max_retry_count = 1;
- for (uint32_t retry_count = 0; retry_count < max_retry_count; ++retry_count)
- {
- if (conn_ap->Connect(remote_url, &error) == eConnectionStatusSuccess)
- break;
- usleep (100000);
- }
+ if (remote_url.empty()) {
+ error.SetErrorStringWithFormat("empty connection URL");
+ return error;
+ }
+
+ std::unique_ptr<ConnectionFileDescriptor> conn_ap(
+ new ConnectionFileDescriptor());
+ if (conn_ap.get()) {
+ // Only try once for now.
+ // TODO: check if we should be retrying?
+ const uint32_t max_retry_count = 1;
+ for (uint32_t retry_count = 0; retry_count < max_retry_count;
+ ++retry_count) {
+ if (conn_ap->Connect(remote_url, &error) == eConnectionStatusSuccess)
+ break;
+ usleep(100000);
}
-
- if (conn_ap->IsConnected())
- {
- const TCPSocket& socket = static_cast<const TCPSocket&>(*conn_ap->GetReadObject());
- const uint16_t reply_port = socket.GetLocalPortNumber();
-
- if (reply_port != 0)
- {
- m_comm.SetConnection(conn_ap.release());
-
- if (m_comm.SendRequestReattach(reply_port))
- {
- if (m_comm.SendRequestConnect(reply_port, reply_port, "Greetings from LLDB..."))
- {
- m_comm.GetVersion();
-
- Target &target = GetTarget();
- ArchSpec kernel_arch;
- // The host architecture
- GetHostArchitecture(kernel_arch);
- ArchSpec target_arch = target.GetArchitecture();
- // Merge in any unspecified stuff into the target architecture in
- // case the target arch isn't set at all or incompletely.
- target_arch.MergeFrom(kernel_arch);
- target.SetArchitecture(target_arch);
-
- /* Get the kernel's UUID and load address via KDP_KERNELVERSION packet. */
- /* An EFI kdp session has neither UUID nor load address. */
-
- UUID kernel_uuid = m_comm.GetUUID ();
- addr_t kernel_load_addr = m_comm.GetLoadAddress ();
-
- if (m_comm.RemoteIsEFI ())
- {
- // Select an invalid plugin name for the dynamic loader so one doesn't get used
- // since EFI does its own manual loading via python scripting
- static ConstString g_none_dynamic_loader("none");
- m_dyld_plugin_name = g_none_dynamic_loader;
-
- if (kernel_uuid.IsValid()) {
- // If EFI passed in a UUID= try to lookup UUID
- // The slide will not be provided. But the UUID
- // lookup will be used to launch EFI debug scripts
- // from the dSYM, that can load all of the symbols.
- ModuleSpec module_spec;
- module_spec.GetUUID() = kernel_uuid;
- module_spec.GetArchitecture() = target.GetArchitecture();
-
- // Lookup UUID locally, before attempting dsymForUUID like action
- module_spec.GetSymbolFileSpec() = Symbols::LocateExecutableSymbolFile(module_spec);
- if (module_spec.GetSymbolFileSpec())
- {
- ModuleSpec executable_module_spec = Symbols::LocateExecutableObjectFile (module_spec);
- if (executable_module_spec.GetFileSpec().Exists())
- {
- module_spec.GetFileSpec() = executable_module_spec.GetFileSpec();
- }
- }
- if (!module_spec.GetSymbolFileSpec() || !module_spec.GetSymbolFileSpec())
- Symbols::DownloadObjectAndSymbolFile (module_spec, true);
-
- if (module_spec.GetFileSpec().Exists())
- {
- ModuleSP module_sp(new Module (module_spec));
- if (module_sp.get() && module_sp->GetObjectFile())
- {
- // Get the current target executable
- ModuleSP exe_module_sp (target.GetExecutableModule ());
-
- // Make sure you don't already have the right module loaded and they will be uniqued
- if (exe_module_sp.get() != module_sp.get())
- target.SetExecutableModule (module_sp, false);
- }
- }
- }
- }
- else if (m_comm.RemoteIsDarwinKernel ())
- {
- m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
- if (kernel_load_addr != LLDB_INVALID_ADDRESS)
- {
- m_kernel_load_addr = kernel_load_addr;
- }
- }
-
- // Set the thread ID
- UpdateThreadListIfNeeded ();
- SetID (1);
- GetThreadList ();
- SetPrivateState (eStateStopped);
- StreamSP async_strm_sp(target.GetDebugger().GetAsyncOutputStream());
- if (async_strm_sp)
- {
- const char *cstr;
- if ((cstr = m_comm.GetKernelVersion ()) != NULL)
- {
- async_strm_sp->Printf ("Version: %s\n", cstr);
- async_strm_sp->Flush();
- }
-// if ((cstr = m_comm.GetImagePath ()) != NULL)
-// {
-// async_strm_sp->Printf ("Image Path: %s\n", cstr);
-// async_strm_sp->Flush();
-// }
- }
+ }
+
+ if (conn_ap->IsConnected()) {
+ const TCPSocket &socket =
+ static_cast<const TCPSocket &>(*conn_ap->GetReadObject());
+ const uint16_t reply_port = socket.GetLocalPortNumber();
+
+ if (reply_port != 0) {
+ m_comm.SetConnection(conn_ap.release());
+
+ if (m_comm.SendRequestReattach(reply_port)) {
+ if (m_comm.SendRequestConnect(reply_port, reply_port,
+ "Greetings from LLDB...")) {
+ m_comm.GetVersion();
+
+ Target &target = GetTarget();
+ ArchSpec kernel_arch;
+ // The host architecture
+ GetHostArchitecture(kernel_arch);
+ ArchSpec target_arch = target.GetArchitecture();
+ // Merge in any unspecified stuff into the target architecture in
+ // case the target arch isn't set at all or incompletely.
+ target_arch.MergeFrom(kernel_arch);
+ target.SetArchitecture(target_arch);
+
+ /* Get the kernel's UUID and load address via KDP_KERNELVERSION
+ * packet. */
+ /* An EFI kdp session has neither UUID nor load address. */
+
+ UUID kernel_uuid = m_comm.GetUUID();
+ addr_t kernel_load_addr = m_comm.GetLoadAddress();
+
+ if (m_comm.RemoteIsEFI()) {
+ // Select an invalid plugin name for the dynamic loader so one
+ // doesn't get used
+ // since EFI does its own manual loading via python scripting
+ static ConstString g_none_dynamic_loader("none");
+ m_dyld_plugin_name = g_none_dynamic_loader;
+
+ if (kernel_uuid.IsValid()) {
+ // If EFI passed in a UUID= try to lookup UUID
+ // The slide will not be provided. But the UUID
+ // lookup will be used to launch EFI debug scripts
+ // from the dSYM, that can load all of the symbols.
+ ModuleSpec module_spec;
+ module_spec.GetUUID() = kernel_uuid;
+ module_spec.GetArchitecture() = target.GetArchitecture();
+
+ // Lookup UUID locally, before attempting dsymForUUID like action
+ module_spec.GetSymbolFileSpec() =
+ Symbols::LocateExecutableSymbolFile(module_spec);
+ if (module_spec.GetSymbolFileSpec()) {
+ ModuleSpec executable_module_spec =
+ Symbols::LocateExecutableObjectFile(module_spec);
+ if (executable_module_spec.GetFileSpec().Exists()) {
+ module_spec.GetFileSpec() =
+ executable_module_spec.GetFileSpec();
}
- else
- {
- error.SetErrorString("KDP_REATTACH failed");
+ }
+ if (!module_spec.GetSymbolFileSpec() ||
+ !module_spec.GetSymbolFileSpec())
+ Symbols::DownloadObjectAndSymbolFile(module_spec, true);
+
+ if (module_spec.GetFileSpec().Exists()) {
+ ModuleSP module_sp(new Module(module_spec));
+ if (module_sp.get() && module_sp->GetObjectFile()) {
+ // Get the current target executable
+ ModuleSP exe_module_sp(target.GetExecutableModule());
+
+ // Make sure you don't already have the right module loaded
+ // and they will be uniqued
+ if (exe_module_sp.get() != module_sp.get())
+ target.SetExecutableModule(module_sp, false);
}
+ }
}
- else
- {
- error.SetErrorString("KDP_REATTACH failed");
+ } else if (m_comm.RemoteIsDarwinKernel()) {
+ m_dyld_plugin_name =
+ DynamicLoaderDarwinKernel::GetPluginNameStatic();
+ if (kernel_load_addr != LLDB_INVALID_ADDRESS) {
+ m_kernel_load_addr = kernel_load_addr;
}
+ }
+
+ // Set the thread ID
+ UpdateThreadListIfNeeded();
+ SetID(1);
+ GetThreadList();
+ SetPrivateState(eStateStopped);
+ StreamSP async_strm_sp(target.GetDebugger().GetAsyncOutputStream());
+ if (async_strm_sp) {
+ const char *cstr;
+ if ((cstr = m_comm.GetKernelVersion()) != NULL) {
+ async_strm_sp->Printf("Version: %s\n", cstr);
+ async_strm_sp->Flush();
+ }
+ // if ((cstr = m_comm.GetImagePath ()) != NULL)
+ // {
+ // async_strm_sp->Printf ("Image Path:
+ // %s\n", cstr);
+ // async_strm_sp->Flush();
+ // }
+ }
+ } else {
+ error.SetErrorString("KDP_REATTACH failed");
}
- else
- {
- error.SetErrorString("invalid reply port from UDP connection");
- }
- }
- else
- {
- if (error.Success())
- error.SetErrorStringWithFormat ("failed to connect to '%s'", remote_url);
+ } else {
+ error.SetErrorString("KDP_REATTACH failed");
+ }
+ } else {
+ error.SetErrorString("invalid reply port from UDP connection");
}
- if (error.Fail())
- m_comm.Disconnect();
-
- return error;
+ } else {
+ if (error.Success())
+ error.SetErrorStringWithFormat("failed to connect to '%s'",
+ remote_url.str().c_str());
+ }
+ if (error.Fail())
+ m_comm.Disconnect();
+
+ return error;
}
//----------------------------------------------------------------------
// Process Control
//----------------------------------------------------------------------
-Error
-ProcessKDP::DoLaunch (Module *exe_module,
- ProcessLaunchInfo &launch_info)
-{
- Error error;
- error.SetErrorString ("launching not supported in kdp-remote plug-in");
- return error;
+Error ProcessKDP::DoLaunch(Module *exe_module, ProcessLaunchInfo &launch_info) {
+ Error error;
+ error.SetErrorString("launching not supported in kdp-remote plug-in");
+ return error;
}
-Error
-ProcessKDP::DoAttachToProcessWithID (lldb::pid_t attach_pid, const ProcessAttachInfo &attach_info)
-{
- Error error;
- error.SetErrorString ("attach to process by ID is not suppported in kdp remote debugging");
- return error;
+Error ProcessKDP::DoAttachToProcessWithID(
+ lldb::pid_t attach_pid, const ProcessAttachInfo &attach_info) {
+ Error error;
+ error.SetErrorString(
+ "attach to process by ID is not suppported in kdp remote debugging");
+ return error;
}
-Error
-ProcessKDP::DoAttachToProcessWithName (const char *process_name, const ProcessAttachInfo &attach_info)
-{
- Error error;
- error.SetErrorString ("attach to process by name is not suppported in kdp remote debugging");
- return error;
+Error ProcessKDP::DoAttachToProcessWithName(
+ const char *process_name, const ProcessAttachInfo &attach_info) {
+ Error error;
+ error.SetErrorString(
+ "attach to process by name is not suppported in kdp remote debugging");
+ return error;
}
+void ProcessKDP::DidAttach(ArchSpec &process_arch) {
+ Process::DidAttach(process_arch);
-void
-ProcessKDP::DidAttach (ArchSpec &process_arch)
-{
- Process::DidAttach(process_arch);
-
- Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS));
- if (log)
- log->Printf ("ProcessKDP::DidAttach()");
- if (GetID() != LLDB_INVALID_PROCESS_ID)
- {
- GetHostArchitecture(process_arch);
- }
+ Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
+ if (log)
+ log->Printf("ProcessKDP::DidAttach()");
+ if (GetID() != LLDB_INVALID_PROCESS_ID) {
+ GetHostArchitecture(process_arch);
+ }
}
-addr_t
-ProcessKDP::GetImageInfoAddress()
-{
- return m_kernel_load_addr;
-}
+addr_t ProcessKDP::GetImageInfoAddress() { return m_kernel_load_addr; }
-lldb_private::DynamicLoader *
-ProcessKDP::GetDynamicLoader ()
-{
- if (m_dyld_ap.get() == NULL)
- m_dyld_ap.reset (DynamicLoader::FindPlugin(this, m_dyld_plugin_name.IsEmpty() ? NULL : m_dyld_plugin_name.GetCString()));
- return m_dyld_ap.get();
+lldb_private::DynamicLoader *ProcessKDP::GetDynamicLoader() {
+ if (m_dyld_ap.get() == NULL)
+ m_dyld_ap.reset(DynamicLoader::FindPlugin(
+ this,
+ m_dyld_plugin_name.IsEmpty() ? NULL : m_dyld_plugin_name.GetCString()));
+ return m_dyld_ap.get();
}
-Error
-ProcessKDP::WillResume ()
-{
- return Error();
-}
+Error ProcessKDP::WillResume() { return Error(); }
-Error
-ProcessKDP::DoResume ()
-{
- Error error;
- Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS));
- // Only start the async thread if we try to do any process control
- if (!m_async_thread.IsJoinable())
- StartAsyncThread();
-
- bool resume = false;
-
- // With KDP there is only one thread we can tell what to do
- ThreadSP kernel_thread_sp (m_thread_list.FindThreadByProtocolID(g_kernel_tid));
-
- if (kernel_thread_sp)
- {
- const StateType thread_resume_state = kernel_thread_sp->GetTemporaryResumeState();
-
- if (log)
- log->Printf ("ProcessKDP::DoResume() thread_resume_state = %s", StateAsCString(thread_resume_state));
- switch (thread_resume_state)
- {
- case eStateSuspended:
- // Nothing to do here when a thread will stay suspended
- // we just leave the CPU mask bit set to zero for the thread
- if (log)
- log->Printf ("ProcessKDP::DoResume() = suspended???");
- break;
-
- case eStateStepping:
- {
- lldb::RegisterContextSP reg_ctx_sp (kernel_thread_sp->GetRegisterContext());
-
- if (reg_ctx_sp)
- {
- if (log)
- log->Printf ("ProcessKDP::DoResume () reg_ctx_sp->HardwareSingleStep (true);");
- reg_ctx_sp->HardwareSingleStep (true);
- resume = true;
- }
- else
- {
- error.SetErrorStringWithFormat("KDP thread 0x%llx has no register context", kernel_thread_sp->GetID());
- }
- }
- break;
-
- case eStateRunning:
- {
- lldb::RegisterContextSP reg_ctx_sp (kernel_thread_sp->GetRegisterContext());
-
- if (reg_ctx_sp)
- {
- if (log)
- log->Printf ("ProcessKDP::DoResume () reg_ctx_sp->HardwareSingleStep (false);");
- reg_ctx_sp->HardwareSingleStep (false);
- resume = true;
- }
- else
- {
- error.SetErrorStringWithFormat("KDP thread 0x%llx has no register context", kernel_thread_sp->GetID());
- }
- }
- break;
+Error ProcessKDP::DoResume() {
+ Error error;
+ Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
+ // Only start the async thread if we try to do any process control
+ if (!m_async_thread.IsJoinable())
+ StartAsyncThread();
- default:
- // The only valid thread resume states are listed above
- assert (!"invalid thread resume state");
- break;
- }
- }
+ bool resume = false;
+
+ // With KDP there is only one thread we can tell what to do
+ ThreadSP kernel_thread_sp(m_thread_list.FindThreadByProtocolID(g_kernel_tid));
+
+ if (kernel_thread_sp) {
+ const StateType thread_resume_state =
+ kernel_thread_sp->GetTemporaryResumeState();
- if (resume)
- {
+ if (log)
+ log->Printf("ProcessKDP::DoResume() thread_resume_state = %s",
+ StateAsCString(thread_resume_state));
+ switch (thread_resume_state) {
+ case eStateSuspended:
+ // Nothing to do here when a thread will stay suspended
+ // we just leave the CPU mask bit set to zero for the thread
+ if (log)
+ log->Printf("ProcessKDP::DoResume() = suspended???");
+ break;
+
+ case eStateStepping: {
+ lldb::RegisterContextSP reg_ctx_sp(
+ kernel_thread_sp->GetRegisterContext());
+
+ if (reg_ctx_sp) {
if (log)
- log->Printf ("ProcessKDP::DoResume () sending resume");
-
- if (m_comm.SendRequestResume ())
- {
- m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue);
- SetPrivateState(eStateRunning);
- }
- else
- error.SetErrorString ("KDP resume failed");
- }
- else
- {
- error.SetErrorString ("kernel thread is suspended");
+ log->Printf(
+ "ProcessKDP::DoResume () reg_ctx_sp->HardwareSingleStep (true);");
+ reg_ctx_sp->HardwareSingleStep(true);
+ resume = true;
+ } else {
+ error.SetErrorStringWithFormat(
+ "KDP thread 0x%llx has no register context",
+ kernel_thread_sp->GetID());
+ }
+ } break;
+
+ case eStateRunning: {
+ lldb::RegisterContextSP reg_ctx_sp(
+ kernel_thread_sp->GetRegisterContext());
+
+ if (reg_ctx_sp) {
+ if (log)
+ log->Printf("ProcessKDP::DoResume () reg_ctx_sp->HardwareSingleStep "
+ "(false);");
+ reg_ctx_sp->HardwareSingleStep(false);
+ resume = true;
+ } else {
+ error.SetErrorStringWithFormat(
+ "KDP thread 0x%llx has no register context",
+ kernel_thread_sp->GetID());
+ }
+ } break;
+
+ default:
+ // The only valid thread resume states are listed above
+ assert(!"invalid thread resume state");
+ break;
}
-
- return error;
-}
+ }
-lldb::ThreadSP
-ProcessKDP::GetKernelThread()
-{
- // KDP only tells us about one thread/core. Any other threads will usually
- // be the ones that are read from memory by the OS plug-ins.
-
- ThreadSP thread_sp (m_kernel_thread_wp.lock());
- if (!thread_sp)
- {
- thread_sp.reset(new ThreadKDP (*this, g_kernel_tid));
- m_kernel_thread_wp = thread_sp;
- }
- return thread_sp;
+ if (resume) {
+ if (log)
+ log->Printf("ProcessKDP::DoResume () sending resume");
+
+ if (m_comm.SendRequestResume()) {
+ m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue);
+ SetPrivateState(eStateRunning);
+ } else
+ error.SetErrorString("KDP resume failed");
+ } else {
+ error.SetErrorString("kernel thread is suspended");
+ }
+
+ return error;
}
+lldb::ThreadSP ProcessKDP::GetKernelThread() {
+ // KDP only tells us about one thread/core. Any other threads will usually
+ // be the ones that are read from memory by the OS plug-ins.
+ ThreadSP thread_sp(m_kernel_thread_wp.lock());
+ if (!thread_sp) {
+ thread_sp.reset(new ThreadKDP(*this, g_kernel_tid));
+ m_kernel_thread_wp = thread_sp;
+ }
+ return thread_sp;
+}
-
-bool
-ProcessKDP::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
-{
- // locker will keep a mutex locked until it goes out of scope
- Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_THREAD));
- if (log && log->GetMask().Test(KDP_LOG_VERBOSE))
- log->Printf ("ProcessKDP::%s (pid = %" PRIu64 ")", __FUNCTION__, GetID());
-
- // Even though there is a CPU mask, it doesn't mean we can see each CPU
- // individually, there is really only one. Lets call this thread 1.
- ThreadSP thread_sp (old_thread_list.FindThreadByProtocolID(g_kernel_tid, false));
- if (!thread_sp)
- thread_sp = GetKernelThread ();
- new_thread_list.AddThread(thread_sp);
-
- return new_thread_list.GetSize(false) > 0;
+bool ProcessKDP::UpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) {
+ // locker will keep a mutex locked until it goes out of scope
+ Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_THREAD));
+ if (log && log->GetMask().Test(KDP_LOG_VERBOSE))
+ log->Printf("ProcessKDP::%s (pid = %" PRIu64 ")", __FUNCTION__, GetID());
+
+ // Even though there is a CPU mask, it doesn't mean we can see each CPU
+ // individually, there is really only one. Lets call this thread 1.
+ ThreadSP thread_sp(
+ old_thread_list.FindThreadByProtocolID(g_kernel_tid, false));
+ if (!thread_sp)
+ thread_sp = GetKernelThread();
+ new_thread_list.AddThread(thread_sp);
+
+ return new_thread_list.GetSize(false) > 0;
}
-void
-ProcessKDP::RefreshStateAfterStop ()
-{
- // Let all threads recover from stopping and do any clean up based
- // on the previous thread state (if any).
- m_thread_list.RefreshStateAfterStop();
+void ProcessKDP::RefreshStateAfterStop() {
+ // Let all threads recover from stopping and do any clean up based
+ // on the previous thread state (if any).
+ m_thread_list.RefreshStateAfterStop();
}
-Error
-ProcessKDP::DoHalt (bool &caused_stop)
-{
- Error error;
-
- if (m_comm.IsRunning())
- {
- if (m_destroy_in_process)
- {
- // If we are attemping to destroy, we need to not return an error to
- // Halt or DoDestroy won't get called.
- // We are also currently running, so send a process stopped event
- SetPrivateState (eStateStopped);
- }
- else
- {
- error.SetErrorString ("KDP cannot interrupt a running kernel");
- }
+Error ProcessKDP::DoHalt(bool &caused_stop) {
+ Error error;
+
+ if (m_comm.IsRunning()) {
+ if (m_destroy_in_process) {
+ // If we are attemping to destroy, we need to not return an error to
+ // Halt or DoDestroy won't get called.
+ // We are also currently running, so send a process stopped event
+ SetPrivateState(eStateStopped);
+ } else {
+ error.SetErrorString("KDP cannot interrupt a running kernel");
}
- return error;
+ }
+ return error;
}
-Error
-ProcessKDP::DoDetach(bool keep_stopped)
-{
- Error error;
- Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
- if (log)
- log->Printf ("ProcessKDP::DoDetach(keep_stopped = %i)", keep_stopped);
-
- if (m_comm.IsRunning())
- {
- // We are running and we can't interrupt a running kernel, so we need
- // to just close the connection to the kernel and hope for the best
- }
- else
- {
- // If we are going to keep the target stopped, then don't send the disconnect message.
- if (!keep_stopped && m_comm.IsConnected())
- {
- const bool success = m_comm.SendRequestDisconnect();
- if (log)
- {
- if (success)
- log->PutCString ("ProcessKDP::DoDetach() detach packet sent successfully");
- else
- log->PutCString ("ProcessKDP::DoDetach() connection channel shutdown failed");
- }
- m_comm.Disconnect ();
- }
+Error ProcessKDP::DoDetach(bool keep_stopped) {
+ Error error;
+ Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
+ if (log)
+ log->Printf("ProcessKDP::DoDetach(keep_stopped = %i)", keep_stopped);
+
+ if (m_comm.IsRunning()) {
+ // We are running and we can't interrupt a running kernel, so we need
+ // to just close the connection to the kernel and hope for the best
+ } else {
+ // If we are going to keep the target stopped, then don't send the
+ // disconnect message.
+ if (!keep_stopped && m_comm.IsConnected()) {
+ const bool success = m_comm.SendRequestDisconnect();
+ if (log) {
+ if (success)
+ log->PutCString(
+ "ProcessKDP::DoDetach() detach packet sent successfully");
+ else
+ log->PutCString(
+ "ProcessKDP::DoDetach() connection channel shutdown failed");
+ }
+ m_comm.Disconnect();
}
- StopAsyncThread ();
- m_comm.Clear();
-
- SetPrivateState (eStateDetached);
- ResumePrivateStateThread();
-
- //KillDebugserverProcess ();
- return error;
+ }
+ StopAsyncThread();
+ m_comm.Clear();
+
+ SetPrivateState(eStateDetached);
+ ResumePrivateStateThread();
+
+ // KillDebugserverProcess ();
+ return error;
}
-Error
-ProcessKDP::DoDestroy ()
-{
- // For KDP there really is no difference between destroy and detach
- bool keep_stopped = false;
- return DoDetach(keep_stopped);
+Error ProcessKDP::DoDestroy() {
+ // For KDP there really is no difference between destroy and detach
+ bool keep_stopped = false;
+ return DoDetach(keep_stopped);
}
//------------------------------------------------------------------
// Process Queries
//------------------------------------------------------------------
-bool
-ProcessKDP::IsAlive ()
-{
- return m_comm.IsConnected() && Process::IsAlive();
+bool ProcessKDP::IsAlive() {
+ return m_comm.IsConnected() && Process::IsAlive();
}
//------------------------------------------------------------------
// Process Memory
//------------------------------------------------------------------
-size_t
-ProcessKDP::DoReadMemory (addr_t addr, void *buf, size_t size, Error &error)
-{
- uint8_t *data_buffer = (uint8_t *) buf;
- if (m_comm.IsConnected())
- {
- const size_t max_read_size = 512;
- size_t total_bytes_read = 0;
-
- // Read the requested amount of memory in 512 byte chunks
- while (total_bytes_read < size)
- {
- size_t bytes_to_read_this_request = size - total_bytes_read;
- if (bytes_to_read_this_request > max_read_size)
- {
- bytes_to_read_this_request = max_read_size;
- }
- size_t bytes_read = m_comm.SendRequestReadMemory (addr + total_bytes_read,
- data_buffer + total_bytes_read,
- bytes_to_read_this_request, error);
- total_bytes_read += bytes_read;
- if (error.Fail() || bytes_read == 0)
- {
- return total_bytes_read;
- }
- }
-
+size_t ProcessKDP::DoReadMemory(addr_t addr, void *buf, size_t size,
+ Error &error) {
+ uint8_t *data_buffer = (uint8_t *)buf;
+ if (m_comm.IsConnected()) {
+ const size_t max_read_size = 512;
+ size_t total_bytes_read = 0;
+
+ // Read the requested amount of memory in 512 byte chunks
+ while (total_bytes_read < size) {
+ size_t bytes_to_read_this_request = size - total_bytes_read;
+ if (bytes_to_read_this_request > max_read_size) {
+ bytes_to_read_this_request = max_read_size;
+ }
+ size_t bytes_read = m_comm.SendRequestReadMemory(
+ addr + total_bytes_read, data_buffer + total_bytes_read,
+ bytes_to_read_this_request, error);
+ total_bytes_read += bytes_read;
+ if (error.Fail() || bytes_read == 0) {
return total_bytes_read;
+ }
}
- error.SetErrorString ("not connected");
- return 0;
-}
-size_t
-ProcessKDP::DoWriteMemory (addr_t addr, const void *buf, size_t size, Error &error)
-{
- if (m_comm.IsConnected())
- return m_comm.SendRequestWriteMemory (addr, buf, size, error);
- error.SetErrorString ("not connected");
- return 0;
+ return total_bytes_read;
+ }
+ error.SetErrorString("not connected");
+ return 0;
}
-lldb::addr_t
-ProcessKDP::DoAllocateMemory (size_t size, uint32_t permissions, Error &error)
-{
- error.SetErrorString ("memory allocation not suppported in kdp remote debugging");
- return LLDB_INVALID_ADDRESS;
+size_t ProcessKDP::DoWriteMemory(addr_t addr, const void *buf, size_t size,
+ Error &error) {
+ if (m_comm.IsConnected())
+ return m_comm.SendRequestWriteMemory(addr, buf, size, error);
+ error.SetErrorString("not connected");
+ return 0;
}
-Error
-ProcessKDP::DoDeallocateMemory (lldb::addr_t addr)
-{
- Error error;
- error.SetErrorString ("memory deallocation not suppported in kdp remote debugging");
- return error;
+lldb::addr_t ProcessKDP::DoAllocateMemory(size_t size, uint32_t permissions,
+ Error &error) {
+ error.SetErrorString(
+ "memory allocation not suppported in kdp remote debugging");
+ return LLDB_INVALID_ADDRESS;
}
-Error
-ProcessKDP::EnableBreakpointSite (BreakpointSite *bp_site)
-{
- if (m_comm.LocalBreakpointsAreSupported ())
- {
- Error error;
- if (!bp_site->IsEnabled())
- {
- if (m_comm.SendRequestBreakpoint(true, bp_site->GetLoadAddress()))
- {
- bp_site->SetEnabled(true);
- bp_site->SetType (BreakpointSite::eExternal);
- }
- else
- {
- error.SetErrorString ("KDP set breakpoint failed");
- }
- }
- return error;
- }
- return EnableSoftwareBreakpoint (bp_site);
+Error ProcessKDP::DoDeallocateMemory(lldb::addr_t addr) {
+ Error error;
+ error.SetErrorString(
+ "memory deallocation not suppported in kdp remote debugging");
+ return error;
}
-Error
-ProcessKDP::DisableBreakpointSite (BreakpointSite *bp_site)
-{
- if (m_comm.LocalBreakpointsAreSupported ())
- {
- Error error;
- if (bp_site->IsEnabled())
- {
- BreakpointSite::Type bp_type = bp_site->GetType();
- if (bp_type == BreakpointSite::eExternal)
- {
- if (m_destroy_in_process && m_comm.IsRunning())
- {
- // We are trying to destroy our connection and we are running
- bp_site->SetEnabled(false);
- }
- else
- {
- if (m_comm.SendRequestBreakpoint(false, bp_site->GetLoadAddress()))
- bp_site->SetEnabled(false);
- else
- error.SetErrorString ("KDP remove breakpoint failed");
- }
- }
- else
- {
- error = DisableSoftwareBreakpoint (bp_site);
- }
- }
- return error;
+Error ProcessKDP::EnableBreakpointSite(BreakpointSite *bp_site) {
+ if (m_comm.LocalBreakpointsAreSupported()) {
+ Error error;
+ if (!bp_site->IsEnabled()) {
+ if (m_comm.SendRequestBreakpoint(true, bp_site->GetLoadAddress())) {
+ bp_site->SetEnabled(true);
+ bp_site->SetType(BreakpointSite::eExternal);
+ } else {
+ error.SetErrorString("KDP set breakpoint failed");
+ }
}
- return DisableSoftwareBreakpoint (bp_site);
+ return error;
+ }
+ return EnableSoftwareBreakpoint(bp_site);
}
-Error
-ProcessKDP::EnableWatchpoint (Watchpoint *wp, bool notify)
-{
+Error ProcessKDP::DisableBreakpointSite(BreakpointSite *bp_site) {
+ if (m_comm.LocalBreakpointsAreSupported()) {
Error error;
- error.SetErrorString ("watchpoints are not suppported in kdp remote debugging");
+ if (bp_site->IsEnabled()) {
+ BreakpointSite::Type bp_type = bp_site->GetType();
+ if (bp_type == BreakpointSite::eExternal) {
+ if (m_destroy_in_process && m_comm.IsRunning()) {
+ // We are trying to destroy our connection and we are running
+ bp_site->SetEnabled(false);
+ } else {
+ if (m_comm.SendRequestBreakpoint(false, bp_site->GetLoadAddress()))
+ bp_site->SetEnabled(false);
+ else
+ error.SetErrorString("KDP remove breakpoint failed");
+ }
+ } else {
+ error = DisableSoftwareBreakpoint(bp_site);
+ }
+ }
return error;
+ }
+ return DisableSoftwareBreakpoint(bp_site);
}
-Error
-ProcessKDP::DisableWatchpoint (Watchpoint *wp, bool notify)
-{
- Error error;
- error.SetErrorString ("watchpoints are not suppported in kdp remote debugging");
- return error;
+Error ProcessKDP::EnableWatchpoint(Watchpoint *wp, bool notify) {
+ Error error;
+ error.SetErrorString(
+ "watchpoints are not suppported in kdp remote debugging");
+ return error;
}
-void
-ProcessKDP::Clear()
-{
- m_thread_list.Clear();
+Error ProcessKDP::DisableWatchpoint(Watchpoint *wp, bool notify) {
+ Error error;
+ error.SetErrorString(
+ "watchpoints are not suppported in kdp remote debugging");
+ return error;
}
-Error
-ProcessKDP::DoSignal (int signo)
-{
- Error error;
- error.SetErrorString ("sending signals is not suppported in kdp remote debugging");
- return error;
+void ProcessKDP::Clear() { m_thread_list.Clear(); }
+
+Error ProcessKDP::DoSignal(int signo) {
+ Error error;
+ error.SetErrorString(
+ "sending signals is not suppported in kdp remote debugging");
+ return error;
}
-void
-ProcessKDP::Initialize()
-{
- static std::once_flag g_once_flag;
-
- std::call_once(g_once_flag, []()
- {
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance,
- DebuggerInitialize);
-
- Log::Callbacks log_callbacks = {
- ProcessKDPLog::DisableLog,
- ProcessKDPLog::EnableLog,
- ProcessKDPLog::ListLogCategories
- };
-
- Log::RegisterLogChannel (ProcessKDP::GetPluginNameStatic(), log_callbacks);
- });
+void ProcessKDP::Initialize() {
+ static std::once_flag g_once_flag;
+
+ std::call_once(g_once_flag, []() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance,
+ DebuggerInitialize);
+
+ Log::Callbacks log_callbacks = {ProcessKDPLog::DisableLog,
+ ProcessKDPLog::EnableLog,
+ ProcessKDPLog::ListLogCategories};
+
+ Log::RegisterLogChannel(ProcessKDP::GetPluginNameStatic(), log_callbacks);
+ });
}
-void
-ProcessKDP::DebuggerInitialize (lldb_private::Debugger &debugger)
-{
- if (!PluginManager::GetSettingForProcessPlugin(debugger, PluginProperties::GetSettingName()))
- {
- const bool is_global_setting = true;
- PluginManager::CreateSettingForProcessPlugin (debugger,
- GetGlobalPluginProperties()->GetValueProperties(),
- ConstString ("Properties for the kdp-remote process plug-in."),
- is_global_setting);
- }
+void ProcessKDP::DebuggerInitialize(lldb_private::Debugger &debugger) {
+ if (!PluginManager::GetSettingForProcessPlugin(
+ debugger, PluginProperties::GetSettingName())) {
+ const bool is_global_setting = true;
+ PluginManager::CreateSettingForProcessPlugin(
+ debugger, GetGlobalPluginProperties()->GetValueProperties(),
+ ConstString("Properties for the kdp-remote process plug-in."),
+ is_global_setting);
+ }
}
-bool
-ProcessKDP::StartAsyncThread ()
-{
- Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
-
- if (log)
- log->Printf ("ProcessKDP::StartAsyncThread ()");
+bool ProcessKDP::StartAsyncThread() {
+ Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
- if (m_async_thread.IsJoinable())
- return true;
+ if (log)
+ log->Printf("ProcessKDP::StartAsyncThread ()");
- m_async_thread = ThreadLauncher::LaunchThread("<lldb.process.kdp-remote.async>", ProcessKDP::AsyncThread, this, NULL);
- return m_async_thread.IsJoinable();
-}
+ if (m_async_thread.IsJoinable())
+ return true;
-void
-ProcessKDP::StopAsyncThread ()
-{
- Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
-
- if (log)
- log->Printf ("ProcessKDP::StopAsyncThread ()");
-
- m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncThreadShouldExit);
-
- // Stop the stdio thread
- if (m_async_thread.IsJoinable())
- m_async_thread.Join(nullptr);
+ m_async_thread = ThreadLauncher::LaunchThread(
+ "<lldb.process.kdp-remote.async>", ProcessKDP::AsyncThread, this, NULL);
+ return m_async_thread.IsJoinable();
}
+void ProcessKDP::StopAsyncThread() {
+ Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
-void *
-ProcessKDP::AsyncThread (void *arg)
-{
- ProcessKDP *process = (ProcessKDP*) arg;
-
- const lldb::pid_t pid = process->GetID();
+ if (log)
+ log->Printf("ProcessKDP::StopAsyncThread ()");
- Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS));
- if (log)
- log->Printf ("ProcessKDP::AsyncThread (arg = %p, pid = %" PRIu64 ") thread starting...", arg, pid);
-
- ListenerSP listener_sp (Listener::MakeListener("ProcessKDP::AsyncThread"));
- EventSP event_sp;
- const uint32_t desired_event_mask = eBroadcastBitAsyncContinue |
- eBroadcastBitAsyncThreadShouldExit;
-
-
- if (listener_sp->StartListeningForEvents (&process->m_async_broadcaster, desired_event_mask) == desired_event_mask)
- {
- bool done = false;
- while (!done)
- {
- if (log)
- log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") listener.WaitForEvent (NULL, event_sp)...",
- pid);
- if (listener_sp->WaitForEvent (NULL, event_sp))
- {
- uint32_t event_type = event_sp->GetType();
- if (log)
- log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") Got an event of type: %d...",
- pid,
- event_type);
-
- // When we are running, poll for 1 second to try and get an exception
- // to indicate the process has stopped. If we don't get one, check to
- // make sure no one asked us to exit
- bool is_running = false;
- DataExtractor exc_reply_packet;
- do
- {
- switch (event_type)
- {
- case eBroadcastBitAsyncContinue:
- {
- is_running = true;
- if (process->m_comm.WaitForPacketWithTimeoutMicroSeconds (exc_reply_packet, 1 * USEC_PER_SEC))
- {
- ThreadSP thread_sp (process->GetKernelThread());
- if (thread_sp)
- {
- lldb::RegisterContextSP reg_ctx_sp (thread_sp->GetRegisterContext());
- if (reg_ctx_sp)
- reg_ctx_sp->InvalidateAllRegisters();
- static_cast<ThreadKDP *>(thread_sp.get())->SetStopInfoFrom_KDP_EXCEPTION (exc_reply_packet);
- }
-
- // TODO: parse the stop reply packet
- is_running = false;
- process->SetPrivateState(eStateStopped);
- }
- else
- {
- // Check to see if we are supposed to exit. There is no way to
- // interrupt a running kernel, so all we can do is wait for an
- // exception or detach...
- if (listener_sp->GetNextEvent(event_sp))
- {
- // We got an event, go through the loop again
- event_type = event_sp->GetType();
- }
- }
- }
- break;
-
- case eBroadcastBitAsyncThreadShouldExit:
- if (log)
- log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") got eBroadcastBitAsyncThreadShouldExit...",
- pid);
- done = true;
- is_running = false;
- break;
-
- default:
- if (log)
- log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") got unknown event 0x%8.8x",
- pid,
- event_type);
- done = true;
- is_running = false;
- break;
- }
- } while (is_running);
- }
- else
- {
- if (log)
- log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") listener.WaitForEvent (NULL, event_sp) => false",
- pid);
- done = true;
+ m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncThreadShouldExit);
+
+ // Stop the stdio thread
+ if (m_async_thread.IsJoinable())
+ m_async_thread.Join(nullptr);
+}
+
+void *ProcessKDP::AsyncThread(void *arg) {
+ ProcessKDP *process = (ProcessKDP *)arg;
+
+ const lldb::pid_t pid = process->GetID();
+
+ Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
+ if (log)
+ log->Printf("ProcessKDP::AsyncThread (arg = %p, pid = %" PRIu64
+ ") thread starting...",
+ arg, pid);
+
+ ListenerSP listener_sp(Listener::MakeListener("ProcessKDP::AsyncThread"));
+ EventSP event_sp;
+ const uint32_t desired_event_mask =
+ eBroadcastBitAsyncContinue | eBroadcastBitAsyncThreadShouldExit;
+
+ if (listener_sp->StartListeningForEvents(&process->m_async_broadcaster,
+ desired_event_mask) ==
+ desired_event_mask) {
+ bool done = false;
+ while (!done) {
+ if (log)
+ log->Printf("ProcessKDP::AsyncThread (pid = %" PRIu64
+ ") listener.WaitForEvent (NULL, event_sp)...",
+ pid);
+ if (listener_sp->GetEvent(event_sp, llvm::None)) {
+ uint32_t event_type = event_sp->GetType();
+ if (log)
+ log->Printf("ProcessKDP::AsyncThread (pid = %" PRIu64
+ ") Got an event of type: %d...",
+ pid, event_type);
+
+ // When we are running, poll for 1 second to try and get an exception
+ // to indicate the process has stopped. If we don't get one, check to
+ // make sure no one asked us to exit
+ bool is_running = false;
+ DataExtractor exc_reply_packet;
+ do {
+ switch (event_type) {
+ case eBroadcastBitAsyncContinue: {
+ is_running = true;
+ if (process->m_comm.WaitForPacketWithTimeoutMicroSeconds(
+ exc_reply_packet, 1 * USEC_PER_SEC)) {
+ ThreadSP thread_sp(process->GetKernelThread());
+ if (thread_sp) {
+ lldb::RegisterContextSP reg_ctx_sp(
+ thread_sp->GetRegisterContext());
+ if (reg_ctx_sp)
+ reg_ctx_sp->InvalidateAllRegisters();
+ static_cast<ThreadKDP *>(thread_sp.get())
+ ->SetStopInfoFrom_KDP_EXCEPTION(exc_reply_packet);
+ }
+
+ // TODO: parse the stop reply packet
+ is_running = false;
+ process->SetPrivateState(eStateStopped);
+ } else {
+ // Check to see if we are supposed to exit. There is no way to
+ // interrupt a running kernel, so all we can do is wait for an
+ // exception or detach...
+ if (listener_sp->GetEvent(event_sp,
+ std::chrono::microseconds(0))) {
+ // We got an event, go through the loop again
+ event_type = event_sp->GetType();
+ }
}
- }
+ } break;
+
+ case eBroadcastBitAsyncThreadShouldExit:
+ if (log)
+ log->Printf("ProcessKDP::AsyncThread (pid = %" PRIu64
+ ") got eBroadcastBitAsyncThreadShouldExit...",
+ pid);
+ done = true;
+ is_running = false;
+ break;
+
+ default:
+ if (log)
+ log->Printf("ProcessKDP::AsyncThread (pid = %" PRIu64
+ ") got unknown event 0x%8.8x",
+ pid, event_type);
+ done = true;
+ is_running = false;
+ break;
+ }
+ } while (is_running);
+ } else {
+ if (log)
+ log->Printf("ProcessKDP::AsyncThread (pid = %" PRIu64
+ ") listener.WaitForEvent (NULL, event_sp) => false",
+ pid);
+ done = true;
+ }
}
-
- if (log)
- log->Printf ("ProcessKDP::AsyncThread (arg = %p, pid = %" PRIu64 ") thread exiting...",
- arg,
- pid);
+ }
- process->m_async_thread.Reset();
- return NULL;
-}
+ if (log)
+ log->Printf("ProcessKDP::AsyncThread (arg = %p, pid = %" PRIu64
+ ") thread exiting...",
+ arg, pid);
+ process->m_async_thread.Reset();
+ return NULL;
+}
-class CommandObjectProcessKDPPacketSend : public CommandObjectParsed
-{
+class CommandObjectProcessKDPPacketSend : public CommandObjectParsed {
private:
-
- OptionGroupOptions m_option_group;
- OptionGroupUInt64 m_command_byte;
- OptionGroupString m_packet_data;
-
- virtual Options *
- GetOptions ()
- {
- return &m_option_group;
- }
-
+ OptionGroupOptions m_option_group;
+ OptionGroupUInt64 m_command_byte;
+ OptionGroupString m_packet_data;
+
+ virtual Options *GetOptions() { return &m_option_group; }
public:
- CommandObjectProcessKDPPacketSend(CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "process plugin packet send",
- "Send a custom packet through the KDP protocol by specifying the command byte and the packet payload data. A packet will be sent with a correct header and payload, and the raw result bytes will be displayed as a string value. ",
- NULL),
- m_option_group (interpreter),
- m_command_byte(LLDB_OPT_SET_1, true , "command", 'c', 0, eArgTypeNone, "Specify the command byte to use when sending the KDP request packet.", 0),
- m_packet_data (LLDB_OPT_SET_1, false, "payload", 'p', 0, eArgTypeNone, "Specify packet payload bytes as a hex ASCII string with no spaces or hex prefixes.", NULL)
- {
- m_option_group.Append (&m_command_byte, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Append (&m_packet_data , LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Finalize();
- }
-
- ~CommandObjectProcessKDPPacketSend ()
- {
- }
-
- bool
- DoExecute (Args& command, CommandReturnObject &result)
- {
- const size_t argc = command.GetArgumentCount();
- if (argc == 0)
- {
- if (!m_command_byte.GetOptionValue().OptionWasSet())
- {
- result.AppendError ("the --command option must be set to a valid command byte");
- result.SetStatus (eReturnStatusFailed);
- }
- else
- {
- const uint64_t command_byte = m_command_byte.GetOptionValue().GetUInt64Value(0);
- if (command_byte > 0 && command_byte <= UINT8_MAX)
- {
- ProcessKDP *process = (ProcessKDP *)m_interpreter.GetExecutionContext().GetProcessPtr();
- if (process)
- {
- const StateType state = process->GetState();
-
- if (StateIsStoppedState (state, true))
- {
- std::vector<uint8_t> payload_bytes;
- const char *ascii_hex_bytes_cstr = m_packet_data.GetOptionValue().GetCurrentValue();
- if (ascii_hex_bytes_cstr && ascii_hex_bytes_cstr[0])
- {
- StringExtractor extractor(ascii_hex_bytes_cstr);
- const size_t ascii_hex_bytes_cstr_len = extractor.GetStringRef().size();
- if (ascii_hex_bytes_cstr_len & 1)
- {
- result.AppendErrorWithFormat ("payload data must contain an even number of ASCII hex characters: '%s'", ascii_hex_bytes_cstr);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- payload_bytes.resize(ascii_hex_bytes_cstr_len/2);
- if (extractor.GetHexBytes(&payload_bytes[0], payload_bytes.size(), '\xdd') != payload_bytes.size())
- {
- result.AppendErrorWithFormat ("payload data must only contain ASCII hex characters (no spaces or hex prefixes): '%s'", ascii_hex_bytes_cstr);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- Error error;
- DataExtractor reply;
- process->GetCommunication().SendRawRequest (command_byte,
- payload_bytes.empty() ? NULL : payload_bytes.data(),
- payload_bytes.size(),
- reply,
- error);
-
- if (error.Success())
- {
- // Copy the binary bytes into a hex ASCII string for the result
- StreamString packet;
- packet.PutBytesAsRawHex8(reply.GetDataStart(),
- reply.GetByteSize(),
- endian::InlHostByteOrder(),
- endian::InlHostByteOrder());
- result.AppendMessage(packet.GetString().c_str());
- result.SetStatus (eReturnStatusSuccessFinishResult);
- return true;
- }
- else
- {
- const char *error_cstr = error.AsCString();
- if (error_cstr && error_cstr[0])
- result.AppendError (error_cstr);
- else
- result.AppendErrorWithFormat ("unknown error 0x%8.8x", error.GetError());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- else
- {
- result.AppendErrorWithFormat ("process must be stopped in order to send KDP packets, state is %s", StateAsCString (state));
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendError ("invalid process");
- result.SetStatus (eReturnStatusFailed);
- }
+ CommandObjectProcessKDPPacketSend(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "process plugin packet send",
+ "Send a custom packet through the KDP protocol by "
+ "specifying the command byte and the packet "
+ "payload data. A packet will be sent with a "
+ "correct header and payload, and the raw result "
+ "bytes will be displayed as a string value. ",
+ NULL),
+ m_option_group(),
+ m_command_byte(LLDB_OPT_SET_1, true, "command", 'c', 0, eArgTypeNone,
+ "Specify the command byte to use when sending the KDP "
+ "request packet.",
+ 0),
+ m_packet_data(LLDB_OPT_SET_1, false, "payload", 'p', 0, eArgTypeNone,
+ "Specify packet payload bytes as a hex ASCII string with "
+ "no spaces or hex prefixes.",
+ NULL) {
+ m_option_group.Append(&m_command_byte, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Append(&m_packet_data, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Finalize();
+ }
+
+ ~CommandObjectProcessKDPPacketSend() {}
+
+ bool DoExecute(Args &command, CommandReturnObject &result) {
+ const size_t argc = command.GetArgumentCount();
+ if (argc == 0) {
+ if (!m_command_byte.GetOptionValue().OptionWasSet()) {
+ result.AppendError(
+ "the --command option must be set to a valid command byte");
+ result.SetStatus(eReturnStatusFailed);
+ } else {
+ const uint64_t command_byte =
+ m_command_byte.GetOptionValue().GetUInt64Value(0);
+ if (command_byte > 0 && command_byte <= UINT8_MAX) {
+ ProcessKDP *process =
+ (ProcessKDP *)m_interpreter.GetExecutionContext().GetProcessPtr();
+ if (process) {
+ const StateType state = process->GetState();
+
+ if (StateIsStoppedState(state, true)) {
+ std::vector<uint8_t> payload_bytes;
+ const char *ascii_hex_bytes_cstr =
+ m_packet_data.GetOptionValue().GetCurrentValue();
+ if (ascii_hex_bytes_cstr && ascii_hex_bytes_cstr[0]) {
+ StringExtractor extractor(ascii_hex_bytes_cstr);
+ const size_t ascii_hex_bytes_cstr_len =
+ extractor.GetStringRef().size();
+ if (ascii_hex_bytes_cstr_len & 1) {
+ result.AppendErrorWithFormat("payload data must contain an "
+ "even number of ASCII hex "
+ "characters: '%s'",
+ ascii_hex_bytes_cstr);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- else
- {
- result.AppendErrorWithFormat ("invalid command byte 0x%" PRIx64 ", valid values are 1 - 255", command_byte);
- result.SetStatus (eReturnStatusFailed);
+ payload_bytes.resize(ascii_hex_bytes_cstr_len / 2);
+ if (extractor.GetHexBytes(payload_bytes, '\xdd') !=
+ payload_bytes.size()) {
+ result.AppendErrorWithFormat("payload data must only contain "
+ "ASCII hex characters (no "
+ "spaces or hex prefixes): '%s'",
+ ascii_hex_bytes_cstr);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
+ }
+ Error error;
+ DataExtractor reply;
+ process->GetCommunication().SendRawRequest(
+ command_byte,
+ payload_bytes.empty() ? NULL : payload_bytes.data(),
+ payload_bytes.size(), reply, error);
+
+ if (error.Success()) {
+ // Copy the binary bytes into a hex ASCII string for the result
+ StreamString packet;
+ packet.PutBytesAsRawHex8(
+ reply.GetDataStart(), reply.GetByteSize(),
+ endian::InlHostByteOrder(), endian::InlHostByteOrder());
+ result.AppendMessage(packet.GetString());
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ } else {
+ const char *error_cstr = error.AsCString();
+ if (error_cstr && error_cstr[0])
+ result.AppendError(error_cstr);
+ else
+ result.AppendErrorWithFormat("unknown error 0x%8.8x",
+ error.GetError());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } else {
+ result.AppendErrorWithFormat("process must be stopped in order "
+ "to send KDP packets, state is %s",
+ StateAsCString(state));
+ result.SetStatus(eReturnStatusFailed);
}
+ } else {
+ result.AppendError("invalid process");
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ result.AppendErrorWithFormat("invalid command byte 0x%" PRIx64
+ ", valid values are 1 - 255",
+ command_byte);
+ result.SetStatus(eReturnStatusFailed);
}
- else
- {
- result.AppendErrorWithFormat ("'%s' takes no arguments, only options.", m_cmd_name.c_str());
- result.SetStatus (eReturnStatusFailed);
- }
- return false;
+ }
+ } else {
+ result.AppendErrorWithFormat("'%s' takes no arguments, only options.",
+ m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
}
+ return false;
+ }
};
-class CommandObjectProcessKDPPacket : public CommandObjectMultiword
-{
+class CommandObjectProcessKDPPacket : public CommandObjectMultiword {
private:
-
public:
- CommandObjectProcessKDPPacket(CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "process plugin packet",
- "Commands that deal with KDP remote packets.",
- NULL)
- {
- LoadSubCommand ("send", CommandObjectSP (new CommandObjectProcessKDPPacketSend (interpreter)));
- }
-
- ~CommandObjectProcessKDPPacket ()
- {
- }
+ CommandObjectProcessKDPPacket(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "process plugin packet",
+ "Commands that deal with KDP remote packets.",
+ NULL) {
+ LoadSubCommand(
+ "send",
+ CommandObjectSP(new CommandObjectProcessKDPPacketSend(interpreter)));
+ }
+
+ ~CommandObjectProcessKDPPacket() {}
};
-class CommandObjectMultiwordProcessKDP : public CommandObjectMultiword
-{
+class CommandObjectMultiwordProcessKDP : public CommandObjectMultiword {
public:
- CommandObjectMultiwordProcessKDP(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "process plugin", "Commands for operating on a ProcessKDP process.",
- "process plugin <subcommand> [<subcommand-options>]")
- {
- LoadSubCommand ("packet", CommandObjectSP (new CommandObjectProcessKDPPacket (interpreter)));
- }
-
- ~CommandObjectMultiwordProcessKDP ()
- {
- }
+ CommandObjectMultiwordProcessKDP(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "process plugin",
+ "Commands for operating on a ProcessKDP process.",
+ "process plugin <subcommand> [<subcommand-options>]") {
+ LoadSubCommand("packet", CommandObjectSP(new CommandObjectProcessKDPPacket(
+ interpreter)));
+ }
+
+ ~CommandObjectMultiwordProcessKDP() {}
};
-CommandObject *
-ProcessKDP::GetPluginCommandObject()
-{
- if (!m_command_sp)
- m_command_sp.reset (new CommandObjectMultiwordProcessKDP (GetTarget().GetDebugger().GetCommandInterpreter()));
- return m_command_sp.get();
+CommandObject *ProcessKDP::GetPluginCommandObject() {
+ if (!m_command_sp)
+ m_command_sp.reset(new CommandObjectMultiwordProcessKDP(
+ GetTarget().GetDebugger().GetCommandInterpreter()));
+ return m_command_sp.get();
}
-
diff --git a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
index 49f636242510..fa5d2bd27feb 100644
--- a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
+++ b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
@@ -32,243 +32,192 @@
class ThreadKDP;
-class ProcessKDP : public lldb_private::Process
-{
+class ProcessKDP : public lldb_private::Process {
public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- static lldb::ProcessSP
- CreateInstance (lldb::TargetSP target_sp,
- lldb::ListenerSP listener_sp,
- const lldb_private::FileSpec *crash_file_path);
-
- static void
- Initialize();
-
- static void
- DebuggerInitialize (lldb_private::Debugger &debugger);
-
- static void
- Terminate();
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- static const char *
- GetPluginDescriptionStatic();
-
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- ProcessKDP(lldb::TargetSP target_sp, lldb::ListenerSP listener);
-
- virtual
- ~ProcessKDP();
-
- //------------------------------------------------------------------
- // Check if a given Process
- //------------------------------------------------------------------
- virtual bool
- CanDebug (lldb::TargetSP target_sp,
- bool plugin_specified_by_name);
-
- virtual lldb_private::CommandObject *
- GetPluginCommandObject();
-
- //------------------------------------------------------------------
- // Creating a new process, or attaching to an existing one
- //------------------------------------------------------------------
- virtual lldb_private::Error
- WillLaunch (lldb_private::Module* module);
-
- virtual lldb_private::Error
- DoLaunch (lldb_private::Module *exe_module,
- lldb_private::ProcessLaunchInfo &launch_info);
-
- virtual lldb_private::Error
- WillAttachToProcessWithID (lldb::pid_t pid);
-
- virtual lldb_private::Error
- WillAttachToProcessWithName (const char *process_name, bool wait_for_launch);
-
- virtual lldb_private::Error
- DoConnectRemote (lldb_private::Stream *strm, const char *remote_url);
-
- virtual lldb_private::Error
- DoAttachToProcessWithID (lldb::pid_t pid, const lldb_private::ProcessAttachInfo &attach_info);
-
- virtual lldb_private::Error
- DoAttachToProcessWithName (const char *process_name, const lldb_private::ProcessAttachInfo &attach_info);
-
- virtual void
- DidAttach (lldb_private::ArchSpec &process_arch);
-
- lldb::addr_t
- GetImageInfoAddress();
-
- lldb_private::DynamicLoader *
- GetDynamicLoader ();
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- virtual lldb_private::ConstString
- GetPluginName();
-
- virtual uint32_t
- GetPluginVersion();
-
- //------------------------------------------------------------------
- // Process Control
- //------------------------------------------------------------------
- virtual lldb_private::Error
- WillResume ();
-
- virtual lldb_private::Error
- DoResume ();
-
- virtual lldb_private::Error
- DoHalt (bool &caused_stop);
-
- virtual lldb_private::Error
- DoDetach (bool keep_stopped);
-
- virtual lldb_private::Error
- DoSignal (int signal);
-
- virtual lldb_private::Error
- DoDestroy ();
-
- virtual void
- RefreshStateAfterStop();
-
- //------------------------------------------------------------------
- // Process Queries
- //------------------------------------------------------------------
- virtual bool
- IsAlive ();
-
- //------------------------------------------------------------------
- // Process Memory
- //------------------------------------------------------------------
- virtual size_t
- DoReadMemory (lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error);
-
- virtual size_t
- DoWriteMemory (lldb::addr_t addr, const void *buf, size_t size, lldb_private::Error &error);
-
- virtual lldb::addr_t
- DoAllocateMemory (size_t size, uint32_t permissions, lldb_private::Error &error);
-
- virtual lldb_private::Error
- DoDeallocateMemory (lldb::addr_t ptr);
-
- //----------------------------------------------------------------------
- // Process Breakpoints
- //----------------------------------------------------------------------
- virtual lldb_private::Error
- EnableBreakpointSite (lldb_private::BreakpointSite *bp_site);
-
- virtual lldb_private::Error
- DisableBreakpointSite (lldb_private::BreakpointSite *bp_site);
-
- //----------------------------------------------------------------------
- // Process Watchpoints
- //----------------------------------------------------------------------
- virtual lldb_private::Error
- EnableWatchpoint (lldb_private::Watchpoint *wp, bool notify = true);
-
- virtual lldb_private::Error
- DisableWatchpoint (lldb_private::Watchpoint *wp, bool notify = true);
-
- CommunicationKDP &
- GetCommunication()
- {
- return m_comm;
- }
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ static lldb::ProcessSP
+ CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
+ const lldb_private::FileSpec *crash_file_path);
+
+ static void Initialize();
+
+ static void DebuggerInitialize(lldb_private::Debugger &debugger);
+
+ static void Terminate();
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static const char *GetPluginDescriptionStatic();
+
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ ProcessKDP(lldb::TargetSP target_sp, lldb::ListenerSP listener);
+
+ ~ProcessKDP() override;
+
+ //------------------------------------------------------------------
+ // Check if a given Process
+ //------------------------------------------------------------------
+ bool CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) override;
+ lldb_private::CommandObject *GetPluginCommandObject() override;
+
+ //------------------------------------------------------------------
+ // Creating a new process, or attaching to an existing one
+ //------------------------------------------------------------------
+ lldb_private::Error WillLaunch(lldb_private::Module *module) override;
+
+ lldb_private::Error
+ DoLaunch(lldb_private::Module *exe_module,
+ lldb_private::ProcessLaunchInfo &launch_info) override;
+
+ lldb_private::Error WillAttachToProcessWithID(lldb::pid_t pid) override;
+
+ lldb_private::Error
+ WillAttachToProcessWithName(const char *process_name,
+ bool wait_for_launch) override;
+
+ lldb_private::Error DoConnectRemote(lldb_private::Stream *strm,
+ llvm::StringRef remote_url) override;
+
+ lldb_private::Error DoAttachToProcessWithID(
+ lldb::pid_t pid,
+ const lldb_private::ProcessAttachInfo &attach_info) override;
+
+ lldb_private::Error DoAttachToProcessWithName(
+ const char *process_name,
+ const lldb_private::ProcessAttachInfo &attach_info) override;
+
+ void DidAttach(lldb_private::ArchSpec &process_arch) override;
+
+ lldb::addr_t GetImageInfoAddress() override;
+
+ lldb_private::DynamicLoader *GetDynamicLoader() override;
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
+
+ //------------------------------------------------------------------
+ // Process Control
+ //------------------------------------------------------------------
+ lldb_private::Error WillResume() override;
+
+ lldb_private::Error DoResume() override;
+
+ lldb_private::Error DoHalt(bool &caused_stop) override;
+
+ lldb_private::Error DoDetach(bool keep_stopped) override;
+
+ lldb_private::Error DoSignal(int signal) override;
+
+ lldb_private::Error DoDestroy() override;
+
+ void RefreshStateAfterStop() override;
+
+ //------------------------------------------------------------------
+ // Process Queries
+ //------------------------------------------------------------------
+ bool IsAlive() override;
+
+ //------------------------------------------------------------------
+ // Process Memory
+ //------------------------------------------------------------------
+ size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ lldb_private::Error &error) override;
+
+ size_t DoWriteMemory(lldb::addr_t 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_private::Error DoDeallocateMemory(lldb::addr_t ptr) override;
+
+ //----------------------------------------------------------------------
+ // Process Breakpoints
+ //----------------------------------------------------------------------
+ lldb_private::Error
+ EnableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
+
+ lldb_private::Error
+ DisableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
+
+ //----------------------------------------------------------------------
+ // Process Watchpoints
+ //----------------------------------------------------------------------
+ lldb_private::Error EnableWatchpoint(lldb_private::Watchpoint *wp,
+ bool notify = true) override;
+
+ lldb_private::Error DisableWatchpoint(lldb_private::Watchpoint *wp,
+ bool notify = true) override;
+
+ CommunicationKDP &GetCommunication() { return m_comm; }
protected:
- friend class ThreadKDP;
- friend class CommunicationKDP;
-
- //----------------------------------------------------------------------
- // Accessors
- //----------------------------------------------------------------------
- bool
- IsRunning ( lldb::StateType state )
- {
- return state == lldb::eStateRunning || IsStepping(state);
- }
-
- bool
- IsStepping ( lldb::StateType state)
- {
- return state == lldb::eStateStepping;
- }
-
- bool
- CanResume ( lldb::StateType state)
- {
- return state == lldb::eStateStopped;
- }
-
- bool
- HasExited (lldb::StateType state)
- {
- return state == lldb::eStateExited;
- }
-
- bool
- GetHostArchitecture (lldb_private::ArchSpec &arch);
-
- bool
- ProcessIDIsValid ( ) const;
-
- void
- Clear ( );
-
- virtual bool
- UpdateThreadList (lldb_private::ThreadList &old_thread_list,
- lldb_private::ThreadList &new_thread_list);
-
- enum
- {
- eBroadcastBitAsyncContinue = (1 << 0),
- eBroadcastBitAsyncThreadShouldExit = (1 << 1)
- };
-
- lldb::ThreadSP
- GetKernelThread ();
-
- //------------------------------------------------------------------
- /// Broadcaster event bits definitions.
- //------------------------------------------------------------------
- CommunicationKDP m_comm;
- lldb_private::Broadcaster m_async_broadcaster;
- lldb_private::HostThread m_async_thread;
- lldb_private::ConstString m_dyld_plugin_name;
- lldb::addr_t m_kernel_load_addr;
- lldb::CommandObjectSP m_command_sp;
- lldb::ThreadWP m_kernel_thread_wp;
-
-
- bool
- StartAsyncThread ();
-
- void
- StopAsyncThread ();
-
- static void *
- AsyncThread (void *arg);
-
+ friend class ThreadKDP;
+ friend class CommunicationKDP;
+
+ //----------------------------------------------------------------------
+ // Accessors
+ //----------------------------------------------------------------------
+ bool IsRunning(lldb::StateType state) {
+ return state == lldb::eStateRunning || IsStepping(state);
+ }
+
+ bool IsStepping(lldb::StateType state) {
+ return state == lldb::eStateStepping;
+ }
+
+ bool CanResume(lldb::StateType state) { return state == lldb::eStateStopped; }
+
+ bool HasExited(lldb::StateType state) { return state == lldb::eStateExited; }
+
+ bool GetHostArchitecture(lldb_private::ArchSpec &arch);
+
+ bool ProcessIDIsValid() const;
+
+ void Clear();
+
+ bool UpdateThreadList(lldb_private::ThreadList &old_thread_list,
+ lldb_private::ThreadList &new_thread_list) override;
+
+ enum {
+ eBroadcastBitAsyncContinue = (1 << 0),
+ eBroadcastBitAsyncThreadShouldExit = (1 << 1)
+ };
+
+ lldb::ThreadSP GetKernelThread();
+
+ //------------------------------------------------------------------
+ /// Broadcaster event bits definitions.
+ //------------------------------------------------------------------
+ CommunicationKDP m_comm;
+ lldb_private::Broadcaster m_async_broadcaster;
+ lldb_private::HostThread m_async_thread;
+ lldb_private::ConstString m_dyld_plugin_name;
+ lldb::addr_t m_kernel_load_addr;
+ lldb::CommandObjectSP m_command_sp;
+ lldb::ThreadWP m_kernel_thread_wp;
+
+ bool StartAsyncThread();
+
+ void StopAsyncThread();
+
+ static void *AsyncThread(void *arg);
+
private:
- //------------------------------------------------------------------
- // For ProcessKDP only
- //------------------------------------------------------------------
-
- DISALLOW_COPY_AND_ASSIGN (ProcessKDP);
-
+ //------------------------------------------------------------------
+ // For ProcessKDP only
+ //------------------------------------------------------------------
+
+ DISALLOW_COPY_AND_ASSIGN(ProcessKDP);
};
-#endif // liblldb_ProcessKDP_h_
+#endif // liblldb_ProcessKDP_h_
diff --git a/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp b/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp
index 79cb62aa0066..479f09aa8981 100644
--- a/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp
@@ -9,178 +9,184 @@
#include "ProcessKDPLog.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Core/StreamFile.h"
+#include "lldb/Interpreter/Args.h"
#include "ProcessKDP.h"
using namespace lldb;
using namespace lldb_private;
-
// We want to avoid global constructors where code needs to be run so here we
// control access to our static g_log_sp by hiding it in a singleton function
-// that will construct the static g_log_sp the first time this function is
+// that will construct the static g_log_sp the first time this function is
// called.
static bool g_log_enabled = false;
-static Log * g_log = NULL;
-static Log *
-GetLog ()
-{
- if (!g_log_enabled)
- return NULL;
- return g_log;
+static Log *g_log = NULL;
+static Log *GetLog() {
+ if (!g_log_enabled)
+ return NULL;
+ return g_log;
}
-Log *
-ProcessKDPLog::GetLogIfAllCategoriesSet (uint32_t mask)
-{
- Log *log(GetLog ());
- if (log && mask)
- {
- uint32_t log_mask = log->GetMask().Get();
- if ((log_mask & mask) != mask)
- return NULL;
- }
- return log;
+Log *ProcessKDPLog::GetLogIfAllCategoriesSet(uint32_t mask) {
+ Log *log(GetLog());
+ if (log && mask) {
+ uint32_t log_mask = log->GetMask().Get();
+ if ((log_mask & mask) != mask)
+ return NULL;
+ }
+ return log;
}
-void
-ProcessKDPLog::DisableLog (const char **categories, Stream *feedback_strm)
-{
- Log *log (GetLog ());
- if (log)
- {
- uint32_t flag_bits = 0;
-
- if (categories[0] != NULL)
- {
- flag_bits = log->GetMask().Get();
- for (size_t i = 0; categories[i] != NULL; ++i)
- {
- const char *arg = categories[i];
-
-
- if (::strcasecmp (arg, "all") == 0 ) flag_bits &= ~KDP_LOG_ALL;
- else if (::strcasecmp (arg, "async") == 0 ) flag_bits &= ~KDP_LOG_ASYNC;
- else if (::strncasecmp (arg, "break", 5) == 0 ) flag_bits &= ~KDP_LOG_BREAKPOINTS;
- else if (::strncasecmp (arg, "comm", 4) == 0 ) flag_bits &= ~KDP_LOG_COMM;
- else if (::strcasecmp (arg, "default") == 0 ) flag_bits &= ~KDP_LOG_DEFAULT;
- else if (::strcasecmp (arg, "packets") == 0 ) flag_bits &= ~KDP_LOG_PACKETS;
- else if (::strcasecmp (arg, "memory") == 0 ) flag_bits &= ~KDP_LOG_MEMORY;
- else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits &= ~KDP_LOG_MEMORY_DATA_SHORT;
- else if (::strcasecmp (arg, "data-long") == 0 ) flag_bits &= ~KDP_LOG_MEMORY_DATA_LONG;
- else if (::strcasecmp (arg, "process") == 0 ) flag_bits &= ~KDP_LOG_PROCESS;
- else if (::strcasecmp (arg, "step") == 0 ) flag_bits &= ~KDP_LOG_STEP;
- else if (::strcasecmp (arg, "thread") == 0 ) flag_bits &= ~KDP_LOG_THREAD;
- else if (::strcasecmp (arg, "verbose") == 0 ) flag_bits &= ~KDP_LOG_VERBOSE;
- else if (::strncasecmp (arg, "watch", 5) == 0 ) flag_bits &= ~KDP_LOG_WATCHPOINTS;
- else
- {
- feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
- ListLogCategories (feedback_strm);
- }
-
- }
+void ProcessKDPLog::DisableLog(const char **categories, Stream *feedback_strm) {
+ Log *log(GetLog());
+ if (log) {
+ uint32_t flag_bits = 0;
+
+ if (categories[0] != NULL) {
+ flag_bits = log->GetMask().Get();
+ for (size_t i = 0; categories[i] != NULL; ++i) {
+ const char *arg = categories[i];
+
+ if (::strcasecmp(arg, "all") == 0)
+ flag_bits &= ~KDP_LOG_ALL;
+ else if (::strcasecmp(arg, "async") == 0)
+ flag_bits &= ~KDP_LOG_ASYNC;
+ else if (::strncasecmp(arg, "break", 5) == 0)
+ flag_bits &= ~KDP_LOG_BREAKPOINTS;
+ else if (::strncasecmp(arg, "comm", 4) == 0)
+ flag_bits &= ~KDP_LOG_COMM;
+ else if (::strcasecmp(arg, "default") == 0)
+ flag_bits &= ~KDP_LOG_DEFAULT;
+ else if (::strcasecmp(arg, "packets") == 0)
+ flag_bits &= ~KDP_LOG_PACKETS;
+ else if (::strcasecmp(arg, "memory") == 0)
+ flag_bits &= ~KDP_LOG_MEMORY;
+ else if (::strcasecmp(arg, "data-short") == 0)
+ flag_bits &= ~KDP_LOG_MEMORY_DATA_SHORT;
+ else if (::strcasecmp(arg, "data-long") == 0)
+ flag_bits &= ~KDP_LOG_MEMORY_DATA_LONG;
+ else if (::strcasecmp(arg, "process") == 0)
+ flag_bits &= ~KDP_LOG_PROCESS;
+ else if (::strcasecmp(arg, "step") == 0)
+ flag_bits &= ~KDP_LOG_STEP;
+ else if (::strcasecmp(arg, "thread") == 0)
+ flag_bits &= ~KDP_LOG_THREAD;
+ else if (::strcasecmp(arg, "verbose") == 0)
+ flag_bits &= ~KDP_LOG_VERBOSE;
+ else if (::strncasecmp(arg, "watch", 5) == 0)
+ flag_bits &= ~KDP_LOG_WATCHPOINTS;
+ else {
+ feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
+ ListLogCategories(feedback_strm);
}
-
- log->GetMask().Reset (flag_bits);
- if (flag_bits == 0)
- g_log_enabled = false;
+ }
}
-
- return;
-}
-Log *
-ProcessKDPLog::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, const char **categories, Stream *feedback_strm)
-{
- // Try see if there already is a log - that way we can reuse its settings.
- // We could reuse the log in toto, but we don't know that the stream is the same.
- uint32_t flag_bits = 0;
- if (g_log)
- flag_bits = g_log->GetMask().Get();
-
- // Now make a new log with this stream if one was provided
- if (log_stream_sp)
- {
- if (g_log)
- g_log->SetStream(log_stream_sp);
- else
- g_log = new Log(log_stream_sp);
- }
+ log->GetMask().Reset(flag_bits);
+ if (flag_bits == 0)
+ g_log_enabled = false;
+ }
+ return;
+}
+
+Log *ProcessKDPLog::EnableLog(StreamSP &log_stream_sp, uint32_t log_options,
+ const char **categories, Stream *feedback_strm) {
+ // Try see if there already is a log - that way we can reuse its settings.
+ // We could reuse the log in toto, but we don't know that the stream is the
+ // same.
+ uint32_t flag_bits = 0;
+ if (g_log)
+ flag_bits = g_log->GetMask().Get();
+
+ // Now make a new log with this stream if one was provided
+ if (log_stream_sp) {
if (g_log)
- {
- bool got_unknown_category = false;
- for (size_t i=0; categories[i] != NULL; ++i)
- {
- const char *arg = categories[i];
-
- if (::strcasecmp (arg, "all") == 0 ) flag_bits |= KDP_LOG_ALL;
- else if (::strcasecmp (arg, "async") == 0 ) flag_bits |= KDP_LOG_ASYNC;
- else if (::strncasecmp (arg, "break", 5) == 0 ) flag_bits |= KDP_LOG_BREAKPOINTS;
- else if (::strncasecmp (arg, "comm", 4) == 0 ) flag_bits |= KDP_LOG_COMM;
- else if (::strcasecmp (arg, "default") == 0 ) flag_bits |= KDP_LOG_DEFAULT;
- else if (::strcasecmp (arg, "packets") == 0 ) flag_bits |= KDP_LOG_PACKETS;
- else if (::strcasecmp (arg, "memory") == 0 ) flag_bits |= KDP_LOG_MEMORY;
- else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits |= KDP_LOG_MEMORY_DATA_SHORT;
- else if (::strcasecmp (arg, "data-long") == 0 ) flag_bits |= KDP_LOG_MEMORY_DATA_LONG;
- else if (::strcasecmp (arg, "process") == 0 ) flag_bits |= KDP_LOG_PROCESS;
- else if (::strcasecmp (arg, "step") == 0 ) flag_bits |= KDP_LOG_STEP;
- else if (::strcasecmp (arg, "thread") == 0 ) flag_bits |= KDP_LOG_THREAD;
- else if (::strcasecmp (arg, "verbose") == 0 ) flag_bits |= KDP_LOG_VERBOSE;
- else if (::strncasecmp (arg, "watch", 5) == 0 ) flag_bits |= KDP_LOG_WATCHPOINTS;
- else
- {
- feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
- if (got_unknown_category == false)
- {
- got_unknown_category = true;
- ListLogCategories (feedback_strm);
- }
- }
+ g_log->SetStream(log_stream_sp);
+ else
+ g_log = new Log(log_stream_sp);
+ }
+
+ if (g_log) {
+ bool got_unknown_category = false;
+ for (size_t i = 0; categories[i] != NULL; ++i) {
+ const char *arg = categories[i];
+
+ if (::strcasecmp(arg, "all") == 0)
+ flag_bits |= KDP_LOG_ALL;
+ else if (::strcasecmp(arg, "async") == 0)
+ flag_bits |= KDP_LOG_ASYNC;
+ else if (::strncasecmp(arg, "break", 5) == 0)
+ flag_bits |= KDP_LOG_BREAKPOINTS;
+ else if (::strncasecmp(arg, "comm", 4) == 0)
+ flag_bits |= KDP_LOG_COMM;
+ else if (::strcasecmp(arg, "default") == 0)
+ flag_bits |= KDP_LOG_DEFAULT;
+ else if (::strcasecmp(arg, "packets") == 0)
+ flag_bits |= KDP_LOG_PACKETS;
+ else if (::strcasecmp(arg, "memory") == 0)
+ flag_bits |= KDP_LOG_MEMORY;
+ else if (::strcasecmp(arg, "data-short") == 0)
+ flag_bits |= KDP_LOG_MEMORY_DATA_SHORT;
+ else if (::strcasecmp(arg, "data-long") == 0)
+ flag_bits |= KDP_LOG_MEMORY_DATA_LONG;
+ else if (::strcasecmp(arg, "process") == 0)
+ flag_bits |= KDP_LOG_PROCESS;
+ else if (::strcasecmp(arg, "step") == 0)
+ flag_bits |= KDP_LOG_STEP;
+ else if (::strcasecmp(arg, "thread") == 0)
+ flag_bits |= KDP_LOG_THREAD;
+ else if (::strcasecmp(arg, "verbose") == 0)
+ flag_bits |= KDP_LOG_VERBOSE;
+ else if (::strncasecmp(arg, "watch", 5) == 0)
+ flag_bits |= KDP_LOG_WATCHPOINTS;
+ else {
+ feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
+ if (got_unknown_category == false) {
+ got_unknown_category = true;
+ ListLogCategories(feedback_strm);
}
- if (flag_bits == 0)
- flag_bits = KDP_LOG_DEFAULT;
- g_log->GetMask().Reset(flag_bits);
- g_log->GetOptions().Reset(log_options);
+ }
}
- g_log_enabled = true;
- return g_log;
+ if (flag_bits == 0)
+ flag_bits = KDP_LOG_DEFAULT;
+ g_log->GetMask().Reset(flag_bits);
+ g_log->GetOptions().Reset(log_options);
+ }
+ g_log_enabled = true;
+ return g_log;
}
-void
-ProcessKDPLog::ListLogCategories (Stream *strm)
-{
- strm->Printf ("Logging categories for '%s':\n"
- " all - turn on all available logging categories\n"
- " async - log asynchronous activity\n"
- " break - log breakpoints\n"
- " communication - log communication activity\n"
- " default - enable the default set of logging categories for liblldb\n"
- " packets - log gdb remote packets\n"
- " memory - log memory reads and writes\n"
- " data-short - log memory bytes for memory reads and writes for short transactions only\n"
- " data-long - log memory bytes for memory reads and writes for all transactions\n"
- " process - log process events and activities\n"
- " thread - log thread events and activities\n"
- " step - log step related activities\n"
- " verbose - enable verbose logging\n"
- " watch - log watchpoint related activities\n",
- ProcessKDP::GetPluginNameStatic().GetCString());
+void ProcessKDPLog::ListLogCategories(Stream *strm) {
+ strm->Printf(
+ "Logging categories for '%s':\n"
+ " all - turn on all available logging categories\n"
+ " async - log asynchronous activity\n"
+ " break - log breakpoints\n"
+ " communication - log communication activity\n"
+ " default - enable the default set of logging categories for liblldb\n"
+ " packets - log gdb remote packets\n"
+ " memory - log memory reads and writes\n"
+ " data-short - log memory bytes for memory reads and writes for short "
+ "transactions only\n"
+ " data-long - log memory bytes for memory reads and writes for all "
+ "transactions\n"
+ " process - log process events and activities\n"
+ " thread - log thread events and activities\n"
+ " step - log step related activities\n"
+ " verbose - enable verbose logging\n"
+ " watch - log watchpoint related activities\n",
+ ProcessKDP::GetPluginNameStatic().GetCString());
}
-
-void
-ProcessKDPLog::LogIf (uint32_t mask, const char *format, ...)
-{
- Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (mask));
- if (log)
- {
- va_list args;
- va_start (args, format);
- log->VAPrintf (format, args);
- va_end (args);
- }
+void ProcessKDPLog::LogIf(uint32_t mask, const char *format, ...) {
+ Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(mask));
+ if (log) {
+ va_list args;
+ va_start(args, format);
+ log->VAPrintf(format, args);
+ va_end(args);
+ }
}
diff --git a/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h b/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h
index 0cb32d9b2dcf..703c775268d2 100644
--- a/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h
+++ b/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h
@@ -17,38 +17,37 @@
// Project includes
#include "lldb/Core/Log.h"
-#define KDP_LOG_VERBOSE (1u << 0)
-#define KDP_LOG_PROCESS (1u << 1)
-#define KDP_LOG_THREAD (1u << 2)
-#define KDP_LOG_PACKETS (1u << 3)
-#define KDP_LOG_MEMORY (1u << 4) // Log memory reads/writes calls
-#define KDP_LOG_MEMORY_DATA_SHORT (1u << 5) // Log short memory reads/writes bytes
-#define KDP_LOG_MEMORY_DATA_LONG (1u << 6) // Log all memory reads/writes bytes
-#define KDP_LOG_BREAKPOINTS (1u << 7)
-#define KDP_LOG_WATCHPOINTS (1u << 8)
-#define KDP_LOG_STEP (1u << 9)
-#define KDP_LOG_COMM (1u << 10)
-#define KDP_LOG_ASYNC (1u << 11)
-#define KDP_LOG_ALL (UINT32_MAX)
-#define KDP_LOG_DEFAULT KDP_LOG_PACKETS
-
-class ProcessKDPLog
-{
+#define KDP_LOG_VERBOSE (1u << 0)
+#define KDP_LOG_PROCESS (1u << 1)
+#define KDP_LOG_THREAD (1u << 2)
+#define KDP_LOG_PACKETS (1u << 3)
+#define KDP_LOG_MEMORY (1u << 4) // Log memory reads/writes calls
+#define KDP_LOG_MEMORY_DATA_SHORT \
+ (1u << 5) // Log short memory reads/writes bytes
+#define KDP_LOG_MEMORY_DATA_LONG (1u << 6) // Log all memory reads/writes bytes
+#define KDP_LOG_BREAKPOINTS (1u << 7)
+#define KDP_LOG_WATCHPOINTS (1u << 8)
+#define KDP_LOG_STEP (1u << 9)
+#define KDP_LOG_COMM (1u << 10)
+#define KDP_LOG_ASYNC (1u << 11)
+#define KDP_LOG_ALL (UINT32_MAX)
+#define KDP_LOG_DEFAULT KDP_LOG_PACKETS
+
+class ProcessKDPLog {
public:
- static lldb_private::Log *
- GetLogIfAllCategoriesSet(uint32_t mask = 0);
+ static lldb_private::Log *GetLogIfAllCategoriesSet(uint32_t mask = 0);
- static void
- DisableLog (const char **categories, lldb_private::Stream *feedback_strm);
+ static void DisableLog(const char **categories,
+ lldb_private::Stream *feedback_strm);
- static lldb_private::Log *
- EnableLog (lldb::StreamSP &log_stream_sp, uint32_t log_options, const char **categories, lldb_private::Stream *feedback_strm);
+ static lldb_private::Log *EnableLog(lldb::StreamSP &log_stream_sp,
+ uint32_t log_options,
+ const char **categories,
+ lldb_private::Stream *feedback_strm);
- static void
- ListLogCategories (lldb_private::Stream *strm);
+ static void ListLogCategories(lldb_private::Stream *strm);
- static void
- LogIf (uint32_t mask, const char *format, ...);
+ static void LogIf(uint32_t mask, const char *format, ...);
};
-#endif // liblldb_ProcessKDPLog_h_
+#endif // liblldb_ProcessKDPLog_h_
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp
index 449ac646ab3c..06c33dba8576 100644
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp
@@ -19,143 +19,133 @@
using namespace lldb;
using namespace lldb_private;
-
-RegisterContextKDP_arm::RegisterContextKDP_arm (ThreadKDP &thread, uint32_t concrete_frame_idx) :
- RegisterContextDarwin_arm (thread, concrete_frame_idx),
- m_kdp_thread (thread)
-{
-}
-
-RegisterContextKDP_arm::~RegisterContextKDP_arm()
-{
-}
-
-int
-RegisterContextKDP_arm::DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, GPRRegSet, &gpr, sizeof(gpr), error))
- {
- if (error.Success())
- return 0;
- }
+RegisterContextKDP_arm::RegisterContextKDP_arm(ThreadKDP &thread,
+ uint32_t concrete_frame_idx)
+ : RegisterContextDarwin_arm(thread, concrete_frame_idx),
+ m_kdp_thread(thread) {}
+
+RegisterContextKDP_arm::~RegisterContextKDP_arm() {}
+
+int RegisterContextKDP_arm::DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestReadRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_arm::DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, FPURegSet, &fpu, sizeof(fpu), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_arm::DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestReadRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_arm::DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, EXCRegSet, &exc, sizeof(exc), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_arm::DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestReadRegisters(tid, EXCRegSet, &exc, sizeof(exc),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_arm::DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, DBGRegSet, &dbg, sizeof(dbg), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_arm::DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestReadRegisters(tid, DBGRegSet, &dbg, sizeof(dbg),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_arm::DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, GPRRegSet, &gpr, sizeof(gpr), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_arm::DoWriteGPR(lldb::tid_t tid, int flavor,
+ const GPR &gpr) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestWriteRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_arm::DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, FPURegSet, &fpu, sizeof(fpu), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_arm::DoWriteFPU(lldb::tid_t tid, int flavor,
+ const FPU &fpu) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestWriteRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_arm::DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, EXCRegSet, &exc, sizeof(exc), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_arm::DoWriteEXC(lldb::tid_t tid, int flavor,
+ const EXC &exc) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestWriteRegisters(tid, EXCRegSet, &exc, sizeof(exc),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_arm::DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, DBGRegSet, &dbg, sizeof(dbg), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_arm::DoWriteDBG(lldb::tid_t tid, int flavor,
+ const DBG &dbg) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestWriteRegisters(tid, DBGRegSet, &dbg, sizeof(dbg),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-
-
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h
index 1e547289d9ce..fe02b0648221 100644
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h
+++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h
@@ -19,43 +19,30 @@
class ThreadKDP;
-class RegisterContextKDP_arm : public RegisterContextDarwin_arm
-{
+class RegisterContextKDP_arm : public RegisterContextDarwin_arm {
public:
+ RegisterContextKDP_arm(ThreadKDP &thread, uint32_t concrete_frame_idx);
- RegisterContextKDP_arm (ThreadKDP &thread,
- uint32_t concrete_frame_idx);
-
- virtual
- ~RegisterContextKDP_arm();
+ virtual ~RegisterContextKDP_arm();
protected:
+ virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr);
+
+ int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu);
+
+ int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc);
+
+ int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg);
+
+ int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr);
+
+ int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu);
+
+ int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc);
+
+ int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg);
- virtual int
- DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr);
-
- int
- DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu);
-
- int
- DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc);
-
- int
- DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg);
-
- int
- DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr);
-
- int
- DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu);
-
- int
- DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc);
-
- int
- DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg);
-
- ThreadKDP &m_kdp_thread;
+ ThreadKDP &m_kdp_thread;
};
-#endif // liblldb_RegisterContextKDP_arm_h_
+#endif // liblldb_RegisterContextKDP_arm_h_
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp
index ed62f1982d3c..6a2733e62759 100644
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp
@@ -1,4 +1,5 @@
-//===-- RegisterContextKDP_arm64.cpp ------------------------------*- C++ -*-===//
+//===-- RegisterContextKDP_arm64.cpp ------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,143 +20,133 @@
using namespace lldb;
using namespace lldb_private;
-
-RegisterContextKDP_arm64::RegisterContextKDP_arm64 (ThreadKDP &thread, uint32_t concrete_frame_idx) :
- RegisterContextDarwin_arm64 (thread, concrete_frame_idx),
- m_kdp_thread (thread)
-{
-}
-
-RegisterContextKDP_arm64::~RegisterContextKDP_arm64()
-{
-}
-
-int
-RegisterContextKDP_arm64::DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, GPRRegSet, &gpr, sizeof(gpr), error))
- {
- if (error.Success())
- return 0;
- }
+RegisterContextKDP_arm64::RegisterContextKDP_arm64(ThreadKDP &thread,
+ uint32_t concrete_frame_idx)
+ : RegisterContextDarwin_arm64(thread, concrete_frame_idx),
+ m_kdp_thread(thread) {}
+
+RegisterContextKDP_arm64::~RegisterContextKDP_arm64() {}
+
+int RegisterContextKDP_arm64::DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestReadRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_arm64::DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, FPURegSet, &fpu, sizeof(fpu), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_arm64::DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestReadRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_arm64::DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, EXCRegSet, &exc, sizeof(exc), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_arm64::DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestReadRegisters(tid, EXCRegSet, &exc, sizeof(exc),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_arm64::DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, DBGRegSet, &dbg, sizeof(dbg), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_arm64::DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestReadRegisters(tid, DBGRegSet, &dbg, sizeof(dbg),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_arm64::DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, GPRRegSet, &gpr, sizeof(gpr), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_arm64::DoWriteGPR(lldb::tid_t tid, int flavor,
+ const GPR &gpr) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestWriteRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_arm64::DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, FPURegSet, &fpu, sizeof(fpu), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_arm64::DoWriteFPU(lldb::tid_t tid, int flavor,
+ const FPU &fpu) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestWriteRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_arm64::DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, EXCRegSet, &exc, sizeof(exc), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_arm64::DoWriteEXC(lldb::tid_t tid, int flavor,
+ const EXC &exc) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestWriteRegisters(tid, EXCRegSet, &exc, sizeof(exc),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_arm64::DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, DBGRegSet, &dbg, sizeof(dbg), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_arm64::DoWriteDBG(lldb::tid_t tid, int flavor,
+ const DBG &dbg) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestWriteRegisters(tid, DBGRegSet, &dbg, sizeof(dbg),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-
-
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h
index 8780b7be4a9a..0922654de2cc 100644
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h
+++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h
@@ -1,4 +1,5 @@
-//===-- RegisterContextKDP_arm64.h --------------------------------*- C++ -*-===//
+//===-- RegisterContextKDP_arm64.h --------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,43 +20,30 @@
class ThreadKDP;
-class RegisterContextKDP_arm64 : public RegisterContextDarwin_arm64
-{
+class RegisterContextKDP_arm64 : public RegisterContextDarwin_arm64 {
public:
+ RegisterContextKDP_arm64(ThreadKDP &thread, uint32_t concrete_frame_idx);
- RegisterContextKDP_arm64 (ThreadKDP &thread,
- uint32_t concrete_frame_idx);
-
- virtual
- ~RegisterContextKDP_arm64();
+ virtual ~RegisterContextKDP_arm64();
protected:
+ virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr);
+
+ int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu);
+
+ int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc);
+
+ int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg);
+
+ int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr);
+
+ int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu);
+
+ int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc);
+
+ int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg);
- virtual int
- DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr);
-
- int
- DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu);
-
- int
- DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc);
-
- int
- DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg);
-
- int
- DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr);
-
- int
- DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu);
-
- int
- DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc);
-
- int
- DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg);
-
- ThreadKDP &m_kdp_thread;
+ ThreadKDP &m_kdp_thread;
};
-#endif // liblldb_RegisterContextKDP_arm64_h_
+#endif // liblldb_RegisterContextKDP_arm64_h_
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp
index 882b0c2e931d..4a130c18d075 100644
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-
// C Includes
// C++ Includes
// Other libraries and framework includes
@@ -19,111 +18,102 @@
using namespace lldb;
using namespace lldb_private;
+RegisterContextKDP_i386::RegisterContextKDP_i386(ThreadKDP &thread,
+ uint32_t concrete_frame_idx)
+ : RegisterContextDarwin_i386(thread, concrete_frame_idx),
+ m_kdp_thread(thread) {}
-RegisterContextKDP_i386::RegisterContextKDP_i386 (ThreadKDP &thread, uint32_t concrete_frame_idx) :
- RegisterContextDarwin_i386 (thread, concrete_frame_idx),
- m_kdp_thread (thread)
-{
-}
-
-RegisterContextKDP_i386::~RegisterContextKDP_i386()
-{
-}
+RegisterContextKDP_i386::~RegisterContextKDP_i386() {}
-int
-RegisterContextKDP_i386::DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, GPRRegSet, &gpr, sizeof(gpr), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_i386::DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestReadRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_i386::DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, FPURegSet, &fpu, sizeof(fpu), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_i386::DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestReadRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_i386::DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, EXCRegSet, &exc, sizeof(exc), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_i386::DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestReadRegisters(tid, EXCRegSet, &exc, sizeof(exc),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_i386::DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, GPRRegSet, &gpr, sizeof(gpr), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_i386::DoWriteGPR(lldb::tid_t tid, int flavor,
+ const GPR &gpr) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestWriteRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_i386::DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, FPURegSet, &fpu, sizeof(fpu), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_i386::DoWriteFPU(lldb::tid_t tid, int flavor,
+ const FPU &fpu) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestWriteRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_i386::DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, EXCRegSet, &exc, sizeof(exc), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_i386::DoWriteEXC(lldb::tid_t tid, int flavor,
+ const EXC &exc) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestWriteRegisters(tid, EXCRegSet, &exc, sizeof(exc),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-
-
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h
index 4b6bc5b262f7..5803670a08b4 100644
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h
+++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h
@@ -18,36 +18,26 @@
class ThreadKDP;
-class RegisterContextKDP_i386 : public RegisterContextDarwin_i386
-{
+class RegisterContextKDP_i386 : public RegisterContextDarwin_i386 {
public:
- RegisterContextKDP_i386 (ThreadKDP &thread,
- uint32_t concrete_frame_idx);
-
- virtual
- ~RegisterContextKDP_i386();
-
+ RegisterContextKDP_i386(ThreadKDP &thread, uint32_t concrete_frame_idx);
+
+ virtual ~RegisterContextKDP_i386();
+
protected:
-
- virtual int
- DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr);
-
- int
- DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu);
-
- int
- DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc);
-
- int
- DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr);
-
- int
- DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu);
-
- int
- DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc);
-
- ThreadKDP &m_kdp_thread;
+ virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr);
+
+ int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu);
+
+ int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc);
+
+ int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr);
+
+ int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu);
+
+ int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc);
+
+ ThreadKDP &m_kdp_thread;
};
-#endif // liblldb_RegisterContextKDP_i386_h_
+#endif // liblldb_RegisterContextKDP_i386_h_
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp
index f4247a5da272..ad10d3f6be52 100644
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-
// C Includes
// C++ Includes
// Other libraries and framework includes
@@ -19,109 +18,105 @@
using namespace lldb;
using namespace lldb_private;
+RegisterContextKDP_x86_64::RegisterContextKDP_x86_64(
+ ThreadKDP &thread, uint32_t concrete_frame_idx)
+ : RegisterContextDarwin_x86_64(thread, concrete_frame_idx),
+ m_kdp_thread(thread) {}
-RegisterContextKDP_x86_64::RegisterContextKDP_x86_64 (ThreadKDP &thread, uint32_t concrete_frame_idx) :
- RegisterContextDarwin_x86_64 (thread, concrete_frame_idx),
- m_kdp_thread (thread)
-{
-}
-
-RegisterContextKDP_x86_64::~RegisterContextKDP_x86_64()
-{
-}
+RegisterContextKDP_x86_64::~RegisterContextKDP_x86_64() {}
-int
-RegisterContextKDP_x86_64::DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, GPRRegSet, &gpr, sizeof(gpr), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_x86_64::DoReadGPR(lldb::tid_t tid, int flavor,
+ GPR &gpr) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestReadRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_x86_64::DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, FPURegSet, &fpu, sizeof(fpu), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_x86_64::DoReadFPU(lldb::tid_t tid, int flavor,
+ FPU &fpu) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestReadRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_x86_64::DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, EXCRegSet, &exc, sizeof(exc), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_x86_64::DoReadEXC(lldb::tid_t tid, int flavor,
+ EXC &exc) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestReadRegisters(tid, EXCRegSet, &exc, sizeof(exc),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_x86_64::DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, GPRRegSet, &gpr, sizeof(gpr), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_x86_64::DoWriteGPR(lldb::tid_t tid, int flavor,
+ const GPR &gpr) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestWriteRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_x86_64::DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, FPURegSet, &fpu, sizeof(fpu), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_x86_64::DoWriteFPU(lldb::tid_t tid, int flavor,
+ const FPU &fpu) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestWriteRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
-int
-RegisterContextKDP_x86_64::DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
-{
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, EXCRegSet, &exc, sizeof(exc), error))
- {
- if (error.Success())
- return 0;
- }
+int RegisterContextKDP_x86_64::DoWriteEXC(lldb::tid_t tid, int flavor,
+ const EXC &exc) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .SendRequestWriteRegisters(tid, EXCRegSet, &exc, sizeof(exc),
+ error)) {
+ if (error.Success())
+ return 0;
}
- return -1;
+ }
+ return -1;
}
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h
index a426349198ff..7a40bb626385 100644
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h
+++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h
@@ -18,37 +18,26 @@
class ThreadKDP;
-class RegisterContextKDP_x86_64 : public RegisterContextDarwin_x86_64
-{
+class RegisterContextKDP_x86_64 : public RegisterContextDarwin_x86_64 {
public:
-
- RegisterContextKDP_x86_64 (ThreadKDP &thread,
- uint32_t concrete_frame_idx);
-
- virtual
- ~RegisterContextKDP_x86_64();
-
+ RegisterContextKDP_x86_64(ThreadKDP &thread, uint32_t concrete_frame_idx);
+
+ virtual ~RegisterContextKDP_x86_64();
+
protected:
-
- virtual int
- DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr);
-
- int
- DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu);
-
- int
- DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc);
-
- int
- DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr);
-
- int
- DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu);
-
- int
- DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc);
-
- ThreadKDP &m_kdp_thread;
+ virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr);
+
+ int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu);
+
+ int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc);
+
+ int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr);
+
+ int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu);
+
+ int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc);
+
+ ThreadKDP &m_kdp_thread;
};
-#endif // liblldb_RegisterContextKDP_x86_64_h_
+#endif // liblldb_RegisterContextKDP_x86_64_h_
diff --git a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
index 3b8bed101a8a..273e1966f3fc 100644
--- a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
@@ -7,29 +7,28 @@
//
//===----------------------------------------------------------------------===//
-
#include "ThreadKDP.h"
#include "lldb/Utility/SafeMachO.h"
+#include "lldb/Breakpoint/Watchpoint.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/DataExtractor.h"
-#include "lldb/Core/StreamString.h"
#include "lldb/Core/State.h"
+#include "lldb/Core/StreamString.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Unwind.h"
-#include "lldb/Breakpoint/Watchpoint.h"
+#include "Plugins/Process/Utility/StopInfoMachException.h"
#include "ProcessKDP.h"
#include "ProcessKDPLog.h"
#include "RegisterContextKDP_arm.h"
#include "RegisterContextKDP_arm64.h"
#include "RegisterContextKDP_i386.h"
#include "RegisterContextKDP_x86_64.h"
-#include "Plugins/Process/Utility/StopInfoMachException.h"
using namespace lldb;
using namespace lldb_private;
@@ -38,174 +37,137 @@ using namespace lldb_private;
// Thread Registers
//----------------------------------------------------------------------
-ThreadKDP::ThreadKDP (Process &process, lldb::tid_t tid) :
- Thread(process, tid),
- m_thread_name (),
- m_dispatch_queue_name (),
- m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS)
-{
- ProcessKDPLog::LogIf(KDP_LOG_THREAD, "%p: ThreadKDP::ThreadKDP (tid = 0x%4.4x)", this, GetID());
-}
-
-ThreadKDP::~ThreadKDP ()
-{
- ProcessKDPLog::LogIf(KDP_LOG_THREAD, "%p: ThreadKDP::~ThreadKDP (tid = 0x%4.4x)", this, GetID());
- DestroyThread();
+ThreadKDP::ThreadKDP(Process &process, lldb::tid_t tid)
+ : Thread(process, tid), m_thread_name(), m_dispatch_queue_name(),
+ m_thread_dispatch_qaddr(LLDB_INVALID_ADDRESS) {
+ ProcessKDPLog::LogIf(KDP_LOG_THREAD,
+ "%p: ThreadKDP::ThreadKDP (tid = 0x%4.4x)", this,
+ GetID());
}
-const char *
-ThreadKDP::GetName ()
-{
- if (m_thread_name.empty())
- return NULL;
- return m_thread_name.c_str();
+ThreadKDP::~ThreadKDP() {
+ ProcessKDPLog::LogIf(KDP_LOG_THREAD,
+ "%p: ThreadKDP::~ThreadKDP (tid = 0x%4.4x)", this,
+ GetID());
+ DestroyThread();
}
-const char *
-ThreadKDP::GetQueueName ()
-{
+const char *ThreadKDP::GetName() {
+ if (m_thread_name.empty())
return NULL;
+ return m_thread_name.c_str();
}
-void
-ThreadKDP::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.
- const bool force = false;
- lldb::RegisterContextSP reg_ctx_sp (GetRegisterContext());
- if (reg_ctx_sp)
- reg_ctx_sp->InvalidateIfNeeded (force);
+const char *ThreadKDP::GetQueueName() { return NULL; }
+
+void ThreadKDP::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.
+ const bool force = false;
+ lldb::RegisterContextSP reg_ctx_sp(GetRegisterContext());
+ if (reg_ctx_sp)
+ reg_ctx_sp->InvalidateIfNeeded(force);
}
-bool
-ThreadKDP::ThreadIDIsValid (lldb::tid_t thread)
-{
- return thread != 0;
-}
-
-void
-ThreadKDP::Dump(Log *log, uint32_t index)
-{
-}
+bool ThreadKDP::ThreadIDIsValid(lldb::tid_t thread) { return thread != 0; }
+void ThreadKDP::Dump(Log *log, uint32_t index) {}
-bool
-ThreadKDP::ShouldStop (bool &step_more)
-{
- return true;
-}
-lldb::RegisterContextSP
-ThreadKDP::GetRegisterContext ()
-{
- if (m_reg_context_sp.get() == NULL)
- m_reg_context_sp = CreateRegisterContextForFrame (NULL);
- return m_reg_context_sp;
+bool ThreadKDP::ShouldStop(bool &step_more) { return true; }
+lldb::RegisterContextSP ThreadKDP::GetRegisterContext() {
+ if (m_reg_context_sp.get() == NULL)
+ m_reg_context_sp = CreateRegisterContextForFrame(NULL);
+ return m_reg_context_sp;
}
lldb::RegisterContextSP
-ThreadKDP::CreateRegisterContextForFrame (StackFrame *frame)
-{
- lldb::RegisterContextSP reg_ctx_sp;
- uint32_t concrete_frame_idx = 0;
-
- if (frame)
- concrete_frame_idx = frame->GetConcreteFrameIndex ();
-
- if (concrete_frame_idx == 0)
- {
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- switch (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().GetCPUType())
- {
- case llvm::MachO::CPU_TYPE_ARM:
- reg_ctx_sp.reset (new RegisterContextKDP_arm (*this, concrete_frame_idx));
- break;
- case llvm::MachO::CPU_TYPE_ARM64:
- reg_ctx_sp.reset (new RegisterContextKDP_arm64 (*this, concrete_frame_idx));
- break;
- case llvm::MachO::CPU_TYPE_I386:
- reg_ctx_sp.reset (new RegisterContextKDP_i386 (*this, concrete_frame_idx));
- break;
- case llvm::MachO::CPU_TYPE_X86_64:
- reg_ctx_sp.reset (new RegisterContextKDP_x86_64 (*this, concrete_frame_idx));
- break;
- default:
- assert (!"Add CPU type support in KDP");
- break;
- }
- }
- }
- else
- {
- Unwind *unwinder = GetUnwinder ();
- if (unwinder)
- reg_ctx_sp = unwinder->CreateRegisterContextForFrame (frame);
+ThreadKDP::CreateRegisterContextForFrame(StackFrame *frame) {
+ lldb::RegisterContextSP reg_ctx_sp;
+ uint32_t concrete_frame_idx = 0;
+
+ if (frame)
+ concrete_frame_idx = frame->GetConcreteFrameIndex();
+
+ if (concrete_frame_idx == 0) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ switch (static_cast<ProcessKDP *>(process_sp.get())
+ ->GetCommunication()
+ .GetCPUType()) {
+ case llvm::MachO::CPU_TYPE_ARM:
+ reg_ctx_sp.reset(new RegisterContextKDP_arm(*this, concrete_frame_idx));
+ break;
+ case llvm::MachO::CPU_TYPE_ARM64:
+ reg_ctx_sp.reset(
+ new RegisterContextKDP_arm64(*this, concrete_frame_idx));
+ break;
+ case llvm::MachO::CPU_TYPE_I386:
+ reg_ctx_sp.reset(
+ new RegisterContextKDP_i386(*this, concrete_frame_idx));
+ break;
+ case llvm::MachO::CPU_TYPE_X86_64:
+ reg_ctx_sp.reset(
+ new RegisterContextKDP_x86_64(*this, concrete_frame_idx));
+ break;
+ default:
+ assert(!"Add CPU type support in KDP");
+ break;
+ }
}
- return reg_ctx_sp;
+ } else {
+ Unwind *unwinder = GetUnwinder();
+ if (unwinder)
+ reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame);
+ }
+ return reg_ctx_sp;
}
-bool
-ThreadKDP::CalculateStopInfo ()
-{
- ProcessSP process_sp (GetProcess());
- if (process_sp)
- {
- if (m_cached_stop_info_sp)
- {
- SetStopInfo (m_cached_stop_info_sp);
- }
- else
- {
- SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, SIGSTOP));
- }
- return true;
+bool ThreadKDP::CalculateStopInfo() {
+ ProcessSP process_sp(GetProcess());
+ if (process_sp) {
+ if (m_cached_stop_info_sp) {
+ SetStopInfo(m_cached_stop_info_sp);
+ } else {
+ SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, SIGSTOP));
}
- return false;
+ return true;
+ }
+ return false;
}
-void
-ThreadKDP::SetStopInfoFrom_KDP_EXCEPTION (const DataExtractor &exc_reply_packet)
-{
- lldb::offset_t offset = 0;
- uint8_t reply_command = exc_reply_packet.GetU8(&offset);
- if (reply_command == CommunicationKDP::KDP_EXCEPTION)
- {
- offset = 8;
- const uint32_t count = exc_reply_packet.GetU32 (&offset);
- if (count >= 1)
- {
- //const uint32_t cpu = exc_reply_packet.GetU32 (&offset);
- offset += 4; // Skip the useless CPU field
- const uint32_t exc_type = exc_reply_packet.GetU32 (&offset);
- const uint32_t exc_code = exc_reply_packet.GetU32 (&offset);
- const uint32_t exc_subcode = exc_reply_packet.GetU32 (&offset);
- // We have to make a copy of the stop info because the thread list
- // will iterate through the threads and clear all stop infos..
-
- // Let the StopInfoMachException::CreateStopReasonWithMachException()
- // function update the PC if needed as we might hit a software breakpoint
- // and need to decrement the PC (i386 and x86_64 need this) and KDP
- // doesn't do this for us.
- const bool pc_already_adjusted = false;
- const bool adjust_pc_if_needed = true;
-
- m_cached_stop_info_sp = StopInfoMachException::CreateStopReasonWithMachException (*this,
- exc_type,
- 2,
- exc_code,
- exc_subcode,
- 0,
- pc_already_adjusted,
- adjust_pc_if_needed);
- }
+void ThreadKDP::SetStopInfoFrom_KDP_EXCEPTION(
+ const DataExtractor &exc_reply_packet) {
+ lldb::offset_t offset = 0;
+ uint8_t reply_command = exc_reply_packet.GetU8(&offset);
+ if (reply_command == CommunicationKDP::KDP_EXCEPTION) {
+ offset = 8;
+ const uint32_t count = exc_reply_packet.GetU32(&offset);
+ if (count >= 1) {
+ // const uint32_t cpu = exc_reply_packet.GetU32 (&offset);
+ offset += 4; // Skip the useless CPU field
+ const uint32_t exc_type = exc_reply_packet.GetU32(&offset);
+ const uint32_t exc_code = exc_reply_packet.GetU32(&offset);
+ const uint32_t exc_subcode = exc_reply_packet.GetU32(&offset);
+ // We have to make a copy of the stop info because the thread list
+ // will iterate through the threads and clear all stop infos..
+
+ // Let the StopInfoMachException::CreateStopReasonWithMachException()
+ // function update the PC if needed as we might hit a software breakpoint
+ // and need to decrement the PC (i386 and x86_64 need this) and KDP
+ // doesn't do this for us.
+ const bool pc_already_adjusted = false;
+ const bool adjust_pc_if_needed = true;
+
+ m_cached_stop_info_sp =
+ StopInfoMachException::CreateStopReasonWithMachException(
+ *this, exc_type, 2, exc_code, exc_subcode, 0, pc_already_adjusted,
+ adjust_pc_if_needed);
}
+ }
}
-
diff --git a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h
index 7dc373f03550..ea517b4254fc 100644
--- a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h
+++ b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h
@@ -17,82 +17,61 @@
class ProcessKDP;
-class ThreadKDP : public lldb_private::Thread
-{
+class ThreadKDP : public lldb_private::Thread {
public:
- ThreadKDP (lldb_private::Process &process,
- lldb::tid_t tid);
+ ThreadKDP(lldb_private::Process &process, lldb::tid_t tid);
- virtual
- ~ThreadKDP ();
+ virtual ~ThreadKDP();
- virtual void
- RefreshStateAfterStop();
+ virtual void RefreshStateAfterStop();
- virtual const char *
- GetName ();
+ virtual const char *GetName();
- virtual const char *
- GetQueueName ();
+ virtual const char *GetQueueName();
- virtual lldb::RegisterContextSP
- GetRegisterContext ();
+ virtual lldb::RegisterContextSP GetRegisterContext();
- virtual lldb::RegisterContextSP
- CreateRegisterContextForFrame (lldb_private::StackFrame *frame);
+ virtual lldb::RegisterContextSP
+ CreateRegisterContextForFrame(lldb_private::StackFrame *frame);
- void
- Dump (lldb_private::Log *log, uint32_t index);
+ void Dump(lldb_private::Log *log, uint32_t index);
- static bool
- ThreadIDIsValid (lldb::tid_t thread);
+ static bool ThreadIDIsValid(lldb::tid_t thread);
- bool
- ShouldStop (bool &step_more);
+ bool ShouldStop(bool &step_more);
- const char *
- GetBasicInfoAsString ();
+ const char *GetBasicInfoAsString();
- void
- SetName (const char *name)
- {
- if (name && name[0])
- m_thread_name.assign (name);
- else
- m_thread_name.clear();
- }
+ void SetName(const char *name) {
+ if (name && name[0])
+ m_thread_name.assign(name);
+ else
+ m_thread_name.clear();
+ }
- lldb::addr_t
- GetThreadDispatchQAddr ()
- {
- return m_thread_dispatch_qaddr;
- }
+ lldb::addr_t GetThreadDispatchQAddr() { return m_thread_dispatch_qaddr; }
- void
- SetThreadDispatchQAddr (lldb::addr_t thread_dispatch_qaddr)
- {
- m_thread_dispatch_qaddr = thread_dispatch_qaddr;
- }
-
- void
- SetStopInfoFrom_KDP_EXCEPTION (const lldb_private::DataExtractor &exc_reply_packet);
+ void SetThreadDispatchQAddr(lldb::addr_t thread_dispatch_qaddr) {
+ m_thread_dispatch_qaddr = thread_dispatch_qaddr;
+ }
+
+ void SetStopInfoFrom_KDP_EXCEPTION(
+ const lldb_private::DataExtractor &exc_reply_packet);
protected:
-
- friend class ProcessKDP;
-
- //------------------------------------------------------------------
- // Member variables.
- //------------------------------------------------------------------
- std::string m_thread_name;
- std::string m_dispatch_queue_name;
- lldb::addr_t m_thread_dispatch_qaddr;
- lldb::StopInfoSP m_cached_stop_info_sp;
- //------------------------------------------------------------------
- // Protected member functions.
- //------------------------------------------------------------------
- virtual bool
- CalculateStopInfo ();
+ friend class ProcessKDP;
+
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ std::string m_thread_name;
+ std::string m_dispatch_queue_name;
+ lldb::addr_t m_thread_dispatch_qaddr;
+ lldb::StopInfoSP m_cached_stop_info_sp;
+ //------------------------------------------------------------------
+ // Protected member functions.
+ //------------------------------------------------------------------
+ virtual bool CalculateStopInfo();
};
-#endif // liblldb_ThreadKDP_h_
+#endif // liblldb_ThreadKDP_h_
diff --git a/source/Plugins/Process/POSIX/CrashReason.cpp b/source/Plugins/Process/POSIX/CrashReason.cpp
index 44409a4ce552..debdd7808e63 100644
--- a/source/Plugins/Process/POSIX/CrashReason.cpp
+++ b/source/Plugins/Process/POSIX/CrashReason.cpp
@@ -9,308 +9,333 @@
#include "CrashReason.h"
+#include "llvm/Support/raw_ostream.h"
+
#include <sstream>
namespace {
-void
-AppendFaultAddr (std::string& str, lldb::addr_t addr)
-{
- std::stringstream ss;
- ss << " (fault address: 0x" << std::hex << addr << ")";
- str += ss.str();
+void AppendFaultAddr(std::string &str, lldb::addr_t addr) {
+ std::stringstream ss;
+ ss << " (fault address: 0x" << std::hex << addr << ")";
+ str += ss.str();
+}
+
+void AppendBounds(std::string &str, lldb::addr_t lower_bound,
+ lldb::addr_t upper_bound, lldb::addr_t addr) {
+ llvm::raw_string_ostream stream(str);
+ if ((unsigned long)addr < lower_bound)
+ stream << ": lower bound violation ";
+ else
+ stream << ": upper bound violation ";
+ stream << "(fault address: 0x";
+ stream.write_hex(addr);
+ stream << ", lower bound: 0x";
+ stream.write_hex(lower_bound);
+ stream << ", upper bound: 0x";
+ stream.write_hex(upper_bound);
+ stream << ")";
+ stream.flush();
}
-CrashReason
-GetCrashReasonForSIGSEGV(const siginfo_t& info)
-{
- assert(info.si_signo == SIGSEGV);
+CrashReason GetCrashReasonForSIGSEGV(const siginfo_t &info) {
+ assert(info.si_signo == SIGSEGV);
- switch (info.si_code)
- {
+ switch (info.si_code) {
#ifdef SI_KERNEL
- case SI_KERNEL:
- // Some platforms will occasionally send nonstandard spurious SI_KERNEL codes.
- // One way to get this is via unaligned SIMD loads.
- return CrashReason::eInvalidAddress; // for lack of anything better
+ case SI_KERNEL:
+ // Some platforms will occasionally send nonstandard spurious SI_KERNEL
+ // codes.
+ // One way to get this is via unaligned SIMD loads.
+ return CrashReason::eInvalidAddress; // for lack of anything better
#endif
- case SEGV_MAPERR:
- return CrashReason::eInvalidAddress;
- case SEGV_ACCERR:
- return CrashReason::ePrivilegedAddress;
- }
-
- assert(false && "unexpected si_code for SIGSEGV");
- return CrashReason::eInvalidCrashReason;
-}
+ case SEGV_MAPERR:
+ return CrashReason::eInvalidAddress;
+ case SEGV_ACCERR:
+ return CrashReason::ePrivilegedAddress;
+#ifndef SEGV_BNDERR
+#define SEGV_BNDERR 3
+#endif
+ case SEGV_BNDERR:
+ return CrashReason::eBoundViolation;
+ }
-CrashReason
-GetCrashReasonForSIGILL(const siginfo_t& info)
-{
- assert(info.si_signo == SIGILL);
-
- switch (info.si_code)
- {
- case ILL_ILLOPC:
- return CrashReason::eIllegalOpcode;
- case ILL_ILLOPN:
- return CrashReason::eIllegalOperand;
- case ILL_ILLADR:
- return CrashReason::eIllegalAddressingMode;
- case ILL_ILLTRP:
- return CrashReason::eIllegalTrap;
- case ILL_PRVOPC:
- return CrashReason::ePrivilegedOpcode;
- case ILL_PRVREG:
- return CrashReason::ePrivilegedRegister;
- case ILL_COPROC:
- return CrashReason::eCoprocessorError;
- case ILL_BADSTK:
- return CrashReason::eInternalStackError;
- }
-
- assert(false && "unexpected si_code for SIGILL");
- return CrashReason::eInvalidCrashReason;
+ assert(false && "unexpected si_code for SIGSEGV");
+ return CrashReason::eInvalidCrashReason;
}
-CrashReason
-GetCrashReasonForSIGFPE(const siginfo_t& info)
-{
- assert(info.si_signo == SIGFPE);
-
- switch (info.si_code)
- {
- case FPE_INTDIV:
- return CrashReason::eIntegerDivideByZero;
- case FPE_INTOVF:
- return CrashReason::eIntegerOverflow;
- case FPE_FLTDIV:
- return CrashReason::eFloatDivideByZero;
- case FPE_FLTOVF:
- return CrashReason::eFloatOverflow;
- case FPE_FLTUND:
- return CrashReason::eFloatUnderflow;
- case FPE_FLTRES:
- return CrashReason::eFloatInexactResult;
- case FPE_FLTINV:
- return CrashReason::eFloatInvalidOperation;
- case FPE_FLTSUB:
- return CrashReason::eFloatSubscriptRange;
- }
-
- assert(false && "unexpected si_code for SIGFPE");
- return CrashReason::eInvalidCrashReason;
+CrashReason GetCrashReasonForSIGILL(const siginfo_t &info) {
+ assert(info.si_signo == SIGILL);
+
+ switch (info.si_code) {
+ case ILL_ILLOPC:
+ return CrashReason::eIllegalOpcode;
+ case ILL_ILLOPN:
+ return CrashReason::eIllegalOperand;
+ case ILL_ILLADR:
+ return CrashReason::eIllegalAddressingMode;
+ case ILL_ILLTRP:
+ return CrashReason::eIllegalTrap;
+ case ILL_PRVOPC:
+ return CrashReason::ePrivilegedOpcode;
+ case ILL_PRVREG:
+ return CrashReason::ePrivilegedRegister;
+ case ILL_COPROC:
+ return CrashReason::eCoprocessorError;
+ case ILL_BADSTK:
+ return CrashReason::eInternalStackError;
+ }
+
+ assert(false && "unexpected si_code for SIGILL");
+ return CrashReason::eInvalidCrashReason;
}
-CrashReason
-GetCrashReasonForSIGBUS(const siginfo_t& info)
-{
- assert(info.si_signo == SIGBUS);
-
- switch (info.si_code)
- {
- case BUS_ADRALN:
- return CrashReason::eIllegalAlignment;
- case BUS_ADRERR:
- return CrashReason::eIllegalAddress;
- case BUS_OBJERR:
- return CrashReason::eHardwareError;
- }
-
- assert(false && "unexpected si_code for SIGBUS");
- return CrashReason::eInvalidCrashReason;
+CrashReason GetCrashReasonForSIGFPE(const siginfo_t &info) {
+ assert(info.si_signo == SIGFPE);
+
+ switch (info.si_code) {
+ case FPE_INTDIV:
+ return CrashReason::eIntegerDivideByZero;
+ case FPE_INTOVF:
+ return CrashReason::eIntegerOverflow;
+ case FPE_FLTDIV:
+ return CrashReason::eFloatDivideByZero;
+ case FPE_FLTOVF:
+ return CrashReason::eFloatOverflow;
+ case FPE_FLTUND:
+ return CrashReason::eFloatUnderflow;
+ case FPE_FLTRES:
+ return CrashReason::eFloatInexactResult;
+ case FPE_FLTINV:
+ return CrashReason::eFloatInvalidOperation;
+ case FPE_FLTSUB:
+ return CrashReason::eFloatSubscriptRange;
+ }
+
+ assert(false && "unexpected si_code for SIGFPE");
+ return CrashReason::eInvalidCrashReason;
}
+CrashReason GetCrashReasonForSIGBUS(const siginfo_t &info) {
+ assert(info.si_signo == SIGBUS);
+
+ switch (info.si_code) {
+ case BUS_ADRALN:
+ return CrashReason::eIllegalAlignment;
+ case BUS_ADRERR:
+ return CrashReason::eIllegalAddress;
+ case BUS_OBJERR:
+ return CrashReason::eHardwareError;
+ }
+
+ assert(false && "unexpected si_code for SIGBUS");
+ return CrashReason::eInvalidCrashReason;
+}
}
-std::string
-GetCrashReasonString (CrashReason reason, lldb::addr_t fault_addr)
-{
- std::string str;
-
- switch (reason)
- {
- default:
- assert(false && "invalid CrashReason");
- break;
-
- case CrashReason::eInvalidAddress:
- str = "signal SIGSEGV: invalid address";
- AppendFaultAddr (str, fault_addr);
- break;
- case CrashReason::ePrivilegedAddress:
- str = "signal SIGSEGV: address access protected";
- AppendFaultAddr (str, fault_addr);
- break;
- case CrashReason::eIllegalOpcode:
- str = "signal SIGILL: illegal instruction";
- break;
- case CrashReason::eIllegalOperand:
- str = "signal SIGILL: illegal instruction operand";
- break;
- case CrashReason::eIllegalAddressingMode:
- str = "signal SIGILL: illegal addressing mode";
- break;
- case CrashReason::eIllegalTrap:
- str = "signal SIGILL: illegal trap";
- break;
- case CrashReason::ePrivilegedOpcode:
- str = "signal SIGILL: privileged instruction";
- break;
- case CrashReason::ePrivilegedRegister:
- str = "signal SIGILL: privileged register";
- break;
- case CrashReason::eCoprocessorError:
- str = "signal SIGILL: coprocessor error";
- break;
- case CrashReason::eInternalStackError:
- str = "signal SIGILL: internal stack error";
- break;
- case CrashReason::eIllegalAlignment:
- str = "signal SIGBUS: illegal alignment";
- break;
- case CrashReason::eIllegalAddress:
- str = "signal SIGBUS: illegal address";
- break;
- case CrashReason::eHardwareError:
- str = "signal SIGBUS: hardware error";
- break;
- case CrashReason::eIntegerDivideByZero:
- str = "signal SIGFPE: integer divide by zero";
- break;
- case CrashReason::eIntegerOverflow:
- str = "signal SIGFPE: integer overflow";
- break;
- case CrashReason::eFloatDivideByZero:
- str = "signal SIGFPE: floating point divide by zero";
- break;
- case CrashReason::eFloatOverflow:
- str = "signal SIGFPE: floating point overflow";
- break;
- case CrashReason::eFloatUnderflow:
- str = "signal SIGFPE: floating point underflow";
- break;
- case CrashReason::eFloatInexactResult:
- str = "signal SIGFPE: inexact floating point result";
- break;
- case CrashReason::eFloatInvalidOperation:
- str = "signal SIGFPE: invalid floating point operation";
- break;
- case CrashReason::eFloatSubscriptRange:
- str = "signal SIGFPE: invalid floating point subscript range";
- break;
- }
+std::string GetCrashReasonString(CrashReason reason, const siginfo_t &info) {
+ std::string str;
+// make sure that siginfo_t has the bound fields available.
+#if defined(si_lower) && defined(si_upper)
+ if (reason == CrashReason::eBoundViolation) {
+ str = "signal SIGSEGV";
+ AppendBounds(str, reinterpret_cast<lldb::addr_t>(info.si_lower),
+ reinterpret_cast<lldb::addr_t>(info.si_upper),
+ reinterpret_cast<lldb::addr_t>(info.si_addr));
return str;
+ }
+#endif
+
+ return GetCrashReasonString(reason,
+ reinterpret_cast<lldb::addr_t>(info.si_addr));
}
-const char *
-CrashReasonAsString (CrashReason reason)
-{
+std::string GetCrashReasonString(CrashReason reason, lldb::addr_t fault_addr) {
+ std::string str;
+
+ switch (reason) {
+ default:
+ assert(false && "invalid CrashReason");
+ break;
+
+ case CrashReason::eInvalidAddress:
+ str = "signal SIGSEGV: invalid address";
+ AppendFaultAddr(str, fault_addr);
+ break;
+ case CrashReason::ePrivilegedAddress:
+ str = "signal SIGSEGV: address access protected";
+ AppendFaultAddr(str, fault_addr);
+ break;
+ case CrashReason::eBoundViolation:
+ str = "signal SIGSEGV: bound violation";
+ break;
+ case CrashReason::eIllegalOpcode:
+ str = "signal SIGILL: illegal instruction";
+ break;
+ case CrashReason::eIllegalOperand:
+ str = "signal SIGILL: illegal instruction operand";
+ break;
+ case CrashReason::eIllegalAddressingMode:
+ str = "signal SIGILL: illegal addressing mode";
+ break;
+ case CrashReason::eIllegalTrap:
+ str = "signal SIGILL: illegal trap";
+ break;
+ case CrashReason::ePrivilegedOpcode:
+ str = "signal SIGILL: privileged instruction";
+ break;
+ case CrashReason::ePrivilegedRegister:
+ str = "signal SIGILL: privileged register";
+ break;
+ case CrashReason::eCoprocessorError:
+ str = "signal SIGILL: coprocessor error";
+ break;
+ case CrashReason::eInternalStackError:
+ str = "signal SIGILL: internal stack error";
+ break;
+ case CrashReason::eIllegalAlignment:
+ str = "signal SIGBUS: illegal alignment";
+ break;
+ case CrashReason::eIllegalAddress:
+ str = "signal SIGBUS: illegal address";
+ break;
+ case CrashReason::eHardwareError:
+ str = "signal SIGBUS: hardware error";
+ break;
+ case CrashReason::eIntegerDivideByZero:
+ str = "signal SIGFPE: integer divide by zero";
+ break;
+ case CrashReason::eIntegerOverflow:
+ str = "signal SIGFPE: integer overflow";
+ break;
+ case CrashReason::eFloatDivideByZero:
+ str = "signal SIGFPE: floating point divide by zero";
+ break;
+ case CrashReason::eFloatOverflow:
+ str = "signal SIGFPE: floating point overflow";
+ break;
+ case CrashReason::eFloatUnderflow:
+ str = "signal SIGFPE: floating point underflow";
+ break;
+ case CrashReason::eFloatInexactResult:
+ str = "signal SIGFPE: inexact floating point result";
+ break;
+ case CrashReason::eFloatInvalidOperation:
+ str = "signal SIGFPE: invalid floating point operation";
+ break;
+ case CrashReason::eFloatSubscriptRange:
+ str = "signal SIGFPE: invalid floating point subscript range";
+ break;
+ }
+
+ return str;
+}
+
+const char *CrashReasonAsString(CrashReason reason) {
#ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION
- // Just return the code in ascii for integration builds.
- chcar str[8];
- sprintf(str, "%d", reason);
+ // Just return the code in ascii for integration builds.
+ chcar str[8];
+ sprintf(str, "%d", reason);
#else
- const char *str = nullptr;
-
- switch (reason)
- {
- case CrashReason::eInvalidCrashReason:
- str = "eInvalidCrashReason";
- break;
-
- // SIGSEGV crash reasons.
- case CrashReason::eInvalidAddress:
- str = "eInvalidAddress";
- break;
- case CrashReason::ePrivilegedAddress:
- str = "ePrivilegedAddress";
- break;
-
- // SIGILL crash reasons.
- case CrashReason::eIllegalOpcode:
- str = "eIllegalOpcode";
- break;
- case CrashReason::eIllegalOperand:
- str = "eIllegalOperand";
- break;
- case CrashReason::eIllegalAddressingMode:
- str = "eIllegalAddressingMode";
- break;
- case CrashReason::eIllegalTrap:
- str = "eIllegalTrap";
- break;
- case CrashReason::ePrivilegedOpcode:
- str = "ePrivilegedOpcode";
- break;
- case CrashReason::ePrivilegedRegister:
- str = "ePrivilegedRegister";
- break;
- case CrashReason::eCoprocessorError:
- str = "eCoprocessorError";
- break;
- case CrashReason::eInternalStackError:
- str = "eInternalStackError";
- break;
-
- // SIGBUS crash reasons:
- case CrashReason::eIllegalAlignment:
- str = "eIllegalAlignment";
- break;
- case CrashReason::eIllegalAddress:
- str = "eIllegalAddress";
- break;
- case CrashReason::eHardwareError:
- str = "eHardwareError";
- break;
-
- // SIGFPE crash reasons:
- case CrashReason::eIntegerDivideByZero:
- str = "eIntegerDivideByZero";
- break;
- case CrashReason::eIntegerOverflow:
- str = "eIntegerOverflow";
- break;
- case CrashReason::eFloatDivideByZero:
- str = "eFloatDivideByZero";
- break;
- case CrashReason::eFloatOverflow:
- str = "eFloatOverflow";
- break;
- case CrashReason::eFloatUnderflow:
- str = "eFloatUnderflow";
- break;
- case CrashReason::eFloatInexactResult:
- str = "eFloatInexactResult";
- break;
- case CrashReason::eFloatInvalidOperation:
- str = "eFloatInvalidOperation";
- break;
- case CrashReason::eFloatSubscriptRange:
- str = "eFloatSubscriptRange";
- break;
- }
+ const char *str = nullptr;
+
+ switch (reason) {
+ case CrashReason::eInvalidCrashReason:
+ str = "eInvalidCrashReason";
+ break;
+
+ // SIGSEGV crash reasons.
+ case CrashReason::eInvalidAddress:
+ str = "eInvalidAddress";
+ break;
+ case CrashReason::ePrivilegedAddress:
+ str = "ePrivilegedAddress";
+ break;
+ case CrashReason::eBoundViolation:
+ str = "eBoundViolation";
+ break;
+
+ // SIGILL crash reasons.
+ case CrashReason::eIllegalOpcode:
+ str = "eIllegalOpcode";
+ break;
+ case CrashReason::eIllegalOperand:
+ str = "eIllegalOperand";
+ break;
+ case CrashReason::eIllegalAddressingMode:
+ str = "eIllegalAddressingMode";
+ break;
+ case CrashReason::eIllegalTrap:
+ str = "eIllegalTrap";
+ break;
+ case CrashReason::ePrivilegedOpcode:
+ str = "ePrivilegedOpcode";
+ break;
+ case CrashReason::ePrivilegedRegister:
+ str = "ePrivilegedRegister";
+ break;
+ case CrashReason::eCoprocessorError:
+ str = "eCoprocessorError";
+ break;
+ case CrashReason::eInternalStackError:
+ str = "eInternalStackError";
+ break;
+
+ // SIGBUS crash reasons:
+ case CrashReason::eIllegalAlignment:
+ str = "eIllegalAlignment";
+ break;
+ case CrashReason::eIllegalAddress:
+ str = "eIllegalAddress";
+ break;
+ case CrashReason::eHardwareError:
+ str = "eHardwareError";
+ break;
+
+ // SIGFPE crash reasons:
+ case CrashReason::eIntegerDivideByZero:
+ str = "eIntegerDivideByZero";
+ break;
+ case CrashReason::eIntegerOverflow:
+ str = "eIntegerOverflow";
+ break;
+ case CrashReason::eFloatDivideByZero:
+ str = "eFloatDivideByZero";
+ break;
+ case CrashReason::eFloatOverflow:
+ str = "eFloatOverflow";
+ break;
+ case CrashReason::eFloatUnderflow:
+ str = "eFloatUnderflow";
+ break;
+ case CrashReason::eFloatInexactResult:
+ str = "eFloatInexactResult";
+ break;
+ case CrashReason::eFloatInvalidOperation:
+ str = "eFloatInvalidOperation";
+ break;
+ case CrashReason::eFloatSubscriptRange:
+ str = "eFloatSubscriptRange";
+ break;
+ }
#endif
- return str;
+ return str;
}
-CrashReason
-GetCrashReason(const siginfo_t& info)
-{
- switch(info.si_signo)
- {
- case SIGSEGV:
- return GetCrashReasonForSIGSEGV(info);
- case SIGBUS:
- return GetCrashReasonForSIGBUS(info);
- case SIGFPE:
- return GetCrashReasonForSIGFPE(info);
- case SIGILL:
- return GetCrashReasonForSIGILL(info);
- }
-
- assert(false && "unexpected signal");
- return CrashReason::eInvalidCrashReason;
+CrashReason GetCrashReason(const siginfo_t &info) {
+ switch (info.si_signo) {
+ case SIGSEGV:
+ return GetCrashReasonForSIGSEGV(info);
+ case SIGBUS:
+ return GetCrashReasonForSIGBUS(info);
+ case SIGFPE:
+ return GetCrashReasonForSIGFPE(info);
+ case SIGILL:
+ return GetCrashReasonForSIGILL(info);
+ }
+
+ assert(false && "unexpected signal");
+ return CrashReason::eInvalidCrashReason;
}
diff --git a/source/Plugins/Process/POSIX/CrashReason.h b/source/Plugins/Process/POSIX/CrashReason.h
index f6d9ba553e4a..57abe47b46b2 100644
--- a/source/Plugins/Process/POSIX/CrashReason.h
+++ b/source/Plugins/Process/POSIX/CrashReason.h
@@ -16,47 +16,45 @@
#include <string>
-enum class CrashReason
-{
- eInvalidCrashReason,
-
- // SIGSEGV crash reasons.
- eInvalidAddress,
- ePrivilegedAddress,
-
- // SIGILL crash reasons.
- eIllegalOpcode,
- eIllegalOperand,
- eIllegalAddressingMode,
- eIllegalTrap,
- ePrivilegedOpcode,
- ePrivilegedRegister,
- eCoprocessorError,
- eInternalStackError,
-
- // SIGBUS crash reasons,
- eIllegalAlignment,
- eIllegalAddress,
- eHardwareError,
-
- // SIGFPE crash reasons,
- eIntegerDivideByZero,
- eIntegerOverflow,
- eFloatDivideByZero,
- eFloatOverflow,
- eFloatUnderflow,
- eFloatInexactResult,
- eFloatInvalidOperation,
- eFloatSubscriptRange
+enum class CrashReason {
+ eInvalidCrashReason,
+
+ // SIGSEGV crash reasons.
+ eInvalidAddress,
+ ePrivilegedAddress,
+ eBoundViolation,
+
+ // SIGILL crash reasons.
+ eIllegalOpcode,
+ eIllegalOperand,
+ eIllegalAddressingMode,
+ eIllegalTrap,
+ ePrivilegedOpcode,
+ ePrivilegedRegister,
+ eCoprocessorError,
+ eInternalStackError,
+
+ // SIGBUS crash reasons,
+ eIllegalAlignment,
+ eIllegalAddress,
+ eHardwareError,
+
+ // SIGFPE crash reasons,
+ eIntegerDivideByZero,
+ eIntegerOverflow,
+ eFloatDivideByZero,
+ eFloatOverflow,
+ eFloatUnderflow,
+ eFloatInexactResult,
+ eFloatInvalidOperation,
+ eFloatSubscriptRange
};
-std::string
-GetCrashReasonString (CrashReason reason, lldb::addr_t fault_addr);
+std::string GetCrashReasonString(CrashReason reason, lldb::addr_t fault_addr);
+std::string GetCrashReasonString(CrashReason reason, const siginfo_t &info);
-const char *
-CrashReasonAsString (CrashReason reason);
+const char *CrashReasonAsString(CrashReason reason);
-CrashReason
-GetCrashReason(const siginfo_t& info);
+CrashReason GetCrashReason(const siginfo_t &info);
#endif // #ifndef liblldb_CrashReason_H_
diff --git a/source/Plugins/Process/POSIX/ProcessMessage.cpp b/source/Plugins/Process/POSIX/ProcessMessage.cpp
index 02049a2af953..48f2a7844cf7 100644
--- a/source/Plugins/Process/POSIX/ProcessMessage.cpp
+++ b/source/Plugins/Process/POSIX/ProcessMessage.cpp
@@ -11,68 +11,59 @@
using namespace lldb_private;
-const char *
-ProcessMessage::PrintCrashReason() const
-{
- return CrashReasonAsString(m_crash_reason);
+const char *ProcessMessage::PrintCrashReason() const {
+ return CrashReasonAsString(m_crash_reason);
}
-const char *
-ProcessMessage::PrintKind(Kind kind)
-{
+const char *ProcessMessage::PrintKind(Kind kind) {
#ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION
- // Just return the code in ascii for integration builds.
- chcar str[8];
- sprintf(str, "%d", reason);
+ // Just return the code in ascii for integration builds.
+ chcar str[8];
+ sprintf(str, "%d", reason);
#else
- const char *str = NULL;
+ const char *str = NULL;
- switch (kind)
- {
- case eInvalidMessage:
- str = "eInvalidMessage";
- break;
- case eAttachMessage:
- str = "eAttachMessage";
- break;
- case eExitMessage:
- str = "eExitMessage";
- break;
- case eLimboMessage:
- str = "eLimboMessage";
- break;
- case eSignalMessage:
- str = "eSignalMessage";
- break;
- case eSignalDeliveredMessage:
- str = "eSignalDeliveredMessage";
- break;
- case eTraceMessage:
- str = "eTraceMessage";
- break;
- case eBreakpointMessage:
- str = "eBreakpointMessage";
- break;
- case eWatchpointMessage:
- str = "eWatchpointMessage";
- break;
- case eCrashMessage:
- str = "eCrashMessage";
- break;
- case eNewThreadMessage:
- str = "eNewThreadMessage";
- break;
- case eExecMessage:
- str = "eExecMessage";
- break;
- }
+ switch (kind) {
+ case eInvalidMessage:
+ str = "eInvalidMessage";
+ break;
+ case eAttachMessage:
+ str = "eAttachMessage";
+ break;
+ case eExitMessage:
+ str = "eExitMessage";
+ break;
+ case eLimboMessage:
+ str = "eLimboMessage";
+ break;
+ case eSignalMessage:
+ str = "eSignalMessage";
+ break;
+ case eSignalDeliveredMessage:
+ str = "eSignalDeliveredMessage";
+ break;
+ case eTraceMessage:
+ str = "eTraceMessage";
+ break;
+ case eBreakpointMessage:
+ str = "eBreakpointMessage";
+ break;
+ case eWatchpointMessage:
+ str = "eWatchpointMessage";
+ break;
+ case eCrashMessage:
+ str = "eCrashMessage";
+ break;
+ case eNewThreadMessage:
+ str = "eNewThreadMessage";
+ break;
+ case eExecMessage:
+ str = "eExecMessage";
+ break;
+ }
#endif
- return str;
+ return str;
}
-const char *
-ProcessMessage::PrintKind() const
-{
- return PrintKind(m_kind);
-}
+const char *ProcessMessage::PrintKind() const { return PrintKind(m_kind); }
diff --git a/source/Plugins/Process/POSIX/ProcessMessage.h b/source/Plugins/Process/POSIX/ProcessMessage.h
index f932e9fff278..3c596ca68549 100644
--- a/source/Plugins/Process/POSIX/ProcessMessage.h
+++ b/source/Plugins/Process/POSIX/ProcessMessage.h
@@ -18,165 +18,152 @@
#include "lldb/lldb-defines.h"
#include "lldb/lldb-types.h"
-class ProcessMessage
-{
+class ProcessMessage {
public:
-
- /// The type of signal this message can correspond to.
- enum Kind
- {
- eInvalidMessage,
- eAttachMessage,
- eExitMessage,
- eLimboMessage,
- eSignalMessage,
- eSignalDeliveredMessage,
- eTraceMessage,
- eBreakpointMessage,
- eWatchpointMessage,
- eCrashMessage,
- eNewThreadMessage,
- eExecMessage
- };
-
- ProcessMessage()
- : m_tid(LLDB_INVALID_PROCESS_ID),
- m_kind(eInvalidMessage),
- m_crash_reason(CrashReason::eInvalidCrashReason),
- m_status(0),
- m_addr(0) { }
-
- Kind GetKind() const { return m_kind; }
-
- lldb::tid_t GetTID() const { return m_tid; }
-
- /// Indicates that the process @p pid has successfully attached.
- static ProcessMessage Attach(lldb::pid_t pid) {
- return ProcessMessage(pid, eAttachMessage);
- }
-
- /// Indicates that the thread @p tid is about to exit with status @p status.
- static ProcessMessage Limbo(lldb::tid_t tid, int status) {
- return ProcessMessage(tid, eLimboMessage, status);
- }
-
- /// Indicates that the thread @p tid had the signal @p signum delivered.
- static ProcessMessage Signal(lldb::tid_t tid, int signum) {
- return ProcessMessage(tid, eSignalMessage, signum);
- }
-
- /// Indicates that a signal @p signum generated by the debugging process was
- /// delivered to the thread @p tid.
- static ProcessMessage SignalDelivered(lldb::tid_t tid, int signum) {
- return ProcessMessage(tid, eSignalDeliveredMessage, signum);
- }
-
- /// Indicates that the thread @p tid encountered a trace point.
- static ProcessMessage Trace(lldb::tid_t tid) {
- return ProcessMessage(tid, eTraceMessage);
- }
-
- /// Indicates that the thread @p tid encountered a break point.
- static ProcessMessage Break(lldb::tid_t tid) {
- return ProcessMessage(tid, eBreakpointMessage);
- }
-
- static ProcessMessage Watch(lldb::tid_t tid, lldb::addr_t wp_addr) {
- return ProcessMessage(tid, eWatchpointMessage, 0, wp_addr);
- }
-
- /// Indicates that the thread @p tid crashed.
- static ProcessMessage Crash(lldb::pid_t pid, CrashReason reason,
- int signo, lldb::addr_t fault_addr) {
- ProcessMessage message(pid, eCrashMessage, signo, fault_addr);
- message.m_crash_reason = reason;
- return message;
- }
-
- /// Indicates that the thread @p child_tid was spawned.
- static ProcessMessage NewThread(lldb::tid_t parent_tid, lldb::tid_t child_tid) {
- return ProcessMessage(parent_tid, eNewThreadMessage, child_tid);
- }
-
- /// Indicates that the thread @p tid is about to exit with status @p status.
- static ProcessMessage Exit(lldb::tid_t tid, int status) {
- return ProcessMessage(tid, eExitMessage, status);
- }
-
- /// Indicates that the thread @p pid has exec'd.
- static ProcessMessage Exec(lldb::tid_t tid) {
- return ProcessMessage(tid, eExecMessage);
- }
-
- int GetExitStatus() const {
- assert(GetKind() == eExitMessage || GetKind() == eLimboMessage);
- return m_status;
- }
-
- int GetSignal() const {
- assert(GetKind() == eSignalMessage || GetKind() == eCrashMessage ||
- GetKind() == eSignalDeliveredMessage);
- return m_status;
- }
-
- int GetStopStatus() const {
- assert(GetKind() == eSignalMessage);
- return m_status;
- }
-
- CrashReason GetCrashReason() const {
- assert(GetKind() == eCrashMessage);
- return m_crash_reason;
- }
-
- lldb::addr_t GetFaultAddress() const {
- assert(GetKind() == eCrashMessage);
- return m_addr;
- }
-
- lldb::addr_t GetHWAddress() const {
- assert(GetKind() == eWatchpointMessage || GetKind() == eTraceMessage);
- return m_addr;
- }
-
- lldb::tid_t GetChildTID() const {
- assert(GetKind() == eNewThreadMessage);
- return m_child_tid;
- }
-
- const char *
- PrintCrashReason() const;
-
- const char *
- PrintKind() const;
-
- static const char *
- PrintKind(Kind);
+ /// The type of signal this message can correspond to.
+ enum Kind {
+ eInvalidMessage,
+ eAttachMessage,
+ eExitMessage,
+ eLimboMessage,
+ eSignalMessage,
+ eSignalDeliveredMessage,
+ eTraceMessage,
+ eBreakpointMessage,
+ eWatchpointMessage,
+ eCrashMessage,
+ eNewThreadMessage,
+ eExecMessage
+ };
+
+ ProcessMessage()
+ : m_tid(LLDB_INVALID_PROCESS_ID), m_kind(eInvalidMessage),
+ m_crash_reason(CrashReason::eInvalidCrashReason), m_status(0),
+ m_addr(0) {}
+
+ Kind GetKind() const { return m_kind; }
+
+ lldb::tid_t GetTID() const { return m_tid; }
+
+ /// Indicates that the process @p pid has successfully attached.
+ static ProcessMessage Attach(lldb::pid_t pid) {
+ return ProcessMessage(pid, eAttachMessage);
+ }
+
+ /// Indicates that the thread @p tid is about to exit with status @p status.
+ static ProcessMessage Limbo(lldb::tid_t tid, int status) {
+ return ProcessMessage(tid, eLimboMessage, status);
+ }
+
+ /// Indicates that the thread @p tid had the signal @p signum delivered.
+ static ProcessMessage Signal(lldb::tid_t tid, int signum) {
+ return ProcessMessage(tid, eSignalMessage, signum);
+ }
+
+ /// Indicates that a signal @p signum generated by the debugging process was
+ /// delivered to the thread @p tid.
+ static ProcessMessage SignalDelivered(lldb::tid_t tid, int signum) {
+ return ProcessMessage(tid, eSignalDeliveredMessage, signum);
+ }
+
+ /// Indicates that the thread @p tid encountered a trace point.
+ static ProcessMessage Trace(lldb::tid_t tid) {
+ return ProcessMessage(tid, eTraceMessage);
+ }
+
+ /// Indicates that the thread @p tid encountered a break point.
+ static ProcessMessage Break(lldb::tid_t tid) {
+ return ProcessMessage(tid, eBreakpointMessage);
+ }
+
+ static ProcessMessage Watch(lldb::tid_t tid, lldb::addr_t wp_addr) {
+ return ProcessMessage(tid, eWatchpointMessage, 0, wp_addr);
+ }
+
+ /// Indicates that the thread @p tid crashed.
+ static ProcessMessage Crash(lldb::pid_t pid, CrashReason reason, int signo,
+ lldb::addr_t fault_addr) {
+ ProcessMessage message(pid, eCrashMessage, signo, fault_addr);
+ message.m_crash_reason = reason;
+ return message;
+ }
+
+ /// Indicates that the thread @p child_tid was spawned.
+ static ProcessMessage NewThread(lldb::tid_t parent_tid,
+ lldb::tid_t child_tid) {
+ return ProcessMessage(parent_tid, eNewThreadMessage, child_tid);
+ }
+
+ /// Indicates that the thread @p tid is about to exit with status @p status.
+ static ProcessMessage Exit(lldb::tid_t tid, int status) {
+ return ProcessMessage(tid, eExitMessage, status);
+ }
+
+ /// Indicates that the thread @p pid has exec'd.
+ static ProcessMessage Exec(lldb::tid_t tid) {
+ return ProcessMessage(tid, eExecMessage);
+ }
+
+ int GetExitStatus() const {
+ assert(GetKind() == eExitMessage || GetKind() == eLimboMessage);
+ return m_status;
+ }
+
+ int GetSignal() const {
+ assert(GetKind() == eSignalMessage || GetKind() == eCrashMessage ||
+ GetKind() == eSignalDeliveredMessage);
+ return m_status;
+ }
+
+ int GetStopStatus() const {
+ assert(GetKind() == eSignalMessage);
+ return m_status;
+ }
+
+ CrashReason GetCrashReason() const {
+ assert(GetKind() == eCrashMessage);
+ return m_crash_reason;
+ }
+
+ lldb::addr_t GetFaultAddress() const {
+ assert(GetKind() == eCrashMessage);
+ return m_addr;
+ }
+
+ lldb::addr_t GetHWAddress() const {
+ assert(GetKind() == eWatchpointMessage || GetKind() == eTraceMessage);
+ return m_addr;
+ }
+
+ lldb::tid_t GetChildTID() const {
+ assert(GetKind() == eNewThreadMessage);
+ return m_child_tid;
+ }
+
+ const char *PrintCrashReason() const;
+
+ const char *PrintKind() const;
+
+ static const char *PrintKind(Kind);
private:
- ProcessMessage(lldb::tid_t tid, Kind kind,
- int status = 0, lldb::addr_t addr = 0)
- : m_tid(tid),
- m_kind(kind),
- m_crash_reason(CrashReason::eInvalidCrashReason),
- m_status(status),
- m_addr(addr),
- m_child_tid(0) { }
-
- ProcessMessage(lldb::tid_t tid, Kind kind, lldb::tid_t child_tid)
- : m_tid(tid),
- m_kind(kind),
- m_crash_reason(CrashReason::eInvalidCrashReason),
- m_status(0),
- m_addr(0),
- m_child_tid(child_tid) { }
-
- lldb::tid_t m_tid;
- Kind m_kind : 8;
- CrashReason m_crash_reason;
- int m_status;
- lldb::addr_t m_addr;
- lldb::tid_t m_child_tid;
+ ProcessMessage(lldb::tid_t tid, Kind kind, int status = 0,
+ lldb::addr_t addr = 0)
+ : m_tid(tid), m_kind(kind),
+ m_crash_reason(CrashReason::eInvalidCrashReason), m_status(status),
+ m_addr(addr), m_child_tid(0) {}
+
+ ProcessMessage(lldb::tid_t tid, Kind kind, lldb::tid_t child_tid)
+ : m_tid(tid), m_kind(kind),
+ m_crash_reason(CrashReason::eInvalidCrashReason), m_status(0),
+ m_addr(0), m_child_tid(child_tid) {}
+
+ lldb::tid_t m_tid;
+ Kind m_kind : 8;
+ CrashReason m_crash_reason;
+ int m_status;
+ lldb::addr_t m_addr;
+ lldb::tid_t m_child_tid;
};
#endif // #ifndef liblldb_ProcessMessage_H_
diff --git a/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp b/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp
index b259804a3a27..9ced11c7ca2a 100644
--- a/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp
+++ b/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp
@@ -1,4 +1,5 @@
-//===-- ProcessPOSIXLog.cpp ---------------------------------------*- C++ -*-===//
+//===-- ProcessPOSIXLog.cpp ---------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,199 +12,185 @@
#include <mutex>
-#include "lldb/Interpreter/Args.h"
#include "lldb/Core/StreamFile.h"
+#include "lldb/Interpreter/Args.h"
#include "ProcessPOSIXLog.h"
using namespace lldb;
using namespace lldb_private;
-
// We want to avoid global constructors where code needs to be run so here we
// control access to our static g_log_sp by hiding it in a singleton function
-// that will construct the static g_log_sp the first time this function is
+// that will construct the static g_log_sp the first time this function is
// called.
static bool g_log_enabled = false;
-static Log * g_log = NULL;
-static Log *
-GetLog ()
-{
- if (!g_log_enabled)
- return NULL;
- return g_log;
+static Log *g_log = NULL;
+static Log *GetLog() {
+ if (!g_log_enabled)
+ return NULL;
+ return g_log;
}
-void
-ProcessPOSIXLog::Initialize(ConstString name)
-{
- static std::once_flag g_once_flag;
-
- std::call_once(g_once_flag, [name](){
- Log::Callbacks log_callbacks = {
- DisableLog,
- EnableLog,
- ListLogCategories
- };
-
- Log::RegisterLogChannel (name, log_callbacks);
- RegisterPluginName(name);
- });
-}
+void ProcessPOSIXLog::Initialize(ConstString name) {
+ static std::once_flag g_once_flag;
-Log *
-ProcessPOSIXLog::GetLogIfAllCategoriesSet (uint32_t mask)
-{
- Log *log(GetLog ());
- if (log && mask)
- {
- uint32_t log_mask = log->GetMask().Get();
- if ((log_mask & mask) != mask)
- return NULL;
- }
- return log;
+ std::call_once(g_once_flag, [name]() {
+ Log::Callbacks log_callbacks = {DisableLog, EnableLog, ListLogCategories};
+
+ Log::RegisterLogChannel(name, log_callbacks);
+ RegisterPluginName(name);
+ });
}
-static uint32_t
-GetFlagBits (const char *arg)
-{
- if (::strcasecmp (arg, "all") == 0 ) return POSIX_LOG_ALL;
- else if (::strcasecmp (arg, "async") == 0 ) return POSIX_LOG_ASYNC;
- else if (::strncasecmp (arg, "break", 5) == 0 ) return POSIX_LOG_BREAKPOINTS;
- else if (::strncasecmp (arg, "comm", 4) == 0 ) return POSIX_LOG_COMM;
- else if (::strcasecmp (arg, "default") == 0 ) return POSIX_LOG_DEFAULT;
- else if (::strcasecmp (arg, "packets") == 0 ) return POSIX_LOG_PACKETS;
- else if (::strcasecmp (arg, "memory") == 0 ) return POSIX_LOG_MEMORY;
- else if (::strcasecmp (arg, "data-short") == 0 ) return POSIX_LOG_MEMORY_DATA_SHORT;
- else if (::strcasecmp (arg, "data-long") == 0 ) return POSIX_LOG_MEMORY_DATA_LONG;
- else if (::strcasecmp (arg, "process") == 0 ) return POSIX_LOG_PROCESS;
- else if (::strcasecmp (arg, "ptrace") == 0 ) return POSIX_LOG_PTRACE;
- else if (::strcasecmp (arg, "registers") == 0 ) return POSIX_LOG_REGISTERS;
- else if (::strcasecmp (arg, "step") == 0 ) return POSIX_LOG_STEP;
- else if (::strcasecmp (arg, "thread") == 0 ) return POSIX_LOG_THREAD;
- else if (::strcasecmp (arg, "verbose") == 0 ) return POSIX_LOG_VERBOSE;
- else if (::strncasecmp (arg, "watch", 5) == 0 ) return POSIX_LOG_WATCHPOINTS;
- return 0;
+Log *ProcessPOSIXLog::GetLogIfAllCategoriesSet(uint32_t mask) {
+ Log *log(GetLog());
+ if (log && mask) {
+ uint32_t log_mask = log->GetMask().Get();
+ if ((log_mask & mask) != mask)
+ return NULL;
+ }
+ return log;
}
-void
-ProcessPOSIXLog::DisableLog (const char **args, Stream *feedback_strm)
-{
- Log *log (GetLog ());
- if (log)
- {
- uint32_t flag_bits = 0;
-
- flag_bits = log->GetMask().Get();
- for (; args[0]; args++)
- {
- const char *arg = args[0];
- uint32_t bits = GetFlagBits(arg);
-
- if (bits)
- {
- flag_bits &= ~bits;
- }
- else
- {
- feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
- ListLogCategories (feedback_strm);
- }
- }
-
- log->GetMask().Reset (flag_bits);
- if (flag_bits == 0)
- g_log_enabled = false;
- }
-
- return;
+static uint32_t GetFlagBits(const char *arg) {
+ if (::strcasecmp(arg, "all") == 0)
+ return POSIX_LOG_ALL;
+ else if (::strcasecmp(arg, "async") == 0)
+ return POSIX_LOG_ASYNC;
+ else if (::strncasecmp(arg, "break", 5) == 0)
+ return POSIX_LOG_BREAKPOINTS;
+ else if (::strncasecmp(arg, "comm", 4) == 0)
+ return POSIX_LOG_COMM;
+ else if (::strcasecmp(arg, "default") == 0)
+ return POSIX_LOG_DEFAULT;
+ else if (::strcasecmp(arg, "packets") == 0)
+ return POSIX_LOG_PACKETS;
+ else if (::strcasecmp(arg, "memory") == 0)
+ return POSIX_LOG_MEMORY;
+ else if (::strcasecmp(arg, "data-short") == 0)
+ return POSIX_LOG_MEMORY_DATA_SHORT;
+ else if (::strcasecmp(arg, "data-long") == 0)
+ return POSIX_LOG_MEMORY_DATA_LONG;
+ else if (::strcasecmp(arg, "process") == 0)
+ return POSIX_LOG_PROCESS;
+ else if (::strcasecmp(arg, "ptrace") == 0)
+ return POSIX_LOG_PTRACE;
+ else if (::strcasecmp(arg, "registers") == 0)
+ return POSIX_LOG_REGISTERS;
+ else if (::strcasecmp(arg, "step") == 0)
+ return POSIX_LOG_STEP;
+ else if (::strcasecmp(arg, "thread") == 0)
+ return POSIX_LOG_THREAD;
+ else if (::strcasecmp(arg, "verbose") == 0)
+ return POSIX_LOG_VERBOSE;
+ else if (::strncasecmp(arg, "watch", 5) == 0)
+ return POSIX_LOG_WATCHPOINTS;
+ return 0;
}
-Log *
-ProcessPOSIXLog::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, const char **args, Stream *feedback_strm)
-{
- // Try see if there already is a log - that way we can reuse its settings.
- // We could reuse the log in toto, but we don't know that the stream is the same.
+void ProcessPOSIXLog::DisableLog(const char **args, Stream *feedback_strm) {
+ Log *log(GetLog());
+ if (log) {
uint32_t flag_bits = 0;
- if (g_log)
- flag_bits = g_log->GetMask().Get();
-
- // Now make a new log with this stream if one was provided
- if (log_stream_sp)
- {
- if (g_log)
- g_log->SetStream(log_stream_sp);
- else
- g_log = new Log(log_stream_sp);
+
+ flag_bits = log->GetMask().Get();
+ for (; args && args[0]; args++) {
+ const char *arg = args[0];
+ uint32_t bits = GetFlagBits(arg);
+
+ if (bits) {
+ flag_bits &= ~bits;
+ } else {
+ feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
+ ListLogCategories(feedback_strm);
+ }
}
+ log->GetMask().Reset(flag_bits);
+ if (flag_bits == 0)
+ g_log_enabled = false;
+ }
+
+ return;
+}
+
+Log *ProcessPOSIXLog::EnableLog(StreamSP &log_stream_sp, uint32_t log_options,
+ const char **args, Stream *feedback_strm) {
+ // Try see if there already is a log - that way we can reuse its settings.
+ // We could reuse the log in toto, but we don't know that the stream is the
+ // same.
+ uint32_t flag_bits = 0;
+ if (g_log)
+ flag_bits = g_log->GetMask().Get();
+
+ // Now make a new log with this stream if one was provided
+ if (log_stream_sp) {
if (g_log)
- {
- bool got_unknown_category = false;
- for (; args[0]; args++)
- {
- const char *arg = args[0];
- uint32_t bits = GetFlagBits(arg);
-
- if (bits)
- {
- flag_bits |= bits;
- }
- else
- {
- feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
- if (got_unknown_category == false)
- {
- got_unknown_category = true;
- ListLogCategories (feedback_strm);
- }
- }
+ g_log->SetStream(log_stream_sp);
+ else
+ g_log = new Log(log_stream_sp);
+ }
+
+ if (g_log) {
+ bool got_unknown_category = false;
+ for (; args && args[0]; args++) {
+ const char *arg = args[0];
+ uint32_t bits = GetFlagBits(arg);
+
+ if (bits) {
+ flag_bits |= bits;
+ } else {
+ feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
+ if (got_unknown_category == false) {
+ got_unknown_category = true;
+ ListLogCategories(feedback_strm);
}
- if (flag_bits == 0)
- flag_bits = POSIX_LOG_DEFAULT;
- g_log->GetMask().Reset(flag_bits);
- g_log->GetOptions().Reset(log_options);
- g_log_enabled = true;
+ }
}
- return g_log;
+ if (flag_bits == 0)
+ flag_bits = POSIX_LOG_DEFAULT;
+ g_log->GetMask().Reset(flag_bits);
+ g_log->GetOptions().Reset(log_options);
+ g_log_enabled = true;
+ }
+ return g_log;
}
-void
-ProcessPOSIXLog::ListLogCategories (Stream *strm)
-{
- strm->Printf ("Logging categories for '%s':\n"
- " all - turn on all available logging categories\n"
- " async - log asynchronous activity\n"
- " break - log breakpoints\n"
- " communication - log communication activity\n"
- " default - enable the default set of logging categories for liblldb\n"
- " packets - log gdb remote packets\n"
- " memory - log memory reads and writes\n"
- " data-short - log memory bytes for memory reads and writes for short transactions only\n"
- " data-long - log memory bytes for memory reads and writes for all transactions\n"
- " process - log process events and activities\n"
+void ProcessPOSIXLog::ListLogCategories(Stream *strm) {
+ strm->Printf(
+ "Logging categories for '%s':\n"
+ " all - turn on all available logging categories\n"
+ " async - log asynchronous activity\n"
+ " break - log breakpoints\n"
+ " communication - log communication activity\n"
+ " default - enable the default set of logging categories for liblldb\n"
+ " packets - log gdb remote packets\n"
+ " memory - log memory reads and writes\n"
+ " data-short - log memory bytes for memory reads and writes for short "
+ "transactions only\n"
+ " data-long - log memory bytes for memory reads and writes for all "
+ "transactions\n"
+ " process - log process events and activities\n"
#ifndef LLDB_CONFIGURATION_BUILDANDINTEGRATION
- " ptrace - log all calls to ptrace\n"
+ " ptrace - log all calls to ptrace\n"
#endif
- " registers - log register read/writes\n"
- " thread - log thread events and activities\n"
- " step - log step related activities\n"
- " verbose - enable verbose logging\n"
- " watch - log watchpoint related activities\n", ProcessPOSIXLog::m_pluginname);
+ " registers - log register read/writes\n"
+ " thread - log thread events and activities\n"
+ " step - log step related activities\n"
+ " verbose - enable verbose logging\n"
+ " watch - log watchpoint related activities\n",
+ ProcessPOSIXLog::m_pluginname);
}
-
-void
-ProcessPOSIXLog::LogIf (uint32_t mask, const char *format, ...)
-{
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (mask));
- if (log)
- {
- va_list args;
- va_start (args, format);
- log->VAPrintf (format, args);
- va_end (args);
- }
+void ProcessPOSIXLog::LogIf(uint32_t mask, const char *format, ...) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(mask));
+ if (log) {
+ va_list args;
+ va_start(args, format);
+ log->VAPrintf(format, args);
+ va_end(args);
+ }
}
int ProcessPOSIXLog::m_nestinglevel;
diff --git a/source/Plugins/Process/POSIX/ProcessPOSIXLog.h b/source/Plugins/Process/POSIX/ProcessPOSIXLog.h
index 7edd839152e6..7d187da4e488 100644
--- a/source/Plugins/Process/POSIX/ProcessPOSIXLog.h
+++ b/source/Plugins/Process/POSIX/ProcessPOSIXLog.h
@@ -1,4 +1,5 @@
-//===-- ProcessPOSIXLog.h -----------------------------------------*- C++ -*-===//
+//===-- ProcessPOSIXLog.h -----------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,101 +18,85 @@
// Project includes
#include "lldb/Core/Log.h"
-#define POSIX_LOG_VERBOSE (1u << 0)
-#define POSIX_LOG_PROCESS (1u << 1)
-#define POSIX_LOG_THREAD (1u << 2)
-#define POSIX_LOG_PACKETS (1u << 3)
-#define POSIX_LOG_MEMORY (1u << 4) // Log memory reads/writes calls
-#define POSIX_LOG_MEMORY_DATA_SHORT (1u << 5) // Log short memory reads/writes bytes
-#define POSIX_LOG_MEMORY_DATA_LONG (1u << 6) // Log all memory reads/writes bytes
-#define POSIX_LOG_BREAKPOINTS (1u << 7)
-#define POSIX_LOG_WATCHPOINTS (1u << 8)
-#define POSIX_LOG_STEP (1u << 9)
-#define POSIX_LOG_COMM (1u << 10)
-#define POSIX_LOG_ASYNC (1u << 11)
-#define POSIX_LOG_PTRACE (1u << 12)
-#define POSIX_LOG_REGISTERS (1u << 13)
-#define POSIX_LOG_ALL (UINT32_MAX)
-#define POSIX_LOG_DEFAULT POSIX_LOG_PACKETS
+#define POSIX_LOG_VERBOSE (1u << 0)
+#define POSIX_LOG_PROCESS (1u << 1)
+#define POSIX_LOG_THREAD (1u << 2)
+#define POSIX_LOG_PACKETS (1u << 3)
+#define POSIX_LOG_MEMORY (1u << 4) // Log memory reads/writes calls
+#define POSIX_LOG_MEMORY_DATA_SHORT \
+ (1u << 5) // Log short memory reads/writes bytes
+#define POSIX_LOG_MEMORY_DATA_LONG \
+ (1u << 6) // Log all memory reads/writes bytes
+#define POSIX_LOG_BREAKPOINTS (1u << 7)
+#define POSIX_LOG_WATCHPOINTS (1u << 8)
+#define POSIX_LOG_STEP (1u << 9)
+#define POSIX_LOG_COMM (1u << 10)
+#define POSIX_LOG_ASYNC (1u << 11)
+#define POSIX_LOG_PTRACE (1u << 12)
+#define POSIX_LOG_REGISTERS (1u << 13)
+#define POSIX_LOG_ALL (UINT32_MAX)
+#define POSIX_LOG_DEFAULT POSIX_LOG_PACKETS
// The size which determines "short memory reads/writes".
-#define POSIX_LOG_MEMORY_SHORT_BYTES (4 * sizeof(ptrdiff_t))
+#define POSIX_LOG_MEMORY_SHORT_BYTES (4 * sizeof(ptrdiff_t))
-class ProcessPOSIXLog
-{
- static int m_nestinglevel;
- static const char *m_pluginname;
+class ProcessPOSIXLog {
+ static int m_nestinglevel;
+ static const char *m_pluginname;
public:
- // ---------------------------------------------------------------------
- // Public Static Methods
- // ---------------------------------------------------------------------
- static void
- Initialize(lldb_private::ConstString name);
-
- static void
- RegisterPluginName(const char *pluginName)
- {
- m_pluginname = pluginName;
- }
-
- static void
- RegisterPluginName(lldb_private::ConstString pluginName)
- {
- m_pluginname = pluginName.GetCString();
- }
-
- static lldb_private::Log *
- GetLogIfAllCategoriesSet(uint32_t mask = 0);
-
- static void
- DisableLog (const char **args, lldb_private::Stream *feedback_strm);
-
- static lldb_private::Log *
- EnableLog (lldb::StreamSP &log_stream_sp, uint32_t log_options,
- const char **args, lldb_private::Stream *feedback_strm);
-
- static void
- ListLogCategories (lldb_private::Stream *strm);
-
- static void
- LogIf (uint32_t mask, const char *format, ...);
-
- // The following functions can be used to enable the client to limit
- // logging to only the top level function calls. This is useful for
- // recursive functions. FIXME: not thread safe!
- // Example:
- // void NestingFunc() {
- // LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_ALL));
- // if (log)
- // {
- // ProcessPOSIXLog::IncNestLevel();
- // if (ProcessPOSIXLog::AtTopNestLevel())
- // log->Print(msg);
- // }
- // NestingFunc();
- // if (log)
- // ProcessPOSIXLog::DecNestLevel();
- // }
-
- static bool
- AtTopNestLevel()
- {
- return m_nestinglevel == 1;
- }
-
- static void
- IncNestLevel()
- {
- ++m_nestinglevel;
- }
-
- static void
- DecNestLevel()
- {
- --m_nestinglevel;
- assert(m_nestinglevel >= 0);
- }
+ // ---------------------------------------------------------------------
+ // Public Static Methods
+ // ---------------------------------------------------------------------
+ static void Initialize(lldb_private::ConstString name);
+
+ static void RegisterPluginName(const char *pluginName) {
+ m_pluginname = pluginName;
+ }
+
+ static void RegisterPluginName(lldb_private::ConstString pluginName) {
+ m_pluginname = pluginName.GetCString();
+ }
+
+ static lldb_private::Log *GetLogIfAllCategoriesSet(uint32_t mask = 0);
+
+ static void DisableLog(const char **args,
+ lldb_private::Stream *feedback_strm);
+
+ static lldb_private::Log *EnableLog(lldb::StreamSP &log_stream_sp,
+ uint32_t log_options, const char **args,
+ lldb_private::Stream *feedback_strm);
+
+ static void ListLogCategories(lldb_private::Stream *strm);
+
+ static void LogIf(uint32_t mask, const char *format, ...);
+
+ // The following functions can be used to enable the client to limit
+ // logging to only the top level function calls. This is useful for
+ // recursive functions. FIXME: not thread safe!
+ // Example:
+ // void NestingFunc() {
+ // LogSP log
+ // (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_ALL));
+ // if (log)
+ // {
+ // ProcessPOSIXLog::IncNestLevel();
+ // if (ProcessPOSIXLog::AtTopNestLevel())
+ // log->Print(msg);
+ // }
+ // NestingFunc();
+ // if (log)
+ // ProcessPOSIXLog::DecNestLevel();
+ // }
+
+ static bool AtTopNestLevel() { return m_nestinglevel == 1; }
+
+ static void IncNestLevel() { ++m_nestinglevel; }
+
+ static void DecNestLevel() {
+ --m_nestinglevel;
+ assert(m_nestinglevel >= 0);
+ }
};
-#endif // liblldb_ProcessPOSIXLog_h_
+#endif // liblldb_ProcessPOSIXLog_h_
diff --git a/source/Plugins/Process/Utility/ARMDefines.h b/source/Plugins/Process/Utility/ARMDefines.h
index cfb33beb447a..84c2cf19be7b 100644
--- a/source/Plugins/Process/Utility/ARMDefines.h
+++ b/source/Plugins/Process/Utility/ARMDefines.h
@@ -10,101 +10,150 @@
#ifndef lldb_ARMDefines_h_
#define lldb_ARMDefines_h_
+#include <cassert>
+#include <cstdint>
+
// Common definitions for the ARM/Thumb Instruction Set Architecture.
namespace lldb_private {
// ARM shifter types
-typedef enum
-{
- SRType_LSL,
- SRType_LSR,
- SRType_ASR,
- SRType_ROR,
- SRType_RRX,
- SRType_Invalid
+typedef enum {
+ SRType_LSL,
+ SRType_LSR,
+ SRType_ASR,
+ SRType_ROR,
+ SRType_RRX,
+ SRType_Invalid
} ARM_ShifterType;
-// ARM conditions // Meaning (integer) Meaning (floating-point) Condition flags
-#define COND_EQ 0x0 // Equal Equal Z == 1
-#define COND_NE 0x1 // Not equal Not equal, or unordered Z == 0
-#define COND_CS 0x2 // Carry set >, ==, or unordered C == 1
-#define COND_HS 0x2
-#define COND_CC 0x3 // Carry clear Less than C == 0
-#define COND_LO 0x3
-#define COND_MI 0x4 // Minus, negative Less than N == 1
-#define COND_PL 0x5 // Plus, positive or zero >, ==, or unordered N == 0
-#define COND_VS 0x6 // Overflow Unordered V == 1
-#define COND_VC 0x7 // No overflow Not unordered V == 0
-#define COND_HI 0x8 // Unsigned higher Greater than, or unordered C == 1 and Z == 0
-#define COND_LS 0x9 // Unsigned lower or same Less than or equal C == 0 or Z == 1
-#define COND_GE 0xA // Greater than or equal Greater than or equal N == V
-#define COND_LT 0xB // Less than Less than, or unordered N != V
-#define COND_GT 0xC // Greater than Greater than Z == 0 and N == V
-#define COND_LE 0xD // Less than or equal <, ==, or unordered Z == 1 or N != V
-#define COND_AL 0xE // Always (unconditional) Always (unconditional) Any
+// ARM conditions // Meaning (integer) Meaning (floating-point)
+// Condition flags
+#define COND_EQ \
+ 0x0 // Equal Equal Z == 1
+#define COND_NE \
+ 0x1 // Not equal Not equal, or unordered Z == 0
+#define COND_CS \
+ 0x2 // Carry set >, ==, or unordered C == 1
+#define COND_HS 0x2
+#define COND_CC \
+ 0x3 // Carry clear Less than C == 0
+#define COND_LO 0x3
+#define COND_MI \
+ 0x4 // Minus, negative Less than N == 1
+#define COND_PL \
+ 0x5 // Plus, positive or zero >, ==, or unordered N == 0
+#define COND_VS \
+ 0x6 // Overflow Unordered V == 1
+#define COND_VC \
+ 0x7 // No overflow Not unordered V == 0
+#define COND_HI \
+ 0x8 // Unsigned higher Greater than, or unordered C == 1 and Z ==
+ // 0
+#define COND_LS \
+ 0x9 // Unsigned lower or same Less than or equal C == 0 or Z ==
+ // 1
+#define COND_GE \
+ 0xA // Greater than or equal Greater than or equal N == V
+#define COND_LT \
+ 0xB // Less than Less than, or unordered N != V
+#define COND_GT \
+ 0xC // Greater than Greater than Z == 0 and N ==
+ // V
+#define COND_LE \
+ 0xD // Less than or equal <, ==, or unordered Z == 1 or N !=
+ // V
+#define COND_AL \
+ 0xE // Always (unconditional) Always (unconditional) Any
#define COND_UNCOND 0xF
-static inline const char *
-ARMCondCodeToString(uint32_t CC)
-{
- switch (CC) {
- default: assert(0 && "Unknown condition code");
- case COND_EQ: return "eq";
- case COND_NE: return "ne";
- case COND_HS: return "hs";
- case COND_LO: return "lo";
- case COND_MI: return "mi";
- case COND_PL: return "pl";
- case COND_VS: return "vs";
- case COND_VC: return "vc";
- case COND_HI: return "hi";
- case COND_LS: return "ls";
- case COND_GE: return "ge";
- case COND_LT: return "lt";
- case COND_GT: return "gt";
- case COND_LE: return "le";
- case COND_AL: return "al";
- }
+static inline const char *ARMCondCodeToString(uint32_t CC) {
+ switch (CC) {
+ default:
+ assert(0 && "Unknown condition code");
+ case COND_EQ:
+ return "eq";
+ case COND_NE:
+ return "ne";
+ case COND_HS:
+ return "hs";
+ case COND_LO:
+ return "lo";
+ case COND_MI:
+ return "mi";
+ case COND_PL:
+ return "pl";
+ case COND_VS:
+ return "vs";
+ case COND_VC:
+ return "vc";
+ case COND_HI:
+ return "hi";
+ case COND_LS:
+ return "ls";
+ case COND_GE:
+ return "ge";
+ case COND_LT:
+ return "lt";
+ case COND_GT:
+ return "gt";
+ case COND_LE:
+ return "le";
+ case COND_AL:
+ return "al";
+ }
}
-static inline bool
-ARMConditionPassed(const uint32_t condition, const uint32_t cpsr)
-{
- const uint32_t cpsr_n = (cpsr >> 31) & 1u; // Negative condition code flag
- const uint32_t cpsr_z = (cpsr >> 30) & 1u; // Zero condition code flag
- const uint32_t cpsr_c = (cpsr >> 29) & 1u; // Carry condition code flag
- const uint32_t cpsr_v = (cpsr >> 28) & 1u; // Overflow condition code flag
+static inline bool ARMConditionPassed(const uint32_t condition,
+ const uint32_t cpsr) {
+ const uint32_t cpsr_n = (cpsr >> 31) & 1u; // Negative condition code flag
+ const uint32_t cpsr_z = (cpsr >> 30) & 1u; // Zero condition code flag
+ const uint32_t cpsr_c = (cpsr >> 29) & 1u; // Carry condition code flag
+ const uint32_t cpsr_v = (cpsr >> 28) & 1u; // Overflow condition code flag
- switch (condition) {
- case COND_EQ: return (cpsr_z == 1);
- case COND_NE: return (cpsr_z == 0);
- case COND_CS: return (cpsr_c == 1);
- case COND_CC: return (cpsr_c == 0);
- case COND_MI: return (cpsr_n == 1);
- case COND_PL: return (cpsr_n == 0);
- case COND_VS: return (cpsr_v == 1);
- case COND_VC: return (cpsr_v == 0);
- case COND_HI: return ((cpsr_c == 1) && (cpsr_z == 0));
- case COND_LS: return ((cpsr_c == 0) || (cpsr_z == 1));
- case COND_GE: return (cpsr_n == cpsr_v);
- case COND_LT: return (cpsr_n != cpsr_v);
- case COND_GT: return ((cpsr_z == 0) && (cpsr_n == cpsr_v));
- case COND_LE: return ((cpsr_z == 1) || (cpsr_n != cpsr_v));
- case COND_AL:
- case COND_UNCOND:
- default:
- return true;
- }
- return false;
+ switch (condition) {
+ case COND_EQ:
+ return (cpsr_z == 1);
+ case COND_NE:
+ return (cpsr_z == 0);
+ case COND_CS:
+ return (cpsr_c == 1);
+ case COND_CC:
+ return (cpsr_c == 0);
+ case COND_MI:
+ return (cpsr_n == 1);
+ case COND_PL:
+ return (cpsr_n == 0);
+ case COND_VS:
+ return (cpsr_v == 1);
+ case COND_VC:
+ return (cpsr_v == 0);
+ case COND_HI:
+ return ((cpsr_c == 1) && (cpsr_z == 0));
+ case COND_LS:
+ return ((cpsr_c == 0) || (cpsr_z == 1));
+ case COND_GE:
+ return (cpsr_n == cpsr_v);
+ case COND_LT:
+ return (cpsr_n != cpsr_v);
+ case COND_GT:
+ return ((cpsr_z == 0) && (cpsr_n == cpsr_v));
+ case COND_LE:
+ return ((cpsr_z == 1) || (cpsr_n != cpsr_v));
+ case COND_AL:
+ case COND_UNCOND:
+ default:
+ return true;
+ }
+ return false;
}
// Bit positions for CPSR
-#define CPSR_T_POS 5
-#define CPSR_F_POS 6
-#define CPSR_I_POS 7
-#define CPSR_A_POS 8
-#define CPSR_E_POS 9
+#define CPSR_T_POS 5
+#define CPSR_F_POS 6
+#define CPSR_I_POS 7
+#define CPSR_A_POS 8
+#define CPSR_E_POS 9
#define CPSR_J_POS 24
#define CPSR_Q_POS 27
#define CPSR_V_POS 28
@@ -113,30 +162,30 @@ ARMConditionPassed(const uint32_t condition, const uint32_t cpsr)
#define CPSR_N_POS 31
// CPSR mode definitions
-#define CPSR_MODE_USR 0x10u
-#define CPSR_MODE_FIQ 0x11u
-#define CPSR_MODE_IRQ 0x12u
-#define CPSR_MODE_SVC 0x13u
-#define CPSR_MODE_ABT 0x17u
-#define CPSR_MODE_UND 0x1bu
-#define CPSR_MODE_SYS 0x1fu
-
+#define CPSR_MODE_USR 0x10u
+#define CPSR_MODE_FIQ 0x11u
+#define CPSR_MODE_IRQ 0x12u
+#define CPSR_MODE_SVC 0x13u
+#define CPSR_MODE_ABT 0x17u
+#define CPSR_MODE_UND 0x1bu
+#define CPSR_MODE_SYS 0x1fu
+
// Masks for CPSR
#define MASK_CPSR_MODE_MASK (0x0000001fu)
-#define MASK_CPSR_IT_MASK (0x0600fc00u)
-#define MASK_CPSR_T (1u << CPSR_T_POS)
-#define MASK_CPSR_F (1u << CPSR_F_POS)
-#define MASK_CPSR_I (1u << CPSR_I_POS)
-#define MASK_CPSR_A (1u << CPSR_A_POS)
-#define MASK_CPSR_E (1u << CPSR_E_POS)
-#define MASK_CPSR_GE_MASK (0x000f0000u)
-#define MASK_CPSR_J (1u << CPSR_J_POS)
-#define MASK_CPSR_Q (1u << CPSR_Q_POS)
-#define MASK_CPSR_V (1u << CPSR_V_POS)
-#define MASK_CPSR_C (1u << CPSR_C_POS)
-#define MASK_CPSR_Z (1u << CPSR_Z_POS)
-#define MASK_CPSR_N (1u << CPSR_N_POS)
+#define MASK_CPSR_IT_MASK (0x0600fc00u)
+#define MASK_CPSR_T (1u << CPSR_T_POS)
+#define MASK_CPSR_F (1u << CPSR_F_POS)
+#define MASK_CPSR_I (1u << CPSR_I_POS)
+#define MASK_CPSR_A (1u << CPSR_A_POS)
+#define MASK_CPSR_E (1u << CPSR_E_POS)
+#define MASK_CPSR_GE_MASK (0x000f0000u)
+#define MASK_CPSR_J (1u << CPSR_J_POS)
+#define MASK_CPSR_Q (1u << CPSR_Q_POS)
+#define MASK_CPSR_V (1u << CPSR_V_POS)
+#define MASK_CPSR_C (1u << CPSR_C_POS)
+#define MASK_CPSR_Z (1u << CPSR_Z_POS)
+#define MASK_CPSR_N (1u << CPSR_N_POS)
-} // namespace lldb_private
+} // namespace lldb_private
-#endif // lldb_ARMDefines_h_
+#endif // lldb_ARMDefines_h_
diff --git a/source/Plugins/Process/Utility/ARMUtils.h b/source/Plugins/Process/Utility/ARMUtils.h
index b6ba3fea6928..2bbd519b246a 100644
--- a/source/Plugins/Process/Utility/ARMUtils.h
+++ b/source/Plugins/Process/Utility/ARMUtils.h
@@ -18,352 +18,335 @@
namespace lldb_private {
-static inline uint32_t Align(uint32_t val, uint32_t alignment)
-{
- return alignment * (val / alignment);
+static inline uint32_t Align(uint32_t val, uint32_t alignment) {
+ return alignment * (val / alignment);
}
-static inline uint32_t DecodeImmShift(const uint32_t type, const uint32_t imm5, ARM_ShifterType &shift_t)
-{
- switch (type)
- {
- default:
- //assert(0 && "Invalid shift type");
- case 0:
- shift_t = SRType_LSL;
- return imm5;
- case 1:
- shift_t = SRType_LSR;
- return (imm5 == 0 ? 32 : imm5);
- case 2:
- shift_t = SRType_ASR;
- return (imm5 == 0 ? 32 : imm5);
- case 3:
- if (imm5 == 0)
- {
- shift_t = SRType_RRX;
- return 1;
- }
- else
- {
- shift_t = SRType_ROR;
- return imm5;
- }
+static inline uint32_t DecodeImmShift(const uint32_t type, const uint32_t imm5,
+ ARM_ShifterType &shift_t) {
+ switch (type) {
+ default:
+ // assert(0 && "Invalid shift type");
+ case 0:
+ shift_t = SRType_LSL;
+ return imm5;
+ case 1:
+ shift_t = SRType_LSR;
+ return (imm5 == 0 ? 32 : imm5);
+ case 2:
+ shift_t = SRType_ASR;
+ return (imm5 == 0 ? 32 : imm5);
+ case 3:
+ if (imm5 == 0) {
+ shift_t = SRType_RRX;
+ return 1;
+ } else {
+ shift_t = SRType_ROR;
+ return imm5;
}
- shift_t = SRType_Invalid;
- return UINT32_MAX;
-
+ }
+ shift_t = SRType_Invalid;
+ return UINT32_MAX;
}
// A8.6.35 CMP (register) -- Encoding T3
// Convenience function.
-static inline uint32_t DecodeImmShiftThumb(const uint32_t opcode, ARM_ShifterType &shift_t)
-{
- return DecodeImmShift(Bits32(opcode, 5, 4), Bits32(opcode, 14, 12)<<2 | Bits32(opcode, 7, 6), shift_t);
+static inline uint32_t DecodeImmShiftThumb(const uint32_t opcode,
+ ARM_ShifterType &shift_t) {
+ return DecodeImmShift(Bits32(opcode, 5, 4),
+ Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6),
+ shift_t);
}
// A8.6.35 CMP (register) -- Encoding A1
// Convenience function.
-static inline uint32_t DecodeImmShiftARM(const uint32_t opcode, ARM_ShifterType &shift_t)
-{
- return DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t);
+static inline uint32_t DecodeImmShiftARM(const uint32_t opcode,
+ ARM_ShifterType &shift_t) {
+ return DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t);
}
-static inline uint32_t DecodeImmShift(const ARM_ShifterType shift_t, const uint32_t imm5)
-{
- ARM_ShifterType dont_care;
- return DecodeImmShift(shift_t, imm5, dont_care);
+static inline uint32_t DecodeImmShift(const ARM_ShifterType shift_t,
+ const uint32_t imm5) {
+ ARM_ShifterType dont_care;
+ return DecodeImmShift(shift_t, imm5, dont_care);
}
-static inline ARM_ShifterType DecodeRegShift(const uint32_t type)
-{
- switch (type) {
- default:
- //assert(0 && "Invalid shift type");
- return SRType_Invalid;
- case 0:
- return SRType_LSL;
- case 1:
- return SRType_LSR;
- case 2:
- return SRType_ASR;
- case 3:
- return SRType_ROR;
- }
+static inline ARM_ShifterType DecodeRegShift(const uint32_t type) {
+ switch (type) {
+ default:
+ // assert(0 && "Invalid shift type");
+ return SRType_Invalid;
+ case 0:
+ return SRType_LSL;
+ case 1:
+ return SRType_LSR;
+ case 2:
+ return SRType_ASR;
+ case 3:
+ return SRType_ROR;
+ }
}
-static inline uint32_t LSL_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out, bool *success)
-{
- if (amount == 0) {
- *success = false;
- return 0;
- }
- *success = true;
- carry_out = amount <= 32 ? Bit32(value, 32 - amount) : 0;
- return value << amount;
+static inline uint32_t LSL_C(const uint32_t value, const uint32_t amount,
+ uint32_t &carry_out, bool *success) {
+ if (amount == 0) {
+ *success = false;
+ return 0;
+ }
+ *success = true;
+ carry_out = amount <= 32 ? Bit32(value, 32 - amount) : 0;
+ return value << amount;
}
-static inline uint32_t LSL(const uint32_t value, const uint32_t amount, bool *success)
-{
- *success = true;
- if (amount == 0)
- return value;
- uint32_t dont_care;
- uint32_t result = LSL_C(value, amount, dont_care, success);
- if (*success)
- return result;
- else
- return 0;
-}
-
-static inline uint32_t LSR_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out, bool *success)
-{
- if (amount == 0) {
- *success = false;
- return 0;
- }
- *success = true;
- carry_out = amount <= 32 ? Bit32(value, amount - 1) : 0;
- return value >> amount;
+static inline uint32_t LSL(const uint32_t value, const uint32_t amount,
+ bool *success) {
+ *success = true;
+ if (amount == 0)
+ return value;
+ uint32_t dont_care;
+ uint32_t result = LSL_C(value, amount, dont_care, success);
+ if (*success)
+ return result;
+ else
+ return 0;
}
-static inline uint32_t LSR(const uint32_t value, const uint32_t amount, bool *success)
-{
- *success = true;
- if (amount == 0)
- return value;
- uint32_t dont_care;
- uint32_t result = LSR_C(value, amount, dont_care, success);
- if (*success)
- return result;
- else
- return 0;
+static inline uint32_t LSR_C(const uint32_t value, const uint32_t amount,
+ uint32_t &carry_out, bool *success) {
+ if (amount == 0) {
+ *success = false;
+ return 0;
+ }
+ *success = true;
+ carry_out = amount <= 32 ? Bit32(value, amount - 1) : 0;
+ return value >> amount;
}
-static inline uint32_t ASR_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out, bool *success)
-{
- if (amount == 0 || amount > 32) {
- *success = false;
- return 0;
- }
- *success = true;
- bool negative = BitIsSet(value, 31);
- if (amount <= 32)
- {
- carry_out = Bit32(value, amount - 1);
- int64_t extended = llvm::SignExtend64<32>(value);
- return UnsignedBits(extended, amount + 31, amount);
- }
- else
- {
- carry_out = (negative ? 1 : 0);
- return (negative ? 0xffffffff : 0);
- }
+static inline uint32_t LSR(const uint32_t value, const uint32_t amount,
+ bool *success) {
+ *success = true;
+ if (amount == 0)
+ return value;
+ uint32_t dont_care;
+ uint32_t result = LSR_C(value, amount, dont_care, success);
+ if (*success)
+ return result;
+ else
+ return 0;
}
-static inline uint32_t ASR(const uint32_t value, const uint32_t amount, bool *success)
-{
- *success = true;
- if (amount == 0)
- return value;
- uint32_t dont_care;
- uint32_t result = ASR_C(value, amount, dont_care, success);
- if (*success)
- return result;
- else
- return 0;
+static inline uint32_t ASR_C(const uint32_t value, const uint32_t amount,
+ uint32_t &carry_out, bool *success) {
+ if (amount == 0 || amount > 32) {
+ *success = false;
+ return 0;
+ }
+ *success = true;
+ bool negative = BitIsSet(value, 31);
+ if (amount <= 32) {
+ carry_out = Bit32(value, amount - 1);
+ int64_t extended = llvm::SignExtend64<32>(value);
+ return UnsignedBits(extended, amount + 31, amount);
+ } else {
+ carry_out = (negative ? 1 : 0);
+ return (negative ? 0xffffffff : 0);
+ }
}
-static inline uint32_t ROR_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out, bool *success)
-{
- if (amount == 0) {
- *success = false;
- return 0;
- }
- *success = true;
- uint32_t amt = amount % 32;
- uint32_t result = Rotr32(value, amt);
- carry_out = Bit32(value, 31);
+static inline uint32_t ASR(const uint32_t value, const uint32_t amount,
+ bool *success) {
+ *success = true;
+ if (amount == 0)
+ return value;
+ uint32_t dont_care;
+ uint32_t result = ASR_C(value, amount, dont_care, success);
+ if (*success)
return result;
+ else
+ return 0;
}
-static inline uint32_t ROR(const uint32_t value, const uint32_t amount, bool *success)
-{
- *success = true;
- if (amount == 0)
- return value;
- uint32_t dont_care;
- uint32_t result = ROR_C(value, amount, dont_care, success);
- if (*success)
- return result;
- else
- return 0;
+static inline uint32_t ROR_C(const uint32_t value, const uint32_t amount,
+ uint32_t &carry_out, bool *success) {
+ if (amount == 0) {
+ *success = false;
+ return 0;
+ }
+ *success = true;
+ uint32_t amt = amount % 32;
+ uint32_t result = Rotr32(value, amt);
+ carry_out = Bit32(value, 31);
+ return result;
}
-static inline uint32_t RRX_C(const uint32_t value, const uint32_t carry_in, uint32_t &carry_out, bool *success)
-{
- *success = true;
- carry_out = Bit32(value, 0);
- return Bit32(carry_in, 0) << 31 | Bits32(value, 31, 1);
+static inline uint32_t ROR(const uint32_t value, const uint32_t amount,
+ bool *success) {
+ *success = true;
+ if (amount == 0)
+ return value;
+ uint32_t dont_care;
+ uint32_t result = ROR_C(value, amount, dont_care, success);
+ if (*success)
+ return result;
+ else
+ return 0;
}
-static inline uint32_t RRX(const uint32_t value, const uint32_t carry_in, bool *success)
-{
- *success = true;
- uint32_t dont_care;
- uint32_t result = RRX_C(value, carry_in, dont_care, success);
- if (*success)
- return result;
- else
- return 0;
+static inline uint32_t RRX_C(const uint32_t value, const uint32_t carry_in,
+ uint32_t &carry_out, bool *success) {
+ *success = true;
+ carry_out = Bit32(value, 0);
+ return Bit32(carry_in, 0) << 31 | Bits32(value, 31, 1);
}
-static inline uint32_t Shift_C(const uint32_t value, ARM_ShifterType type, const uint32_t amount,
- const uint32_t carry_in, uint32_t &carry_out, bool *success)
-{
- if (type == SRType_RRX && amount != 1) {
- *success = false;
- return 0;
- }
- *success = true;
+static inline uint32_t RRX(const uint32_t value, const uint32_t carry_in,
+ bool *success) {
+ *success = true;
+ uint32_t dont_care;
+ uint32_t result = RRX_C(value, carry_in, dont_care, success);
+ if (*success)
+ return result;
+ else
+ return 0;
+}
- if (amount == 0) {
- carry_out = carry_in;
- return value;
- }
- uint32_t result;
- switch (type) {
- case SRType_LSL:
- result = LSL_C(value, amount, carry_out, success);
- break;
- case SRType_LSR:
- result = LSR_C(value, amount, carry_out, success);
- break;
- case SRType_ASR:
- result = ASR_C(value, amount, carry_out, success);
- break;
- case SRType_ROR:
- result = ROR_C(value, amount, carry_out, success);
- break;
- case SRType_RRX:
- result = RRX_C(value, carry_in, carry_out, success);
- break;
- default:
- *success = false;
- break;
- }
- if (*success)
- return result;
- else
- return 0;
+static inline uint32_t Shift_C(const uint32_t value, ARM_ShifterType type,
+ const uint32_t amount, const uint32_t carry_in,
+ uint32_t &carry_out, bool *success) {
+ if (type == SRType_RRX && amount != 1) {
+ *success = false;
+ return 0;
+ }
+ *success = true;
+
+ if (amount == 0) {
+ carry_out = carry_in;
+ return value;
+ }
+ uint32_t result;
+ switch (type) {
+ case SRType_LSL:
+ result = LSL_C(value, amount, carry_out, success);
+ break;
+ case SRType_LSR:
+ result = LSR_C(value, amount, carry_out, success);
+ break;
+ case SRType_ASR:
+ result = ASR_C(value, amount, carry_out, success);
+ break;
+ case SRType_ROR:
+ result = ROR_C(value, amount, carry_out, success);
+ break;
+ case SRType_RRX:
+ result = RRX_C(value, carry_in, carry_out, success);
+ break;
+ default:
+ *success = false;
+ break;
+ }
+ if (*success)
+ return result;
+ else
+ return 0;
}
-static inline uint32_t Shift(const uint32_t value, ARM_ShifterType type, const uint32_t amount,
- const uint32_t carry_in, bool *success)
-{
- // Don't care about carry out in this case.
- uint32_t dont_care;
- uint32_t result = Shift_C(value, type, amount, carry_in, dont_care, success);
- if (*success)
- return result;
- else
- return 0;
+static inline uint32_t Shift(const uint32_t value, ARM_ShifterType type,
+ const uint32_t amount, const uint32_t carry_in,
+ bool *success) {
+ // Don't care about carry out in this case.
+ uint32_t dont_care;
+ uint32_t result = Shift_C(value, type, amount, carry_in, dont_care, success);
+ if (*success)
+ return result;
+ else
+ return 0;
}
-static inline uint32_t bits(const uint32_t val, const uint32_t msbit, const uint32_t lsbit)
-{
- return Bits32(val, msbit, lsbit);
+static inline uint32_t bits(const uint32_t val, const uint32_t msbit,
+ const uint32_t lsbit) {
+ return Bits32(val, msbit, lsbit);
}
-static inline uint32_t bit(const uint32_t val, const uint32_t msbit)
-{
- return bits(val, msbit, msbit);
+static inline uint32_t bit(const uint32_t val, const uint32_t msbit) {
+ return bits(val, msbit, msbit);
}
-static uint32_t ror(uint32_t val, uint32_t N, uint32_t shift)
-{
- uint32_t m = shift % N;
- return (val >> m) | (val << (N - m));
+static uint32_t ror(uint32_t val, uint32_t N, uint32_t shift) {
+ uint32_t m = shift % N;
+ return (val >> m) | (val << (N - m));
}
// (imm32, carry_out) = ARMExpandImm_C(imm12, carry_in)
-static inline uint32_t ARMExpandImm_C(uint32_t opcode, uint32_t carry_in, uint32_t &carry_out)
-{
- uint32_t imm32; // the expanded result
- uint32_t imm = bits(opcode, 7, 0); // immediate value
- uint32_t amt = 2 * bits(opcode, 11, 8); // rotate amount
- if (amt == 0)
- {
- imm32 = imm;
- carry_out = carry_in;
- }
- else
- {
- imm32 = ror(imm, 32, amt);
- carry_out = Bit32(imm32, 31);
- }
- return imm32;
+static inline uint32_t ARMExpandImm_C(uint32_t opcode, uint32_t carry_in,
+ uint32_t &carry_out) {
+ uint32_t imm32; // the expanded result
+ uint32_t imm = bits(opcode, 7, 0); // immediate value
+ uint32_t amt = 2 * bits(opcode, 11, 8); // rotate amount
+ if (amt == 0) {
+ imm32 = imm;
+ carry_out = carry_in;
+ } else {
+ imm32 = ror(imm, 32, amt);
+ carry_out = Bit32(imm32, 31);
+ }
+ return imm32;
}
-static inline uint32_t ARMExpandImm(uint32_t opcode)
-{
- // 'carry_in' argument to following function call does not affect the imm32 result.
- uint32_t carry_in = 0;
- uint32_t carry_out;
- return ARMExpandImm_C(opcode, carry_in, carry_out);
+static inline uint32_t ARMExpandImm(uint32_t opcode) {
+ // 'carry_in' argument to following function call does not affect the imm32
+ // result.
+ uint32_t carry_in = 0;
+ uint32_t carry_out;
+ return ARMExpandImm_C(opcode, carry_in, carry_out);
}
// (imm32, carry_out) = ThumbExpandImm_C(imm12, carry_in)
-static inline uint32_t ThumbExpandImm_C(uint32_t opcode, uint32_t carry_in, uint32_t &carry_out)
-{
- uint32_t imm32; // the expanded result
- const uint32_t i = bit(opcode, 26);
- const uint32_t imm3 = bits(opcode, 14, 12);
- const uint32_t abcdefgh = bits(opcode, 7, 0);
- const uint32_t imm12 = i << 11 | imm3 << 8 | abcdefgh;
-
- if (bits(imm12, 11, 10) == 0)
- {
- switch (bits(imm12, 9, 8)) {
- default: // Keep static analyzer happy with a default case
- case 0:
- imm32 = abcdefgh;
- break;
-
- case 1:
- imm32 = abcdefgh << 16 | abcdefgh;
- break;
-
- case 2:
- imm32 = abcdefgh << 24 | abcdefgh << 8;
- break;
-
- case 3:
- imm32 = abcdefgh << 24 | abcdefgh << 16 | abcdefgh << 8 | abcdefgh;
- break;
- }
- carry_out = carry_in;
- }
- else
- {
- const uint32_t unrotated_value = 0x80 | bits(imm12, 6, 0);
- imm32 = ror(unrotated_value, 32, bits(imm12, 11, 7));
- carry_out = Bit32(imm32, 31);
+static inline uint32_t ThumbExpandImm_C(uint32_t opcode, uint32_t carry_in,
+ uint32_t &carry_out) {
+ uint32_t imm32; // the expanded result
+ const uint32_t i = bit(opcode, 26);
+ const uint32_t imm3 = bits(opcode, 14, 12);
+ const uint32_t abcdefgh = bits(opcode, 7, 0);
+ const uint32_t imm12 = i << 11 | imm3 << 8 | abcdefgh;
+
+ if (bits(imm12, 11, 10) == 0) {
+ switch (bits(imm12, 9, 8)) {
+ default: // Keep static analyzer happy with a default case
+ case 0:
+ imm32 = abcdefgh;
+ break;
+
+ case 1:
+ imm32 = abcdefgh << 16 | abcdefgh;
+ break;
+
+ case 2:
+ imm32 = abcdefgh << 24 | abcdefgh << 8;
+ break;
+
+ case 3:
+ imm32 = abcdefgh << 24 | abcdefgh << 16 | abcdefgh << 8 | abcdefgh;
+ break;
}
- return imm32;
+ carry_out = carry_in;
+ } else {
+ const uint32_t unrotated_value = 0x80 | bits(imm12, 6, 0);
+ imm32 = ror(unrotated_value, 32, bits(imm12, 11, 7));
+ carry_out = Bit32(imm32, 31);
+ }
+ return imm32;
}
-static inline uint32_t ThumbExpandImm(uint32_t opcode)
-{
- // 'carry_in' argument to following function call does not affect the imm32 result.
- uint32_t carry_in = 0;
- uint32_t carry_out;
- return ThumbExpandImm_C(opcode, carry_in, carry_out);
+static inline uint32_t ThumbExpandImm(uint32_t opcode) {
+ // 'carry_in' argument to following function call does not affect the imm32
+ // result.
+ uint32_t carry_in = 0;
+ uint32_t carry_out;
+ return ThumbExpandImm_C(opcode, carry_in, carry_out);
}
// imm32 = ZeroExtend(i:imm3:imm8, 32)
-static inline uint32_t ThumbImm12(uint32_t opcode)
-{
+static inline uint32_t ThumbImm12(uint32_t opcode) {
const uint32_t i = bit(opcode, 26);
const uint32_t imm3 = bits(opcode, 14, 12);
const uint32_t imm8 = bits(opcode, 7, 0);
@@ -372,15 +355,13 @@ static inline uint32_t ThumbImm12(uint32_t opcode)
}
// imm32 = ZeroExtend(imm7:'00', 32)
-static inline uint32_t ThumbImm7Scaled(uint32_t opcode)
-{
+static inline uint32_t ThumbImm7Scaled(uint32_t opcode) {
const uint32_t imm7 = bits(opcode, 6, 0);
return imm7 * 4;
}
// imm32 = ZeroExtend(imm8:'00', 32)
-static inline uint32_t ThumbImm8Scaled(uint32_t opcode)
-{
+static inline uint32_t ThumbImm8Scaled(uint32_t opcode) {
const uint32_t imm8 = bits(opcode, 7, 0);
return imm8 * 4;
}
@@ -389,6 +370,6 @@ static inline uint32_t ThumbImm8Scaled(uint32_t opcode)
// not permitted for many Thumb register specifiers.
static inline bool BadReg(uint32_t n) { return n == 13 || n == 15; }
-} // namespace lldb_private
+} // namespace lldb_private
-#endif // lldb_ARMUtils_h_
+#endif // lldb_ARMUtils_h_
diff --git a/source/Plugins/Process/Utility/CMakeLists.txt b/source/Plugins/Process/Utility/CMakeLists.txt
index eb0c81fd7979..c557667e3910 100644
--- a/source/Plugins/Process/Utility/CMakeLists.txt
+++ b/source/Plugins/Process/Utility/CMakeLists.txt
@@ -16,14 +16,12 @@ add_lldb_library(lldbPluginProcessUtility
RegisterContextDarwin_x86_64.cpp
RegisterContextDummy.cpp
RegisterContextFreeBSD_arm.cpp
- RegisterContextFreeBSD_arm64.cpp
RegisterContextFreeBSD_i386.cpp
RegisterContextFreeBSD_mips64.cpp
RegisterContextFreeBSD_powerpc.cpp
RegisterContextFreeBSD_x86_64.cpp
RegisterContextHistory.cpp
RegisterContextLinux_arm.cpp
- RegisterContextLinux_arm64.cpp
RegisterContextLinux_i386.cpp
RegisterContextLinux_x86_64.cpp
RegisterContextLinux_mips64.cpp
@@ -43,6 +41,7 @@ add_lldb_library(lldbPluginProcessUtility
RegisterContextPOSIX_s390x.cpp
RegisterContextPOSIX_x86.cpp
RegisterContextThreadMemory.cpp
+ RegisterInfoPOSIX_arm64.cpp
StopInfoMachException.cpp
ThreadMemory.cpp
UnwindLLDB.cpp
diff --git a/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp b/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
index 6efdb468111b..7c8c26047f85 100644
--- a/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
+++ b/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
@@ -24,788 +24,725 @@
using namespace lldb;
using namespace lldb_private;
-DynamicRegisterInfo::DynamicRegisterInfo () :
- m_regs (),
- m_sets (),
- m_set_reg_nums (),
- m_set_names (),
- m_value_regs_map (),
- m_invalidate_regs_map (),
- m_dynamic_reg_size_map (),
- m_reg_data_byte_size (0),
- m_finalized (false)
-{
+DynamicRegisterInfo::DynamicRegisterInfo()
+ : m_regs(), m_sets(), m_set_reg_nums(), m_set_names(), m_value_regs_map(),
+ m_invalidate_regs_map(), m_dynamic_reg_size_map(),
+ m_reg_data_byte_size(0), m_finalized(false) {}
+
+DynamicRegisterInfo::DynamicRegisterInfo(
+ const lldb_private::StructuredData::Dictionary &dict,
+ const lldb_private::ArchSpec &arch)
+ : m_regs(), m_sets(), m_set_reg_nums(), m_set_names(), m_value_regs_map(),
+ m_invalidate_regs_map(), m_dynamic_reg_size_map(),
+ m_reg_data_byte_size(0), m_finalized(false) {
+ SetRegisterInfo(dict, arch);
}
-DynamicRegisterInfo::DynamicRegisterInfo(const lldb_private::StructuredData::Dictionary &dict,
- const lldb_private::ArchSpec &arch) :
- m_regs (),
- m_sets (),
- m_set_reg_nums (),
- m_set_names (),
- m_value_regs_map (),
- m_invalidate_regs_map (),
- m_dynamic_reg_size_map (),
- m_reg_data_byte_size (0),
- m_finalized (false)
-{
- SetRegisterInfo (dict, arch);
-}
-
-DynamicRegisterInfo::~DynamicRegisterInfo ()
-{
-}
+DynamicRegisterInfo::~DynamicRegisterInfo() {}
size_t
-DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict, const ArchSpec &arch)
-{
- assert(!m_finalized);
- StructuredData::Array *sets = nullptr;
- if (dict.GetValueForKeyAsArray("sets", sets))
- {
- const uint32_t num_sets = sets->GetSize();
- for (uint32_t i=0; i<num_sets; ++i)
- {
- std::string set_name_str;
- ConstString set_name;
- if (sets->GetItemAtIndexAsString(i, set_name_str))
- set_name.SetCString(set_name_str.c_str());
- if (set_name)
- {
- RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL };
- m_sets.push_back (new_set);
- }
- else
- {
- Clear();
- printf("error: register sets must have valid names\n");
- return 0;
- }
- }
- m_set_reg_nums.resize(m_sets.size());
- }
- StructuredData::Array *regs = nullptr;
- if (!dict.GetValueForKeyAsArray("registers", regs))
+DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict,
+ const ArchSpec &arch) {
+ assert(!m_finalized);
+ StructuredData::Array *sets = nullptr;
+ if (dict.GetValueForKeyAsArray("sets", sets)) {
+ const uint32_t num_sets = sets->GetSize();
+ for (uint32_t i = 0; i < num_sets; ++i) {
+ std::string set_name_str;
+ ConstString set_name;
+ if (sets->GetItemAtIndexAsString(i, set_name_str))
+ set_name.SetCString(set_name_str.c_str());
+ if (set_name) {
+ RegisterSet new_set = {set_name.AsCString(), NULL, 0, NULL};
+ m_sets.push_back(new_set);
+ } else {
+ Clear();
+ printf("error: register sets must have valid names\n");
return 0;
+ }
+ }
+ m_set_reg_nums.resize(m_sets.size());
+ }
+ StructuredData::Array *regs = nullptr;
+ if (!dict.GetValueForKeyAsArray("registers", regs))
+ return 0;
+
+ const uint32_t num_regs = regs->GetSize();
+ // typedef std::map<std::string, std::vector<std::string> >
+ // InvalidateNameMap;
+ // InvalidateNameMap invalidate_map;
+ for (uint32_t i = 0; i < num_regs; ++i) {
+ StructuredData::Dictionary *reg_info_dict = nullptr;
+ if (!regs->GetItemAtIndexAsDictionary(i, reg_info_dict)) {
+ Clear();
+ printf("error: items in the 'registers' array must be dictionaries\n");
+ regs->DumpToStdout();
+ return 0;
+ }
- const uint32_t num_regs = regs->GetSize();
-// typedef std::map<std::string, std::vector<std::string> > InvalidateNameMap;
-// InvalidateNameMap invalidate_map;
- for (uint32_t i = 0; i < num_regs; ++i)
- {
- StructuredData::Dictionary *reg_info_dict = nullptr;
- if (!regs->GetItemAtIndexAsDictionary(i, reg_info_dict))
- {
- Clear();
- printf("error: items in the 'registers' array must be dictionaries\n");
- regs->DumpToStdout();
- return 0;
- }
-
- // { 'name':'rcx' , 'bitsize' : 64, 'offset' : 16, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'ehframe' : 2,
- // 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', },
- RegisterInfo reg_info;
- std::vector<uint32_t> value_regs;
- std::vector<uint32_t> invalidate_regs;
- memset(&reg_info, 0, sizeof(reg_info));
-
- ConstString name_val;
- ConstString alt_name_val;
- if (!reg_info_dict->GetValueForKeyAsString("name", name_val, nullptr))
- {
- Clear();
- printf("error: registers must have valid names and offsets\n");
- reg_info_dict->DumpToStdout();
- return 0;
- }
- reg_info.name = name_val.GetCString();
- reg_info_dict->GetValueForKeyAsString("alt-name", alt_name_val, nullptr);
- reg_info.alt_name = alt_name_val.GetCString();
-
- reg_info_dict->GetValueForKeyAsInteger("offset", reg_info.byte_offset, UINT32_MAX);
-
- const ByteOrder byte_order = arch.GetByteOrder();
-
- if (reg_info.byte_offset == UINT32_MAX)
- {
- // No offset for this register, see if the register has a value expression
- // which indicates this register is part of another register. Value expressions
- // are things like "rax[31:0]" which state that the current register's value
- // is in a concrete register "rax" in bits 31:0. If there is a value expression
- // we can calculate the offset
- bool success = false;
- std::string slice_str;
- if (reg_info_dict->GetValueForKeyAsString("slice", slice_str, nullptr))
- {
- // Slices use the following format:
- // REGNAME[MSBIT:LSBIT]
- // REGNAME - name of the register to grab a slice of
- // MSBIT - the most significant bit at which the current register value starts at
- // LSBIT - the least significant bit at which the current register value ends at
- static RegularExpression g_bitfield_regex("([A-Za-z_][A-Za-z0-9_]*)\\[([0-9]+):([0-9]+)\\]");
- RegularExpression::Match regex_match(3);
- if (g_bitfield_regex.Execute(slice_str.c_str(), &regex_match))
- {
- llvm::StringRef reg_name_str;
- std::string msbit_str;
- std::string lsbit_str;
- if (regex_match.GetMatchAtIndex(slice_str.c_str(), 1, reg_name_str) &&
- regex_match.GetMatchAtIndex(slice_str.c_str(), 2, msbit_str) &&
- regex_match.GetMatchAtIndex(slice_str.c_str(), 3, lsbit_str))
- {
- const uint32_t msbit = StringConvert::ToUInt32(msbit_str.c_str(), UINT32_MAX);
- const uint32_t lsbit = StringConvert::ToUInt32(lsbit_str.c_str(), UINT32_MAX);
- if (msbit != UINT32_MAX && lsbit != UINT32_MAX)
- {
- if (msbit > lsbit)
- {
- const uint32_t msbyte = msbit / 8;
- const uint32_t lsbyte = lsbit / 8;
-
- ConstString containing_reg_name(reg_name_str);
-
- RegisterInfo *containing_reg_info = GetRegisterInfo(containing_reg_name);
- if (containing_reg_info)
- {
- const uint32_t max_bit = containing_reg_info->byte_size * 8;
- if (msbit < max_bit && lsbit < max_bit)
- {
- m_invalidate_regs_map[containing_reg_info->kinds[eRegisterKindLLDB]].push_back(i);
- m_value_regs_map[i].push_back(containing_reg_info->kinds[eRegisterKindLLDB]);
- m_invalidate_regs_map[i].push_back(containing_reg_info->kinds[eRegisterKindLLDB]);
-
- if (byte_order == eByteOrderLittle)
- {
- success = true;
- reg_info.byte_offset = containing_reg_info->byte_offset + lsbyte;
- }
- else if (byte_order == eByteOrderBig)
- {
- success = true;
- reg_info.byte_offset = containing_reg_info->byte_offset + msbyte;
- }
- else
- {
- assert(!"Invalid byte order");
- }
- }
- else
- {
- if (msbit > max_bit)
- printf("error: msbit (%u) must be less than the bitsize of the register (%u)\n", msbit,
- max_bit);
- else
- printf("error: lsbit (%u) must be less than the bitsize of the register (%u)\n", lsbit,
- max_bit);
- }
- }
- else
- {
- printf("error: invalid concrete register \"%s\"\n", containing_reg_name.GetCString());
- }
- }
- else
- {
- printf("error: msbit (%u) must be greater than lsbit (%u)\n", msbit, lsbit);
- }
- }
- else
- {
- printf("error: msbit (%u) and lsbit (%u) must be valid\n", msbit, lsbit);
- }
+ // { 'name':'rcx' , 'bitsize' : 64, 'offset' : 16, 'encoding':'uint'
+ // , 'format':'hex' , 'set': 0, 'ehframe' : 2,
+ // 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', },
+ RegisterInfo reg_info;
+ std::vector<uint32_t> value_regs;
+ std::vector<uint32_t> invalidate_regs;
+ memset(&reg_info, 0, sizeof(reg_info));
+
+ ConstString name_val;
+ ConstString alt_name_val;
+ if (!reg_info_dict->GetValueForKeyAsString("name", name_val, nullptr)) {
+ Clear();
+ printf("error: registers must have valid names and offsets\n");
+ reg_info_dict->DumpToStdout();
+ return 0;
+ }
+ reg_info.name = name_val.GetCString();
+ reg_info_dict->GetValueForKeyAsString("alt-name", alt_name_val, nullptr);
+ reg_info.alt_name = alt_name_val.GetCString();
+
+ reg_info_dict->GetValueForKeyAsInteger("offset", reg_info.byte_offset,
+ UINT32_MAX);
+
+ const ByteOrder byte_order = arch.GetByteOrder();
+
+ if (reg_info.byte_offset == UINT32_MAX) {
+ // No offset for this register, see if the register has a value expression
+ // which indicates this register is part of another register. Value
+ // expressions
+ // are things like "rax[31:0]" which state that the current register's
+ // value
+ // is in a concrete register "rax" in bits 31:0. If there is a value
+ // expression
+ // we can calculate the offset
+ bool success = false;
+ std::string slice_str;
+ if (reg_info_dict->GetValueForKeyAsString("slice", slice_str, nullptr)) {
+ // Slices use the following format:
+ // REGNAME[MSBIT:LSBIT]
+ // REGNAME - name of the register to grab a slice of
+ // MSBIT - the most significant bit at which the current register value
+ // starts at
+ // LSBIT - the least significant bit at which the current register value
+ // ends at
+ static RegularExpression g_bitfield_regex(
+ llvm::StringRef("([A-Za-z_][A-Za-z0-9_]*)\\[([0-9]+):([0-9]+)\\]"));
+ RegularExpression::Match regex_match(3);
+ if (g_bitfield_regex.Execute(slice_str, &regex_match)) {
+ llvm::StringRef reg_name_str;
+ std::string msbit_str;
+ std::string lsbit_str;
+ if (regex_match.GetMatchAtIndex(slice_str.c_str(), 1, reg_name_str) &&
+ regex_match.GetMatchAtIndex(slice_str.c_str(), 2, msbit_str) &&
+ regex_match.GetMatchAtIndex(slice_str.c_str(), 3, lsbit_str)) {
+ const uint32_t msbit =
+ StringConvert::ToUInt32(msbit_str.c_str(), UINT32_MAX);
+ const uint32_t lsbit =
+ StringConvert::ToUInt32(lsbit_str.c_str(), UINT32_MAX);
+ if (msbit != UINT32_MAX && lsbit != UINT32_MAX) {
+ if (msbit > lsbit) {
+ const uint32_t msbyte = msbit / 8;
+ const uint32_t lsbyte = lsbit / 8;
+
+ ConstString containing_reg_name(reg_name_str);
+
+ RegisterInfo *containing_reg_info =
+ GetRegisterInfo(containing_reg_name);
+ if (containing_reg_info) {
+ const uint32_t max_bit = containing_reg_info->byte_size * 8;
+ if (msbit < max_bit && lsbit < max_bit) {
+ m_invalidate_regs_map[containing_reg_info
+ ->kinds[eRegisterKindLLDB]]
+ .push_back(i);
+ m_value_regs_map[i].push_back(
+ containing_reg_info->kinds[eRegisterKindLLDB]);
+ m_invalidate_regs_map[i].push_back(
+ containing_reg_info->kinds[eRegisterKindLLDB]);
+
+ if (byte_order == eByteOrderLittle) {
+ success = true;
+ reg_info.byte_offset =
+ containing_reg_info->byte_offset + lsbyte;
+ } else if (byte_order == eByteOrderBig) {
+ success = true;
+ reg_info.byte_offset =
+ containing_reg_info->byte_offset + msbyte;
+ } else {
+ assert(!"Invalid byte order");
}
+ } else {
+ if (msbit > max_bit)
+ printf("error: msbit (%u) must be less than the bitsize "
+ "of the register (%u)\n",
+ msbit, max_bit);
else
- {
- // TODO: print error invalid slice string that doesn't follow the format
- printf("error: failed to extract regex matches for parsing the register bitfield regex\n");
- }
- }
- else
- {
- // TODO: print error invalid slice string that doesn't follow the format
- printf("error: failed to match against register bitfield regex\n");
+ printf("error: lsbit (%u) must be less than the bitsize "
+ "of the register (%u)\n",
+ lsbit, max_bit);
+ }
+ } else {
+ printf("error: invalid concrete register \"%s\"\n",
+ containing_reg_name.GetCString());
}
+ } else {
+ printf("error: msbit (%u) must be greater than lsbit (%u)\n",
+ msbit, lsbit);
+ }
+ } else {
+ printf("error: msbit (%u) and lsbit (%u) must be valid\n", msbit,
+ lsbit);
}
- else
- {
- StructuredData::Array *composite_reg_list = nullptr;
- if (reg_info_dict->GetValueForKeyAsArray("composite", composite_reg_list))
- {
- const size_t num_composite_regs = composite_reg_list->GetSize();
- if (num_composite_regs > 0)
- {
- uint32_t composite_offset = UINT32_MAX;
- for (uint32_t composite_idx = 0; composite_idx < num_composite_regs; ++composite_idx)
- {
- ConstString composite_reg_name;
- if (composite_reg_list->GetItemAtIndexAsString(composite_idx, composite_reg_name, nullptr))
- {
- RegisterInfo *composite_reg_info = GetRegisterInfo(composite_reg_name);
- if (composite_reg_info)
- {
- composite_offset = std::min(composite_offset, composite_reg_info->byte_offset);
- m_value_regs_map[i].push_back(composite_reg_info->kinds[eRegisterKindLLDB]);
- m_invalidate_regs_map[composite_reg_info->kinds[eRegisterKindLLDB]].push_back(i);
- m_invalidate_regs_map[i].push_back(composite_reg_info->kinds[eRegisterKindLLDB]);
- }
- else
- {
- // TODO: print error invalid slice string that doesn't follow the format
- printf("error: failed to find composite register by name: \"%s\"\n", composite_reg_name.GetCString());
- }
- }
- else
- {
- printf("error: 'composite' list value wasn't a python string\n");
- }
- }
- if (composite_offset != UINT32_MAX)
- {
- reg_info.byte_offset = composite_offset;
- success = m_value_regs_map.find(i) != m_value_regs_map.end();
- }
- else
- {
- printf("error: 'composite' registers must specify at least one real register\n");
- }
- }
- else
- {
- printf("error: 'composite' list was empty\n");
- }
+ } else {
+ // TODO: print error invalid slice string that doesn't follow the
+ // format
+ printf("error: failed to extract regex matches for parsing the "
+ "register bitfield regex\n");
+ }
+ } else {
+ // TODO: print error invalid slice string that doesn't follow the
+ // format
+ printf("error: failed to match against register bitfield regex\n");
+ }
+ } else {
+ StructuredData::Array *composite_reg_list = nullptr;
+ if (reg_info_dict->GetValueForKeyAsArray("composite",
+ composite_reg_list)) {
+ const size_t num_composite_regs = composite_reg_list->GetSize();
+ if (num_composite_regs > 0) {
+ uint32_t composite_offset = UINT32_MAX;
+ for (uint32_t composite_idx = 0; composite_idx < num_composite_regs;
+ ++composite_idx) {
+ ConstString composite_reg_name;
+ if (composite_reg_list->GetItemAtIndexAsString(
+ composite_idx, composite_reg_name, nullptr)) {
+ RegisterInfo *composite_reg_info =
+ GetRegisterInfo(composite_reg_name);
+ if (composite_reg_info) {
+ composite_offset = std::min(composite_offset,
+ composite_reg_info->byte_offset);
+ m_value_regs_map[i].push_back(
+ composite_reg_info->kinds[eRegisterKindLLDB]);
+ m_invalidate_regs_map[composite_reg_info
+ ->kinds[eRegisterKindLLDB]]
+ .push_back(i);
+ m_invalidate_regs_map[i].push_back(
+ composite_reg_info->kinds[eRegisterKindLLDB]);
+ } else {
+ // TODO: print error invalid slice string that doesn't follow
+ // the format
+ printf("error: failed to find composite register by name: "
+ "\"%s\"\n",
+ composite_reg_name.GetCString());
}
+ } else {
+ printf(
+ "error: 'composite' list value wasn't a python string\n");
+ }
}
-
- if (!success)
- {
- Clear();
- reg_info_dict->DumpToStdout();
- return 0;
+ if (composite_offset != UINT32_MAX) {
+ reg_info.byte_offset = composite_offset;
+ success = m_value_regs_map.find(i) != m_value_regs_map.end();
+ } else {
+ printf("error: 'composite' registers must specify at least one "
+ "real register\n");
}
+ } else {
+ printf("error: 'composite' list was empty\n");
+ }
}
+ }
- int64_t bitsize = 0;
- if (!reg_info_dict->GetValueForKeyAsInteger("bitsize", bitsize))
- {
- Clear();
- printf("error: invalid or missing 'bitsize' key/value pair in register dictionary\n");
- reg_info_dict->DumpToStdout();
- return 0;
- }
-
- reg_info.byte_size = bitsize / 8;
-
- std::string dwarf_opcode_string;
- if (reg_info_dict->GetValueForKeyAsString ("dynamic_size_dwarf_expr_bytes", dwarf_opcode_string))
- {
- reg_info.dynamic_size_dwarf_len = dwarf_opcode_string.length () / 2;
- assert (reg_info.dynamic_size_dwarf_len > 0);
-
- std::vector<uint8_t> dwarf_opcode_bytes(reg_info.dynamic_size_dwarf_len);
- uint32_t j;
- StringExtractor opcode_extractor;
- // Swap "dwarf_opcode_string" over into "opcode_extractor"
- opcode_extractor.GetStringRef ().swap (dwarf_opcode_string);
- uint32_t ret_val = opcode_extractor.GetHexBytesAvail (dwarf_opcode_bytes.data (),
- reg_info.dynamic_size_dwarf_len);
- assert (ret_val == reg_info.dynamic_size_dwarf_len);
-
- for (j = 0; j < reg_info.dynamic_size_dwarf_len; ++j)
- m_dynamic_reg_size_map[i].push_back(dwarf_opcode_bytes[j]);
+ if (!success) {
+ Clear();
+ reg_info_dict->DumpToStdout();
+ return 0;
+ }
+ }
- reg_info.dynamic_size_dwarf_expr_bytes = m_dynamic_reg_size_map[i].data ();
- }
+ int64_t bitsize = 0;
+ if (!reg_info_dict->GetValueForKeyAsInteger("bitsize", bitsize)) {
+ Clear();
+ printf("error: invalid or missing 'bitsize' key/value pair in register "
+ "dictionary\n");
+ reg_info_dict->DumpToStdout();
+ return 0;
+ }
- std::string format_str;
- if (reg_info_dict->GetValueForKeyAsString("format", format_str, nullptr))
- {
- if (Args::StringToFormat(format_str.c_str(), reg_info.format, NULL).Fail())
- {
- Clear();
- printf("error: invalid 'format' value in register dictionary\n");
- reg_info_dict->DumpToStdout();
- return 0;
- }
- }
- else
- {
- reg_info_dict->GetValueForKeyAsInteger("format", reg_info.format, eFormatHex);
- }
+ reg_info.byte_size = bitsize / 8;
- std::string encoding_str;
- if (reg_info_dict->GetValueForKeyAsString("encoding", encoding_str))
- reg_info.encoding = Args::StringToEncoding(encoding_str.c_str(), eEncodingUint);
- else
- reg_info_dict->GetValueForKeyAsInteger("encoding", reg_info.encoding, eEncodingUint);
-
- size_t set = 0;
- if (!reg_info_dict->GetValueForKeyAsInteger<size_t>("set", set, -1) || set >= m_sets.size())
- {
- Clear();
- printf("error: invalid 'set' value in register dictionary, valid values are 0 - %i\n", (int)set);
- reg_info_dict->DumpToStdout();
- return 0;
- }
+ std::string dwarf_opcode_string;
+ if (reg_info_dict->GetValueForKeyAsString("dynamic_size_dwarf_expr_bytes",
+ dwarf_opcode_string)) {
+ reg_info.dynamic_size_dwarf_len = dwarf_opcode_string.length() / 2;
+ assert(reg_info.dynamic_size_dwarf_len > 0);
- // Fill in the register numbers
- reg_info.kinds[lldb::eRegisterKindLLDB] = i;
- reg_info.kinds[lldb::eRegisterKindProcessPlugin] = i;
- uint32_t eh_frame_regno = LLDB_INVALID_REGNUM;
- reg_info_dict->GetValueForKeyAsInteger("gcc", eh_frame_regno, LLDB_INVALID_REGNUM);
- if (eh_frame_regno == LLDB_INVALID_REGNUM)
- reg_info_dict->GetValueForKeyAsInteger("ehframe", eh_frame_regno, LLDB_INVALID_REGNUM);
- reg_info.kinds[lldb::eRegisterKindEHFrame] = eh_frame_regno;
- reg_info_dict->GetValueForKeyAsInteger("dwarf", reg_info.kinds[lldb::eRegisterKindDWARF], LLDB_INVALID_REGNUM);
- std::string generic_str;
- if (reg_info_dict->GetValueForKeyAsString("generic", generic_str))
- reg_info.kinds[lldb::eRegisterKindGeneric] = Args::StringToGenericRegister(generic_str.c_str());
- else
- reg_info_dict->GetValueForKeyAsInteger("generic", reg_info.kinds[lldb::eRegisterKindGeneric], LLDB_INVALID_REGNUM);
-
- // Check if this register invalidates any other register values when it is modified
- StructuredData::Array *invalidate_reg_list = nullptr;
- if (reg_info_dict->GetValueForKeyAsArray("invalidate-regs", invalidate_reg_list))
- {
- const size_t num_regs = invalidate_reg_list->GetSize();
- if (num_regs > 0)
- {
- for (uint32_t idx = 0; idx < num_regs; ++idx)
- {
- ConstString invalidate_reg_name;
- uint64_t invalidate_reg_num;
- if (invalidate_reg_list->GetItemAtIndexAsString(idx, invalidate_reg_name))
- {
- RegisterInfo *invalidate_reg_info = GetRegisterInfo(invalidate_reg_name);
- if (invalidate_reg_info)
- {
- m_invalidate_regs_map[i].push_back(invalidate_reg_info->kinds[eRegisterKindLLDB]);
- }
- else
- {
- // TODO: print error invalid slice string that doesn't follow the format
- printf("error: failed to find a 'invalidate-regs' register for \"%s\" while parsing register \"%s\"\n",
- invalidate_reg_name.GetCString(), reg_info.name);
- }
- }
- else if (invalidate_reg_list->GetItemAtIndexAsInteger(idx, invalidate_reg_num))
- {
- if (invalidate_reg_num != UINT64_MAX)
- m_invalidate_regs_map[i].push_back(invalidate_reg_num);
- else
- printf("error: 'invalidate-regs' list value wasn't a valid integer\n");
- }
- else
- {
- printf("error: 'invalidate-regs' list value wasn't a python string or integer\n");
- }
- }
- }
- else
- {
- printf("error: 'invalidate-regs' contained an empty list\n");
- }
- }
+ std::vector<uint8_t> dwarf_opcode_bytes(reg_info.dynamic_size_dwarf_len);
+ uint32_t j;
+ StringExtractor opcode_extractor;
+ // Swap "dwarf_opcode_string" over into "opcode_extractor"
+ opcode_extractor.GetStringRef().swap(dwarf_opcode_string);
+ uint32_t ret_val = opcode_extractor.GetHexBytesAvail(dwarf_opcode_bytes);
+ assert(ret_val == reg_info.dynamic_size_dwarf_len);
- // Calculate the register offset
- const size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size;
- if (m_reg_data_byte_size < end_reg_offset)
- m_reg_data_byte_size = end_reg_offset;
+ for (j = 0; j < reg_info.dynamic_size_dwarf_len; ++j)
+ m_dynamic_reg_size_map[i].push_back(dwarf_opcode_bytes[j]);
- m_regs.push_back(reg_info);
- m_set_reg_nums[set].push_back(i);
+ reg_info.dynamic_size_dwarf_expr_bytes = m_dynamic_reg_size_map[i].data();
}
- Finalize(arch);
- return m_regs.size();
-}
-
-void
-DynamicRegisterInfo::AddRegister (RegisterInfo &reg_info,
- ConstString &reg_name,
- ConstString &reg_alt_name,
- ConstString &set_name)
-{
- assert(!m_finalized);
- const uint32_t reg_num = m_regs.size();
- reg_info.name = reg_name.AsCString();
- assert (reg_info.name);
- reg_info.alt_name = reg_alt_name.AsCString(NULL);
- uint32_t i;
- if (reg_info.value_regs)
- {
- for (i=0; reg_info.value_regs[i] != LLDB_INVALID_REGNUM; ++i)
- m_value_regs_map[reg_num].push_back(reg_info.value_regs[i]);
+ std::string format_str;
+ if (reg_info_dict->GetValueForKeyAsString("format", format_str, nullptr)) {
+ if (Args::StringToFormat(format_str.c_str(), reg_info.format, NULL)
+ .Fail()) {
+ Clear();
+ printf("error: invalid 'format' value in register dictionary\n");
+ reg_info_dict->DumpToStdout();
+ return 0;
+ }
+ } else {
+ reg_info_dict->GetValueForKeyAsInteger("format", reg_info.format,
+ eFormatHex);
}
- if (reg_info.invalidate_regs)
- {
- for (i=0; reg_info.invalidate_regs[i] != LLDB_INVALID_REGNUM; ++i)
- m_invalidate_regs_map[reg_num].push_back(reg_info.invalidate_regs[i]);
+
+ std::string encoding_str;
+ if (reg_info_dict->GetValueForKeyAsString("encoding", encoding_str))
+ reg_info.encoding = Args::StringToEncoding(encoding_str, eEncodingUint);
+ else
+ reg_info_dict->GetValueForKeyAsInteger("encoding", reg_info.encoding,
+ eEncodingUint);
+
+ size_t set = 0;
+ if (!reg_info_dict->GetValueForKeyAsInteger<size_t>("set", set, -1) ||
+ set >= m_sets.size()) {
+ Clear();
+ printf("error: invalid 'set' value in register dictionary, valid values "
+ "are 0 - %i\n",
+ (int)set);
+ reg_info_dict->DumpToStdout();
+ return 0;
}
- if (reg_info.dynamic_size_dwarf_expr_bytes)
- {
- for (i = 0; i < reg_info.dynamic_size_dwarf_len; ++i)
- m_dynamic_reg_size_map[reg_num].push_back(reg_info.dynamic_size_dwarf_expr_bytes[i]);
- reg_info.dynamic_size_dwarf_expr_bytes = m_dynamic_reg_size_map[reg_num].data ();
+ // Fill in the register numbers
+ reg_info.kinds[lldb::eRegisterKindLLDB] = i;
+ reg_info.kinds[lldb::eRegisterKindProcessPlugin] = i;
+ uint32_t eh_frame_regno = LLDB_INVALID_REGNUM;
+ reg_info_dict->GetValueForKeyAsInteger("gcc", eh_frame_regno,
+ LLDB_INVALID_REGNUM);
+ if (eh_frame_regno == LLDB_INVALID_REGNUM)
+ reg_info_dict->GetValueForKeyAsInteger("ehframe", eh_frame_regno,
+ LLDB_INVALID_REGNUM);
+ reg_info.kinds[lldb::eRegisterKindEHFrame] = eh_frame_regno;
+ reg_info_dict->GetValueForKeyAsInteger(
+ "dwarf", reg_info.kinds[lldb::eRegisterKindDWARF], LLDB_INVALID_REGNUM);
+ std::string generic_str;
+ if (reg_info_dict->GetValueForKeyAsString("generic", generic_str))
+ reg_info.kinds[lldb::eRegisterKindGeneric] =
+ Args::StringToGenericRegister(generic_str);
+ else
+ reg_info_dict->GetValueForKeyAsInteger(
+ "generic", reg_info.kinds[lldb::eRegisterKindGeneric],
+ LLDB_INVALID_REGNUM);
+
+ // Check if this register invalidates any other register values when it is
+ // modified
+ StructuredData::Array *invalidate_reg_list = nullptr;
+ if (reg_info_dict->GetValueForKeyAsArray("invalidate-regs",
+ invalidate_reg_list)) {
+ const size_t num_regs = invalidate_reg_list->GetSize();
+ if (num_regs > 0) {
+ for (uint32_t idx = 0; idx < num_regs; ++idx) {
+ ConstString invalidate_reg_name;
+ uint64_t invalidate_reg_num;
+ if (invalidate_reg_list->GetItemAtIndexAsString(
+ idx, invalidate_reg_name)) {
+ RegisterInfo *invalidate_reg_info =
+ GetRegisterInfo(invalidate_reg_name);
+ if (invalidate_reg_info) {
+ m_invalidate_regs_map[i].push_back(
+ invalidate_reg_info->kinds[eRegisterKindLLDB]);
+ } else {
+ // TODO: print error invalid slice string that doesn't follow the
+ // format
+ printf("error: failed to find a 'invalidate-regs' register for "
+ "\"%s\" while parsing register \"%s\"\n",
+ invalidate_reg_name.GetCString(), reg_info.name);
+ }
+ } else if (invalidate_reg_list->GetItemAtIndexAsInteger(
+ idx, invalidate_reg_num)) {
+ if (invalidate_reg_num != UINT64_MAX)
+ m_invalidate_regs_map[i].push_back(invalidate_reg_num);
+ else
+ printf("error: 'invalidate-regs' list value wasn't a valid "
+ "integer\n");
+ } else {
+ printf("error: 'invalidate-regs' list value wasn't a python string "
+ "or integer\n");
+ }
+ }
+ } else {
+ printf("error: 'invalidate-regs' contained an empty list\n");
+ }
}
- m_regs.push_back (reg_info);
- uint32_t set = GetRegisterSetIndexByName (set_name, true);
- assert (set < m_sets.size());
- assert (set < m_set_reg_nums.size());
- assert (set < m_set_names.size());
- m_set_reg_nums[set].push_back(reg_num);
- size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size;
+ // Calculate the register offset
+ const size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size;
if (m_reg_data_byte_size < end_reg_offset)
- m_reg_data_byte_size = end_reg_offset;
+ m_reg_data_byte_size = end_reg_offset;
+
+ m_regs.push_back(reg_info);
+ m_set_reg_nums[set].push_back(i);
+ }
+ Finalize(arch);
+ return m_regs.size();
}
-void
-DynamicRegisterInfo::Finalize (const ArchSpec &arch)
-{
- if (m_finalized)
- return;
-
- m_finalized = true;
- const size_t num_sets = m_sets.size();
- for (size_t set = 0; set < num_sets; ++set)
- {
- assert (m_sets.size() == m_set_reg_nums.size());
- m_sets[set].num_registers = m_set_reg_nums[set].size();
- m_sets[set].registers = &m_set_reg_nums[set][0];
- }
-
- // sort and unique all value registers and make sure each is terminated with
- // LLDB_INVALID_REGNUM
-
- for (reg_to_regs_map::iterator pos = m_value_regs_map.begin(), end = m_value_regs_map.end();
- pos != end;
- ++pos)
- {
- if (pos->second.size() > 1)
- {
- std::sort (pos->second.begin(), pos->second.end());
- reg_num_collection::iterator unique_end = std::unique (pos->second.begin(), pos->second.end());
- if (unique_end != pos->second.end())
- pos->second.erase(unique_end, pos->second.end());
- }
- assert (!pos->second.empty());
- if (pos->second.back() != LLDB_INVALID_REGNUM)
- pos->second.push_back(LLDB_INVALID_REGNUM);
- }
-
- // Now update all value_regs with each register info as needed
- const size_t num_regs = m_regs.size();
- for (size_t i=0; i<num_regs; ++i)
- {
- if (m_value_regs_map.find(i) != m_value_regs_map.end())
- m_regs[i].value_regs = m_value_regs_map[i].data();
- else
- m_regs[i].value_regs = NULL;
- }
+void DynamicRegisterInfo::AddRegister(RegisterInfo &reg_info,
+ ConstString &reg_name,
+ ConstString &reg_alt_name,
+ ConstString &set_name) {
+ assert(!m_finalized);
+ const uint32_t reg_num = m_regs.size();
+ reg_info.name = reg_name.AsCString();
+ assert(reg_info.name);
+ reg_info.alt_name = reg_alt_name.AsCString(NULL);
+ uint32_t i;
+ if (reg_info.value_regs) {
+ for (i = 0; reg_info.value_regs[i] != LLDB_INVALID_REGNUM; ++i)
+ m_value_regs_map[reg_num].push_back(reg_info.value_regs[i]);
+ }
+ if (reg_info.invalidate_regs) {
+ for (i = 0; reg_info.invalidate_regs[i] != LLDB_INVALID_REGNUM; ++i)
+ m_invalidate_regs_map[reg_num].push_back(reg_info.invalidate_regs[i]);
+ }
+ if (reg_info.dynamic_size_dwarf_expr_bytes) {
+ for (i = 0; i < reg_info.dynamic_size_dwarf_len; ++i)
+ m_dynamic_reg_size_map[reg_num].push_back(
+ reg_info.dynamic_size_dwarf_expr_bytes[i]);
+
+ reg_info.dynamic_size_dwarf_expr_bytes =
+ m_dynamic_reg_size_map[reg_num].data();
+ }
+
+ m_regs.push_back(reg_info);
+ uint32_t set = GetRegisterSetIndexByName(set_name, true);
+ assert(set < m_sets.size());
+ assert(set < m_set_reg_nums.size());
+ assert(set < m_set_names.size());
+ m_set_reg_nums[set].push_back(reg_num);
+ size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size;
+ if (m_reg_data_byte_size < end_reg_offset)
+ m_reg_data_byte_size = end_reg_offset;
+}
- // Expand all invalidation dependencies
- for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(), end = m_invalidate_regs_map.end();
- pos != end;
- ++pos)
- {
- const uint32_t reg_num = pos->first;
-
- if (m_regs[reg_num].value_regs)
- {
- reg_num_collection extra_invalid_regs;
- for (const uint32_t invalidate_reg_num : pos->second)
- {
- reg_to_regs_map::iterator invalidate_pos = m_invalidate_regs_map.find(invalidate_reg_num);
- if (invalidate_pos != m_invalidate_regs_map.end())
- {
- for (const uint32_t concrete_invalidate_reg_num : invalidate_pos->second)
- {
- if (concrete_invalidate_reg_num != reg_num)
- extra_invalid_regs.push_back(concrete_invalidate_reg_num);
- }
- }
- }
- pos->second.insert(pos->second.end(), extra_invalid_regs.begin(), extra_invalid_regs.end());
- }
+void DynamicRegisterInfo::Finalize(const ArchSpec &arch) {
+ if (m_finalized)
+ return;
+
+ m_finalized = true;
+ const size_t num_sets = m_sets.size();
+ for (size_t set = 0; set < num_sets; ++set) {
+ assert(m_sets.size() == m_set_reg_nums.size());
+ m_sets[set].num_registers = m_set_reg_nums[set].size();
+ m_sets[set].registers = &m_set_reg_nums[set][0];
+ }
+
+ // sort and unique all value registers and make sure each is terminated with
+ // LLDB_INVALID_REGNUM
+
+ for (reg_to_regs_map::iterator pos = m_value_regs_map.begin(),
+ end = m_value_regs_map.end();
+ pos != end; ++pos) {
+ if (pos->second.size() > 1) {
+ std::sort(pos->second.begin(), pos->second.end());
+ reg_num_collection::iterator unique_end =
+ std::unique(pos->second.begin(), pos->second.end());
+ if (unique_end != pos->second.end())
+ pos->second.erase(unique_end, pos->second.end());
}
-
- // sort and unique all invalidate registers and make sure each is terminated with
- // LLDB_INVALID_REGNUM
- for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(), end = m_invalidate_regs_map.end();
- pos != end;
- ++pos)
- {
- if (pos->second.size() > 1)
- {
- std::sort (pos->second.begin(), pos->second.end());
- reg_num_collection::iterator unique_end = std::unique (pos->second.begin(), pos->second.end());
- if (unique_end != pos->second.end())
- pos->second.erase(unique_end, pos->second.end());
+ assert(!pos->second.empty());
+ if (pos->second.back() != LLDB_INVALID_REGNUM)
+ pos->second.push_back(LLDB_INVALID_REGNUM);
+ }
+
+ // Now update all value_regs with each register info as needed
+ const size_t num_regs = m_regs.size();
+ for (size_t i = 0; i < num_regs; ++i) {
+ if (m_value_regs_map.find(i) != m_value_regs_map.end())
+ m_regs[i].value_regs = m_value_regs_map[i].data();
+ else
+ m_regs[i].value_regs = NULL;
+ }
+
+ // Expand all invalidation dependencies
+ for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(),
+ end = m_invalidate_regs_map.end();
+ pos != end; ++pos) {
+ const uint32_t reg_num = pos->first;
+
+ if (m_regs[reg_num].value_regs) {
+ reg_num_collection extra_invalid_regs;
+ for (const uint32_t invalidate_reg_num : pos->second) {
+ reg_to_regs_map::iterator invalidate_pos =
+ m_invalidate_regs_map.find(invalidate_reg_num);
+ if (invalidate_pos != m_invalidate_regs_map.end()) {
+ for (const uint32_t concrete_invalidate_reg_num :
+ invalidate_pos->second) {
+ if (concrete_invalidate_reg_num != reg_num)
+ extra_invalid_regs.push_back(concrete_invalidate_reg_num);
+ }
}
- assert (!pos->second.empty());
- if (pos->second.back() != LLDB_INVALID_REGNUM)
- pos->second.push_back(LLDB_INVALID_REGNUM);
+ }
+ pos->second.insert(pos->second.end(), extra_invalid_regs.begin(),
+ extra_invalid_regs.end());
}
-
- // Now update all invalidate_regs with each register info as needed
- for (size_t i=0; i<num_regs; ++i)
- {
- if (m_invalidate_regs_map.find(i) != m_invalidate_regs_map.end())
- m_regs[i].invalidate_regs = m_invalidate_regs_map[i].data();
- else
- m_regs[i].invalidate_regs = NULL;
+ }
+
+ // sort and unique all invalidate registers and make sure each is terminated
+ // with
+ // LLDB_INVALID_REGNUM
+ for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(),
+ end = m_invalidate_regs_map.end();
+ pos != end; ++pos) {
+ if (pos->second.size() > 1) {
+ std::sort(pos->second.begin(), pos->second.end());
+ reg_num_collection::iterator unique_end =
+ std::unique(pos->second.begin(), pos->second.end());
+ if (unique_end != pos->second.end())
+ pos->second.erase(unique_end, pos->second.end());
}
-
- // Check if we need to automatically set the generic registers in case
- // they weren't set
- bool generic_regs_specified = false;
- for (const auto &reg: m_regs)
- {
- if (reg.kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM)
- {
- generic_regs_specified = true;
- break;
- }
+ assert(!pos->second.empty());
+ if (pos->second.back() != LLDB_INVALID_REGNUM)
+ pos->second.push_back(LLDB_INVALID_REGNUM);
+ }
+
+ // Now update all invalidate_regs with each register info as needed
+ for (size_t i = 0; i < num_regs; ++i) {
+ if (m_invalidate_regs_map.find(i) != m_invalidate_regs_map.end())
+ m_regs[i].invalidate_regs = m_invalidate_regs_map[i].data();
+ else
+ m_regs[i].invalidate_regs = NULL;
+ }
+
+ // Check if we need to automatically set the generic registers in case
+ // they weren't set
+ bool generic_regs_specified = false;
+ for (const auto &reg : m_regs) {
+ if (reg.kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM) {
+ generic_regs_specified = true;
+ break;
}
-
- if (!generic_regs_specified)
- {
- switch (arch.GetMachine())
- {
- case llvm::Triple::aarch64:
- case llvm::Triple::aarch64_be:
- for (auto &reg: m_regs)
- {
- if (strcmp(reg.name, "pc") == 0)
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
- else if ((strcmp(reg.name, "fp") == 0) || (strcmp(reg.name, "x29") == 0))
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
- else if ((strcmp(reg.name, "lr") == 0) || (strcmp(reg.name, "x30") == 0))
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
- else if ((strcmp(reg.name, "sp") == 0) || (strcmp(reg.name, "x31") == 0))
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
- else if (strcmp(reg.name, "cpsr") == 0)
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
- }
- break;
-
- case llvm::Triple::arm:
- case llvm::Triple::armeb:
- case llvm::Triple::thumb:
- case llvm::Triple::thumbeb:
- for (auto &reg: m_regs)
- {
- if ((strcmp(reg.name, "pc") == 0) || (strcmp(reg.name, "r15") == 0))
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
- else if ((strcmp(reg.name, "sp") == 0) || (strcmp(reg.name, "r13") == 0))
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
- else if ((strcmp(reg.name, "lr") == 0) || (strcmp(reg.name, "r14") == 0))
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
- else if ((strcmp(reg.name, "r7") == 0) && arch.GetTriple().getVendor() == llvm::Triple::Apple)
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
- else if ((strcmp(reg.name, "r11") == 0) && arch.GetTriple().getVendor() != llvm::Triple::Apple)
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
- else if (strcmp(reg.name, "fp") == 0)
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
- else if (strcmp(reg.name, "cpsr") == 0)
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
- }
- break;
-
- case llvm::Triple::x86:
- for (auto &reg: m_regs)
- {
- if ((strcmp(reg.name, "eip") == 0) || (strcmp(reg.name, "pc") == 0))
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
- else if ((strcmp(reg.name, "esp") == 0) || (strcmp(reg.name, "sp") == 0))
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
- else if ((strcmp(reg.name, "ebp") == 0) || (strcmp(reg.name, "fp") == 0))
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
- else if ((strcmp(reg.name, "eflags") == 0) || (strcmp(reg.name, "flags") == 0))
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
- }
- break;
-
- case llvm::Triple::x86_64:
- for (auto &reg: m_regs)
- {
- if ((strcmp(reg.name, "rip") == 0) || (strcmp(reg.name, "pc") == 0))
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
- else if ((strcmp(reg.name, "rsp") == 0) || (strcmp(reg.name, "sp") == 0))
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
- else if ((strcmp(reg.name, "rbp") == 0) || (strcmp(reg.name, "fp") == 0))
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
- else if ((strcmp(reg.name, "rflags") == 0) || (strcmp(reg.name, "flags") == 0))
- reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
- }
- break;
-
- default:
- break;
- }
+ }
+
+ if (!generic_regs_specified) {
+ switch (arch.GetMachine()) {
+ case llvm::Triple::aarch64:
+ case llvm::Triple::aarch64_be:
+ for (auto &reg : m_regs) {
+ if (strcmp(reg.name, "pc") == 0)
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
+ else if ((strcmp(reg.name, "fp") == 0) ||
+ (strcmp(reg.name, "x29") == 0))
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
+ else if ((strcmp(reg.name, "lr") == 0) ||
+ (strcmp(reg.name, "x30") == 0))
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
+ else if ((strcmp(reg.name, "sp") == 0) ||
+ (strcmp(reg.name, "x31") == 0))
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
+ else if (strcmp(reg.name, "cpsr") == 0)
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
+ }
+ break;
+
+ case llvm::Triple::arm:
+ case llvm::Triple::armeb:
+ case llvm::Triple::thumb:
+ case llvm::Triple::thumbeb:
+ for (auto &reg : m_regs) {
+ if ((strcmp(reg.name, "pc") == 0) || (strcmp(reg.name, "r15") == 0))
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
+ else if ((strcmp(reg.name, "sp") == 0) ||
+ (strcmp(reg.name, "r13") == 0))
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
+ else if ((strcmp(reg.name, "lr") == 0) ||
+ (strcmp(reg.name, "r14") == 0))
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
+ else if ((strcmp(reg.name, "r7") == 0) &&
+ arch.GetTriple().getVendor() == llvm::Triple::Apple)
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
+ else if ((strcmp(reg.name, "r11") == 0) &&
+ arch.GetTriple().getVendor() != llvm::Triple::Apple)
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
+ else if (strcmp(reg.name, "fp") == 0)
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
+ else if (strcmp(reg.name, "cpsr") == 0)
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
+ }
+ break;
+
+ case llvm::Triple::x86:
+ for (auto &reg : m_regs) {
+ if ((strcmp(reg.name, "eip") == 0) || (strcmp(reg.name, "pc") == 0))
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
+ else if ((strcmp(reg.name, "esp") == 0) ||
+ (strcmp(reg.name, "sp") == 0))
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
+ else if ((strcmp(reg.name, "ebp") == 0) ||
+ (strcmp(reg.name, "fp") == 0))
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
+ else if ((strcmp(reg.name, "eflags") == 0) ||
+ (strcmp(reg.name, "flags") == 0))
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
+ }
+ break;
+
+ case llvm::Triple::x86_64:
+ for (auto &reg : m_regs) {
+ if ((strcmp(reg.name, "rip") == 0) || (strcmp(reg.name, "pc") == 0))
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
+ else if ((strcmp(reg.name, "rsp") == 0) ||
+ (strcmp(reg.name, "sp") == 0))
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
+ else if ((strcmp(reg.name, "rbp") == 0) ||
+ (strcmp(reg.name, "fp") == 0))
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
+ else if ((strcmp(reg.name, "rflags") == 0) ||
+ (strcmp(reg.name, "flags") == 0))
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
+ }
+ break;
+
+ default:
+ break;
}
+ }
}
-size_t
-DynamicRegisterInfo::GetNumRegisters() const
-{
- return m_regs.size();
-}
+size_t DynamicRegisterInfo::GetNumRegisters() const { return m_regs.size(); }
-size_t
-DynamicRegisterInfo::GetNumRegisterSets() const
-{
- return m_sets.size();
-}
+size_t DynamicRegisterInfo::GetNumRegisterSets() const { return m_sets.size(); }
-size_t
-DynamicRegisterInfo::GetRegisterDataByteSize() const
-{
- return m_reg_data_byte_size;
+size_t DynamicRegisterInfo::GetRegisterDataByteSize() const {
+ return m_reg_data_byte_size;
}
const RegisterInfo *
-DynamicRegisterInfo::GetRegisterInfoAtIndex (uint32_t i) const
-{
- if (i < m_regs.size())
- return &m_regs[i];
- return NULL;
+DynamicRegisterInfo::GetRegisterInfoAtIndex(uint32_t i) const {
+ if (i < m_regs.size())
+ return &m_regs[i];
+ return NULL;
}
-RegisterInfo *
-DynamicRegisterInfo::GetRegisterInfoAtIndex (uint32_t i)
-{
- if (i < m_regs.size())
- return &m_regs[i];
- return NULL;
+RegisterInfo *DynamicRegisterInfo::GetRegisterInfoAtIndex(uint32_t i) {
+ if (i < m_regs.size())
+ return &m_regs[i];
+ return NULL;
}
-const RegisterSet *
-DynamicRegisterInfo::GetRegisterSet (uint32_t i) const
-{
- if (i < m_sets.size())
- return &m_sets[i];
- return NULL;
+const RegisterSet *DynamicRegisterInfo::GetRegisterSet(uint32_t i) const {
+ if (i < m_sets.size())
+ return &m_sets[i];
+ return NULL;
}
-uint32_t
-DynamicRegisterInfo::GetRegisterSetIndexByName (ConstString &set_name, bool can_create)
-{
- name_collection::iterator pos, end = m_set_names.end();
- for (pos = m_set_names.begin(); pos != end; ++pos)
- {
- if (*pos == set_name)
- return std::distance (m_set_names.begin(), pos);
- }
-
- m_set_names.push_back(set_name);
- m_set_reg_nums.resize(m_set_reg_nums.size()+1);
- RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL };
- m_sets.push_back (new_set);
- return m_sets.size() - 1;
+uint32_t DynamicRegisterInfo::GetRegisterSetIndexByName(ConstString &set_name,
+ bool can_create) {
+ name_collection::iterator pos, end = m_set_names.end();
+ for (pos = m_set_names.begin(); pos != end; ++pos) {
+ if (*pos == set_name)
+ return std::distance(m_set_names.begin(), pos);
+ }
+
+ m_set_names.push_back(set_name);
+ m_set_reg_nums.resize(m_set_reg_nums.size() + 1);
+ RegisterSet new_set = {set_name.AsCString(), NULL, 0, NULL};
+ m_sets.push_back(new_set);
+ return m_sets.size() - 1;
}
uint32_t
-DynamicRegisterInfo::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) const
-{
- reg_collection::const_iterator pos, end = m_regs.end();
- for (pos = m_regs.begin(); pos != end; ++pos)
- {
- if (pos->kinds[kind] == num)
- return std::distance (m_regs.begin(), pos);
- }
-
- return LLDB_INVALID_REGNUM;
+DynamicRegisterInfo::ConvertRegisterKindToRegisterNumber(uint32_t kind,
+ uint32_t num) const {
+ reg_collection::const_iterator pos, end = m_regs.end();
+ for (pos = m_regs.begin(); pos != end; ++pos) {
+ if (pos->kinds[kind] == num)
+ return std::distance(m_regs.begin(), pos);
+ }
+
+ return LLDB_INVALID_REGNUM;
}
-void
-DynamicRegisterInfo::Clear()
-{
- m_regs.clear();
- m_sets.clear();
- m_set_reg_nums.clear();
- m_set_names.clear();
- m_value_regs_map.clear();
- m_invalidate_regs_map.clear();
- m_dynamic_reg_size_map.clear();
- m_reg_data_byte_size = 0;
- m_finalized = false;
+void DynamicRegisterInfo::Clear() {
+ m_regs.clear();
+ m_sets.clear();
+ m_set_reg_nums.clear();
+ m_set_names.clear();
+ m_value_regs_map.clear();
+ m_invalidate_regs_map.clear();
+ m_dynamic_reg_size_map.clear();
+ m_reg_data_byte_size = 0;
+ m_finalized = false;
}
-void
-DynamicRegisterInfo::Dump () const
-{
- StreamFile s(stdout, false);
- const size_t num_regs = m_regs.size();
- s.Printf("%p: DynamicRegisterInfo contains %" PRIu64 " registers:\n",
- static_cast<const void*>(this), static_cast<uint64_t>(num_regs));
- for (size_t i=0; i<num_regs; ++i)
- {
- s.Printf("[%3" PRIu64 "] name = %-10s", (uint64_t)i, m_regs[i].name);
- s.Printf(", size = %2u, offset = %4u, encoding = %u, format = %-10s",
- m_regs[i].byte_size,
- m_regs[i].byte_offset,
- m_regs[i].encoding,
- FormatManager::GetFormatAsCString (m_regs[i].format));
- if (m_regs[i].kinds[eRegisterKindProcessPlugin] != LLDB_INVALID_REGNUM)
- s.Printf(", process plugin = %3u", m_regs[i].kinds[eRegisterKindProcessPlugin]);
- if (m_regs[i].kinds[eRegisterKindDWARF] != LLDB_INVALID_REGNUM)
- s.Printf(", dwarf = %3u", m_regs[i].kinds[eRegisterKindDWARF]);
- if (m_regs[i].kinds[eRegisterKindEHFrame] != LLDB_INVALID_REGNUM)
- s.Printf(", ehframe = %3u", m_regs[i].kinds[eRegisterKindEHFrame]);
- if (m_regs[i].kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM)
- s.Printf(", generic = %3u", m_regs[i].kinds[eRegisterKindGeneric]);
- if (m_regs[i].alt_name)
- s.Printf(", alt-name = %s", m_regs[i].alt_name);
- if (m_regs[i].value_regs)
- {
- s.Printf(", value_regs = [ ");
- for (size_t j=0; m_regs[i].value_regs[j] != LLDB_INVALID_REGNUM; ++j)
- {
- s.Printf("%s ", m_regs[m_regs[i].value_regs[j]].name);
- }
- s.Printf("]");
- }
- if (m_regs[i].invalidate_regs)
- {
- s.Printf(", invalidate_regs = [ ");
- for (size_t j=0; m_regs[i].invalidate_regs[j] != LLDB_INVALID_REGNUM; ++j)
- {
- s.Printf("%s ", m_regs[m_regs[i].invalidate_regs[j]].name);
- }
- s.Printf("]");
- }
- s.EOL();
+void DynamicRegisterInfo::Dump() const {
+ StreamFile s(stdout, false);
+ const size_t num_regs = m_regs.size();
+ s.Printf("%p: DynamicRegisterInfo contains %" PRIu64 " registers:\n",
+ static_cast<const void *>(this), static_cast<uint64_t>(num_regs));
+ for (size_t i = 0; i < num_regs; ++i) {
+ s.Printf("[%3" PRIu64 "] name = %-10s", (uint64_t)i, m_regs[i].name);
+ s.Printf(", size = %2u, offset = %4u, encoding = %u, format = %-10s",
+ m_regs[i].byte_size, m_regs[i].byte_offset, m_regs[i].encoding,
+ FormatManager::GetFormatAsCString(m_regs[i].format));
+ if (m_regs[i].kinds[eRegisterKindProcessPlugin] != LLDB_INVALID_REGNUM)
+ s.Printf(", process plugin = %3u",
+ m_regs[i].kinds[eRegisterKindProcessPlugin]);
+ if (m_regs[i].kinds[eRegisterKindDWARF] != LLDB_INVALID_REGNUM)
+ s.Printf(", dwarf = %3u", m_regs[i].kinds[eRegisterKindDWARF]);
+ if (m_regs[i].kinds[eRegisterKindEHFrame] != LLDB_INVALID_REGNUM)
+ s.Printf(", ehframe = %3u", m_regs[i].kinds[eRegisterKindEHFrame]);
+ if (m_regs[i].kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM)
+ s.Printf(", generic = %3u", m_regs[i].kinds[eRegisterKindGeneric]);
+ if (m_regs[i].alt_name)
+ s.Printf(", alt-name = %s", m_regs[i].alt_name);
+ if (m_regs[i].value_regs) {
+ s.Printf(", value_regs = [ ");
+ for (size_t j = 0; m_regs[i].value_regs[j] != LLDB_INVALID_REGNUM; ++j) {
+ s.Printf("%s ", m_regs[m_regs[i].value_regs[j]].name);
+ }
+ s.Printf("]");
}
-
- const size_t num_sets = m_sets.size();
- s.Printf("%p: DynamicRegisterInfo contains %" PRIu64 " register sets:\n",
- static_cast<const void*>(this), static_cast<uint64_t>(num_sets));
- for (size_t i=0; i<num_sets; ++i)
- {
- s.Printf("set[%" PRIu64 "] name = %s, regs = [", (uint64_t)i, m_sets[i].name);
- for (size_t idx=0; idx<m_sets[i].num_registers; ++idx)
- {
- s.Printf("%s ", m_regs[m_sets[i].registers[idx]].name);
- }
- s.Printf("]\n");
+ if (m_regs[i].invalidate_regs) {
+ s.Printf(", invalidate_regs = [ ");
+ for (size_t j = 0; m_regs[i].invalidate_regs[j] != LLDB_INVALID_REGNUM;
+ ++j) {
+ s.Printf("%s ", m_regs[m_regs[i].invalidate_regs[j]].name);
+ }
+ s.Printf("]");
+ }
+ s.EOL();
+ }
+
+ const size_t num_sets = m_sets.size();
+ s.Printf("%p: DynamicRegisterInfo contains %" PRIu64 " register sets:\n",
+ static_cast<const void *>(this), static_cast<uint64_t>(num_sets));
+ for (size_t i = 0; i < num_sets; ++i) {
+ s.Printf("set[%" PRIu64 "] name = %s, regs = [", (uint64_t)i,
+ m_sets[i].name);
+ for (size_t idx = 0; idx < m_sets[i].num_registers; ++idx) {
+ s.Printf("%s ", m_regs[m_sets[i].registers[idx]].name);
}
+ s.Printf("]\n");
+ }
}
-
-
-lldb_private::RegisterInfo *
-DynamicRegisterInfo::GetRegisterInfo (const lldb_private::ConstString &reg_name)
-{
- for (auto &reg_info : m_regs)
- {
- // We can use pointer comparison since we used a ConstString to set
- // the "name" member in AddRegister()
- if (reg_info.name == reg_name.GetCString())
- {
- return &reg_info;
- }
+lldb_private::RegisterInfo *DynamicRegisterInfo::GetRegisterInfo(
+ const lldb_private::ConstString &reg_name) {
+ for (auto &reg_info : m_regs) {
+ // We can use pointer comparison since we used a ConstString to set
+ // the "name" member in AddRegister()
+ if (reg_info.name == reg_name.GetCString()) {
+ return &reg_info;
}
- return NULL;
+ }
+ return NULL;
}
diff --git a/source/Plugins/Process/Utility/DynamicRegisterInfo.h b/source/Plugins/Process/Utility/DynamicRegisterInfo.h
index d97dc136bd63..e5c22fe484e9 100644
--- a/source/Plugins/Process/Utility/DynamicRegisterInfo.h
+++ b/source/Plugins/Process/Utility/DynamicRegisterInfo.h
@@ -12,93 +12,82 @@
// C Includes
// C++ Includes
-#include <vector>
#include <map>
+#include <vector>
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/StructuredData.h"
+#include "lldb/lldb-private.h"
-class DynamicRegisterInfo
-{
+class DynamicRegisterInfo {
public:
- DynamicRegisterInfo ();
+ DynamicRegisterInfo();
- DynamicRegisterInfo(const lldb_private::StructuredData::Dictionary &dict,
- const lldb_private::ArchSpec &arch);
+ DynamicRegisterInfo(const lldb_private::StructuredData::Dictionary &dict,
+ const lldb_private::ArchSpec &arch);
- virtual
- ~DynamicRegisterInfo ();
+ virtual ~DynamicRegisterInfo();
- size_t SetRegisterInfo(const lldb_private::StructuredData::Dictionary &dict,
- const lldb_private::ArchSpec &arch);
+ size_t SetRegisterInfo(const lldb_private::StructuredData::Dictionary &dict,
+ const lldb_private::ArchSpec &arch);
- void
- AddRegister (lldb_private::RegisterInfo &reg_info,
- lldb_private::ConstString &reg_name,
- lldb_private::ConstString &reg_alt_name,
- lldb_private::ConstString &set_name);
+ void AddRegister(lldb_private::RegisterInfo &reg_info,
+ lldb_private::ConstString &reg_name,
+ lldb_private::ConstString &reg_alt_name,
+ lldb_private::ConstString &set_name);
- void
- Finalize (const lldb_private::ArchSpec &arch);
+ void Finalize(const lldb_private::ArchSpec &arch);
- size_t
- GetNumRegisters() const;
+ size_t GetNumRegisters() const;
- size_t
- GetNumRegisterSets() const;
+ size_t GetNumRegisterSets() const;
- size_t
- GetRegisterDataByteSize() const;
+ size_t GetRegisterDataByteSize() const;
- const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex (uint32_t i) const;
+ const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(uint32_t i) const;
- lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex (uint32_t i);
+ lldb_private::RegisterInfo *GetRegisterInfoAtIndex(uint32_t i);
- const lldb_private::RegisterSet *
- GetRegisterSet (uint32_t i) const;
+ const lldb_private::RegisterSet *GetRegisterSet(uint32_t i) const;
- uint32_t
- GetRegisterSetIndexByName (lldb_private::ConstString &set_name, bool can_create);
+ uint32_t GetRegisterSetIndexByName(lldb_private::ConstString &set_name,
+ bool can_create);
- uint32_t
- ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) const;
+ uint32_t ConvertRegisterKindToRegisterNumber(uint32_t kind,
+ uint32_t num) const;
- void
- Dump () const;
+ void Dump() const;
- void
- Clear();
+ void Clear();
protected:
- //------------------------------------------------------------------
- // Classes that inherit from DynamicRegisterInfo can see and modify these
- //------------------------------------------------------------------
- typedef std::vector <lldb_private::RegisterInfo> reg_collection;
- typedef std::vector <lldb_private::RegisterSet> set_collection;
- typedef std::vector <uint32_t> reg_num_collection;
- typedef std::vector <reg_num_collection> set_reg_num_collection;
- typedef std::vector <lldb_private::ConstString> name_collection;
- typedef std::map<uint32_t, reg_num_collection> reg_to_regs_map;
- typedef std::vector <uint8_t> dwarf_opcode;
- typedef std::map<uint32_t, dwarf_opcode> dynamic_reg_size_map;
-
- lldb_private::RegisterInfo *
- GetRegisterInfo (const lldb_private::ConstString &reg_name);
-
- reg_collection m_regs;
- set_collection m_sets;
- set_reg_num_collection m_set_reg_nums;
- name_collection m_set_names;
- reg_to_regs_map m_value_regs_map;
- reg_to_regs_map m_invalidate_regs_map;
- dynamic_reg_size_map m_dynamic_reg_size_map;
- size_t m_reg_data_byte_size; // The number of bytes required to store all registers
- bool m_finalized;
+ //------------------------------------------------------------------
+ // Classes that inherit from DynamicRegisterInfo can see and modify these
+ //------------------------------------------------------------------
+ typedef std::vector<lldb_private::RegisterInfo> reg_collection;
+ typedef std::vector<lldb_private::RegisterSet> set_collection;
+ typedef std::vector<uint32_t> reg_num_collection;
+ typedef std::vector<reg_num_collection> set_reg_num_collection;
+ typedef std::vector<lldb_private::ConstString> name_collection;
+ typedef std::map<uint32_t, reg_num_collection> reg_to_regs_map;
+ typedef std::vector<uint8_t> dwarf_opcode;
+ typedef std::map<uint32_t, dwarf_opcode> dynamic_reg_size_map;
+
+ lldb_private::RegisterInfo *
+ GetRegisterInfo(const lldb_private::ConstString &reg_name);
+
+ reg_collection m_regs;
+ set_collection m_sets;
+ set_reg_num_collection m_set_reg_nums;
+ name_collection m_set_names;
+ reg_to_regs_map m_value_regs_map;
+ reg_to_regs_map m_invalidate_regs_map;
+ dynamic_reg_size_map m_dynamic_reg_size_map;
+ size_t m_reg_data_byte_size; // The number of bytes required to store all
+ // registers
+ bool m_finalized;
};
-#endif // lldb_DynamicRegisterInfo_h_
+#endif // lldb_DynamicRegisterInfo_h_
diff --git a/source/Plugins/Process/Utility/FreeBSDSignals.cpp b/source/Plugins/Process/Utility/FreeBSDSignals.cpp
index e575e2c6a496..f695a11c9759 100644
--- a/source/Plugins/Process/Utility/FreeBSDSignals.cpp
+++ b/source/Plugins/Process/Utility/FreeBSDSignals.cpp
@@ -15,81 +15,77 @@
using namespace lldb_private;
-FreeBSDSignals::FreeBSDSignals()
- : UnixSignals()
-{
- Reset();
-}
+FreeBSDSignals::FreeBSDSignals() : UnixSignals() { Reset(); }
-void
-FreeBSDSignals::Reset()
-{
- UnixSignals::Reset();
+void FreeBSDSignals::Reset() {
+ UnixSignals::Reset();
- // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION
- // ====== ============ ======== ====== ====== ===================================================
- AddSignal (32, "SIGTHR", false, false, false, "thread interrupt");
- AddSignal (33, "SIGLIBRT", false, false, false, "reserved by real-time library");
- AddSignal (65, "SIGRTMIN", false, false, false, "real time signal 0");
- AddSignal (66, "SIGRTMIN+1", false, false, false, "real time signal 1");
- AddSignal (67, "SIGRTMIN+2", false, false, false, "real time signal 2");
- AddSignal (68, "SIGRTMIN+3", false, false, false, "real time signal 3");
- AddSignal (69, "SIGRTMIN+4", false, false, false, "real time signal 4");
- AddSignal (70, "SIGRTMIN+5", false, false, false, "real time signal 5");
- AddSignal (71, "SIGRTMIN+6", false, false, false, "real time signal 6");
- AddSignal (72, "SIGRTMIN+7", false, false, false, "real time signal 7");
- AddSignal (73, "SIGRTMIN+8", false, false, false, "real time signal 8");
- AddSignal (74, "SIGRTMIN+9", false, false, false, "real time signal 9");
- AddSignal (75, "SIGRTMIN+10", false, false, false, "real time signal 10");
- AddSignal (76, "SIGRTMIN+11", false, false, false, "real time signal 11");
- AddSignal (77, "SIGRTMIN+12", false, false, false, "real time signal 12");
- AddSignal (78, "SIGRTMIN+13", false, false, false, "real time signal 13");
- AddSignal (79, "SIGRTMIN+14", false, false, false, "real time signal 14");
- AddSignal (80, "SIGRTMIN+15", false, false, false, "real time signal 15");
- AddSignal (81, "SIGRTMIN+16", false, false, false, "real time signal 16");
- AddSignal (82, "SIGRTMIN+17", false, false, false, "real time signal 17");
- AddSignal (83, "SIGRTMIN+18", false, false, false, "real time signal 18");
- AddSignal (84, "SIGRTMIN+19", false, false, false, "real time signal 19");
- AddSignal (85, "SIGRTMIN+20", false, false, false, "real time signal 20");
- AddSignal (86, "SIGRTMIN+21", false, false, false, "real time signal 21");
- AddSignal (87, "SIGRTMIN+22", false, false, false, "real time signal 22");
- AddSignal (88, "SIGRTMIN+23", false, false, false, "real time signal 23");
- AddSignal (89, "SIGRTMIN+24", false, false, false, "real time signal 24");
- AddSignal (90, "SIGRTMIN+25", false, false, false, "real time signal 25");
- AddSignal (91, "SIGRTMIN+26", false, false, false, "real time signal 26");
- AddSignal (92, "SIGRTMIN+27", false, false, false, "real time signal 27");
- AddSignal (93, "SIGRTMIN+28", false, false, false, "real time signal 28");
- AddSignal (94, "SIGRTMIN+29", false, false, false, "real time signal 29");
- AddSignal (95, "SIGRTMIN+30", false, false, false, "real time signal 30");
- AddSignal (96, "SIGRTMAX-30", false, false, false, "real time signal 31");
- AddSignal (97, "SIGRTMAX-29", false, false, false, "real time signal 32");
- AddSignal (98, "SIGRTMAX-28", false, false, false, "real time signal 33");
- AddSignal (99, "SIGRTMAX-27", false, false, false, "real time signal 34");
- AddSignal (100, "SIGRTMAX-26", false, false, false, "real time signal 35");
- AddSignal (101, "SIGRTMAX-25", false, false, false, "real time signal 36");
- AddSignal (102, "SIGRTMAX-24", false, false, false, "real time signal 37");
- AddSignal (103, "SIGRTMAX-23", false, false, false, "real time signal 38");
- AddSignal (104, "SIGRTMAX-22", false, false, false, "real time signal 39");
- AddSignal (105, "SIGRTMAX-21", false, false, false, "real time signal 40");
- AddSignal (106, "SIGRTMAX-20", false, false, false, "real time signal 41");
- AddSignal (107, "SIGRTMAX-19", false, false, false, "real time signal 42");
- AddSignal (108, "SIGRTMAX-18", false, false, false, "real time signal 43");
- AddSignal (109, "SIGRTMAX-17", false, false, false, "real time signal 44");
- AddSignal (110, "SIGRTMAX-16", false, false, false, "real time signal 45");
- AddSignal (111, "SIGRTMAX-15", false, false, false, "real time signal 46");
- AddSignal (112, "SIGRTMAX-14", false, false, false, "real time signal 47");
- AddSignal (113, "SIGRTMAX-13", false, false, false, "real time signal 48");
- AddSignal (114, "SIGRTMAX-12", false, false, false, "real time signal 49");
- AddSignal (115, "SIGRTMAX-11", false, false, false, "real time signal 50");
- AddSignal (116, "SIGRTMAX-10", false, false, false, "real time signal 51");
- AddSignal (117, "SIGRTMAX-9", false, false, false, "real time signal 52");
- AddSignal (118, "SIGRTMAX-8", false, false, false, "real time signal 53");
- AddSignal (119, "SIGRTMAX-7", false, false, false, "real time signal 54");
- AddSignal (120, "SIGRTMAX-6", false, false, false, "real time signal 55");
- AddSignal (121, "SIGRTMAX-5", false, false, false, "real time signal 56");
- AddSignal (122, "SIGRTMAX-4", false, false, false, "real time signal 57");
- AddSignal (123, "SIGRTMAX-3", false, false, false, "real time signal 58");
- AddSignal (124, "SIGRTMAX-2", false, false, false, "real time signal 59");
- AddSignal (125, "SIGRTMAX-1", false, false, false, "real time signal 60");
- AddSignal (126, "SIGRTMAX", false, false, false, "real time signal 61");
+ // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION
+ // ====== ============ ======== ====== ======
+ // ===================================================
+ AddSignal(32, "SIGTHR", false, false, false, "thread interrupt");
+ AddSignal(33, "SIGLIBRT", false, false, false,
+ "reserved by real-time library");
+ AddSignal(65, "SIGRTMIN", false, false, false, "real time signal 0");
+ AddSignal(66, "SIGRTMIN+1", false, false, false, "real time signal 1");
+ AddSignal(67, "SIGRTMIN+2", false, false, false, "real time signal 2");
+ AddSignal(68, "SIGRTMIN+3", false, false, false, "real time signal 3");
+ AddSignal(69, "SIGRTMIN+4", false, false, false, "real time signal 4");
+ AddSignal(70, "SIGRTMIN+5", false, false, false, "real time signal 5");
+ AddSignal(71, "SIGRTMIN+6", false, false, false, "real time signal 6");
+ AddSignal(72, "SIGRTMIN+7", false, false, false, "real time signal 7");
+ AddSignal(73, "SIGRTMIN+8", false, false, false, "real time signal 8");
+ AddSignal(74, "SIGRTMIN+9", false, false, false, "real time signal 9");
+ AddSignal(75, "SIGRTMIN+10", false, false, false, "real time signal 10");
+ AddSignal(76, "SIGRTMIN+11", false, false, false, "real time signal 11");
+ AddSignal(77, "SIGRTMIN+12", false, false, false, "real time signal 12");
+ AddSignal(78, "SIGRTMIN+13", false, false, false, "real time signal 13");
+ AddSignal(79, "SIGRTMIN+14", false, false, false, "real time signal 14");
+ AddSignal(80, "SIGRTMIN+15", false, false, false, "real time signal 15");
+ AddSignal(81, "SIGRTMIN+16", false, false, false, "real time signal 16");
+ AddSignal(82, "SIGRTMIN+17", false, false, false, "real time signal 17");
+ AddSignal(83, "SIGRTMIN+18", false, false, false, "real time signal 18");
+ AddSignal(84, "SIGRTMIN+19", false, false, false, "real time signal 19");
+ AddSignal(85, "SIGRTMIN+20", false, false, false, "real time signal 20");
+ AddSignal(86, "SIGRTMIN+21", false, false, false, "real time signal 21");
+ AddSignal(87, "SIGRTMIN+22", false, false, false, "real time signal 22");
+ AddSignal(88, "SIGRTMIN+23", false, false, false, "real time signal 23");
+ AddSignal(89, "SIGRTMIN+24", false, false, false, "real time signal 24");
+ AddSignal(90, "SIGRTMIN+25", false, false, false, "real time signal 25");
+ AddSignal(91, "SIGRTMIN+26", false, false, false, "real time signal 26");
+ AddSignal(92, "SIGRTMIN+27", false, false, false, "real time signal 27");
+ AddSignal(93, "SIGRTMIN+28", false, false, false, "real time signal 28");
+ AddSignal(94, "SIGRTMIN+29", false, false, false, "real time signal 29");
+ AddSignal(95, "SIGRTMIN+30", false, false, false, "real time signal 30");
+ AddSignal(96, "SIGRTMAX-30", false, false, false, "real time signal 31");
+ AddSignal(97, "SIGRTMAX-29", false, false, false, "real time signal 32");
+ AddSignal(98, "SIGRTMAX-28", false, false, false, "real time signal 33");
+ AddSignal(99, "SIGRTMAX-27", false, false, false, "real time signal 34");
+ AddSignal(100, "SIGRTMAX-26", false, false, false, "real time signal 35");
+ AddSignal(101, "SIGRTMAX-25", false, false, false, "real time signal 36");
+ AddSignal(102, "SIGRTMAX-24", false, false, false, "real time signal 37");
+ AddSignal(103, "SIGRTMAX-23", false, false, false, "real time signal 38");
+ AddSignal(104, "SIGRTMAX-22", false, false, false, "real time signal 39");
+ AddSignal(105, "SIGRTMAX-21", false, false, false, "real time signal 40");
+ AddSignal(106, "SIGRTMAX-20", false, false, false, "real time signal 41");
+ AddSignal(107, "SIGRTMAX-19", false, false, false, "real time signal 42");
+ AddSignal(108, "SIGRTMAX-18", false, false, false, "real time signal 43");
+ AddSignal(109, "SIGRTMAX-17", false, false, false, "real time signal 44");
+ AddSignal(110, "SIGRTMAX-16", false, false, false, "real time signal 45");
+ AddSignal(111, "SIGRTMAX-15", false, false, false, "real time signal 46");
+ AddSignal(112, "SIGRTMAX-14", false, false, false, "real time signal 47");
+ AddSignal(113, "SIGRTMAX-13", false, false, false, "real time signal 48");
+ AddSignal(114, "SIGRTMAX-12", false, false, false, "real time signal 49");
+ AddSignal(115, "SIGRTMAX-11", false, false, false, "real time signal 50");
+ AddSignal(116, "SIGRTMAX-10", false, false, false, "real time signal 51");
+ AddSignal(117, "SIGRTMAX-9", false, false, false, "real time signal 52");
+ AddSignal(118, "SIGRTMAX-8", false, false, false, "real time signal 53");
+ AddSignal(119, "SIGRTMAX-7", false, false, false, "real time signal 54");
+ AddSignal(120, "SIGRTMAX-6", false, false, false, "real time signal 55");
+ AddSignal(121, "SIGRTMAX-5", false, false, false, "real time signal 56");
+ AddSignal(122, "SIGRTMAX-4", false, false, false, "real time signal 57");
+ AddSignal(123, "SIGRTMAX-3", false, false, false, "real time signal 58");
+ AddSignal(124, "SIGRTMAX-2", false, false, false, "real time signal 59");
+ AddSignal(125, "SIGRTMAX-1", false, false, false, "real time signal 60");
+ AddSignal(126, "SIGRTMAX", false, false, false, "real time signal 61");
}
diff --git a/source/Plugins/Process/Utility/FreeBSDSignals.h b/source/Plugins/Process/Utility/FreeBSDSignals.h
index b715c62c81e9..8ec96e824f7a 100644
--- a/source/Plugins/Process/Utility/FreeBSDSignals.h
+++ b/source/Plugins/Process/Utility/FreeBSDSignals.h
@@ -16,14 +16,12 @@
namespace lldb_private {
/// FreeBSD specific set of Unix signals.
-class FreeBSDSignals : public UnixSignals
-{
+class FreeBSDSignals : public UnixSignals {
public:
- FreeBSDSignals();
+ FreeBSDSignals();
private:
- void
- Reset() override;
+ void Reset() override;
};
} // namespace lldb_private
diff --git a/source/Plugins/Process/Utility/GDBRemoteSignals.cpp b/source/Plugins/Process/Utility/GDBRemoteSignals.cpp
index 4e355c63b3aa..abcc8a38669a 100644
--- a/source/Plugins/Process/Utility/GDBRemoteSignals.cpp
+++ b/source/Plugins/Process/Utility/GDBRemoteSignals.cpp
@@ -14,19 +14,9 @@
using namespace lldb_private;
-GDBRemoteSignals::GDBRemoteSignals()
- : UnixSignals()
-{
- Reset();
-}
+GDBRemoteSignals::GDBRemoteSignals() : UnixSignals() { Reset(); }
GDBRemoteSignals::GDBRemoteSignals(const lldb::UnixSignalsSP &rhs)
- : UnixSignals(*rhs)
-{
-}
+ : UnixSignals(*rhs) {}
-void
-GDBRemoteSignals::Reset()
-{
- m_signals.clear();
-}
+void GDBRemoteSignals::Reset() { m_signals.clear(); }
diff --git a/source/Plugins/Process/Utility/GDBRemoteSignals.h b/source/Plugins/Process/Utility/GDBRemoteSignals.h
index bbb631a14090..5900fa75d6f2 100644
--- a/source/Plugins/Process/Utility/GDBRemoteSignals.h
+++ b/source/Plugins/Process/Utility/GDBRemoteSignals.h
@@ -19,16 +19,14 @@
namespace lldb_private {
/// Empty set of Unix signals to be filled by PlatformRemoteGDBServer
-class GDBRemoteSignals : public UnixSignals
-{
+class GDBRemoteSignals : public UnixSignals {
public:
- GDBRemoteSignals();
+ GDBRemoteSignals();
- GDBRemoteSignals(const lldb::UnixSignalsSP &rhs);
+ GDBRemoteSignals(const lldb::UnixSignalsSP &rhs);
private:
- void
- Reset() override;
+ void Reset() override;
};
} // namespace lldb_private
diff --git a/source/Plugins/Process/Utility/HistoryThread.cpp b/source/Plugins/Process/Utility/HistoryThread.cpp
index 956539da219c..d27a7b0da943 100644
--- a/source/Plugins/Process/Utility/HistoryThread.cpp
+++ b/source/Plugins/Process/Utility/HistoryThread.cpp
@@ -9,91 +9,75 @@
#include "lldb/lldb-private.h"
-#include "Plugins/Process/Utility/HistoryUnwind.h"
#include "Plugins/Process/Utility/HistoryThread.h"
+#include "Plugins/Process/Utility/HistoryUnwind.h"
#include "Plugins/Process/Utility/RegisterContextHistory.h"
#include "lldb/Core/Log.h"
-#include "lldb/Target/StackFrameList.h"
#include "lldb/Target/Process.h"
+#include "lldb/Target/StackFrameList.h"
using namespace lldb;
using namespace lldb_private;
// Constructor
-HistoryThread::HistoryThread(lldb_private::Process &process, lldb::tid_t tid, std::vector<lldb::addr_t> pcs,
- uint32_t stop_id, bool stop_id_is_valid)
- : Thread(process, tid, true),
- m_framelist_mutex(),
- m_framelist(),
- m_pcs(pcs),
- m_stop_id(stop_id),
- m_stop_id_is_valid(stop_id_is_valid),
- m_extended_unwind_token(LLDB_INVALID_ADDRESS),
- m_queue_name(),
- m_thread_name(),
- m_originating_unique_thread_id(tid),
- m_queue_id(LLDB_INVALID_QUEUE_ID)
-{
- m_unwinder_ap.reset(new HistoryUnwind(*this, pcs, stop_id_is_valid));
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
- if (log)
- log->Printf("%p HistoryThread::HistoryThread", static_cast<void *>(this));
+HistoryThread::HistoryThread(lldb_private::Process &process, lldb::tid_t tid,
+ std::vector<lldb::addr_t> pcs, uint32_t stop_id,
+ bool stop_id_is_valid)
+ : Thread(process, tid, true), m_framelist_mutex(), m_framelist(),
+ m_pcs(pcs), m_stop_id(stop_id), m_stop_id_is_valid(stop_id_is_valid),
+ m_extended_unwind_token(LLDB_INVALID_ADDRESS), m_queue_name(),
+ m_thread_name(), m_originating_unique_thread_id(tid),
+ m_queue_id(LLDB_INVALID_QUEUE_ID) {
+ m_unwinder_ap.reset(new HistoryUnwind(*this, pcs, stop_id_is_valid));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
+ if (log)
+ log->Printf("%p HistoryThread::HistoryThread", static_cast<void *>(this));
}
// Destructor
-HistoryThread::~HistoryThread ()
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
- if (log)
- log->Printf ("%p HistoryThread::~HistoryThread (tid=0x%" PRIx64 ")",
- static_cast<void*>(this), GetID());
- DestroyThread();
+HistoryThread::~HistoryThread() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
+ if (log)
+ log->Printf("%p HistoryThread::~HistoryThread (tid=0x%" PRIx64 ")",
+ static_cast<void *>(this), GetID());
+ DestroyThread();
}
-lldb::RegisterContextSP
-HistoryThread::GetRegisterContext ()
-{
- RegisterContextSP rctx ;
- if (m_pcs.size() > 0)
- {
- rctx.reset (new RegisterContextHistory (*this, 0, GetProcess()->GetAddressByteSize(), m_pcs[0]));
- }
- return rctx;
-
+lldb::RegisterContextSP HistoryThread::GetRegisterContext() {
+ RegisterContextSP rctx;
+ if (m_pcs.size() > 0) {
+ rctx.reset(new RegisterContextHistory(
+ *this, 0, GetProcess()->GetAddressByteSize(), m_pcs[0]));
+ }
+ return rctx;
}
lldb::RegisterContextSP
-HistoryThread::CreateRegisterContextForFrame (StackFrame *frame)
-{
- return m_unwinder_ap->CreateRegisterContextForFrame (frame);
+HistoryThread::CreateRegisterContextForFrame(StackFrame *frame) {
+ return m_unwinder_ap->CreateRegisterContextForFrame(frame);
}
-lldb::StackFrameListSP
-HistoryThread::GetStackFrameList ()
-{
- // FIXME do not throw away the lock after we acquire it..
- std::unique_lock<std::mutex> lock(m_framelist_mutex);
- lock.unlock();
- if (m_framelist.get() == NULL)
- {
- m_framelist.reset (new StackFrameList (*this, StackFrameListSP(), true));
- }
+lldb::StackFrameListSP HistoryThread::GetStackFrameList() {
+ // FIXME do not throw away the lock after we acquire it..
+ std::unique_lock<std::mutex> lock(m_framelist_mutex);
+ lock.unlock();
+ if (m_framelist.get() == NULL) {
+ m_framelist.reset(new StackFrameList(*this, StackFrameListSP(), true));
+ }
- return m_framelist;
+ return m_framelist;
}
-uint32_t
-HistoryThread::GetExtendedBacktraceOriginatingIndexID ()
-{
- if (m_originating_unique_thread_id != LLDB_INVALID_THREAD_ID)
- {
- if (GetProcess()->HasAssignedIndexIDToThread (m_originating_unique_thread_id))
- {
- return GetProcess()->AssignIndexIDToThread (m_originating_unique_thread_id);
- }
+uint32_t HistoryThread::GetExtendedBacktraceOriginatingIndexID() {
+ if (m_originating_unique_thread_id != LLDB_INVALID_THREAD_ID) {
+ if (GetProcess()->HasAssignedIndexIDToThread(
+ m_originating_unique_thread_id)) {
+ return GetProcess()->AssignIndexIDToThread(
+ m_originating_unique_thread_id);
}
- return LLDB_INVALID_THREAD_ID;
+ }
+ return LLDB_INVALID_THREAD_ID;
}
diff --git a/source/Plugins/Process/Utility/HistoryThread.h b/source/Plugins/Process/Utility/HistoryThread.h
index 43ac13c2d8bc..1a4898a95b7d 100644
--- a/source/Plugins/Process/Utility/HistoryThread.h
+++ b/source/Plugins/Process/Utility/HistoryThread.h
@@ -16,7 +16,6 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Core/Broadcaster.h"
#include "lldb/Core/Event.h"
#include "lldb/Core/UserID.h"
@@ -24,119 +23,78 @@
#include "lldb/Target/ExecutionContextScope.h"
#include "lldb/Target/StackFrameList.h"
#include "lldb/Target/Thread.h"
+#include "lldb/lldb-private.h"
namespace lldb_private {
//----------------------------------------------------------------------
/// @class HistoryThread HistoryThread.h "HistoryThread.h"
-/// @brief A thread object representing a backtrace from a previous point in the process execution
+/// @brief A thread object representing a backtrace from a previous point in the
+/// process execution
///
/// This subclass of Thread is used to provide a backtrace from earlier in
-/// process execution. It is given a backtrace list of pc addresses and
+/// process execution. It is given a backtrace list of pc addresses and
/// optionally a stop_id of when those pc addresses were collected, and it will
/// create stack frames for them.
//----------------------------------------------------------------------
-class HistoryThread : public lldb_private::Thread
-{
+class HistoryThread : public lldb_private::Thread {
public:
- HistoryThread (lldb_private::Process &process, lldb::tid_t tid, std::vector<lldb::addr_t> pcs, uint32_t stop_id, bool stop_id_is_valid);
-
- ~HistoryThread() override;
-
- lldb::RegisterContextSP
- GetRegisterContext() override;
-
- lldb::RegisterContextSP
- CreateRegisterContextForFrame(StackFrame *frame) override;
-
- void
- RefreshStateAfterStop() override { }
-
- bool
- CalculateStopInfo() override
- {
- return false;
- }
-
- void
- SetExtendedBacktraceToken(uint64_t token) override
- {
- m_extended_unwind_token = token;
- }
-
- uint64_t
- GetExtendedBacktraceToken() override
- {
- return m_extended_unwind_token;
- }
-
- const char *
- GetQueueName() override
- {
- return m_queue_name.c_str();
- }
-
- void
- SetQueueName(const char *name) override
- {
- m_queue_name = name;
- }
-
- lldb::queue_id_t
- GetQueueID() override
- {
- return m_queue_id;
- }
-
- void
- SetQueueID(lldb::queue_id_t queue) override
- {
- m_queue_id = queue;
- }
-
- const char *
- GetThreadName ()
- {
- return m_thread_name.c_str();
- }
-
- uint32_t
- GetExtendedBacktraceOriginatingIndexID() override;
-
- void
- SetThreadName (const char *name)
- {
- m_thread_name = name;
- }
-
- const char *
- GetName() override
- {
- return m_thread_name.c_str();
- }
-
- void
- SetName(const char *name) override
- {
- m_thread_name = name;
- }
+ HistoryThread(lldb_private::Process &process, lldb::tid_t tid,
+ std::vector<lldb::addr_t> pcs, uint32_t stop_id,
+ bool stop_id_is_valid);
+
+ ~HistoryThread() override;
+
+ lldb::RegisterContextSP GetRegisterContext() override;
+
+ lldb::RegisterContextSP
+ CreateRegisterContextForFrame(StackFrame *frame) override;
+
+ void RefreshStateAfterStop() override {}
+
+ bool CalculateStopInfo() override { return false; }
+
+ void SetExtendedBacktraceToken(uint64_t token) override {
+ m_extended_unwind_token = token;
+ }
+
+ uint64_t GetExtendedBacktraceToken() override {
+ return m_extended_unwind_token;
+ }
+
+ const char *GetQueueName() override { return m_queue_name.c_str(); }
+
+ void SetQueueName(const char *name) override { m_queue_name = name; }
+
+ lldb::queue_id_t GetQueueID() override { return m_queue_id; }
+
+ void SetQueueID(lldb::queue_id_t queue) override { m_queue_id = queue; }
+
+ const char *GetThreadName() { return m_thread_name.c_str(); }
+
+ uint32_t GetExtendedBacktraceOriginatingIndexID() override;
+
+ void SetThreadName(const char *name) { m_thread_name = name; }
+
+ const char *GetName() override { return m_thread_name.c_str(); }
+
+ void SetName(const char *name) override { m_thread_name = name; }
protected:
- virtual lldb::StackFrameListSP
- GetStackFrameList ();
-
- mutable std::mutex m_framelist_mutex;
- lldb::StackFrameListSP m_framelist;
- std::vector<lldb::addr_t> m_pcs;
- uint32_t m_stop_id;
- bool m_stop_id_is_valid;
-
- uint64_t m_extended_unwind_token;
- std::string m_queue_name;
- std::string m_thread_name;
- lldb::tid_t m_originating_unique_thread_id;
- lldb::queue_id_t m_queue_id;
+ virtual lldb::StackFrameListSP GetStackFrameList();
+
+ mutable std::mutex m_framelist_mutex;
+ lldb::StackFrameListSP m_framelist;
+ std::vector<lldb::addr_t> m_pcs;
+ uint32_t m_stop_id;
+ bool m_stop_id_is_valid;
+
+ uint64_t m_extended_unwind_token;
+ std::string m_queue_name;
+ std::string m_thread_name;
+ lldb::tid_t m_originating_unique_thread_id;
+ lldb::queue_id_t m_queue_id;
};
} // namespace lldb_private
diff --git a/source/Plugins/Process/Utility/HistoryUnwind.cpp b/source/Plugins/Process/Utility/HistoryUnwind.cpp
index 01d8c3ebdcd3..4f0ecba613bf 100644
--- a/source/Plugins/Process/Utility/HistoryUnwind.cpp
+++ b/source/Plugins/Process/Utility/HistoryUnwind.cpp
@@ -9,75 +9,59 @@
#include "lldb/lldb-private.h"
-#include "Plugins/Process/Utility/RegisterContextHistory.h"
#include "Plugins/Process/Utility/HistoryUnwind.h"
+#include "Plugins/Process/Utility/RegisterContextHistory.h"
-#include "lldb/Target/StackFrame.h"
-#include "lldb/Target/Thread.h"
#include "lldb/Target/Process.h"
+#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
using namespace lldb;
using namespace lldb_private;
-// Constructor
+// Constructor
-HistoryUnwind::HistoryUnwind (Thread &thread,
- std::vector<lldb::addr_t> pcs,
- bool stop_id_is_valid) :
- Unwind (thread),
- m_pcs (pcs),
- m_stop_id_is_valid (stop_id_is_valid)
-{
-}
+HistoryUnwind::HistoryUnwind(Thread &thread, std::vector<lldb::addr_t> pcs,
+ bool stop_id_is_valid)
+ : Unwind(thread), m_pcs(pcs), m_stop_id_is_valid(stop_id_is_valid) {}
// Destructor
-HistoryUnwind::~HistoryUnwind ()
-{
-}
+HistoryUnwind::~HistoryUnwind() {}
-void
-HistoryUnwind::DoClear ()
-{
- std::lock_guard<std::recursive_mutex> guard(m_unwind_mutex);
- m_pcs.clear();
- m_stop_id_is_valid = false;
+void HistoryUnwind::DoClear() {
+ std::lock_guard<std::recursive_mutex> guard(m_unwind_mutex);
+ m_pcs.clear();
+ m_stop_id_is_valid = false;
}
lldb::RegisterContextSP
-HistoryUnwind::DoCreateRegisterContextForFrame (StackFrame *frame)
-{
- RegisterContextSP rctx;
- if (frame)
- {
- addr_t pc = frame->GetFrameCodeAddress().GetLoadAddress (&frame->GetThread()->GetProcess()->GetTarget());
- if (pc != LLDB_INVALID_ADDRESS)
- {
- rctx.reset (new RegisterContextHistory (*frame->GetThread().get(), frame->GetConcreteFrameIndex(),
- frame->GetThread()->GetProcess()->GetAddressByteSize(), pc));
- }
+HistoryUnwind::DoCreateRegisterContextForFrame(StackFrame *frame) {
+ RegisterContextSP rctx;
+ if (frame) {
+ addr_t pc = frame->GetFrameCodeAddress().GetLoadAddress(
+ &frame->GetThread()->GetProcess()->GetTarget());
+ if (pc != LLDB_INVALID_ADDRESS) {
+ rctx.reset(new RegisterContextHistory(
+ *frame->GetThread().get(), frame->GetConcreteFrameIndex(),
+ frame->GetThread()->GetProcess()->GetAddressByteSize(), pc));
}
- return rctx;
+ }
+ return rctx;
}
-bool
-HistoryUnwind::DoGetFrameInfoAtIndex (uint32_t frame_idx, lldb::addr_t& cfa, lldb::addr_t& pc)
-{
- // FIXME do not throw away the lock after we acquire it..
- std::unique_lock<std::recursive_mutex> guard(m_unwind_mutex);
- guard.unlock();
- if (frame_idx < m_pcs.size())
- {
- cfa = frame_idx;
- pc = m_pcs[frame_idx];
- return true;
- }
- return false;
+bool HistoryUnwind::DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
+ lldb::addr_t &pc) {
+ // FIXME do not throw away the lock after we acquire it..
+ std::unique_lock<std::recursive_mutex> guard(m_unwind_mutex);
+ guard.unlock();
+ if (frame_idx < m_pcs.size()) {
+ cfa = frame_idx;
+ pc = m_pcs[frame_idx];
+ return true;
+ }
+ return false;
}
-uint32_t
-HistoryUnwind::DoGetFrameCount ()
-{
- return m_pcs.size();
-}
+uint32_t HistoryUnwind::DoGetFrameCount() { return m_pcs.size(); }
diff --git a/source/Plugins/Process/Utility/HistoryUnwind.h b/source/Plugins/Process/Utility/HistoryUnwind.h
index 890604fcb680..3b64e38bfaa7 100644
--- a/source/Plugins/Process/Utility/HistoryUnwind.h
+++ b/source/Plugins/Process/Utility/HistoryUnwind.h
@@ -16,36 +16,31 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Target/Unwind.h"
+#include "lldb/lldb-private.h"
namespace lldb_private {
-class HistoryUnwind : public lldb_private::Unwind
-{
+class HistoryUnwind : public lldb_private::Unwind {
public:
- HistoryUnwind (Thread &thread, std::vector<lldb::addr_t> pcs, bool stop_id_is_valid);
+ HistoryUnwind(Thread &thread, std::vector<lldb::addr_t> pcs,
+ bool stop_id_is_valid);
- ~HistoryUnwind() override;
+ ~HistoryUnwind() override;
protected:
- void
- DoClear() override;
+ void DoClear() override;
- lldb::RegisterContextSP
- DoCreateRegisterContextForFrame(StackFrame *frame) override;
+ lldb::RegisterContextSP
+ DoCreateRegisterContextForFrame(StackFrame *frame) override;
- bool
- DoGetFrameInfoAtIndex(uint32_t frame_idx,
- lldb::addr_t& cfa,
- lldb::addr_t& pc) override;
- uint32_t
- DoGetFrameCount() override;
+ bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
+ lldb::addr_t &pc) override;
+ uint32_t DoGetFrameCount() override;
private:
-
- std::vector<lldb::addr_t> m_pcs;
- bool m_stop_id_is_valid;
+ std::vector<lldb::addr_t> m_pcs;
+ bool m_stop_id_is_valid;
};
} // namespace lldb_private
diff --git a/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp b/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
index b694b833cb48..4e1f10c6ae18 100644
--- a/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
+++ b/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
@@ -34,225 +34,207 @@
using namespace lldb;
using namespace lldb_private;
-bool
-lldb_private::InferiorCallMmap (Process *process,
- addr_t &allocated_addr,
- addr_t addr,
- addr_t length,
- unsigned prot,
- unsigned flags,
- addr_t fd,
- addr_t offset)
-{
- Thread *thread = process->GetThreadList().GetExpressionExecutionThread().get();
- if (thread == NULL)
- return false;
-
- const bool append = true;
- const bool include_symbols = true;
- const bool include_inlines = false;
- SymbolContextList sc_list;
- const uint32_t count
- = process->GetTarget().GetImages().FindFunctions (ConstString ("mmap"),
- eFunctionNameTypeFull,
- include_symbols,
- include_inlines,
- append,
- sc_list);
- if (count > 0)
- {
- SymbolContext sc;
- if (sc_list.GetContextAtIndex(0, sc))
- {
- const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol;
- const bool use_inline_block_range = false;
- EvaluateExpressionOptions options;
- options.SetStopOthers(true);
- options.SetUnwindOnError(true);
- options.SetIgnoreBreakpoints(true);
- options.SetTryAllThreads(true);
- options.SetDebug (false);
- options.SetTimeoutUsec(500000);
- options.SetTrapExceptions(false);
-
- addr_t prot_arg, flags_arg = 0;
- if (prot == eMmapProtNone)
- prot_arg = PROT_NONE;
- else {
- prot_arg = 0;
- if (prot & eMmapProtExec)
- prot_arg |= PROT_EXEC;
- if (prot & eMmapProtRead)
- prot_arg |= PROT_READ;
- if (prot & eMmapProtWrite)
- prot_arg |= PROT_WRITE;
- }
-
- const ArchSpec arch = process->GetTarget().GetArchitecture();
- flags_arg = process->GetTarget().GetPlatform()->ConvertMmapFlagsToPlatform(arch,flags);
-
- AddressRange mmap_range;
- if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, mmap_range))
- {
- ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
- CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- lldb::addr_t args[] = { addr, length, prot_arg, flags_arg, fd, offset };
- lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallFunction(*thread, mmap_range.GetBaseAddress(),
- clang_void_ptr_type, args, options));
- if (call_plan_sp)
- {
- DiagnosticManager diagnostics;
-
- StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
- if (frame)
- {
- ExecutionContext exe_ctx;
- frame->CalculateExecutionContext (exe_ctx);
- ExpressionResults result = process->RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostics);
- if (result == eExpressionCompleted)
- {
+bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr,
+ addr_t addr, addr_t length, unsigned prot,
+ unsigned flags, addr_t fd, addr_t offset) {
+ Thread *thread =
+ process->GetThreadList().GetExpressionExecutionThread().get();
+ if (thread == NULL)
+ return false;
- allocated_addr = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
- if (process->GetAddressByteSize() == 4)
- {
- if (allocated_addr == UINT32_MAX)
- return false;
- }
- else if (process->GetAddressByteSize() == 8)
- {
- if (allocated_addr == UINT64_MAX)
- return false;
- }
- return true;
- }
- }
- }
+ const bool append = true;
+ const bool include_symbols = true;
+ const bool include_inlines = false;
+ SymbolContextList sc_list;
+ const uint32_t count = process->GetTarget().GetImages().FindFunctions(
+ ConstString("mmap"), eFunctionNameTypeFull, include_symbols,
+ include_inlines, append, sc_list);
+ if (count > 0) {
+ SymbolContext sc;
+ if (sc_list.GetContextAtIndex(0, sc)) {
+ const uint32_t range_scope =
+ eSymbolContextFunction | eSymbolContextSymbol;
+ const bool use_inline_block_range = false;
+ EvaluateExpressionOptions options;
+ options.SetStopOthers(true);
+ options.SetUnwindOnError(true);
+ options.SetIgnoreBreakpoints(true);
+ options.SetTryAllThreads(true);
+ options.SetDebug(false);
+ options.SetTimeout(std::chrono::milliseconds(500));
+ options.SetTrapExceptions(false);
+
+ addr_t prot_arg, flags_arg = 0;
+ if (prot == eMmapProtNone)
+ prot_arg = PROT_NONE;
+ else {
+ prot_arg = 0;
+ if (prot & eMmapProtExec)
+ prot_arg |= PROT_EXEC;
+ if (prot & eMmapProtRead)
+ prot_arg |= PROT_READ;
+ if (prot & eMmapProtWrite)
+ prot_arg |= PROT_WRITE;
+ }
+
+ const ArchSpec arch = process->GetTarget().GetArchitecture();
+ flags_arg =
+ process->GetTarget().GetPlatform()->ConvertMmapFlagsToPlatform(arch,
+ flags);
+
+ AddressRange mmap_range;
+ if (sc.GetAddressRange(range_scope, 0, use_inline_block_range,
+ mmap_range)) {
+ ClangASTContext *clang_ast_context =
+ process->GetTarget().GetScratchClangASTContext();
+ CompilerType clang_void_ptr_type =
+ clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ lldb::addr_t args[] = {addr, length, prot_arg, flags_arg, fd, offset};
+ lldb::ThreadPlanSP call_plan_sp(
+ new ThreadPlanCallFunction(*thread, mmap_range.GetBaseAddress(),
+ clang_void_ptr_type, args, options));
+ if (call_plan_sp) {
+ DiagnosticManager diagnostics;
+
+ StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
+ if (frame) {
+ ExecutionContext exe_ctx;
+ frame->CalculateExecutionContext(exe_ctx);
+ ExpressionResults result = process->RunThreadPlan(
+ exe_ctx, call_plan_sp, options, diagnostics);
+ if (result == eExpressionCompleted) {
+
+ allocated_addr =
+ call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(
+ LLDB_INVALID_ADDRESS);
+ if (process->GetAddressByteSize() == 4) {
+ if (allocated_addr == UINT32_MAX)
+ return false;
+ } else if (process->GetAddressByteSize() == 8) {
+ if (allocated_addr == UINT64_MAX)
+ return false;
+ }
+ return true;
}
+ }
}
+ }
}
+ }
- return false;
+ return false;
}
-bool
-lldb_private::InferiorCallMunmap (Process *process,
- addr_t addr,
- addr_t length)
-{
- Thread *thread = process->GetThreadList().GetExpressionExecutionThread().get();
- if (thread == NULL)
- return false;
-
- const bool append = true;
- const bool include_symbols = true;
- const bool include_inlines = false;
- SymbolContextList sc_list;
- const uint32_t count
- = process->GetTarget().GetImages().FindFunctions (ConstString ("munmap"),
- eFunctionNameTypeFull,
- include_symbols,
- include_inlines,
- append,
- sc_list);
- if (count > 0)
- {
- SymbolContext sc;
- if (sc_list.GetContextAtIndex(0, sc))
- {
- const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol;
- const bool use_inline_block_range = false;
- EvaluateExpressionOptions options;
- options.SetStopOthers(true);
- options.SetUnwindOnError(true);
- options.SetIgnoreBreakpoints(true);
- options.SetTryAllThreads(true);
- options.SetDebug (false);
- options.SetTimeoutUsec(500000);
- options.SetTrapExceptions(false);
-
- AddressRange munmap_range;
- if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, munmap_range))
- {
- lldb::addr_t args[] = { addr, length };
- lldb::ThreadPlanSP call_plan_sp(
- new ThreadPlanCallFunction(*thread, munmap_range.GetBaseAddress(), CompilerType(), args, options));
- if (call_plan_sp)
- {
- DiagnosticManager diagnostics;
+bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr,
+ addr_t length) {
+ Thread *thread =
+ process->GetThreadList().GetExpressionExecutionThread().get();
+ if (thread == NULL)
+ return false;
- StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
- if (frame)
- {
- ExecutionContext exe_ctx;
- frame->CalculateExecutionContext (exe_ctx);
- ExpressionResults result = process->RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostics);
- if (result == eExpressionCompleted)
- {
- return true;
- }
- }
- }
+ const bool append = true;
+ const bool include_symbols = true;
+ const bool include_inlines = false;
+ SymbolContextList sc_list;
+ const uint32_t count = process->GetTarget().GetImages().FindFunctions(
+ ConstString("munmap"), eFunctionNameTypeFull, include_symbols,
+ include_inlines, append, sc_list);
+ if (count > 0) {
+ SymbolContext sc;
+ if (sc_list.GetContextAtIndex(0, sc)) {
+ const uint32_t range_scope =
+ eSymbolContextFunction | eSymbolContextSymbol;
+ const bool use_inline_block_range = false;
+ EvaluateExpressionOptions options;
+ options.SetStopOthers(true);
+ options.SetUnwindOnError(true);
+ options.SetIgnoreBreakpoints(true);
+ options.SetTryAllThreads(true);
+ options.SetDebug(false);
+ options.SetTimeout(std::chrono::milliseconds(500));
+ options.SetTrapExceptions(false);
+
+ AddressRange munmap_range;
+ if (sc.GetAddressRange(range_scope, 0, use_inline_block_range,
+ munmap_range)) {
+ lldb::addr_t args[] = {addr, length};
+ lldb::ThreadPlanSP call_plan_sp(
+ new ThreadPlanCallFunction(*thread, munmap_range.GetBaseAddress(),
+ CompilerType(), args, options));
+ if (call_plan_sp) {
+ DiagnosticManager diagnostics;
+
+ StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
+ if (frame) {
+ ExecutionContext exe_ctx;
+ frame->CalculateExecutionContext(exe_ctx);
+ ExpressionResults result = process->RunThreadPlan(
+ exe_ctx, call_plan_sp, options, diagnostics);
+ if (result == eExpressionCompleted) {
+ return true;
}
+ }
}
+ }
}
+ }
- return false;
+ return false;
}
-// FIXME: This has nothing to do with Posix, it is just a convenience function that calls a
-// function of the form "void * (*)(void)". We should find a better place to put this.
-
-bool
-lldb_private::InferiorCall (Process *process,
- const Address *address,
- addr_t &returned_func,
- bool trap_exceptions)
-{
- Thread *thread = process->GetThreadList().GetExpressionExecutionThread().get();
- if (thread == NULL || address == NULL)
- return false;
-
- EvaluateExpressionOptions options;
- options.SetStopOthers(true);
- options.SetUnwindOnError(true);
- options.SetIgnoreBreakpoints(true);
- options.SetTryAllThreads(true);
- options.SetDebug (false);
- options.SetTimeoutUsec(500000);
- options.SetTrapExceptions(trap_exceptions);
-
- ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
- CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- lldb::ThreadPlanSP call_plan_sp(
- new ThreadPlanCallFunction(*thread, *address, clang_void_ptr_type, llvm::ArrayRef<addr_t>(), options));
- if (call_plan_sp)
- {
- DiagnosticManager diagnostics;
+// FIXME: This has nothing to do with Posix, it is just a convenience function
+// that calls a
+// function of the form "void * (*)(void)". We should find a better place to
+// put this.
- StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
- if (frame)
- {
- ExecutionContext exe_ctx;
- frame->CalculateExecutionContext (exe_ctx);
- ExpressionResults result = process->RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostics);
- if (result == eExpressionCompleted)
- {
- returned_func = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+bool lldb_private::InferiorCall(Process *process, const Address *address,
+ addr_t &returned_func, bool trap_exceptions) {
+ Thread *thread =
+ process->GetThreadList().GetExpressionExecutionThread().get();
+ if (thread == NULL || address == NULL)
+ return false;
- if (process->GetAddressByteSize() == 4)
- {
- if (returned_func == UINT32_MAX)
- return false;
- }
- else if (process->GetAddressByteSize() == 8)
- {
- if (returned_func == UINT64_MAX)
- return false;
- }
- return true;
- }
+ EvaluateExpressionOptions options;
+ options.SetStopOthers(true);
+ options.SetUnwindOnError(true);
+ options.SetIgnoreBreakpoints(true);
+ options.SetTryAllThreads(true);
+ options.SetDebug(false);
+ options.SetTimeout(std::chrono::milliseconds(500));
+ options.SetTrapExceptions(trap_exceptions);
+
+ ClangASTContext *clang_ast_context =
+ process->GetTarget().GetScratchClangASTContext();
+ CompilerType clang_void_ptr_type =
+ clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ lldb::ThreadPlanSP call_plan_sp(
+ new ThreadPlanCallFunction(*thread, *address, clang_void_ptr_type,
+ llvm::ArrayRef<addr_t>(), options));
+ if (call_plan_sp) {
+ DiagnosticManager diagnostics;
+
+ StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
+ if (frame) {
+ ExecutionContext exe_ctx;
+ frame->CalculateExecutionContext(exe_ctx);
+ ExpressionResults result =
+ process->RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostics);
+ if (result == eExpressionCompleted) {
+ returned_func =
+ call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(
+ LLDB_INVALID_ADDRESS);
+
+ if (process->GetAddressByteSize() == 4) {
+ if (returned_func == UINT32_MAX)
+ return false;
+ } else if (process->GetAddressByteSize() == 8) {
+ if (returned_func == UINT64_MAX)
+ return false;
}
+ return true;
+ }
}
+ }
- return false;
+ return false;
}
diff --git a/source/Plugins/Process/Utility/InferiorCallPOSIX.h b/source/Plugins/Process/Utility/InferiorCallPOSIX.h
index d10e8490d809..07bde5bf09b3 100644
--- a/source/Plugins/Process/Utility/InferiorCallPOSIX.h
+++ b/source/Plugins/Process/Utility/InferiorCallPOSIX.h
@@ -31,9 +31,9 @@ bool InferiorCallMmap(Process *proc, lldb::addr_t &allocated_addr,
bool InferiorCallMunmap(Process *proc, lldb::addr_t addr, lldb::addr_t length);
-bool InferiorCall(Process *proc, const Address *address, lldb::addr_t &returned_func,
- bool trap_exceptions = false);
+bool InferiorCall(Process *proc, const Address *address,
+ lldb::addr_t &returned_func, bool trap_exceptions = false);
-} // namespace lldb_private
+} // namespace lldb_private
-#endif // lldb_InferiorCallPOSIX_h_
+#endif // lldb_InferiorCallPOSIX_h_
diff --git a/source/Plugins/Process/Utility/InstructionUtils.h b/source/Plugins/Process/Utility/InstructionUtils.h
index 6226fbc04b08..e422a96200c8 100644
--- a/source/Plugins/Process/Utility/InstructionUtils.h
+++ b/source/Plugins/Process/Utility/InstructionUtils.h
@@ -16,123 +16,99 @@ namespace lldb_private {
// Return the bit field(s) from the most significant bit (msbit) to the
// least significant bit (lsbit) of a 64-bit unsigned value.
-static inline uint64_t
-Bits64 (const uint64_t bits, const uint32_t msbit, const uint32_t lsbit)
-{
- assert(msbit < 64 && lsbit <= msbit);
- return (bits >> lsbit) & ((1ull << (msbit - lsbit + 1)) - 1);
+static inline uint64_t Bits64(const uint64_t bits, const uint32_t msbit,
+ const uint32_t lsbit) {
+ assert(msbit < 64 && lsbit <= msbit);
+ return (bits >> lsbit) & ((1ull << (msbit - lsbit + 1)) - 1);
}
// Return the bit field(s) from the most significant bit (msbit) to the
// least significant bit (lsbit) of a 32-bit unsigned value.
-static inline uint32_t
-Bits32 (const uint32_t bits, const uint32_t msbit, const uint32_t lsbit)
-{
- assert(msbit < 32 && lsbit <= msbit);
- return (bits >> lsbit) & ((1u << (msbit - lsbit + 1)) - 1);
+static inline uint32_t Bits32(const uint32_t bits, const uint32_t msbit,
+ const uint32_t lsbit) {
+ assert(msbit < 32 && lsbit <= msbit);
+ return (bits >> lsbit) & ((1u << (msbit - lsbit + 1)) - 1);
}
// Return the bit value from the 'bit' position of a 32-bit unsigned value.
-static inline uint32_t
-Bit32 (const uint32_t bits, const uint32_t bit)
-{
- return (bits >> bit) & 1u;
+static inline uint32_t Bit32(const uint32_t bits, const uint32_t bit) {
+ return (bits >> bit) & 1u;
}
-static inline uint64_t
-Bit64 (const uint64_t bits, const uint32_t bit)
-{
- return (bits >> bit) & 1ull;
+static inline uint64_t Bit64(const uint64_t bits, const uint32_t bit) {
+ return (bits >> bit) & 1ull;
}
// Set the bit field(s) from the most significant bit (msbit) to the
// least significant bit (lsbit) of a 32-bit unsigned value to 'val'.
-static inline void
-SetBits32(uint32_t &bits, const uint32_t msbit, const uint32_t lsbit, const uint32_t val)
-{
- assert(msbit < 32 && lsbit < 32 && msbit >= lsbit);
- uint32_t mask = ((1u << (msbit - lsbit + 1)) - 1);
- bits &= ~(mask << lsbit);
- bits |= (val & mask) << lsbit;
+static inline void SetBits32(uint32_t &bits, const uint32_t msbit,
+ const uint32_t lsbit, const uint32_t val) {
+ assert(msbit < 32 && lsbit < 32 && msbit >= lsbit);
+ uint32_t mask = ((1u << (msbit - lsbit + 1)) - 1);
+ bits &= ~(mask << lsbit);
+ bits |= (val & mask) << lsbit;
}
// Set the 'bit' position of a 32-bit unsigned value to 'val'.
-static inline void
-SetBit32(uint32_t &bits, const uint32_t bit, const uint32_t val)
-{
- SetBits32(bits, bit, bit, val);
+static inline void SetBit32(uint32_t &bits, const uint32_t bit,
+ const uint32_t val) {
+ SetBits32(bits, bit, bit, val);
}
// Rotate a 32-bit unsigned value right by the specified amount.
-static inline uint32_t
-Rotr32 (uint32_t bits, uint32_t amt)
-{
- assert(amt < 32 && "Invalid rotate amount");
- return (bits >> amt) | (bits << ((32-amt)&31));
+static inline uint32_t Rotr32(uint32_t bits, uint32_t amt) {
+ assert(amt < 32 && "Invalid rotate amount");
+ return (bits >> amt) | (bits << ((32 - amt) & 31));
}
// Rotate a 32-bit unsigned value left by the specified amount.
-static inline uint32_t
-Rotl32 (uint32_t bits, uint32_t amt)
-{
- assert(amt < 32 && "Invalid rotate amount");
- return (bits << amt) | (bits >> ((32-amt)&31));
+static inline uint32_t Rotl32(uint32_t bits, uint32_t amt) {
+ assert(amt < 32 && "Invalid rotate amount");
+ return (bits << amt) | (bits >> ((32 - amt) & 31));
}
// Create a mask that starts at bit zero and includes "bit"
-static inline uint64_t
-MaskUpToBit (const uint64_t bit)
-{
- if (bit >= 63)
- return -1ll;
- return (1ull << (bit + 1ull)) - 1ull;
+static inline uint64_t MaskUpToBit(const uint64_t bit) {
+ if (bit >= 63)
+ return -1ll;
+ return (1ull << (bit + 1ull)) - 1ull;
}
// Return an integer result equal to the number of bits of x that are ones.
-static inline uint32_t
-BitCount (uint64_t x)
-{
- // c accumulates the total bits set in x
- uint32_t c;
- for (c = 0; x; ++c)
- {
- x &= x - 1; // clear the least significant bit set
- }
- return c;
+static inline uint32_t BitCount(uint64_t x) {
+ // c accumulates the total bits set in x
+ uint32_t c;
+ for (c = 0; x; ++c) {
+ x &= x - 1; // clear the least significant bit set
+ }
+ return c;
}
-static inline bool
-BitIsSet (const uint64_t value, const uint64_t bit)
-{
- return (value & (1ull << bit)) != 0;
+static inline bool BitIsSet(const uint64_t value, const uint64_t bit) {
+ return (value & (1ull << bit)) != 0;
}
-static inline bool
-BitIsClear (const uint64_t value, const uint64_t bit)
-{
- return (value & (1ull << bit)) == 0;
+static inline bool BitIsClear(const uint64_t value, const uint64_t bit) {
+ return (value & (1ull << bit)) == 0;
}
-static inline uint64_t
-UnsignedBits (const uint64_t value, const uint64_t msbit, const uint64_t lsbit)
-{
- uint64_t result = value >> lsbit;
- result &= MaskUpToBit (msbit - lsbit);
- return result;
+static inline uint64_t UnsignedBits(const uint64_t value, const uint64_t msbit,
+ const uint64_t lsbit) {
+ uint64_t result = value >> lsbit;
+ result &= MaskUpToBit(msbit - lsbit);
+ return result;
}
-static inline int64_t
-SignedBits (const uint64_t value, const uint64_t msbit, const uint64_t lsbit)
-{
- uint64_t result = UnsignedBits (value, msbit, lsbit);
- if (BitIsSet(value, msbit))
- {
- // Sign extend
- result |= ~MaskUpToBit (msbit - lsbit);
- }
- return result;
+static inline int64_t SignedBits(const uint64_t value, const uint64_t msbit,
+ const uint64_t lsbit) {
+ uint64_t result = UnsignedBits(value, msbit, lsbit);
+ if (BitIsSet(value, msbit)) {
+ // Sign extend
+ result |= ~MaskUpToBit(msbit - lsbit);
+ }
+ return result;
}
-} // namespace lldb_private
+} // namespace lldb_private
-#endif // lldb_InstructionUtils_h_
+#endif // lldb_InstructionUtils_h_
diff --git a/source/Plugins/Process/Utility/LinuxSignals.cpp b/source/Plugins/Process/Utility/LinuxSignals.cpp
index 5687577f9d16..eb01075ed133 100644
--- a/source/Plugins/Process/Utility/LinuxSignals.cpp
+++ b/source/Plugins/Process/Utility/LinuxSignals.cpp
@@ -14,80 +14,83 @@
using namespace lldb_private;
-LinuxSignals::LinuxSignals()
- : UnixSignals()
-{
- Reset();
-}
+LinuxSignals::LinuxSignals() : UnixSignals() { Reset(); }
-void
-LinuxSignals::Reset()
-{
- m_signals.clear();
- // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION ALIAS
- // ===== =========== ======== ===== ====== ====================================== ======
- AddSignal (1, "SIGHUP", false, true , true , "hangup" );
- AddSignal (2, "SIGINT", true , true , true , "interrupt" );
- AddSignal (3, "SIGQUIT", false, true , true , "quit" );
- AddSignal (4, "SIGILL", false, true , true , "illegal instruction" );
- AddSignal (5, "SIGTRAP", true , true , true , "trace trap (not reset when caught)" );
- AddSignal (6, "SIGABRT", false, true , true , "abort()/IOT trap", "SIGIOT");
- AddSignal (7, "SIGBUS", false, true , true , "bus error" );
- AddSignal (8, "SIGFPE", false, true , true , "floating point exception" );
- AddSignal (9, "SIGKILL", false, true , true , "kill" );
- AddSignal (10, "SIGUSR1", false, true , true , "user defined signal 1" );
- AddSignal (11, "SIGSEGV", false, true , true , "segmentation violation" );
- AddSignal (12, "SIGUSR2", false, true , true , "user defined signal 2" );
- AddSignal (13, "SIGPIPE", false, true , true , "write to pipe with reading end closed" );
- AddSignal (14, "SIGALRM", false, false, false, "alarm" );
- AddSignal (15, "SIGTERM", false, true , true , "termination requested" );
- AddSignal (16, "SIGSTKFLT", false, true , true , "stack fault" );
- AddSignal (17, "SIGCHLD", false, false, true , "child status has changed", "SIGCLD");
- AddSignal (18, "SIGCONT", false, true , true , "process continue" );
- AddSignal (19, "SIGSTOP", true , true , true , "process stop" );
- AddSignal (20, "SIGTSTP", false, true , true , "tty stop" );
- AddSignal (21, "SIGTTIN", false, true , true , "background tty read" );
- AddSignal (22, "SIGTTOU", false, true , true , "background tty write" );
- AddSignal (23, "SIGURG", false, true , true , "urgent data on socket" );
- AddSignal (24, "SIGXCPU", false, true , true , "CPU resource exceeded" );
- AddSignal (25, "SIGXFSZ", false, true , true , "file size limit exceeded" );
- AddSignal (26, "SIGVTALRM", false, true , true , "virtual time alarm" );
- AddSignal (27, "SIGPROF", false, false, false, "profiling time alarm" );
- AddSignal (28, "SIGWINCH", false, true , true , "window size changes" );
- AddSignal (29, "SIGIO", false, true , true , "input/output ready/Pollable event", "SIGPOLL");
- AddSignal (30, "SIGPWR", false, true , true , "power failure" );
- AddSignal (31, "SIGSYS", false, true , true , "invalid system call" );
- AddSignal (32, "SIG32", false, false, false, "threading library internal signal 1" );
- AddSignal (33, "SIG33", false, false, false, "threading library internal signal 2" );
- AddSignal (34, "SIGRTMIN", false, false, false, "real time signal 0" );
- AddSignal (35, "SIGRTMIN+1", false, false, false, "real time signal 1" );
- AddSignal (36, "SIGRTMIN+2", false, false, false, "real time signal 2" );
- AddSignal (37, "SIGRTMIN+3", false, false, false, "real time signal 3" );
- AddSignal (38, "SIGRTMIN+4", false, false, false, "real time signal 4" );
- AddSignal (39, "SIGRTMIN+5", false, false, false, "real time signal 5" );
- AddSignal (40, "SIGRTMIN+6", false, false, false, "real time signal 6" );
- AddSignal (41, "SIGRTMIN+7", false, false, false, "real time signal 7" );
- AddSignal (42, "SIGRTMIN+8", false, false, false, "real time signal 8" );
- AddSignal (43, "SIGRTMIN+9", false, false, false, "real time signal 9" );
- AddSignal (44, "SIGRTMIN+10", false, false, false, "real time signal 10" );
- AddSignal (45, "SIGRTMIN+11", false, false, false, "real time signal 11" );
- AddSignal (46, "SIGRTMIN+12", false, false, false, "real time signal 12" );
- AddSignal (47, "SIGRTMIN+13", false, false, false, "real time signal 13" );
- AddSignal (48, "SIGRTMIN+14", false, false, false, "real time signal 14" );
- AddSignal (49, "SIGRTMIN+15", false, false, false, "real time signal 15" );
- AddSignal (50, "SIGRTMAX-14", false, false, false, "real time signal 16" ); // switching to SIGRTMAX-xxx to match "kill -l" output
- AddSignal (51, "SIGRTMAX-13", false, false, false, "real time signal 17" );
- AddSignal (52, "SIGRTMAX-12", false, false, false, "real time signal 18" );
- AddSignal (53, "SIGRTMAX-11", false, false, false, "real time signal 19" );
- AddSignal (54, "SIGRTMAX-10", false, false, false, "real time signal 20" );
- AddSignal (55, "SIGRTMAX-9", false, false, false, "real time signal 21" );
- AddSignal (56, "SIGRTMAX-8", false, false, false, "real time signal 22" );
- AddSignal (57, "SIGRTMAX-7", false, false, false, "real time signal 23" );
- AddSignal (58, "SIGRTMAX-6", false, false, false, "real time signal 24" );
- AddSignal (59, "SIGRTMAX-5", false, false, false, "real time signal 25" );
- AddSignal (60, "SIGRTMAX-4", false, false, false, "real time signal 26" );
- AddSignal (61, "SIGRTMAX-3", false, false, false, "real time signal 27" );
- AddSignal (62, "SIGRTMAX-2", false, false, false, "real time signal 28" );
- AddSignal (63, "SIGRTMAX-1", false, false, false, "real time signal 29" );
- AddSignal (64, "SIGRTMAX", false, false, false, "real time signal 30" );
+void LinuxSignals::Reset() {
+ m_signals.clear();
+ // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION ALIAS
+ // ===== =========== ======== ===== ======
+ // ====================================== ======
+ AddSignal(1, "SIGHUP", false, true, true, "hangup");
+ AddSignal(2, "SIGINT", true, true, true, "interrupt");
+ AddSignal(3, "SIGQUIT", false, true, true, "quit");
+ AddSignal(4, "SIGILL", false, true, true, "illegal instruction");
+ AddSignal(5, "SIGTRAP", true, true, true,
+ "trace trap (not reset when caught)");
+ AddSignal(6, "SIGABRT", false, true, true, "abort()/IOT trap", "SIGIOT");
+ AddSignal(7, "SIGBUS", false, true, true, "bus error");
+ AddSignal(8, "SIGFPE", false, true, true, "floating point exception");
+ AddSignal(9, "SIGKILL", false, true, true, "kill");
+ AddSignal(10, "SIGUSR1", false, true, true, "user defined signal 1");
+ AddSignal(11, "SIGSEGV", false, true, true, "segmentation violation");
+ AddSignal(12, "SIGUSR2", false, true, true, "user defined signal 2");
+ AddSignal(13, "SIGPIPE", false, true, true,
+ "write to pipe with reading end closed");
+ AddSignal(14, "SIGALRM", false, false, false, "alarm");
+ AddSignal(15, "SIGTERM", false, true, true, "termination requested");
+ AddSignal(16, "SIGSTKFLT", false, true, true, "stack fault");
+ AddSignal(17, "SIGCHLD", false, false, true, "child status has changed",
+ "SIGCLD");
+ AddSignal(18, "SIGCONT", false, true, true, "process continue");
+ AddSignal(19, "SIGSTOP", true, true, true, "process stop");
+ AddSignal(20, "SIGTSTP", false, true, true, "tty stop");
+ AddSignal(21, "SIGTTIN", false, true, true, "background tty read");
+ AddSignal(22, "SIGTTOU", false, true, true, "background tty write");
+ AddSignal(23, "SIGURG", false, true, true, "urgent data on socket");
+ AddSignal(24, "SIGXCPU", false, true, true, "CPU resource exceeded");
+ AddSignal(25, "SIGXFSZ", false, true, true, "file size limit exceeded");
+ AddSignal(26, "SIGVTALRM", false, true, true, "virtual time alarm");
+ AddSignal(27, "SIGPROF", false, false, false, "profiling time alarm");
+ AddSignal(28, "SIGWINCH", false, true, true, "window size changes");
+ AddSignal(29, "SIGIO", false, true, true, "input/output ready/Pollable event",
+ "SIGPOLL");
+ AddSignal(30, "SIGPWR", false, true, true, "power failure");
+ AddSignal(31, "SIGSYS", false, true, true, "invalid system call");
+ AddSignal(32, "SIG32", false, false, false,
+ "threading library internal signal 1");
+ AddSignal(33, "SIG33", false, false, false,
+ "threading library internal signal 2");
+ AddSignal(34, "SIGRTMIN", false, false, false, "real time signal 0");
+ AddSignal(35, "SIGRTMIN+1", false, false, false, "real time signal 1");
+ AddSignal(36, "SIGRTMIN+2", false, false, false, "real time signal 2");
+ AddSignal(37, "SIGRTMIN+3", false, false, false, "real time signal 3");
+ AddSignal(38, "SIGRTMIN+4", false, false, false, "real time signal 4");
+ AddSignal(39, "SIGRTMIN+5", false, false, false, "real time signal 5");
+ AddSignal(40, "SIGRTMIN+6", false, false, false, "real time signal 6");
+ AddSignal(41, "SIGRTMIN+7", false, false, false, "real time signal 7");
+ AddSignal(42, "SIGRTMIN+8", false, false, false, "real time signal 8");
+ AddSignal(43, "SIGRTMIN+9", false, false, false, "real time signal 9");
+ AddSignal(44, "SIGRTMIN+10", false, false, false, "real time signal 10");
+ AddSignal(45, "SIGRTMIN+11", false, false, false, "real time signal 11");
+ AddSignal(46, "SIGRTMIN+12", false, false, false, "real time signal 12");
+ AddSignal(47, "SIGRTMIN+13", false, false, false, "real time signal 13");
+ AddSignal(48, "SIGRTMIN+14", false, false, false, "real time signal 14");
+ AddSignal(49, "SIGRTMIN+15", false, false, false, "real time signal 15");
+ AddSignal(50, "SIGRTMAX-14", false, false, false,
+ "real time signal 16"); // switching to SIGRTMAX-xxx to match "kill
+ // -l" output
+ AddSignal(51, "SIGRTMAX-13", false, false, false, "real time signal 17");
+ AddSignal(52, "SIGRTMAX-12", false, false, false, "real time signal 18");
+ AddSignal(53, "SIGRTMAX-11", false, false, false, "real time signal 19");
+ AddSignal(54, "SIGRTMAX-10", false, false, false, "real time signal 20");
+ AddSignal(55, "SIGRTMAX-9", false, false, false, "real time signal 21");
+ AddSignal(56, "SIGRTMAX-8", false, false, false, "real time signal 22");
+ AddSignal(57, "SIGRTMAX-7", false, false, false, "real time signal 23");
+ AddSignal(58, "SIGRTMAX-6", false, false, false, "real time signal 24");
+ AddSignal(59, "SIGRTMAX-5", false, false, false, "real time signal 25");
+ AddSignal(60, "SIGRTMAX-4", false, false, false, "real time signal 26");
+ AddSignal(61, "SIGRTMAX-3", false, false, false, "real time signal 27");
+ AddSignal(62, "SIGRTMAX-2", false, false, false, "real time signal 28");
+ AddSignal(63, "SIGRTMAX-1", false, false, false, "real time signal 29");
+ AddSignal(64, "SIGRTMAX", false, false, false, "real time signal 30");
}
diff --git a/source/Plugins/Process/Utility/LinuxSignals.h b/source/Plugins/Process/Utility/LinuxSignals.h
index dd9062f040a2..e41126225cee 100644
--- a/source/Plugins/Process/Utility/LinuxSignals.h
+++ b/source/Plugins/Process/Utility/LinuxSignals.h
@@ -19,14 +19,12 @@
namespace lldb_private {
/// Linux specific set of Unix signals.
-class LinuxSignals : public UnixSignals
-{
+class LinuxSignals : public UnixSignals {
public:
- LinuxSignals();
+ LinuxSignals();
private:
- void
- Reset() override;
+ void Reset() override;
};
} // namespace lldb_private
diff --git a/source/Plugins/Process/Utility/MipsLinuxSignals.cpp b/source/Plugins/Process/Utility/MipsLinuxSignals.cpp
index 422fc9b642d0..36231023aa3a 100644
--- a/source/Plugins/Process/Utility/MipsLinuxSignals.cpp
+++ b/source/Plugins/Process/Utility/MipsLinuxSignals.cpp
@@ -1,4 +1,5 @@
-//===-- MipsLinuxSignals.cpp ----------------------------------------*- C++ -*-===//
+//===-- MipsLinuxSignals.cpp ----------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,80 +15,83 @@
using namespace lldb_private;
-MipsLinuxSignals::MipsLinuxSignals()
- : UnixSignals()
-{
- Reset();
-}
+MipsLinuxSignals::MipsLinuxSignals() : UnixSignals() { Reset(); }
-void
-MipsLinuxSignals::Reset()
-{
- m_signals.clear();
- // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION ALIAS
- // ===== =========== ======== ===== ====== ====================================== ========
- AddSignal (1, "SIGHUP", false, true , true , "hangup" );
- AddSignal (2, "SIGINT", true , true , true , "interrupt" );
- AddSignal (3, "SIGQUIT", false, true , true , "quit" );
- AddSignal (4, "SIGILL", false, true , true , "illegal instruction" );
- AddSignal (5, "SIGTRAP", true , true , true , "trace trap (not reset when caught)" );
- AddSignal (6, "SIGABRT", false, true , true , "abort()/IOT trap", "SIGIOT");
- AddSignal (7, "SIGEMT", false, true , true , "terminate process with core dump" );
- AddSignal (8, "SIGFPE", false, true , true , "floating point exception" );
- AddSignal (9, "SIGKILL", false, true , true , "kill" );
- AddSignal (10, "SIGBUS", false, true , true , "bus error" );
- AddSignal (11, "SIGSEGV", false, true , true , "segmentation violation" );
- AddSignal (12, "SIGSYS", false, true , true , "invalid system call" );
- AddSignal (13, "SIGPIPE", false, true , true , "write to pipe with reading end closed" );
- AddSignal (14, "SIGALRM", false, false, false, "alarm" );
- AddSignal (15, "SIGTERM", false, true , true , "termination requested" );
- AddSignal (16, "SIGUSR1", false, true , true , "user defined signal 1" );
- AddSignal (17, "SIGUSR2", false, true , true , "user defined signal 2" );
- AddSignal (18, "SIGCHLD", false, false, true , "child status has changed", "SIGCLD");
- AddSignal (19, "SIGPWR", false, true , true , "power failure" );
- AddSignal (20, "SIGWINCH", false, true , true , "window size changes" );
- AddSignal (21, "SIGURG", false, true , true , "urgent data on socket" );
- AddSignal (22, "SIGIO", false, true , true , "input/output ready/Pollable event", "SIGPOLL");
- AddSignal (23, "SIGSTOP", true , true , true , "process stop" );
- AddSignal (24, "SIGTSTP", false, true , true , "tty stop" );
- AddSignal (25, "SIGCONT", false, true , true , "process continue" );
- AddSignal (26, "SIGTTIN", false, true , true , "background tty read" );
- AddSignal (27, "SIGTTOU", false, true , true , "background tty write" );
- AddSignal (28, "SIGVTALRM", false, true , true , "virtual time alarm" );
- AddSignal (29, "SIGPROF", false, false, false, "profiling time alarm" );
- AddSignal (30, "SIGXCPU", false, true , true , "CPU resource exceeded" );
- AddSignal (31, "SIGXFSZ", false, true , true , "file size limit exceeded" );
- AddSignal (32, "SIG32", false, false, false, "threading library internal signal 1" );
- AddSignal (33, "SIG33", false, false, false, "threading library internal signal 2" );
- AddSignal (34, "SIGRTMIN", false, false, false, "real time signal 0" );
- AddSignal (35, "SIGRTMIN+1", false, false, false, "real time signal 1" );
- AddSignal (36, "SIGRTMIN+2", false, false, false, "real time signal 2" );
- AddSignal (37, "SIGRTMIN+3", false, false, false, "real time signal 3" );
- AddSignal (38, "SIGRTMIN+4", false, false, false, "real time signal 4" );
- AddSignal (39, "SIGRTMIN+5", false, false, false, "real time signal 5" );
- AddSignal (40, "SIGRTMIN+6", false, false, false, "real time signal 6" );
- AddSignal (41, "SIGRTMIN+7", false, false, false, "real time signal 7" );
- AddSignal (42, "SIGRTMIN+8", false, false, false, "real time signal 8" );
- AddSignal (43, "SIGRTMIN+9", false, false, false, "real time signal 9" );
- AddSignal (44, "SIGRTMIN+10", false, false, false, "real time signal 10" );
- AddSignal (45, "SIGRTMIN+11", false, false, false, "real time signal 11" );
- AddSignal (46, "SIGRTMIN+12", false, false, false, "real time signal 12" );
- AddSignal (47, "SIGRTMIN+13", false, false, false, "real time signal 13" );
- AddSignal (48, "SIGRTMIN+14", false, false, false, "real time signal 14" );
- AddSignal (49, "SIGRTMIN+15", false, false, false, "real time signal 15" );
- AddSignal (50, "SIGRTMAX-14", false, false, false, "real time signal 16" ); // switching to SIGRTMAX-xxx to match "kill -l" output
- AddSignal (51, "SIGRTMAX-13", false, false, false, "real time signal 17" );
- AddSignal (52, "SIGRTMAX-12", false, false, false, "real time signal 18" );
- AddSignal (53, "SIGRTMAX-11", false, false, false, "real time signal 19" );
- AddSignal (54, "SIGRTMAX-10", false, false, false, "real time signal 20" );
- AddSignal (55, "SIGRTMAX-9", false, false, false, "real time signal 21" );
- AddSignal (56, "SIGRTMAX-8", false, false, false, "real time signal 22" );
- AddSignal (57, "SIGRTMAX-7", false, false, false, "real time signal 23" );
- AddSignal (58, "SIGRTMAX-6", false, false, false, "real time signal 24" );
- AddSignal (59, "SIGRTMAX-5", false, false, false, "real time signal 25" );
- AddSignal (60, "SIGRTMAX-4", false, false, false, "real time signal 26" );
- AddSignal (61, "SIGRTMAX-3", false, false, false, "real time signal 27" );
- AddSignal (62, "SIGRTMAX-2", false, false, false, "real time signal 28" );
- AddSignal (63, "SIGRTMAX-1", false, false, false, "real time signal 29" );
- AddSignal (64, "SIGRTMAX", false, false, false, "real time signal 30" );
+void MipsLinuxSignals::Reset() {
+ m_signals.clear();
+ // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION ALIAS
+ // ===== =========== ======== ===== ======
+ // ====================================== ========
+ AddSignal(1, "SIGHUP", false, true, true, "hangup");
+ AddSignal(2, "SIGINT", true, true, true, "interrupt");
+ AddSignal(3, "SIGQUIT", false, true, true, "quit");
+ AddSignal(4, "SIGILL", false, true, true, "illegal instruction");
+ AddSignal(5, "SIGTRAP", true, true, true,
+ "trace trap (not reset when caught)");
+ AddSignal(6, "SIGABRT", false, true, true, "abort()/IOT trap", "SIGIOT");
+ AddSignal(7, "SIGEMT", false, true, true, "terminate process with core dump");
+ AddSignal(8, "SIGFPE", false, true, true, "floating point exception");
+ AddSignal(9, "SIGKILL", false, true, true, "kill");
+ AddSignal(10, "SIGBUS", false, true, true, "bus error");
+ AddSignal(11, "SIGSEGV", false, true, true, "segmentation violation");
+ AddSignal(12, "SIGSYS", false, true, true, "invalid system call");
+ AddSignal(13, "SIGPIPE", false, true, true,
+ "write to pipe with reading end closed");
+ AddSignal(14, "SIGALRM", false, false, false, "alarm");
+ AddSignal(15, "SIGTERM", false, true, true, "termination requested");
+ AddSignal(16, "SIGUSR1", false, true, true, "user defined signal 1");
+ AddSignal(17, "SIGUSR2", false, true, true, "user defined signal 2");
+ AddSignal(18, "SIGCHLD", false, false, true, "child status has changed",
+ "SIGCLD");
+ AddSignal(19, "SIGPWR", false, true, true, "power failure");
+ AddSignal(20, "SIGWINCH", false, true, true, "window size changes");
+ AddSignal(21, "SIGURG", false, true, true, "urgent data on socket");
+ AddSignal(22, "SIGIO", false, true, true, "input/output ready/Pollable event",
+ "SIGPOLL");
+ AddSignal(23, "SIGSTOP", true, true, true, "process stop");
+ AddSignal(24, "SIGTSTP", false, true, true, "tty stop");
+ AddSignal(25, "SIGCONT", false, true, true, "process continue");
+ AddSignal(26, "SIGTTIN", false, true, true, "background tty read");
+ AddSignal(27, "SIGTTOU", false, true, true, "background tty write");
+ AddSignal(28, "SIGVTALRM", false, true, true, "virtual time alarm");
+ AddSignal(29, "SIGPROF", false, false, false, "profiling time alarm");
+ AddSignal(30, "SIGXCPU", false, true, true, "CPU resource exceeded");
+ AddSignal(31, "SIGXFSZ", false, true, true, "file size limit exceeded");
+ AddSignal(32, "SIG32", false, false, false,
+ "threading library internal signal 1");
+ AddSignal(33, "SIG33", false, false, false,
+ "threading library internal signal 2");
+ AddSignal(34, "SIGRTMIN", false, false, false, "real time signal 0");
+ AddSignal(35, "SIGRTMIN+1", false, false, false, "real time signal 1");
+ AddSignal(36, "SIGRTMIN+2", false, false, false, "real time signal 2");
+ AddSignal(37, "SIGRTMIN+3", false, false, false, "real time signal 3");
+ AddSignal(38, "SIGRTMIN+4", false, false, false, "real time signal 4");
+ AddSignal(39, "SIGRTMIN+5", false, false, false, "real time signal 5");
+ AddSignal(40, "SIGRTMIN+6", false, false, false, "real time signal 6");
+ AddSignal(41, "SIGRTMIN+7", false, false, false, "real time signal 7");
+ AddSignal(42, "SIGRTMIN+8", false, false, false, "real time signal 8");
+ AddSignal(43, "SIGRTMIN+9", false, false, false, "real time signal 9");
+ AddSignal(44, "SIGRTMIN+10", false, false, false, "real time signal 10");
+ AddSignal(45, "SIGRTMIN+11", false, false, false, "real time signal 11");
+ AddSignal(46, "SIGRTMIN+12", false, false, false, "real time signal 12");
+ AddSignal(47, "SIGRTMIN+13", false, false, false, "real time signal 13");
+ AddSignal(48, "SIGRTMIN+14", false, false, false, "real time signal 14");
+ AddSignal(49, "SIGRTMIN+15", false, false, false, "real time signal 15");
+ AddSignal(50, "SIGRTMAX-14", false, false, false,
+ "real time signal 16"); // switching to SIGRTMAX-xxx to match "kill
+ // -l" output
+ AddSignal(51, "SIGRTMAX-13", false, false, false, "real time signal 17");
+ AddSignal(52, "SIGRTMAX-12", false, false, false, "real time signal 18");
+ AddSignal(53, "SIGRTMAX-11", false, false, false, "real time signal 19");
+ AddSignal(54, "SIGRTMAX-10", false, false, false, "real time signal 20");
+ AddSignal(55, "SIGRTMAX-9", false, false, false, "real time signal 21");
+ AddSignal(56, "SIGRTMAX-8", false, false, false, "real time signal 22");
+ AddSignal(57, "SIGRTMAX-7", false, false, false, "real time signal 23");
+ AddSignal(58, "SIGRTMAX-6", false, false, false, "real time signal 24");
+ AddSignal(59, "SIGRTMAX-5", false, false, false, "real time signal 25");
+ AddSignal(60, "SIGRTMAX-4", false, false, false, "real time signal 26");
+ AddSignal(61, "SIGRTMAX-3", false, false, false, "real time signal 27");
+ AddSignal(62, "SIGRTMAX-2", false, false, false, "real time signal 28");
+ AddSignal(63, "SIGRTMAX-1", false, false, false, "real time signal 29");
+ AddSignal(64, "SIGRTMAX", false, false, false, "real time signal 30");
}
diff --git a/source/Plugins/Process/Utility/MipsLinuxSignals.h b/source/Plugins/Process/Utility/MipsLinuxSignals.h
index a5041b50eea3..e48ea5943f2b 100644
--- a/source/Plugins/Process/Utility/MipsLinuxSignals.h
+++ b/source/Plugins/Process/Utility/MipsLinuxSignals.h
@@ -1,4 +1,5 @@
-//===-- MipsLinuxSignals.h ------------------------------------------*- C++ -*-===//
+//===-- MipsLinuxSignals.h ------------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,14 +20,12 @@
namespace lldb_private {
/// Linux specific set of Unix signals.
-class MipsLinuxSignals : public UnixSignals
-{
+class MipsLinuxSignals : public UnixSignals {
public:
- MipsLinuxSignals();
+ MipsLinuxSignals();
private:
- void
- Reset() override;
+ void Reset() override;
};
} // namespace lldb_private
diff --git a/source/Plugins/Process/Utility/NetBSDSignals.cpp b/source/Plugins/Process/Utility/NetBSDSignals.cpp
index 5dce51616c4e..9b9db51e5167 100644
--- a/source/Plugins/Process/Utility/NetBSDSignals.cpp
+++ b/source/Plugins/Process/Utility/NetBSDSignals.cpp
@@ -15,20 +15,16 @@
using namespace lldb_private;
-NetBSDSignals::NetBSDSignals()
- : UnixSignals()
-{
- Reset();
-}
+NetBSDSignals::NetBSDSignals() : UnixSignals() { Reset(); }
-void
-NetBSDSignals::Reset()
-{
- UnixSignals::Reset();
- // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION
- // ====== ============ ======== ====== ====== ===================================================
- AddSignal (32, "SIGPWR", false, true , true , "power fail/restart (not reset when caught)");
+void NetBSDSignals::Reset() {
+ UnixSignals::Reset();
+ // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION
+ // ====== ============ ======== ====== ======
+ // ===================================================
+ AddSignal(32, "SIGPWR", false, true, true,
+ "power fail/restart (not reset when caught)");
#ifdef SIGRTMIN /* SIGRTMAX */
- /* Kernel only; not exposed to userland yet */
+ /* Kernel only; not exposed to userland yet */
#endif
}
diff --git a/source/Plugins/Process/Utility/NetBSDSignals.h b/source/Plugins/Process/Utility/NetBSDSignals.h
index 441402b056db..4338f881645e 100644
--- a/source/Plugins/Process/Utility/NetBSDSignals.h
+++ b/source/Plugins/Process/Utility/NetBSDSignals.h
@@ -16,14 +16,12 @@
namespace lldb_private {
/// NetBSD specific set of Unix signals.
-class NetBSDSignals : public UnixSignals
-{
+class NetBSDSignals : public UnixSignals {
public:
- NetBSDSignals();
+ NetBSDSignals();
private:
- void
- Reset() override;
+ void Reset() override;
};
} // namespace lldb_private
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
index 1d0fc4fb7020..52ace5602f49 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
@@ -42,403 +42,926 @@
using namespace lldb;
using namespace lldb_private;
-enum
-{
- gpr_r0 = 0,
- gpr_r1,
- gpr_r2,
- gpr_r3,
- gpr_r4,
- gpr_r5,
- gpr_r6,
- gpr_r7,
- gpr_r8,
- gpr_r9,
- gpr_r10,
- gpr_r11,
- gpr_r12,
- gpr_r13, gpr_sp = gpr_r13,
- gpr_r14, gpr_lr = gpr_r14,
- gpr_r15, gpr_pc = gpr_r15,
- gpr_cpsr,
-
- fpu_s0,
- fpu_s1,
- fpu_s2,
- fpu_s3,
- fpu_s4,
- fpu_s5,
- fpu_s6,
- fpu_s7,
- fpu_s8,
- fpu_s9,
- fpu_s10,
- fpu_s11,
- fpu_s12,
- fpu_s13,
- fpu_s14,
- fpu_s15,
- fpu_s16,
- fpu_s17,
- fpu_s18,
- fpu_s19,
- fpu_s20,
- fpu_s21,
- fpu_s22,
- fpu_s23,
- fpu_s24,
- fpu_s25,
- fpu_s26,
- fpu_s27,
- fpu_s28,
- fpu_s29,
- fpu_s30,
- fpu_s31,
- fpu_fpscr,
-
- exc_exception,
- exc_fsr,
- exc_far,
-
- dbg_bvr0,
- dbg_bvr1,
- dbg_bvr2,
- dbg_bvr3,
- dbg_bvr4,
- dbg_bvr5,
- dbg_bvr6,
- dbg_bvr7,
- dbg_bvr8,
- dbg_bvr9,
- dbg_bvr10,
- dbg_bvr11,
- dbg_bvr12,
- dbg_bvr13,
- dbg_bvr14,
- dbg_bvr15,
-
- dbg_bcr0,
- dbg_bcr1,
- dbg_bcr2,
- dbg_bcr3,
- dbg_bcr4,
- dbg_bcr5,
- dbg_bcr6,
- dbg_bcr7,
- dbg_bcr8,
- dbg_bcr9,
- dbg_bcr10,
- dbg_bcr11,
- dbg_bcr12,
- dbg_bcr13,
- dbg_bcr14,
- dbg_bcr15,
-
- dbg_wvr0,
- dbg_wvr1,
- dbg_wvr2,
- dbg_wvr3,
- dbg_wvr4,
- dbg_wvr5,
- dbg_wvr6,
- dbg_wvr7,
- dbg_wvr8,
- dbg_wvr9,
- dbg_wvr10,
- dbg_wvr11,
- dbg_wvr12,
- dbg_wvr13,
- dbg_wvr14,
- dbg_wvr15,
-
- dbg_wcr0,
- dbg_wcr1,
- dbg_wcr2,
- dbg_wcr3,
- dbg_wcr4,
- dbg_wcr5,
- dbg_wcr6,
- dbg_wcr7,
- dbg_wcr8,
- dbg_wcr9,
- dbg_wcr10,
- dbg_wcr11,
- dbg_wcr12,
- dbg_wcr13,
- dbg_wcr14,
- dbg_wcr15,
-
- k_num_registers
+enum {
+ gpr_r0 = 0,
+ gpr_r1,
+ gpr_r2,
+ gpr_r3,
+ gpr_r4,
+ gpr_r5,
+ gpr_r6,
+ gpr_r7,
+ gpr_r8,
+ gpr_r9,
+ gpr_r10,
+ gpr_r11,
+ gpr_r12,
+ gpr_r13,
+ gpr_sp = gpr_r13,
+ gpr_r14,
+ gpr_lr = gpr_r14,
+ gpr_r15,
+ gpr_pc = gpr_r15,
+ gpr_cpsr,
+
+ fpu_s0,
+ fpu_s1,
+ fpu_s2,
+ fpu_s3,
+ fpu_s4,
+ fpu_s5,
+ fpu_s6,
+ fpu_s7,
+ fpu_s8,
+ fpu_s9,
+ fpu_s10,
+ fpu_s11,
+ fpu_s12,
+ fpu_s13,
+ fpu_s14,
+ fpu_s15,
+ fpu_s16,
+ fpu_s17,
+ fpu_s18,
+ fpu_s19,
+ fpu_s20,
+ fpu_s21,
+ fpu_s22,
+ fpu_s23,
+ fpu_s24,
+ fpu_s25,
+ fpu_s26,
+ fpu_s27,
+ fpu_s28,
+ fpu_s29,
+ fpu_s30,
+ fpu_s31,
+ fpu_fpscr,
+
+ exc_exception,
+ exc_fsr,
+ exc_far,
+
+ dbg_bvr0,
+ dbg_bvr1,
+ dbg_bvr2,
+ dbg_bvr3,
+ dbg_bvr4,
+ dbg_bvr5,
+ dbg_bvr6,
+ dbg_bvr7,
+ dbg_bvr8,
+ dbg_bvr9,
+ dbg_bvr10,
+ dbg_bvr11,
+ dbg_bvr12,
+ dbg_bvr13,
+ dbg_bvr14,
+ dbg_bvr15,
+
+ dbg_bcr0,
+ dbg_bcr1,
+ dbg_bcr2,
+ dbg_bcr3,
+ dbg_bcr4,
+ dbg_bcr5,
+ dbg_bcr6,
+ dbg_bcr7,
+ dbg_bcr8,
+ dbg_bcr9,
+ dbg_bcr10,
+ dbg_bcr11,
+ dbg_bcr12,
+ dbg_bcr13,
+ dbg_bcr14,
+ dbg_bcr15,
+
+ dbg_wvr0,
+ dbg_wvr1,
+ dbg_wvr2,
+ dbg_wvr3,
+ dbg_wvr4,
+ dbg_wvr5,
+ dbg_wvr6,
+ dbg_wvr7,
+ dbg_wvr8,
+ dbg_wvr9,
+ dbg_wvr10,
+ dbg_wvr11,
+ dbg_wvr12,
+ dbg_wvr13,
+ dbg_wvr14,
+ dbg_wvr15,
+
+ dbg_wcr0,
+ dbg_wcr1,
+ dbg_wcr2,
+ dbg_wcr3,
+ dbg_wcr4,
+ dbg_wcr5,
+ dbg_wcr6,
+ dbg_wcr7,
+ dbg_wcr8,
+ dbg_wcr9,
+ dbg_wcr10,
+ dbg_wcr11,
+ dbg_wcr12,
+ dbg_wcr13,
+ dbg_wcr14,
+ dbg_wcr15,
+
+ k_num_registers
};
-
-#define GPR_OFFSET(idx) ((idx) * 4)
-#define FPU_OFFSET(idx) ((idx) * 4 + sizeof (RegisterContextDarwin_arm::GPR))
-#define EXC_OFFSET(idx) ((idx) * 4 + sizeof (RegisterContextDarwin_arm::GPR) + sizeof (RegisterContextDarwin_arm::FPU))
-#define DBG_OFFSET(reg) ((LLVM_EXTENSION offsetof (RegisterContextDarwin_arm::DBG, reg) + sizeof (RegisterContextDarwin_arm::GPR) + sizeof (RegisterContextDarwin_arm::FPU) + sizeof (RegisterContextDarwin_arm::EXC)))
-
-#define DEFINE_DBG(reg, i) #reg, NULL, sizeof(((RegisterContextDarwin_arm::DBG *)NULL)->reg[i]), DBG_OFFSET(reg[i]), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL, NULL, 0
-#define REG_CONTEXT_SIZE (sizeof (RegisterContextDarwin_arm::GPR) + sizeof (RegisterContextDarwin_arm::FPU) + sizeof (RegisterContextDarwin_arm::EXC))
+#define GPR_OFFSET(idx) ((idx)*4)
+#define FPU_OFFSET(idx) ((idx)*4 + sizeof(RegisterContextDarwin_arm::GPR))
+#define EXC_OFFSET(idx) \
+ ((idx)*4 + sizeof(RegisterContextDarwin_arm::GPR) + \
+ sizeof(RegisterContextDarwin_arm::FPU))
+#define DBG_OFFSET(reg) \
+ ((LLVM_EXTENSION offsetof(RegisterContextDarwin_arm::DBG, reg) + \
+ sizeof(RegisterContextDarwin_arm::GPR) + \
+ sizeof(RegisterContextDarwin_arm::FPU) + \
+ sizeof(RegisterContextDarwin_arm::EXC)))
+
+#define DEFINE_DBG(reg, i) \
+ #reg, NULL, sizeof(((RegisterContextDarwin_arm::DBG *) NULL)->reg[i]), \
+ DBG_OFFSET(reg[i]), eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM }, \
+ nullptr, nullptr, nullptr, 0
+#define REG_CONTEXT_SIZE \
+ (sizeof(RegisterContextDarwin_arm::GPR) + \
+ sizeof(RegisterContextDarwin_arm::FPU) + \
+ sizeof(RegisterContextDarwin_arm::EXC))
static RegisterInfo g_register_infos[] = {
-// General purpose registers
-// NAME ALT SZ OFFSET ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB NATIVE VALUE REGS INVALIDATE REGS
-// ====== ======= == ============= ============= ============ =============== =============== ========================= ===================== ============= ========== ===============
-{ "r0", NULL, 4, GPR_OFFSET(0), eEncodingUint, eFormatHex, { ehframe_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r0 }, NULL, NULL},
-{ "r1", NULL, 4, GPR_OFFSET(1), eEncodingUint, eFormatHex, { ehframe_r1, dwarf_r1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r1 }, NULL, NULL},
-{ "r2", NULL, 4, GPR_OFFSET(2), eEncodingUint, eFormatHex, { ehframe_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r2 }, NULL, NULL},
-{ "r3", NULL, 4, GPR_OFFSET(3), eEncodingUint, eFormatHex, { ehframe_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r3 }, NULL, NULL},
-{ "r4", NULL, 4, GPR_OFFSET(4), eEncodingUint, eFormatHex, { ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r4 }, NULL, NULL},
-{ "r5", NULL, 4, GPR_OFFSET(5), eEncodingUint, eFormatHex, { ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r5 }, NULL, NULL},
-{ "r6", NULL, 4, GPR_OFFSET(6), eEncodingUint, eFormatHex, { ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r6 }, NULL, NULL},
-{ "r7", NULL, 4, GPR_OFFSET(7), eEncodingUint, eFormatHex, { ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, gpr_r7 }, NULL, NULL},
-{ "r8", NULL, 4, GPR_OFFSET(8), eEncodingUint, eFormatHex, { ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r8 }, NULL, NULL},
-{ "r9", NULL, 4, GPR_OFFSET(9), eEncodingUint, eFormatHex, { ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r9 }, NULL, NULL},
-{ "r10", NULL, 4, GPR_OFFSET(10), eEncodingUint, eFormatHex, { ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r10 }, NULL, NULL},
-{ "r11", NULL, 4, GPR_OFFSET(11), eEncodingUint, eFormatHex, { ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r11 }, NULL, NULL},
-{ "r12", NULL, 4, GPR_OFFSET(12), eEncodingUint, eFormatHex, { ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r12 }, NULL, NULL},
-{ "sp", "r13", 4, GPR_OFFSET(13), eEncodingUint, eFormatHex, { ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, gpr_sp }, NULL, NULL},
-{ "lr", "r14", 4, GPR_OFFSET(14), eEncodingUint, eFormatHex, { ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, gpr_lr }, NULL, NULL},
-{ "pc", "r15", 4, GPR_OFFSET(15), eEncodingUint, eFormatHex, { ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, gpr_pc }, NULL, NULL},
-{ "cpsr", "psr", 4, GPR_OFFSET(16), eEncodingUint, eFormatHex, { ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, gpr_cpsr }, NULL, NULL},
-
-{ "s0", NULL, 4, FPU_OFFSET(0), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s0 }, NULL, NULL},
-{ "s1", NULL, 4, FPU_OFFSET(1), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s1 }, NULL, NULL},
-{ "s2", NULL, 4, FPU_OFFSET(2), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s2 }, NULL, NULL},
-{ "s3", NULL, 4, FPU_OFFSET(3), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s3 }, NULL, NULL},
-{ "s4", NULL, 4, FPU_OFFSET(4), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s4 }, NULL, NULL},
-{ "s5", NULL, 4, FPU_OFFSET(5), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s5 }, NULL, NULL},
-{ "s6", NULL, 4, FPU_OFFSET(6), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s6 }, NULL, NULL},
-{ "s7", NULL, 4, FPU_OFFSET(7), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s7 }, NULL, NULL},
-{ "s8", NULL, 4, FPU_OFFSET(8), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s8 }, NULL, NULL},
-{ "s9", NULL, 4, FPU_OFFSET(9), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s9 }, NULL, NULL},
-{ "s10", NULL, 4, FPU_OFFSET(10), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s10 }, NULL, NULL},
-{ "s11", NULL, 4, FPU_OFFSET(11), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s11 }, NULL, NULL},
-{ "s12", NULL, 4, FPU_OFFSET(12), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s12 }, NULL, NULL},
-{ "s13", NULL, 4, FPU_OFFSET(13), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s13 }, NULL, NULL},
-{ "s14", NULL, 4, FPU_OFFSET(14), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s14 }, NULL, NULL},
-{ "s15", NULL, 4, FPU_OFFSET(15), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s15 }, NULL, NULL},
-{ "s16", NULL, 4, FPU_OFFSET(16), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s16 }, NULL, NULL},
-{ "s17", NULL, 4, FPU_OFFSET(17), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s17 }, NULL, NULL},
-{ "s18", NULL, 4, FPU_OFFSET(18), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s18 }, NULL, NULL},
-{ "s19", NULL, 4, FPU_OFFSET(19), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s19 }, NULL, NULL},
-{ "s20", NULL, 4, FPU_OFFSET(20), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s20 }, NULL, NULL},
-{ "s21", NULL, 4, FPU_OFFSET(21), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s21 }, NULL, NULL},
-{ "s22", NULL, 4, FPU_OFFSET(22), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s22 }, NULL, NULL},
-{ "s23", NULL, 4, FPU_OFFSET(23), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s23 }, NULL, NULL},
-{ "s24", NULL, 4, FPU_OFFSET(24), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s24 }, NULL, NULL},
-{ "s25", NULL, 4, FPU_OFFSET(25), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s25 }, NULL, NULL},
-{ "s26", NULL, 4, FPU_OFFSET(26), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s26 }, NULL, NULL},
-{ "s27", NULL, 4, FPU_OFFSET(27), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s27 }, NULL, NULL},
-{ "s28", NULL, 4, FPU_OFFSET(28), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s28 }, NULL, NULL},
-{ "s29", NULL, 4, FPU_OFFSET(29), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s29 }, NULL, NULL},
-{ "s30", NULL, 4, FPU_OFFSET(30), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s30 }, NULL, NULL},
-{ "s31", NULL, 4, FPU_OFFSET(31), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s31 }, NULL, NULL},
-{ "fpscr", NULL, 4, FPU_OFFSET(32), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_fpscr }, NULL, NULL},
-
-{ "exception",NULL, 4, EXC_OFFSET(0), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_exception }, NULL, NULL},
-{ "fsr", NULL, 4, EXC_OFFSET(1), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_fsr }, NULL, NULL},
-{ "far", NULL, 4, EXC_OFFSET(2), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_far }, NULL, NULL},
-
-{ DEFINE_DBG (bvr, 0) },
-{ DEFINE_DBG (bvr, 1) },
-{ DEFINE_DBG (bvr, 2) },
-{ DEFINE_DBG (bvr, 3) },
-{ DEFINE_DBG (bvr, 4) },
-{ DEFINE_DBG (bvr, 5) },
-{ DEFINE_DBG (bvr, 6) },
-{ DEFINE_DBG (bvr, 7) },
-{ DEFINE_DBG (bvr, 8) },
-{ DEFINE_DBG (bvr, 9) },
-{ DEFINE_DBG (bvr, 10) },
-{ DEFINE_DBG (bvr, 11) },
-{ DEFINE_DBG (bvr, 12) },
-{ DEFINE_DBG (bvr, 13) },
-{ DEFINE_DBG (bvr, 14) },
-{ DEFINE_DBG (bvr, 15) },
-
-{ DEFINE_DBG (bcr, 0) },
-{ DEFINE_DBG (bcr, 1) },
-{ DEFINE_DBG (bcr, 2) },
-{ DEFINE_DBG (bcr, 3) },
-{ DEFINE_DBG (bcr, 4) },
-{ DEFINE_DBG (bcr, 5) },
-{ DEFINE_DBG (bcr, 6) },
-{ DEFINE_DBG (bcr, 7) },
-{ DEFINE_DBG (bcr, 8) },
-{ DEFINE_DBG (bcr, 9) },
-{ DEFINE_DBG (bcr, 10) },
-{ DEFINE_DBG (bcr, 11) },
-{ DEFINE_DBG (bcr, 12) },
-{ DEFINE_DBG (bcr, 13) },
-{ DEFINE_DBG (bcr, 14) },
-{ DEFINE_DBG (bcr, 15) },
-
-{ DEFINE_DBG (wvr, 0) },
-{ DEFINE_DBG (wvr, 1) },
-{ DEFINE_DBG (wvr, 2) },
-{ DEFINE_DBG (wvr, 3) },
-{ DEFINE_DBG (wvr, 4) },
-{ DEFINE_DBG (wvr, 5) },
-{ DEFINE_DBG (wvr, 6) },
-{ DEFINE_DBG (wvr, 7) },
-{ DEFINE_DBG (wvr, 8) },
-{ DEFINE_DBG (wvr, 9) },
-{ DEFINE_DBG (wvr, 10) },
-{ DEFINE_DBG (wvr, 11) },
-{ DEFINE_DBG (wvr, 12) },
-{ DEFINE_DBG (wvr, 13) },
-{ DEFINE_DBG (wvr, 14) },
-{ DEFINE_DBG (wvr, 15) },
-
-{ DEFINE_DBG (wcr, 0) },
-{ DEFINE_DBG (wcr, 1) },
-{ DEFINE_DBG (wcr, 2) },
-{ DEFINE_DBG (wcr, 3) },
-{ DEFINE_DBG (wcr, 4) },
-{ DEFINE_DBG (wcr, 5) },
-{ DEFINE_DBG (wcr, 6) },
-{ DEFINE_DBG (wcr, 7) },
-{ DEFINE_DBG (wcr, 8) },
-{ DEFINE_DBG (wcr, 9) },
-{ DEFINE_DBG (wcr, 10) },
-{ DEFINE_DBG (wcr, 11) },
-{ DEFINE_DBG (wcr, 12) },
-{ DEFINE_DBG (wcr, 13) },
-{ DEFINE_DBG (wcr, 14) },
-{ DEFINE_DBG (wcr, 15) }
-};
+ // General purpose registers
+ // NAME ALT SZ OFFSET ENCODING FORMAT
+ // EH_FRAME DWARF GENERIC
+ // PROCESS PLUGIN LLDB NATIVE
+ // ====== ======= == ============= ============= ============
+ // =============== =============== =========================
+ // ===================== =============
+ {"r0",
+ NULL,
+ 4,
+ GPR_OFFSET(0),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r0},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r1",
+ NULL,
+ 4,
+ GPR_OFFSET(1),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r1, dwarf_r1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r1},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r2",
+ NULL,
+ 4,
+ GPR_OFFSET(2),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r2},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r3",
+ NULL,
+ 4,
+ GPR_OFFSET(3),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r3},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r4",
+ NULL,
+ 4,
+ GPR_OFFSET(4),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r4},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r5",
+ NULL,
+ 4,
+ GPR_OFFSET(5),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r5},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r6",
+ NULL,
+ 4,
+ GPR_OFFSET(6),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r6},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r7",
+ NULL,
+ 4,
+ GPR_OFFSET(7),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
+ gpr_r7},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r8",
+ NULL,
+ 4,
+ GPR_OFFSET(8),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r8},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r9",
+ NULL,
+ 4,
+ GPR_OFFSET(9),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r9},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r10",
+ NULL,
+ 4,
+ GPR_OFFSET(10),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ gpr_r10},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r11",
+ NULL,
+ 4,
+ GPR_OFFSET(11),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ gpr_r11},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r12",
+ NULL,
+ 4,
+ GPR_OFFSET(12),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ gpr_r12},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"sp",
+ "r13",
+ 4,
+ GPR_OFFSET(13),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
+ gpr_sp},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"lr",
+ "r14",
+ 4,
+ GPR_OFFSET(14),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM,
+ gpr_lr},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"pc",
+ "r15",
+ 4,
+ GPR_OFFSET(15),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
+ gpr_pc},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"cpsr",
+ "psr",
+ 4,
+ GPR_OFFSET(16),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM,
+ gpr_cpsr},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+
+ {"s0",
+ NULL,
+ 4,
+ FPU_OFFSET(0),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s0},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s1",
+ NULL,
+ 4,
+ FPU_OFFSET(1),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s1},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s2",
+ NULL,
+ 4,
+ FPU_OFFSET(2),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s2},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s3",
+ NULL,
+ 4,
+ FPU_OFFSET(3),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s3},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s4",
+ NULL,
+ 4,
+ FPU_OFFSET(4),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s4},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s5",
+ NULL,
+ 4,
+ FPU_OFFSET(5),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s5},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s6",
+ NULL,
+ 4,
+ FPU_OFFSET(6),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s6},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s7",
+ NULL,
+ 4,
+ FPU_OFFSET(7),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s7},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s8",
+ NULL,
+ 4,
+ FPU_OFFSET(8),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s8},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s9",
+ NULL,
+ 4,
+ FPU_OFFSET(9),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s9},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s10",
+ NULL,
+ 4,
+ FPU_OFFSET(10),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s10},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s11",
+ NULL,
+ 4,
+ FPU_OFFSET(11),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s11},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s12",
+ NULL,
+ 4,
+ FPU_OFFSET(12),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s12},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s13",
+ NULL,
+ 4,
+ FPU_OFFSET(13),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s13},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s14",
+ NULL,
+ 4,
+ FPU_OFFSET(14),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s14},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s15",
+ NULL,
+ 4,
+ FPU_OFFSET(15),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s15},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s16",
+ NULL,
+ 4,
+ FPU_OFFSET(16),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s16},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s17",
+ NULL,
+ 4,
+ FPU_OFFSET(17),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s17},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s18",
+ NULL,
+ 4,
+ FPU_OFFSET(18),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s18},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s19",
+ NULL,
+ 4,
+ FPU_OFFSET(19),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s19},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s20",
+ NULL,
+ 4,
+ FPU_OFFSET(20),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s20},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s21",
+ NULL,
+ 4,
+ FPU_OFFSET(21),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s21},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s22",
+ NULL,
+ 4,
+ FPU_OFFSET(22),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s22},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s23",
+ NULL,
+ 4,
+ FPU_OFFSET(23),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s23},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s24",
+ NULL,
+ 4,
+ FPU_OFFSET(24),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s24},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s25",
+ NULL,
+ 4,
+ FPU_OFFSET(25),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s25},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s26",
+ NULL,
+ 4,
+ FPU_OFFSET(26),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s26},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s27",
+ NULL,
+ 4,
+ FPU_OFFSET(27),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s27},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s28",
+ NULL,
+ 4,
+ FPU_OFFSET(28),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s28},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s29",
+ NULL,
+ 4,
+ FPU_OFFSET(29),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s29},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s30",
+ NULL,
+ 4,
+ FPU_OFFSET(30),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s30},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"s31",
+ NULL,
+ 4,
+ FPU_OFFSET(31),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s31},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fpscr",
+ NULL,
+ 4,
+ FPU_OFFSET(32),
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_fpscr},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+
+ {"exception",
+ NULL,
+ 4,
+ EXC_OFFSET(0),
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, exc_exception},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fsr",
+ NULL,
+ 4,
+ EXC_OFFSET(1),
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, exc_fsr},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"far",
+ NULL,
+ 4,
+ EXC_OFFSET(2),
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, exc_far},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+
+ {DEFINE_DBG(bvr, 0)},
+ {DEFINE_DBG(bvr, 1)},
+ {DEFINE_DBG(bvr, 2)},
+ {DEFINE_DBG(bvr, 3)},
+ {DEFINE_DBG(bvr, 4)},
+ {DEFINE_DBG(bvr, 5)},
+ {DEFINE_DBG(bvr, 6)},
+ {DEFINE_DBG(bvr, 7)},
+ {DEFINE_DBG(bvr, 8)},
+ {DEFINE_DBG(bvr, 9)},
+ {DEFINE_DBG(bvr, 10)},
+ {DEFINE_DBG(bvr, 11)},
+ {DEFINE_DBG(bvr, 12)},
+ {DEFINE_DBG(bvr, 13)},
+ {DEFINE_DBG(bvr, 14)},
+ {DEFINE_DBG(bvr, 15)},
+
+ {DEFINE_DBG(bcr, 0)},
+ {DEFINE_DBG(bcr, 1)},
+ {DEFINE_DBG(bcr, 2)},
+ {DEFINE_DBG(bcr, 3)},
+ {DEFINE_DBG(bcr, 4)},
+ {DEFINE_DBG(bcr, 5)},
+ {DEFINE_DBG(bcr, 6)},
+ {DEFINE_DBG(bcr, 7)},
+ {DEFINE_DBG(bcr, 8)},
+ {DEFINE_DBG(bcr, 9)},
+ {DEFINE_DBG(bcr, 10)},
+ {DEFINE_DBG(bcr, 11)},
+ {DEFINE_DBG(bcr, 12)},
+ {DEFINE_DBG(bcr, 13)},
+ {DEFINE_DBG(bcr, 14)},
+ {DEFINE_DBG(bcr, 15)},
+
+ {DEFINE_DBG(wvr, 0)},
+ {DEFINE_DBG(wvr, 1)},
+ {DEFINE_DBG(wvr, 2)},
+ {DEFINE_DBG(wvr, 3)},
+ {DEFINE_DBG(wvr, 4)},
+ {DEFINE_DBG(wvr, 5)},
+ {DEFINE_DBG(wvr, 6)},
+ {DEFINE_DBG(wvr, 7)},
+ {DEFINE_DBG(wvr, 8)},
+ {DEFINE_DBG(wvr, 9)},
+ {DEFINE_DBG(wvr, 10)},
+ {DEFINE_DBG(wvr, 11)},
+ {DEFINE_DBG(wvr, 12)},
+ {DEFINE_DBG(wvr, 13)},
+ {DEFINE_DBG(wvr, 14)},
+ {DEFINE_DBG(wvr, 15)},
+
+ {DEFINE_DBG(wcr, 0)},
+ {DEFINE_DBG(wcr, 1)},
+ {DEFINE_DBG(wcr, 2)},
+ {DEFINE_DBG(wcr, 3)},
+ {DEFINE_DBG(wcr, 4)},
+ {DEFINE_DBG(wcr, 5)},
+ {DEFINE_DBG(wcr, 6)},
+ {DEFINE_DBG(wcr, 7)},
+ {DEFINE_DBG(wcr, 8)},
+ {DEFINE_DBG(wcr, 9)},
+ {DEFINE_DBG(wcr, 10)},
+ {DEFINE_DBG(wcr, 11)},
+ {DEFINE_DBG(wcr, 12)},
+ {DEFINE_DBG(wcr, 13)},
+ {DEFINE_DBG(wcr, 14)},
+ {DEFINE_DBG(wcr, 15)}};
// General purpose registers
-static uint32_t
-g_gpr_regnums[] =
-{
- gpr_r0,
- gpr_r1,
- gpr_r2,
- gpr_r3,
- gpr_r4,
- gpr_r5,
- gpr_r6,
- gpr_r7,
- gpr_r8,
- gpr_r9,
- gpr_r10,
- gpr_r11,
- gpr_r12,
- gpr_sp,
- gpr_lr,
- gpr_pc,
- gpr_cpsr
-};
+static uint32_t g_gpr_regnums[] = {
+ gpr_r0, gpr_r1, gpr_r2, gpr_r3, gpr_r4, gpr_r5, gpr_r6, gpr_r7, gpr_r8,
+ gpr_r9, gpr_r10, gpr_r11, gpr_r12, gpr_sp, gpr_lr, gpr_pc, gpr_cpsr};
// Floating point registers
-static uint32_t
-g_fpu_regnums[] =
-{
- fpu_s0,
- fpu_s1,
- fpu_s2,
- fpu_s3,
- fpu_s4,
- fpu_s5,
- fpu_s6,
- fpu_s7,
- fpu_s8,
- fpu_s9,
- fpu_s10,
- fpu_s11,
- fpu_s12,
- fpu_s13,
- fpu_s14,
- fpu_s15,
- fpu_s16,
- fpu_s17,
- fpu_s18,
- fpu_s19,
- fpu_s20,
- fpu_s21,
- fpu_s22,
- fpu_s23,
- fpu_s24,
- fpu_s25,
- fpu_s26,
- fpu_s27,
- fpu_s28,
- fpu_s29,
- fpu_s30,
- fpu_s31,
- fpu_fpscr,
+static uint32_t g_fpu_regnums[] = {
+ fpu_s0, fpu_s1, fpu_s2, fpu_s3, fpu_s4, fpu_s5, fpu_s6,
+ fpu_s7, fpu_s8, fpu_s9, fpu_s10, fpu_s11, fpu_s12, fpu_s13,
+ fpu_s14, fpu_s15, fpu_s16, fpu_s17, fpu_s18, fpu_s19, fpu_s20,
+ fpu_s21, fpu_s22, fpu_s23, fpu_s24, fpu_s25, fpu_s26, fpu_s27,
+ fpu_s28, fpu_s29, fpu_s30, fpu_s31, fpu_fpscr,
};
// Exception registers
-static uint32_t
-g_exc_regnums[] =
-{
- exc_exception,
- exc_fsr,
- exc_far,
+static uint32_t g_exc_regnums[] = {
+ exc_exception, exc_fsr, exc_far,
};
static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
-RegisterContextDarwin_arm::RegisterContextDarwin_arm(Thread &thread, uint32_t concrete_frame_idx) :
- RegisterContext(thread, concrete_frame_idx),
- gpr(),
- fpu(),
- exc()
-{
- uint32_t i;
- for (i=0; i<kNumErrors; i++)
- {
- gpr_errs[i] = -1;
- fpu_errs[i] = -1;
- exc_errs[i] = -1;
- }
-}
-
-RegisterContextDarwin_arm::~RegisterContextDarwin_arm()
-{
+RegisterContextDarwin_arm::RegisterContextDarwin_arm(
+ Thread &thread, uint32_t concrete_frame_idx)
+ : RegisterContext(thread, concrete_frame_idx), gpr(), fpu(), exc() {
+ uint32_t i;
+ for (i = 0; i < kNumErrors; i++) {
+ gpr_errs[i] = -1;
+ fpu_errs[i] = -1;
+ exc_errs[i] = -1;
+ }
}
+RegisterContextDarwin_arm::~RegisterContextDarwin_arm() {}
-void
-RegisterContextDarwin_arm::InvalidateAllRegisters ()
-{
- InvalidateAllRegisterStates();
+void RegisterContextDarwin_arm::InvalidateAllRegisters() {
+ InvalidateAllRegisterStates();
}
-
-size_t
-RegisterContextDarwin_arm::GetRegisterCount ()
-{
- assert(k_num_register_infos == k_num_registers);
- return k_num_registers;
+size_t RegisterContextDarwin_arm::GetRegisterCount() {
+ assert(k_num_register_infos == k_num_registers);
+ return k_num_registers;
}
const RegisterInfo *
-RegisterContextDarwin_arm::GetRegisterInfoAtIndex (size_t reg)
-{
- assert(k_num_register_infos == k_num_registers);
- if (reg < k_num_registers)
- return &g_register_infos[reg];
- return NULL;
+RegisterContextDarwin_arm::GetRegisterInfoAtIndex(size_t reg) {
+ assert(k_num_register_infos == k_num_registers);
+ if (reg < k_num_registers)
+ return &g_register_infos[reg];
+ return NULL;
}
-size_t
-RegisterContextDarwin_arm::GetRegisterInfosCount ()
-{
- return k_num_register_infos;
+size_t RegisterContextDarwin_arm::GetRegisterInfosCount() {
+ return k_num_register_infos;
}
-const RegisterInfo *
-RegisterContextDarwin_arm::GetRegisterInfos ()
-{
- return g_register_infos;
+const RegisterInfo *RegisterContextDarwin_arm::GetRegisterInfos() {
+ return g_register_infos;
}
-
// Number of registers in each register set
const size_t k_num_gpr_registers = llvm::array_lengthof(g_gpr_regnums);
const size_t k_num_fpu_registers = llvm::array_lengthof(g_fpu_regnums);
@@ -449,782 +972,799 @@ const size_t k_num_exc_registers = llvm::array_lengthof(g_exc_regnums);
// of zero is for all registers, followed by other registers sets. The
// register information for the all register set need not be filled in.
//----------------------------------------------------------------------
-static const RegisterSet g_reg_sets[] =
-{
- { "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums, },
- { "Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums },
- { "Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums }
-};
+static const RegisterSet g_reg_sets[] = {
+ {
+ "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums,
+ },
+ {"Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums},
+ {"Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums}};
const size_t k_num_regsets = llvm::array_lengthof(g_reg_sets);
-
-size_t
-RegisterContextDarwin_arm::GetRegisterSetCount ()
-{
- return k_num_regsets;
+size_t RegisterContextDarwin_arm::GetRegisterSetCount() {
+ return k_num_regsets;
}
-const RegisterSet *
-RegisterContextDarwin_arm::GetRegisterSet (size_t reg_set)
-{
- if (reg_set < k_num_regsets)
- return &g_reg_sets[reg_set];
- return NULL;
+const RegisterSet *RegisterContextDarwin_arm::GetRegisterSet(size_t reg_set) {
+ if (reg_set < k_num_regsets)
+ return &g_reg_sets[reg_set];
+ return NULL;
}
-
//----------------------------------------------------------------------
// Register information definitions for 32 bit i386.
//----------------------------------------------------------------------
-int
-RegisterContextDarwin_arm::GetSetForNativeRegNum (int reg)
-{
- if (reg < fpu_s0)
- return GPRRegSet;
- else if (reg < exc_exception)
- return FPURegSet;
- else if (reg < k_num_registers)
- return EXCRegSet;
- return -1;
+int RegisterContextDarwin_arm::GetSetForNativeRegNum(int reg) {
+ if (reg < fpu_s0)
+ return GPRRegSet;
+ else if (reg < exc_exception)
+ return FPURegSet;
+ else if (reg < k_num_registers)
+ return EXCRegSet;
+ return -1;
}
-int
-RegisterContextDarwin_arm::ReadGPR (bool force)
-{
- int set = GPRRegSet;
- if (force || !RegisterSetIsCached(set))
- {
- SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
- }
- return GetError(GPRRegSet, Read);
+int RegisterContextDarwin_arm::ReadGPR(bool force) {
+ int set = GPRRegSet;
+ if (force || !RegisterSetIsCached(set)) {
+ SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
+ }
+ return GetError(GPRRegSet, Read);
}
-int
-RegisterContextDarwin_arm::ReadFPU (bool force)
-{
- int set = FPURegSet;
- if (force || !RegisterSetIsCached(set))
- {
- SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
- }
- return GetError(FPURegSet, Read);
+int RegisterContextDarwin_arm::ReadFPU(bool force) {
+ int set = FPURegSet;
+ if (force || !RegisterSetIsCached(set)) {
+ SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
+ }
+ return GetError(FPURegSet, Read);
}
-int
-RegisterContextDarwin_arm::ReadEXC (bool force)
-{
- int set = EXCRegSet;
- if (force || !RegisterSetIsCached(set))
- {
- SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
- }
- return GetError(EXCRegSet, Read);
+int RegisterContextDarwin_arm::ReadEXC(bool force) {
+ int set = EXCRegSet;
+ if (force || !RegisterSetIsCached(set)) {
+ SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
+ }
+ return GetError(EXCRegSet, Read);
}
-int
-RegisterContextDarwin_arm::ReadDBG (bool force)
-{
- int set = DBGRegSet;
- if (force || !RegisterSetIsCached(set))
- {
- SetError(set, Read, DoReadDBG(GetThreadID(), set, dbg));
- }
- return GetError(DBGRegSet, Read);
+int RegisterContextDarwin_arm::ReadDBG(bool force) {
+ int set = DBGRegSet;
+ if (force || !RegisterSetIsCached(set)) {
+ SetError(set, Read, DoReadDBG(GetThreadID(), set, dbg));
+ }
+ return GetError(DBGRegSet, Read);
}
-int
-RegisterContextDarwin_arm::WriteGPR ()
-{
- int set = GPRRegSet;
- if (!RegisterSetIsCached(set))
- {
- SetError (set, Write, -1);
- return KERN_INVALID_ARGUMENT;
- }
- SetError (set, Write, DoWriteGPR(GetThreadID(), set, gpr));
- SetError (set, Read, -1);
- return GetError(GPRRegSet, Write);
-}
-
-int
-RegisterContextDarwin_arm::WriteFPU ()
-{
- int set = FPURegSet;
- if (!RegisterSetIsCached(set))
- {
- SetError (set, Write, -1);
- return KERN_INVALID_ARGUMENT;
- }
- SetError (set, Write, DoWriteFPU(GetThreadID(), set, fpu));
- SetError (set, Read, -1);
- return GetError(FPURegSet, Write);
+int RegisterContextDarwin_arm::WriteGPR() {
+ int set = GPRRegSet;
+ if (!RegisterSetIsCached(set)) {
+ SetError(set, Write, -1);
+ return KERN_INVALID_ARGUMENT;
+ }
+ SetError(set, Write, DoWriteGPR(GetThreadID(), set, gpr));
+ SetError(set, Read, -1);
+ return GetError(GPRRegSet, Write);
}
-int
-RegisterContextDarwin_arm::WriteEXC ()
-{
- int set = EXCRegSet;
- if (!RegisterSetIsCached(set))
- {
- SetError (set, Write, -1);
- return KERN_INVALID_ARGUMENT;
- }
- SetError (set, Write, DoWriteEXC(GetThreadID(), set, exc));
- SetError (set, Read, -1);
- return GetError(EXCRegSet, Write);
+int RegisterContextDarwin_arm::WriteFPU() {
+ int set = FPURegSet;
+ if (!RegisterSetIsCached(set)) {
+ SetError(set, Write, -1);
+ return KERN_INVALID_ARGUMENT;
+ }
+ SetError(set, Write, DoWriteFPU(GetThreadID(), set, fpu));
+ SetError(set, Read, -1);
+ return GetError(FPURegSet, Write);
}
-int
-RegisterContextDarwin_arm::WriteDBG ()
-{
- int set = DBGRegSet;
- if (!RegisterSetIsCached(set))
- {
- SetError (set, Write, -1);
- return KERN_INVALID_ARGUMENT;
- }
- SetError (set, Write, DoWriteDBG(GetThreadID(), set, dbg));
- SetError (set, Read, -1);
- return GetError(DBGRegSet, Write);
+int RegisterContextDarwin_arm::WriteEXC() {
+ int set = EXCRegSet;
+ if (!RegisterSetIsCached(set)) {
+ SetError(set, Write, -1);
+ return KERN_INVALID_ARGUMENT;
+ }
+ SetError(set, Write, DoWriteEXC(GetThreadID(), set, exc));
+ SetError(set, Read, -1);
+ return GetError(EXCRegSet, Write);
}
-
-int
-RegisterContextDarwin_arm::ReadRegisterSet (uint32_t set, bool force)
-{
- switch (set)
- {
- case GPRRegSet: return ReadGPR(force);
- case GPRAltRegSet: return ReadGPR(force);
- case FPURegSet: return ReadFPU(force);
- case EXCRegSet: return ReadEXC(force);
- case DBGRegSet: return ReadDBG(force);
- default: break;
- }
+int RegisterContextDarwin_arm::WriteDBG() {
+ int set = DBGRegSet;
+ if (!RegisterSetIsCached(set)) {
+ SetError(set, Write, -1);
return KERN_INVALID_ARGUMENT;
+ }
+ SetError(set, Write, DoWriteDBG(GetThreadID(), set, dbg));
+ SetError(set, Read, -1);
+ return GetError(DBGRegSet, Write);
}
-int
-RegisterContextDarwin_arm::WriteRegisterSet (uint32_t set)
-{
- // Make sure we have a valid context to set.
- if (RegisterSetIsCached(set))
- {
- switch (set)
- {
- case GPRRegSet: return WriteGPR();
- case GPRAltRegSet: return WriteGPR();
- case FPURegSet: return WriteFPU();
- case EXCRegSet: return WriteEXC();
- case DBGRegSet: return WriteDBG();
- default: break;
- }
- }
- return KERN_INVALID_ARGUMENT;
+int RegisterContextDarwin_arm::ReadRegisterSet(uint32_t set, bool force) {
+ switch (set) {
+ case GPRRegSet:
+ return ReadGPR(force);
+ case GPRAltRegSet:
+ return ReadGPR(force);
+ case FPURegSet:
+ return ReadFPU(force);
+ case EXCRegSet:
+ return ReadEXC(force);
+ case DBGRegSet:
+ return ReadDBG(force);
+ default:
+ break;
+ }
+ return KERN_INVALID_ARGUMENT;
}
-void
-RegisterContextDarwin_arm::LogDBGRegisters (Log *log, const DBG& dbg)
-{
- if (log)
- {
- for (uint32_t i=0; i<16; i++)
- log->Printf("BVR%-2u/BCR%-2u = { 0x%8.8x, 0x%8.8x } WVR%-2u/WCR%-2u = { 0x%8.8x, 0x%8.8x }",
- i, i, dbg.bvr[i], dbg.bcr[i],
- i, i, dbg.wvr[i], dbg.wcr[i]);
+int RegisterContextDarwin_arm::WriteRegisterSet(uint32_t set) {
+ // Make sure we have a valid context to set.
+ if (RegisterSetIsCached(set)) {
+ switch (set) {
+ case GPRRegSet:
+ return WriteGPR();
+ case GPRAltRegSet:
+ return WriteGPR();
+ case FPURegSet:
+ return WriteFPU();
+ case EXCRegSet:
+ return WriteEXC();
+ case DBGRegSet:
+ return WriteDBG();
+ default:
+ break;
}
+ }
+ return KERN_INVALID_ARGUMENT;
}
+void RegisterContextDarwin_arm::LogDBGRegisters(Log *log, const DBG &dbg) {
+ if (log) {
+ for (uint32_t i = 0; i < 16; i++)
+ log->Printf("BVR%-2u/BCR%-2u = { 0x%8.8x, 0x%8.8x } WVR%-2u/WCR%-2u = { "
+ "0x%8.8x, 0x%8.8x }",
+ i, i, dbg.bvr[i], dbg.bcr[i], i, i, dbg.wvr[i], dbg.wcr[i]);
+ }
+}
-bool
-RegisterContextDarwin_arm::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value)
-{
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- int set = RegisterContextDarwin_arm::GetSetForNativeRegNum (reg);
-
- if (set == -1)
- return false;
-
- if (ReadRegisterSet(set, false) != KERN_SUCCESS)
- return false;
+bool RegisterContextDarwin_arm::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &value) {
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+ int set = RegisterContextDarwin_arm::GetSetForNativeRegNum(reg);
- switch (reg)
- {
- case gpr_r0:
- case gpr_r1:
- case gpr_r2:
- case gpr_r3:
- case gpr_r4:
- case gpr_r5:
- case gpr_r6:
- case gpr_r7:
- case gpr_r8:
- case gpr_r9:
- case gpr_r10:
- case gpr_r11:
- case gpr_r12:
- case gpr_sp:
- case gpr_lr:
- case gpr_pc:
- case gpr_cpsr:
- value.SetUInt32 (gpr.r[reg - gpr_r0]);
- break;
-
- case fpu_s0:
- case fpu_s1:
- case fpu_s2:
- case fpu_s3:
- case fpu_s4:
- case fpu_s5:
- case fpu_s6:
- case fpu_s7:
- case fpu_s8:
- case fpu_s9:
- case fpu_s10:
- case fpu_s11:
- case fpu_s12:
- case fpu_s13:
- case fpu_s14:
- case fpu_s15:
- case fpu_s16:
- case fpu_s17:
- case fpu_s18:
- case fpu_s19:
- case fpu_s20:
- case fpu_s21:
- case fpu_s22:
- case fpu_s23:
- case fpu_s24:
- case fpu_s25:
- case fpu_s26:
- case fpu_s27:
- case fpu_s28:
- case fpu_s29:
- case fpu_s30:
- case fpu_s31:
- value.SetUInt32 (fpu.floats.s[reg], RegisterValue::eTypeFloat);
- break;
-
- case fpu_fpscr:
- value.SetUInt32 (fpu.fpscr);
- break;
-
- case exc_exception:
- value.SetUInt32 (exc.exception);
- break;
- case exc_fsr:
- value.SetUInt32 (exc.fsr);
- break;
- case exc_far:
- value.SetUInt32 (exc.far);
- break;
+ if (set == -1)
+ return false;
- default:
- value.SetValueToInvalid();
- return false;
+ if (ReadRegisterSet(set, false) != KERN_SUCCESS)
+ return false;
- }
- return true;
+ switch (reg) {
+ case gpr_r0:
+ case gpr_r1:
+ case gpr_r2:
+ case gpr_r3:
+ case gpr_r4:
+ case gpr_r5:
+ case gpr_r6:
+ case gpr_r7:
+ case gpr_r8:
+ case gpr_r9:
+ case gpr_r10:
+ case gpr_r11:
+ case gpr_r12:
+ case gpr_sp:
+ case gpr_lr:
+ case gpr_pc:
+ case gpr_cpsr:
+ value.SetUInt32(gpr.r[reg - gpr_r0]);
+ break;
+
+ case fpu_s0:
+ case fpu_s1:
+ case fpu_s2:
+ case fpu_s3:
+ case fpu_s4:
+ case fpu_s5:
+ case fpu_s6:
+ case fpu_s7:
+ case fpu_s8:
+ case fpu_s9:
+ case fpu_s10:
+ case fpu_s11:
+ case fpu_s12:
+ case fpu_s13:
+ case fpu_s14:
+ case fpu_s15:
+ case fpu_s16:
+ case fpu_s17:
+ case fpu_s18:
+ case fpu_s19:
+ case fpu_s20:
+ case fpu_s21:
+ case fpu_s22:
+ case fpu_s23:
+ case fpu_s24:
+ case fpu_s25:
+ case fpu_s26:
+ case fpu_s27:
+ case fpu_s28:
+ case fpu_s29:
+ case fpu_s30:
+ case fpu_s31:
+ value.SetUInt32(fpu.floats.s[reg], RegisterValue::eTypeFloat);
+ break;
+
+ case fpu_fpscr:
+ value.SetUInt32(fpu.fpscr);
+ break;
+
+ case exc_exception:
+ value.SetUInt32(exc.exception);
+ break;
+ case exc_fsr:
+ value.SetUInt32(exc.fsr);
+ break;
+ case exc_far:
+ value.SetUInt32(exc.far);
+ break;
+
+ default:
+ value.SetValueToInvalid();
+ return false;
+ }
+ return true;
}
+bool RegisterContextDarwin_arm::WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &value) {
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+ int set = GetSetForNativeRegNum(reg);
-bool
-RegisterContextDarwin_arm::WriteRegister (const RegisterInfo *reg_info,
- const RegisterValue &value)
-{
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- int set = GetSetForNativeRegNum (reg);
-
- if (set == -1)
- return false;
-
- if (ReadRegisterSet(set, false) != KERN_SUCCESS)
- return false;
-
- switch (reg)
- {
- case gpr_r0:
- case gpr_r1:
- case gpr_r2:
- case gpr_r3:
- case gpr_r4:
- case gpr_r5:
- case gpr_r6:
- case gpr_r7:
- case gpr_r8:
- case gpr_r9:
- case gpr_r10:
- case gpr_r11:
- case gpr_r12:
- case gpr_sp:
- case gpr_lr:
- case gpr_pc:
- case gpr_cpsr:
- gpr.r[reg - gpr_r0] = value.GetAsUInt32();
- break;
-
- case fpu_s0:
- case fpu_s1:
- case fpu_s2:
- case fpu_s3:
- case fpu_s4:
- case fpu_s5:
- case fpu_s6:
- case fpu_s7:
- case fpu_s8:
- case fpu_s9:
- case fpu_s10:
- case fpu_s11:
- case fpu_s12:
- case fpu_s13:
- case fpu_s14:
- case fpu_s15:
- case fpu_s16:
- case fpu_s17:
- case fpu_s18:
- case fpu_s19:
- case fpu_s20:
- case fpu_s21:
- case fpu_s22:
- case fpu_s23:
- case fpu_s24:
- case fpu_s25:
- case fpu_s26:
- case fpu_s27:
- case fpu_s28:
- case fpu_s29:
- case fpu_s30:
- case fpu_s31:
- fpu.floats.s[reg] = value.GetAsUInt32();
- break;
-
- case fpu_fpscr:
- fpu.fpscr = value.GetAsUInt32();
- break;
-
- case exc_exception:
- exc.exception = value.GetAsUInt32();
- break;
- case exc_fsr:
- exc.fsr = value.GetAsUInt32();
- break;
- case exc_far:
- exc.far = value.GetAsUInt32();
- break;
+ if (set == -1)
+ return false;
- default:
- return false;
+ if (ReadRegisterSet(set, false) != KERN_SUCCESS)
+ return false;
- }
- return WriteRegisterSet(set) == KERN_SUCCESS;
+ switch (reg) {
+ case gpr_r0:
+ case gpr_r1:
+ case gpr_r2:
+ case gpr_r3:
+ case gpr_r4:
+ case gpr_r5:
+ case gpr_r6:
+ case gpr_r7:
+ case gpr_r8:
+ case gpr_r9:
+ case gpr_r10:
+ case gpr_r11:
+ case gpr_r12:
+ case gpr_sp:
+ case gpr_lr:
+ case gpr_pc:
+ case gpr_cpsr:
+ gpr.r[reg - gpr_r0] = value.GetAsUInt32();
+ break;
+
+ case fpu_s0:
+ case fpu_s1:
+ case fpu_s2:
+ case fpu_s3:
+ case fpu_s4:
+ case fpu_s5:
+ case fpu_s6:
+ case fpu_s7:
+ case fpu_s8:
+ case fpu_s9:
+ case fpu_s10:
+ case fpu_s11:
+ case fpu_s12:
+ case fpu_s13:
+ case fpu_s14:
+ case fpu_s15:
+ case fpu_s16:
+ case fpu_s17:
+ case fpu_s18:
+ case fpu_s19:
+ case fpu_s20:
+ case fpu_s21:
+ case fpu_s22:
+ case fpu_s23:
+ case fpu_s24:
+ case fpu_s25:
+ case fpu_s26:
+ case fpu_s27:
+ case fpu_s28:
+ case fpu_s29:
+ case fpu_s30:
+ case fpu_s31:
+ fpu.floats.s[reg] = value.GetAsUInt32();
+ break;
+
+ case fpu_fpscr:
+ fpu.fpscr = value.GetAsUInt32();
+ break;
+
+ case exc_exception:
+ exc.exception = value.GetAsUInt32();
+ break;
+ case exc_fsr:
+ exc.fsr = value.GetAsUInt32();
+ break;
+ case exc_far:
+ exc.far = value.GetAsUInt32();
+ break;
+
+ default:
+ return false;
+ }
+ return WriteRegisterSet(set) == KERN_SUCCESS;
}
-bool
-RegisterContextDarwin_arm::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
-{
- data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
- if (data_sp &&
- ReadGPR (false) == KERN_SUCCESS &&
- ReadFPU (false) == KERN_SUCCESS &&
- ReadEXC (false) == KERN_SUCCESS)
- {
- uint8_t *dst = data_sp->GetBytes();
- ::memcpy (dst, &gpr, sizeof(gpr));
- dst += sizeof(gpr);
+bool RegisterContextDarwin_arm::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (data_sp && ReadGPR(false) == KERN_SUCCESS &&
+ ReadFPU(false) == KERN_SUCCESS && ReadEXC(false) == KERN_SUCCESS) {
+ uint8_t *dst = data_sp->GetBytes();
+ ::memcpy(dst, &gpr, sizeof(gpr));
+ dst += sizeof(gpr);
- ::memcpy (dst, &fpu, sizeof(fpu));
- dst += sizeof(gpr);
+ ::memcpy(dst, &fpu, sizeof(fpu));
+ dst += sizeof(gpr);
- ::memcpy (dst, &exc, sizeof(exc));
- return true;
- }
- return false;
+ ::memcpy(dst, &exc, sizeof(exc));
+ return true;
+ }
+ return false;
}
-bool
-RegisterContextDarwin_arm::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
-{
- if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE)
- {
- const uint8_t *src = data_sp->GetBytes();
- ::memcpy (&gpr, src, sizeof(gpr));
- src += sizeof(gpr);
-
- ::memcpy (&fpu, src, sizeof(fpu));
- src += sizeof(gpr);
-
- ::memcpy (&exc, src, sizeof(exc));
- uint32_t success_count = 0;
- if (WriteGPR() == KERN_SUCCESS)
- ++success_count;
- if (WriteFPU() == KERN_SUCCESS)
- ++success_count;
- if (WriteEXC() == KERN_SUCCESS)
- ++success_count;
- return success_count == 3;
- }
- return false;
+bool RegisterContextDarwin_arm::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
+ const uint8_t *src = data_sp->GetBytes();
+ ::memcpy(&gpr, src, sizeof(gpr));
+ src += sizeof(gpr);
+
+ ::memcpy(&fpu, src, sizeof(fpu));
+ src += sizeof(gpr);
+
+ ::memcpy(&exc, src, sizeof(exc));
+ uint32_t success_count = 0;
+ if (WriteGPR() == KERN_SUCCESS)
+ ++success_count;
+ if (WriteFPU() == KERN_SUCCESS)
+ ++success_count;
+ if (WriteEXC() == KERN_SUCCESS)
+ ++success_count;
+ return success_count == 3;
+ }
+ return false;
}
-uint32_t
-RegisterContextDarwin_arm::ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t reg)
-{
- if (kind == eRegisterKindGeneric)
- {
- switch (reg)
- {
- case LLDB_REGNUM_GENERIC_PC: return gpr_pc;
- case LLDB_REGNUM_GENERIC_SP: return gpr_sp;
- case LLDB_REGNUM_GENERIC_FP: return gpr_r7;
- case LLDB_REGNUM_GENERIC_RA: return gpr_lr;
- case LLDB_REGNUM_GENERIC_FLAGS: return gpr_cpsr;
- default:
- break;
- }
- }
- else if (kind == eRegisterKindDWARF)
- {
- switch (reg)
- {
- case dwarf_r0: return gpr_r0;
- case dwarf_r1: return gpr_r1;
- case dwarf_r2: return gpr_r2;
- case dwarf_r3: return gpr_r3;
- case dwarf_r4: return gpr_r4;
- case dwarf_r5: return gpr_r5;
- case dwarf_r6: return gpr_r6;
- case dwarf_r7: return gpr_r7;
- case dwarf_r8: return gpr_r8;
- case dwarf_r9: return gpr_r9;
- case dwarf_r10: return gpr_r10;
- case dwarf_r11: return gpr_r11;
- case dwarf_r12: return gpr_r12;
- case dwarf_sp: return gpr_sp;
- case dwarf_lr: return gpr_lr;
- case dwarf_pc: return gpr_pc;
- case dwarf_spsr: return gpr_cpsr;
-
- case dwarf_s0: return fpu_s0;
- case dwarf_s1: return fpu_s1;
- case dwarf_s2: return fpu_s2;
- case dwarf_s3: return fpu_s3;
- case dwarf_s4: return fpu_s4;
- case dwarf_s5: return fpu_s5;
- case dwarf_s6: return fpu_s6;
- case dwarf_s7: return fpu_s7;
- case dwarf_s8: return fpu_s8;
- case dwarf_s9: return fpu_s9;
- case dwarf_s10: return fpu_s10;
- case dwarf_s11: return fpu_s11;
- case dwarf_s12: return fpu_s12;
- case dwarf_s13: return fpu_s13;
- case dwarf_s14: return fpu_s14;
- case dwarf_s15: return fpu_s15;
- case dwarf_s16: return fpu_s16;
- case dwarf_s17: return fpu_s17;
- case dwarf_s18: return fpu_s18;
- case dwarf_s19: return fpu_s19;
- case dwarf_s20: return fpu_s20;
- case dwarf_s21: return fpu_s21;
- case dwarf_s22: return fpu_s22;
- case dwarf_s23: return fpu_s23;
- case dwarf_s24: return fpu_s24;
- case dwarf_s25: return fpu_s25;
- case dwarf_s26: return fpu_s26;
- case dwarf_s27: return fpu_s27;
- case dwarf_s28: return fpu_s28;
- case dwarf_s29: return fpu_s29;
- case dwarf_s30: return fpu_s30;
- case dwarf_s31: return fpu_s31;
-
- default:
- break;
- }
+uint32_t RegisterContextDarwin_arm::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t reg) {
+ if (kind == eRegisterKindGeneric) {
+ switch (reg) {
+ case LLDB_REGNUM_GENERIC_PC:
+ return gpr_pc;
+ case LLDB_REGNUM_GENERIC_SP:
+ return gpr_sp;
+ case LLDB_REGNUM_GENERIC_FP:
+ return gpr_r7;
+ case LLDB_REGNUM_GENERIC_RA:
+ return gpr_lr;
+ case LLDB_REGNUM_GENERIC_FLAGS:
+ return gpr_cpsr;
+ default:
+ break;
}
- else if (kind == eRegisterKindEHFrame)
- {
- switch (reg)
- {
- case ehframe_r0: return gpr_r0;
- case ehframe_r1: return gpr_r1;
- case ehframe_r2: return gpr_r2;
- case ehframe_r3: return gpr_r3;
- case ehframe_r4: return gpr_r4;
- case ehframe_r5: return gpr_r5;
- case ehframe_r6: return gpr_r6;
- case ehframe_r7: return gpr_r7;
- case ehframe_r8: return gpr_r8;
- case ehframe_r9: return gpr_r9;
- case ehframe_r10: return gpr_r10;
- case ehframe_r11: return gpr_r11;
- case ehframe_r12: return gpr_r12;
- case ehframe_sp: return gpr_sp;
- case ehframe_lr: return gpr_lr;
- case ehframe_pc: return gpr_pc;
- case ehframe_cpsr: return gpr_cpsr;
- }
+ } else if (kind == eRegisterKindDWARF) {
+ switch (reg) {
+ case dwarf_r0:
+ return gpr_r0;
+ case dwarf_r1:
+ return gpr_r1;
+ case dwarf_r2:
+ return gpr_r2;
+ case dwarf_r3:
+ return gpr_r3;
+ case dwarf_r4:
+ return gpr_r4;
+ case dwarf_r5:
+ return gpr_r5;
+ case dwarf_r6:
+ return gpr_r6;
+ case dwarf_r7:
+ return gpr_r7;
+ case dwarf_r8:
+ return gpr_r8;
+ case dwarf_r9:
+ return gpr_r9;
+ case dwarf_r10:
+ return gpr_r10;
+ case dwarf_r11:
+ return gpr_r11;
+ case dwarf_r12:
+ return gpr_r12;
+ case dwarf_sp:
+ return gpr_sp;
+ case dwarf_lr:
+ return gpr_lr;
+ case dwarf_pc:
+ return gpr_pc;
+ case dwarf_spsr:
+ return gpr_cpsr;
+
+ case dwarf_s0:
+ return fpu_s0;
+ case dwarf_s1:
+ return fpu_s1;
+ case dwarf_s2:
+ return fpu_s2;
+ case dwarf_s3:
+ return fpu_s3;
+ case dwarf_s4:
+ return fpu_s4;
+ case dwarf_s5:
+ return fpu_s5;
+ case dwarf_s6:
+ return fpu_s6;
+ case dwarf_s7:
+ return fpu_s7;
+ case dwarf_s8:
+ return fpu_s8;
+ case dwarf_s9:
+ return fpu_s9;
+ case dwarf_s10:
+ return fpu_s10;
+ case dwarf_s11:
+ return fpu_s11;
+ case dwarf_s12:
+ return fpu_s12;
+ case dwarf_s13:
+ return fpu_s13;
+ case dwarf_s14:
+ return fpu_s14;
+ case dwarf_s15:
+ return fpu_s15;
+ case dwarf_s16:
+ return fpu_s16;
+ case dwarf_s17:
+ return fpu_s17;
+ case dwarf_s18:
+ return fpu_s18;
+ case dwarf_s19:
+ return fpu_s19;
+ case dwarf_s20:
+ return fpu_s20;
+ case dwarf_s21:
+ return fpu_s21;
+ case dwarf_s22:
+ return fpu_s22;
+ case dwarf_s23:
+ return fpu_s23;
+ case dwarf_s24:
+ return fpu_s24;
+ case dwarf_s25:
+ return fpu_s25;
+ case dwarf_s26:
+ return fpu_s26;
+ case dwarf_s27:
+ return fpu_s27;
+ case dwarf_s28:
+ return fpu_s28;
+ case dwarf_s29:
+ return fpu_s29;
+ case dwarf_s30:
+ return fpu_s30;
+ case dwarf_s31:
+ return fpu_s31;
+
+ default:
+ break;
}
- else if (kind == eRegisterKindLLDB)
- {
- return reg;
+ } else if (kind == eRegisterKindEHFrame) {
+ switch (reg) {
+ case ehframe_r0:
+ return gpr_r0;
+ case ehframe_r1:
+ return gpr_r1;
+ case ehframe_r2:
+ return gpr_r2;
+ case ehframe_r3:
+ return gpr_r3;
+ case ehframe_r4:
+ return gpr_r4;
+ case ehframe_r5:
+ return gpr_r5;
+ case ehframe_r6:
+ return gpr_r6;
+ case ehframe_r7:
+ return gpr_r7;
+ case ehframe_r8:
+ return gpr_r8;
+ case ehframe_r9:
+ return gpr_r9;
+ case ehframe_r10:
+ return gpr_r10;
+ case ehframe_r11:
+ return gpr_r11;
+ case ehframe_r12:
+ return gpr_r12;
+ case ehframe_sp:
+ return gpr_sp;
+ case ehframe_lr:
+ return gpr_lr;
+ case ehframe_pc:
+ return gpr_pc;
+ case ehframe_cpsr:
+ return gpr_cpsr;
}
- return LLDB_INVALID_REGNUM;
+ } else if (kind == eRegisterKindLLDB) {
+ return reg;
+ }
+ return LLDB_INVALID_REGNUM;
}
-
-uint32_t
-RegisterContextDarwin_arm::NumSupportedHardwareBreakpoints ()
-{
-#if defined (__arm__)
- // Set the init value to something that will let us know that we need to
- // autodetect how many breakpoints are supported dynamically...
- static uint32_t g_num_supported_hw_breakpoints = UINT32_MAX;
- if (g_num_supported_hw_breakpoints == UINT32_MAX)
- {
- // Set this to zero in case we can't tell if there are any HW breakpoints
- g_num_supported_hw_breakpoints = 0;
-
- uint32_t register_DBGDIDR;
-
- asm("mrc p14, 0, %0, c0, c0, 0" : "=r" (register_DBGDIDR));
- g_num_supported_hw_breakpoints = Bits32 (register_DBGDIDR, 27, 24);
- // Zero is reserved for the BRP count, so don't increment it if it is zero
- if (g_num_supported_hw_breakpoints > 0)
- g_num_supported_hw_breakpoints++;
-// if (log) log->Printf ("DBGDIDR=0x%8.8x (number BRP pairs = %u)", register_DBGDIDR, g_num_supported_hw_breakpoints);
-
- }
- return g_num_supported_hw_breakpoints;
+uint32_t RegisterContextDarwin_arm::NumSupportedHardwareBreakpoints() {
+#if defined(__arm__)
+ // Set the init value to something that will let us know that we need to
+ // autodetect how many breakpoints are supported dynamically...
+ static uint32_t g_num_supported_hw_breakpoints = UINT32_MAX;
+ if (g_num_supported_hw_breakpoints == UINT32_MAX) {
+ // Set this to zero in case we can't tell if there are any HW breakpoints
+ g_num_supported_hw_breakpoints = 0;
+
+ uint32_t register_DBGDIDR;
+
+ asm("mrc p14, 0, %0, c0, c0, 0" : "=r"(register_DBGDIDR));
+ g_num_supported_hw_breakpoints = Bits32(register_DBGDIDR, 27, 24);
+ // Zero is reserved for the BRP count, so don't increment it if it is zero
+ if (g_num_supported_hw_breakpoints > 0)
+ g_num_supported_hw_breakpoints++;
+ // if (log) log->Printf ("DBGDIDR=0x%8.8x (number BRP pairs = %u)",
+ // register_DBGDIDR, g_num_supported_hw_breakpoints);
+ }
+ return g_num_supported_hw_breakpoints;
#else
- // TODO: figure out remote case here!
- return 6;
+ // TODO: figure out remote case here!
+ return 6;
#endif
}
-uint32_t
-RegisterContextDarwin_arm::SetHardwareBreakpoint (lldb::addr_t addr, size_t size)
-{
- // Make sure our address isn't bogus
- if (addr & 1)
- return LLDB_INVALID_INDEX32;
+uint32_t RegisterContextDarwin_arm::SetHardwareBreakpoint(lldb::addr_t addr,
+ size_t size) {
+ // Make sure our address isn't bogus
+ if (addr & 1)
+ return LLDB_INVALID_INDEX32;
- int kret = ReadDBG (false);
+ int kret = ReadDBG(false);
- if (kret == KERN_SUCCESS)
- {
- const uint32_t num_hw_breakpoints = NumSupportedHardwareBreakpoints();
- uint32_t i;
- for (i=0; i<num_hw_breakpoints; ++i)
- {
- if ((dbg.bcr[i] & BCR_ENABLE) == 0)
- break; // We found an available hw breakpoint slot (in i)
- }
-
- // See if we found an available hw breakpoint slot above
- if (i < num_hw_breakpoints)
- {
- // Make sure bits 1:0 are clear in our address
- dbg.bvr[i] = addr & ~((lldb::addr_t)3);
-
- if (size == 2 || addr & 2)
- {
- uint32_t byte_addr_select = (addr & 2) ? BAS_IMVA_2_3 : BAS_IMVA_0_1;
-
- // We have a thumb breakpoint
- // We have an ARM breakpoint
- dbg.bcr[i] = BCR_M_IMVA_MATCH | // Stop on address mismatch
- byte_addr_select | // Set the correct byte address select so we only trigger on the correct opcode
- S_USER | // Which modes should this breakpoint stop in?
- BCR_ENABLE; // Enable this hardware breakpoint
-// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareBreakpoint( addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x / 0x%8.8x (Thumb)",
-// addr,
-// size,
-// i,
-// i,
-// dbg.bvr[i],
-// dbg.bcr[i]);
- }
- else if (size == 4)
- {
- // We have an ARM breakpoint
- dbg.bcr[i] = BCR_M_IMVA_MATCH | // Stop on address mismatch
- BAS_IMVA_ALL | // Stop on any of the four bytes following the IMVA
- S_USER | // Which modes should this breakpoint stop in?
- BCR_ENABLE; // Enable this hardware breakpoint
-// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareBreakpoint( addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x / 0x%8.8x (ARM)",
-// addr,
-// size,
-// i,
-// i,
-// dbg.bvr[i],
-// dbg.bcr[i]);
- }
-
- kret = WriteDBG();
-// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareBreakpoint() WriteDBG() => 0x%8.8x.", kret);
-
- if (kret == KERN_SUCCESS)
- return i;
- }
-// else
-// {
-// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(addr = %8.8p, size = %u) => all hardware breakpoint resources are being used.", addr, size);
-// }
+ if (kret == KERN_SUCCESS) {
+ const uint32_t num_hw_breakpoints = NumSupportedHardwareBreakpoints();
+ uint32_t i;
+ for (i = 0; i < num_hw_breakpoints; ++i) {
+ if ((dbg.bcr[i] & BCR_ENABLE) == 0)
+ break; // We found an available hw breakpoint slot (in i)
}
- return LLDB_INVALID_INDEX32;
+ // See if we found an available hw breakpoint slot above
+ if (i < num_hw_breakpoints) {
+ // Make sure bits 1:0 are clear in our address
+ dbg.bvr[i] = addr & ~((lldb::addr_t)3);
+
+ if (size == 2 || addr & 2) {
+ uint32_t byte_addr_select = (addr & 2) ? BAS_IMVA_2_3 : BAS_IMVA_0_1;
+
+ // We have a thumb breakpoint
+ // We have an ARM breakpoint
+ dbg.bcr[i] = BCR_M_IMVA_MATCH | // Stop on address mismatch
+ byte_addr_select | // Set the correct byte address select
+ // so we only trigger on the correct
+ // opcode
+ S_USER | // Which modes should this breakpoint stop in?
+ BCR_ENABLE; // Enable this hardware breakpoint
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(
+ // addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x /
+ // 0x%8.8x (Thumb)",
+ // addr,
+ // size,
+ // i,
+ // i,
+ // dbg.bvr[i],
+ // dbg.bcr[i]);
+ } else if (size == 4) {
+ // We have an ARM breakpoint
+ dbg.bcr[i] =
+ BCR_M_IMVA_MATCH | // Stop on address mismatch
+ BAS_IMVA_ALL | // Stop on any of the four bytes following the IMVA
+ S_USER | // Which modes should this breakpoint stop in?
+ BCR_ENABLE; // Enable this hardware breakpoint
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(
+ // addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x /
+ // 0x%8.8x (ARM)",
+ // addr,
+ // size,
+ // i,
+ // i,
+ // dbg.bvr[i],
+ // dbg.bcr[i]);
+ }
+
+ kret = WriteDBG();
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm::EnableHardwareBreakpoint()
+ // WriteDBG() => 0x%8.8x.", kret);
+
+ if (kret == KERN_SUCCESS)
+ return i;
+ }
+ // else
+ // {
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(addr =
+ // %8.8p, size = %u) => all hardware breakpoint resources are
+ // being used.", addr, size);
+ // }
+ }
+
+ return LLDB_INVALID_INDEX32;
}
-bool
-RegisterContextDarwin_arm::ClearHardwareBreakpoint (uint32_t hw_index)
-{
- int kret = ReadDBG (false);
-
- const uint32_t num_hw_points = NumSupportedHardwareBreakpoints();
- if (kret == KERN_SUCCESS)
- {
- if (hw_index < num_hw_points)
- {
- dbg.bcr[hw_index] = 0;
-// if (log) log->Printf ("RegisterContextDarwin_arm::SetHardwareBreakpoint( %u ) - BVR%u = 0x%8.8x BCR%u = 0x%8.8x",
-// hw_index,
-// hw_index,
-// dbg.bvr[hw_index],
-// hw_index,
-// dbg.bcr[hw_index]);
-
- kret = WriteDBG();
-
- if (kret == KERN_SUCCESS)
- return true;
- }
+bool RegisterContextDarwin_arm::ClearHardwareBreakpoint(uint32_t hw_index) {
+ int kret = ReadDBG(false);
+
+ const uint32_t num_hw_points = NumSupportedHardwareBreakpoints();
+ if (kret == KERN_SUCCESS) {
+ if (hw_index < num_hw_points) {
+ dbg.bcr[hw_index] = 0;
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm::SetHardwareBreakpoint( %u ) -
+ // BVR%u = 0x%8.8x BCR%u = 0x%8.8x",
+ // hw_index,
+ // hw_index,
+ // dbg.bvr[hw_index],
+ // hw_index,
+ // dbg.bcr[hw_index]);
+
+ kret = WriteDBG();
+
+ if (kret == KERN_SUCCESS)
+ return true;
}
- return false;
+ }
+ return false;
}
-uint32_t
-RegisterContextDarwin_arm::NumSupportedHardwareWatchpoints ()
-{
-#if defined (__arm__)
- // Set the init value to something that will let us know that we need to
- // autodetect how many watchpoints are supported dynamically...
- static uint32_t g_num_supported_hw_watchpoints = UINT32_MAX;
- if (g_num_supported_hw_watchpoints == UINT32_MAX)
- {
- // Set this to zero in case we can't tell if there are any HW breakpoints
- g_num_supported_hw_watchpoints = 0;
-
- uint32_t register_DBGDIDR;
- asm("mrc p14, 0, %0, c0, c0, 0" : "=r" (register_DBGDIDR));
- g_num_supported_hw_watchpoints = Bits32 (register_DBGDIDR, 31, 28) + 1;
-// if (log) log->Printf ("DBGDIDR=0x%8.8x (number WRP pairs = %u)", register_DBGDIDR, g_num_supported_hw_watchpoints);
- }
- return g_num_supported_hw_watchpoints;
+uint32_t RegisterContextDarwin_arm::NumSupportedHardwareWatchpoints() {
+#if defined(__arm__)
+ // Set the init value to something that will let us know that we need to
+ // autodetect how many watchpoints are supported dynamically...
+ static uint32_t g_num_supported_hw_watchpoints = UINT32_MAX;
+ if (g_num_supported_hw_watchpoints == UINT32_MAX) {
+ // Set this to zero in case we can't tell if there are any HW breakpoints
+ g_num_supported_hw_watchpoints = 0;
+
+ uint32_t register_DBGDIDR;
+ asm("mrc p14, 0, %0, c0, c0, 0" : "=r"(register_DBGDIDR));
+ g_num_supported_hw_watchpoints = Bits32(register_DBGDIDR, 31, 28) + 1;
+ // if (log) log->Printf ("DBGDIDR=0x%8.8x (number WRP pairs = %u)",
+ // register_DBGDIDR, g_num_supported_hw_watchpoints);
+ }
+ return g_num_supported_hw_watchpoints;
#else
- // TODO: figure out remote case here!
- return 2;
+ // TODO: figure out remote case here!
+ return 2;
#endif
}
+uint32_t RegisterContextDarwin_arm::SetHardwareWatchpoint(lldb::addr_t addr,
+ size_t size,
+ bool read,
+ bool write) {
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint(addr = %8.8p, size
+ // = %u, read = %u, write = %u)", addr, size, read, write);
-uint32_t
-RegisterContextDarwin_arm::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write)
-{
-// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint(addr = %8.8p, size = %u, read = %u, write = %u)", addr, size, read, write);
+ const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
- const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
+ // Can't watch zero bytes
+ if (size == 0)
+ return LLDB_INVALID_INDEX32;
- // Can't watch zero bytes
- if (size == 0)
- return LLDB_INVALID_INDEX32;
+ // We must watch for either read or write
+ if (read == false && write == false)
+ return LLDB_INVALID_INDEX32;
- // We must watch for either read or write
- if (read == false && write == false)
- return LLDB_INVALID_INDEX32;
+ // Can't watch more than 4 bytes per WVR/WCR pair
+ if (size > 4)
+ return LLDB_INVALID_INDEX32;
- // Can't watch more than 4 bytes per WVR/WCR pair
- if (size > 4)
- return LLDB_INVALID_INDEX32;
+ // We can only watch up to four bytes that follow a 4 byte aligned address
+ // per watchpoint register pair. Since we have at most so we can only watch
+ // until the next 4 byte boundary and we need to make sure we can properly
+ // encode this.
+ uint32_t addr_word_offset = addr % 4;
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() -
+ // addr_word_offset = 0x%8.8x", addr_word_offset);
+
+ uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset;
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() - byte_mask =
+ // 0x%8.8x", byte_mask);
+ if (byte_mask > 0xfu)
+ return LLDB_INVALID_INDEX32;
- // We can only watch up to four bytes that follow a 4 byte aligned address
- // per watchpoint register pair. Since we have at most so we can only watch
- // until the next 4 byte boundary and we need to make sure we can properly
- // encode this.
- uint32_t addr_word_offset = addr % 4;
-// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() - addr_word_offset = 0x%8.8x", addr_word_offset);
+ // Read the debug state
+ int kret = ReadDBG(false);
- uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset;
-// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() - byte_mask = 0x%8.8x", byte_mask);
- if (byte_mask > 0xfu)
- return LLDB_INVALID_INDEX32;
+ if (kret == KERN_SUCCESS) {
+ // Check to make sure we have the needed hardware support
+ uint32_t i = 0;
- // Read the debug state
- int kret = ReadDBG (false);
+ for (i = 0; i < num_hw_watchpoints; ++i) {
+ if ((dbg.wcr[i] & WCR_ENABLE) == 0)
+ break; // We found an available hw breakpoint slot (in i)
+ }
- if (kret == KERN_SUCCESS)
- {
- // Check to make sure we have the needed hardware support
- uint32_t i = 0;
-
- for (i=0; i<num_hw_watchpoints; ++i)
- {
- if ((dbg.wcr[i] & WCR_ENABLE) == 0)
- break; // We found an available hw breakpoint slot (in i)
- }
-
- // See if we found an available hw breakpoint slot above
- if (i < num_hw_watchpoints)
- {
- // Make the byte_mask into a valid Byte Address Select mask
- uint32_t byte_address_select = byte_mask << 5;
- // Make sure bits 1:0 are clear in our address
- dbg.wvr[i] = addr & ~((lldb::addr_t)3);
- dbg.wcr[i] = byte_address_select | // Which bytes that follow the IMVA that we will watch
- S_USER | // Stop only in user mode
- (read ? WCR_LOAD : 0) | // Stop on read access?
- (write ? WCR_STORE : 0) | // Stop on write access?
- WCR_ENABLE; // Enable this watchpoint;
-
- kret = WriteDBG();
-// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() WriteDBG() => 0x%8.8x.", kret);
-
- if (kret == KERN_SUCCESS)
- return i;
- }
- else
- {
-// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint(): All hardware resources (%u) are in use.", num_hw_watchpoints);
- }
+ // See if we found an available hw breakpoint slot above
+ if (i < num_hw_watchpoints) {
+ // Make the byte_mask into a valid Byte Address Select mask
+ uint32_t byte_address_select = byte_mask << 5;
+ // Make sure bits 1:0 are clear in our address
+ dbg.wvr[i] = addr & ~((lldb::addr_t)3);
+ dbg.wcr[i] = byte_address_select | // Which bytes that follow the IMVA
+ // that we will watch
+ S_USER | // Stop only in user mode
+ (read ? WCR_LOAD : 0) | // Stop on read access?
+ (write ? WCR_STORE : 0) | // Stop on write access?
+ WCR_ENABLE; // Enable this watchpoint;
+
+ kret = WriteDBG();
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint()
+ // WriteDBG() => 0x%8.8x.", kret);
+
+ if (kret == KERN_SUCCESS)
+ return i;
+ } else {
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint(): All
+ // hardware resources (%u) are in use.", num_hw_watchpoints);
}
- return LLDB_INVALID_INDEX32;
+ }
+ return LLDB_INVALID_INDEX32;
}
-bool
-RegisterContextDarwin_arm::ClearHardwareWatchpoint (uint32_t hw_index)
-{
- int kret = ReadDBG (false);
-
- const uint32_t num_hw_points = NumSupportedHardwareWatchpoints();
- if (kret == KERN_SUCCESS)
- {
- if (hw_index < num_hw_points)
- {
- dbg.wcr[hw_index] = 0;
-// if (log) log->Printf ("RegisterContextDarwin_arm::ClearHardwareWatchpoint( %u ) - WVR%u = 0x%8.8x WCR%u = 0x%8.8x",
-// hw_index,
-// hw_index,
-// dbg.wvr[hw_index],
-// hw_index,
-// dbg.wcr[hw_index]);
-
- kret = WriteDBG();
-
- if (kret == KERN_SUCCESS)
- return true;
- }
+bool RegisterContextDarwin_arm::ClearHardwareWatchpoint(uint32_t hw_index) {
+ int kret = ReadDBG(false);
+
+ const uint32_t num_hw_points = NumSupportedHardwareWatchpoints();
+ if (kret == KERN_SUCCESS) {
+ if (hw_index < num_hw_points) {
+ dbg.wcr[hw_index] = 0;
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm::ClearHardwareWatchpoint( %u ) -
+ // WVR%u = 0x%8.8x WCR%u = 0x%8.8x",
+ // hw_index,
+ // hw_index,
+ // dbg.wvr[hw_index],
+ // hw_index,
+ // dbg.wcr[hw_index]);
+
+ kret = WriteDBG();
+
+ if (kret == KERN_SUCCESS)
+ return true;
}
- return false;
+ }
+ return false;
}
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h b/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h
index 4e831b5a8da7..cdf3479dff69 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h
@@ -14,317 +14,256 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/lldb-private.h"
// BCR address match type
-#define BCR_M_IMVA_MATCH ((uint32_t)(0u << 21))
-#define BCR_M_CONTEXT_ID_MATCH ((uint32_t)(1u << 21))
-#define BCR_M_IMVA_MISMATCH ((uint32_t)(2u << 21))
-#define BCR_M_RESERVED ((uint32_t)(3u << 21))
+#define BCR_M_IMVA_MATCH ((uint32_t)(0u << 21))
+#define BCR_M_CONTEXT_ID_MATCH ((uint32_t)(1u << 21))
+#define BCR_M_IMVA_MISMATCH ((uint32_t)(2u << 21))
+#define BCR_M_RESERVED ((uint32_t)(3u << 21))
// Link a BVR/BCR or WVR/WCR pair to another
-#define E_ENABLE_LINKING ((uint32_t)(1u << 20))
+#define E_ENABLE_LINKING ((uint32_t)(1u << 20))
// Byte Address Select
-#define BAS_IMVA_PLUS_0 ((uint32_t)(1u << 5))
-#define BAS_IMVA_PLUS_1 ((uint32_t)(1u << 6))
-#define BAS_IMVA_PLUS_2 ((uint32_t)(1u << 7))
-#define BAS_IMVA_PLUS_3 ((uint32_t)(1u << 8))
-#define BAS_IMVA_0_1 ((uint32_t)(3u << 5))
-#define BAS_IMVA_2_3 ((uint32_t)(3u << 7))
-#define BAS_IMVA_ALL ((uint32_t)(0xfu << 5))
+#define BAS_IMVA_PLUS_0 ((uint32_t)(1u << 5))
+#define BAS_IMVA_PLUS_1 ((uint32_t)(1u << 6))
+#define BAS_IMVA_PLUS_2 ((uint32_t)(1u << 7))
+#define BAS_IMVA_PLUS_3 ((uint32_t)(1u << 8))
+#define BAS_IMVA_0_1 ((uint32_t)(3u << 5))
+#define BAS_IMVA_2_3 ((uint32_t)(3u << 7))
+#define BAS_IMVA_ALL ((uint32_t)(0xfu << 5))
// Break only in privileged or user mode
-#define S_RSVD ((uint32_t)(0u << 1))
-#define S_PRIV ((uint32_t)(1u << 1))
-#define S_USER ((uint32_t)(2u << 1))
-#define S_PRIV_USER ((S_PRIV) | (S_USER))
+#define S_RSVD ((uint32_t)(0u << 1))
+#define S_PRIV ((uint32_t)(1u << 1))
+#define S_USER ((uint32_t)(2u << 1))
+#define S_PRIV_USER ((S_PRIV) | (S_USER))
-#define BCR_ENABLE ((uint32_t)(1u))
-#define WCR_ENABLE ((uint32_t)(1u))
+#define BCR_ENABLE ((uint32_t)(1u))
+#define WCR_ENABLE ((uint32_t)(1u))
// Watchpoint load/store
-#define WCR_LOAD ((uint32_t)(1u << 3))
-#define WCR_STORE ((uint32_t)(1u << 4))
+#define WCR_LOAD ((uint32_t)(1u << 3))
+#define WCR_STORE ((uint32_t)(1u << 4))
-class RegisterContextDarwin_arm : public lldb_private::RegisterContext
-{
+class RegisterContextDarwin_arm : public lldb_private::RegisterContext {
public:
- RegisterContextDarwin_arm(lldb_private::Thread &thread, uint32_t concrete_frame_idx);
+ RegisterContextDarwin_arm(lldb_private::Thread &thread,
+ uint32_t concrete_frame_idx);
- ~RegisterContextDarwin_arm() override;
+ ~RegisterContextDarwin_arm() override;
- void
- InvalidateAllRegisters() override;
+ void InvalidateAllRegisters() override;
- size_t
- GetRegisterCount() override;
+ size_t GetRegisterCount() override;
- const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex(size_t reg) override;
+ const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
- size_t
- GetRegisterSetCount() override;
+ size_t GetRegisterSetCount() override;
- const lldb_private::RegisterSet *
- GetRegisterSet(size_t set) override;
+ const lldb_private::RegisterSet *GetRegisterSet(size_t set) override;
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &reg_value) override;
-
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &reg_value) override;
-
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &reg_value) override;
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &reg_value) override;
- uint32_t
- ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
- uint32_t
- NumSupportedHardwareBreakpoints() override;
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- uint32_t
- SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override;
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
- bool
- ClearHardwareBreakpoint(uint32_t hw_idx) override;
+ uint32_t NumSupportedHardwareBreakpoints() override;
- uint32_t
- NumSupportedHardwareWatchpoints() override;
+ uint32_t SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override;
- uint32_t
- SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write) override;
+ bool ClearHardwareBreakpoint(uint32_t hw_idx) override;
- bool
- ClearHardwareWatchpoint(uint32_t hw_index) override;
+ uint32_t NumSupportedHardwareWatchpoints() override;
- struct GPR
- {
- uint32_t r[16]; // R0-R15
- uint32_t cpsr; // CPSR
- };
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read,
+ bool write) override;
- struct QReg
- {
- uint8_t bytes[16];
- };
+ bool ClearHardwareWatchpoint(uint32_t hw_index) override;
- struct FPU
- {
- union {
- uint32_t s[32];
- uint64_t d[32];
- QReg q[16]; // the 128-bit NEON registers
- } floats;
- uint32_t fpscr;
- };
+ struct GPR {
+ uint32_t r[16]; // R0-R15
+ uint32_t cpsr; // CPSR
+ };
-// struct NeonReg
-// {
-// uint8_t bytes[16];
-// };
-//
-// struct VFPv3
-// {
-// union {
-// uint32_t s[32];
-// uint64_t d[32];
-// NeonReg q[16];
-// } v3;
-// uint32_t fpscr;
-// };
-
- struct EXC
- {
- uint32_t exception;
- uint32_t fsr; /* Fault status */
- uint32_t far; /* Virtual Fault Address */
- };
-
- struct DBG
- {
- uint32_t bvr[16];
- uint32_t bcr[16];
- uint32_t wvr[16];
- uint32_t wcr[16];
- };
-
- static void
- LogDBGRegisters (lldb_private::Log *log, const DBG& dbg);
+ struct QReg {
+ uint8_t bytes[16];
+ };
+
+ struct FPU {
+ union {
+ uint32_t s[32];
+ uint64_t d[32];
+ QReg q[16]; // the 128-bit NEON registers
+ } floats;
+ uint32_t fpscr;
+ };
+
+ // struct NeonReg
+ // {
+ // uint8_t bytes[16];
+ // };
+ //
+ // struct VFPv3
+ // {
+ // union {
+ // uint32_t s[32];
+ // uint64_t d[32];
+ // NeonReg q[16];
+ // } v3;
+ // uint32_t fpscr;
+ // };
+
+ struct EXC {
+ uint32_t exception;
+ uint32_t fsr; /* Fault status */
+ uint32_t far; /* Virtual Fault Address */
+ };
+
+ struct DBG {
+ uint32_t bvr[16];
+ uint32_t bcr[16];
+ uint32_t wvr[16];
+ uint32_t wcr[16];
+ };
+
+ static void LogDBGRegisters(lldb_private::Log *log, const DBG &dbg);
protected:
- enum
- {
- GPRRegSet = 1, // ARM_THREAD_STATE
- GPRAltRegSet = 9, // ARM_THREAD_STATE32
- FPURegSet = 2, // ARM_VFP_STATE
- EXCRegSet = 3, // ARM_EXCEPTION_STATE
- DBGRegSet = 4 // ARM_DEBUG_STATE
- };
-
- enum
- {
- GPRWordCount = sizeof(GPR)/sizeof(uint32_t),
- FPUWordCount = sizeof(FPU)/sizeof(uint32_t),
- EXCWordCount = sizeof(EXC)/sizeof(uint32_t),
- DBGWordCount = sizeof(DBG)/sizeof(uint32_t)
- };
-
- enum
- {
- Read = 0,
- Write = 1,
- kNumErrors = 2
- };
-
- GPR gpr;
- FPU fpu;
- EXC exc;
- DBG dbg;
- int gpr_errs[2]; // Read/Write errors
- int fpu_errs[2]; // Read/Write errors
- int exc_errs[2]; // Read/Write errors
- int dbg_errs[2]; // Read/Write errors
-
- void
- InvalidateAllRegisterStates()
- {
- SetError (GPRRegSet, Read, -1);
- SetError (FPURegSet, Read, -1);
- SetError (EXCRegSet, Read, -1);
+ enum {
+ GPRRegSet = 1, // ARM_THREAD_STATE
+ GPRAltRegSet = 9, // ARM_THREAD_STATE32
+ FPURegSet = 2, // ARM_VFP_STATE
+ EXCRegSet = 3, // ARM_EXCEPTION_STATE
+ DBGRegSet = 4 // ARM_DEBUG_STATE
+ };
+
+ enum {
+ GPRWordCount = sizeof(GPR) / sizeof(uint32_t),
+ FPUWordCount = sizeof(FPU) / sizeof(uint32_t),
+ EXCWordCount = sizeof(EXC) / sizeof(uint32_t),
+ DBGWordCount = sizeof(DBG) / sizeof(uint32_t)
+ };
+
+ enum { Read = 0, Write = 1, kNumErrors = 2 };
+
+ GPR gpr;
+ FPU fpu;
+ EXC exc;
+ DBG dbg;
+ int gpr_errs[2]; // Read/Write errors
+ int fpu_errs[2]; // Read/Write errors
+ int exc_errs[2]; // Read/Write errors
+ int dbg_errs[2]; // Read/Write errors
+
+ void InvalidateAllRegisterStates() {
+ SetError(GPRRegSet, Read, -1);
+ SetError(FPURegSet, Read, -1);
+ SetError(EXCRegSet, Read, -1);
+ }
+
+ int GetError(int flavor, uint32_t err_idx) const {
+ if (err_idx < kNumErrors) {
+ switch (flavor) {
+ // When getting all errors, just OR all values together to see if
+ // we got any kind of error.
+ case GPRRegSet:
+ return gpr_errs[err_idx];
+ case FPURegSet:
+ return fpu_errs[err_idx];
+ case EXCRegSet:
+ return exc_errs[err_idx];
+ case DBGRegSet:
+ return dbg_errs[err_idx];
+ default:
+ break;
+ }
}
-
- int
- GetError (int flavor, uint32_t err_idx) const
- {
- if (err_idx < kNumErrors)
- {
- switch (flavor)
- {
- // When getting all errors, just OR all values together to see if
- // we got any kind of error.
- case GPRRegSet: return gpr_errs[err_idx];
- case FPURegSet: return fpu_errs[err_idx];
- case EXCRegSet: return exc_errs[err_idx];
- case DBGRegSet: return dbg_errs[err_idx];
- default: break;
- }
- }
- return -1;
+ return -1;
+ }
+
+ bool SetError(int flavor, uint32_t err_idx, int err) {
+ if (err_idx < kNumErrors) {
+ switch (flavor) {
+ case GPRRegSet:
+ gpr_errs[err_idx] = err;
+ return true;
+
+ case FPURegSet:
+ fpu_errs[err_idx] = err;
+ return true;
+
+ case EXCRegSet:
+ exc_errs[err_idx] = err;
+ return true;
+
+ case DBGRegSet:
+ exc_errs[err_idx] = err;
+ return true;
+
+ default:
+ break;
+ }
}
+ return false;
+ }
- bool
- SetError (int flavor, uint32_t err_idx, int err)
- {
- if (err_idx < kNumErrors)
- {
- switch (flavor)
- {
- case GPRRegSet:
- gpr_errs[err_idx] = err;
- return true;
-
- case FPURegSet:
- fpu_errs[err_idx] = err;
- return true;
-
- case EXCRegSet:
- exc_errs[err_idx] = err;
- return true;
-
- case DBGRegSet:
- exc_errs[err_idx] = err;
- return true;
-
- default: break;
- }
- }
- return false;
- }
+ bool RegisterSetIsCached(int set) const { return GetError(set, Read) == 0; }
- bool
- RegisterSetIsCached (int set) const
- {
- return GetError(set, Read) == 0;
- }
+ int ReadGPR(bool force);
- int
- ReadGPR (bool force);
+ int ReadFPU(bool force);
- int
- ReadFPU (bool force);
+ int ReadEXC(bool force);
- int
- ReadEXC (bool force);
+ int ReadDBG(bool force);
- int
- ReadDBG (bool force);
+ int WriteGPR();
- int
- WriteGPR ();
+ int WriteFPU();
- int
- WriteFPU ();
+ int WriteEXC();
- int
- WriteEXC ();
+ int WriteDBG();
- int
- WriteDBG ();
+ // Subclasses override these to do the actual reading.
+ virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) { return -1; }
-
- // Subclasses override these to do the actual reading.
- virtual int
- DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
- {
- return -1;
- }
-
- virtual int
- DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu) = 0;
-
- virtual int
- DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc) = 0;
+ virtual int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) = 0;
+
+ virtual int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) = 0;
+
+ virtual int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) = 0;
+
+ virtual int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) = 0;
- virtual int
- DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg) = 0;
+ virtual int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) = 0;
- virtual int
- DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr) = 0;
-
- virtual int
- DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu) = 0;
-
- virtual int
- DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc) = 0;
+ virtual int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) = 0;
- virtual int
- DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg) = 0;
+ virtual int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) = 0;
- int
- ReadRegisterSet (uint32_t set, bool force);
+ int ReadRegisterSet(uint32_t set, bool force);
- int
- WriteRegisterSet (uint32_t set);
+ int WriteRegisterSet(uint32_t set);
- static uint32_t
- GetRegisterNumber (uint32_t reg_kind, uint32_t reg_num);
+ static uint32_t GetRegisterNumber(uint32_t reg_kind, uint32_t reg_num);
- static int
- GetSetForNativeRegNum (int reg_num);
+ static int GetSetForNativeRegNum(int reg_num);
- static size_t
- GetRegisterInfosCount ();
+ static size_t GetRegisterInfosCount();
- static const lldb_private::RegisterInfo *
- GetRegisterInfos ();
+ static const lldb_private::RegisterInfo *GetRegisterInfos();
};
#endif // liblldb_RegisterContextDarwin_arm_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
index 53cb9dea0fb2..64983a2404e6 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
@@ -1,4 +1,5 @@
-//===-- RegisterContextDarwin_arm64.cpp ---------------------------*- C++ -*-===//
+//===-- RegisterContextDarwin_arm64.cpp ---------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -24,6 +25,8 @@
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Host/Endian.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Thread.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Compiler.h"
@@ -41,18 +44,36 @@
using namespace lldb;
using namespace lldb_private;
-
-#define GPR_OFFSET(idx) ((idx) * 8)
-#define GPR_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_arm64::GPR, reg))
-
-#define FPU_OFFSET(idx) ((idx) * 16 + sizeof (RegisterContextDarwin_arm64::GPR))
-#define FPU_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_arm64::FPU, reg))
-
-#define EXC_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_arm64::EXC, reg) + sizeof (RegisterContextDarwin_arm64::GPR) + sizeof (RegisterContextDarwin_arm64::FPU))
-#define DBG_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_arm64::DBG, reg) + sizeof (RegisterContextDarwin_arm64::GPR) + sizeof (RegisterContextDarwin_arm64::FPU) + sizeof (RegisterContextDarwin_arm64::EXC))
-
-#define DEFINE_DBG(reg, i) #reg, NULL, sizeof(((RegisterContextDarwin_arm64::DBG *)NULL)->reg[i]), DBG_OFFSET_NAME(reg[i]), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL, NULL, 0
-#define REG_CONTEXT_SIZE (sizeof (RegisterContextDarwin_arm64::GPR) + sizeof (RegisterContextDarwin_arm64::FPU) + sizeof (RegisterContextDarwin_arm64::EXC))
+#define GPR_OFFSET(idx) ((idx)*8)
+#define GPR_OFFSET_NAME(reg) \
+ (LLVM_EXTENSION offsetof(RegisterContextDarwin_arm64::GPR, reg))
+
+#define FPU_OFFSET(idx) ((idx)*16 + sizeof(RegisterContextDarwin_arm64::GPR))
+#define FPU_OFFSET_NAME(reg) \
+ (LLVM_EXTENSION offsetof(RegisterContextDarwin_arm64::FPU, reg))
+
+#define EXC_OFFSET_NAME(reg) \
+ (LLVM_EXTENSION offsetof(RegisterContextDarwin_arm64::EXC, reg) + \
+ sizeof(RegisterContextDarwin_arm64::GPR) + \
+ sizeof(RegisterContextDarwin_arm64::FPU))
+#define DBG_OFFSET_NAME(reg) \
+ (LLVM_EXTENSION offsetof(RegisterContextDarwin_arm64::DBG, reg) + \
+ sizeof(RegisterContextDarwin_arm64::GPR) + \
+ sizeof(RegisterContextDarwin_arm64::FPU) + \
+ sizeof(RegisterContextDarwin_arm64::EXC))
+
+#define DEFINE_DBG(reg, i) \
+ #reg, NULL, \
+ sizeof(((RegisterContextDarwin_arm64::DBG *) NULL)->reg[i]), \
+ DBG_OFFSET_NAME(reg[i]), eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM }, \
+ NULL, NULL, NULL, 0
+#define REG_CONTEXT_SIZE \
+ (sizeof(RegisterContextDarwin_arm64::GPR) + \
+ sizeof(RegisterContextDarwin_arm64::FPU) + \
+ sizeof(RegisterContextDarwin_arm64::EXC))
//-----------------------------------------------------------------------------
// Include RegisterInfos_arm64 to declare our g_register_infos_arm64 structure.
@@ -62,153 +83,66 @@ using namespace lldb_private;
#undef DECLARE_REGISTER_INFOS_ARM64_STRUCT
// General purpose registers
-static uint32_t
-g_gpr_regnums[] =
-{
- gpr_x0,
- gpr_x1,
- gpr_x2,
- gpr_x3,
- gpr_x4,
- gpr_x5,
- gpr_x6,
- gpr_x7,
- gpr_x8,
- gpr_x9,
- gpr_x10,
- gpr_x11,
- gpr_x12,
- gpr_x13,
- gpr_x14,
- gpr_x15,
- gpr_x16,
- gpr_x17,
- gpr_x18,
- gpr_x19,
- gpr_x20,
- gpr_x21,
- gpr_x22,
- gpr_x23,
- gpr_x24,
- gpr_x25,
- gpr_x26,
- gpr_x27,
- gpr_x28,
- gpr_fp,
- gpr_lr,
- gpr_sp,
- gpr_pc,
- gpr_cpsr
-};
+static uint32_t g_gpr_regnums[] = {
+ gpr_x0, gpr_x1, gpr_x2, gpr_x3, gpr_x4, gpr_x5, gpr_x6,
+ gpr_x7, gpr_x8, gpr_x9, gpr_x10, gpr_x11, gpr_x12, gpr_x13,
+ gpr_x14, gpr_x15, gpr_x16, gpr_x17, gpr_x18, gpr_x19, gpr_x20,
+ gpr_x21, gpr_x22, gpr_x23, gpr_x24, gpr_x25, gpr_x26, gpr_x27,
+ gpr_x28, gpr_fp, gpr_lr, gpr_sp, gpr_pc, gpr_cpsr};
// Floating point registers
-static uint32_t
-g_fpu_regnums[] =
-{
- fpu_v0,
- fpu_v1,
- fpu_v2,
- fpu_v3,
- fpu_v4,
- fpu_v5,
- fpu_v6,
- fpu_v7,
- fpu_v8,
- fpu_v9,
- fpu_v10,
- fpu_v11,
- fpu_v12,
- fpu_v13,
- fpu_v14,
- fpu_v15,
- fpu_v16,
- fpu_v17,
- fpu_v18,
- fpu_v19,
- fpu_v20,
- fpu_v21,
- fpu_v22,
- fpu_v23,
- fpu_v24,
- fpu_v25,
- fpu_v26,
- fpu_v27,
- fpu_v28,
- fpu_v29,
- fpu_v30,
- fpu_v31,
- fpu_fpsr,
- fpu_fpcr
-};
+static uint32_t g_fpu_regnums[] = {
+ fpu_v0, fpu_v1, fpu_v2, fpu_v3, fpu_v4, fpu_v5, fpu_v6,
+ fpu_v7, fpu_v8, fpu_v9, fpu_v10, fpu_v11, fpu_v12, fpu_v13,
+ fpu_v14, fpu_v15, fpu_v16, fpu_v17, fpu_v18, fpu_v19, fpu_v20,
+ fpu_v21, fpu_v22, fpu_v23, fpu_v24, fpu_v25, fpu_v26, fpu_v27,
+ fpu_v28, fpu_v29, fpu_v30, fpu_v31, fpu_fpsr, fpu_fpcr};
// Exception registers
-static uint32_t
-g_exc_regnums[] =
-{
- exc_far,
- exc_esr,
- exc_exception
-};
-
-static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos_arm64);
-
-RegisterContextDarwin_arm64::RegisterContextDarwin_arm64(Thread &thread, uint32_t concrete_frame_idx) :
- RegisterContext(thread, concrete_frame_idx),
- gpr(),
- fpu(),
- exc()
-{
- uint32_t i;
- for (i=0; i<kNumErrors; i++)
- {
- gpr_errs[i] = -1;
- fpu_errs[i] = -1;
- exc_errs[i] = -1;
- }
-}
+static uint32_t g_exc_regnums[] = {exc_far, exc_esr, exc_exception};
+
+static size_t k_num_register_infos =
+ llvm::array_lengthof(g_register_infos_arm64_le);
-RegisterContextDarwin_arm64::~RegisterContextDarwin_arm64()
-{
+RegisterContextDarwin_arm64::RegisterContextDarwin_arm64(
+ Thread &thread, uint32_t concrete_frame_idx)
+ : RegisterContext(thread, concrete_frame_idx), gpr(), fpu(), exc() {
+ uint32_t i;
+ for (i = 0; i < kNumErrors; i++) {
+ gpr_errs[i] = -1;
+ fpu_errs[i] = -1;
+ exc_errs[i] = -1;
+ }
}
+RegisterContextDarwin_arm64::~RegisterContextDarwin_arm64() {}
-void
-RegisterContextDarwin_arm64::InvalidateAllRegisters ()
-{
- InvalidateAllRegisterStates();
+void RegisterContextDarwin_arm64::InvalidateAllRegisters() {
+ InvalidateAllRegisterStates();
}
-
-size_t
-RegisterContextDarwin_arm64::GetRegisterCount ()
-{
- assert(k_num_register_infos == k_num_registers);
- return k_num_registers;
+size_t RegisterContextDarwin_arm64::GetRegisterCount() {
+ assert(k_num_register_infos == k_num_registers);
+ return k_num_registers;
}
const RegisterInfo *
-RegisterContextDarwin_arm64::GetRegisterInfoAtIndex (size_t reg)
-{
- assert(k_num_register_infos == k_num_registers);
- if (reg < k_num_registers)
- return &g_register_infos_arm64[reg];
- return NULL;
+RegisterContextDarwin_arm64::GetRegisterInfoAtIndex(size_t reg) {
+ assert(k_num_register_infos == k_num_registers);
+ if (reg < k_num_registers)
+ return &g_register_infos_arm64_le[reg];
+ return NULL;
}
-size_t
-RegisterContextDarwin_arm64::GetRegisterInfosCount ()
-{
- return k_num_register_infos;
+size_t RegisterContextDarwin_arm64::GetRegisterInfosCount() {
+ return k_num_register_infos;
}
-const RegisterInfo *
-RegisterContextDarwin_arm64::GetRegisterInfos ()
-{
- return g_register_infos_arm64;
+const RegisterInfo *RegisterContextDarwin_arm64::GetRegisterInfos() {
+ return g_register_infos_arm64_le;
}
-
// Number of registers in each register set
const size_t k_num_gpr_registers = llvm::array_lengthof(g_gpr_regnums);
const size_t k_num_fpu_registers = llvm::array_lengthof(g_fpu_regnums);
@@ -219,726 +153,895 @@ const size_t k_num_exc_registers = llvm::array_lengthof(g_exc_regnums);
// of zero is for all registers, followed by other registers sets. The
// register information for the all register set need not be filled in.
//----------------------------------------------------------------------
-static const RegisterSet g_reg_sets[] =
-{
- { "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums, },
- { "Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums },
- { "Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums }
-};
+static const RegisterSet g_reg_sets[] = {
+ {
+ "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums,
+ },
+ {"Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums},
+ {"Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums}};
const size_t k_num_regsets = llvm::array_lengthof(g_reg_sets);
-
-size_t
-RegisterContextDarwin_arm64::GetRegisterSetCount ()
-{
- return k_num_regsets;
+size_t RegisterContextDarwin_arm64::GetRegisterSetCount() {
+ return k_num_regsets;
}
-const RegisterSet *
-RegisterContextDarwin_arm64::GetRegisterSet (size_t reg_set)
-{
- if (reg_set < k_num_regsets)
- return &g_reg_sets[reg_set];
- return NULL;
+const RegisterSet *RegisterContextDarwin_arm64::GetRegisterSet(size_t reg_set) {
+ if (reg_set < k_num_regsets)
+ return &g_reg_sets[reg_set];
+ return NULL;
}
-
//----------------------------------------------------------------------
// Register information definitions for arm64
//----------------------------------------------------------------------
-int
-RegisterContextDarwin_arm64::GetSetForNativeRegNum (int reg)
-{
- if (reg < fpu_v0)
- return GPRRegSet;
- else if (reg < exc_far)
- return FPURegSet;
- else if (reg < k_num_registers)
- return EXCRegSet;
- return -1;
+int RegisterContextDarwin_arm64::GetSetForNativeRegNum(int reg) {
+ if (reg < fpu_v0)
+ return GPRRegSet;
+ else if (reg < exc_far)
+ return FPURegSet;
+ else if (reg < k_num_registers)
+ return EXCRegSet;
+ return -1;
}
-int
-RegisterContextDarwin_arm64::ReadGPR (bool force)
-{
- int set = GPRRegSet;
- if (force || !RegisterSetIsCached(set))
- {
- SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
- }
- return GetError(GPRRegSet, Read);
+int RegisterContextDarwin_arm64::ReadGPR(bool force) {
+ int set = GPRRegSet;
+ if (force || !RegisterSetIsCached(set)) {
+ SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
+ }
+ return GetError(GPRRegSet, Read);
}
-int
-RegisterContextDarwin_arm64::ReadFPU (bool force)
-{
- int set = FPURegSet;
- if (force || !RegisterSetIsCached(set))
- {
- SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
- }
- return GetError(FPURegSet, Read);
+int RegisterContextDarwin_arm64::ReadFPU(bool force) {
+ int set = FPURegSet;
+ if (force || !RegisterSetIsCached(set)) {
+ SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
+ }
+ return GetError(FPURegSet, Read);
}
-int
-RegisterContextDarwin_arm64::ReadEXC (bool force)
-{
- int set = EXCRegSet;
- if (force || !RegisterSetIsCached(set))
- {
- SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
- }
- return GetError(EXCRegSet, Read);
-}
-
-int
-RegisterContextDarwin_arm64::ReadDBG (bool force)
-{
- int set = DBGRegSet;
- if (force || !RegisterSetIsCached(set))
- {
- SetError(set, Read, DoReadDBG(GetThreadID(), set, dbg));
- }
- return GetError(DBGRegSet, Read);
+int RegisterContextDarwin_arm64::ReadEXC(bool force) {
+ int set = EXCRegSet;
+ if (force || !RegisterSetIsCached(set)) {
+ SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
+ }
+ return GetError(EXCRegSet, Read);
}
-int
-RegisterContextDarwin_arm64::WriteGPR ()
-{
- int set = GPRRegSet;
- if (!RegisterSetIsCached(set))
- {
- SetError (set, Write, -1);
- return KERN_INVALID_ARGUMENT;
- }
- SetError (set, Write, DoWriteGPR(GetThreadID(), set, gpr));
- SetError (set, Read, -1);
- return GetError(GPRRegSet, Write);
+int RegisterContextDarwin_arm64::ReadDBG(bool force) {
+ int set = DBGRegSet;
+ if (force || !RegisterSetIsCached(set)) {
+ SetError(set, Read, DoReadDBG(GetThreadID(), set, dbg));
+ }
+ return GetError(DBGRegSet, Read);
}
-int
-RegisterContextDarwin_arm64::WriteFPU ()
-{
- int set = FPURegSet;
- if (!RegisterSetIsCached(set))
- {
- SetError (set, Write, -1);
- return KERN_INVALID_ARGUMENT;
- }
- SetError (set, Write, DoWriteFPU(GetThreadID(), set, fpu));
- SetError (set, Read, -1);
- return GetError(FPURegSet, Write);
+int RegisterContextDarwin_arm64::WriteGPR() {
+ int set = GPRRegSet;
+ if (!RegisterSetIsCached(set)) {
+ SetError(set, Write, -1);
+ return KERN_INVALID_ARGUMENT;
+ }
+ SetError(set, Write, DoWriteGPR(GetThreadID(), set, gpr));
+ SetError(set, Read, -1);
+ return GetError(GPRRegSet, Write);
}
-int
-RegisterContextDarwin_arm64::WriteEXC ()
-{
- int set = EXCRegSet;
- if (!RegisterSetIsCached(set))
- {
- SetError (set, Write, -1);
- return KERN_INVALID_ARGUMENT;
- }
- SetError (set, Write, DoWriteEXC(GetThreadID(), set, exc));
- SetError (set, Read, -1);
- return GetError(EXCRegSet, Write);
+int RegisterContextDarwin_arm64::WriteFPU() {
+ int set = FPURegSet;
+ if (!RegisterSetIsCached(set)) {
+ SetError(set, Write, -1);
+ return KERN_INVALID_ARGUMENT;
+ }
+ SetError(set, Write, DoWriteFPU(GetThreadID(), set, fpu));
+ SetError(set, Read, -1);
+ return GetError(FPURegSet, Write);
}
-int
-RegisterContextDarwin_arm64::WriteDBG ()
-{
- int set = DBGRegSet;
- if (!RegisterSetIsCached(set))
- {
- SetError (set, Write, -1);
- return KERN_INVALID_ARGUMENT;
- }
- SetError (set, Write, DoWriteDBG(GetThreadID(), set, dbg));
- SetError (set, Read, -1);
- return GetError(DBGRegSet, Write);
+int RegisterContextDarwin_arm64::WriteEXC() {
+ int set = EXCRegSet;
+ if (!RegisterSetIsCached(set)) {
+ SetError(set, Write, -1);
+ return KERN_INVALID_ARGUMENT;
+ }
+ SetError(set, Write, DoWriteEXC(GetThreadID(), set, exc));
+ SetError(set, Read, -1);
+ return GetError(EXCRegSet, Write);
}
-
-int
-RegisterContextDarwin_arm64::ReadRegisterSet (uint32_t set, bool force)
-{
- switch (set)
- {
- case GPRRegSet: return ReadGPR(force);
- case FPURegSet: return ReadFPU(force);
- case EXCRegSet: return ReadEXC(force);
- case DBGRegSet: return ReadDBG(force);
- default: break;
- }
+int RegisterContextDarwin_arm64::WriteDBG() {
+ int set = DBGRegSet;
+ if (!RegisterSetIsCached(set)) {
+ SetError(set, Write, -1);
return KERN_INVALID_ARGUMENT;
+ }
+ SetError(set, Write, DoWriteDBG(GetThreadID(), set, dbg));
+ SetError(set, Read, -1);
+ return GetError(DBGRegSet, Write);
}
-int
-RegisterContextDarwin_arm64::WriteRegisterSet (uint32_t set)
-{
- // Make sure we have a valid context to set.
- if (RegisterSetIsCached(set))
- {
- switch (set)
- {
- case GPRRegSet: return WriteGPR();
- case FPURegSet: return WriteFPU();
- case EXCRegSet: return WriteEXC();
- case DBGRegSet: return WriteDBG();
- default: break;
- }
- }
- return KERN_INVALID_ARGUMENT;
+int RegisterContextDarwin_arm64::ReadRegisterSet(uint32_t set, bool force) {
+ switch (set) {
+ case GPRRegSet:
+ return ReadGPR(force);
+ case FPURegSet:
+ return ReadFPU(force);
+ case EXCRegSet:
+ return ReadEXC(force);
+ case DBGRegSet:
+ return ReadDBG(force);
+ default:
+ break;
+ }
+ return KERN_INVALID_ARGUMENT;
}
-void
-RegisterContextDarwin_arm64::LogDBGRegisters (Log *log, const DBG& dbg)
-{
- if (log)
- {
- for (uint32_t i=0; i<16; i++)
- log->Printf("BVR%-2u/BCR%-2u = { 0x%8.8llx, 0x%8.8llx } WVR%-2u/WCR%-2u = { 0x%8.8llx, 0x%8.8llx }",
- i, i, dbg.bvr[i], dbg.bcr[i],
- i, i, dbg.wvr[i], dbg.wcr[i]);
+int RegisterContextDarwin_arm64::WriteRegisterSet(uint32_t set) {
+ // Make sure we have a valid context to set.
+ if (RegisterSetIsCached(set)) {
+ switch (set) {
+ case GPRRegSet:
+ return WriteGPR();
+ case FPURegSet:
+ return WriteFPU();
+ case EXCRegSet:
+ return WriteEXC();
+ case DBGRegSet:
+ return WriteDBG();
+ default:
+ break;
}
+ }
+ return KERN_INVALID_ARGUMENT;
}
+void RegisterContextDarwin_arm64::LogDBGRegisters(Log *log, const DBG &dbg) {
+ if (log) {
+ for (uint32_t i = 0; i < 16; i++)
+ log->Printf("BVR%-2u/BCR%-2u = { 0x%8.8llx, 0x%8.8llx } WVR%-2u/WCR%-2u "
+ "= { 0x%8.8llx, 0x%8.8llx }",
+ i, i, dbg.bvr[i], dbg.bcr[i], i, i, dbg.wvr[i], dbg.wcr[i]);
+ }
+}
-bool
-RegisterContextDarwin_arm64::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value)
-{
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- int set = RegisterContextDarwin_arm64::GetSetForNativeRegNum (reg);
-
- if (set == -1)
- return false;
-
- if (ReadRegisterSet(set, false) != KERN_SUCCESS)
- return false;
+bool RegisterContextDarwin_arm64::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &value) {
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+ int set = RegisterContextDarwin_arm64::GetSetForNativeRegNum(reg);
- switch (reg)
- {
- case gpr_x0:
- case gpr_x1:
- case gpr_x2:
- case gpr_x3:
- case gpr_x4:
- case gpr_x5:
- case gpr_x6:
- case gpr_x7:
- case gpr_x8:
- case gpr_x9:
- case gpr_x10:
- case gpr_x11:
- case gpr_x12:
- case gpr_x13:
- case gpr_x14:
- case gpr_x15:
- case gpr_x16:
- case gpr_x17:
- case gpr_x18:
- case gpr_x19:
- case gpr_x20:
- case gpr_x21:
- case gpr_x22:
- case gpr_x23:
- case gpr_x24:
- case gpr_x25:
- case gpr_x26:
- case gpr_x27:
- case gpr_x28:
- case gpr_fp:
- case gpr_sp:
- case gpr_lr:
- case gpr_pc:
- case gpr_cpsr:
- value.SetUInt64 (gpr.x[reg - gpr_x0]);
- break;
-
- case fpu_v0:
- case fpu_v1:
- case fpu_v2:
- case fpu_v3:
- case fpu_v4:
- case fpu_v5:
- case fpu_v6:
- case fpu_v7:
- case fpu_v8:
- case fpu_v9:
- case fpu_v10:
- case fpu_v11:
- case fpu_v12:
- case fpu_v13:
- case fpu_v14:
- case fpu_v15:
- case fpu_v16:
- case fpu_v17:
- case fpu_v18:
- case fpu_v19:
- case fpu_v20:
- case fpu_v21:
- case fpu_v22:
- case fpu_v23:
- case fpu_v24:
- case fpu_v25:
- case fpu_v26:
- case fpu_v27:
- case fpu_v28:
- case fpu_v29:
- case fpu_v30:
- case fpu_v31:
- value.SetBytes(fpu.v[reg].bytes, reg_info->byte_size, endian::InlHostByteOrder());
- break;
-
- case fpu_fpsr:
- value.SetUInt32 (fpu.fpsr);
- break;
-
- case fpu_fpcr:
- value.SetUInt32 (fpu.fpcr);
- break;
-
- case exc_exception:
- value.SetUInt32 (exc.exception);
- break;
- case exc_esr:
- value.SetUInt32 (exc.esr);
- break;
- case exc_far:
- value.SetUInt64 (exc.far);
- break;
+ if (set == -1)
+ return false;
- default:
- value.SetValueToInvalid();
- return false;
+ if (ReadRegisterSet(set, false) != KERN_SUCCESS)
+ return false;
+ switch (reg) {
+ case gpr_x0:
+ case gpr_x1:
+ case gpr_x2:
+ case gpr_x3:
+ case gpr_x4:
+ case gpr_x5:
+ case gpr_x6:
+ case gpr_x7:
+ case gpr_x8:
+ case gpr_x9:
+ case gpr_x10:
+ case gpr_x11:
+ case gpr_x12:
+ case gpr_x13:
+ case gpr_x14:
+ case gpr_x15:
+ case gpr_x16:
+ case gpr_x17:
+ case gpr_x18:
+ case gpr_x19:
+ case gpr_x20:
+ case gpr_x21:
+ case gpr_x22:
+ case gpr_x23:
+ case gpr_x24:
+ case gpr_x25:
+ case gpr_x26:
+ case gpr_x27:
+ case gpr_x28:
+ case gpr_fp:
+ case gpr_sp:
+ case gpr_lr:
+ case gpr_pc:
+ case gpr_cpsr:
+ value.SetUInt64(gpr.x[reg - gpr_x0]);
+ break;
+
+ case gpr_w0:
+ case gpr_w1:
+ case gpr_w2:
+ case gpr_w3:
+ case gpr_w4:
+ case gpr_w5:
+ case gpr_w6:
+ case gpr_w7:
+ case gpr_w8:
+ case gpr_w9:
+ case gpr_w10:
+ case gpr_w11:
+ case gpr_w12:
+ case gpr_w13:
+ case gpr_w14:
+ case gpr_w15:
+ case gpr_w16:
+ case gpr_w17:
+ case gpr_w18:
+ case gpr_w19:
+ case gpr_w20:
+ case gpr_w21:
+ case gpr_w22:
+ case gpr_w23:
+ case gpr_w24:
+ case gpr_w25:
+ case gpr_w26:
+ case gpr_w27:
+ case gpr_w28: {
+ ProcessSP process_sp(m_thread.GetProcess());
+ if (process_sp.get()) {
+ DataExtractor regdata(&gpr.x[reg - gpr_w0], 8, process_sp->GetByteOrder(),
+ process_sp->GetAddressByteSize());
+ offset_t offset = 0;
+ uint64_t retval = regdata.GetMaxU64(&offset, 8);
+ uint32_t retval_lower32 = static_cast<uint32_t>(retval & 0xffffffff);
+ value.SetUInt32(retval_lower32);
}
- return true;
+ } break;
+
+ case fpu_v0:
+ case fpu_v1:
+ case fpu_v2:
+ case fpu_v3:
+ case fpu_v4:
+ case fpu_v5:
+ case fpu_v6:
+ case fpu_v7:
+ case fpu_v8:
+ case fpu_v9:
+ case fpu_v10:
+ case fpu_v11:
+ case fpu_v12:
+ case fpu_v13:
+ case fpu_v14:
+ case fpu_v15:
+ case fpu_v16:
+ case fpu_v17:
+ case fpu_v18:
+ case fpu_v19:
+ case fpu_v20:
+ case fpu_v21:
+ case fpu_v22:
+ case fpu_v23:
+ case fpu_v24:
+ case fpu_v25:
+ case fpu_v26:
+ case fpu_v27:
+ case fpu_v28:
+ case fpu_v29:
+ case fpu_v30:
+ case fpu_v31:
+ value.SetBytes(fpu.v[reg].bytes, reg_info->byte_size,
+ endian::InlHostByteOrder());
+ break;
+
+ case fpu_s0:
+ case fpu_s1:
+ case fpu_s2:
+ case fpu_s3:
+ case fpu_s4:
+ case fpu_s5:
+ case fpu_s6:
+ case fpu_s7:
+ case fpu_s8:
+ case fpu_s9:
+ case fpu_s10:
+ case fpu_s11:
+ case fpu_s12:
+ case fpu_s13:
+ case fpu_s14:
+ case fpu_s15:
+ case fpu_s16:
+ case fpu_s17:
+ case fpu_s18:
+ case fpu_s19:
+ case fpu_s20:
+ case fpu_s21:
+ case fpu_s22:
+ case fpu_s23:
+ case fpu_s24:
+ case fpu_s25:
+ case fpu_s26:
+ case fpu_s27:
+ case fpu_s28:
+ case fpu_s29:
+ case fpu_s30:
+ case fpu_s31: {
+ ProcessSP process_sp(m_thread.GetProcess());
+ if (process_sp.get()) {
+ DataExtractor regdata(&fpu.v[reg - fpu_s0], 4, process_sp->GetByteOrder(),
+ process_sp->GetAddressByteSize());
+ offset_t offset = 0;
+ value.SetFloat(regdata.GetFloat(&offset));
+ }
+ } break;
+
+ case fpu_d0:
+ case fpu_d1:
+ case fpu_d2:
+ case fpu_d3:
+ case fpu_d4:
+ case fpu_d5:
+ case fpu_d6:
+ case fpu_d7:
+ case fpu_d8:
+ case fpu_d9:
+ case fpu_d10:
+ case fpu_d11:
+ case fpu_d12:
+ case fpu_d13:
+ case fpu_d14:
+ case fpu_d15:
+ case fpu_d16:
+ case fpu_d17:
+ case fpu_d18:
+ case fpu_d19:
+ case fpu_d20:
+ case fpu_d21:
+ case fpu_d22:
+ case fpu_d23:
+ case fpu_d24:
+ case fpu_d25:
+ case fpu_d26:
+ case fpu_d27:
+ case fpu_d28:
+ case fpu_d29:
+ case fpu_d30:
+ case fpu_d31: {
+ ProcessSP process_sp(m_thread.GetProcess());
+ if (process_sp.get()) {
+ DataExtractor regdata(&fpu.v[reg - fpu_s0], 8, process_sp->GetByteOrder(),
+ process_sp->GetAddressByteSize());
+ offset_t offset = 0;
+ value.SetDouble(regdata.GetDouble(&offset));
+ }
+ } break;
+
+ case fpu_fpsr:
+ value.SetUInt32(fpu.fpsr);
+ break;
+
+ case fpu_fpcr:
+ value.SetUInt32(fpu.fpcr);
+ break;
+
+ case exc_exception:
+ value.SetUInt32(exc.exception);
+ break;
+ case exc_esr:
+ value.SetUInt32(exc.esr);
+ break;
+ case exc_far:
+ value.SetUInt64(exc.far);
+ break;
+
+ default:
+ value.SetValueToInvalid();
+ return false;
+ }
+ return true;
}
+bool RegisterContextDarwin_arm64::WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &value) {
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+ int set = GetSetForNativeRegNum(reg);
-bool
-RegisterContextDarwin_arm64::WriteRegister (const RegisterInfo *reg_info,
- const RegisterValue &value)
-{
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- int set = GetSetForNativeRegNum (reg);
-
- if (set == -1)
- return false;
-
- if (ReadRegisterSet(set, false) != KERN_SUCCESS)
- return false;
-
- switch (reg)
- {
- case gpr_x0:
- case gpr_x1:
- case gpr_x2:
- case gpr_x3:
- case gpr_x4:
- case gpr_x5:
- case gpr_x6:
- case gpr_x7:
- case gpr_x8:
- case gpr_x9:
- case gpr_x10:
- case gpr_x11:
- case gpr_x12:
- case gpr_x13:
- case gpr_x14:
- case gpr_x15:
- case gpr_x16:
- case gpr_x17:
- case gpr_x18:
- case gpr_x19:
- case gpr_x20:
- case gpr_x21:
- case gpr_x22:
- case gpr_x23:
- case gpr_x24:
- case gpr_x25:
- case gpr_x26:
- case gpr_x27:
- case gpr_x28:
- case gpr_fp:
- case gpr_sp:
- case gpr_lr:
- case gpr_pc:
- case gpr_cpsr:
- gpr.x[reg - gpr_x0] = value.GetAsUInt64();
- break;
-
- case fpu_v0:
- case fpu_v1:
- case fpu_v2:
- case fpu_v3:
- case fpu_v4:
- case fpu_v5:
- case fpu_v6:
- case fpu_v7:
- case fpu_v8:
- case fpu_v9:
- case fpu_v10:
- case fpu_v11:
- case fpu_v12:
- case fpu_v13:
- case fpu_v14:
- case fpu_v15:
- case fpu_v16:
- case fpu_v17:
- case fpu_v18:
- case fpu_v19:
- case fpu_v20:
- case fpu_v21:
- case fpu_v22:
- case fpu_v23:
- case fpu_v24:
- case fpu_v25:
- case fpu_v26:
- case fpu_v27:
- case fpu_v28:
- case fpu_v29:
- case fpu_v30:
- case fpu_v31:
- ::memcpy (fpu.v[reg].bytes, value.GetBytes(), value.GetByteSize());
- break;
-
- case fpu_fpsr:
- fpu.fpsr = value.GetAsUInt32();
- break;
-
- case fpu_fpcr:
- fpu.fpcr = value.GetAsUInt32();
- break;
-
- case exc_exception:
- exc.exception = value.GetAsUInt32();
- break;
- case exc_esr:
- exc.esr = value.GetAsUInt32();
- break;
- case exc_far:
- exc.far = value.GetAsUInt64();
- break;
+ if (set == -1)
+ return false;
- default:
- return false;
+ if (ReadRegisterSet(set, false) != KERN_SUCCESS)
+ return false;
- }
- return WriteRegisterSet(set) == KERN_SUCCESS;
+ switch (reg) {
+ case gpr_x0:
+ case gpr_x1:
+ case gpr_x2:
+ case gpr_x3:
+ case gpr_x4:
+ case gpr_x5:
+ case gpr_x6:
+ case gpr_x7:
+ case gpr_x8:
+ case gpr_x9:
+ case gpr_x10:
+ case gpr_x11:
+ case gpr_x12:
+ case gpr_x13:
+ case gpr_x14:
+ case gpr_x15:
+ case gpr_x16:
+ case gpr_x17:
+ case gpr_x18:
+ case gpr_x19:
+ case gpr_x20:
+ case gpr_x21:
+ case gpr_x22:
+ case gpr_x23:
+ case gpr_x24:
+ case gpr_x25:
+ case gpr_x26:
+ case gpr_x27:
+ case gpr_x28:
+ case gpr_fp:
+ case gpr_sp:
+ case gpr_lr:
+ case gpr_pc:
+ case gpr_cpsr:
+ gpr.x[reg - gpr_x0] = value.GetAsUInt64();
+ break;
+
+ case fpu_v0:
+ case fpu_v1:
+ case fpu_v2:
+ case fpu_v3:
+ case fpu_v4:
+ case fpu_v5:
+ case fpu_v6:
+ case fpu_v7:
+ case fpu_v8:
+ case fpu_v9:
+ case fpu_v10:
+ case fpu_v11:
+ case fpu_v12:
+ case fpu_v13:
+ case fpu_v14:
+ case fpu_v15:
+ case fpu_v16:
+ case fpu_v17:
+ case fpu_v18:
+ case fpu_v19:
+ case fpu_v20:
+ case fpu_v21:
+ case fpu_v22:
+ case fpu_v23:
+ case fpu_v24:
+ case fpu_v25:
+ case fpu_v26:
+ case fpu_v27:
+ case fpu_v28:
+ case fpu_v29:
+ case fpu_v30:
+ case fpu_v31:
+ ::memcpy(fpu.v[reg].bytes, value.GetBytes(), value.GetByteSize());
+ break;
+
+ case fpu_fpsr:
+ fpu.fpsr = value.GetAsUInt32();
+ break;
+
+ case fpu_fpcr:
+ fpu.fpcr = value.GetAsUInt32();
+ break;
+
+ case exc_exception:
+ exc.exception = value.GetAsUInt32();
+ break;
+ case exc_esr:
+ exc.esr = value.GetAsUInt32();
+ break;
+ case exc_far:
+ exc.far = value.GetAsUInt64();
+ break;
+
+ default:
+ return false;
+ }
+ return WriteRegisterSet(set) == KERN_SUCCESS;
}
-bool
-RegisterContextDarwin_arm64::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
-{
- data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
- if (data_sp &&
- ReadGPR (false) == KERN_SUCCESS &&
- ReadFPU (false) == KERN_SUCCESS &&
- ReadEXC (false) == KERN_SUCCESS)
- {
- uint8_t *dst = data_sp->GetBytes();
- ::memcpy (dst, &gpr, sizeof(gpr));
- dst += sizeof(gpr);
+bool RegisterContextDarwin_arm64::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (data_sp && ReadGPR(false) == KERN_SUCCESS &&
+ ReadFPU(false) == KERN_SUCCESS && ReadEXC(false) == KERN_SUCCESS) {
+ uint8_t *dst = data_sp->GetBytes();
+ ::memcpy(dst, &gpr, sizeof(gpr));
+ dst += sizeof(gpr);
- ::memcpy (dst, &fpu, sizeof(fpu));
- dst += sizeof(gpr);
+ ::memcpy(dst, &fpu, sizeof(fpu));
+ dst += sizeof(gpr);
- ::memcpy (dst, &exc, sizeof(exc));
- return true;
- }
- return false;
+ ::memcpy(dst, &exc, sizeof(exc));
+ return true;
+ }
+ return false;
}
-bool
-RegisterContextDarwin_arm64::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
-{
- if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE)
- {
- const uint8_t *src = data_sp->GetBytes();
- ::memcpy (&gpr, src, sizeof(gpr));
- src += sizeof(gpr);
-
- ::memcpy (&fpu, src, sizeof(fpu));
- src += sizeof(gpr);
-
- ::memcpy (&exc, src, sizeof(exc));
- uint32_t success_count = 0;
- if (WriteGPR() == KERN_SUCCESS)
- ++success_count;
- if (WriteFPU() == KERN_SUCCESS)
- ++success_count;
- if (WriteEXC() == KERN_SUCCESS)
- ++success_count;
- return success_count == 3;
- }
- return false;
+bool RegisterContextDarwin_arm64::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
+ const uint8_t *src = data_sp->GetBytes();
+ ::memcpy(&gpr, src, sizeof(gpr));
+ src += sizeof(gpr);
+
+ ::memcpy(&fpu, src, sizeof(fpu));
+ src += sizeof(gpr);
+
+ ::memcpy(&exc, src, sizeof(exc));
+ uint32_t success_count = 0;
+ if (WriteGPR() == KERN_SUCCESS)
+ ++success_count;
+ if (WriteFPU() == KERN_SUCCESS)
+ ++success_count;
+ if (WriteEXC() == KERN_SUCCESS)
+ ++success_count;
+ return success_count == 3;
+ }
+ return false;
}
-uint32_t
-RegisterContextDarwin_arm64::ConvertRegisterKindToRegisterNumber (RegisterKind kind, uint32_t reg)
-{
- if (kind == eRegisterKindGeneric)
- {
- switch (reg)
- {
- case LLDB_REGNUM_GENERIC_PC: return gpr_pc;
- case LLDB_REGNUM_GENERIC_SP: return gpr_sp;
- case LLDB_REGNUM_GENERIC_FP: return gpr_fp;
- case LLDB_REGNUM_GENERIC_RA: return gpr_lr;
- case LLDB_REGNUM_GENERIC_FLAGS: return gpr_cpsr;
- default:
- break;
- }
- }
- else if (kind == eRegisterKindDWARF)
- {
- switch (reg)
- {
- case arm64_dwarf::x0: return gpr_x0;
- case arm64_dwarf::x1: return gpr_x1;
- case arm64_dwarf::x2: return gpr_x2;
- case arm64_dwarf::x3: return gpr_x3;
- case arm64_dwarf::x4: return gpr_x4;
- case arm64_dwarf::x5: return gpr_x5;
- case arm64_dwarf::x6: return gpr_x6;
- case arm64_dwarf::x7: return gpr_x7;
- case arm64_dwarf::x8: return gpr_x8;
- case arm64_dwarf::x9: return gpr_x9;
- case arm64_dwarf::x10: return gpr_x10;
- case arm64_dwarf::x11: return gpr_x11;
- case arm64_dwarf::x12: return gpr_x12;
- case arm64_dwarf::x13: return gpr_x13;
- case arm64_dwarf::x14: return gpr_x14;
- case arm64_dwarf::x15: return gpr_x15;
- case arm64_dwarf::x16: return gpr_x16;
- case arm64_dwarf::x17: return gpr_x17;
- case arm64_dwarf::x18: return gpr_x18;
- case arm64_dwarf::x19: return gpr_x19;
- case arm64_dwarf::x20: return gpr_x20;
- case arm64_dwarf::x21: return gpr_x21;
- case arm64_dwarf::x22: return gpr_x22;
- case arm64_dwarf::x23: return gpr_x23;
- case arm64_dwarf::x24: return gpr_x24;
- case arm64_dwarf::x25: return gpr_x25;
- case arm64_dwarf::x26: return gpr_x26;
- case arm64_dwarf::x27: return gpr_x27;
- case arm64_dwarf::x28: return gpr_x28;
-
- case arm64_dwarf::fp: return gpr_fp;
- case arm64_dwarf::sp: return gpr_sp;
- case arm64_dwarf::lr: return gpr_lr;
- case arm64_dwarf::pc: return gpr_pc;
- case arm64_dwarf::cpsr: return gpr_cpsr;
-
- case arm64_dwarf::v0: return fpu_v0;
- case arm64_dwarf::v1: return fpu_v1;
- case arm64_dwarf::v2: return fpu_v2;
- case arm64_dwarf::v3: return fpu_v3;
- case arm64_dwarf::v4: return fpu_v4;
- case arm64_dwarf::v5: return fpu_v5;
- case arm64_dwarf::v6: return fpu_v6;
- case arm64_dwarf::v7: return fpu_v7;
- case arm64_dwarf::v8: return fpu_v8;
- case arm64_dwarf::v9: return fpu_v9;
- case arm64_dwarf::v10: return fpu_v10;
- case arm64_dwarf::v11: return fpu_v11;
- case arm64_dwarf::v12: return fpu_v12;
- case arm64_dwarf::v13: return fpu_v13;
- case arm64_dwarf::v14: return fpu_v14;
- case arm64_dwarf::v15: return fpu_v15;
- case arm64_dwarf::v16: return fpu_v16;
- case arm64_dwarf::v17: return fpu_v17;
- case arm64_dwarf::v18: return fpu_v18;
- case arm64_dwarf::v19: return fpu_v19;
- case arm64_dwarf::v20: return fpu_v20;
- case arm64_dwarf::v21: return fpu_v21;
- case arm64_dwarf::v22: return fpu_v22;
- case arm64_dwarf::v23: return fpu_v23;
- case arm64_dwarf::v24: return fpu_v24;
- case arm64_dwarf::v25: return fpu_v25;
- case arm64_dwarf::v26: return fpu_v26;
- case arm64_dwarf::v27: return fpu_v27;
- case arm64_dwarf::v28: return fpu_v28;
- case arm64_dwarf::v29: return fpu_v29;
- case arm64_dwarf::v30: return fpu_v30;
- case arm64_dwarf::v31: return fpu_v31;
-
- default:
- break;
- }
+uint32_t RegisterContextDarwin_arm64::ConvertRegisterKindToRegisterNumber(
+ RegisterKind kind, uint32_t reg) {
+ if (kind == eRegisterKindGeneric) {
+ switch (reg) {
+ case LLDB_REGNUM_GENERIC_PC:
+ return gpr_pc;
+ case LLDB_REGNUM_GENERIC_SP:
+ return gpr_sp;
+ case LLDB_REGNUM_GENERIC_FP:
+ return gpr_fp;
+ case LLDB_REGNUM_GENERIC_RA:
+ return gpr_lr;
+ case LLDB_REGNUM_GENERIC_FLAGS:
+ return gpr_cpsr;
+ default:
+ break;
}
- else if (kind == eRegisterKindEHFrame)
- {
- switch (reg)
- {
- case arm64_ehframe::x0: return gpr_x0;
- case arm64_ehframe::x1: return gpr_x1;
- case arm64_ehframe::x2: return gpr_x2;
- case arm64_ehframe::x3: return gpr_x3;
- case arm64_ehframe::x4: return gpr_x4;
- case arm64_ehframe::x5: return gpr_x5;
- case arm64_ehframe::x6: return gpr_x6;
- case arm64_ehframe::x7: return gpr_x7;
- case arm64_ehframe::x8: return gpr_x8;
- case arm64_ehframe::x9: return gpr_x9;
- case arm64_ehframe::x10: return gpr_x10;
- case arm64_ehframe::x11: return gpr_x11;
- case arm64_ehframe::x12: return gpr_x12;
- case arm64_ehframe::x13: return gpr_x13;
- case arm64_ehframe::x14: return gpr_x14;
- case arm64_ehframe::x15: return gpr_x15;
- case arm64_ehframe::x16: return gpr_x16;
- case arm64_ehframe::x17: return gpr_x17;
- case arm64_ehframe::x18: return gpr_x18;
- case arm64_ehframe::x19: return gpr_x19;
- case arm64_ehframe::x20: return gpr_x20;
- case arm64_ehframe::x21: return gpr_x21;
- case arm64_ehframe::x22: return gpr_x22;
- case arm64_ehframe::x23: return gpr_x23;
- case arm64_ehframe::x24: return gpr_x24;
- case arm64_ehframe::x25: return gpr_x25;
- case arm64_ehframe::x26: return gpr_x26;
- case arm64_ehframe::x27: return gpr_x27;
- case arm64_ehframe::x28: return gpr_x28;
- case arm64_ehframe::fp: return gpr_fp;
- case arm64_ehframe::sp: return gpr_sp;
- case arm64_ehframe::lr: return gpr_lr;
- case arm64_ehframe::pc: return gpr_pc;
- case arm64_ehframe::cpsr: return gpr_cpsr;
- }
+ } else if (kind == eRegisterKindDWARF) {
+ switch (reg) {
+ case arm64_dwarf::x0:
+ return gpr_x0;
+ case arm64_dwarf::x1:
+ return gpr_x1;
+ case arm64_dwarf::x2:
+ return gpr_x2;
+ case arm64_dwarf::x3:
+ return gpr_x3;
+ case arm64_dwarf::x4:
+ return gpr_x4;
+ case arm64_dwarf::x5:
+ return gpr_x5;
+ case arm64_dwarf::x6:
+ return gpr_x6;
+ case arm64_dwarf::x7:
+ return gpr_x7;
+ case arm64_dwarf::x8:
+ return gpr_x8;
+ case arm64_dwarf::x9:
+ return gpr_x9;
+ case arm64_dwarf::x10:
+ return gpr_x10;
+ case arm64_dwarf::x11:
+ return gpr_x11;
+ case arm64_dwarf::x12:
+ return gpr_x12;
+ case arm64_dwarf::x13:
+ return gpr_x13;
+ case arm64_dwarf::x14:
+ return gpr_x14;
+ case arm64_dwarf::x15:
+ return gpr_x15;
+ case arm64_dwarf::x16:
+ return gpr_x16;
+ case arm64_dwarf::x17:
+ return gpr_x17;
+ case arm64_dwarf::x18:
+ return gpr_x18;
+ case arm64_dwarf::x19:
+ return gpr_x19;
+ case arm64_dwarf::x20:
+ return gpr_x20;
+ case arm64_dwarf::x21:
+ return gpr_x21;
+ case arm64_dwarf::x22:
+ return gpr_x22;
+ case arm64_dwarf::x23:
+ return gpr_x23;
+ case arm64_dwarf::x24:
+ return gpr_x24;
+ case arm64_dwarf::x25:
+ return gpr_x25;
+ case arm64_dwarf::x26:
+ return gpr_x26;
+ case arm64_dwarf::x27:
+ return gpr_x27;
+ case arm64_dwarf::x28:
+ return gpr_x28;
+
+ case arm64_dwarf::fp:
+ return gpr_fp;
+ case arm64_dwarf::sp:
+ return gpr_sp;
+ case arm64_dwarf::lr:
+ return gpr_lr;
+ case arm64_dwarf::pc:
+ return gpr_pc;
+ case arm64_dwarf::cpsr:
+ return gpr_cpsr;
+
+ case arm64_dwarf::v0:
+ return fpu_v0;
+ case arm64_dwarf::v1:
+ return fpu_v1;
+ case arm64_dwarf::v2:
+ return fpu_v2;
+ case arm64_dwarf::v3:
+ return fpu_v3;
+ case arm64_dwarf::v4:
+ return fpu_v4;
+ case arm64_dwarf::v5:
+ return fpu_v5;
+ case arm64_dwarf::v6:
+ return fpu_v6;
+ case arm64_dwarf::v7:
+ return fpu_v7;
+ case arm64_dwarf::v8:
+ return fpu_v8;
+ case arm64_dwarf::v9:
+ return fpu_v9;
+ case arm64_dwarf::v10:
+ return fpu_v10;
+ case arm64_dwarf::v11:
+ return fpu_v11;
+ case arm64_dwarf::v12:
+ return fpu_v12;
+ case arm64_dwarf::v13:
+ return fpu_v13;
+ case arm64_dwarf::v14:
+ return fpu_v14;
+ case arm64_dwarf::v15:
+ return fpu_v15;
+ case arm64_dwarf::v16:
+ return fpu_v16;
+ case arm64_dwarf::v17:
+ return fpu_v17;
+ case arm64_dwarf::v18:
+ return fpu_v18;
+ case arm64_dwarf::v19:
+ return fpu_v19;
+ case arm64_dwarf::v20:
+ return fpu_v20;
+ case arm64_dwarf::v21:
+ return fpu_v21;
+ case arm64_dwarf::v22:
+ return fpu_v22;
+ case arm64_dwarf::v23:
+ return fpu_v23;
+ case arm64_dwarf::v24:
+ return fpu_v24;
+ case arm64_dwarf::v25:
+ return fpu_v25;
+ case arm64_dwarf::v26:
+ return fpu_v26;
+ case arm64_dwarf::v27:
+ return fpu_v27;
+ case arm64_dwarf::v28:
+ return fpu_v28;
+ case arm64_dwarf::v29:
+ return fpu_v29;
+ case arm64_dwarf::v30:
+ return fpu_v30;
+ case arm64_dwarf::v31:
+ return fpu_v31;
+
+ default:
+ break;
}
- else if (kind == eRegisterKindLLDB)
- {
- return reg;
+ } else if (kind == eRegisterKindEHFrame) {
+ switch (reg) {
+ case arm64_ehframe::x0:
+ return gpr_x0;
+ case arm64_ehframe::x1:
+ return gpr_x1;
+ case arm64_ehframe::x2:
+ return gpr_x2;
+ case arm64_ehframe::x3:
+ return gpr_x3;
+ case arm64_ehframe::x4:
+ return gpr_x4;
+ case arm64_ehframe::x5:
+ return gpr_x5;
+ case arm64_ehframe::x6:
+ return gpr_x6;
+ case arm64_ehframe::x7:
+ return gpr_x7;
+ case arm64_ehframe::x8:
+ return gpr_x8;
+ case arm64_ehframe::x9:
+ return gpr_x9;
+ case arm64_ehframe::x10:
+ return gpr_x10;
+ case arm64_ehframe::x11:
+ return gpr_x11;
+ case arm64_ehframe::x12:
+ return gpr_x12;
+ case arm64_ehframe::x13:
+ return gpr_x13;
+ case arm64_ehframe::x14:
+ return gpr_x14;
+ case arm64_ehframe::x15:
+ return gpr_x15;
+ case arm64_ehframe::x16:
+ return gpr_x16;
+ case arm64_ehframe::x17:
+ return gpr_x17;
+ case arm64_ehframe::x18:
+ return gpr_x18;
+ case arm64_ehframe::x19:
+ return gpr_x19;
+ case arm64_ehframe::x20:
+ return gpr_x20;
+ case arm64_ehframe::x21:
+ return gpr_x21;
+ case arm64_ehframe::x22:
+ return gpr_x22;
+ case arm64_ehframe::x23:
+ return gpr_x23;
+ case arm64_ehframe::x24:
+ return gpr_x24;
+ case arm64_ehframe::x25:
+ return gpr_x25;
+ case arm64_ehframe::x26:
+ return gpr_x26;
+ case arm64_ehframe::x27:
+ return gpr_x27;
+ case arm64_ehframe::x28:
+ return gpr_x28;
+ case arm64_ehframe::fp:
+ return gpr_fp;
+ case arm64_ehframe::sp:
+ return gpr_sp;
+ case arm64_ehframe::lr:
+ return gpr_lr;
+ case arm64_ehframe::pc:
+ return gpr_pc;
+ case arm64_ehframe::cpsr:
+ return gpr_cpsr;
}
- return LLDB_INVALID_REGNUM;
+ } else if (kind == eRegisterKindLLDB) {
+ return reg;
+ }
+ return LLDB_INVALID_REGNUM;
}
-
-uint32_t
-RegisterContextDarwin_arm64::NumSupportedHardwareWatchpoints ()
-{
-#if defined (__arm64__) || defined (__aarch64__)
- // autodetect how many watchpoints are supported dynamically...
- static uint32_t g_num_supported_hw_watchpoints = UINT32_MAX;
- if (g_num_supported_hw_watchpoints == UINT32_MAX)
- {
- size_t len;
- uint32_t n = 0;
- len = sizeof (n);
- if (::sysctlbyname("hw.optional.watchpoint", &n, &len, NULL, 0) == 0)
- {
- g_num_supported_hw_watchpoints = n;
- }
+uint32_t RegisterContextDarwin_arm64::NumSupportedHardwareWatchpoints() {
+#if defined(__arm64__) || defined(__aarch64__)
+ // autodetect how many watchpoints are supported dynamically...
+ static uint32_t g_num_supported_hw_watchpoints = UINT32_MAX;
+ if (g_num_supported_hw_watchpoints == UINT32_MAX) {
+ size_t len;
+ uint32_t n = 0;
+ len = sizeof(n);
+ if (::sysctlbyname("hw.optional.watchpoint", &n, &len, NULL, 0) == 0) {
+ g_num_supported_hw_watchpoints = n;
}
- return g_num_supported_hw_watchpoints;
+ }
+ return g_num_supported_hw_watchpoints;
#else
- // TODO: figure out remote case here!
- return 2;
+ // TODO: figure out remote case here!
+ return 2;
#endif
}
+uint32_t RegisterContextDarwin_arm64::SetHardwareWatchpoint(lldb::addr_t addr,
+ size_t size,
+ bool read,
+ bool write) {
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint(addr = %8.8p,
+ // size = %u, read = %u, write = %u)", addr, size, read, write);
-uint32_t
-RegisterContextDarwin_arm64::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write)
-{
-// if (log) log->Printf ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint(addr = %8.8p, size = %u, read = %u, write = %u)", addr, size, read, write);
+ const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
- const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
+ // Can't watch zero bytes
+ if (size == 0)
+ return LLDB_INVALID_INDEX32;
- // Can't watch zero bytes
- if (size == 0)
- return LLDB_INVALID_INDEX32;
+ // We must watch for either read or write
+ if (read == false && write == false)
+ return LLDB_INVALID_INDEX32;
- // We must watch for either read or write
- if (read == false && write == false)
- return LLDB_INVALID_INDEX32;
+ // Can't watch more than 4 bytes per WVR/WCR pair
+ if (size > 4)
+ return LLDB_INVALID_INDEX32;
- // Can't watch more than 4 bytes per WVR/WCR pair
- if (size > 4)
- return LLDB_INVALID_INDEX32;
+ // We can only watch up to four bytes that follow a 4 byte aligned address
+ // per watchpoint register pair. Since we have at most so we can only watch
+ // until the next 4 byte boundary and we need to make sure we can properly
+ // encode this.
+ uint32_t addr_word_offset = addr % 4;
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() -
+ // addr_word_offset = 0x%8.8x", addr_word_offset);
+
+ uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset;
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() - byte_mask =
+ // 0x%8.8x", byte_mask);
+ if (byte_mask > 0xfu)
+ return LLDB_INVALID_INDEX32;
- // We can only watch up to four bytes that follow a 4 byte aligned address
- // per watchpoint register pair. Since we have at most so we can only watch
- // until the next 4 byte boundary and we need to make sure we can properly
- // encode this.
- uint32_t addr_word_offset = addr % 4;
-// if (log) log->Printf ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() - addr_word_offset = 0x%8.8x", addr_word_offset);
+ // Read the debug state
+ int kret = ReadDBG(false);
- uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset;
-// if (log) log->Printf ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() - byte_mask = 0x%8.8x", byte_mask);
- if (byte_mask > 0xfu)
- return LLDB_INVALID_INDEX32;
+ if (kret == KERN_SUCCESS) {
+ // Check to make sure we have the needed hardware support
+ uint32_t i = 0;
- // Read the debug state
- int kret = ReadDBG (false);
+ for (i = 0; i < num_hw_watchpoints; ++i) {
+ if ((dbg.wcr[i] & WCR_ENABLE) == 0)
+ break; // We found an available hw breakpoint slot (in i)
+ }
- if (kret == KERN_SUCCESS)
- {
- // Check to make sure we have the needed hardware support
- uint32_t i = 0;
-
- for (i=0; i<num_hw_watchpoints; ++i)
- {
- if ((dbg.wcr[i] & WCR_ENABLE) == 0)
- break; // We found an available hw breakpoint slot (in i)
- }
-
- // See if we found an available hw breakpoint slot above
- if (i < num_hw_watchpoints)
- {
- // Make the byte_mask into a valid Byte Address Select mask
- uint32_t byte_address_select = byte_mask << 5;
- // Make sure bits 1:0 are clear in our address
- dbg.wvr[i] = addr & ~((lldb::addr_t)3);
- dbg.wcr[i] = byte_address_select | // Which bytes that follow the IMVA that we will watch
- S_USER | // Stop only in user mode
- (read ? WCR_LOAD : 0) | // Stop on read access?
- (write ? WCR_STORE : 0) | // Stop on write access?
- WCR_ENABLE; // Enable this watchpoint;
-
- kret = WriteDBG();
-// if (log) log->Printf ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() WriteDBG() => 0x%8.8x.", kret);
-
- if (kret == KERN_SUCCESS)
- return i;
- }
- else
- {
-// if (log) log->Printf ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint(): All hardware resources (%u) are in use.", num_hw_watchpoints);
- }
+ // See if we found an available hw breakpoint slot above
+ if (i < num_hw_watchpoints) {
+ // Make the byte_mask into a valid Byte Address Select mask
+ uint32_t byte_address_select = byte_mask << 5;
+ // Make sure bits 1:0 are clear in our address
+ dbg.wvr[i] = addr & ~((lldb::addr_t)3);
+ dbg.wcr[i] = byte_address_select | // Which bytes that follow the IMVA
+ // that we will watch
+ S_USER | // Stop only in user mode
+ (read ? WCR_LOAD : 0) | // Stop on read access?
+ (write ? WCR_STORE : 0) | // Stop on write access?
+ WCR_ENABLE; // Enable this watchpoint;
+
+ kret = WriteDBG();
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint()
+ // WriteDBG() => 0x%8.8x.", kret);
+
+ if (kret == KERN_SUCCESS)
+ return i;
+ } else {
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint():
+ // All hardware resources (%u) are in use.",
+ // num_hw_watchpoints);
}
- return LLDB_INVALID_INDEX32;
+ }
+ return LLDB_INVALID_INDEX32;
}
-bool
-RegisterContextDarwin_arm64::ClearHardwareWatchpoint (uint32_t hw_index)
-{
- int kret = ReadDBG (false);
-
- const uint32_t num_hw_points = NumSupportedHardwareWatchpoints();
- if (kret == KERN_SUCCESS)
- {
- if (hw_index < num_hw_points)
- {
- dbg.wcr[hw_index] = 0;
-// if (log) log->Printf ("RegisterContextDarwin_arm64::ClearHardwareWatchpoint( %u ) - WVR%u = 0x%8.8x WCR%u = 0x%8.8x",
-// hw_index,
-// hw_index,
-// dbg.wvr[hw_index],
-// hw_index,
-// dbg.wcr[hw_index]);
-
- kret = WriteDBG();
-
- if (kret == KERN_SUCCESS)
- return true;
- }
+bool RegisterContextDarwin_arm64::ClearHardwareWatchpoint(uint32_t hw_index) {
+ int kret = ReadDBG(false);
+
+ const uint32_t num_hw_points = NumSupportedHardwareWatchpoints();
+ if (kret == KERN_SUCCESS) {
+ if (hw_index < num_hw_points) {
+ dbg.wcr[hw_index] = 0;
+ // if (log) log->Printf
+ // ("RegisterContextDarwin_arm64::ClearHardwareWatchpoint( %u )
+ // - WVR%u = 0x%8.8x WCR%u = 0x%8.8x",
+ // hw_index,
+ // hw_index,
+ // dbg.wvr[hw_index],
+ // hw_index,
+ // dbg.wcr[hw_index]);
+
+ kret = WriteDBG();
+
+ if (kret == KERN_SUCCESS)
+ return true;
}
- return false;
+ }
+ return false;
}
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h
index b228c42ade53..2d1fe0555b58 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h
@@ -1,4 +1,5 @@
-//===-- RegisterContextDarwin_arm64.h -----------------------------*- C++ -*-===//
+//===-- RegisterContextDarwin_arm64.h -----------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,279 +15,222 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/lldb-private.h"
// Break only in privileged or user mode
-#define S_RSVD ((uint32_t)(0u << 1))
-#define S_PRIV ((uint32_t)(1u << 1))
-#define S_USER ((uint32_t)(2u << 1))
-#define S_PRIV_USER ((S_PRIV) | (S_USER))
+#define S_RSVD ((uint32_t)(0u << 1))
+#define S_PRIV ((uint32_t)(1u << 1))
+#define S_USER ((uint32_t)(2u << 1))
+#define S_PRIV_USER ((S_PRIV) | (S_USER))
-#define WCR_ENABLE ((uint32_t)(1u))
+#define WCR_ENABLE ((uint32_t)(1u))
// Watchpoint load/store
-#define WCR_LOAD ((uint32_t)(1u << 3))
-#define WCR_STORE ((uint32_t)(1u << 4))
+#define WCR_LOAD ((uint32_t)(1u << 3))
+#define WCR_STORE ((uint32_t)(1u << 4))
-class RegisterContextDarwin_arm64 : public lldb_private::RegisterContext
-{
+class RegisterContextDarwin_arm64 : public lldb_private::RegisterContext {
public:
- RegisterContextDarwin_arm64(lldb_private::Thread &thread, uint32_t concrete_frame_idx);
-
- ~RegisterContextDarwin_arm64() override;
-
- void
- InvalidateAllRegisters() override;
-
- size_t
- GetRegisterCount() override;
-
- const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex(size_t reg) override;
-
- size_t
- GetRegisterSetCount() override;
-
- const lldb_private::RegisterSet *
- GetRegisterSet(size_t set) override;
-
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &reg_value) override;
-
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &reg_value) override;
-
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
-
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
-
- uint32_t
- ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
-
- uint32_t
- NumSupportedHardwareWatchpoints() override;
-
- uint32_t
- SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write) override;
-
- bool
- ClearHardwareWatchpoint(uint32_t hw_index) override;
-
- // mirrors <mach/arm/thread_status.h> arm_thread_state64_t
- struct GPR
- {
- uint64_t x[29]; // x0-x28
- uint64_t fp; // x29
- uint64_t lr; // x30
- uint64_t sp; // x31
- uint64_t pc; // pc
- uint32_t cpsr; // cpsr
- };
-
- struct VReg
- {
- uint8_t bytes[16];
- };
-
- // mirrors <mach/arm/thread_status.h> arm_neon_state64_t
- struct FPU
- {
- VReg v[32];
- uint32_t fpsr;
- uint32_t fpcr;
- };
-
- // mirrors <mach/arm/thread_status.h> arm_exception_state64_t
- struct EXC
- {
- uint64_t far; // Virtual Fault Address
- uint32_t esr; // Exception syndrome
- uint32_t exception; // number of arm exception token
- };
-
- // mirrors <mach/arm/thread_status.h> arm_debug_state64_t
- struct DBG
- {
- uint64_t bvr[16];
- uint64_t bcr[16];
- uint64_t wvr[16];
- uint64_t wcr[16];
- uint64_t mdscr_el1;
- };
-
- static void
- LogDBGRegisters (lldb_private::Log *log, const DBG& dbg);
+ RegisterContextDarwin_arm64(lldb_private::Thread &thread,
+ uint32_t concrete_frame_idx);
+
+ ~RegisterContextDarwin_arm64() override;
+
+ void InvalidateAllRegisters() override;
+
+ size_t GetRegisterCount() override;
+
+ const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
+
+ size_t GetRegisterSetCount() override;
+
+ const lldb_private::RegisterSet *GetRegisterSet(size_t set) override;
+
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &reg_value) override;
+
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &reg_value) override;
+
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
+
+ uint32_t NumSupportedHardwareWatchpoints() override;
+
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read,
+ bool write) override;
+
+ bool ClearHardwareWatchpoint(uint32_t hw_index) override;
+
+ // mirrors <mach/arm/thread_status.h> arm_thread_state64_t
+ struct GPR {
+ uint64_t x[29]; // x0-x28
+ uint64_t fp; // x29
+ uint64_t lr; // x30
+ uint64_t sp; // x31
+ uint64_t pc; // pc
+ uint32_t cpsr; // cpsr
+ };
+
+ struct VReg {
+ uint8_t bytes[16];
+ };
+
+ // mirrors <mach/arm/thread_status.h> arm_neon_state64_t
+ struct FPU {
+ VReg v[32];
+ uint32_t fpsr;
+ uint32_t fpcr;
+ };
+
+ // mirrors <mach/arm/thread_status.h> arm_exception_state64_t
+ struct EXC {
+ uint64_t far; // Virtual Fault Address
+ uint32_t esr; // Exception syndrome
+ uint32_t exception; // number of arm exception token
+ };
+
+ // mirrors <mach/arm/thread_status.h> arm_debug_state64_t
+ struct DBG {
+ uint64_t bvr[16];
+ uint64_t bcr[16];
+ uint64_t wvr[16];
+ uint64_t wcr[16];
+ uint64_t mdscr_el1;
+ };
+
+ static void LogDBGRegisters(lldb_private::Log *log, const DBG &dbg);
protected:
- enum
- {
- GPRRegSet = 6, // ARM_THREAD_STATE64
- FPURegSet = 17, // ARM_NEON_STATE64
- EXCRegSet = 7, // ARM_EXCEPTION_STATE64
- DBGRegSet = 15 // ARM_DEBUG_STATE64
- };
-
- enum
- {
- GPRWordCount = sizeof(GPR)/sizeof(uint32_t), // ARM_THREAD_STATE64_COUNT
- FPUWordCount = sizeof(FPU)/sizeof(uint32_t), // ARM_NEON_STATE64_COUNT
- EXCWordCount = sizeof(EXC)/sizeof(uint32_t), // ARM_EXCEPTION_STATE64_COUNT
- DBGWordCount = sizeof(DBG)/sizeof(uint32_t) // ARM_DEBUG_STATE64_COUNT
- };
-
- enum
- {
- Read = 0,
- Write = 1,
- kNumErrors = 2
- };
-
- GPR gpr;
- FPU fpu;
- EXC exc;
- DBG dbg;
- int gpr_errs[2]; // Read/Write errors
- int fpu_errs[2]; // Read/Write errors
- int exc_errs[2]; // Read/Write errors
- int dbg_errs[2]; // Read/Write errors
-
- void
- InvalidateAllRegisterStates()
- {
- SetError (GPRRegSet, Read, -1);
- SetError (FPURegSet, Read, -1);
- SetError (EXCRegSet, Read, -1);
+ enum {
+ GPRRegSet = 6, // ARM_THREAD_STATE64
+ FPURegSet = 17, // ARM_NEON_STATE64
+ EXCRegSet = 7, // ARM_EXCEPTION_STATE64
+ DBGRegSet = 15 // ARM_DEBUG_STATE64
+ };
+
+ enum {
+ GPRWordCount = sizeof(GPR) / sizeof(uint32_t), // ARM_THREAD_STATE64_COUNT
+ FPUWordCount = sizeof(FPU) / sizeof(uint32_t), // ARM_NEON_STATE64_COUNT
+ EXCWordCount =
+ sizeof(EXC) / sizeof(uint32_t), // ARM_EXCEPTION_STATE64_COUNT
+ DBGWordCount = sizeof(DBG) / sizeof(uint32_t) // ARM_DEBUG_STATE64_COUNT
+ };
+
+ enum { Read = 0, Write = 1, kNumErrors = 2 };
+
+ GPR gpr;
+ FPU fpu;
+ EXC exc;
+ DBG dbg;
+ int gpr_errs[2]; // Read/Write errors
+ int fpu_errs[2]; // Read/Write errors
+ int exc_errs[2]; // Read/Write errors
+ int dbg_errs[2]; // Read/Write errors
+
+ void InvalidateAllRegisterStates() {
+ SetError(GPRRegSet, Read, -1);
+ SetError(FPURegSet, Read, -1);
+ SetError(EXCRegSet, Read, -1);
+ }
+
+ int GetError(int flavor, uint32_t err_idx) const {
+ if (err_idx < kNumErrors) {
+ switch (flavor) {
+ // When getting all errors, just OR all values together to see if
+ // we got any kind of error.
+ case GPRRegSet:
+ return gpr_errs[err_idx];
+ case FPURegSet:
+ return fpu_errs[err_idx];
+ case EXCRegSet:
+ return exc_errs[err_idx];
+ case DBGRegSet:
+ return dbg_errs[err_idx];
+ default:
+ break;
+ }
}
-
- int
- GetError (int flavor, uint32_t err_idx) const
- {
- if (err_idx < kNumErrors)
- {
- switch (flavor)
- {
- // When getting all errors, just OR all values together to see if
- // we got any kind of error.
- case GPRRegSet: return gpr_errs[err_idx];
- case FPURegSet: return fpu_errs[err_idx];
- case EXCRegSet: return exc_errs[err_idx];
- case DBGRegSet: return dbg_errs[err_idx];
- default: break;
- }
- }
- return -1;
+ return -1;
+ }
+
+ bool SetError(int flavor, uint32_t err_idx, int err) {
+ if (err_idx < kNumErrors) {
+ switch (flavor) {
+ case GPRRegSet:
+ gpr_errs[err_idx] = err;
+ return true;
+
+ case FPURegSet:
+ fpu_errs[err_idx] = err;
+ return true;
+
+ case EXCRegSet:
+ exc_errs[err_idx] = err;
+ return true;
+
+ case DBGRegSet:
+ exc_errs[err_idx] = err;
+ return true;
+
+ default:
+ break;
+ }
}
+ return false;
+ }
- bool
- SetError (int flavor, uint32_t err_idx, int err)
- {
- if (err_idx < kNumErrors)
- {
- switch (flavor)
- {
- case GPRRegSet:
- gpr_errs[err_idx] = err;
- return true;
-
- case FPURegSet:
- fpu_errs[err_idx] = err;
- return true;
-
- case EXCRegSet:
- exc_errs[err_idx] = err;
- return true;
-
- case DBGRegSet:
- exc_errs[err_idx] = err;
- return true;
-
- default: break;
- }
- }
- return false;
- }
+ bool RegisterSetIsCached(int set) const { return GetError(set, Read) == 0; }
- bool
- RegisterSetIsCached (int set) const
- {
- return GetError(set, Read) == 0;
- }
+ int ReadGPR(bool force);
- int
- ReadGPR (bool force);
+ int ReadFPU(bool force);
- int
- ReadFPU (bool force);
+ int ReadEXC(bool force);
- int
- ReadEXC (bool force);
+ int ReadDBG(bool force);
- int
- ReadDBG (bool force);
+ int WriteGPR();
- int
- WriteGPR ();
+ int WriteFPU();
- int
- WriteFPU ();
+ int WriteEXC();
- int
- WriteEXC ();
+ int WriteDBG();
- int
- WriteDBG ();
+ // Subclasses override these to do the actual reading.
+ virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) { return -1; }
-
- // Subclasses override these to do the actual reading.
- virtual int
- DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
- {
- return -1;
- }
-
- virtual int
- DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu) = 0;
-
- virtual int
- DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc) = 0;
+ virtual int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) = 0;
+
+ virtual int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) = 0;
+
+ virtual int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) = 0;
+
+ virtual int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) = 0;
- virtual int
- DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg) = 0;
+ virtual int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) = 0;
- virtual int
- DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr) = 0;
-
- virtual int
- DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu) = 0;
-
- virtual int
- DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc) = 0;
+ virtual int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) = 0;
- virtual int
- DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg) = 0;
+ virtual int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) = 0;
- int
- ReadRegisterSet (uint32_t set, bool force);
+ int ReadRegisterSet(uint32_t set, bool force);
- int
- WriteRegisterSet (uint32_t set);
+ int WriteRegisterSet(uint32_t set);
- static uint32_t
- GetRegisterNumber (uint32_t reg_kind, uint32_t reg_num);
+ static uint32_t GetRegisterNumber(uint32_t reg_kind, uint32_t reg_num);
- static int
- GetSetForNativeRegNum (int reg_num);
+ static int GetSetForNativeRegNum(int reg_num);
- static size_t
- GetRegisterInfosCount ();
+ static size_t GetRegisterInfosCount();
- static const lldb_private::RegisterInfo *
- GetRegisterInfos ();
+ static const lldb_private::RegisterInfo *GetRegisterInfos();
};
#endif // liblldb_RegisterContextDarwin_arm64_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp
index 1b01c28b5d96..f42fb00b375f 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp
@@ -7,9 +7,8 @@
//
//===----------------------------------------------------------------------===//
-
// C Includes
-#include <stddef.h> // offsetof
+#include <stddef.h> // offsetof
// C++ Includes
// Other libraries and framework includes
@@ -34,302 +33,430 @@
using namespace lldb;
using namespace lldb_private;
-enum
-{
- gpr_eax = 0,
- gpr_ebx,
- gpr_ecx,
- gpr_edx,
- gpr_edi,
- gpr_esi,
- gpr_ebp,
- gpr_esp,
- gpr_ss,
- gpr_eflags,
- gpr_eip,
- gpr_cs,
- gpr_ds,
- gpr_es,
- gpr_fs,
- gpr_gs,
-
- fpu_fcw,
- fpu_fsw,
- fpu_ftw,
- fpu_fop,
- fpu_ip,
- fpu_cs,
- fpu_dp,
- fpu_ds,
- fpu_mxcsr,
- fpu_mxcsrmask,
- fpu_stmm0,
- fpu_stmm1,
- fpu_stmm2,
- fpu_stmm3,
- fpu_stmm4,
- fpu_stmm5,
- fpu_stmm6,
- fpu_stmm7,
- fpu_xmm0,
- fpu_xmm1,
- fpu_xmm2,
- fpu_xmm3,
- fpu_xmm4,
- fpu_xmm5,
- fpu_xmm6,
- fpu_xmm7,
-
- exc_trapno,
- exc_err,
- exc_faultvaddr,
-
- k_num_registers,
-
- // Aliases
- fpu_fctrl = fpu_fcw,
- fpu_fstat = fpu_fsw,
- fpu_ftag = fpu_ftw,
- fpu_fiseg = fpu_cs,
- fpu_fioff = fpu_ip,
- fpu_foseg = fpu_ds,
- fpu_fooff = fpu_dp
+enum {
+ gpr_eax = 0,
+ gpr_ebx,
+ gpr_ecx,
+ gpr_edx,
+ gpr_edi,
+ gpr_esi,
+ gpr_ebp,
+ gpr_esp,
+ gpr_ss,
+ gpr_eflags,
+ gpr_eip,
+ gpr_cs,
+ gpr_ds,
+ gpr_es,
+ gpr_fs,
+ gpr_gs,
+
+ fpu_fcw,
+ fpu_fsw,
+ fpu_ftw,
+ fpu_fop,
+ fpu_ip,
+ fpu_cs,
+ fpu_dp,
+ fpu_ds,
+ fpu_mxcsr,
+ fpu_mxcsrmask,
+ fpu_stmm0,
+ fpu_stmm1,
+ fpu_stmm2,
+ fpu_stmm3,
+ fpu_stmm4,
+ fpu_stmm5,
+ fpu_stmm6,
+ fpu_stmm7,
+ fpu_xmm0,
+ fpu_xmm1,
+ fpu_xmm2,
+ fpu_xmm3,
+ fpu_xmm4,
+ fpu_xmm5,
+ fpu_xmm6,
+ fpu_xmm7,
+
+ exc_trapno,
+ exc_err,
+ exc_faultvaddr,
+
+ k_num_registers,
+
+ // Aliases
+ fpu_fctrl = fpu_fcw,
+ fpu_fstat = fpu_fsw,
+ fpu_ftag = fpu_ftw,
+ fpu_fiseg = fpu_cs,
+ fpu_fioff = fpu_ip,
+ fpu_foseg = fpu_ds,
+ fpu_fooff = fpu_dp
};
-enum
-{
- ehframe_eax = 0,
- ehframe_ecx,
- ehframe_edx,
- ehframe_ebx,
- ehframe_ebp,
- ehframe_esp,
- ehframe_esi,
- ehframe_edi,
- ehframe_eip,
- ehframe_eflags
+enum {
+ ehframe_eax = 0,
+ ehframe_ecx,
+ ehframe_edx,
+ ehframe_ebx,
+ ehframe_ebp,
+ ehframe_esp,
+ ehframe_esi,
+ ehframe_edi,
+ ehframe_eip,
+ ehframe_eflags
};
-enum
-{
- dwarf_eax = 0,
- dwarf_ecx,
- dwarf_edx,
- dwarf_ebx,
- dwarf_esp,
- dwarf_ebp,
- dwarf_esi,
- dwarf_edi,
- dwarf_eip,
- dwarf_eflags,
- dwarf_stmm0 = 11,
- dwarf_stmm1,
- dwarf_stmm2,
- dwarf_stmm3,
- dwarf_stmm4,
- dwarf_stmm5,
- dwarf_stmm6,
- dwarf_stmm7,
- dwarf_xmm0 = 21,
- dwarf_xmm1,
- dwarf_xmm2,
- dwarf_xmm3,
- dwarf_xmm4,
- dwarf_xmm5,
- dwarf_xmm6,
- dwarf_xmm7
+enum {
+ dwarf_eax = 0,
+ dwarf_ecx,
+ dwarf_edx,
+ dwarf_ebx,
+ dwarf_esp,
+ dwarf_ebp,
+ dwarf_esi,
+ dwarf_edi,
+ dwarf_eip,
+ dwarf_eflags,
+ dwarf_stmm0 = 11,
+ dwarf_stmm1,
+ dwarf_stmm2,
+ dwarf_stmm3,
+ dwarf_stmm4,
+ dwarf_stmm5,
+ dwarf_stmm6,
+ dwarf_stmm7,
+ dwarf_xmm0 = 21,
+ dwarf_xmm1,
+ dwarf_xmm2,
+ dwarf_xmm3,
+ dwarf_xmm4,
+ dwarf_xmm5,
+ dwarf_xmm6,
+ dwarf_xmm7
};
-
-#define GPR_OFFSET(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_i386::GPR, reg))
-#define FPU_OFFSET(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_i386::FPU, reg) + sizeof (RegisterContextDarwin_i386::GPR))
-#define EXC_OFFSET(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_i386::EXC, reg) + sizeof (RegisterContextDarwin_i386::GPR) + sizeof (RegisterContextDarwin_i386::FPU))
+#define GPR_OFFSET(reg) \
+ (LLVM_EXTENSION offsetof(RegisterContextDarwin_i386::GPR, reg))
+#define FPU_OFFSET(reg) \
+ (LLVM_EXTENSION offsetof(RegisterContextDarwin_i386::FPU, reg) + \
+ sizeof(RegisterContextDarwin_i386::GPR))
+#define EXC_OFFSET(reg) \
+ (LLVM_EXTENSION offsetof(RegisterContextDarwin_i386::EXC, reg) + \
+ sizeof(RegisterContextDarwin_i386::GPR) + \
+ sizeof(RegisterContextDarwin_i386::FPU))
// These macros will auto define the register name, alt name, register size,
// register offset, encoding, format and native register. This ensures that
// the register state structures are defined correctly and have the correct
// sizes and offsets.
-#define DEFINE_GPR(reg, alt) #reg, alt, sizeof(((RegisterContextDarwin_i386::GPR *)NULL)->reg), GPR_OFFSET(reg), eEncodingUint, eFormatHex
-#define DEFINE_FPU_UINT(reg) #reg, NULL, sizeof(((RegisterContextDarwin_i386::FPU *)NULL)->reg), FPU_OFFSET(reg), eEncodingUint, eFormatHex
-#define DEFINE_FPU_VECT(reg, i) #reg#i, NULL, sizeof(((RegisterContextDarwin_i386::FPU *)NULL)->reg[i].bytes), FPU_OFFSET(reg[i]), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_##reg##i, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_##reg##i }, NULL, NULL
-
-#define DEFINE_EXC(reg) #reg, NULL, sizeof(((RegisterContextDarwin_i386::EXC *)NULL)->reg), EXC_OFFSET(reg), eEncodingUint, eFormatHex
-#define REG_CONTEXT_SIZE (sizeof (RegisterContextDarwin_i386::GPR) + sizeof (RegisterContextDarwin_i386::FPU) + sizeof (RegisterContextDarwin_i386::EXC))
-
-static RegisterInfo g_register_infos[] =
-{
-// Macro auto defines most stuff eh_frame DWARF GENERIC PROCESS PLUGIN LLDB VALUE REGS INVALIDATE REGS
-// =============================== ======================= =================== ========================= ================== ================= ========== ===============
- { DEFINE_GPR(eax , NULL) , { ehframe_eax , dwarf_eax , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_eax }, NULL, NULL},
- { DEFINE_GPR(ebx , NULL) , { ehframe_ebx , dwarf_ebx , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_ebx }, NULL, NULL},
- { DEFINE_GPR(ecx , NULL) , { ehframe_ecx , dwarf_ecx , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_ecx }, NULL, NULL},
- { DEFINE_GPR(edx , NULL) , { ehframe_edx , dwarf_edx , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_edx }, NULL, NULL},
- { DEFINE_GPR(edi , NULL) , { ehframe_edi , dwarf_edi , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_edi }, NULL, NULL},
- { DEFINE_GPR(esi , NULL) , { ehframe_esi , dwarf_esi , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_esi }, NULL, NULL},
- { DEFINE_GPR(ebp , "fp") , { ehframe_ebp , dwarf_ebp , LLDB_REGNUM_GENERIC_FP , LLDB_INVALID_REGNUM, gpr_ebp }, NULL, NULL},
- { DEFINE_GPR(esp , "sp") , { ehframe_esp , dwarf_esp , LLDB_REGNUM_GENERIC_SP , LLDB_INVALID_REGNUM, gpr_esp }, NULL, NULL},
- { DEFINE_GPR(ss , NULL) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_ss }, NULL, NULL},
- { DEFINE_GPR(eflags , "flags") , { ehframe_eflags , dwarf_eflags , LLDB_REGNUM_GENERIC_FLAGS , LLDB_INVALID_REGNUM, gpr_eflags }, NULL, NULL},
- { DEFINE_GPR(eip , "pc") , { ehframe_eip , dwarf_eip , LLDB_REGNUM_GENERIC_PC , LLDB_INVALID_REGNUM, gpr_eip }, NULL, NULL},
- { DEFINE_GPR(cs , NULL) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_cs }, NULL, NULL},
- { DEFINE_GPR(ds , NULL) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_ds }, NULL, NULL},
- { DEFINE_GPR(es , NULL) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_es }, NULL, NULL},
- { DEFINE_GPR(fs , NULL) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_fs }, NULL, NULL},
- { DEFINE_GPR(gs , NULL) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_gs }, NULL, NULL},
-
- { DEFINE_FPU_UINT(fcw) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_fcw }, NULL, NULL},
- { DEFINE_FPU_UINT(fsw) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_fsw }, NULL, NULL},
- { DEFINE_FPU_UINT(ftw) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_ftw }, NULL, NULL},
- { DEFINE_FPU_UINT(fop) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_fop }, NULL, NULL},
- { DEFINE_FPU_UINT(ip) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_ip }, NULL, NULL},
- { DEFINE_FPU_UINT(cs) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_cs }, NULL, NULL},
- { DEFINE_FPU_UINT(dp) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_dp }, NULL, NULL},
- { DEFINE_FPU_UINT(ds) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_ds }, NULL, NULL},
- { DEFINE_FPU_UINT(mxcsr) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_mxcsr }, NULL, NULL},
- { DEFINE_FPU_UINT(mxcsrmask) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_mxcsrmask}, NULL, NULL},
- { DEFINE_FPU_VECT(stmm,0) },
- { DEFINE_FPU_VECT(stmm,1) },
- { DEFINE_FPU_VECT(stmm,2) },
- { DEFINE_FPU_VECT(stmm,3) },
- { DEFINE_FPU_VECT(stmm,4) },
- { DEFINE_FPU_VECT(stmm,5) },
- { DEFINE_FPU_VECT(stmm,6) },
- { DEFINE_FPU_VECT(stmm,7) },
- { DEFINE_FPU_VECT(xmm,0) },
- { DEFINE_FPU_VECT(xmm,1) },
- { DEFINE_FPU_VECT(xmm,2) },
- { DEFINE_FPU_VECT(xmm,3) },
- { DEFINE_FPU_VECT(xmm,4) },
- { DEFINE_FPU_VECT(xmm,5) },
- { DEFINE_FPU_VECT(xmm,6) },
- { DEFINE_FPU_VECT(xmm,7) },
-
- { DEFINE_EXC(trapno) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, exc_trapno }, NULL, NULL},
- { DEFINE_EXC(err) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, exc_err }, NULL, NULL},
- { DEFINE_EXC(faultvaddr) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, exc_faultvaddr }, NULL, NULL}
-};
+#define DEFINE_GPR(reg, alt) \
+ #reg, alt, sizeof(((RegisterContextDarwin_i386::GPR *) NULL)->reg), \
+ GPR_OFFSET(reg), eEncodingUint, eFormatHex
+#define DEFINE_FPU_UINT(reg) \
+ #reg, NULL, sizeof(((RegisterContextDarwin_i386::FPU *) NULL)->reg), \
+ FPU_OFFSET(reg), eEncodingUint, eFormatHex
+#define DEFINE_FPU_VECT(reg, i) \
+ #reg #i, NULL, \
+ sizeof(((RegisterContextDarwin_i386::FPU *) NULL)->reg[i].bytes), \
+ FPU_OFFSET(reg[i]), eEncodingVector, eFormatVectorOfUInt8, \
+ {LLDB_INVALID_REGNUM, dwarf_##reg##i, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ fpu_##reg##i }, \
+ nullptr, nullptr, nullptr, 0
+
+#define DEFINE_EXC(reg) \
+ #reg, NULL, sizeof(((RegisterContextDarwin_i386::EXC *) NULL)->reg), \
+ EXC_OFFSET(reg), eEncodingUint, eFormatHex
+#define REG_CONTEXT_SIZE \
+ (sizeof(RegisterContextDarwin_i386::GPR) + \
+ sizeof(RegisterContextDarwin_i386::FPU) + \
+ sizeof(RegisterContextDarwin_i386::EXC))
+
+static RegisterInfo g_register_infos[] = {
+ // Macro auto defines most stuff eh_frame DWARF
+ // GENERIC PROCESS PLUGIN LLDB
+ // =============================== =======================
+ // =================== ========================= ==================
+ // =================
+ {DEFINE_GPR(eax, NULL),
+ {ehframe_eax, dwarf_eax, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ gpr_eax},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(ebx, NULL),
+ {ehframe_ebx, dwarf_ebx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ gpr_ebx},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(ecx, NULL),
+ {ehframe_ecx, dwarf_ecx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ gpr_ecx},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(edx, NULL),
+ {ehframe_edx, dwarf_edx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ gpr_edx},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(edi, NULL),
+ {ehframe_edi, dwarf_edi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ gpr_edi},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(esi, NULL),
+ {ehframe_esi, dwarf_esi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ gpr_esi},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(ebp, "fp"),
+ {ehframe_ebp, dwarf_ebp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
+ gpr_ebp},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(esp, "sp"),
+ {ehframe_esp, dwarf_esp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
+ gpr_esp},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(ss, NULL),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_ss},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(eflags, "flags"),
+ {ehframe_eflags, dwarf_eflags, LLDB_REGNUM_GENERIC_FLAGS,
+ LLDB_INVALID_REGNUM, gpr_eflags},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(eip, "pc"),
+ {ehframe_eip, dwarf_eip, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
+ gpr_eip},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(cs, NULL),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_cs},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(ds, NULL),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_ds},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(es, NULL),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_es},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(fs, NULL),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_fs},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(gs, NULL),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_gs},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+
+ {DEFINE_FPU_UINT(fcw),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_fcw},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(fsw),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_fsw},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(ftw),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_ftw},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(fop),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_fop},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(ip),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_ip},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(cs),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_cs},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(dp),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_dp},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(ds),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_ds},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(mxcsr),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_mxcsr},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(mxcsrmask),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_mxcsrmask},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_VECT(stmm, 0)},
+ {DEFINE_FPU_VECT(stmm, 1)},
+ {DEFINE_FPU_VECT(stmm, 2)},
+ {DEFINE_FPU_VECT(stmm, 3)},
+ {DEFINE_FPU_VECT(stmm, 4)},
+ {DEFINE_FPU_VECT(stmm, 5)},
+ {DEFINE_FPU_VECT(stmm, 6)},
+ {DEFINE_FPU_VECT(stmm, 7)},
+ {DEFINE_FPU_VECT(xmm, 0)},
+ {DEFINE_FPU_VECT(xmm, 1)},
+ {DEFINE_FPU_VECT(xmm, 2)},
+ {DEFINE_FPU_VECT(xmm, 3)},
+ {DEFINE_FPU_VECT(xmm, 4)},
+ {DEFINE_FPU_VECT(xmm, 5)},
+ {DEFINE_FPU_VECT(xmm, 6)},
+ {DEFINE_FPU_VECT(xmm, 7)},
+
+ {DEFINE_EXC(trapno),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, exc_trapno},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_EXC(err),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, exc_err},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_EXC(faultvaddr),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, exc_faultvaddr},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0}};
static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
-RegisterContextDarwin_i386::RegisterContextDarwin_i386 (Thread &thread, uint32_t concrete_frame_idx) :
- RegisterContext(thread, concrete_frame_idx),
- gpr(),
- fpu(),
- exc()
-{
- uint32_t i;
- for (i=0; i<kNumErrors; i++)
- {
- gpr_errs[i] = -1;
- fpu_errs[i] = -1;
- exc_errs[i] = -1;
- }
-}
-
-RegisterContextDarwin_i386::~RegisterContextDarwin_i386()
-{
+RegisterContextDarwin_i386::RegisterContextDarwin_i386(
+ Thread &thread, uint32_t concrete_frame_idx)
+ : RegisterContext(thread, concrete_frame_idx), gpr(), fpu(), exc() {
+ uint32_t i;
+ for (i = 0; i < kNumErrors; i++) {
+ gpr_errs[i] = -1;
+ fpu_errs[i] = -1;
+ exc_errs[i] = -1;
+ }
}
+RegisterContextDarwin_i386::~RegisterContextDarwin_i386() {}
-void
-RegisterContextDarwin_i386::InvalidateAllRegisters ()
-{
- InvalidateAllRegisterStates();
+void RegisterContextDarwin_i386::InvalidateAllRegisters() {
+ InvalidateAllRegisterStates();
}
-
-size_t
-RegisterContextDarwin_i386::GetRegisterCount ()
-{
- assert(k_num_register_infos == k_num_registers);
- return k_num_registers;
+size_t RegisterContextDarwin_i386::GetRegisterCount() {
+ assert(k_num_register_infos == k_num_registers);
+ return k_num_registers;
}
const RegisterInfo *
-RegisterContextDarwin_i386::GetRegisterInfoAtIndex (size_t reg)
-{
- assert(k_num_register_infos == k_num_registers);
- if (reg < k_num_registers)
- return &g_register_infos[reg];
- return NULL;
+RegisterContextDarwin_i386::GetRegisterInfoAtIndex(size_t reg) {
+ assert(k_num_register_infos == k_num_registers);
+ if (reg < k_num_registers)
+ return &g_register_infos[reg];
+ return NULL;
}
-size_t
-RegisterContextDarwin_i386::GetRegisterInfosCount ()
-{
- return k_num_register_infos;
+size_t RegisterContextDarwin_i386::GetRegisterInfosCount() {
+ return k_num_register_infos;
}
-const RegisterInfo *
-RegisterContextDarwin_i386::GetRegisterInfos ()
-{
- return g_register_infos;
+const RegisterInfo *RegisterContextDarwin_i386::GetRegisterInfos() {
+ return g_register_infos;
}
-
// General purpose registers
-static uint32_t
-g_gpr_regnums[] =
-{
- gpr_eax,
- gpr_ebx,
- gpr_ecx,
- gpr_edx,
- gpr_edi,
- gpr_esi,
- gpr_ebp,
- gpr_esp,
- gpr_ss,
- gpr_eflags,
- gpr_eip,
- gpr_cs,
- gpr_ds,
- gpr_es,
- gpr_fs,
- gpr_gs
-};
+static uint32_t g_gpr_regnums[] = {
+ gpr_eax, gpr_ebx, gpr_ecx, gpr_edx, gpr_edi, gpr_esi, gpr_ebp, gpr_esp,
+ gpr_ss, gpr_eflags, gpr_eip, gpr_cs, gpr_ds, gpr_es, gpr_fs, gpr_gs};
// Floating point registers
-static uint32_t
-g_fpu_regnums[] =
-{
- fpu_fcw,
- fpu_fsw,
- fpu_ftw,
- fpu_fop,
- fpu_ip,
- fpu_cs,
- fpu_dp,
- fpu_ds,
- fpu_mxcsr,
- fpu_mxcsrmask,
- fpu_stmm0,
- fpu_stmm1,
- fpu_stmm2,
- fpu_stmm3,
- fpu_stmm4,
- fpu_stmm5,
- fpu_stmm6,
- fpu_stmm7,
- fpu_xmm0,
- fpu_xmm1,
- fpu_xmm2,
- fpu_xmm3,
- fpu_xmm4,
- fpu_xmm5,
- fpu_xmm6,
- fpu_xmm7
-};
+static uint32_t g_fpu_regnums[] = {
+ fpu_fcw, fpu_fsw, fpu_ftw, fpu_fop, fpu_ip, fpu_cs,
+ fpu_dp, fpu_ds, fpu_mxcsr, fpu_mxcsrmask, fpu_stmm0, fpu_stmm1,
+ fpu_stmm2, fpu_stmm3, fpu_stmm4, fpu_stmm5, fpu_stmm6, fpu_stmm7,
+ fpu_xmm0, fpu_xmm1, fpu_xmm2, fpu_xmm3, fpu_xmm4, fpu_xmm5,
+ fpu_xmm6, fpu_xmm7};
// Exception registers
-static uint32_t
-g_exc_regnums[] =
-{
- exc_trapno,
- exc_err,
- exc_faultvaddr
-};
+static uint32_t g_exc_regnums[] = {exc_trapno, exc_err, exc_faultvaddr};
// Number of registers in each register set
const size_t k_num_gpr_registers = llvm::array_lengthof(g_gpr_regnums);
@@ -341,539 +468,514 @@ const size_t k_num_exc_registers = llvm::array_lengthof(g_exc_regnums);
// of zero is for all registers, followed by other registers sets. The
// register information for the all register set need not be filled in.
//----------------------------------------------------------------------
-static const RegisterSet g_reg_sets[] =
-{
- { "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums, },
- { "Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums },
- { "Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums }
-};
+static const RegisterSet g_reg_sets[] = {
+ {
+ "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums,
+ },
+ {"Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums},
+ {"Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums}};
const size_t k_num_regsets = llvm::array_lengthof(g_reg_sets);
-
-size_t
-RegisterContextDarwin_i386::GetRegisterSetCount ()
-{
- return k_num_regsets;
+size_t RegisterContextDarwin_i386::GetRegisterSetCount() {
+ return k_num_regsets;
}
-const RegisterSet *
-RegisterContextDarwin_i386::GetRegisterSet (size_t reg_set)
-{
- if (reg_set < k_num_regsets)
- return &g_reg_sets[reg_set];
- return NULL;
+const RegisterSet *RegisterContextDarwin_i386::GetRegisterSet(size_t reg_set) {
+ if (reg_set < k_num_regsets)
+ return &g_reg_sets[reg_set];
+ return NULL;
}
-
//----------------------------------------------------------------------
// Register information definitions for 32 bit i386.
//----------------------------------------------------------------------
-int
-RegisterContextDarwin_i386::GetSetForNativeRegNum (int reg_num)
-{
- if (reg_num < fpu_fcw)
- return GPRRegSet;
- else if (reg_num < exc_trapno)
- return FPURegSet;
- else if (reg_num < k_num_registers)
- return EXCRegSet;
- return -1;
+int RegisterContextDarwin_i386::GetSetForNativeRegNum(int reg_num) {
+ if (reg_num < fpu_fcw)
+ return GPRRegSet;
+ else if (reg_num < exc_trapno)
+ return FPURegSet;
+ else if (reg_num < k_num_registers)
+ return EXCRegSet;
+ return -1;
}
-
-void
-RegisterContextDarwin_i386::LogGPR(Log *log, const char *title)
-{
- if (log)
- {
- if (title)
- log->Printf ("%s", title);
- for (uint32_t i=0; i<k_num_gpr_registers; i++)
- {
- uint32_t reg = gpr_eax + i;
- log->Printf("%12s = 0x%8.8x", g_register_infos[reg].name, (&gpr.eax)[reg]);
- }
+void RegisterContextDarwin_i386::LogGPR(Log *log, const char *title) {
+ if (log) {
+ if (title)
+ log->Printf("%s", title);
+ for (uint32_t i = 0; i < k_num_gpr_registers; i++) {
+ uint32_t reg = gpr_eax + i;
+ log->Printf("%12s = 0x%8.8x", g_register_infos[reg].name,
+ (&gpr.eax)[reg]);
}
+ }
}
-
-
-int
-RegisterContextDarwin_i386::ReadGPR (bool force)
-{
- int set = GPRRegSet;
- if (force || !RegisterSetIsCached(set))
- {
- SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
- }
- return GetError(set, Read);
+int RegisterContextDarwin_i386::ReadGPR(bool force) {
+ int set = GPRRegSet;
+ if (force || !RegisterSetIsCached(set)) {
+ SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
+ }
+ return GetError(set, Read);
}
-int
-RegisterContextDarwin_i386::ReadFPU (bool force)
-{
- int set = FPURegSet;
- if (force || !RegisterSetIsCached(set))
- {
- SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
- }
- return GetError(set, Read);
+int RegisterContextDarwin_i386::ReadFPU(bool force) {
+ int set = FPURegSet;
+ if (force || !RegisterSetIsCached(set)) {
+ SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
+ }
+ return GetError(set, Read);
}
-int
-RegisterContextDarwin_i386::ReadEXC (bool force)
-{
- int set = EXCRegSet;
- if (force || !RegisterSetIsCached(set))
- {
- SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
- }
- return GetError(set, Read);
+int RegisterContextDarwin_i386::ReadEXC(bool force) {
+ int set = EXCRegSet;
+ if (force || !RegisterSetIsCached(set)) {
+ SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
+ }
+ return GetError(set, Read);
}
-int
-RegisterContextDarwin_i386::WriteGPR ()
-{
- int set = GPRRegSet;
- if (!RegisterSetIsCached(set))
- {
- SetError (set, Write, -1);
- return -1;
- }
- SetError (set, Write, DoWriteGPR(GetThreadID(), set, gpr));
- SetError (set, Read, -1);
- return GetError(set, Write);
+int RegisterContextDarwin_i386::WriteGPR() {
+ int set = GPRRegSet;
+ if (!RegisterSetIsCached(set)) {
+ SetError(set, Write, -1);
+ return -1;
+ }
+ SetError(set, Write, DoWriteGPR(GetThreadID(), set, gpr));
+ SetError(set, Read, -1);
+ return GetError(set, Write);
}
-int
-RegisterContextDarwin_i386::WriteFPU ()
-{
- int set = FPURegSet;
- if (!RegisterSetIsCached(set))
- {
- SetError (set, Write, -1);
- return -1;
- }
- SetError (set, Write, DoWriteFPU(GetThreadID(), set, fpu));
- SetError (set, Read, -1);
- return GetError(set, Write);
+int RegisterContextDarwin_i386::WriteFPU() {
+ int set = FPURegSet;
+ if (!RegisterSetIsCached(set)) {
+ SetError(set, Write, -1);
+ return -1;
+ }
+ SetError(set, Write, DoWriteFPU(GetThreadID(), set, fpu));
+ SetError(set, Read, -1);
+ return GetError(set, Write);
}
-int
-RegisterContextDarwin_i386::WriteEXC ()
-{
- int set = EXCRegSet;
- if (!RegisterSetIsCached(set))
- {
- SetError (set, Write, -1);
- return -1;
- }
- SetError (set, Write, DoWriteEXC(GetThreadID(), set, exc));
- SetError (set, Read, -1);
- return GetError(set, Write);
+int RegisterContextDarwin_i386::WriteEXC() {
+ int set = EXCRegSet;
+ if (!RegisterSetIsCached(set)) {
+ SetError(set, Write, -1);
+ return -1;
+ }
+ SetError(set, Write, DoWriteEXC(GetThreadID(), set, exc));
+ SetError(set, Read, -1);
+ return GetError(set, Write);
}
-int
-RegisterContextDarwin_i386::ReadRegisterSet (uint32_t set, bool force)
-{
- switch (set)
- {
- case GPRRegSet: return ReadGPR(force);
- case FPURegSet: return ReadFPU(force);
- case EXCRegSet: return ReadEXC(force);
- default: break;
- }
- return -1;
+int RegisterContextDarwin_i386::ReadRegisterSet(uint32_t set, bool force) {
+ switch (set) {
+ case GPRRegSet:
+ return ReadGPR(force);
+ case FPURegSet:
+ return ReadFPU(force);
+ case EXCRegSet:
+ return ReadEXC(force);
+ default:
+ break;
+ }
+ return -1;
}
-int
-RegisterContextDarwin_i386::WriteRegisterSet (uint32_t set)
-{
- // Make sure we have a valid context to set.
- if (RegisterSetIsCached(set))
- {
- switch (set)
- {
- case GPRRegSet: return WriteGPR();
- case FPURegSet: return WriteFPU();
- case EXCRegSet: return WriteEXC();
- default: break;
- }
+int RegisterContextDarwin_i386::WriteRegisterSet(uint32_t set) {
+ // Make sure we have a valid context to set.
+ if (RegisterSetIsCached(set)) {
+ switch (set) {
+ case GPRRegSet:
+ return WriteGPR();
+ case FPURegSet:
+ return WriteFPU();
+ case EXCRegSet:
+ return WriteEXC();
+ default:
+ break;
}
- return -1;
+ }
+ return -1;
}
-bool
-RegisterContextDarwin_i386::ReadRegister (const RegisterInfo *reg_info,
- RegisterValue &value)
-{
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- int set = RegisterContextDarwin_i386::GetSetForNativeRegNum (reg);
+bool RegisterContextDarwin_i386::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &value) {
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+ int set = RegisterContextDarwin_i386::GetSetForNativeRegNum(reg);
- if (set == -1)
- return false;
+ if (set == -1)
+ return false;
- if (ReadRegisterSet(set, false) != 0)
- return false;
+ if (ReadRegisterSet(set, false) != 0)
+ return false;
- switch (reg)
- {
- case gpr_eax:
- case gpr_ebx:
- case gpr_ecx:
- case gpr_edx:
- case gpr_edi:
- case gpr_esi:
- case gpr_ebp:
- case gpr_esp:
- case gpr_ss:
- case gpr_eflags:
- case gpr_eip:
- case gpr_cs:
- case gpr_ds:
- case gpr_es:
- case gpr_fs:
- case gpr_gs:
- value = (&gpr.eax)[reg - gpr_eax];
- break;
-
- case fpu_fcw:
- value = fpu.fcw;
- break;
-
- case fpu_fsw:
- value = fpu.fsw;
- break;
-
- case fpu_ftw:
- value = fpu.ftw;
- break;
-
- case fpu_fop:
- value = fpu.fop;
- break;
-
- case fpu_ip:
- value = fpu.ip;
- break;
-
- case fpu_cs:
- value = fpu.cs;
- break;
-
- case fpu_dp:
- value = fpu.dp;
- break;
-
- case fpu_ds:
- value = fpu.ds;
- break;
-
- case fpu_mxcsr:
- value = fpu.mxcsr;
- break;
-
- case fpu_mxcsrmask:
- value = fpu.mxcsrmask;
- break;
-
- case fpu_stmm0:
- case fpu_stmm1:
- case fpu_stmm2:
- case fpu_stmm3:
- case fpu_stmm4:
- case fpu_stmm5:
- case fpu_stmm6:
- case fpu_stmm7:
- // These values don't fit into scalar types,
- // RegisterContext::ReadRegisterBytes() must be used for these
- // registers
- //::memcpy (reg_value.value.vector.uint8, fpu.stmm[reg - fpu_stmm0].bytes, 10);
- return false;
-
- case fpu_xmm0:
- case fpu_xmm1:
- case fpu_xmm2:
- case fpu_xmm3:
- case fpu_xmm4:
- case fpu_xmm5:
- case fpu_xmm6:
- case fpu_xmm7:
- // These values don't fit into scalar types, RegisterContext::ReadRegisterBytes()
- // must be used for these registers
- //::memcpy (reg_value.value.vector.uint8, fpu.xmm[reg - fpu_xmm0].bytes, 16);
- return false;
-
- case exc_trapno:
- value = exc.trapno;
- break;
-
- case exc_err:
- value = exc.err;
- break;
-
- case exc_faultvaddr:
- value = exc.faultvaddr;
- break;
+ switch (reg) {
+ case gpr_eax:
+ case gpr_ebx:
+ case gpr_ecx:
+ case gpr_edx:
+ case gpr_edi:
+ case gpr_esi:
+ case gpr_ebp:
+ case gpr_esp:
+ case gpr_ss:
+ case gpr_eflags:
+ case gpr_eip:
+ case gpr_cs:
+ case gpr_ds:
+ case gpr_es:
+ case gpr_fs:
+ case gpr_gs:
+ value = (&gpr.eax)[reg - gpr_eax];
+ break;
+
+ case fpu_fcw:
+ value = fpu.fcw;
+ break;
+
+ case fpu_fsw:
+ value = fpu.fsw;
+ break;
+
+ case fpu_ftw:
+ value = fpu.ftw;
+ break;
+
+ case fpu_fop:
+ value = fpu.fop;
+ break;
+
+ case fpu_ip:
+ value = fpu.ip;
+ break;
+
+ case fpu_cs:
+ value = fpu.cs;
+ break;
+
+ case fpu_dp:
+ value = fpu.dp;
+ break;
+
+ case fpu_ds:
+ value = fpu.ds;
+ break;
+
+ case fpu_mxcsr:
+ value = fpu.mxcsr;
+ break;
+
+ case fpu_mxcsrmask:
+ value = fpu.mxcsrmask;
+ break;
+
+ case fpu_stmm0:
+ case fpu_stmm1:
+ case fpu_stmm2:
+ case fpu_stmm3:
+ case fpu_stmm4:
+ case fpu_stmm5:
+ case fpu_stmm6:
+ case fpu_stmm7:
+ // These values don't fit into scalar types,
+ // RegisterContext::ReadRegisterBytes() must be used for these
+ // registers
+ //::memcpy (reg_value.value.vector.uint8, fpu.stmm[reg - fpu_stmm0].bytes,
+ //10);
+ return false;
- default:
- return false;
- }
- return true;
-}
+ case fpu_xmm0:
+ case fpu_xmm1:
+ case fpu_xmm2:
+ case fpu_xmm3:
+ case fpu_xmm4:
+ case fpu_xmm5:
+ case fpu_xmm6:
+ case fpu_xmm7:
+ // These values don't fit into scalar types,
+ // RegisterContext::ReadRegisterBytes()
+ // must be used for these registers
+ //::memcpy (reg_value.value.vector.uint8, fpu.xmm[reg - fpu_xmm0].bytes,
+ //16);
+ return false;
+ case exc_trapno:
+ value = exc.trapno;
+ break;
-bool
-RegisterContextDarwin_i386::WriteRegister (const RegisterInfo *reg_info,
- const RegisterValue &value)
-{
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- int set = GetSetForNativeRegNum (reg);
+ case exc_err:
+ value = exc.err;
+ break;
- if (set == -1)
- return false;
+ case exc_faultvaddr:
+ value = exc.faultvaddr;
+ break;
- if (ReadRegisterSet(set, false) != 0)
- return false;
+ default:
+ return false;
+ }
+ return true;
+}
- switch (reg)
- {
- case gpr_eax:
- case gpr_ebx:
- case gpr_ecx:
- case gpr_edx:
- case gpr_edi:
- case gpr_esi:
- case gpr_ebp:
- case gpr_esp:
- case gpr_ss:
- case gpr_eflags:
- case gpr_eip:
- case gpr_cs:
- case gpr_ds:
- case gpr_es:
- case gpr_fs:
- case gpr_gs:
- (&gpr.eax)[reg - gpr_eax] = value.GetAsUInt32();
- break;
-
- case fpu_fcw:
- fpu.fcw = value.GetAsUInt16();
- break;
-
- case fpu_fsw:
- fpu.fsw = value.GetAsUInt16();
- break;
-
- case fpu_ftw:
- fpu.ftw = value.GetAsUInt8();
- break;
-
- case fpu_fop:
- fpu.fop = value.GetAsUInt16();
- break;
-
- case fpu_ip:
- fpu.ip = value.GetAsUInt32();
- break;
-
- case fpu_cs:
- fpu.cs = value.GetAsUInt16();
- break;
-
- case fpu_dp:
- fpu.dp = value.GetAsUInt32();
- break;
-
- case fpu_ds:
- fpu.ds = value.GetAsUInt16();
- break;
-
- case fpu_mxcsr:
- fpu.mxcsr = value.GetAsUInt32();
- break;
-
- case fpu_mxcsrmask:
- fpu.mxcsrmask = value.GetAsUInt32();
- break;
-
- case fpu_stmm0:
- case fpu_stmm1:
- case fpu_stmm2:
- case fpu_stmm3:
- case fpu_stmm4:
- case fpu_stmm5:
- case fpu_stmm6:
- case fpu_stmm7:
- // These values don't fit into scalar types, RegisterContext::ReadRegisterBytes()
- // must be used for these registers
- ::memcpy (fpu.stmm[reg - fpu_stmm0].bytes, value.GetBytes(), value.GetByteSize());
- return false;
-
- case fpu_xmm0:
- case fpu_xmm1:
- case fpu_xmm2:
- case fpu_xmm3:
- case fpu_xmm4:
- case fpu_xmm5:
- case fpu_xmm6:
- case fpu_xmm7:
- // These values don't fit into scalar types, RegisterContext::ReadRegisterBytes()
- // must be used for these registers
- ::memcpy (fpu.xmm[reg - fpu_xmm0].bytes, value.GetBytes(), value.GetByteSize());
- return false;
-
- case exc_trapno:
- exc.trapno = value.GetAsUInt32();
- break;
-
- case exc_err:
- exc.err = value.GetAsUInt32();
- break;
-
- case exc_faultvaddr:
- exc.faultvaddr = value.GetAsUInt32();
- break;
+bool RegisterContextDarwin_i386::WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &value) {
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+ int set = GetSetForNativeRegNum(reg);
- default:
- return false;
- }
- return WriteRegisterSet(set) == 0;
-}
+ if (set == -1)
+ return false;
-bool
-RegisterContextDarwin_i386::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
-{
- data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
- if (data_sp &&
- ReadGPR (false) == 0 &&
- ReadFPU (false) == 0 &&
- ReadEXC (false) == 0)
- {
- uint8_t *dst = data_sp->GetBytes();
- ::memcpy (dst, &gpr, sizeof(gpr));
- dst += sizeof(gpr);
+ if (ReadRegisterSet(set, false) != 0)
+ return false;
- ::memcpy (dst, &fpu, sizeof(fpu));
- dst += sizeof(gpr);
+ switch (reg) {
+ case gpr_eax:
+ case gpr_ebx:
+ case gpr_ecx:
+ case gpr_edx:
+ case gpr_edi:
+ case gpr_esi:
+ case gpr_ebp:
+ case gpr_esp:
+ case gpr_ss:
+ case gpr_eflags:
+ case gpr_eip:
+ case gpr_cs:
+ case gpr_ds:
+ case gpr_es:
+ case gpr_fs:
+ case gpr_gs:
+ (&gpr.eax)[reg - gpr_eax] = value.GetAsUInt32();
+ break;
+
+ case fpu_fcw:
+ fpu.fcw = value.GetAsUInt16();
+ break;
+
+ case fpu_fsw:
+ fpu.fsw = value.GetAsUInt16();
+ break;
+
+ case fpu_ftw:
+ fpu.ftw = value.GetAsUInt8();
+ break;
+
+ case fpu_fop:
+ fpu.fop = value.GetAsUInt16();
+ break;
+
+ case fpu_ip:
+ fpu.ip = value.GetAsUInt32();
+ break;
+
+ case fpu_cs:
+ fpu.cs = value.GetAsUInt16();
+ break;
+
+ case fpu_dp:
+ fpu.dp = value.GetAsUInt32();
+ break;
+
+ case fpu_ds:
+ fpu.ds = value.GetAsUInt16();
+ break;
+
+ case fpu_mxcsr:
+ fpu.mxcsr = value.GetAsUInt32();
+ break;
+
+ case fpu_mxcsrmask:
+ fpu.mxcsrmask = value.GetAsUInt32();
+ break;
+
+ case fpu_stmm0:
+ case fpu_stmm1:
+ case fpu_stmm2:
+ case fpu_stmm3:
+ case fpu_stmm4:
+ case fpu_stmm5:
+ case fpu_stmm6:
+ case fpu_stmm7:
+ // These values don't fit into scalar types,
+ // RegisterContext::ReadRegisterBytes()
+ // must be used for these registers
+ ::memcpy(fpu.stmm[reg - fpu_stmm0].bytes, value.GetBytes(),
+ value.GetByteSize());
+ return false;
- ::memcpy (dst, &exc, sizeof(exc));
- return true;
- }
+ case fpu_xmm0:
+ case fpu_xmm1:
+ case fpu_xmm2:
+ case fpu_xmm3:
+ case fpu_xmm4:
+ case fpu_xmm5:
+ case fpu_xmm6:
+ case fpu_xmm7:
+ // These values don't fit into scalar types,
+ // RegisterContext::ReadRegisterBytes()
+ // must be used for these registers
+ ::memcpy(fpu.xmm[reg - fpu_xmm0].bytes, value.GetBytes(),
+ value.GetByteSize());
return false;
-}
-bool
-RegisterContextDarwin_i386::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
-{
- if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE)
- {
- const uint8_t *src = data_sp->GetBytes();
- ::memcpy (&gpr, src, sizeof(gpr));
- src += sizeof(gpr);
-
- ::memcpy (&fpu, src, sizeof(fpu));
- src += sizeof(gpr);
-
- ::memcpy (&exc, src, sizeof(exc));
- uint32_t success_count = 0;
- if (WriteGPR() == 0)
- ++success_count;
- if (WriteFPU() == 0)
- ++success_count;
- if (WriteEXC() == 0)
- ++success_count;
- return success_count == 3;
- }
+ case exc_trapno:
+ exc.trapno = value.GetAsUInt32();
+ break;
+
+ case exc_err:
+ exc.err = value.GetAsUInt32();
+ break;
+
+ case exc_faultvaddr:
+ exc.faultvaddr = value.GetAsUInt32();
+ break;
+
+ default:
return false;
+ }
+ return WriteRegisterSet(set) == 0;
}
+bool RegisterContextDarwin_i386::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (data_sp && ReadGPR(false) == 0 && ReadFPU(false) == 0 &&
+ ReadEXC(false) == 0) {
+ uint8_t *dst = data_sp->GetBytes();
+ ::memcpy(dst, &gpr, sizeof(gpr));
+ dst += sizeof(gpr);
-uint32_t
-RegisterContextDarwin_i386::ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t reg)
-{
- if (kind == eRegisterKindGeneric)
- {
- switch (reg)
- {
- case LLDB_REGNUM_GENERIC_PC: return gpr_eip;
- case LLDB_REGNUM_GENERIC_SP: return gpr_esp;
- case LLDB_REGNUM_GENERIC_FP: return gpr_ebp;
- case LLDB_REGNUM_GENERIC_FLAGS: return gpr_eflags;
- case LLDB_REGNUM_GENERIC_RA:
- default:
- break;
- }
- }
- else if (kind == eRegisterKindEHFrame || kind == eRegisterKindDWARF)
- {
- switch (reg)
- {
- case dwarf_eax: return gpr_eax;
- case dwarf_ecx: return gpr_ecx;
- case dwarf_edx: return gpr_edx;
- case dwarf_ebx: return gpr_ebx;
- case dwarf_esp: return gpr_esp;
- case dwarf_ebp: return gpr_ebp;
- case dwarf_esi: return gpr_esi;
- case dwarf_edi: return gpr_edi;
- case dwarf_eip: return gpr_eip;
- case dwarf_eflags: return gpr_eflags;
- case dwarf_stmm0: return fpu_stmm0;
- case dwarf_stmm1: return fpu_stmm1;
- case dwarf_stmm2: return fpu_stmm2;
- case dwarf_stmm3: return fpu_stmm3;
- case dwarf_stmm4: return fpu_stmm4;
- case dwarf_stmm5: return fpu_stmm5;
- case dwarf_stmm6: return fpu_stmm6;
- case dwarf_stmm7: return fpu_stmm7;
- case dwarf_xmm0: return fpu_xmm0;
- case dwarf_xmm1: return fpu_xmm1;
- case dwarf_xmm2: return fpu_xmm2;
- case dwarf_xmm3: return fpu_xmm3;
- case dwarf_xmm4: return fpu_xmm4;
- case dwarf_xmm5: return fpu_xmm5;
- case dwarf_xmm6: return fpu_xmm6;
- case dwarf_xmm7: return fpu_xmm7;
- default:
- break;
- }
- }
- else if (kind == eRegisterKindLLDB)
- {
- return reg;
- }
- return LLDB_INVALID_REGNUM;
-}
+ ::memcpy(dst, &fpu, sizeof(fpu));
+ dst += sizeof(gpr);
+ ::memcpy(dst, &exc, sizeof(exc));
+ return true;
+ }
+ return false;
+}
-bool
-RegisterContextDarwin_i386::HardwareSingleStep (bool enable)
-{
- if (ReadGPR(false) != 0)
- return false;
+bool RegisterContextDarwin_i386::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
+ const uint8_t *src = data_sp->GetBytes();
+ ::memcpy(&gpr, src, sizeof(gpr));
+ src += sizeof(gpr);
+
+ ::memcpy(&fpu, src, sizeof(fpu));
+ src += sizeof(gpr);
+
+ ::memcpy(&exc, src, sizeof(exc));
+ uint32_t success_count = 0;
+ if (WriteGPR() == 0)
+ ++success_count;
+ if (WriteFPU() == 0)
+ ++success_count;
+ if (WriteEXC() == 0)
+ ++success_count;
+ return success_count == 3;
+ }
+ return false;
+}
- const uint32_t trace_bit = 0x100u;
- if (enable)
- {
- // If the trace bit is already set, there is nothing to do
- if (gpr.eflags & trace_bit)
- return true;
- else
- gpr.eflags |= trace_bit;
+uint32_t RegisterContextDarwin_i386::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t reg) {
+ if (kind == eRegisterKindGeneric) {
+ switch (reg) {
+ case LLDB_REGNUM_GENERIC_PC:
+ return gpr_eip;
+ case LLDB_REGNUM_GENERIC_SP:
+ return gpr_esp;
+ case LLDB_REGNUM_GENERIC_FP:
+ return gpr_ebp;
+ case LLDB_REGNUM_GENERIC_FLAGS:
+ return gpr_eflags;
+ case LLDB_REGNUM_GENERIC_RA:
+ default:
+ break;
}
- else
- {
- // If the trace bit is already cleared, there is nothing to do
- if (gpr.eflags & trace_bit)
- gpr.eflags &= ~trace_bit;
- else
- return true;
+ } else if (kind == eRegisterKindEHFrame || kind == eRegisterKindDWARF) {
+ switch (reg) {
+ case dwarf_eax:
+ return gpr_eax;
+ case dwarf_ecx:
+ return gpr_ecx;
+ case dwarf_edx:
+ return gpr_edx;
+ case dwarf_ebx:
+ return gpr_ebx;
+ case dwarf_esp:
+ return gpr_esp;
+ case dwarf_ebp:
+ return gpr_ebp;
+ case dwarf_esi:
+ return gpr_esi;
+ case dwarf_edi:
+ return gpr_edi;
+ case dwarf_eip:
+ return gpr_eip;
+ case dwarf_eflags:
+ return gpr_eflags;
+ case dwarf_stmm0:
+ return fpu_stmm0;
+ case dwarf_stmm1:
+ return fpu_stmm1;
+ case dwarf_stmm2:
+ return fpu_stmm2;
+ case dwarf_stmm3:
+ return fpu_stmm3;
+ case dwarf_stmm4:
+ return fpu_stmm4;
+ case dwarf_stmm5:
+ return fpu_stmm5;
+ case dwarf_stmm6:
+ return fpu_stmm6;
+ case dwarf_stmm7:
+ return fpu_stmm7;
+ case dwarf_xmm0:
+ return fpu_xmm0;
+ case dwarf_xmm1:
+ return fpu_xmm1;
+ case dwarf_xmm2:
+ return fpu_xmm2;
+ case dwarf_xmm3:
+ return fpu_xmm3;
+ case dwarf_xmm4:
+ return fpu_xmm4;
+ case dwarf_xmm5:
+ return fpu_xmm5;
+ case dwarf_xmm6:
+ return fpu_xmm6;
+ case dwarf_xmm7:
+ return fpu_xmm7;
+ default:
+ break;
}
-
- return WriteGPR() == 0;
+ } else if (kind == eRegisterKindLLDB) {
+ return reg;
+ }
+ return LLDB_INVALID_REGNUM;
}
+bool RegisterContextDarwin_i386::HardwareSingleStep(bool enable) {
+ if (ReadGPR(false) != 0)
+ return false;
+ const uint32_t trace_bit = 0x100u;
+ if (enable) {
+ // If the trace bit is already set, there is nothing to do
+ if (gpr.eflags & trace_bit)
+ return true;
+ else
+ gpr.eflags |= trace_bit;
+ } else {
+ // If the trace bit is already cleared, there is nothing to do
+ if (gpr.eflags & trace_bit)
+ gpr.eflags &= ~trace_bit;
+ else
+ return true;
+ }
+ return WriteGPR() == 0;
+}
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h b/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h
index 9568b0332b4c..aea8a2900911 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h
@@ -14,255 +14,200 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/lldb-private.h"
-class RegisterContextDarwin_i386 : public lldb_private::RegisterContext
-{
+class RegisterContextDarwin_i386 : public lldb_private::RegisterContext {
public:
- RegisterContextDarwin_i386(lldb_private::Thread &thread,
- uint32_t concrete_frame_idx);
-
- ~RegisterContextDarwin_i386() override;
-
- void
- InvalidateAllRegisters() override;
-
- size_t
- GetRegisterCount() override;
-
- const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex(size_t reg) override;
-
- size_t
- GetRegisterSetCount() override;
-
- const lldb_private::RegisterSet *
- GetRegisterSet(size_t set) override;
-
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value) override;
-
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value) override;
-
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
-
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
-
- uint32_t
- ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
-
- bool
- HardwareSingleStep(bool enable) override;
-
- struct GPR
- {
- uint32_t eax;
- uint32_t ebx;
- uint32_t ecx;
- uint32_t edx;
- uint32_t edi;
- uint32_t esi;
- uint32_t ebp;
- uint32_t esp;
- uint32_t ss;
- uint32_t eflags;
- uint32_t eip;
- uint32_t cs;
- uint32_t ds;
- uint32_t es;
- uint32_t fs;
- uint32_t gs;
- };
-
- struct MMSReg
- {
- uint8_t bytes[10];
- uint8_t pad[6];
- };
-
- struct XMMReg
- {
- uint8_t bytes[16];
- };
-
- struct FPU
- {
- uint32_t pad[2];
- uint16_t fcw;
- uint16_t fsw;
- uint8_t ftw;
- uint8_t pad1;
- uint16_t fop;
- uint32_t ip;
- uint16_t cs;
- uint16_t pad2;
- uint32_t dp;
- uint16_t ds;
- uint16_t pad3;
- uint32_t mxcsr;
- uint32_t mxcsrmask;
- MMSReg stmm[8];
- XMMReg xmm[8];
- uint8_t pad4[14*16];
- int pad5;
- };
-
- struct EXC
- {
- uint32_t trapno;
- uint32_t err;
- uint32_t faultvaddr;
- };
+ RegisterContextDarwin_i386(lldb_private::Thread &thread,
+ uint32_t concrete_frame_idx);
+
+ ~RegisterContextDarwin_i386() override;
+
+ void InvalidateAllRegisters() override;
+
+ size_t GetRegisterCount() override;
+
+ const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
+
+ size_t GetRegisterSetCount() override;
+
+ const lldb_private::RegisterSet *GetRegisterSet(size_t set) override;
+
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) override;
+
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) override;
+
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
+
+ bool HardwareSingleStep(bool enable) override;
+
+ struct GPR {
+ uint32_t eax;
+ uint32_t ebx;
+ uint32_t ecx;
+ uint32_t edx;
+ uint32_t edi;
+ uint32_t esi;
+ uint32_t ebp;
+ uint32_t esp;
+ uint32_t ss;
+ uint32_t eflags;
+ uint32_t eip;
+ uint32_t cs;
+ uint32_t ds;
+ uint32_t es;
+ uint32_t fs;
+ uint32_t gs;
+ };
+
+ struct MMSReg {
+ uint8_t bytes[10];
+ uint8_t pad[6];
+ };
+
+ struct XMMReg {
+ uint8_t bytes[16];
+ };
+
+ struct FPU {
+ uint32_t pad[2];
+ uint16_t fcw;
+ uint16_t fsw;
+ uint8_t ftw;
+ uint8_t pad1;
+ uint16_t fop;
+ uint32_t ip;
+ uint16_t cs;
+ uint16_t pad2;
+ uint32_t dp;
+ uint16_t ds;
+ uint16_t pad3;
+ uint32_t mxcsr;
+ uint32_t mxcsrmask;
+ MMSReg stmm[8];
+ XMMReg xmm[8];
+ uint8_t pad4[14 * 16];
+ int pad5;
+ };
+
+ struct EXC {
+ uint32_t trapno;
+ uint32_t err;
+ uint32_t faultvaddr;
+ };
protected:
- enum
- {
- GPRRegSet = 1,
- FPURegSet = 2,
- EXCRegSet = 3
- };
-
- enum
- {
- GPRWordCount = sizeof(GPR)/sizeof(uint32_t),
- FPUWordCount = sizeof(FPU)/sizeof(uint32_t),
- EXCWordCount = sizeof(EXC)/sizeof(uint32_t)
- };
-
- enum
- {
- Read = 0,
- Write = 1,
- kNumErrors = 2
- };
-
- GPR gpr;
- FPU fpu;
- EXC exc;
- int gpr_errs[2]; // Read/Write errors
- int fpu_errs[2]; // Read/Write errors
- int exc_errs[2]; // Read/Write errors
-
- void
- InvalidateAllRegisterStates()
- {
- SetError (GPRRegSet, Read, -1);
- SetError (FPURegSet, Read, -1);
- SetError (EXCRegSet, Read, -1);
+ enum { GPRRegSet = 1, FPURegSet = 2, EXCRegSet = 3 };
+
+ enum {
+ GPRWordCount = sizeof(GPR) / sizeof(uint32_t),
+ FPUWordCount = sizeof(FPU) / sizeof(uint32_t),
+ EXCWordCount = sizeof(EXC) / sizeof(uint32_t)
+ };
+
+ enum { Read = 0, Write = 1, kNumErrors = 2 };
+
+ GPR gpr;
+ FPU fpu;
+ EXC exc;
+ int gpr_errs[2]; // Read/Write errors
+ int fpu_errs[2]; // Read/Write errors
+ int exc_errs[2]; // Read/Write errors
+
+ void InvalidateAllRegisterStates() {
+ SetError(GPRRegSet, Read, -1);
+ SetError(FPURegSet, Read, -1);
+ SetError(EXCRegSet, Read, -1);
+ }
+
+ int GetError(int flavor, uint32_t err_idx) const {
+ if (err_idx < kNumErrors) {
+ switch (flavor) {
+ // When getting all errors, just OR all values together to see if
+ // we got any kind of error.
+ case GPRRegSet:
+ return gpr_errs[err_idx];
+ case FPURegSet:
+ return fpu_errs[err_idx];
+ case EXCRegSet:
+ return exc_errs[err_idx];
+ default:
+ break;
+ }
}
-
- int
- GetError (int flavor, uint32_t err_idx) const
- {
- if (err_idx < kNumErrors)
- {
- switch (flavor)
- {
- // When getting all errors, just OR all values together to see if
- // we got any kind of error.
- case GPRRegSet: return gpr_errs[err_idx];
- case FPURegSet: return fpu_errs[err_idx];
- case EXCRegSet: return exc_errs[err_idx];
- default: break;
- }
- }
- return -1;
+ return -1;
+ }
+
+ bool SetError(int flavor, uint32_t err_idx, int err) {
+ if (err_idx < kNumErrors) {
+ switch (flavor) {
+ case GPRRegSet:
+ gpr_errs[err_idx] = err;
+ return true;
+
+ case FPURegSet:
+ fpu_errs[err_idx] = err;
+ return true;
+
+ case EXCRegSet:
+ exc_errs[err_idx] = err;
+ return true;
+
+ default:
+ break;
+ }
}
+ return false;
+ }
- bool
- SetError (int flavor, uint32_t err_idx, int err)
- {
- if (err_idx < kNumErrors)
- {
- switch (flavor)
- {
- case GPRRegSet:
- gpr_errs[err_idx] = err;
- return true;
-
- case FPURegSet:
- fpu_errs[err_idx] = err;
- return true;
-
- case EXCRegSet:
- exc_errs[err_idx] = err;
- return true;
-
- default: break;
- }
- }
- return false;
- }
+ bool RegisterSetIsCached(int set) const { return GetError(set, Read) == 0; }
- bool
- RegisterSetIsCached (int set) const
- {
- return GetError(set, Read) == 0;
- }
+ void LogGPR(lldb_private::Log *log, const char *title);
+
+ int ReadGPR(bool force);
+
+ int ReadFPU(bool force);
- void
- LogGPR (lldb_private::Log *log, const char *title);
+ int ReadEXC(bool force);
- int
- ReadGPR (bool force);
+ int WriteGPR();
- int
- ReadFPU (bool force);
+ int WriteFPU();
- int
- ReadEXC (bool force);
+ int WriteEXC();
- int
- WriteGPR ();
+ // Subclasses override these to do the actual reading.
+ virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) = 0;
- int
- WriteFPU ();
+ virtual int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) = 0;
- int
- WriteEXC ();
+ virtual int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) = 0;
- // Subclasses override these to do the actual reading.
- virtual int
- DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr) = 0;
-
- virtual int
- DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu) = 0;
+ virtual int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) = 0;
- virtual int
- DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc) = 0;
+ virtual int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) = 0;
- virtual int
- DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr) = 0;
-
- virtual int
- DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu) = 0;
-
- virtual int
- DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc) = 0;
+ virtual int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) = 0;
- int
- ReadRegisterSet (uint32_t set, bool force);
+ int ReadRegisterSet(uint32_t set, bool force);
- int
- WriteRegisterSet (uint32_t set);
+ int WriteRegisterSet(uint32_t set);
- static uint32_t
- GetRegisterNumber (uint32_t reg_kind, uint32_t reg_num);
+ static uint32_t GetRegisterNumber(uint32_t reg_kind, uint32_t reg_num);
- static int
- GetSetForNativeRegNum (int reg_num);
+ static int GetSetForNativeRegNum(int reg_num);
- static size_t
- GetRegisterInfosCount ();
+ static size_t GetRegisterInfosCount();
- static const lldb_private::RegisterInfo *
- GetRegisterInfos ();
+ static const lldb_private::RegisterInfo *GetRegisterInfos();
};
#endif // liblldb_RegisterContextDarwin_i386_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp
index aee6e1228d2a..7c0bafa68f9e 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp
@@ -7,11 +7,10 @@
//
//===----------------------------------------------------------------------===//
-
// C Includes
#include <inttypes.h> // PRIx64
#include <stdarg.h>
-#include <stddef.h> // offsetof
+#include <stddef.h> // offsetof
// C++ Includes
// Other libraries and framework includes
@@ -36,340 +35,489 @@
using namespace lldb;
using namespace lldb_private;
-enum
-{
- gpr_rax = 0,
- gpr_rbx,
- gpr_rcx,
- gpr_rdx,
- gpr_rdi,
- gpr_rsi,
- gpr_rbp,
- gpr_rsp,
- gpr_r8,
- gpr_r9,
- gpr_r10,
- gpr_r11,
- gpr_r12,
- gpr_r13,
- gpr_r14,
- gpr_r15,
- gpr_rip,
- gpr_rflags,
- gpr_cs,
- gpr_fs,
- gpr_gs,
-
- fpu_fcw,
- fpu_fsw,
- fpu_ftw,
- fpu_fop,
- fpu_ip,
- fpu_cs,
- fpu_dp,
- fpu_ds,
- fpu_mxcsr,
- fpu_mxcsrmask,
- fpu_stmm0,
- fpu_stmm1,
- fpu_stmm2,
- fpu_stmm3,
- fpu_stmm4,
- fpu_stmm5,
- fpu_stmm6,
- fpu_stmm7,
- fpu_xmm0,
- fpu_xmm1,
- fpu_xmm2,
- fpu_xmm3,
- fpu_xmm4,
- fpu_xmm5,
- fpu_xmm6,
- fpu_xmm7,
- fpu_xmm8,
- fpu_xmm9,
- fpu_xmm10,
- fpu_xmm11,
- fpu_xmm12,
- fpu_xmm13,
- fpu_xmm14,
- fpu_xmm15,
-
- exc_trapno,
- exc_err,
- exc_faultvaddr,
-
- k_num_registers,
-
- // Aliases
- fpu_fctrl = fpu_fcw,
- fpu_fstat = fpu_fsw,
- fpu_ftag = fpu_ftw,
- fpu_fiseg = fpu_cs,
- fpu_fioff = fpu_ip,
- fpu_foseg = fpu_ds,
- fpu_fooff = fpu_dp
+enum {
+ gpr_rax = 0,
+ gpr_rbx,
+ gpr_rcx,
+ gpr_rdx,
+ gpr_rdi,
+ gpr_rsi,
+ gpr_rbp,
+ gpr_rsp,
+ gpr_r8,
+ gpr_r9,
+ gpr_r10,
+ gpr_r11,
+ gpr_r12,
+ gpr_r13,
+ gpr_r14,
+ gpr_r15,
+ gpr_rip,
+ gpr_rflags,
+ gpr_cs,
+ gpr_fs,
+ gpr_gs,
+
+ fpu_fcw,
+ fpu_fsw,
+ fpu_ftw,
+ fpu_fop,
+ fpu_ip,
+ fpu_cs,
+ fpu_dp,
+ fpu_ds,
+ fpu_mxcsr,
+ fpu_mxcsrmask,
+ fpu_stmm0,
+ fpu_stmm1,
+ fpu_stmm2,
+ fpu_stmm3,
+ fpu_stmm4,
+ fpu_stmm5,
+ fpu_stmm6,
+ fpu_stmm7,
+ fpu_xmm0,
+ fpu_xmm1,
+ fpu_xmm2,
+ fpu_xmm3,
+ fpu_xmm4,
+ fpu_xmm5,
+ fpu_xmm6,
+ fpu_xmm7,
+ fpu_xmm8,
+ fpu_xmm9,
+ fpu_xmm10,
+ fpu_xmm11,
+ fpu_xmm12,
+ fpu_xmm13,
+ fpu_xmm14,
+ fpu_xmm15,
+
+ exc_trapno,
+ exc_err,
+ exc_faultvaddr,
+
+ k_num_registers,
+
+ // Aliases
+ fpu_fctrl = fpu_fcw,
+ fpu_fstat = fpu_fsw,
+ fpu_ftag = fpu_ftw,
+ fpu_fiseg = fpu_cs,
+ fpu_fioff = fpu_ip,
+ fpu_foseg = fpu_ds,
+ fpu_fooff = fpu_dp
};
-enum ehframe_dwarf_regnums
-{
- ehframe_dwarf_gpr_rax = 0,
- ehframe_dwarf_gpr_rdx,
- ehframe_dwarf_gpr_rcx,
- ehframe_dwarf_gpr_rbx,
- ehframe_dwarf_gpr_rsi,
- ehframe_dwarf_gpr_rdi,
- ehframe_dwarf_gpr_rbp,
- ehframe_dwarf_gpr_rsp,
- ehframe_dwarf_gpr_r8,
- ehframe_dwarf_gpr_r9,
- ehframe_dwarf_gpr_r10,
- ehframe_dwarf_gpr_r11,
- ehframe_dwarf_gpr_r12,
- ehframe_dwarf_gpr_r13,
- ehframe_dwarf_gpr_r14,
- ehframe_dwarf_gpr_r15,
- ehframe_dwarf_gpr_rip,
- ehframe_dwarf_fpu_xmm0,
- ehframe_dwarf_fpu_xmm1,
- ehframe_dwarf_fpu_xmm2,
- ehframe_dwarf_fpu_xmm3,
- ehframe_dwarf_fpu_xmm4,
- ehframe_dwarf_fpu_xmm5,
- ehframe_dwarf_fpu_xmm6,
- ehframe_dwarf_fpu_xmm7,
- ehframe_dwarf_fpu_xmm8,
- ehframe_dwarf_fpu_xmm9,
- ehframe_dwarf_fpu_xmm10,
- ehframe_dwarf_fpu_xmm11,
- ehframe_dwarf_fpu_xmm12,
- ehframe_dwarf_fpu_xmm13,
- ehframe_dwarf_fpu_xmm14,
- ehframe_dwarf_fpu_xmm15,
- ehframe_dwarf_fpu_stmm0,
- ehframe_dwarf_fpu_stmm1,
- ehframe_dwarf_fpu_stmm2,
- ehframe_dwarf_fpu_stmm3,
- ehframe_dwarf_fpu_stmm4,
- ehframe_dwarf_fpu_stmm5,
- ehframe_dwarf_fpu_stmm6,
- ehframe_dwarf_fpu_stmm7
+enum ehframe_dwarf_regnums {
+ ehframe_dwarf_gpr_rax = 0,
+ ehframe_dwarf_gpr_rdx,
+ ehframe_dwarf_gpr_rcx,
+ ehframe_dwarf_gpr_rbx,
+ ehframe_dwarf_gpr_rsi,
+ ehframe_dwarf_gpr_rdi,
+ ehframe_dwarf_gpr_rbp,
+ ehframe_dwarf_gpr_rsp,
+ ehframe_dwarf_gpr_r8,
+ ehframe_dwarf_gpr_r9,
+ ehframe_dwarf_gpr_r10,
+ ehframe_dwarf_gpr_r11,
+ ehframe_dwarf_gpr_r12,
+ ehframe_dwarf_gpr_r13,
+ ehframe_dwarf_gpr_r14,
+ ehframe_dwarf_gpr_r15,
+ ehframe_dwarf_gpr_rip,
+ ehframe_dwarf_fpu_xmm0,
+ ehframe_dwarf_fpu_xmm1,
+ ehframe_dwarf_fpu_xmm2,
+ ehframe_dwarf_fpu_xmm3,
+ ehframe_dwarf_fpu_xmm4,
+ ehframe_dwarf_fpu_xmm5,
+ ehframe_dwarf_fpu_xmm6,
+ ehframe_dwarf_fpu_xmm7,
+ ehframe_dwarf_fpu_xmm8,
+ ehframe_dwarf_fpu_xmm9,
+ ehframe_dwarf_fpu_xmm10,
+ ehframe_dwarf_fpu_xmm11,
+ ehframe_dwarf_fpu_xmm12,
+ ehframe_dwarf_fpu_xmm13,
+ ehframe_dwarf_fpu_xmm14,
+ ehframe_dwarf_fpu_xmm15,
+ ehframe_dwarf_fpu_stmm0,
+ ehframe_dwarf_fpu_stmm1,
+ ehframe_dwarf_fpu_stmm2,
+ ehframe_dwarf_fpu_stmm3,
+ ehframe_dwarf_fpu_stmm4,
+ ehframe_dwarf_fpu_stmm5,
+ ehframe_dwarf_fpu_stmm6,
+ ehframe_dwarf_fpu_stmm7
};
-#define GPR_OFFSET(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_x86_64::GPR, reg))
-#define FPU_OFFSET(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_x86_64::FPU, reg) + sizeof (RegisterContextDarwin_x86_64::GPR))
-#define EXC_OFFSET(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_x86_64::EXC, reg) + sizeof (RegisterContextDarwin_x86_64::GPR) + sizeof (RegisterContextDarwin_x86_64::FPU))
+#define GPR_OFFSET(reg) \
+ (LLVM_EXTENSION offsetof(RegisterContextDarwin_x86_64::GPR, reg))
+#define FPU_OFFSET(reg) \
+ (LLVM_EXTENSION offsetof(RegisterContextDarwin_x86_64::FPU, reg) + \
+ sizeof(RegisterContextDarwin_x86_64::GPR))
+#define EXC_OFFSET(reg) \
+ (LLVM_EXTENSION offsetof(RegisterContextDarwin_x86_64::EXC, reg) + \
+ sizeof(RegisterContextDarwin_x86_64::GPR) + \
+ sizeof(RegisterContextDarwin_x86_64::FPU))
// These macros will auto define the register name, alt name, register size,
// register offset, encoding, format and native register. This ensures that
// the register state structures are defined correctly and have the correct
// sizes and offsets.
-#define DEFINE_GPR(reg, alt) #reg, alt, sizeof(((RegisterContextDarwin_x86_64::GPR *)NULL)->reg), GPR_OFFSET(reg), eEncodingUint, eFormatHex
-#define DEFINE_FPU_UINT(reg) #reg, NULL, sizeof(((RegisterContextDarwin_x86_64::FPU *)NULL)->reg), FPU_OFFSET(reg), eEncodingUint, eFormatHex
-#define DEFINE_FPU_VECT(reg, i) #reg#i, NULL, sizeof(((RegisterContextDarwin_x86_64::FPU *)NULL)->reg[i].bytes), FPU_OFFSET(reg[i]), eEncodingVector, eFormatVectorOfUInt8, { ehframe_dwarf_fpu_##reg##i, ehframe_dwarf_fpu_##reg##i, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_##reg##i }, NULL, NULL
-#define DEFINE_EXC(reg) #reg, NULL, sizeof(((RegisterContextDarwin_x86_64::EXC *)NULL)->reg), EXC_OFFSET(reg), eEncodingUint, eFormatHex
-
-#define REG_CONTEXT_SIZE (sizeof (RegisterContextDarwin_x86_64::GPR) + sizeof (RegisterContextDarwin_x86_64::FPU) + sizeof (RegisterContextDarwin_x86_64::EXC))
+#define DEFINE_GPR(reg, alt) \
+ #reg, alt, sizeof(((RegisterContextDarwin_x86_64::GPR *) NULL)->reg), \
+ GPR_OFFSET(reg), eEncodingUint, eFormatHex
+#define DEFINE_FPU_UINT(reg) \
+ #reg, NULL, sizeof(((RegisterContextDarwin_x86_64::FPU *) NULL)->reg), \
+ FPU_OFFSET(reg), eEncodingUint, eFormatHex
+#define DEFINE_FPU_VECT(reg, i) \
+ #reg #i, NULL, \
+ sizeof(((RegisterContextDarwin_x86_64::FPU *) NULL)->reg[i].bytes), \
+ FPU_OFFSET(reg[i]), eEncodingVector, eFormatVectorOfUInt8, \
+ {ehframe_dwarf_fpu_##reg##i, \
+ ehframe_dwarf_fpu_##reg##i, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, fpu_##reg##i }, \
+ nullptr, nullptr, nullptr, 0
+#define DEFINE_EXC(reg) \
+ #reg, NULL, sizeof(((RegisterContextDarwin_x86_64::EXC *) NULL)->reg), \
+ EXC_OFFSET(reg), eEncodingUint, eFormatHex
+
+#define REG_CONTEXT_SIZE \
+ (sizeof(RegisterContextDarwin_x86_64::GPR) + \
+ sizeof(RegisterContextDarwin_x86_64::FPU) + \
+ sizeof(RegisterContextDarwin_x86_64::EXC))
// General purpose registers for 64 bit
-static RegisterInfo g_register_infos[] =
-{
-// Macro auto defines most stuff EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB VALUE REGS INVALIDATE REGS
-// =============================== ====================== =================== ========================== ==================== =================== ========== ===============
- { DEFINE_GPR (rax , NULL) , { ehframe_dwarf_gpr_rax , ehframe_dwarf_gpr_rax , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_rax }, NULL, NULL},
- { DEFINE_GPR (rbx , NULL) , { ehframe_dwarf_gpr_rbx , ehframe_dwarf_gpr_rbx , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_rbx }, NULL, NULL},
- { DEFINE_GPR (rcx , NULL) , { ehframe_dwarf_gpr_rcx , ehframe_dwarf_gpr_rcx , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_rcx }, NULL, NULL},
- { DEFINE_GPR (rdx , NULL) , { ehframe_dwarf_gpr_rdx , ehframe_dwarf_gpr_rdx , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_rdx }, NULL, NULL},
- { DEFINE_GPR (rdi , NULL) , { ehframe_dwarf_gpr_rdi , ehframe_dwarf_gpr_rdi , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_rdi }, NULL, NULL},
- { DEFINE_GPR (rsi , NULL) , { ehframe_dwarf_gpr_rsi , ehframe_dwarf_gpr_rsi , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_rsi }, NULL, NULL},
- { DEFINE_GPR (rbp , "fp") , { ehframe_dwarf_gpr_rbp , ehframe_dwarf_gpr_rbp , LLDB_REGNUM_GENERIC_FP , LLDB_INVALID_REGNUM, gpr_rbp }, NULL, NULL},
- { DEFINE_GPR (rsp , "sp") , { ehframe_dwarf_gpr_rsp , ehframe_dwarf_gpr_rsp , LLDB_REGNUM_GENERIC_SP , LLDB_INVALID_REGNUM, gpr_rsp }, NULL, NULL},
- { DEFINE_GPR (r8 , NULL) , { ehframe_dwarf_gpr_r8 , ehframe_dwarf_gpr_r8 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_r8 }, NULL, NULL},
- { DEFINE_GPR (r9 , NULL) , { ehframe_dwarf_gpr_r9 , ehframe_dwarf_gpr_r9 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_r9 }, NULL, NULL},
- { DEFINE_GPR (r10 , NULL) , { ehframe_dwarf_gpr_r10 , ehframe_dwarf_gpr_r10 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_r10 }, NULL, NULL},
- { DEFINE_GPR (r11 , NULL) , { ehframe_dwarf_gpr_r11 , ehframe_dwarf_gpr_r11 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_r11 }, NULL, NULL},
- { DEFINE_GPR (r12 , NULL) , { ehframe_dwarf_gpr_r12 , ehframe_dwarf_gpr_r12 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_r12 }, NULL, NULL},
- { DEFINE_GPR (r13 , NULL) , { ehframe_dwarf_gpr_r13 , ehframe_dwarf_gpr_r13 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_r13 }, NULL, NULL},
- { DEFINE_GPR (r14 , NULL) , { ehframe_dwarf_gpr_r14 , ehframe_dwarf_gpr_r14 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_r14 }, NULL, NULL},
- { DEFINE_GPR (r15 , NULL) , { ehframe_dwarf_gpr_r15 , ehframe_dwarf_gpr_r15 , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_r15 }, NULL, NULL},
- { DEFINE_GPR (rip , "pc") , { ehframe_dwarf_gpr_rip , ehframe_dwarf_gpr_rip , LLDB_REGNUM_GENERIC_PC , LLDB_INVALID_REGNUM, gpr_rip }, NULL, NULL},
- { DEFINE_GPR (rflags, "flags") , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, gpr_rflags }, NULL, NULL},
- { DEFINE_GPR (cs , NULL) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_cs }, NULL, NULL},
- { DEFINE_GPR (fs , NULL) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_fs }, NULL, NULL},
- { DEFINE_GPR (gs , NULL) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_gs }, NULL, NULL},
-
- { DEFINE_FPU_UINT(fcw) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_fcw }, NULL, NULL},
- { DEFINE_FPU_UINT(fsw) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_fsw }, NULL, NULL},
- { DEFINE_FPU_UINT(ftw) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_ftw }, NULL, NULL},
- { DEFINE_FPU_UINT(fop) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_fop }, NULL, NULL},
- { DEFINE_FPU_UINT(ip) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_ip }, NULL, NULL},
- { DEFINE_FPU_UINT(cs) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_cs }, NULL, NULL},
- { DEFINE_FPU_UINT(dp) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_dp }, NULL, NULL},
- { DEFINE_FPU_UINT(ds) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_ds }, NULL, NULL},
- { DEFINE_FPU_UINT(mxcsr) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_mxcsr }, NULL, NULL},
- { DEFINE_FPU_UINT(mxcsrmask) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_mxcsrmask }, NULL, NULL},
- { DEFINE_FPU_VECT(stmm,0) },
- { DEFINE_FPU_VECT(stmm,1) },
- { DEFINE_FPU_VECT(stmm,2) },
- { DEFINE_FPU_VECT(stmm,3) },
- { DEFINE_FPU_VECT(stmm,4) },
- { DEFINE_FPU_VECT(stmm,5) },
- { DEFINE_FPU_VECT(stmm,6) },
- { DEFINE_FPU_VECT(stmm,7) },
- { DEFINE_FPU_VECT(xmm,0) },
- { DEFINE_FPU_VECT(xmm,1) },
- { DEFINE_FPU_VECT(xmm,2) },
- { DEFINE_FPU_VECT(xmm,3) },
- { DEFINE_FPU_VECT(xmm,4) },
- { DEFINE_FPU_VECT(xmm,5) },
- { DEFINE_FPU_VECT(xmm,6) },
- { DEFINE_FPU_VECT(xmm,7) },
- { DEFINE_FPU_VECT(xmm,8) },
- { DEFINE_FPU_VECT(xmm,9) },
- { DEFINE_FPU_VECT(xmm,10) },
- { DEFINE_FPU_VECT(xmm,11) },
- { DEFINE_FPU_VECT(xmm,12) },
- { DEFINE_FPU_VECT(xmm,13) },
- { DEFINE_FPU_VECT(xmm,14) },
- { DEFINE_FPU_VECT(xmm,15) },
-
- { DEFINE_EXC(trapno) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, exc_trapno }, NULL, NULL},
- { DEFINE_EXC(err) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, exc_err }, NULL, NULL},
- { DEFINE_EXC(faultvaddr) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, exc_faultvaddr }, NULL, NULL}
-};
+static RegisterInfo g_register_infos[] = {
+ // Macro auto defines most stuff EH_FRAME DWARF
+ // GENERIC PROCESS PLUGIN LLDB
+ // =============================== ======================
+ // =================== ========================== ====================
+ // ===================
+ {DEFINE_GPR(rax, NULL),
+ {ehframe_dwarf_gpr_rax, ehframe_dwarf_gpr_rax, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_rax},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(rbx, NULL),
+ {ehframe_dwarf_gpr_rbx, ehframe_dwarf_gpr_rbx, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_rbx},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(rcx, NULL),
+ {ehframe_dwarf_gpr_rcx, ehframe_dwarf_gpr_rcx, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_rcx},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(rdx, NULL),
+ {ehframe_dwarf_gpr_rdx, ehframe_dwarf_gpr_rdx, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_rdx},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(rdi, NULL),
+ {ehframe_dwarf_gpr_rdi, ehframe_dwarf_gpr_rdi, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_rdi},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(rsi, NULL),
+ {ehframe_dwarf_gpr_rsi, ehframe_dwarf_gpr_rsi, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_rsi},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(rbp, "fp"),
+ {ehframe_dwarf_gpr_rbp, ehframe_dwarf_gpr_rbp, LLDB_REGNUM_GENERIC_FP,
+ LLDB_INVALID_REGNUM, gpr_rbp},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(rsp, "sp"),
+ {ehframe_dwarf_gpr_rsp, ehframe_dwarf_gpr_rsp, LLDB_REGNUM_GENERIC_SP,
+ LLDB_INVALID_REGNUM, gpr_rsp},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(r8, NULL),
+ {ehframe_dwarf_gpr_r8, ehframe_dwarf_gpr_r8, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_r8},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(r9, NULL),
+ {ehframe_dwarf_gpr_r9, ehframe_dwarf_gpr_r9, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_r9},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(r10, NULL),
+ {ehframe_dwarf_gpr_r10, ehframe_dwarf_gpr_r10, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_r10},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(r11, NULL),
+ {ehframe_dwarf_gpr_r11, ehframe_dwarf_gpr_r11, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_r11},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(r12, NULL),
+ {ehframe_dwarf_gpr_r12, ehframe_dwarf_gpr_r12, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_r12},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(r13, NULL),
+ {ehframe_dwarf_gpr_r13, ehframe_dwarf_gpr_r13, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_r13},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(r14, NULL),
+ {ehframe_dwarf_gpr_r14, ehframe_dwarf_gpr_r14, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_r14},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(r15, NULL),
+ {ehframe_dwarf_gpr_r15, ehframe_dwarf_gpr_r15, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_r15},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(rip, "pc"),
+ {ehframe_dwarf_gpr_rip, ehframe_dwarf_gpr_rip, LLDB_REGNUM_GENERIC_PC,
+ LLDB_INVALID_REGNUM, gpr_rip},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(rflags, "flags"),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS,
+ LLDB_INVALID_REGNUM, gpr_rflags},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(cs, NULL),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_cs},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(fs, NULL),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_fs},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_GPR(gs, NULL),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, gpr_gs},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+
+ {DEFINE_FPU_UINT(fcw),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_fcw},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(fsw),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_fsw},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(ftw),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_ftw},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(fop),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_fop},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(ip),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_ip},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(cs),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_cs},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(dp),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_dp},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(ds),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_ds},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(mxcsr),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_mxcsr},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_UINT(mxcsrmask),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_mxcsrmask},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_FPU_VECT(stmm, 0)},
+ {DEFINE_FPU_VECT(stmm, 1)},
+ {DEFINE_FPU_VECT(stmm, 2)},
+ {DEFINE_FPU_VECT(stmm, 3)},
+ {DEFINE_FPU_VECT(stmm, 4)},
+ {DEFINE_FPU_VECT(stmm, 5)},
+ {DEFINE_FPU_VECT(stmm, 6)},
+ {DEFINE_FPU_VECT(stmm, 7)},
+ {DEFINE_FPU_VECT(xmm, 0)},
+ {DEFINE_FPU_VECT(xmm, 1)},
+ {DEFINE_FPU_VECT(xmm, 2)},
+ {DEFINE_FPU_VECT(xmm, 3)},
+ {DEFINE_FPU_VECT(xmm, 4)},
+ {DEFINE_FPU_VECT(xmm, 5)},
+ {DEFINE_FPU_VECT(xmm, 6)},
+ {DEFINE_FPU_VECT(xmm, 7)},
+ {DEFINE_FPU_VECT(xmm, 8)},
+ {DEFINE_FPU_VECT(xmm, 9)},
+ {DEFINE_FPU_VECT(xmm, 10)},
+ {DEFINE_FPU_VECT(xmm, 11)},
+ {DEFINE_FPU_VECT(xmm, 12)},
+ {DEFINE_FPU_VECT(xmm, 13)},
+ {DEFINE_FPU_VECT(xmm, 14)},
+ {DEFINE_FPU_VECT(xmm, 15)},
+
+ {DEFINE_EXC(trapno),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, exc_trapno},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_EXC(err),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, exc_err},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {DEFINE_EXC(faultvaddr),
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, exc_faultvaddr},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0}};
static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
-RegisterContextDarwin_x86_64::RegisterContextDarwin_x86_64 (Thread &thread, uint32_t concrete_frame_idx) :
- RegisterContext (thread, concrete_frame_idx),
- gpr(),
- fpu(),
- exc()
-{
- uint32_t i;
- for (i=0; i<kNumErrors; i++)
- {
- gpr_errs[i] = -1;
- fpu_errs[i] = -1;
- exc_errs[i] = -1;
- }
-}
-
-RegisterContextDarwin_x86_64::~RegisterContextDarwin_x86_64()
-{
+RegisterContextDarwin_x86_64::RegisterContextDarwin_x86_64(
+ Thread &thread, uint32_t concrete_frame_idx)
+ : RegisterContext(thread, concrete_frame_idx), gpr(), fpu(), exc() {
+ uint32_t i;
+ for (i = 0; i < kNumErrors; i++) {
+ gpr_errs[i] = -1;
+ fpu_errs[i] = -1;
+ exc_errs[i] = -1;
+ }
}
+RegisterContextDarwin_x86_64::~RegisterContextDarwin_x86_64() {}
-void
-RegisterContextDarwin_x86_64::InvalidateAllRegisters ()
-{
- InvalidateAllRegisterStates();
+void RegisterContextDarwin_x86_64::InvalidateAllRegisters() {
+ InvalidateAllRegisterStates();
}
-
-size_t
-RegisterContextDarwin_x86_64::GetRegisterCount ()
-{
- assert(k_num_register_infos == k_num_registers);
- return k_num_registers;
+size_t RegisterContextDarwin_x86_64::GetRegisterCount() {
+ assert(k_num_register_infos == k_num_registers);
+ return k_num_registers;
}
-
const RegisterInfo *
-RegisterContextDarwin_x86_64::GetRegisterInfoAtIndex (size_t reg)
-{
- assert(k_num_register_infos == k_num_registers);
- if (reg < k_num_registers)
- return &g_register_infos[reg];
- return NULL;
+RegisterContextDarwin_x86_64::GetRegisterInfoAtIndex(size_t reg) {
+ assert(k_num_register_infos == k_num_registers);
+ if (reg < k_num_registers)
+ return &g_register_infos[reg];
+ return NULL;
}
-
-size_t
-RegisterContextDarwin_x86_64::GetRegisterInfosCount ()
-{
- return k_num_register_infos;
+size_t RegisterContextDarwin_x86_64::GetRegisterInfosCount() {
+ return k_num_register_infos;
}
const lldb_private::RegisterInfo *
-RegisterContextDarwin_x86_64::GetRegisterInfos ()
-{
- return g_register_infos;
+RegisterContextDarwin_x86_64::GetRegisterInfos() {
+ return g_register_infos;
}
+static uint32_t g_gpr_regnums[] = {
+ gpr_rax, gpr_rbx, gpr_rcx, gpr_rdx, gpr_rdi, gpr_rsi, gpr_rbp,
+ gpr_rsp, gpr_r8, gpr_r9, gpr_r10, gpr_r11, gpr_r12, gpr_r13,
+ gpr_r14, gpr_r15, gpr_rip, gpr_rflags, gpr_cs, gpr_fs, gpr_gs};
+static uint32_t g_fpu_regnums[] = {
+ fpu_fcw, fpu_fsw, fpu_ftw, fpu_fop, fpu_ip, fpu_cs,
+ fpu_dp, fpu_ds, fpu_mxcsr, fpu_mxcsrmask, fpu_stmm0, fpu_stmm1,
+ fpu_stmm2, fpu_stmm3, fpu_stmm4, fpu_stmm5, fpu_stmm6, fpu_stmm7,
+ fpu_xmm0, fpu_xmm1, fpu_xmm2, fpu_xmm3, fpu_xmm4, fpu_xmm5,
+ fpu_xmm6, fpu_xmm7, fpu_xmm8, fpu_xmm9, fpu_xmm10, fpu_xmm11,
+ fpu_xmm12, fpu_xmm13, fpu_xmm14, fpu_xmm15};
-static uint32_t g_gpr_regnums[] =
-{
- gpr_rax,
- gpr_rbx,
- gpr_rcx,
- gpr_rdx,
- gpr_rdi,
- gpr_rsi,
- gpr_rbp,
- gpr_rsp,
- gpr_r8,
- gpr_r9,
- gpr_r10,
- gpr_r11,
- gpr_r12,
- gpr_r13,
- gpr_r14,
- gpr_r15,
- gpr_rip,
- gpr_rflags,
- gpr_cs,
- gpr_fs,
- gpr_gs
-};
-
-static uint32_t g_fpu_regnums[] =
-{
- fpu_fcw,
- fpu_fsw,
- fpu_ftw,
- fpu_fop,
- fpu_ip,
- fpu_cs,
- fpu_dp,
- fpu_ds,
- fpu_mxcsr,
- fpu_mxcsrmask,
- fpu_stmm0,
- fpu_stmm1,
- fpu_stmm2,
- fpu_stmm3,
- fpu_stmm4,
- fpu_stmm5,
- fpu_stmm6,
- fpu_stmm7,
- fpu_xmm0,
- fpu_xmm1,
- fpu_xmm2,
- fpu_xmm3,
- fpu_xmm4,
- fpu_xmm5,
- fpu_xmm6,
- fpu_xmm7,
- fpu_xmm8,
- fpu_xmm9,
- fpu_xmm10,
- fpu_xmm11,
- fpu_xmm12,
- fpu_xmm13,
- fpu_xmm14,
- fpu_xmm15
-};
-
-static uint32_t
-g_exc_regnums[] =
-{
- exc_trapno,
- exc_err,
- exc_faultvaddr
-};
+static uint32_t g_exc_regnums[] = {exc_trapno, exc_err, exc_faultvaddr};
// Number of registers in each register set
const size_t k_num_gpr_registers = llvm::array_lengthof(g_gpr_regnums);
@@ -381,562 +529,556 @@ const size_t k_num_exc_registers = llvm::array_lengthof(g_exc_regnums);
// of zero is for all registers, followed by other registers sets. The
// register information for the all register set need not be filled in.
//----------------------------------------------------------------------
-static const RegisterSet g_reg_sets[] =
-{
- { "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums, },
- { "Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums },
- { "Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums }
-};
+static const RegisterSet g_reg_sets[] = {
+ {
+ "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums,
+ },
+ {"Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums},
+ {"Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums}};
const size_t k_num_regsets = llvm::array_lengthof(g_reg_sets);
-
-size_t
-RegisterContextDarwin_x86_64::GetRegisterSetCount ()
-{
- return k_num_regsets;
+size_t RegisterContextDarwin_x86_64::GetRegisterSetCount() {
+ return k_num_regsets;
}
const RegisterSet *
-RegisterContextDarwin_x86_64::GetRegisterSet (size_t reg_set)
-{
- if (reg_set < k_num_regsets)
- return &g_reg_sets[reg_set];
- return NULL;
-}
-
-int
-RegisterContextDarwin_x86_64::GetSetForNativeRegNum (int reg_num)
-{
- if (reg_num < fpu_fcw)
- return GPRRegSet;
- else if (reg_num < exc_trapno)
- return FPURegSet;
- else if (reg_num < k_num_registers)
- return EXCRegSet;
- return -1;
+RegisterContextDarwin_x86_64::GetRegisterSet(size_t reg_set) {
+ if (reg_set < k_num_regsets)
+ return &g_reg_sets[reg_set];
+ return NULL;
}
-void
-RegisterContextDarwin_x86_64::LogGPR(Log *log, const char *format, ...)
-{
- if (log)
- {
- if (format)
- {
- va_list args;
- va_start (args, format);
- log->VAPrintf (format, args);
- va_end (args);
- }
- for (uint32_t i=0; i<k_num_gpr_registers; i++)
- {
- uint32_t reg = gpr_rax + i;
- log->Printf("%12s = 0x%16.16" PRIx64, g_register_infos[reg].name, (&gpr.rax)[reg]);
- }
- }
+int RegisterContextDarwin_x86_64::GetSetForNativeRegNum(int reg_num) {
+ if (reg_num < fpu_fcw)
+ return GPRRegSet;
+ else if (reg_num < exc_trapno)
+ return FPURegSet;
+ else if (reg_num < k_num_registers)
+ return EXCRegSet;
+ return -1;
}
-int
-RegisterContextDarwin_x86_64::ReadGPR (bool force)
-{
- int set = GPRRegSet;
- if (force || !RegisterSetIsCached(set))
- {
- SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
+void RegisterContextDarwin_x86_64::LogGPR(Log *log, const char *format, ...) {
+ if (log) {
+ if (format) {
+ va_list args;
+ va_start(args, format);
+ log->VAPrintf(format, args);
+ va_end(args);
}
- return GetError(GPRRegSet, Read);
-}
-
-int
-RegisterContextDarwin_x86_64::ReadFPU (bool force)
-{
- int set = FPURegSet;
- if (force || !RegisterSetIsCached(set))
- {
- SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
+ for (uint32_t i = 0; i < k_num_gpr_registers; i++) {
+ uint32_t reg = gpr_rax + i;
+ log->Printf("%12s = 0x%16.16" PRIx64, g_register_infos[reg].name,
+ (&gpr.rax)[reg]);
}
- return GetError(FPURegSet, Read);
+ }
}
-int
-RegisterContextDarwin_x86_64::ReadEXC (bool force)
-{
- int set = EXCRegSet;
- if (force || !RegisterSetIsCached(set))
- {
- SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
- }
- return GetError(EXCRegSet, Read);
+int RegisterContextDarwin_x86_64::ReadGPR(bool force) {
+ int set = GPRRegSet;
+ if (force || !RegisterSetIsCached(set)) {
+ SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
+ }
+ return GetError(GPRRegSet, Read);
}
-int
-RegisterContextDarwin_x86_64::WriteGPR ()
-{
- int set = GPRRegSet;
- if (!RegisterSetIsCached(set))
- {
- SetError (set, Write, -1);
- return -1;
- }
- SetError (set, Write, DoWriteGPR(GetThreadID(), set, gpr));
- SetError (set, Read, -1);
- return GetError (set, Write);
+int RegisterContextDarwin_x86_64::ReadFPU(bool force) {
+ int set = FPURegSet;
+ if (force || !RegisterSetIsCached(set)) {
+ SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
+ }
+ return GetError(FPURegSet, Read);
}
-int
-RegisterContextDarwin_x86_64::WriteFPU ()
-{
- int set = FPURegSet;
- if (!RegisterSetIsCached(set))
- {
- SetError (set, Write, -1);
- return -1;
- }
- SetError (set, Write, DoWriteFPU(GetThreadID(), set, fpu));
- SetError (set, Read, -1);
- return GetError (set, Write);
+int RegisterContextDarwin_x86_64::ReadEXC(bool force) {
+ int set = EXCRegSet;
+ if (force || !RegisterSetIsCached(set)) {
+ SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
+ }
+ return GetError(EXCRegSet, Read);
}
-int
-RegisterContextDarwin_x86_64::WriteEXC ()
-{
- int set = EXCRegSet;
- if (!RegisterSetIsCached(set))
- {
- SetError (set, Write, -1);
- return -1;
- }
- SetError (set, Write, DoWriteEXC(GetThreadID(), set, exc));
- SetError (set, Read, -1);
- return GetError (set, Write);
+int RegisterContextDarwin_x86_64::WriteGPR() {
+ int set = GPRRegSet;
+ if (!RegisterSetIsCached(set)) {
+ SetError(set, Write, -1);
+ return -1;
+ }
+ SetError(set, Write, DoWriteGPR(GetThreadID(), set, gpr));
+ SetError(set, Read, -1);
+ return GetError(set, Write);
}
-int
-RegisterContextDarwin_x86_64::ReadRegisterSet(uint32_t set, bool force)
-{
- switch (set)
- {
- case GPRRegSet: return ReadGPR (force);
- case FPURegSet: return ReadFPU (force);
- case EXCRegSet: return ReadEXC (force);
- default: break;
- }
+int RegisterContextDarwin_x86_64::WriteFPU() {
+ int set = FPURegSet;
+ if (!RegisterSetIsCached(set)) {
+ SetError(set, Write, -1);
return -1;
+ }
+ SetError(set, Write, DoWriteFPU(GetThreadID(), set, fpu));
+ SetError(set, Read, -1);
+ return GetError(set, Write);
}
-int
-RegisterContextDarwin_x86_64::WriteRegisterSet(uint32_t set)
-{
- // Make sure we have a valid context to set.
- switch (set)
- {
- case GPRRegSet: return WriteGPR ();
- case FPURegSet: return WriteFPU ();
- case EXCRegSet: return WriteEXC ();
- default: break;
- }
+int RegisterContextDarwin_x86_64::WriteEXC() {
+ int set = EXCRegSet;
+ if (!RegisterSetIsCached(set)) {
+ SetError(set, Write, -1);
return -1;
+ }
+ SetError(set, Write, DoWriteEXC(GetThreadID(), set, exc));
+ SetError(set, Read, -1);
+ return GetError(set, Write);
}
+int RegisterContextDarwin_x86_64::ReadRegisterSet(uint32_t set, bool force) {
+ switch (set) {
+ case GPRRegSet:
+ return ReadGPR(force);
+ case FPURegSet:
+ return ReadFPU(force);
+ case EXCRegSet:
+ return ReadEXC(force);
+ default:
+ break;
+ }
+ return -1;
+}
-bool
-RegisterContextDarwin_x86_64::ReadRegister (const RegisterInfo *reg_info,
- RegisterValue &value)
-{
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- int set = RegisterContextDarwin_x86_64::GetSetForNativeRegNum (reg);
- if (set == -1)
- return false;
+int RegisterContextDarwin_x86_64::WriteRegisterSet(uint32_t set) {
+ // Make sure we have a valid context to set.
+ switch (set) {
+ case GPRRegSet:
+ return WriteGPR();
+ case FPURegSet:
+ return WriteFPU();
+ case EXCRegSet:
+ return WriteEXC();
+ default:
+ break;
+ }
+ return -1;
+}
- if (ReadRegisterSet(set, false) != 0)
- return false;
+bool RegisterContextDarwin_x86_64::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &value) {
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+ int set = RegisterContextDarwin_x86_64::GetSetForNativeRegNum(reg);
+ if (set == -1)
+ return false;
- switch (reg)
- {
- case gpr_rax:
- case gpr_rbx:
- case gpr_rcx:
- case gpr_rdx:
- case gpr_rdi:
- case gpr_rsi:
- case gpr_rbp:
- case gpr_rsp:
- case gpr_r8:
- case gpr_r9:
- case gpr_r10:
- case gpr_r11:
- case gpr_r12:
- case gpr_r13:
- case gpr_r14:
- case gpr_r15:
- case gpr_rip:
- case gpr_rflags:
- case gpr_cs:
- case gpr_fs:
- case gpr_gs:
- value = (&gpr.rax)[reg - gpr_rax];
- break;
-
- case fpu_fcw:
- value = fpu.fcw;
- break;
-
- case fpu_fsw:
- value = fpu.fsw;
- break;
-
- case fpu_ftw:
- value = fpu.ftw;
- break;
-
- case fpu_fop:
- value = fpu.fop;
- break;
-
- case fpu_ip:
- value = fpu.ip;
- break;
-
- case fpu_cs:
- value = fpu.cs;
- break;
-
- case fpu_dp:
- value = fpu.dp;
- break;
-
- case fpu_ds:
- value = fpu.ds;
- break;
-
- case fpu_mxcsr:
- value = fpu.mxcsr;
- break;
-
- case fpu_mxcsrmask:
- value = fpu.mxcsrmask;
- break;
-
- case fpu_stmm0:
- case fpu_stmm1:
- case fpu_stmm2:
- case fpu_stmm3:
- case fpu_stmm4:
- case fpu_stmm5:
- case fpu_stmm6:
- case fpu_stmm7:
- value.SetBytes(fpu.stmm[reg - fpu_stmm0].bytes, reg_info->byte_size, endian::InlHostByteOrder());
- break;
-
- case fpu_xmm0:
- case fpu_xmm1:
- case fpu_xmm2:
- case fpu_xmm3:
- case fpu_xmm4:
- case fpu_xmm5:
- case fpu_xmm6:
- case fpu_xmm7:
- case fpu_xmm8:
- case fpu_xmm9:
- case fpu_xmm10:
- case fpu_xmm11:
- case fpu_xmm12:
- case fpu_xmm13:
- case fpu_xmm14:
- case fpu_xmm15:
- value.SetBytes(fpu.xmm[reg - fpu_xmm0].bytes, reg_info->byte_size, endian::InlHostByteOrder());
- break;
-
- case exc_trapno:
- value = exc.trapno;
- break;
-
- case exc_err:
- value = exc.err;
- break;
-
- case exc_faultvaddr:
- value = exc.faultvaddr;
- break;
+ if (ReadRegisterSet(set, false) != 0)
+ return false;
- default:
- return false;
- }
- return true;
+ switch (reg) {
+ case gpr_rax:
+ case gpr_rbx:
+ case gpr_rcx:
+ case gpr_rdx:
+ case gpr_rdi:
+ case gpr_rsi:
+ case gpr_rbp:
+ case gpr_rsp:
+ case gpr_r8:
+ case gpr_r9:
+ case gpr_r10:
+ case gpr_r11:
+ case gpr_r12:
+ case gpr_r13:
+ case gpr_r14:
+ case gpr_r15:
+ case gpr_rip:
+ case gpr_rflags:
+ case gpr_cs:
+ case gpr_fs:
+ case gpr_gs:
+ value = (&gpr.rax)[reg - gpr_rax];
+ break;
+
+ case fpu_fcw:
+ value = fpu.fcw;
+ break;
+
+ case fpu_fsw:
+ value = fpu.fsw;
+ break;
+
+ case fpu_ftw:
+ value = fpu.ftw;
+ break;
+
+ case fpu_fop:
+ value = fpu.fop;
+ break;
+
+ case fpu_ip:
+ value = fpu.ip;
+ break;
+
+ case fpu_cs:
+ value = fpu.cs;
+ break;
+
+ case fpu_dp:
+ value = fpu.dp;
+ break;
+
+ case fpu_ds:
+ value = fpu.ds;
+ break;
+
+ case fpu_mxcsr:
+ value = fpu.mxcsr;
+ break;
+
+ case fpu_mxcsrmask:
+ value = fpu.mxcsrmask;
+ break;
+
+ case fpu_stmm0:
+ case fpu_stmm1:
+ case fpu_stmm2:
+ case fpu_stmm3:
+ case fpu_stmm4:
+ case fpu_stmm5:
+ case fpu_stmm6:
+ case fpu_stmm7:
+ value.SetBytes(fpu.stmm[reg - fpu_stmm0].bytes, reg_info->byte_size,
+ endian::InlHostByteOrder());
+ break;
+
+ case fpu_xmm0:
+ case fpu_xmm1:
+ case fpu_xmm2:
+ case fpu_xmm3:
+ case fpu_xmm4:
+ case fpu_xmm5:
+ case fpu_xmm6:
+ case fpu_xmm7:
+ case fpu_xmm8:
+ case fpu_xmm9:
+ case fpu_xmm10:
+ case fpu_xmm11:
+ case fpu_xmm12:
+ case fpu_xmm13:
+ case fpu_xmm14:
+ case fpu_xmm15:
+ value.SetBytes(fpu.xmm[reg - fpu_xmm0].bytes, reg_info->byte_size,
+ endian::InlHostByteOrder());
+ break;
+
+ case exc_trapno:
+ value = exc.trapno;
+ break;
+
+ case exc_err:
+ value = exc.err;
+ break;
+
+ case exc_faultvaddr:
+ value = exc.faultvaddr;
+ break;
+
+ default:
+ return false;
+ }
+ return true;
}
+bool RegisterContextDarwin_x86_64::WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &value) {
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+ int set = RegisterContextDarwin_x86_64::GetSetForNativeRegNum(reg);
-bool
-RegisterContextDarwin_x86_64::WriteRegister (const RegisterInfo *reg_info,
- const RegisterValue &value)
-{
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- int set = RegisterContextDarwin_x86_64::GetSetForNativeRegNum (reg);
-
- if (set == -1)
- return false;
+ if (set == -1)
+ return false;
- if (ReadRegisterSet(set, false) != 0)
- return false;
+ if (ReadRegisterSet(set, false) != 0)
+ return false;
- switch (reg)
- {
- case gpr_rax:
- case gpr_rbx:
- case gpr_rcx:
- case gpr_rdx:
- case gpr_rdi:
- case gpr_rsi:
- case gpr_rbp:
- case gpr_rsp:
- case gpr_r8:
- case gpr_r9:
- case gpr_r10:
- case gpr_r11:
- case gpr_r12:
- case gpr_r13:
- case gpr_r14:
- case gpr_r15:
- case gpr_rip:
- case gpr_rflags:
- case gpr_cs:
- case gpr_fs:
- case gpr_gs:
- (&gpr.rax)[reg - gpr_rax] = value.GetAsUInt64();
- break;
-
- case fpu_fcw:
- fpu.fcw = value.GetAsUInt16();
- break;
-
- case fpu_fsw:
- fpu.fsw = value.GetAsUInt16();
- break;
-
- case fpu_ftw:
- fpu.ftw = value.GetAsUInt8();
- break;
-
- case fpu_fop:
- fpu.fop = value.GetAsUInt16();
- break;
-
- case fpu_ip:
- fpu.ip = value.GetAsUInt32();
- break;
-
- case fpu_cs:
- fpu.cs = value.GetAsUInt16();
- break;
-
- case fpu_dp:
- fpu.dp = value.GetAsUInt32();
- break;
-
- case fpu_ds:
- fpu.ds = value.GetAsUInt16();
- break;
-
- case fpu_mxcsr:
- fpu.mxcsr = value.GetAsUInt32();
- break;
-
- case fpu_mxcsrmask:
- fpu.mxcsrmask = value.GetAsUInt32();
- break;
-
- case fpu_stmm0:
- case fpu_stmm1:
- case fpu_stmm2:
- case fpu_stmm3:
- case fpu_stmm4:
- case fpu_stmm5:
- case fpu_stmm6:
- case fpu_stmm7:
- ::memcpy (fpu.stmm[reg - fpu_stmm0].bytes, value.GetBytes(), value.GetByteSize());
- break;
-
- case fpu_xmm0:
- case fpu_xmm1:
- case fpu_xmm2:
- case fpu_xmm3:
- case fpu_xmm4:
- case fpu_xmm5:
- case fpu_xmm6:
- case fpu_xmm7:
- case fpu_xmm8:
- case fpu_xmm9:
- case fpu_xmm10:
- case fpu_xmm11:
- case fpu_xmm12:
- case fpu_xmm13:
- case fpu_xmm14:
- case fpu_xmm15:
- ::memcpy (fpu.xmm[reg - fpu_xmm0].bytes, value.GetBytes(), value.GetByteSize());
- return false;
-
- case exc_trapno:
- exc.trapno = value.GetAsUInt32();
- break;
-
- case exc_err:
- exc.err = value.GetAsUInt32();
- break;
-
- case exc_faultvaddr:
- exc.faultvaddr = value.GetAsUInt64();
- break;
+ switch (reg) {
+ case gpr_rax:
+ case gpr_rbx:
+ case gpr_rcx:
+ case gpr_rdx:
+ case gpr_rdi:
+ case gpr_rsi:
+ case gpr_rbp:
+ case gpr_rsp:
+ case gpr_r8:
+ case gpr_r9:
+ case gpr_r10:
+ case gpr_r11:
+ case gpr_r12:
+ case gpr_r13:
+ case gpr_r14:
+ case gpr_r15:
+ case gpr_rip:
+ case gpr_rflags:
+ case gpr_cs:
+ case gpr_fs:
+ case gpr_gs:
+ (&gpr.rax)[reg - gpr_rax] = value.GetAsUInt64();
+ break;
+
+ case fpu_fcw:
+ fpu.fcw = value.GetAsUInt16();
+ break;
+
+ case fpu_fsw:
+ fpu.fsw = value.GetAsUInt16();
+ break;
+
+ case fpu_ftw:
+ fpu.ftw = value.GetAsUInt8();
+ break;
+
+ case fpu_fop:
+ fpu.fop = value.GetAsUInt16();
+ break;
+
+ case fpu_ip:
+ fpu.ip = value.GetAsUInt32();
+ break;
+
+ case fpu_cs:
+ fpu.cs = value.GetAsUInt16();
+ break;
+
+ case fpu_dp:
+ fpu.dp = value.GetAsUInt32();
+ break;
+
+ case fpu_ds:
+ fpu.ds = value.GetAsUInt16();
+ break;
+
+ case fpu_mxcsr:
+ fpu.mxcsr = value.GetAsUInt32();
+ break;
+
+ case fpu_mxcsrmask:
+ fpu.mxcsrmask = value.GetAsUInt32();
+ break;
+
+ case fpu_stmm0:
+ case fpu_stmm1:
+ case fpu_stmm2:
+ case fpu_stmm3:
+ case fpu_stmm4:
+ case fpu_stmm5:
+ case fpu_stmm6:
+ case fpu_stmm7:
+ ::memcpy(fpu.stmm[reg - fpu_stmm0].bytes, value.GetBytes(),
+ value.GetByteSize());
+ break;
+
+ case fpu_xmm0:
+ case fpu_xmm1:
+ case fpu_xmm2:
+ case fpu_xmm3:
+ case fpu_xmm4:
+ case fpu_xmm5:
+ case fpu_xmm6:
+ case fpu_xmm7:
+ case fpu_xmm8:
+ case fpu_xmm9:
+ case fpu_xmm10:
+ case fpu_xmm11:
+ case fpu_xmm12:
+ case fpu_xmm13:
+ case fpu_xmm14:
+ case fpu_xmm15:
+ ::memcpy(fpu.xmm[reg - fpu_xmm0].bytes, value.GetBytes(),
+ value.GetByteSize());
+ return false;
- default:
- return false;
- }
- return WriteRegisterSet(set) == 0;
-}
+ case exc_trapno:
+ exc.trapno = value.GetAsUInt32();
+ break;
-bool
-RegisterContextDarwin_x86_64::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
-{
- data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
- if (data_sp &&
- ReadGPR (false) == 0 &&
- ReadFPU (false) == 0 &&
- ReadEXC (false) == 0)
- {
- uint8_t *dst = data_sp->GetBytes();
- ::memcpy (dst, &gpr, sizeof(gpr));
- dst += sizeof(gpr);
+ case exc_err:
+ exc.err = value.GetAsUInt32();
+ break;
- ::memcpy (dst, &fpu, sizeof(fpu));
- dst += sizeof(gpr);
+ case exc_faultvaddr:
+ exc.faultvaddr = value.GetAsUInt64();
+ break;
- ::memcpy (dst, &exc, sizeof(exc));
- return true;
- }
+ default:
return false;
+ }
+ return WriteRegisterSet(set) == 0;
}
-bool
-RegisterContextDarwin_x86_64::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
-{
- if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE)
- {
- const uint8_t *src = data_sp->GetBytes();
- ::memcpy (&gpr, src, sizeof(gpr));
- src += sizeof(gpr);
-
- ::memcpy (&fpu, src, sizeof(fpu));
- src += sizeof(gpr);
-
- ::memcpy (&exc, src, sizeof(exc));
- uint32_t success_count = 0;
- if (WriteGPR() == 0)
- ++success_count;
- if (WriteFPU() == 0)
- ++success_count;
- if (WriteEXC() == 0)
- ++success_count;
- return success_count == 3;
- }
- return false;
+bool RegisterContextDarwin_x86_64::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (data_sp && ReadGPR(false) == 0 && ReadFPU(false) == 0 &&
+ ReadEXC(false) == 0) {
+ uint8_t *dst = data_sp->GetBytes();
+ ::memcpy(dst, &gpr, sizeof(gpr));
+ dst += sizeof(gpr);
+
+ ::memcpy(dst, &fpu, sizeof(fpu));
+ dst += sizeof(gpr);
+
+ ::memcpy(dst, &exc, sizeof(exc));
+ return true;
+ }
+ return false;
}
+bool RegisterContextDarwin_x86_64::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
+ const uint8_t *src = data_sp->GetBytes();
+ ::memcpy(&gpr, src, sizeof(gpr));
+ src += sizeof(gpr);
+
+ ::memcpy(&fpu, src, sizeof(fpu));
+ src += sizeof(gpr);
+
+ ::memcpy(&exc, src, sizeof(exc));
+ uint32_t success_count = 0;
+ if (WriteGPR() == 0)
+ ++success_count;
+ if (WriteFPU() == 0)
+ ++success_count;
+ if (WriteEXC() == 0)
+ ++success_count;
+ return success_count == 3;
+ }
+ return false;
+}
-uint32_t
-RegisterContextDarwin_x86_64::ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t reg)
-{
- if (kind == eRegisterKindGeneric)
- {
- switch (reg)
- {
- case LLDB_REGNUM_GENERIC_PC: return gpr_rip;
- case LLDB_REGNUM_GENERIC_SP: return gpr_rsp;
- case LLDB_REGNUM_GENERIC_FP: return gpr_rbp;
- case LLDB_REGNUM_GENERIC_FLAGS: return gpr_rflags;
- case LLDB_REGNUM_GENERIC_RA:
- default:
- break;
- }
- }
- else if (kind == eRegisterKindEHFrame || kind == eRegisterKindDWARF)
- {
- switch (reg)
- {
- case ehframe_dwarf_gpr_rax: return gpr_rax;
- case ehframe_dwarf_gpr_rdx: return gpr_rdx;
- case ehframe_dwarf_gpr_rcx: return gpr_rcx;
- case ehframe_dwarf_gpr_rbx: return gpr_rbx;
- case ehframe_dwarf_gpr_rsi: return gpr_rsi;
- case ehframe_dwarf_gpr_rdi: return gpr_rdi;
- case ehframe_dwarf_gpr_rbp: return gpr_rbp;
- case ehframe_dwarf_gpr_rsp: return gpr_rsp;
- case ehframe_dwarf_gpr_r8: return gpr_r8;
- case ehframe_dwarf_gpr_r9: return gpr_r9;
- case ehframe_dwarf_gpr_r10: return gpr_r10;
- case ehframe_dwarf_gpr_r11: return gpr_r11;
- case ehframe_dwarf_gpr_r12: return gpr_r12;
- case ehframe_dwarf_gpr_r13: return gpr_r13;
- case ehframe_dwarf_gpr_r14: return gpr_r14;
- case ehframe_dwarf_gpr_r15: return gpr_r15;
- case ehframe_dwarf_gpr_rip: return gpr_rip;
- case ehframe_dwarf_fpu_xmm0: return fpu_xmm0;
- case ehframe_dwarf_fpu_xmm1: return fpu_xmm1;
- case ehframe_dwarf_fpu_xmm2: return fpu_xmm2;
- case ehframe_dwarf_fpu_xmm3: return fpu_xmm3;
- case ehframe_dwarf_fpu_xmm4: return fpu_xmm4;
- case ehframe_dwarf_fpu_xmm5: return fpu_xmm5;
- case ehframe_dwarf_fpu_xmm6: return fpu_xmm6;
- case ehframe_dwarf_fpu_xmm7: return fpu_xmm7;
- case ehframe_dwarf_fpu_xmm8: return fpu_xmm8;
- case ehframe_dwarf_fpu_xmm9: return fpu_xmm9;
- case ehframe_dwarf_fpu_xmm10: return fpu_xmm10;
- case ehframe_dwarf_fpu_xmm11: return fpu_xmm11;
- case ehframe_dwarf_fpu_xmm12: return fpu_xmm12;
- case ehframe_dwarf_fpu_xmm13: return fpu_xmm13;
- case ehframe_dwarf_fpu_xmm14: return fpu_xmm14;
- case ehframe_dwarf_fpu_xmm15: return fpu_xmm15;
- case ehframe_dwarf_fpu_stmm0: return fpu_stmm0;
- case ehframe_dwarf_fpu_stmm1: return fpu_stmm1;
- case ehframe_dwarf_fpu_stmm2: return fpu_stmm2;
- case ehframe_dwarf_fpu_stmm3: return fpu_stmm3;
- case ehframe_dwarf_fpu_stmm4: return fpu_stmm4;
- case ehframe_dwarf_fpu_stmm5: return fpu_stmm5;
- case ehframe_dwarf_fpu_stmm6: return fpu_stmm6;
- case ehframe_dwarf_fpu_stmm7: return fpu_stmm7;
- default:
- break;
- }
+uint32_t RegisterContextDarwin_x86_64::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t reg) {
+ if (kind == eRegisterKindGeneric) {
+ switch (reg) {
+ case LLDB_REGNUM_GENERIC_PC:
+ return gpr_rip;
+ case LLDB_REGNUM_GENERIC_SP:
+ return gpr_rsp;
+ case LLDB_REGNUM_GENERIC_FP:
+ return gpr_rbp;
+ case LLDB_REGNUM_GENERIC_FLAGS:
+ return gpr_rflags;
+ case LLDB_REGNUM_GENERIC_RA:
+ default:
+ break;
}
- else if (kind == eRegisterKindLLDB)
- {
- return reg;
+ } else if (kind == eRegisterKindEHFrame || kind == eRegisterKindDWARF) {
+ switch (reg) {
+ case ehframe_dwarf_gpr_rax:
+ return gpr_rax;
+ case ehframe_dwarf_gpr_rdx:
+ return gpr_rdx;
+ case ehframe_dwarf_gpr_rcx:
+ return gpr_rcx;
+ case ehframe_dwarf_gpr_rbx:
+ return gpr_rbx;
+ case ehframe_dwarf_gpr_rsi:
+ return gpr_rsi;
+ case ehframe_dwarf_gpr_rdi:
+ return gpr_rdi;
+ case ehframe_dwarf_gpr_rbp:
+ return gpr_rbp;
+ case ehframe_dwarf_gpr_rsp:
+ return gpr_rsp;
+ case ehframe_dwarf_gpr_r8:
+ return gpr_r8;
+ case ehframe_dwarf_gpr_r9:
+ return gpr_r9;
+ case ehframe_dwarf_gpr_r10:
+ return gpr_r10;
+ case ehframe_dwarf_gpr_r11:
+ return gpr_r11;
+ case ehframe_dwarf_gpr_r12:
+ return gpr_r12;
+ case ehframe_dwarf_gpr_r13:
+ return gpr_r13;
+ case ehframe_dwarf_gpr_r14:
+ return gpr_r14;
+ case ehframe_dwarf_gpr_r15:
+ return gpr_r15;
+ case ehframe_dwarf_gpr_rip:
+ return gpr_rip;
+ case ehframe_dwarf_fpu_xmm0:
+ return fpu_xmm0;
+ case ehframe_dwarf_fpu_xmm1:
+ return fpu_xmm1;
+ case ehframe_dwarf_fpu_xmm2:
+ return fpu_xmm2;
+ case ehframe_dwarf_fpu_xmm3:
+ return fpu_xmm3;
+ case ehframe_dwarf_fpu_xmm4:
+ return fpu_xmm4;
+ case ehframe_dwarf_fpu_xmm5:
+ return fpu_xmm5;
+ case ehframe_dwarf_fpu_xmm6:
+ return fpu_xmm6;
+ case ehframe_dwarf_fpu_xmm7:
+ return fpu_xmm7;
+ case ehframe_dwarf_fpu_xmm8:
+ return fpu_xmm8;
+ case ehframe_dwarf_fpu_xmm9:
+ return fpu_xmm9;
+ case ehframe_dwarf_fpu_xmm10:
+ return fpu_xmm10;
+ case ehframe_dwarf_fpu_xmm11:
+ return fpu_xmm11;
+ case ehframe_dwarf_fpu_xmm12:
+ return fpu_xmm12;
+ case ehframe_dwarf_fpu_xmm13:
+ return fpu_xmm13;
+ case ehframe_dwarf_fpu_xmm14:
+ return fpu_xmm14;
+ case ehframe_dwarf_fpu_xmm15:
+ return fpu_xmm15;
+ case ehframe_dwarf_fpu_stmm0:
+ return fpu_stmm0;
+ case ehframe_dwarf_fpu_stmm1:
+ return fpu_stmm1;
+ case ehframe_dwarf_fpu_stmm2:
+ return fpu_stmm2;
+ case ehframe_dwarf_fpu_stmm3:
+ return fpu_stmm3;
+ case ehframe_dwarf_fpu_stmm4:
+ return fpu_stmm4;
+ case ehframe_dwarf_fpu_stmm5:
+ return fpu_stmm5;
+ case ehframe_dwarf_fpu_stmm6:
+ return fpu_stmm6;
+ case ehframe_dwarf_fpu_stmm7:
+ return fpu_stmm7;
+ default:
+ break;
}
- return LLDB_INVALID_REGNUM;
+ } else if (kind == eRegisterKindLLDB) {
+ return reg;
+ }
+ return LLDB_INVALID_REGNUM;
}
-bool
-RegisterContextDarwin_x86_64::HardwareSingleStep (bool enable)
-{
- if (ReadGPR(true) != 0)
- return false;
+bool RegisterContextDarwin_x86_64::HardwareSingleStep(bool enable) {
+ if (ReadGPR(true) != 0)
+ return false;
- const uint64_t trace_bit = 0x100ull;
- if (enable)
- {
+ const uint64_t trace_bit = 0x100ull;
+ if (enable) {
- if (gpr.rflags & trace_bit)
- return true; // trace bit is already set, there is nothing to do
- else
- gpr.rflags |= trace_bit;
- }
+ if (gpr.rflags & trace_bit)
+ return true; // trace bit is already set, there is nothing to do
else
- {
- if (gpr.rflags & trace_bit)
- gpr.rflags &= ~trace_bit;
- else
- return true; // trace bit is clear, there is nothing to do
- }
+ gpr.rflags |= trace_bit;
+ } else {
+ if (gpr.rflags & trace_bit)
+ gpr.rflags &= ~trace_bit;
+ else
+ return true; // trace bit is clear, there is nothing to do
+ }
- return WriteGPR() == 0;
+ return WriteGPR() == 0;
}
-
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h b/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h
index ed627e194a26..fdd5e8036dee 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h
@@ -14,261 +14,205 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/lldb-private.h"
-class RegisterContextDarwin_x86_64 : public lldb_private::RegisterContext
-{
+class RegisterContextDarwin_x86_64 : public lldb_private::RegisterContext {
public:
- RegisterContextDarwin_x86_64 (lldb_private::Thread &thread,
- uint32_t concrete_frame_idx);
-
- ~RegisterContextDarwin_x86_64() override;
-
- void
- InvalidateAllRegisters() override;
-
- size_t
- GetRegisterCount() override;
-
- const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex(size_t reg) override;
-
- size_t
- GetRegisterSetCount() override;
-
- const lldb_private::RegisterSet *
- GetRegisterSet(size_t set) override;
-
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value) override;
-
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value) override;
-
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
-
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
-
- uint32_t
- ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
-
- bool
- HardwareSingleStep(bool enable) override;
-
- struct GPR
- {
- uint64_t rax;
- uint64_t rbx;
- uint64_t rcx;
- uint64_t rdx;
- uint64_t rdi;
- uint64_t rsi;
- uint64_t rbp;
- uint64_t rsp;
- uint64_t r8;
- uint64_t r9;
- uint64_t r10;
- uint64_t r11;
- uint64_t r12;
- uint64_t r13;
- uint64_t r14;
- uint64_t r15;
- uint64_t rip;
- uint64_t rflags;
- uint64_t cs;
- uint64_t fs;
- uint64_t gs;
- };
-
- struct MMSReg
- {
- uint8_t bytes[10];
- uint8_t pad[6];
- };
-
- struct XMMReg
- {
- uint8_t bytes[16];
- };
-
- struct FPU
- {
- uint32_t pad[2];
- uint16_t fcw; // "fctrl"
- uint16_t fsw; // "fstat"
- uint8_t ftw; // "ftag"
- uint8_t pad1;
- uint16_t fop; // "fop"
- uint32_t ip; // "fioff"
- uint16_t cs; // "fiseg"
- uint16_t pad2;
- uint32_t dp; // "fooff"
- uint16_t ds; // "foseg"
- uint16_t pad3;
- uint32_t mxcsr;
- uint32_t mxcsrmask;
- MMSReg stmm[8];
- XMMReg xmm[16];
- uint8_t pad4[6*16];
- int pad5;
- };
-
- struct EXC
- {
- uint32_t trapno;
- uint32_t err;
- uint64_t faultvaddr;
- };
+ RegisterContextDarwin_x86_64(lldb_private::Thread &thread,
+ uint32_t concrete_frame_idx);
+
+ ~RegisterContextDarwin_x86_64() override;
+
+ void InvalidateAllRegisters() override;
+
+ size_t GetRegisterCount() override;
+
+ const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
+
+ size_t GetRegisterSetCount() override;
+
+ const lldb_private::RegisterSet *GetRegisterSet(size_t set) override;
+
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) override;
+
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) override;
+
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
+
+ bool HardwareSingleStep(bool enable) override;
+
+ struct GPR {
+ uint64_t rax;
+ uint64_t rbx;
+ uint64_t rcx;
+ uint64_t rdx;
+ uint64_t rdi;
+ uint64_t rsi;
+ uint64_t rbp;
+ uint64_t rsp;
+ uint64_t r8;
+ uint64_t r9;
+ uint64_t r10;
+ uint64_t r11;
+ uint64_t r12;
+ uint64_t r13;
+ uint64_t r14;
+ uint64_t r15;
+ uint64_t rip;
+ uint64_t rflags;
+ uint64_t cs;
+ uint64_t fs;
+ uint64_t gs;
+ };
+
+ struct MMSReg {
+ uint8_t bytes[10];
+ uint8_t pad[6];
+ };
+
+ struct XMMReg {
+ uint8_t bytes[16];
+ };
+
+ struct FPU {
+ uint32_t pad[2];
+ uint16_t fcw; // "fctrl"
+ uint16_t fsw; // "fstat"
+ uint8_t ftw; // "ftag"
+ uint8_t pad1;
+ uint16_t fop; // "fop"
+ uint32_t ip; // "fioff"
+ uint16_t cs; // "fiseg"
+ uint16_t pad2;
+ uint32_t dp; // "fooff"
+ uint16_t ds; // "foseg"
+ uint16_t pad3;
+ uint32_t mxcsr;
+ uint32_t mxcsrmask;
+ MMSReg stmm[8];
+ XMMReg xmm[16];
+ uint8_t pad4[6 * 16];
+ int pad5;
+ };
+
+ struct EXC {
+ uint32_t trapno;
+ uint32_t err;
+ uint64_t faultvaddr;
+ };
protected:
-
- enum
- {
- GPRRegSet = 4,
- FPURegSet = 5,
- EXCRegSet = 6
- };
-
- enum
- {
- GPRWordCount = sizeof(GPR)/sizeof(uint32_t),
- FPUWordCount = sizeof(FPU)/sizeof(uint32_t),
- EXCWordCount = sizeof(EXC)/sizeof(uint32_t)
- };
-
- enum
- {
- Read = 0,
- Write = 1,
- kNumErrors = 2
- };
-
- GPR gpr;
- FPU fpu;
- EXC exc;
- int gpr_errs[2]; // Read/Write errors
- int fpu_errs[2]; // Read/Write errors
- int exc_errs[2]; // Read/Write errors
-
- void
- InvalidateAllRegisterStates()
- {
- SetError (GPRRegSet, Read, -1);
- SetError (FPURegSet, Read, -1);
- SetError (EXCRegSet, Read, -1);
+ enum { GPRRegSet = 4, FPURegSet = 5, EXCRegSet = 6 };
+
+ enum {
+ GPRWordCount = sizeof(GPR) / sizeof(uint32_t),
+ FPUWordCount = sizeof(FPU) / sizeof(uint32_t),
+ EXCWordCount = sizeof(EXC) / sizeof(uint32_t)
+ };
+
+ enum { Read = 0, Write = 1, kNumErrors = 2 };
+
+ GPR gpr;
+ FPU fpu;
+ EXC exc;
+ int gpr_errs[2]; // Read/Write errors
+ int fpu_errs[2]; // Read/Write errors
+ int exc_errs[2]; // Read/Write errors
+
+ void InvalidateAllRegisterStates() {
+ SetError(GPRRegSet, Read, -1);
+ SetError(FPURegSet, Read, -1);
+ SetError(EXCRegSet, Read, -1);
+ }
+
+ int GetError(int flavor, uint32_t err_idx) const {
+ if (err_idx < kNumErrors) {
+ switch (flavor) {
+ // When getting all errors, just OR all values together to see if
+ // we got any kind of error.
+ case GPRRegSet:
+ return gpr_errs[err_idx];
+ case FPURegSet:
+ return fpu_errs[err_idx];
+ case EXCRegSet:
+ return exc_errs[err_idx];
+ default:
+ break;
+ }
}
-
- int
- GetError (int flavor, uint32_t err_idx) const
- {
- if (err_idx < kNumErrors)
- {
- switch (flavor)
- {
- // When getting all errors, just OR all values together to see if
- // we got any kind of error.
- case GPRRegSet: return gpr_errs[err_idx];
- case FPURegSet: return fpu_errs[err_idx];
- case EXCRegSet: return exc_errs[err_idx];
- default: break;
- }
- }
- return -1;
+ return -1;
+ }
+
+ bool SetError(int flavor, uint32_t err_idx, int err) {
+ if (err_idx < kNumErrors) {
+ switch (flavor) {
+ case GPRRegSet:
+ gpr_errs[err_idx] = err;
+ return true;
+
+ case FPURegSet:
+ fpu_errs[err_idx] = err;
+ return true;
+
+ case EXCRegSet:
+ exc_errs[err_idx] = err;
+ return true;
+
+ default:
+ break;
+ }
}
+ return false;
+ }
- bool
- SetError (int flavor, uint32_t err_idx, int err)
- {
- if (err_idx < kNumErrors)
- {
- switch (flavor)
- {
- case GPRRegSet:
- gpr_errs[err_idx] = err;
- return true;
-
- case FPURegSet:
- fpu_errs[err_idx] = err;
- return true;
-
- case EXCRegSet:
- exc_errs[err_idx] = err;
- return true;
-
- default: break;
- }
- }
- return false;
- }
+ bool RegisterSetIsCached(int set) const { return GetError(set, Read) == 0; }
- bool
- RegisterSetIsCached (int set) const
- {
- return GetError(set, Read) == 0;
- }
+ void LogGPR(lldb_private::Log *log, const char *format, ...);
+
+ int ReadGPR(bool force);
+
+ int ReadFPU(bool force);
+
+ int ReadEXC(bool force);
+
+ int WriteGPR();
+
+ int WriteFPU();
+
+ int WriteEXC();
+
+ // Subclasses override these to do the actual reading.
+ virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) = 0;
+
+ virtual int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) = 0;
+
+ virtual int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) = 0;
+
+ virtual int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) = 0;
+
+ virtual int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) = 0;
+
+ virtual int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) = 0;
+
+ int ReadRegisterSet(uint32_t set, bool force);
+
+ int WriteRegisterSet(uint32_t set);
+
+ static uint32_t GetRegisterNumber(uint32_t reg_kind, uint32_t reg_num);
+
+ static int GetSetForNativeRegNum(int reg_num);
+
+ static size_t GetRegisterInfosCount();
- void
- LogGPR (lldb_private::Log *log, const char *format, ...);
-
- int
- ReadGPR (bool force);
-
- int
- ReadFPU (bool force);
-
- int
- ReadEXC (bool force);
-
- int
- WriteGPR ();
-
- int
- WriteFPU ();
-
- int
- WriteEXC ();
-
- // Subclasses override these to do the actual reading.
- virtual int
- DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr) = 0;
-
- virtual int
- DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu) = 0;
-
- virtual int
- DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc) = 0;
-
- virtual int
- DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr) = 0;
-
- virtual int
- DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu) = 0;
-
- virtual int
- DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc) = 0;
-
- int
- ReadRegisterSet (uint32_t set, bool force);
-
- int
- WriteRegisterSet (uint32_t set);
-
- static uint32_t
- GetRegisterNumber (uint32_t reg_kind, uint32_t reg_num);
-
- static int
- GetSetForNativeRegNum (int reg_num);
-
- static size_t
- GetRegisterInfosCount ();
-
- static const lldb_private::RegisterInfo *
- GetRegisterInfos ();
+ static const lldb_private::RegisterInfo *GetRegisterInfos();
};
#endif // liblldb_RegisterContextDarwin_x86_64_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextDummy.cpp b/source/Plugins/Process/Utility/RegisterContextDummy.cpp
index 0859e4e9419c..93bb09b810ac 100644
--- a/source/Plugins/Process/Utility/RegisterContextDummy.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextDummy.cpp
@@ -1,4 +1,5 @@
-//===-- RegisterContextDummy.cpp ---------------------------------*- C++ -*-===//
+//===-- RegisterContextDummy.cpp ---------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,8 +8,6 @@
//
//===----------------------------------------------------------------------===//
-
-#include "lldb/lldb-private.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/AddressRange.h"
#include "lldb/Core/DataBufferHeap.h"
@@ -20,118 +19,103 @@
#include "lldb/Symbol/FuncUnwinders.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/Symbol.h"
+#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Target/ABI.h"
+#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-#include "lldb/Target/DynamicLoader.h"
+#include "lldb/lldb-private.h"
#include "RegisterContextDummy.h"
using namespace lldb;
using namespace lldb_private;
-RegisterContextDummy::RegisterContextDummy (Thread &thread, uint32_t concrete_frame_idx, uint32_t address_byte_size) :
-RegisterContext (thread, concrete_frame_idx)
-{
- m_reg_set0.name = "General Purpose Registers";
- m_reg_set0.short_name = "GPR";
- m_reg_set0.num_registers = 1;
- m_reg_set0.registers = new uint32_t(0);
-
- m_pc_reg_info.name = "pc";
- m_pc_reg_info.alt_name = "pc";
- m_pc_reg_info.byte_offset = 0;
- m_pc_reg_info.byte_size = address_byte_size;
- m_pc_reg_info.encoding = eEncodingUint;
- m_pc_reg_info.format = eFormatPointer;
- m_pc_reg_info.invalidate_regs = NULL;
- m_pc_reg_info.value_regs = NULL;
- m_pc_reg_info.kinds[eRegisterKindEHFrame] = LLDB_INVALID_REGNUM;
- m_pc_reg_info.kinds[eRegisterKindDWARF] = LLDB_INVALID_REGNUM;
- m_pc_reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
- m_pc_reg_info.kinds[eRegisterKindProcessPlugin] = LLDB_INVALID_REGNUM;
- m_pc_reg_info.kinds[eRegisterKindLLDB] = LLDB_INVALID_REGNUM;
+RegisterContextDummy::RegisterContextDummy(Thread &thread,
+ uint32_t concrete_frame_idx,
+ uint32_t address_byte_size)
+ : RegisterContext(thread, concrete_frame_idx) {
+ m_reg_set0.name = "General Purpose Registers";
+ m_reg_set0.short_name = "GPR";
+ m_reg_set0.num_registers = 1;
+ m_reg_set0.registers = new uint32_t(0);
+
+ m_pc_reg_info.name = "pc";
+ m_pc_reg_info.alt_name = "pc";
+ m_pc_reg_info.byte_offset = 0;
+ m_pc_reg_info.byte_size = address_byte_size;
+ m_pc_reg_info.encoding = eEncodingUint;
+ m_pc_reg_info.format = eFormatPointer;
+ m_pc_reg_info.invalidate_regs = NULL;
+ m_pc_reg_info.value_regs = NULL;
+ m_pc_reg_info.kinds[eRegisterKindEHFrame] = LLDB_INVALID_REGNUM;
+ m_pc_reg_info.kinds[eRegisterKindDWARF] = LLDB_INVALID_REGNUM;
+ m_pc_reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
+ m_pc_reg_info.kinds[eRegisterKindProcessPlugin] = LLDB_INVALID_REGNUM;
+ m_pc_reg_info.kinds[eRegisterKindLLDB] = LLDB_INVALID_REGNUM;
}
-RegisterContextDummy::~RegisterContextDummy ()
-{
- delete m_reg_set0.registers;
- delete m_pc_reg_info.invalidate_regs;
- delete m_pc_reg_info.value_regs;
+RegisterContextDummy::~RegisterContextDummy() {
+ delete m_reg_set0.registers;
+ delete m_pc_reg_info.invalidate_regs;
+ delete m_pc_reg_info.value_regs;
}
-void
-RegisterContextDummy::InvalidateAllRegisters () {}
+void RegisterContextDummy::InvalidateAllRegisters() {}
-size_t
-RegisterContextDummy::GetRegisterCount ()
-{
- return 1;
-}
+size_t RegisterContextDummy::GetRegisterCount() { return 1; }
const lldb_private::RegisterInfo *
-RegisterContextDummy::GetRegisterInfoAtIndex (size_t reg)
-{
- if (reg)
- return NULL;
- return &m_pc_reg_info;
+RegisterContextDummy::GetRegisterInfoAtIndex(size_t reg) {
+ if (reg)
+ return NULL;
+ return &m_pc_reg_info;
}
-size_t
-RegisterContextDummy::GetRegisterSetCount ()
-{
- return 1;
-}
+size_t RegisterContextDummy::GetRegisterSetCount() { return 1; }
const lldb_private::RegisterSet *
-RegisterContextDummy::GetRegisterSet (size_t reg_set)
-{
- if (reg_set)
- return NULL;
- return &m_reg_set0;
+RegisterContextDummy::GetRegisterSet(size_t reg_set) {
+ if (reg_set)
+ return NULL;
+ return &m_reg_set0;
}
-bool
-RegisterContextDummy::ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value)
-{
- if (!reg_info)
- return false;
- uint32_t reg_number = reg_info->kinds[eRegisterKindGeneric];
- if (reg_number == LLDB_REGNUM_GENERIC_PC)
- {
- value.SetUInt(LLDB_INVALID_ADDRESS, reg_info->byte_size);
- return true;
- }
+bool RegisterContextDummy::ReadRegister(
+ const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) {
+ if (!reg_info)
return false;
+ uint32_t reg_number = reg_info->kinds[eRegisterKindGeneric];
+ if (reg_number == LLDB_REGNUM_GENERIC_PC) {
+ value.SetUInt(LLDB_INVALID_ADDRESS, reg_info->byte_size);
+ return true;
+ }
+ return false;
}
-bool
-RegisterContextDummy::WriteRegister (const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value)
-{
- return false;
+bool RegisterContextDummy::WriteRegister(
+ const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) {
+ return false;
}
-bool
-RegisterContextDummy::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextDummy::ReadAllRegisterValues(lldb::DataBufferSP &data_sp) {
+ return false;
}
-bool
-RegisterContextDummy::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextDummy::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ return false;
}
-uint32_t
-RegisterContextDummy::ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t num)
-{
- if (kind == eRegisterKindGeneric && num == LLDB_REGNUM_GENERIC_PC)
- return 0;
- return LLDB_INVALID_REGNUM;
+uint32_t RegisterContextDummy::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t num) {
+ if (kind == eRegisterKindGeneric && num == LLDB_REGNUM_GENERIC_PC)
+ return 0;
+ return LLDB_INVALID_REGNUM;
}
diff --git a/source/Plugins/Process/Utility/RegisterContextDummy.h b/source/Plugins/Process/Utility/RegisterContextDummy.h
index 9f6a8dc347b5..ea70288f3d69 100644
--- a/source/Plugins/Process/Utility/RegisterContextDummy.h
+++ b/source/Plugins/Process/Utility/RegisterContextDummy.h
@@ -1,4 +1,5 @@
-//===-- RegisterContextDummy.h ----------------------------------------*- C++ -*-===//
+//===-- RegisterContextDummy.h ----------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,62 +17,53 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
-#include "lldb/Target/RegisterContext.h"
#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/lldb-private.h"
namespace lldb_private {
-
-class RegisterContextDummy : public lldb_private::RegisterContext
-{
+
+class RegisterContextDummy : public lldb_private::RegisterContext {
public:
- typedef std::shared_ptr<RegisterContextDummy> SharedPtr;
-
- RegisterContextDummy (Thread &thread, uint32_t concrete_frame_idx, uint32_t address_byte_size);
-
- ~RegisterContextDummy() override;
+ typedef std::shared_ptr<RegisterContextDummy> SharedPtr;
- void
- InvalidateAllRegisters() override;
+ RegisterContextDummy(Thread &thread, uint32_t concrete_frame_idx,
+ uint32_t address_byte_size);
- size_t
- GetRegisterCount() override;
+ ~RegisterContextDummy() override;
- const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex(size_t reg) override;
+ void InvalidateAllRegisters() override;
- size_t
- GetRegisterSetCount() override;
+ size_t GetRegisterCount() override;
- const lldb_private::RegisterSet *
- GetRegisterSet(size_t reg_set) override;
+ const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value) override;
+ size_t GetRegisterSetCount() override;
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value) override;
+ const lldb_private::RegisterSet *GetRegisterSet(size_t reg_set) override;
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) override;
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) override;
+
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
- uint32_t
- ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
-
private:
- //------------------------------------------------------------------
- // For RegisterContextLLDB only
- //------------------------------------------------------------------
-
- lldb_private::RegisterSet m_reg_set0; // register set 0 (PC only)
- lldb_private::RegisterInfo m_pc_reg_info;
-
- DISALLOW_COPY_AND_ASSIGN (RegisterContextDummy);
+ //------------------------------------------------------------------
+ // For RegisterContextLLDB only
+ //------------------------------------------------------------------
+
+ lldb_private::RegisterSet m_reg_set0; // register set 0 (PC only)
+ lldb_private::RegisterInfo m_pc_reg_info;
+
+ DISALLOW_COPY_AND_ASSIGN(RegisterContextDummy);
};
} // namespace lldb_private
diff --git a/source/Plugins/Process/Utility/RegisterContextFreeBSD_arm.cpp b/source/Plugins/Process/Utility/RegisterContextFreeBSD_arm.cpp
index 588793d5a644..fecfae0b7e66 100644
--- a/source/Plugins/Process/Utility/RegisterContextFreeBSD_arm.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextFreeBSD_arm.cpp
@@ -7,12 +7,12 @@
//
//===---------------------------------------------------------------------===//
+#include <cassert>
#include <stddef.h>
#include <vector>
-#include <cassert>
-#include "llvm/Support/Compiler.h"
#include "lldb/lldb-defines.h"
+#include "llvm/Support/Compiler.h"
#include "RegisterContextFreeBSD_arm.h"
@@ -21,14 +21,31 @@ using namespace lldb_private;
// Based on RegisterContextLinux_arm.cpp and
// http://svnweb.freebsd.org/base/head/sys/arm/include/reg.h
-#define GPR_OFFSET(idx) ((idx) * 4)
-#define FPU_OFFSET(idx) ((idx) * 4 + sizeof (RegisterContextFreeBSD_arm::GPR))
-#define FPSCR_OFFSET (LLVM_EXTENSION offsetof (RegisterContextFreeBSD_arm::FPU, fpscr) + sizeof (RegisterContextFreeBSD_arm::GPR))
-#define EXC_OFFSET(idx) ((idx) * 4 + sizeof (RegisterContextFreeBSD_arm::GPR) + sizeof (RegisterContextFreeBSD_arm::FPU))
-#define DBG_OFFSET(reg) ((LLVM_EXTENSION offsetof (RegisterContextFreeBSD_arm::DBG, reg) + sizeof (RegisterContextFreeBSD_arm::GPR) + sizeof (RegisterContextFreeBSD_arm::FPU) + sizeof (RegisterContextFreeBSD_arm::EXC)))
+#define GPR_OFFSET(idx) ((idx)*4)
+#define FPU_OFFSET(idx) ((idx)*4 + sizeof(RegisterContextFreeBSD_arm::GPR))
+#define FPSCR_OFFSET \
+ (LLVM_EXTENSION offsetof(RegisterContextFreeBSD_arm::FPU, fpscr) + \
+ sizeof(RegisterContextFreeBSD_arm::GPR))
+#define EXC_OFFSET(idx) \
+ ((idx)*4 + sizeof(RegisterContextFreeBSD_arm::GPR) + \
+ sizeof(RegisterContextFreeBSD_arm::FPU))
+#define DBG_OFFSET(reg) \
+ ((LLVM_EXTENSION offsetof(RegisterContextFreeBSD_arm::DBG, reg) + \
+ sizeof(RegisterContextFreeBSD_arm::GPR) + \
+ sizeof(RegisterContextFreeBSD_arm::FPU) + \
+ sizeof(RegisterContextFreeBSD_arm::EXC)))
-#define DEFINE_DBG(reg, i) #reg, NULL, sizeof(((RegisterContextFreeBSD_arm::DBG *)NULL)->reg[i]), DBG_OFFSET(reg[i]), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, dbg_##reg##i }, NULL, NULL, NULL, 0
-#define REG_CONTEXT_SIZE (sizeof (RegisterContextFreeBSD_arm::GPR) + sizeof (RegisterContextFreeBSD_arm::FPU) + sizeof (RegisterContextFreeBSD_arm::EXC))
+#define DEFINE_DBG(reg, i) \
+ #reg, NULL, sizeof(((RegisterContextFreeBSD_arm::DBG *) NULL)->reg[i]), \
+ DBG_OFFSET(reg[i]), eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ dbg_##reg##i }, \
+ NULL, NULL, NULL, 0
+#define REG_CONTEXT_SIZE \
+ (sizeof(RegisterContextFreeBSD_arm::GPR) + \
+ sizeof(RegisterContextFreeBSD_arm::FPU) + \
+ sizeof(RegisterContextFreeBSD_arm::EXC))
//-----------------------------------------------------------------------------
// Include RegisterInfos_arm to declare our g_register_infos_arm structure.
@@ -38,52 +55,43 @@ using namespace lldb_private;
#undef DECLARE_REGISTER_INFOS_ARM_STRUCT
static const lldb_private::RegisterInfo *
-GetRegisterInfoPtr (const lldb_private::ArchSpec &target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::arm:
- return g_register_infos_arm;
- default:
- assert(false && "Unhandled target architecture.");
- return NULL;
- }
+GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::arm:
+ return g_register_infos_arm;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return NULL;
+ }
}
static uint32_t
-GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::arm:
- return static_cast<uint32_t>(sizeof(g_register_infos_arm) / sizeof(g_register_infos_arm[0]));
- default:
- assert(false && "Unhandled target architecture.");
- return 0;
- }
+GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::arm:
+ return static_cast<uint32_t>(sizeof(g_register_infos_arm) /
+ sizeof(g_register_infos_arm[0]));
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
}
-RegisterContextFreeBSD_arm::RegisterContextFreeBSD_arm(const lldb_private::ArchSpec &target_arch) :
- lldb_private::RegisterInfoInterface(target_arch),
- m_register_info_p(GetRegisterInfoPtr(target_arch)),
- m_register_info_count(GetRegisterInfoCount(target_arch))
-{
-}
+RegisterContextFreeBSD_arm::RegisterContextFreeBSD_arm(
+ const lldb_private::ArchSpec &target_arch)
+ : lldb_private::RegisterInfoInterface(target_arch),
+ m_register_info_p(GetRegisterInfoPtr(target_arch)),
+ m_register_info_count(GetRegisterInfoCount(target_arch)) {}
-size_t
-RegisterContextFreeBSD_arm::GetGPRSize() const
-{
- return sizeof(struct RegisterContextFreeBSD_arm::GPR);
+size_t RegisterContextFreeBSD_arm::GetGPRSize() const {
+ return sizeof(struct RegisterContextFreeBSD_arm::GPR);
}
const lldb_private::RegisterInfo *
-RegisterContextFreeBSD_arm::GetRegisterInfo() const
-{
- return m_register_info_p;
+RegisterContextFreeBSD_arm::GetRegisterInfo() const {
+ return m_register_info_p;
}
-uint32_t
-RegisterContextFreeBSD_arm::GetRegisterCount() const
-{
- return m_register_info_count;
+uint32_t RegisterContextFreeBSD_arm::GetRegisterCount() const {
+ return m_register_info_count;
}
diff --git a/source/Plugins/Process/Utility/RegisterContextFreeBSD_arm.h b/source/Plugins/Process/Utility/RegisterContextFreeBSD_arm.h
index f2d9364b3ce6..422ecb7686dc 100644
--- a/source/Plugins/Process/Utility/RegisterContextFreeBSD_arm.h
+++ b/source/Plugins/Process/Utility/RegisterContextFreeBSD_arm.h
@@ -10,65 +10,53 @@
#ifndef liblldb_RegisterContextFreeBSD_arm_h_
#define liblldb_RegisterContextFreeBSD_arm_h_
-#include "lldb/lldb-private.h"
-#include "lldb/Target/RegisterContext.h"
#include "RegisterInfoInterface.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/lldb-private.h"
-class RegisterContextFreeBSD_arm
- : public lldb_private::RegisterInfoInterface
-{
+class RegisterContextFreeBSD_arm : public lldb_private::RegisterInfoInterface {
public:
-
- struct GPR
- {
- uint32_t r[16]; // R0-R15
- uint32_t cpsr; // CPSR
- };
-
-
- struct QReg
- {
- uint8_t bytes[16];
- };
-
- struct FPU
- {
- union {
- uint32_t s[32];
- uint64_t d[32];
- QReg q[16]; // the 128-bit NEON registers
- } floats;
- uint32_t fpscr;
- };
- struct EXC
- {
- uint32_t exception;
- uint32_t fsr; /* Fault status */
- uint32_t far; /* Virtual Fault Address */
- };
-
- struct DBG
- {
- uint32_t bvr[16];
- uint32_t bcr[16];
- uint32_t wvr[16];
- uint32_t wcr[16];
- };
-
- RegisterContextFreeBSD_arm(const lldb_private::ArchSpec &target_arch);
-
- size_t
- GetGPRSize() const override;
-
- const lldb_private::RegisterInfo *
- GetRegisterInfo() const override;
-
- uint32_t
- GetRegisterCount () const override;
+ struct GPR {
+ uint32_t r[16]; // R0-R15
+ uint32_t cpsr; // CPSR
+ };
+
+ struct QReg {
+ uint8_t bytes[16];
+ };
+
+ struct FPU {
+ union {
+ uint32_t s[32];
+ uint64_t d[32];
+ QReg q[16]; // the 128-bit NEON registers
+ } floats;
+ uint32_t fpscr;
+ };
+ struct EXC {
+ uint32_t exception;
+ uint32_t fsr; /* Fault status */
+ uint32_t far; /* Virtual Fault Address */
+ };
+
+ struct DBG {
+ uint32_t bvr[16];
+ uint32_t bcr[16];
+ uint32_t wvr[16];
+ uint32_t wcr[16];
+ };
+
+ RegisterContextFreeBSD_arm(const lldb_private::ArchSpec &target_arch);
+
+ size_t GetGPRSize() const override;
+
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
+
+ uint32_t GetRegisterCount() const override;
private:
- const lldb_private::RegisterInfo *m_register_info_p;
- uint32_t m_register_info_count;
+ const lldb_private::RegisterInfo *m_register_info_p;
+ uint32_t m_register_info_count;
};
-#endif // liblldb_RegisterContextFreeBSD_arm_h_
+#endif // liblldb_RegisterContextFreeBSD_arm_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextFreeBSD_arm64.cpp b/source/Plugins/Process/Utility/RegisterContextFreeBSD_arm64.cpp
deleted file mode 100644
index 6e7e9e67f524..000000000000
--- a/source/Plugins/Process/Utility/RegisterContextFreeBSD_arm64.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-//===-- RegisterContextFreeBSD_arm64.cpp ----------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===---------------------------------------------------------------------===//
-
-#include <vector>
-#include "RegisterContextPOSIX_arm64.h"
-#include "RegisterContextFreeBSD_arm64.h"
-
-using namespace lldb;
-
-// Based on RegisterContextDarwin_arm64.cpp
-#define GPR_OFFSET(idx) ((idx) * 8)
-#define GPR_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextFreeBSD_arm64::GPR, reg))
-
-#define FPU_OFFSET(idx) ((idx) * 16 + sizeof (RegisterContextFreeBSD_arm64::GPR))
-#define FPU_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextFreeBSD_arm64::FPU, reg))
-
-#define EXC_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextFreeBSD_arm64::EXC, reg) + sizeof (RegisterContextFreeBSD_arm64::GPR) + sizeof (RegisterContextFreeBSD_arm64::FPU))
-#define DBG_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextFreeBSD_arm64::DBG, reg) + sizeof (RegisterContextFreeBSD_arm64::GPR) + sizeof (RegisterContextFreeBSD_arm64::FPU) + sizeof (RegisterContextFreeBSD_arm64::EXC))
-
-#define DEFINE_DBG(reg, i) #reg, NULL, sizeof(((RegisterContextFreeBSD_arm64::DBG *)NULL)->reg[i]), DBG_OFFSET_NAME(reg[i]), lldb::eEncodingUint, lldb::eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, dbg_##reg##i }, NULL, NULL, NULL, 0
-#define REG_CONTEXT_SIZE (sizeof (RegisterContextFreeBSD_arm64::GPR) + sizeof (RegisterContextFreeBSD_arm64::FPU) + sizeof (RegisterContextFreeBSD_arm64::EXC))
-
-//-----------------------------------------------------------------------------
-// Include RegisterInfos_arm64 to declare our g_register_infos_arm64 structure.
-//-----------------------------------------------------------------------------
-#define DECLARE_REGISTER_INFOS_ARM64_STRUCT
-#include "RegisterInfos_arm64.h"
-#undef DECLARE_REGISTER_INFOS_ARM64_STRUCT
-
-static const lldb_private::RegisterInfo *
-GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::aarch64:
- return g_register_infos_arm64;
- default:
- assert(false && "Unhandled target architecture.");
- return nullptr;
- }
-}
-
-static uint32_t
-GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::aarch64:
- return static_cast<uint32_t>(sizeof(g_register_infos_arm64) / sizeof(g_register_infos_arm64[0]));
- default:
- assert(false && "Unhandled target architecture.");
- return 0;
- }
-}
-
-RegisterContextFreeBSD_arm64::RegisterContextFreeBSD_arm64(const lldb_private::ArchSpec &target_arch) :
- RegisterInfoInterface(target_arch),
- m_register_info_p(GetRegisterInfoPtr(target_arch)),
- m_register_info_count(GetRegisterInfoCount(target_arch))
-{
-}
-
-size_t
-RegisterContextFreeBSD_arm64::GetGPRSize() const
-{
- return sizeof(struct RegisterContextFreeBSD_arm64::GPR);
-}
-
-const lldb_private::RegisterInfo *
-RegisterContextFreeBSD_arm64::GetRegisterInfo() const
-{
- return m_register_info_p;
-}
-
-uint32_t
-RegisterContextFreeBSD_arm64::GetRegisterCount() const
-{
- return m_register_info_count;
-}
-
diff --git a/source/Plugins/Process/Utility/RegisterContextFreeBSD_arm64.h b/source/Plugins/Process/Utility/RegisterContextFreeBSD_arm64.h
deleted file mode 100644
index cfdae4d2b557..000000000000
--- a/source/Plugins/Process/Utility/RegisterContextFreeBSD_arm64.h
+++ /dev/null
@@ -1,78 +0,0 @@
-//===-- RegisterContextFreeBSD_arm64.h --------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_RegisterContextFreeBSD_arm64_H_
-#define liblldb_RegisterContextFreeBSD_arm64_H_
-
-#include "RegisterInfoInterface.h"
-
-class RegisterContextFreeBSD_arm64:
- public lldb_private::RegisterInfoInterface
-{
-public:
- // based on RegisterContextDarwin_arm64.h
- struct GPR
- {
- uint64_t x[29]; // x0-x28
- uint64_t fp; // x29
- uint64_t lr; // x30
- uint64_t sp; // x31
- uint64_t pc; // pc
- uint32_t cpsr; // cpsr
- };
-
- // based on RegisterContextDarwin_arm64.h
- struct VReg
- {
- uint8_t bytes[16];
- };
-
- // based on RegisterContextDarwin_arm64.h
- struct FPU
- {
- VReg v[32];
- uint32_t fpsr;
- uint32_t fpcr;
- };
-
- // based on RegisterContextDarwin_arm64.h
- struct EXC
- {
- uint64_t far; // Virtual Fault Address
- uint32_t esr; // Exception syndrome
- uint32_t exception; // number of arm exception token
- };
-
- // based on RegisterContextDarwin_arm64.h
- struct DBG
- {
- uint64_t bvr[16];
- uint64_t bcr[16];
- uint64_t wvr[16];
- uint64_t wcr[16];
- uint64_t mdscr_el1;
- };
-
- RegisterContextFreeBSD_arm64(const lldb_private::ArchSpec &target_arch);
-
- size_t
- GetGPRSize() const override;
-
- const lldb_private::RegisterInfo *
- GetRegisterInfo() const override;
-
- uint32_t
- GetRegisterCount () const override;
-
-private:
- const lldb_private::RegisterInfo *m_register_info_p;
- uint32_t m_register_info_count;
-};
-
-#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp b/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp
index 0171da66a199..4ccfa2a16fef 100644
--- a/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp
@@ -7,55 +7,52 @@
//
//===---------------------------------------------------------------------===//
-#include "RegisterContextPOSIX_x86.h"
#include "RegisterContextFreeBSD_i386.h"
+#include "RegisterContextPOSIX_x86.h"
using namespace lldb_private;
using namespace lldb;
// http://svnweb.freebsd.org/base/head/sys/x86/include/reg.h
-struct GPR
-{
- uint32_t fs;
- uint32_t es;
- uint32_t ds;
- uint32_t edi;
- uint32_t esi;
- uint32_t ebp;
- uint32_t isp;
- uint32_t ebx;
- uint32_t edx;
- uint32_t ecx;
- uint32_t eax;
- uint32_t trapno;
- uint32_t err;
- uint32_t eip;
- uint32_t cs;
- uint32_t eflags;
- uint32_t esp;
- uint32_t ss;
- uint32_t gs;
+struct GPR {
+ uint32_t fs;
+ uint32_t es;
+ uint32_t ds;
+ uint32_t edi;
+ uint32_t esi;
+ uint32_t ebp;
+ uint32_t isp;
+ uint32_t ebx;
+ uint32_t edx;
+ uint32_t ecx;
+ uint32_t eax;
+ uint32_t trapno;
+ uint32_t err;
+ uint32_t eip;
+ uint32_t cs;
+ uint32_t eflags;
+ uint32_t esp;
+ uint32_t ss;
+ uint32_t gs;
};
struct dbreg {
- uint32_t dr[8]; /* debug registers */
- /* Index 0-3: debug address registers */
- /* Index 4-5: reserved */
- /* Index 6: debug status */
- /* Index 7: debug control */
+ uint32_t dr[8]; /* debug registers */
+ /* Index 0-3: debug address registers */
+ /* Index 4-5: reserved */
+ /* Index 6: debug status */
+ /* Index 7: debug control */
};
using FPR_i386 = FXSAVE;
-struct UserArea
-{
- GPR gpr;
- FPR_i386 i387;
+struct UserArea {
+ GPR gpr;
+ FPR_i386 i387;
};
#define DR_SIZE sizeof(uint32_t)
-#define DR_OFFSET(reg_index) \
- (LLVM_EXTENSION offsetof(dbreg, dr[reg_index]))
+#define DR_OFFSET(reg_index) (LLVM_EXTENSION offsetof(dbreg, dr[reg_index]))
//---------------------------------------------------------------------------
// Include RegisterInfos_i386 to declare our g_register_infos_i386 structure.
@@ -64,32 +61,23 @@ struct UserArea
#include "RegisterInfos_i386.h"
#undef DECLARE_REGISTER_INFOS_I386_STRUCT
-RegisterContextFreeBSD_i386::RegisterContextFreeBSD_i386(const ArchSpec &target_arch) :
- RegisterInfoInterface(target_arch)
-{
-}
+RegisterContextFreeBSD_i386::RegisterContextFreeBSD_i386(
+ const ArchSpec &target_arch)
+ : RegisterInfoInterface(target_arch) {}
-size_t
-RegisterContextFreeBSD_i386::GetGPRSize() const
-{
- return sizeof(GPR);
-}
+size_t RegisterContextFreeBSD_i386::GetGPRSize() const { return sizeof(GPR); }
-const RegisterInfo *
-RegisterContextFreeBSD_i386::GetRegisterInfo() const
-{
- switch (m_target_arch.GetMachine())
- {
- case llvm::Triple::x86:
- return g_register_infos_i386;
- default:
- assert(false && "Unhandled target architecture.");
- return NULL;
- }
+const RegisterInfo *RegisterContextFreeBSD_i386::GetRegisterInfo() const {
+ switch (m_target_arch.GetMachine()) {
+ case llvm::Triple::x86:
+ return g_register_infos_i386;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return NULL;
+ }
}
-uint32_t
-RegisterContextFreeBSD_i386::GetRegisterCount () const
-{
- return static_cast<uint32_t> (sizeof (g_register_infos_i386) / sizeof (g_register_infos_i386 [0]));
+uint32_t RegisterContextFreeBSD_i386::GetRegisterCount() const {
+ return static_cast<uint32_t>(sizeof(g_register_infos_i386) /
+ sizeof(g_register_infos_i386[0]));
}
diff --git a/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.h b/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.h
index 9527fc03f728..35a79c14abfc 100644
--- a/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.h
+++ b/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.h
@@ -12,20 +12,15 @@
#include "RegisterInfoInterface.h"
-class RegisterContextFreeBSD_i386
- : public lldb_private::RegisterInfoInterface
-{
+class RegisterContextFreeBSD_i386 : public lldb_private::RegisterInfoInterface {
public:
- RegisterContextFreeBSD_i386(const lldb_private::ArchSpec &target_arch);
+ RegisterContextFreeBSD_i386(const lldb_private::ArchSpec &target_arch);
- size_t
- GetGPRSize() const override;
+ size_t GetGPRSize() const override;
- const lldb_private::RegisterInfo *
- GetRegisterInfo() const override;
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
- uint32_t
- GetRegisterCount () const override;
+ uint32_t GetRegisterCount() const override;
};
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp b/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp
index 53fa4169bffc..c114cfb829f5 100644
--- a/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp
@@ -7,87 +7,79 @@
//
//===---------------------------------------------------------------------===//
-#include <vector>
-#include "RegisterContextPOSIX_mips64.h"
#include "RegisterContextFreeBSD_mips64.h"
+#include "RegisterContextPOSIX_mips64.h"
+#include <vector>
using namespace lldb_private;
using namespace lldb;
// http://svnweb.freebsd.org/base/head/sys/mips/include/regnum.h
-typedef struct _GPR
-{
- uint64_t zero;
- uint64_t r1;
- uint64_t r2;
- uint64_t r3;
- uint64_t r4;
- uint64_t r5;
- uint64_t r6;
- uint64_t r7;
- uint64_t r8;
- uint64_t r9;
- uint64_t r10;
- uint64_t r11;
- uint64_t r12;
- uint64_t r13;
- uint64_t r14;
- uint64_t r15;
- uint64_t r16;
- uint64_t r17;
- uint64_t r18;
- uint64_t r19;
- uint64_t r20;
- uint64_t r21;
- uint64_t r22;
- uint64_t r23;
- uint64_t r24;
- uint64_t r25;
- uint64_t r26;
- uint64_t r27;
- uint64_t gp;
- uint64_t sp;
- uint64_t r30;
- uint64_t ra;
- uint64_t sr;
- uint64_t mullo;
- uint64_t mulhi;
- uint64_t badvaddr;
- uint64_t cause;
- uint64_t pc;
- uint64_t ic;
- uint64_t dummy;
+typedef struct _GPR {
+ uint64_t zero;
+ uint64_t r1;
+ uint64_t r2;
+ uint64_t r3;
+ uint64_t r4;
+ uint64_t r5;
+ uint64_t r6;
+ uint64_t r7;
+ uint64_t r8;
+ uint64_t r9;
+ uint64_t r10;
+ uint64_t r11;
+ uint64_t r12;
+ uint64_t r13;
+ uint64_t r14;
+ uint64_t r15;
+ uint64_t r16;
+ uint64_t r17;
+ uint64_t r18;
+ uint64_t r19;
+ uint64_t r20;
+ uint64_t r21;
+ uint64_t r22;
+ uint64_t r23;
+ uint64_t r24;
+ uint64_t r25;
+ uint64_t r26;
+ uint64_t r27;
+ uint64_t gp;
+ uint64_t sp;
+ uint64_t r30;
+ uint64_t ra;
+ uint64_t sr;
+ uint64_t mullo;
+ uint64_t mulhi;
+ uint64_t badvaddr;
+ uint64_t cause;
+ uint64_t pc;
+ uint64_t ic;
+ uint64_t dummy;
} GPR_freebsd_mips;
//---------------------------------------------------------------------------
-// Include RegisterInfos_mips64 to declare our g_register_infos_mips64 structure.
+// Include RegisterInfos_mips64 to declare our g_register_infos_mips64
+// structure.
//---------------------------------------------------------------------------
#define DECLARE_REGISTER_INFOS_MIPS64_STRUCT
#include "RegisterInfos_mips64.h"
#undef DECLARE_REGISTER_INFOS_MIPS64_STRUCT
-RegisterContextFreeBSD_mips64::RegisterContextFreeBSD_mips64(const ArchSpec &target_arch) :
- RegisterInfoInterface(target_arch)
-{
-}
+RegisterContextFreeBSD_mips64::RegisterContextFreeBSD_mips64(
+ const ArchSpec &target_arch)
+ : RegisterInfoInterface(target_arch) {}
-size_t
-RegisterContextFreeBSD_mips64::GetGPRSize() const
-{
- return sizeof(GPR_freebsd_mips);
+size_t RegisterContextFreeBSD_mips64::GetGPRSize() const {
+ return sizeof(GPR_freebsd_mips);
}
-const RegisterInfo *
-RegisterContextFreeBSD_mips64::GetRegisterInfo() const
-{
- assert (m_target_arch.GetCore() == ArchSpec::eCore_mips64);
- return g_register_infos_mips64;
+const RegisterInfo *RegisterContextFreeBSD_mips64::GetRegisterInfo() const {
+ assert(m_target_arch.GetCore() == ArchSpec::eCore_mips64);
+ return g_register_infos_mips64;
}
-uint32_t
-RegisterContextFreeBSD_mips64::GetRegisterCount () const
-{
- return static_cast<uint32_t> (sizeof (g_register_infos_mips64) / sizeof (g_register_infos_mips64 [0]));
+uint32_t RegisterContextFreeBSD_mips64::GetRegisterCount() const {
+ return static_cast<uint32_t>(sizeof(g_register_infos_mips64) /
+ sizeof(g_register_infos_mips64[0]));
}
-
-
diff --git a/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h b/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h
index 5c042af20eac..043e638758da 100644
--- a/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h
+++ b/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h
@@ -12,20 +12,16 @@
#include "RegisterInfoInterface.h"
-class RegisterContextFreeBSD_mips64:
- public lldb_private::RegisterInfoInterface
-{
+class RegisterContextFreeBSD_mips64
+ : public lldb_private::RegisterInfoInterface {
public:
- RegisterContextFreeBSD_mips64(const lldb_private::ArchSpec &target_arch);
+ RegisterContextFreeBSD_mips64(const lldb_private::ArchSpec &target_arch);
- size_t
- GetGPRSize() const override;
+ size_t GetGPRSize() const override;
- const lldb_private::RegisterInfo *
- GetRegisterInfo() const override;
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
- uint32_t
- GetRegisterCount () const override;
+ uint32_t GetRegisterCount() const override;
};
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp b/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp
index 5133d6088bd3..efa4cc6d8182 100644
--- a/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp
@@ -7,263 +7,233 @@
//
//===---------------------------------------------------------------------===//
-#include <vector>
-#include "RegisterContextPOSIX_powerpc.h"
#include "RegisterContextFreeBSD_powerpc.h"
+#include "RegisterContextPOSIX_powerpc.h"
+#include <vector>
using namespace lldb_private;
using namespace lldb;
// http://svnweb.freebsd.org/base/head/sys/powerpc/include/reg.h
-typedef struct _GPR64
-{
- uint64_t r0;
- uint64_t r1;
- uint64_t r2;
- uint64_t r3;
- uint64_t r4;
- uint64_t r5;
- uint64_t r6;
- uint64_t r7;
- uint64_t r8;
- uint64_t r9;
- uint64_t r10;
- uint64_t r11;
- uint64_t r12;
- uint64_t r13;
- uint64_t r14;
- uint64_t r15;
- uint64_t r16;
- uint64_t r17;
- uint64_t r18;
- uint64_t r19;
- uint64_t r20;
- uint64_t r21;
- uint64_t r22;
- uint64_t r23;
- uint64_t r24;
- uint64_t r25;
- uint64_t r26;
- uint64_t r27;
- uint64_t r28;
- uint64_t r29;
- uint64_t r30;
- uint64_t r31;
- uint64_t lr;
- uint64_t cr;
- uint64_t xer;
- uint64_t ctr;
- uint64_t pc;
+typedef struct _GPR64 {
+ uint64_t r0;
+ uint64_t r1;
+ uint64_t r2;
+ uint64_t r3;
+ uint64_t r4;
+ uint64_t r5;
+ uint64_t r6;
+ uint64_t r7;
+ uint64_t r8;
+ uint64_t r9;
+ uint64_t r10;
+ uint64_t r11;
+ uint64_t r12;
+ uint64_t r13;
+ uint64_t r14;
+ uint64_t r15;
+ uint64_t r16;
+ uint64_t r17;
+ uint64_t r18;
+ uint64_t r19;
+ uint64_t r20;
+ uint64_t r21;
+ uint64_t r22;
+ uint64_t r23;
+ uint64_t r24;
+ uint64_t r25;
+ uint64_t r26;
+ uint64_t r27;
+ uint64_t r28;
+ uint64_t r29;
+ uint64_t r30;
+ uint64_t r31;
+ uint64_t lr;
+ uint64_t cr;
+ uint64_t xer;
+ uint64_t ctr;
+ uint64_t pc;
} GPR64;
-typedef struct _GPR32
-{
- uint32_t r0;
- uint32_t r1;
- uint32_t r2;
- uint32_t r3;
- uint32_t r4;
- uint32_t r5;
- uint32_t r6;
- uint32_t r7;
- uint32_t r8;
- uint32_t r9;
- uint32_t r10;
- uint32_t r11;
- uint32_t r12;
- uint32_t r13;
- uint32_t r14;
- uint32_t r15;
- uint32_t r16;
- uint32_t r17;
- uint32_t r18;
- uint32_t r19;
- uint32_t r20;
- uint32_t r21;
- uint32_t r22;
- uint32_t r23;
- uint32_t r24;
- uint32_t r25;
- uint32_t r26;
- uint32_t r27;
- uint32_t r28;
- uint32_t r29;
- uint32_t r30;
- uint32_t r31;
- uint32_t lr;
- uint32_t cr;
- uint32_t xer;
- uint32_t ctr;
- uint32_t pc;
+typedef struct _GPR32 {
+ uint32_t r0;
+ uint32_t r1;
+ uint32_t r2;
+ uint32_t r3;
+ uint32_t r4;
+ uint32_t r5;
+ uint32_t r6;
+ uint32_t r7;
+ uint32_t r8;
+ uint32_t r9;
+ uint32_t r10;
+ uint32_t r11;
+ uint32_t r12;
+ uint32_t r13;
+ uint32_t r14;
+ uint32_t r15;
+ uint32_t r16;
+ uint32_t r17;
+ uint32_t r18;
+ uint32_t r19;
+ uint32_t r20;
+ uint32_t r21;
+ uint32_t r22;
+ uint32_t r23;
+ uint32_t r24;
+ uint32_t r25;
+ uint32_t r26;
+ uint32_t r27;
+ uint32_t r28;
+ uint32_t r29;
+ uint32_t r30;
+ uint32_t r31;
+ uint32_t lr;
+ uint32_t cr;
+ uint32_t xer;
+ uint32_t ctr;
+ uint32_t pc;
} GPR32;
-typedef struct _FPR
-{
- uint64_t f0;
- uint64_t f1;
- uint64_t f2;
- uint64_t f3;
- uint64_t f4;
- uint64_t f5;
- uint64_t f6;
- uint64_t f7;
- uint64_t f8;
- uint64_t f9;
- uint64_t f10;
- uint64_t f11;
- uint64_t f12;
- uint64_t f13;
- uint64_t f14;
- uint64_t f15;
- uint64_t f16;
- uint64_t f17;
- uint64_t f18;
- uint64_t f19;
- uint64_t f20;
- uint64_t f21;
- uint64_t f22;
- uint64_t f23;
- uint64_t f24;
- uint64_t f25;
- uint64_t f26;
- uint64_t f27;
- uint64_t f28;
- uint64_t f29;
- uint64_t f30;
- uint64_t f31;
- uint64_t fpscr;
+typedef struct _FPR {
+ uint64_t f0;
+ uint64_t f1;
+ uint64_t f2;
+ uint64_t f3;
+ uint64_t f4;
+ uint64_t f5;
+ uint64_t f6;
+ uint64_t f7;
+ uint64_t f8;
+ uint64_t f9;
+ uint64_t f10;
+ uint64_t f11;
+ uint64_t f12;
+ uint64_t f13;
+ uint64_t f14;
+ uint64_t f15;
+ uint64_t f16;
+ uint64_t f17;
+ uint64_t f18;
+ uint64_t f19;
+ uint64_t f20;
+ uint64_t f21;
+ uint64_t f22;
+ uint64_t f23;
+ uint64_t f24;
+ uint64_t f25;
+ uint64_t f26;
+ uint64_t f27;
+ uint64_t f28;
+ uint64_t f29;
+ uint64_t f30;
+ uint64_t f31;
+ uint64_t fpscr;
} FPR;
-typedef struct _VMX
-{
- uint32_t v0[4];
- uint32_t v1[4];
- uint32_t v2[4];
- uint32_t v3[4];
- uint32_t v4[4];
- uint32_t v5[4];
- uint32_t v6[4];
- uint32_t v7[4];
- uint32_t v8[4];
- uint32_t v9[4];
- uint32_t v10[4];
- uint32_t v11[4];
- uint32_t v12[4];
- uint32_t v13[4];
- uint32_t v14[4];
- uint32_t v15[4];
- uint32_t v16[4];
- uint32_t v17[4];
- uint32_t v18[4];
- uint32_t v19[4];
- uint32_t v20[4];
- uint32_t v21[4];
- uint32_t v22[4];
- uint32_t v23[4];
- uint32_t v24[4];
- uint32_t v25[4];
- uint32_t v26[4];
- uint32_t v27[4];
- uint32_t v28[4];
- uint32_t v29[4];
- uint32_t v30[4];
- uint32_t v31[4];
- uint32_t pad[2];
- uint32_t vrsave;
- uint32_t vscr;
+typedef struct _VMX {
+ uint32_t v0[4];
+ uint32_t v1[4];
+ uint32_t v2[4];
+ uint32_t v3[4];
+ uint32_t v4[4];
+ uint32_t v5[4];
+ uint32_t v6[4];
+ uint32_t v7[4];
+ uint32_t v8[4];
+ uint32_t v9[4];
+ uint32_t v10[4];
+ uint32_t v11[4];
+ uint32_t v12[4];
+ uint32_t v13[4];
+ uint32_t v14[4];
+ uint32_t v15[4];
+ uint32_t v16[4];
+ uint32_t v17[4];
+ uint32_t v18[4];
+ uint32_t v19[4];
+ uint32_t v20[4];
+ uint32_t v21[4];
+ uint32_t v22[4];
+ uint32_t v23[4];
+ uint32_t v24[4];
+ uint32_t v25[4];
+ uint32_t v26[4];
+ uint32_t v27[4];
+ uint32_t v28[4];
+ uint32_t v29[4];
+ uint32_t v30[4];
+ uint32_t v31[4];
+ uint32_t pad[2];
+ uint32_t vrsave;
+ uint32_t vscr;
} VMX;
//---------------------------------------------------------------------------
-// Include RegisterInfos_powerpc to declare our g_register_infos_powerpc structure.
+// Include RegisterInfos_powerpc to declare our g_register_infos_powerpc
+// structure.
//---------------------------------------------------------------------------
#define DECLARE_REGISTER_INFOS_POWERPC_STRUCT
#include "RegisterInfos_powerpc.h"
#undef DECLARE_REGISTER_INFOS_POWERPC_STRUCT
-RegisterContextFreeBSD_powerpc::RegisterContextFreeBSD_powerpc(const ArchSpec &target_arch) :
- RegisterInfoInterface(target_arch)
-{
-}
+RegisterContextFreeBSD_powerpc::RegisterContextFreeBSD_powerpc(
+ const ArchSpec &target_arch)
+ : RegisterInfoInterface(target_arch) {}
-RegisterContextFreeBSD_powerpc::~RegisterContextFreeBSD_powerpc()
-{
-}
+RegisterContextFreeBSD_powerpc::~RegisterContextFreeBSD_powerpc() {}
-size_t
-RegisterContextFreeBSD_powerpc::GetGPRSize() const
-{
- // This is an 'abstract' base, so no GPR struct.
- return 0;
+size_t RegisterContextFreeBSD_powerpc::GetGPRSize() const {
+ // This is an 'abstract' base, so no GPR struct.
+ return 0;
}
-const RegisterInfo *
-RegisterContextFreeBSD_powerpc::GetRegisterInfo() const
-{
- //assert (m_target_arch.GetCore() == ArchSpec::eCore_powerpc);
- llvm_unreachable("Abstract class!");
- return NULL;
+const RegisterInfo *RegisterContextFreeBSD_powerpc::GetRegisterInfo() const {
+ // assert (m_target_arch.GetCore() == ArchSpec::eCore_powerpc);
+ llvm_unreachable("Abstract class!");
+ return NULL;
}
-uint32_t
-RegisterContextFreeBSD_powerpc::GetRegisterCount () const
-{
- return 0;
-}
+uint32_t RegisterContextFreeBSD_powerpc::GetRegisterCount() const { return 0; }
-RegisterContextFreeBSD_powerpc32::RegisterContextFreeBSD_powerpc32(const ArchSpec &target_arch) :
- RegisterContextFreeBSD_powerpc(target_arch)
-{
-}
+RegisterContextFreeBSD_powerpc32::RegisterContextFreeBSD_powerpc32(
+ const ArchSpec &target_arch)
+ : RegisterContextFreeBSD_powerpc(target_arch) {}
-RegisterContextFreeBSD_powerpc32::~RegisterContextFreeBSD_powerpc32()
-{
-}
+RegisterContextFreeBSD_powerpc32::~RegisterContextFreeBSD_powerpc32() {}
-size_t
-RegisterContextFreeBSD_powerpc32::GetGPRSize() const
-{
- return sizeof(GPR32);
+size_t RegisterContextFreeBSD_powerpc32::GetGPRSize() const {
+ return sizeof(GPR32);
}
-const RegisterInfo *
-RegisterContextFreeBSD_powerpc32::GetRegisterInfo() const
-{
- //assert (m_target_arch.GetCore() == ArchSpec::eCore_powerpc);
- return g_register_infos_powerpc32;
+const RegisterInfo *RegisterContextFreeBSD_powerpc32::GetRegisterInfo() const {
+ // assert (m_target_arch.GetCore() == ArchSpec::eCore_powerpc);
+ return g_register_infos_powerpc32;
}
-uint32_t
-RegisterContextFreeBSD_powerpc32::GetRegisterCount () const
-{
- return static_cast<uint32_t> (sizeof (g_register_infos_powerpc32) / sizeof (g_register_infos_powerpc32 [0]));
+uint32_t RegisterContextFreeBSD_powerpc32::GetRegisterCount() const {
+ return static_cast<uint32_t>(sizeof(g_register_infos_powerpc32) /
+ sizeof(g_register_infos_powerpc32[0]));
}
-RegisterContextFreeBSD_powerpc64::RegisterContextFreeBSD_powerpc64(const ArchSpec &target_arch) :
- RegisterContextFreeBSD_powerpc(target_arch)
-{
-}
+RegisterContextFreeBSD_powerpc64::RegisterContextFreeBSD_powerpc64(
+ const ArchSpec &target_arch)
+ : RegisterContextFreeBSD_powerpc(target_arch) {}
-RegisterContextFreeBSD_powerpc64::~RegisterContextFreeBSD_powerpc64()
-{
-}
+RegisterContextFreeBSD_powerpc64::~RegisterContextFreeBSD_powerpc64() {}
-size_t
-RegisterContextFreeBSD_powerpc64::GetGPRSize() const
-{
- return sizeof(GPR64);
+size_t RegisterContextFreeBSD_powerpc64::GetGPRSize() const {
+ return sizeof(GPR64);
}
-const RegisterInfo *
-RegisterContextFreeBSD_powerpc64::GetRegisterInfo() const
-{
- //assert (m_target_arch.GetCore() == ArchSpec::eCore_powerpc);
- if (m_target_arch.GetMachine() == llvm::Triple::ppc)
- return g_register_infos_powerpc64_32;
- return g_register_infos_powerpc64;
+const RegisterInfo *RegisterContextFreeBSD_powerpc64::GetRegisterInfo() const {
+ // assert (m_target_arch.GetCore() == ArchSpec::eCore_powerpc);
+ if (m_target_arch.GetMachine() == llvm::Triple::ppc)
+ return g_register_infos_powerpc64_32;
+ return g_register_infos_powerpc64;
}
-uint32_t
-RegisterContextFreeBSD_powerpc64::GetRegisterCount () const
-{
- return static_cast<uint32_t> (sizeof (g_register_infos_powerpc64) / sizeof (g_register_infos_powerpc64 [0]));
+uint32_t RegisterContextFreeBSD_powerpc64::GetRegisterCount() const {
+ return static_cast<uint32_t>(sizeof(g_register_infos_powerpc64) /
+ sizeof(g_register_infos_powerpc64[0]));
}
diff --git a/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h b/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h
index 930683f8a870..c9a65b1cacce 100644
--- a/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h
+++ b/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h
@@ -1,4 +1,5 @@
-//===-- RegisterContextFreeBSD_powerpc.h -------------------------*- C++ -*-===//
+//===-- RegisterContextFreeBSD_powerpc.h -------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,55 +17,41 @@
// Project includes
#include "RegisterInfoInterface.h"
-class RegisterContextFreeBSD_powerpc:
- public lldb_private::RegisterInfoInterface
-{
+class RegisterContextFreeBSD_powerpc
+ : public lldb_private::RegisterInfoInterface {
public:
- RegisterContextFreeBSD_powerpc(const lldb_private::ArchSpec &target_arch);
- ~RegisterContextFreeBSD_powerpc() override;
+ RegisterContextFreeBSD_powerpc(const lldb_private::ArchSpec &target_arch);
+ ~RegisterContextFreeBSD_powerpc() override;
- size_t
- GetGPRSize() const override;
+ size_t GetGPRSize() const override;
- const lldb_private::RegisterInfo *
- GetRegisterInfo() const override;
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
- uint32_t
- GetRegisterCount() const override;
+ uint32_t GetRegisterCount() const override;
};
-class RegisterContextFreeBSD_powerpc32:
- public RegisterContextFreeBSD_powerpc
-{
+class RegisterContextFreeBSD_powerpc32 : public RegisterContextFreeBSD_powerpc {
public:
- RegisterContextFreeBSD_powerpc32(const lldb_private::ArchSpec &target_arch);
- ~RegisterContextFreeBSD_powerpc32() override;
+ RegisterContextFreeBSD_powerpc32(const lldb_private::ArchSpec &target_arch);
+ ~RegisterContextFreeBSD_powerpc32() override;
- size_t
- GetGPRSize() const override;
+ size_t GetGPRSize() const override;
- const lldb_private::RegisterInfo *
- GetRegisterInfo() const override;
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
- uint32_t
- GetRegisterCount() const override;
+ uint32_t GetRegisterCount() const override;
};
-class RegisterContextFreeBSD_powerpc64:
- public RegisterContextFreeBSD_powerpc
-{
+class RegisterContextFreeBSD_powerpc64 : public RegisterContextFreeBSD_powerpc {
public:
- RegisterContextFreeBSD_powerpc64(const lldb_private::ArchSpec &target_arch);
- ~RegisterContextFreeBSD_powerpc64() override;
+ RegisterContextFreeBSD_powerpc64(const lldb_private::ArchSpec &target_arch);
+ ~RegisterContextFreeBSD_powerpc64() override;
- size_t
- GetGPRSize() const override;
+ size_t GetGPRSize() const override;
- const lldb_private::RegisterInfo *
- GetRegisterInfo() const override;
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
- uint32_t
- GetRegisterCount() const override;
+ uint32_t GetRegisterCount() const override;
};
#endif // liblldb_RegisterContextFreeBSD_powerpc_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp b/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp
index 34f2d185da8a..4bbbd5c3d0a6 100644
--- a/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp
@@ -7,158 +7,142 @@
//
//===---------------------------------------------------------------------===//
-#include <vector>
-#include "RegisterContextPOSIX_x86.h"
-#include "RegisterContextFreeBSD_i386.h"
#include "RegisterContextFreeBSD_x86_64.h"
+#include "RegisterContextFreeBSD_i386.h"
+#include "RegisterContextPOSIX_x86.h"
+#include <vector>
using namespace lldb_private;
using namespace lldb;
// http://svnweb.freebsd.org/base/head/sys/x86/include/reg.h
-typedef struct _GPR
-{
- uint64_t r15;
- uint64_t r14;
- uint64_t r13;
- uint64_t r12;
- uint64_t r11;
- uint64_t r10;
- uint64_t r9;
- uint64_t r8;
- uint64_t rdi;
- uint64_t rsi;
- uint64_t rbp;
- uint64_t rbx;
- uint64_t rdx;
- uint64_t rcx;
- uint64_t rax;
- uint32_t trapno;
- uint16_t fs;
- uint16_t gs;
- uint32_t err;
- uint16_t es;
- uint16_t ds;
- uint64_t rip;
- uint64_t cs;
- uint64_t rflags;
- uint64_t rsp;
- uint64_t ss;
+typedef struct _GPR {
+ uint64_t r15;
+ uint64_t r14;
+ uint64_t r13;
+ uint64_t r12;
+ uint64_t r11;
+ uint64_t r10;
+ uint64_t r9;
+ uint64_t r8;
+ uint64_t rdi;
+ uint64_t rsi;
+ uint64_t rbp;
+ uint64_t rbx;
+ uint64_t rdx;
+ uint64_t rcx;
+ uint64_t rax;
+ uint32_t trapno;
+ uint16_t fs;
+ uint16_t gs;
+ uint32_t err;
+ uint16_t es;
+ uint16_t ds;
+ uint64_t rip;
+ uint64_t cs;
+ uint64_t rflags;
+ uint64_t rsp;
+ uint64_t ss;
} GPR;
struct DBG {
- uint64_t dr[16]; /* debug registers */
- /* Index 0-3: debug address registers */
- /* Index 4-5: reserved */
- /* Index 6: debug status */
- /* Index 7: debug control */
- /* Index 8-15: reserved */
+ uint64_t dr[16]; /* debug registers */
+ /* Index 0-3: debug address registers */
+ /* Index 4-5: reserved */
+ /* Index 6: debug status */
+ /* Index 7: debug control */
+ /* Index 8-15: reserved */
};
-struct UserArea
-{
- GPR gpr;
- FPR fpr;
- DBG dbg;
+struct UserArea {
+ GPR gpr;
+ FPR fpr;
+ DBG dbg;
};
-#define DR_OFFSET(reg_index) \
- (LLVM_EXTENSION offsetof(DBG, dr[reg_index]))
+#define DR_OFFSET(reg_index) (LLVM_EXTENSION offsetof(DBG, dr[reg_index]))
//---------------------------------------------------------------------------
-// Include RegisterInfos_x86_64 to declare our g_register_infos_x86_64 structure.
+// Include RegisterInfos_x86_64 to declare our g_register_infos_x86_64
+// structure.
//---------------------------------------------------------------------------
#define DECLARE_REGISTER_INFOS_X86_64_STRUCT
#include "RegisterInfos_x86_64.h"
#undef DECLARE_REGISTER_INFOS_X86_64_STRUCT
-static std::vector<lldb_private::RegisterInfo>&
-GetSharedRegisterInfoVector ()
-{
- static std::vector<lldb_private::RegisterInfo> register_infos;
- return register_infos;
+static std::vector<lldb_private::RegisterInfo> &GetSharedRegisterInfoVector() {
+ static std::vector<lldb_private::RegisterInfo> register_infos;
+ return register_infos;
}
static const RegisterInfo *
-GetRegisterInfo_i386(const lldb_private::ArchSpec& arch)
-{
- static std::vector<lldb_private::RegisterInfo> g_register_infos (GetSharedRegisterInfoVector ());
-
- // Allocate RegisterInfo only once
- if (g_register_infos.empty())
- {
- // Copy the register information from base class
- std::unique_ptr<RegisterContextFreeBSD_i386> reg_interface(new RegisterContextFreeBSD_i386 (arch));
- const RegisterInfo *base_info = reg_interface->GetRegisterInfo();
- g_register_infos.insert(g_register_infos.end(), &base_info[0], &base_info[k_num_registers_i386]);
-
- //---------------------------------------------------------------------------
- // Include RegisterInfos_x86_64 to update the g_register_infos structure
- // with x86_64 offsets.
- //---------------------------------------------------------------------------
- #define UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
- #include "RegisterInfos_x86_64.h"
- #undef UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
- }
-
- return &g_register_infos[0];
+GetRegisterInfo_i386(const lldb_private::ArchSpec &arch) {
+ static std::vector<lldb_private::RegisterInfo> g_register_infos(
+ GetSharedRegisterInfoVector());
+
+ // Allocate RegisterInfo only once
+ if (g_register_infos.empty()) {
+ // Copy the register information from base class
+ std::unique_ptr<RegisterContextFreeBSD_i386> reg_interface(
+ new RegisterContextFreeBSD_i386(arch));
+ const RegisterInfo *base_info = reg_interface->GetRegisterInfo();
+ g_register_infos.insert(g_register_infos.end(), &base_info[0],
+ &base_info[k_num_registers_i386]);
+
+//---------------------------------------------------------------------------
+// Include RegisterInfos_x86_64 to update the g_register_infos structure
+// with x86_64 offsets.
+//---------------------------------------------------------------------------
+#define UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
+#include "RegisterInfos_x86_64.h"
+#undef UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
+ }
+
+ return &g_register_infos[0];
}
static const RegisterInfo *
-PrivateGetRegisterInfoPtr (const lldb_private::ArchSpec& target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::x86:
- return GetRegisterInfo_i386 (target_arch);
- case llvm::Triple::x86_64:
- return g_register_infos_x86_64;
- default:
- assert(false && "Unhandled target architecture.");
- return nullptr;
- }
+PrivateGetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::x86:
+ return GetRegisterInfo_i386(target_arch);
+ case llvm::Triple::x86_64:
+ return g_register_infos_x86_64;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return nullptr;
+ }
}
static uint32_t
-PrivateGetRegisterCount (const lldb_private::ArchSpec& target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::x86:
- // This vector should have already been filled.
- assert (!GetSharedRegisterInfoVector ().empty () && "i386 register info vector not filled.");
- return static_cast<uint32_t> (GetSharedRegisterInfoVector().size ());
- case llvm::Triple::x86_64:
- return static_cast<uint32_t> (sizeof (g_register_infos_x86_64) / sizeof (g_register_infos_x86_64 [0]));
- default:
- assert(false && "Unhandled target architecture.");
- return 0;
- }
+PrivateGetRegisterCount(const lldb_private::ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::x86:
+ // This vector should have already been filled.
+ assert(!GetSharedRegisterInfoVector().empty() &&
+ "i386 register info vector not filled.");
+ return static_cast<uint32_t>(GetSharedRegisterInfoVector().size());
+ case llvm::Triple::x86_64:
+ return static_cast<uint32_t>(sizeof(g_register_infos_x86_64) /
+ sizeof(g_register_infos_x86_64[0]));
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
}
-RegisterContextFreeBSD_x86_64::RegisterContextFreeBSD_x86_64(const ArchSpec &target_arch) :
- lldb_private::RegisterInfoInterface(target_arch),
- m_register_info_p (PrivateGetRegisterInfoPtr (target_arch)),
- m_register_count (PrivateGetRegisterCount (target_arch))
-{
-}
+RegisterContextFreeBSD_x86_64::RegisterContextFreeBSD_x86_64(
+ const ArchSpec &target_arch)
+ : lldb_private::RegisterInfoInterface(target_arch),
+ m_register_info_p(PrivateGetRegisterInfoPtr(target_arch)),
+ m_register_count(PrivateGetRegisterCount(target_arch)) {}
-size_t
-RegisterContextFreeBSD_x86_64::GetGPRSize() const
-{
- return sizeof(GPR);
-}
+size_t RegisterContextFreeBSD_x86_64::GetGPRSize() const { return sizeof(GPR); }
-const RegisterInfo *
-RegisterContextFreeBSD_x86_64::GetRegisterInfo() const
-{
- return m_register_info_p;
+const RegisterInfo *RegisterContextFreeBSD_x86_64::GetRegisterInfo() const {
+ return m_register_info_p;
}
-uint32_t
-RegisterContextFreeBSD_x86_64::GetRegisterCount () const
-{
- return m_register_count;
+uint32_t RegisterContextFreeBSD_x86_64::GetRegisterCount() const {
+ return m_register_count;
}
-
-
diff --git a/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h b/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h
index e739fa50ed6c..dc30f1783b41 100644
--- a/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h
+++ b/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h
@@ -12,24 +12,20 @@
#include "RegisterInfoInterface.h"
-class RegisterContextFreeBSD_x86_64:
- public lldb_private::RegisterInfoInterface
-{
+class RegisterContextFreeBSD_x86_64
+ : public lldb_private::RegisterInfoInterface {
public:
- RegisterContextFreeBSD_x86_64(const lldb_private::ArchSpec &target_arch);
+ RegisterContextFreeBSD_x86_64(const lldb_private::ArchSpec &target_arch);
- size_t
- GetGPRSize() const override;
+ size_t GetGPRSize() const override;
- const lldb_private::RegisterInfo *
- GetRegisterInfo() const override;
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
- uint32_t
- GetRegisterCount () const override;
+ uint32_t GetRegisterCount() const override;
private:
- const lldb_private::RegisterInfo *m_register_info_p;
- const uint32_t m_register_count;
+ const lldb_private::RegisterInfo *m_register_info_p;
+ const uint32_t m_register_count;
};
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextHistory.cpp b/source/Plugins/Process/Utility/RegisterContextHistory.cpp
index 9d2181376e09..0fc47fcd8e3a 100644
--- a/source/Plugins/Process/Utility/RegisterContextHistory.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextHistory.cpp
@@ -1,4 +1,5 @@
-//===-- RegisterContextHistory.cpp ---------------------------------*- C++ -*-===//
+//===-- RegisterContextHistory.cpp ---------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,8 +8,6 @@
//
//===----------------------------------------------------------------------===//
-
-#include "lldb/lldb-private.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/AddressRange.h"
#include "lldb/Core/DataBufferHeap.h"
@@ -20,119 +19,105 @@
#include "lldb/Symbol/FuncUnwinders.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/Symbol.h"
+#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Target/ABI.h"
+#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-#include "lldb/Target/DynamicLoader.h"
+#include "lldb/lldb-private.h"
#include "RegisterContextHistory.h"
using namespace lldb;
using namespace lldb_private;
-RegisterContextHistory::RegisterContextHistory (Thread &thread, uint32_t concrete_frame_idx, uint32_t address_byte_size, addr_t pc_value) :
-RegisterContext (thread, concrete_frame_idx),
- m_pc_value (pc_value)
-{
- m_reg_set0.name = "General Purpose Registers";
- m_reg_set0.short_name = "GPR";
- m_reg_set0.num_registers = 1;
- m_reg_set0.registers = new uint32_t(0);
-
- m_pc_reg_info.name = "pc";
- m_pc_reg_info.alt_name = "pc";
- m_pc_reg_info.byte_offset = 0;
- m_pc_reg_info.byte_size = address_byte_size;
- m_pc_reg_info.encoding = eEncodingUint;
- m_pc_reg_info.format = eFormatPointer;
- m_pc_reg_info.invalidate_regs = NULL;
- m_pc_reg_info.value_regs = NULL;
- m_pc_reg_info.kinds[eRegisterKindEHFrame] = LLDB_INVALID_REGNUM;
- m_pc_reg_info.kinds[eRegisterKindDWARF] = LLDB_INVALID_REGNUM;
- m_pc_reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
- m_pc_reg_info.kinds[eRegisterKindProcessPlugin] = LLDB_INVALID_REGNUM;
- m_pc_reg_info.kinds[eRegisterKindLLDB] = LLDB_INVALID_REGNUM;
+RegisterContextHistory::RegisterContextHistory(Thread &thread,
+ uint32_t concrete_frame_idx,
+ uint32_t address_byte_size,
+ addr_t pc_value)
+ : RegisterContext(thread, concrete_frame_idx), m_pc_value(pc_value) {
+ m_reg_set0.name = "General Purpose Registers";
+ m_reg_set0.short_name = "GPR";
+ m_reg_set0.num_registers = 1;
+ m_reg_set0.registers = new uint32_t(0);
+
+ m_pc_reg_info.name = "pc";
+ m_pc_reg_info.alt_name = "pc";
+ m_pc_reg_info.byte_offset = 0;
+ m_pc_reg_info.byte_size = address_byte_size;
+ m_pc_reg_info.encoding = eEncodingUint;
+ m_pc_reg_info.format = eFormatPointer;
+ m_pc_reg_info.invalidate_regs = NULL;
+ m_pc_reg_info.value_regs = NULL;
+ m_pc_reg_info.kinds[eRegisterKindEHFrame] = LLDB_INVALID_REGNUM;
+ m_pc_reg_info.kinds[eRegisterKindDWARF] = LLDB_INVALID_REGNUM;
+ m_pc_reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
+ m_pc_reg_info.kinds[eRegisterKindProcessPlugin] = LLDB_INVALID_REGNUM;
+ m_pc_reg_info.kinds[eRegisterKindLLDB] = LLDB_INVALID_REGNUM;
}
-RegisterContextHistory::~RegisterContextHistory ()
-{
- delete m_reg_set0.registers;
- delete m_pc_reg_info.invalidate_regs;
- delete m_pc_reg_info.value_regs;
+RegisterContextHistory::~RegisterContextHistory() {
+ delete m_reg_set0.registers;
+ delete m_pc_reg_info.invalidate_regs;
+ delete m_pc_reg_info.value_regs;
}
-void
-RegisterContextHistory::InvalidateAllRegisters () {}
+void RegisterContextHistory::InvalidateAllRegisters() {}
-size_t
-RegisterContextHistory::GetRegisterCount ()
-{
- return 1;
-}
+size_t RegisterContextHistory::GetRegisterCount() { return 1; }
const lldb_private::RegisterInfo *
-RegisterContextHistory::GetRegisterInfoAtIndex (size_t reg)
-{
- if (reg)
- return NULL;
- return &m_pc_reg_info;
+RegisterContextHistory::GetRegisterInfoAtIndex(size_t reg) {
+ if (reg)
+ return NULL;
+ return &m_pc_reg_info;
}
-size_t
-RegisterContextHistory::GetRegisterSetCount ()
-{
- return 1;
-}
+size_t RegisterContextHistory::GetRegisterSetCount() { return 1; }
const lldb_private::RegisterSet *
-RegisterContextHistory::GetRegisterSet (size_t reg_set)
-{
- if (reg_set)
- return NULL;
- return &m_reg_set0;
+RegisterContextHistory::GetRegisterSet(size_t reg_set) {
+ if (reg_set)
+ return NULL;
+ return &m_reg_set0;
}
-bool
-RegisterContextHistory::ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value)
-{
- if (!reg_info)
- return false;
- uint32_t reg_number = reg_info->kinds[eRegisterKindGeneric];
- if (reg_number == LLDB_REGNUM_GENERIC_PC)
- {
- value.SetUInt(m_pc_value, reg_info->byte_size);
- return true;
- }
+bool RegisterContextHistory::ReadRegister(
+ const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) {
+ if (!reg_info)
return false;
+ uint32_t reg_number = reg_info->kinds[eRegisterKindGeneric];
+ if (reg_number == LLDB_REGNUM_GENERIC_PC) {
+ value.SetUInt(m_pc_value, reg_info->byte_size);
+ return true;
+ }
+ return false;
}
-bool
-RegisterContextHistory::WriteRegister (const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value)
-{
- return false;
+bool RegisterContextHistory::WriteRegister(
+ const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) {
+ return false;
}
-bool
-RegisterContextHistory::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextHistory::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ return false;
}
-bool
-RegisterContextHistory::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextHistory::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ return false;
}
-uint32_t
-RegisterContextHistory::ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t num)
-{
- if (kind == eRegisterKindGeneric && num == LLDB_REGNUM_GENERIC_PC)
- return 0;
- return LLDB_INVALID_REGNUM;
+uint32_t RegisterContextHistory::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t num) {
+ if (kind == eRegisterKindGeneric && num == LLDB_REGNUM_GENERIC_PC)
+ return 0;
+ return LLDB_INVALID_REGNUM;
}
diff --git a/source/Plugins/Process/Utility/RegisterContextHistory.h b/source/Plugins/Process/Utility/RegisterContextHistory.h
index 3f44a1fde68b..acaf8fe5c04a 100644
--- a/source/Plugins/Process/Utility/RegisterContextHistory.h
+++ b/source/Plugins/Process/Utility/RegisterContextHistory.h
@@ -1,4 +1,5 @@
-//===-- RegisterContextHistory.h ----------------------------------------*- C++ -*-===//
+//===-- RegisterContextHistory.h ----------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,64 +17,55 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
-#include "lldb/Target/RegisterContext.h"
#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/lldb-private.h"
namespace lldb_private {
-
-class RegisterContextHistory : public lldb_private::RegisterContext
-{
+
+class RegisterContextHistory : public lldb_private::RegisterContext {
public:
- typedef std::shared_ptr<RegisterContextHistory> SharedPtr;
-
- RegisterContextHistory (Thread &thread, uint32_t concrete_frame_idx, uint32_t address_byte_size, lldb::addr_t pc_value);
-
- ~RegisterContextHistory() override;
+ typedef std::shared_ptr<RegisterContextHistory> SharedPtr;
+
+ RegisterContextHistory(Thread &thread, uint32_t concrete_frame_idx,
+ uint32_t address_byte_size, lldb::addr_t pc_value);
- void
- InvalidateAllRegisters() override;
+ ~RegisterContextHistory() override;
- size_t
- GetRegisterCount() override;
+ void InvalidateAllRegisters() override;
- const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex(size_t reg) override;
+ size_t GetRegisterCount() override;
- size_t
- GetRegisterSetCount() override;
+ const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
- const lldb_private::RegisterSet *
- GetRegisterSet(size_t reg_set) override;
+ size_t GetRegisterSetCount() override;
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value) override;
+ const lldb_private::RegisterSet *GetRegisterSet(size_t reg_set) override;
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value) override;
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) override;
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) override;
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
- uint32_t
- ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
-
private:
- //------------------------------------------------------------------
- // For RegisterContextLLDB only
- //------------------------------------------------------------------
-
- lldb_private::RegisterSet m_reg_set0; // register set 0 (PC only)
- lldb_private::RegisterInfo m_pc_reg_info;
-
- lldb::addr_t m_pc_value;
-
- DISALLOW_COPY_AND_ASSIGN (RegisterContextHistory);
+ //------------------------------------------------------------------
+ // For RegisterContextLLDB only
+ //------------------------------------------------------------------
+
+ lldb_private::RegisterSet m_reg_set0; // register set 0 (PC only)
+ lldb_private::RegisterInfo m_pc_reg_info;
+
+ lldb::addr_t m_pc_value;
+
+ DISALLOW_COPY_AND_ASSIGN(RegisterContextHistory);
};
} // namespace lldb_private
diff --git a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
index 8bbaeb8e9a59..3c33ddb335d6 100644
--- a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-
-#include "lldb/lldb-private.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/AddressRange.h"
#include "lldb/Core/DataBufferHeap.h"
@@ -33,1829 +31,1824 @@
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
+#include "lldb/lldb-private.h"
#include "RegisterContextLLDB.h"
using namespace lldb;
using namespace lldb_private;
-static ConstString GetSymbolOrFunctionName(const SymbolContext &sym_ctx)
-{
- if (sym_ctx.symbol)
- return sym_ctx.symbol->GetName();
- else if (sym_ctx.function)
- return sym_ctx.function->GetName();
- return ConstString();
+static ConstString GetSymbolOrFunctionName(const SymbolContext &sym_ctx) {
+ if (sym_ctx.symbol)
+ return sym_ctx.symbol->GetName();
+ else if (sym_ctx.function)
+ return sym_ctx.function->GetName();
+ return ConstString();
}
-RegisterContextLLDB::RegisterContextLLDB
-(
- Thread& thread,
- const SharedPtr &next_frame,
- SymbolContext& sym_ctx,
- uint32_t frame_number,
- UnwindLLDB& unwind_lldb
-) :
- RegisterContext (thread, frame_number),
- m_thread(thread),
- m_fast_unwind_plan_sp (),
- m_full_unwind_plan_sp (),
- m_fallback_unwind_plan_sp (),
- m_all_registers_available(false),
- m_frame_type (-1),
- m_cfa (LLDB_INVALID_ADDRESS),
- m_start_pc (),
- m_current_pc (),
- m_current_offset (0),
- m_current_offset_backed_up_one (0),
- m_sym_ctx(sym_ctx),
- m_sym_ctx_valid (false),
- m_frame_number (frame_number),
- m_registers(),
- m_parent_unwind (unwind_lldb)
-{
- m_sym_ctx.Clear(false);
- m_sym_ctx_valid = false;
-
- if (IsFrameZero ())
- {
- InitializeZerothFrame ();
- }
- else
- {
- InitializeNonZerothFrame ();
- }
-
- // This same code exists over in the GetFullUnwindPlanForFrame() but it may not have been executed yet
- if (IsFrameZero()
- || next_frame->m_frame_type == eTrapHandlerFrame
- || next_frame->m_frame_type == eDebuggerFrame)
- {
- m_all_registers_available = true;
- }
+RegisterContextLLDB::RegisterContextLLDB(Thread &thread,
+ const SharedPtr &next_frame,
+ SymbolContext &sym_ctx,
+ uint32_t frame_number,
+ UnwindLLDB &unwind_lldb)
+ : RegisterContext(thread, frame_number), m_thread(thread),
+ m_fast_unwind_plan_sp(), m_full_unwind_plan_sp(),
+ m_fallback_unwind_plan_sp(), m_all_registers_available(false),
+ m_frame_type(-1), m_cfa(LLDB_INVALID_ADDRESS), m_start_pc(),
+ m_current_pc(), m_current_offset(0), m_current_offset_backed_up_one(0),
+ m_sym_ctx(sym_ctx), m_sym_ctx_valid(false), m_frame_number(frame_number),
+ m_registers(), m_parent_unwind(unwind_lldb) {
+ m_sym_ctx.Clear(false);
+ m_sym_ctx_valid = false;
+
+ if (IsFrameZero()) {
+ InitializeZerothFrame();
+ } else {
+ InitializeNonZerothFrame();
+ }
+
+ // This same code exists over in the GetFullUnwindPlanForFrame() but it may
+ // not have been executed yet
+ if (IsFrameZero() || next_frame->m_frame_type == eTrapHandlerFrame ||
+ next_frame->m_frame_type == eDebuggerFrame) {
+ m_all_registers_available = true;
+ }
}
-bool
-RegisterContextLLDB::IsUnwindPlanValidForCurrentPC(lldb::UnwindPlanSP unwind_plan_sp, int &valid_pc_offset)
-{
- if (!unwind_plan_sp)
- return false;
+bool RegisterContextLLDB::IsUnwindPlanValidForCurrentPC(
+ lldb::UnwindPlanSP unwind_plan_sp, int &valid_pc_offset) {
+ if (!unwind_plan_sp)
+ return false;
- // check if m_current_pc is valid
- if (unwind_plan_sp->PlanValidAtAddress(m_current_pc))
- {
- // yes - current offset can be used as is
- valid_pc_offset = m_current_offset;
- return true;
- }
+ // check if m_current_pc is valid
+ if (unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
+ // yes - current offset can be used as is
+ valid_pc_offset = m_current_offset;
+ return true;
+ }
- // if m_current_offset <= 0, we've got nothing else to try
- if (m_current_offset <= 0)
- return false;
+ // if m_current_offset <= 0, we've got nothing else to try
+ if (m_current_offset <= 0)
+ return false;
- // check pc - 1 to see if it's valid
- Address pc_minus_one (m_current_pc);
- pc_minus_one.SetOffset(m_current_pc.GetOffset() - 1);
- if (unwind_plan_sp->PlanValidAtAddress(pc_minus_one))
- {
- // *valid_pc_offset = m_current_offset - 1;
- valid_pc_offset = m_current_pc.GetOffset() - 1;
- return true;
- }
+ // check pc - 1 to see if it's valid
+ Address pc_minus_one(m_current_pc);
+ pc_minus_one.SetOffset(m_current_pc.GetOffset() - 1);
+ if (unwind_plan_sp->PlanValidAtAddress(pc_minus_one)) {
+ // *valid_pc_offset = m_current_offset - 1;
+ valid_pc_offset = m_current_pc.GetOffset() - 1;
+ return true;
+ }
- return false;
+ return false;
}
-// Initialize a RegisterContextLLDB which is the first frame of a stack -- the zeroth frame or currently
+// Initialize a RegisterContextLLDB which is the first frame of a stack -- the
+// zeroth frame or currently
// executing frame.
-void
-RegisterContextLLDB::InitializeZerothFrame()
-{
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
- ExecutionContext exe_ctx(m_thread.shared_from_this());
- RegisterContextSP reg_ctx_sp = m_thread.GetRegisterContext();
-
- if (reg_ctx_sp.get() == NULL)
- {
- m_frame_type = eNotAValidFrame;
- UnwindLogMsg ("frame does not have a register context");
- return;
- }
-
- addr_t current_pc = reg_ctx_sp->GetPC();
+void RegisterContextLLDB::InitializeZerothFrame() {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
+ ExecutionContext exe_ctx(m_thread.shared_from_this());
+ RegisterContextSP reg_ctx_sp = m_thread.GetRegisterContext();
- if (current_pc == LLDB_INVALID_ADDRESS)
- {
- m_frame_type = eNotAValidFrame;
- UnwindLogMsg ("frame does not have a pc");
- return;
- }
-
- Process *process = exe_ctx.GetProcessPtr();
-
- // Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs
- // this will strip bit zero in case we read a PC from memory or from the LR.
- // (which would be a no-op in frame 0 where we get it from the register set,
- // but still a good idea to make the call here for other ABIs that may exist.)
- ABI *abi = process->GetABI().get();
- if (abi)
- current_pc = abi->FixCodeAddress(current_pc);
-
- // Initialize m_current_pc, an Address object, based on current_pc, an addr_t.
- m_current_pc.SetLoadAddress (current_pc, &process->GetTarget());
-
- // If we don't have a Module for some reason, we're not going to find symbol/function information - just
- // stick in some reasonable defaults and hope we can unwind past this frame.
- ModuleSP pc_module_sp (m_current_pc.GetModule());
- if (!m_current_pc.IsValid() || !pc_module_sp)
- {
- UnwindLogMsg ("using architectural default unwind method");
- }
+ if (reg_ctx_sp.get() == NULL) {
+ m_frame_type = eNotAValidFrame;
+ UnwindLogMsg("frame does not have a register context");
+ return;
+ }
- // We require either a symbol or function in the symbols context to be successfully
- // filled in or this context is of no use to us.
- const uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol;
- if (pc_module_sp.get()
- && (pc_module_sp->ResolveSymbolContextForAddress (m_current_pc, resolve_scope, m_sym_ctx) & resolve_scope))
- {
- m_sym_ctx_valid = true;
- }
+ addr_t current_pc = reg_ctx_sp->GetPC();
- if (m_sym_ctx.symbol)
- {
- UnwindLogMsg ("with pc value of 0x%" PRIx64 ", symbol name is '%s'",
- current_pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
- }
- else if (m_sym_ctx.function)
- {
- UnwindLogMsg ("with pc value of 0x%" PRIx64 ", function name is '%s'",
- current_pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
- }
- else
- {
- UnwindLogMsg ("with pc value of 0x%" PRIx64 ", no symbol/function name is known.", current_pc);
- }
-
- AddressRange addr_range;
- m_sym_ctx.GetAddressRange (resolve_scope, 0, false, addr_range);
+ if (current_pc == LLDB_INVALID_ADDRESS) {
+ m_frame_type = eNotAValidFrame;
+ UnwindLogMsg("frame does not have a pc");
+ return;
+ }
+
+ Process *process = exe_ctx.GetProcessPtr();
+
+ // Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs
+ // this will strip bit zero in case we read a PC from memory or from the LR.
+ // (which would be a no-op in frame 0 where we get it from the register set,
+ // but still a good idea to make the call here for other ABIs that may exist.)
+ ABI *abi = process->GetABI().get();
+ if (abi)
+ current_pc = abi->FixCodeAddress(current_pc);
+
+ // Initialize m_current_pc, an Address object, based on current_pc, an addr_t.
+ m_current_pc.SetLoadAddress(current_pc, &process->GetTarget());
+
+ // If we don't have a Module for some reason, we're not going to find
+ // symbol/function information - just
+ // stick in some reasonable defaults and hope we can unwind past this frame.
+ ModuleSP pc_module_sp(m_current_pc.GetModule());
+ if (!m_current_pc.IsValid() || !pc_module_sp) {
+ UnwindLogMsg("using architectural default unwind method");
+ }
+
+ // We require either a symbol or function in the symbols context to be
+ // successfully
+ // filled in or this context is of no use to us.
+ const uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol;
+ if (pc_module_sp.get() && (pc_module_sp->ResolveSymbolContextForAddress(
+ m_current_pc, resolve_scope, m_sym_ctx) &
+ resolve_scope)) {
+ m_sym_ctx_valid = true;
+ }
+
+ if (m_sym_ctx.symbol) {
+ UnwindLogMsg("with pc value of 0x%" PRIx64 ", symbol name is '%s'",
+ current_pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
+ } else if (m_sym_ctx.function) {
+ UnwindLogMsg("with pc value of 0x%" PRIx64 ", function name is '%s'",
+ current_pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
+ } else {
+ UnwindLogMsg("with pc value of 0x%" PRIx64
+ ", no symbol/function name is known.",
+ current_pc);
+ }
+
+ AddressRange addr_range;
+ m_sym_ctx.GetAddressRange(resolve_scope, 0, false, addr_range);
+
+ if (IsTrapHandlerSymbol(process, m_sym_ctx)) {
+ m_frame_type = eTrapHandlerFrame;
+ } else {
+ // FIXME: Detect eDebuggerFrame here.
+ m_frame_type = eNormalFrame;
+ }
+
+ // If we were able to find a symbol/function, set addr_range to the bounds of
+ // that symbol/function.
+ // else treat the current pc value as the start_pc and record no offset.
+ if (addr_range.GetBaseAddress().IsValid()) {
+ m_start_pc = addr_range.GetBaseAddress();
+ if (m_current_pc.GetSection() == m_start_pc.GetSection()) {
+ m_current_offset = m_current_pc.GetOffset() - m_start_pc.GetOffset();
+ } else if (m_current_pc.GetModule() == m_start_pc.GetModule()) {
+ // This means that whatever symbol we kicked up isn't really correct
+ // --- we should not cross section boundaries ... We really should NULL
+ // out
+ // the function/symbol in this case unless there is a bad assumption
+ // here due to inlined functions?
+ m_current_offset =
+ m_current_pc.GetFileAddress() - m_start_pc.GetFileAddress();
+ }
+ m_current_offset_backed_up_one = m_current_offset;
+ } else {
+ m_start_pc = m_current_pc;
+ m_current_offset = -1;
+ m_current_offset_backed_up_one = -1;
+ }
+
+ // We've set m_frame_type and m_sym_ctx before these calls.
+
+ m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame();
+ m_full_unwind_plan_sp = GetFullUnwindPlanForFrame();
+
+ UnwindPlan::RowSP active_row;
+ lldb::RegisterKind row_register_kind = eRegisterKindGeneric;
+ if (m_full_unwind_plan_sp &&
+ m_full_unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
+ active_row =
+ m_full_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
+ row_register_kind = m_full_unwind_plan_sp->GetRegisterKind();
+ if (active_row.get() && log) {
+ StreamString active_row_strm;
+ active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread,
+ m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
+ UnwindLogMsg("%s", active_row_strm.GetData());
+ }
+ }
+
+ if (!active_row.get()) {
+ UnwindLogMsg("could not find an unwindplan row for this frame's pc");
+ m_frame_type = eNotAValidFrame;
+ return;
+ }
- if (IsTrapHandlerSymbol (process, m_sym_ctx))
- {
- m_frame_type = eTrapHandlerFrame;
- }
- else
- {
- // FIXME: Detect eDebuggerFrame here.
- m_frame_type = eNormalFrame;
- }
+ if (!ReadCFAValueForRow(row_register_kind, active_row, m_cfa)) {
+ // Try the fall back unwind plan since the
+ // full unwind plan failed.
+ FuncUnwindersSP func_unwinders_sp;
+ UnwindPlanSP call_site_unwind_plan;
+ bool cfa_status = false;
- // If we were able to find a symbol/function, set addr_range to the bounds of that symbol/function.
- // else treat the current pc value as the start_pc and record no offset.
- if (addr_range.GetBaseAddress().IsValid())
- {
- m_start_pc = addr_range.GetBaseAddress();
- if (m_current_pc.GetSection() == m_start_pc.GetSection())
- {
- m_current_offset = m_current_pc.GetOffset() - m_start_pc.GetOffset();
- }
- else if (m_current_pc.GetModule() == m_start_pc.GetModule())
- {
- // This means that whatever symbol we kicked up isn't really correct
- // --- we should not cross section boundaries ... We really should NULL out
- // the function/symbol in this case unless there is a bad assumption
- // here due to inlined functions?
- m_current_offset = m_current_pc.GetFileAddress() - m_start_pc.GetFileAddress();
- }
- m_current_offset_backed_up_one = m_current_offset;
- }
- else
- {
- m_start_pc = m_current_pc;
- m_current_offset = -1;
- m_current_offset_backed_up_one = -1;
+ if (m_sym_ctx_valid) {
+ func_unwinders_sp =
+ pc_module_sp->GetObjectFile()
+ ->GetUnwindTable()
+ .GetFuncUnwindersContainingAddress(m_current_pc, m_sym_ctx);
}
- // We've set m_frame_type and m_sym_ctx before these calls.
+ if (func_unwinders_sp.get() != nullptr)
+ call_site_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(
+ process->GetTarget(), m_current_offset_backed_up_one);
- m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame ();
- m_full_unwind_plan_sp = GetFullUnwindPlanForFrame ();
-
- UnwindPlan::RowSP active_row;
- lldb::RegisterKind row_register_kind = eRegisterKindGeneric;
- if (m_full_unwind_plan_sp && m_full_unwind_plan_sp->PlanValidAtAddress (m_current_pc))
- {
- active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
- row_register_kind = m_full_unwind_plan_sp->GetRegisterKind ();
- if (active_row.get() && log)
- {
- StreamString active_row_strm;
- active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
- UnwindLogMsg ("%s", active_row_strm.GetString().c_str());
- }
+ if (call_site_unwind_plan.get() != nullptr) {
+ m_fallback_unwind_plan_sp = call_site_unwind_plan;
+ if (TryFallbackUnwindPlan())
+ cfa_status = true;
}
-
- if (!active_row.get())
- {
- UnwindLogMsg ("could not find an unwindplan row for this frame's pc");
- m_frame_type = eNotAValidFrame;
- return;
- }
-
-
- if (!ReadCFAValueForRow (row_register_kind, active_row, m_cfa))
- {
- // Try the fall back unwind plan since the
- // full unwind plan failed.
- FuncUnwindersSP func_unwinders_sp;
- UnwindPlanSP call_site_unwind_plan;
- bool cfa_status = false;
-
- if (m_sym_ctx_valid)
- {
- func_unwinders_sp = pc_module_sp->GetObjectFile()->GetUnwindTable().GetFuncUnwindersContainingAddress (m_current_pc, m_sym_ctx);
- }
-
- if(func_unwinders_sp.get() != nullptr)
- call_site_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget(), m_current_offset_backed_up_one);
-
- if (call_site_unwind_plan.get() != nullptr)
- {
- m_fallback_unwind_plan_sp = call_site_unwind_plan;
- if(TryFallbackUnwindPlan())
- cfa_status = true;
- }
- if (!cfa_status)
- {
- UnwindLogMsg ("could not read CFA value for first frame.");
- m_frame_type = eNotAValidFrame;
- return;
- }
+ if (!cfa_status) {
+ UnwindLogMsg("could not read CFA value for first frame.");
+ m_frame_type = eNotAValidFrame;
+ return;
}
+ }
- UnwindLogMsg ("initialized frame current pc is 0x%" PRIx64 " cfa is 0x%" PRIx64 " using %s UnwindPlan",
- (uint64_t) m_current_pc.GetLoadAddress (exe_ctx.GetTargetPtr()),
- (uint64_t) m_cfa,
- m_full_unwind_plan_sp->GetSourceName().GetCString());
+ UnwindLogMsg("initialized frame current pc is 0x%" PRIx64 " cfa is 0x%" PRIx64
+ " using %s UnwindPlan",
+ (uint64_t)m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr()),
+ (uint64_t)m_cfa,
+ m_full_unwind_plan_sp->GetSourceName().GetCString());
}
-// Initialize a RegisterContextLLDB for the non-zeroth frame -- rely on the RegisterContextLLDB "below" it
+// Initialize a RegisterContextLLDB for the non-zeroth frame -- rely on the
+// RegisterContextLLDB "below" it
// to provide things like its current pc value.
-void
-RegisterContextLLDB::InitializeNonZerothFrame()
-{
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
- if (IsFrameZero ())
- {
- m_frame_type = eNotAValidFrame;
- UnwindLogMsg ("non-zeroth frame tests positive for IsFrameZero -- that shouldn't happen.");
- return;
- }
-
- if (!GetNextFrame().get() || !GetNextFrame()->IsValid())
- {
- m_frame_type = eNotAValidFrame;
- UnwindLogMsg ("Could not get next frame, marking this frame as invalid.");
- return;
- }
- if (!m_thread.GetRegisterContext())
- {
- m_frame_type = eNotAValidFrame;
- UnwindLogMsg ("Could not get register context for this thread, marking this frame as invalid.");
- return;
- }
+void RegisterContextLLDB::InitializeNonZerothFrame() {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
+ if (IsFrameZero()) {
+ m_frame_type = eNotAValidFrame;
+ UnwindLogMsg("non-zeroth frame tests positive for IsFrameZero -- that "
+ "shouldn't happen.");
+ return;
+ }
- addr_t pc;
- if (!ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc))
- {
- UnwindLogMsg ("could not get pc value");
+ if (!GetNextFrame().get() || !GetNextFrame()->IsValid()) {
+ m_frame_type = eNotAValidFrame;
+ UnwindLogMsg("Could not get next frame, marking this frame as invalid.");
+ return;
+ }
+ if (!m_thread.GetRegisterContext()) {
+ m_frame_type = eNotAValidFrame;
+ UnwindLogMsg("Could not get register context for this thread, marking this "
+ "frame as invalid.");
+ return;
+ }
+
+ addr_t pc;
+ if (!ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc)) {
+ UnwindLogMsg("could not get pc value");
+ m_frame_type = eNotAValidFrame;
+ return;
+ }
+
+ if (log) {
+ UnwindLogMsg("pc = 0x%" PRIx64, pc);
+ addr_t reg_val;
+ if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP, reg_val))
+ UnwindLogMsg("fp = 0x%" PRIx64, reg_val);
+ if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, reg_val))
+ UnwindLogMsg("sp = 0x%" PRIx64, reg_val);
+ }
+
+ // A pc of 0x0 means it's the end of the stack crawl unless we're above a trap
+ // handler function
+ bool above_trap_handler = false;
+ if (GetNextFrame().get() && GetNextFrame()->IsValid() &&
+ GetNextFrame()->IsTrapHandlerFrame())
+ above_trap_handler = true;
+
+ if (pc == 0 || pc == 0x1) {
+ if (above_trap_handler == false) {
+ m_frame_type = eNotAValidFrame;
+ UnwindLogMsg("this frame has a pc of 0x0");
+ return;
+ }
+ }
+
+ ExecutionContext exe_ctx(m_thread.shared_from_this());
+ Process *process = exe_ctx.GetProcessPtr();
+ // Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs
+ // this will strip bit zero in case we read a PC from memory or from the LR.
+ ABI *abi = process->GetABI().get();
+ if (abi)
+ pc = abi->FixCodeAddress(pc);
+
+ m_current_pc.SetLoadAddress(pc, &process->GetTarget());
+
+ // If we don't have a Module for some reason, we're not going to find
+ // symbol/function information - just
+ // stick in some reasonable defaults and hope we can unwind past this frame.
+ ModuleSP pc_module_sp(m_current_pc.GetModule());
+ if (!m_current_pc.IsValid() || !pc_module_sp) {
+ UnwindLogMsg("using architectural default unwind method");
+
+ // Test the pc value to see if we know it's in an unmapped/non-executable
+ // region of memory.
+ uint32_t permissions;
+ if (process->GetLoadAddressPermissions(pc, permissions) &&
+ (permissions & ePermissionsExecutable) == 0) {
+ // If this is the second frame off the stack, we may have unwound the
+ // first frame
+ // incorrectly. But using the architecture default unwind plan may get us
+ // back on
+ // track -- albeit possibly skipping a real frame. Give this frame a
+ // clearly-invalid
+ // pc and see if we can get any further.
+ if (GetNextFrame().get() && GetNextFrame()->IsValid() &&
+ GetNextFrame()->IsFrameZero()) {
+ UnwindLogMsg("had a pc of 0x%" PRIx64 " which is not in executable "
+ "memory but on frame 1 -- "
+ "allowing it once.",
+ (uint64_t)pc);
+ m_frame_type = eSkipFrame;
+ } else {
+ // anywhere other than the second frame, a non-executable pc means we're
+ // off in the weeds -- stop now.
m_frame_type = eNotAValidFrame;
+ UnwindLogMsg("pc is in a non-executable section of memory and this "
+ "isn't the 2nd frame in the stack walk.");
return;
+ }
}
- if (log)
- {
- UnwindLogMsg ("pc = 0x%" PRIx64, pc);
- addr_t reg_val;
- if (ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP, reg_val))
- UnwindLogMsg ("fp = 0x%" PRIx64, reg_val);
- if (ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, reg_val))
- UnwindLogMsg ("sp = 0x%" PRIx64, reg_val);
- }
-
- // A pc of 0x0 means it's the end of the stack crawl unless we're above a trap handler function
- bool above_trap_handler = false;
- if (GetNextFrame().get() && GetNextFrame()->IsValid() && GetNextFrame()->IsTrapHandlerFrame())
- above_trap_handler = true;
-
- if (pc == 0 || pc == 0x1)
- {
- if (above_trap_handler == false)
- {
+ if (abi) {
+ m_fast_unwind_plan_sp.reset();
+ m_full_unwind_plan_sp.reset(new UnwindPlan(lldb::eRegisterKindGeneric));
+ abi->CreateDefaultUnwindPlan(*m_full_unwind_plan_sp);
+ if (m_frame_type != eSkipFrame) // don't override eSkipFrame
+ {
+ m_frame_type = eNormalFrame;
+ }
+ m_all_registers_available = false;
+ m_current_offset = -1;
+ m_current_offset_backed_up_one = -1;
+ RegisterKind row_register_kind = m_full_unwind_plan_sp->GetRegisterKind();
+ UnwindPlan::RowSP row = m_full_unwind_plan_sp->GetRowForFunctionOffset(0);
+ if (row.get()) {
+ if (!ReadCFAValueForRow(row_register_kind, row, m_cfa)) {
+ UnwindLogMsg("failed to get cfa value");
+ if (m_frame_type != eSkipFrame) // don't override eSkipFrame
+ {
m_frame_type = eNotAValidFrame;
- UnwindLogMsg ("this frame has a pc of 0x0");
- return;
+ }
+ return;
}
- }
- ExecutionContext exe_ctx(m_thread.shared_from_this());
- Process *process = exe_ctx.GetProcessPtr();
- // Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs
- // this will strip bit zero in case we read a PC from memory or from the LR.
- ABI *abi = process->GetABI().get();
- if (abi)
- pc = abi->FixCodeAddress(pc);
-
- m_current_pc.SetLoadAddress (pc, &process->GetTarget());
-
- // If we don't have a Module for some reason, we're not going to find symbol/function information - just
- // stick in some reasonable defaults and hope we can unwind past this frame.
- ModuleSP pc_module_sp (m_current_pc.GetModule());
- if (!m_current_pc.IsValid() || !pc_module_sp)
- {
- UnwindLogMsg ("using architectural default unwind method");
-
- // Test the pc value to see if we know it's in an unmapped/non-executable region of memory.
- uint32_t permissions;
- if (process->GetLoadAddressPermissions(pc, permissions)
- && (permissions & ePermissionsExecutable) == 0)
- {
- // If this is the second frame off the stack, we may have unwound the first frame
- // incorrectly. But using the architecture default unwind plan may get us back on
- // track -- albeit possibly skipping a real frame. Give this frame a clearly-invalid
- // pc and see if we can get any further.
- if (GetNextFrame().get() && GetNextFrame()->IsValid() && GetNextFrame()->IsFrameZero())
- {
- UnwindLogMsg ("had a pc of 0x%" PRIx64 " which is not in executable memory but on frame 1 -- allowing it once.",
- (uint64_t) pc);
- m_frame_type = eSkipFrame;
- }
- else
- {
- // anywhere other than the second frame, a non-executable pc means we're off in the weeds -- stop now.
- m_frame_type = eNotAValidFrame;
- UnwindLogMsg ("pc is in a non-executable section of memory and this isn't the 2nd frame in the stack walk.");
- return;
- }
+ // A couple of sanity checks..
+ if (m_cfa == LLDB_INVALID_ADDRESS || m_cfa == 0 || m_cfa == 1) {
+ UnwindLogMsg("could not find a valid cfa address");
+ m_frame_type = eNotAValidFrame;
+ return;
}
- if (abi)
- {
- m_fast_unwind_plan_sp.reset ();
- m_full_unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
- abi->CreateDefaultUnwindPlan(*m_full_unwind_plan_sp);
- if (m_frame_type != eSkipFrame) // don't override eSkipFrame
- {
- m_frame_type = eNormalFrame;
- }
- m_all_registers_available = false;
- m_current_offset = -1;
- m_current_offset_backed_up_one = -1;
- RegisterKind row_register_kind = m_full_unwind_plan_sp->GetRegisterKind ();
- UnwindPlan::RowSP row = m_full_unwind_plan_sp->GetRowForFunctionOffset(0);
- if (row.get())
- {
- if (!ReadCFAValueForRow (row_register_kind, row, m_cfa))
- {
- UnwindLogMsg ("failed to get cfa value");
- if (m_frame_type != eSkipFrame) // don't override eSkipFrame
- {
- m_frame_type = eNotAValidFrame;
- }
- return;
- }
-
- // A couple of sanity checks..
- if (m_cfa == LLDB_INVALID_ADDRESS || m_cfa == 0 || m_cfa == 1)
- {
- UnwindLogMsg ("could not find a valid cfa address");
- m_frame_type = eNotAValidFrame;
- return;
- }
-
- // m_cfa should point into the stack memory; if we can query memory region permissions,
- // see if the memory is allocated & readable.
- if (process->GetLoadAddressPermissions(m_cfa, permissions)
- && (permissions & ePermissionsReadable) == 0)
- {
- m_frame_type = eNotAValidFrame;
- UnwindLogMsg ("the CFA points to a region of memory that is not readable");
- return;
- }
- }
- else
- {
- UnwindLogMsg ("could not find a row for function offset zero");
- m_frame_type = eNotAValidFrame;
- return;
- }
-
- if (CheckIfLoopingStack ())
- {
- TryFallbackUnwindPlan();
- if (CheckIfLoopingStack ())
- {
- UnwindLogMsg ("same CFA address as next frame, assuming the unwind is looping - stopping");
- m_frame_type = eNotAValidFrame;
- return;
- }
- }
-
- UnwindLogMsg ("initialized frame cfa is 0x%" PRIx64, (uint64_t) m_cfa);
- return;
+ // m_cfa should point into the stack memory; if we can query memory
+ // region permissions,
+ // see if the memory is allocated & readable.
+ if (process->GetLoadAddressPermissions(m_cfa, permissions) &&
+ (permissions & ePermissionsReadable) == 0) {
+ m_frame_type = eNotAValidFrame;
+ UnwindLogMsg(
+ "the CFA points to a region of memory that is not readable");
+ return;
}
+ } else {
+ UnwindLogMsg("could not find a row for function offset zero");
m_frame_type = eNotAValidFrame;
- UnwindLogMsg ("could not find any symbol for this pc, or a default unwind plan, to continue unwind.");
return;
- }
-
- bool resolve_tail_call_address = false; // m_current_pc can be one past the address range of the function...
- // If the saved pc does not point to a function/symbol because it is
- // beyond the bounds of the correct function and there's no symbol there,
- // we do *not* want ResolveSymbolContextForAddress to back up the pc by 1,
- // because then we might not find the correct unwind information later.
- // Instead, let ResolveSymbolContextForAddress fail, and handle the case
- // via decr_pc_and_recompute_addr_range below.
- const uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol;
- uint32_t resolved_scope = pc_module_sp->ResolveSymbolContextForAddress (m_current_pc,
- resolve_scope,
- m_sym_ctx, resolve_tail_call_address);
-
- // We require either a symbol or function in the symbols context to be successfully
- // filled in or this context is of no use to us.
- if (resolve_scope & resolved_scope)
- {
- m_sym_ctx_valid = true;
- }
-
- if (m_sym_ctx.symbol)
- {
- UnwindLogMsg ("with pc value of 0x%" PRIx64 ", symbol name is '%s'",
- pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
- }
- else if (m_sym_ctx.function)
- {
- UnwindLogMsg ("with pc value of 0x%" PRIx64 ", function name is '%s'",
- pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
- }
- else
- {
- UnwindLogMsg ("with pc value of 0x%" PRIx64 ", no symbol/function name is known.", pc);
- }
+ }
- AddressRange addr_range;
- if (!m_sym_ctx.GetAddressRange (resolve_scope, 0, false, addr_range))
- {
- m_sym_ctx_valid = false;
- }
-
- bool decr_pc_and_recompute_addr_range = false;
-
- // If the symbol lookup failed...
- if (m_sym_ctx_valid == false)
- decr_pc_and_recompute_addr_range = true;
-
- // Or if we're in the middle of the stack (and not "above" an asynchronous event like sigtramp),
- // and our "current" pc is the start of a function...
- if (m_sym_ctx_valid
- && GetNextFrame()->m_frame_type != eTrapHandlerFrame
- && GetNextFrame()->m_frame_type != eDebuggerFrame
- && addr_range.GetBaseAddress().IsValid()
- && addr_range.GetBaseAddress().GetSection() == m_current_pc.GetSection()
- && addr_range.GetBaseAddress().GetOffset() == m_current_pc.GetOffset())
- {
- decr_pc_and_recompute_addr_range = true;
- }
-
- // We need to back up the pc by 1 byte and re-search for the Symbol to handle the case where the "saved pc"
- // value is pointing to the next function, e.g. if a function ends with a CALL instruction.
- // FIXME this may need to be an architectural-dependent behavior; if so we'll need to add a member function
- // to the ABI plugin and consult that.
- if (decr_pc_and_recompute_addr_range)
- {
- UnwindLogMsg ("Backing up the pc value of 0x%" PRIx64 " by 1 and re-doing symbol lookup; old symbol was %s",
- pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
- Address temporary_pc;
- temporary_pc.SetLoadAddress (pc - 1, &process->GetTarget());
- m_sym_ctx.Clear (false);
- m_sym_ctx_valid = false;
- uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol;
-
- ModuleSP temporary_module_sp = temporary_pc.GetModule();
- if (temporary_module_sp &&
- temporary_module_sp->ResolveSymbolContextForAddress (temporary_pc, resolve_scope, m_sym_ctx) & resolve_scope)
- {
- if (m_sym_ctx.GetAddressRange (resolve_scope, 0, false, addr_range))
- m_sym_ctx_valid = true;
- }
- UnwindLogMsg ("Symbol is now %s", GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
- }
-
- // If we were able to find a symbol/function, set addr_range_ptr to the bounds of that symbol/function.
- // else treat the current pc value as the start_pc and record no offset.
- if (addr_range.GetBaseAddress().IsValid())
- {
- m_start_pc = addr_range.GetBaseAddress();
- m_current_offset = pc - m_start_pc.GetLoadAddress (&process->GetTarget());
- m_current_offset_backed_up_one = m_current_offset;
- if (decr_pc_and_recompute_addr_range && m_current_offset_backed_up_one > 0)
- {
- m_current_offset_backed_up_one--;
- if (m_sym_ctx_valid)
- {
- m_current_pc.SetLoadAddress (pc - 1, &process->GetTarget());
- }
- }
- }
- else
- {
- m_start_pc = m_current_pc;
- m_current_offset = -1;
- m_current_offset_backed_up_one = -1;
- }
-
- if (IsTrapHandlerSymbol (process, m_sym_ctx))
- {
- m_frame_type = eTrapHandlerFrame;
- }
- else
- {
- // FIXME: Detect eDebuggerFrame here.
- if (m_frame_type != eSkipFrame) // don't override eSkipFrame
- {
- m_frame_type = eNormalFrame;
+ if (CheckIfLoopingStack()) {
+ TryFallbackUnwindPlan();
+ if (CheckIfLoopingStack()) {
+ UnwindLogMsg("same CFA address as next frame, assuming the unwind is "
+ "looping - stopping");
+ m_frame_type = eNotAValidFrame;
+ return;
}
- }
-
- // We've set m_frame_type and m_sym_ctx before this call.
- m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame ();
+ }
- UnwindPlan::RowSP active_row;
- RegisterKind row_register_kind = eRegisterKindGeneric;
-
- // Try to get by with just the fast UnwindPlan if possible - the full UnwindPlan may be expensive to get
- // (e.g. if we have to parse the entire eh_frame section of an ObjectFile for the first time.)
-
- if (m_fast_unwind_plan_sp && m_fast_unwind_plan_sp->PlanValidAtAddress (m_current_pc))
- {
- active_row = m_fast_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
- row_register_kind = m_fast_unwind_plan_sp->GetRegisterKind ();
- if (active_row.get() && log)
- {
- StreamString active_row_strm;
- active_row->Dump(active_row_strm, m_fast_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
- UnwindLogMsg ("active row: %s", active_row_strm.GetString().c_str());
- }
- }
- else
- {
- m_full_unwind_plan_sp = GetFullUnwindPlanForFrame ();
- int valid_offset = -1;
- if (IsUnwindPlanValidForCurrentPC(m_full_unwind_plan_sp, valid_offset))
- {
- active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (valid_offset);
- row_register_kind = m_full_unwind_plan_sp->GetRegisterKind ();
- if (active_row.get() && log)
- {
- StreamString active_row_strm;
- active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
- UnwindLogMsg ("active row: %s", active_row_strm.GetString().c_str());
- }
- }
+ UnwindLogMsg("initialized frame cfa is 0x%" PRIx64, (uint64_t)m_cfa);
+ return;
}
-
- if (!active_row.get())
- {
- m_frame_type = eNotAValidFrame;
- UnwindLogMsg ("could not find unwind row for this pc");
- return;
+ m_frame_type = eNotAValidFrame;
+ UnwindLogMsg("could not find any symbol for this pc, or a default unwind "
+ "plan, to continue unwind.");
+ return;
+ }
+
+ bool resolve_tail_call_address = false; // m_current_pc can be one past the
+ // address range of the function...
+ // If the saved pc does not point to a function/symbol because it is
+ // beyond the bounds of the correct function and there's no symbol there,
+ // we do *not* want ResolveSymbolContextForAddress to back up the pc by 1,
+ // because then we might not find the correct unwind information later.
+ // Instead, let ResolveSymbolContextForAddress fail, and handle the case
+ // via decr_pc_and_recompute_addr_range below.
+ const uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol;
+ uint32_t resolved_scope = pc_module_sp->ResolveSymbolContextForAddress(
+ m_current_pc, resolve_scope, m_sym_ctx, resolve_tail_call_address);
+
+ // We require either a symbol or function in the symbols context to be
+ // successfully
+ // filled in or this context is of no use to us.
+ if (resolve_scope & resolved_scope) {
+ m_sym_ctx_valid = true;
+ }
+
+ if (m_sym_ctx.symbol) {
+ UnwindLogMsg("with pc value of 0x%" PRIx64 ", symbol name is '%s'", pc,
+ GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
+ } else if (m_sym_ctx.function) {
+ UnwindLogMsg("with pc value of 0x%" PRIx64 ", function name is '%s'", pc,
+ GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
+ } else {
+ UnwindLogMsg("with pc value of 0x%" PRIx64
+ ", no symbol/function name is known.",
+ pc);
+ }
+
+ AddressRange addr_range;
+ if (!m_sym_ctx.GetAddressRange(resolve_scope, 0, false, addr_range)) {
+ m_sym_ctx_valid = false;
+ }
+
+ bool decr_pc_and_recompute_addr_range = false;
+
+ // If the symbol lookup failed...
+ if (m_sym_ctx_valid == false)
+ decr_pc_and_recompute_addr_range = true;
+
+ // Or if we're in the middle of the stack (and not "above" an asynchronous
+ // event like sigtramp),
+ // and our "current" pc is the start of a function...
+ if (m_sym_ctx_valid && GetNextFrame()->m_frame_type != eTrapHandlerFrame &&
+ GetNextFrame()->m_frame_type != eDebuggerFrame &&
+ addr_range.GetBaseAddress().IsValid() &&
+ addr_range.GetBaseAddress().GetSection() == m_current_pc.GetSection() &&
+ addr_range.GetBaseAddress().GetOffset() == m_current_pc.GetOffset()) {
+ decr_pc_and_recompute_addr_range = true;
+ }
+
+ // We need to back up the pc by 1 byte and re-search for the Symbol to handle
+ // the case where the "saved pc"
+ // value is pointing to the next function, e.g. if a function ends with a CALL
+ // instruction.
+ // FIXME this may need to be an architectural-dependent behavior; if so we'll
+ // need to add a member function
+ // to the ABI plugin and consult that.
+ if (decr_pc_and_recompute_addr_range) {
+ UnwindLogMsg("Backing up the pc value of 0x%" PRIx64
+ " by 1 and re-doing symbol lookup; old symbol was %s",
+ pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
+ Address temporary_pc;
+ temporary_pc.SetLoadAddress(pc - 1, &process->GetTarget());
+ m_sym_ctx.Clear(false);
+ m_sym_ctx_valid = false;
+ uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol;
+
+ ModuleSP temporary_module_sp = temporary_pc.GetModule();
+ if (temporary_module_sp &&
+ temporary_module_sp->ResolveSymbolContextForAddress(
+ temporary_pc, resolve_scope, m_sym_ctx) &
+ resolve_scope) {
+ if (m_sym_ctx.GetAddressRange(resolve_scope, 0, false, addr_range))
+ m_sym_ctx_valid = true;
}
+ UnwindLogMsg("Symbol is now %s",
+ GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
+ }
+
+ // If we were able to find a symbol/function, set addr_range_ptr to the bounds
+ // of that symbol/function.
+ // else treat the current pc value as the start_pc and record no offset.
+ if (addr_range.GetBaseAddress().IsValid()) {
+ m_start_pc = addr_range.GetBaseAddress();
+ m_current_offset = pc - m_start_pc.GetLoadAddress(&process->GetTarget());
+ m_current_offset_backed_up_one = m_current_offset;
+ if (decr_pc_and_recompute_addr_range &&
+ m_current_offset_backed_up_one > 0) {
+ m_current_offset_backed_up_one--;
+ if (m_sym_ctx_valid) {
+ m_current_pc.SetLoadAddress(pc - 1, &process->GetTarget());
+ }
+ }
+ } else {
+ m_start_pc = m_current_pc;
+ m_current_offset = -1;
+ m_current_offset_backed_up_one = -1;
+ }
+
+ if (IsTrapHandlerSymbol(process, m_sym_ctx)) {
+ m_frame_type = eTrapHandlerFrame;
+ } else {
+ // FIXME: Detect eDebuggerFrame here.
+ if (m_frame_type != eSkipFrame) // don't override eSkipFrame
+ {
+ m_frame_type = eNormalFrame;
+ }
+ }
+
+ // We've set m_frame_type and m_sym_ctx before this call.
+ m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame();
+
+ UnwindPlan::RowSP active_row;
+ RegisterKind row_register_kind = eRegisterKindGeneric;
+
+ // Try to get by with just the fast UnwindPlan if possible - the full
+ // UnwindPlan may be expensive to get
+ // (e.g. if we have to parse the entire eh_frame section of an ObjectFile for
+ // the first time.)
+
+ if (m_fast_unwind_plan_sp &&
+ m_fast_unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
+ active_row =
+ m_fast_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
+ row_register_kind = m_fast_unwind_plan_sp->GetRegisterKind();
+ if (active_row.get() && log) {
+ StreamString active_row_strm;
+ active_row->Dump(active_row_strm, m_fast_unwind_plan_sp.get(), &m_thread,
+ m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
+ UnwindLogMsg("active row: %s", active_row_strm.GetData());
+ }
+ } else {
+ m_full_unwind_plan_sp = GetFullUnwindPlanForFrame();
+ int valid_offset = -1;
+ if (IsUnwindPlanValidForCurrentPC(m_full_unwind_plan_sp, valid_offset)) {
+ active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset(valid_offset);
+ row_register_kind = m_full_unwind_plan_sp->GetRegisterKind();
+ if (active_row.get() && log) {
+ StreamString active_row_strm;
+ active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(),
+ &m_thread,
+ m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
+ UnwindLogMsg("active row: %s", active_row_strm.GetData());
+ }
+ }
+ }
+
+ if (!active_row.get()) {
+ m_frame_type = eNotAValidFrame;
+ UnwindLogMsg("could not find unwind row for this pc");
+ return;
+ }
- if (!ReadCFAValueForRow (row_register_kind, active_row, m_cfa))
- {
- UnwindLogMsg ("failed to get cfa");
- m_frame_type = eNotAValidFrame;
- return;
- }
+ if (!ReadCFAValueForRow(row_register_kind, active_row, m_cfa)) {
+ UnwindLogMsg("failed to get cfa");
+ m_frame_type = eNotAValidFrame;
+ return;
+ }
- UnwindLogMsg ("m_cfa = 0x%" PRIx64, m_cfa);
+ UnwindLogMsg("m_cfa = 0x%" PRIx64, m_cfa);
- if (CheckIfLoopingStack ())
- {
- TryFallbackUnwindPlan();
- if (CheckIfLoopingStack ())
- {
- UnwindLogMsg ("same CFA address as next frame, assuming the unwind is looping - stopping");
- m_frame_type = eNotAValidFrame;
- return;
- }
+ if (CheckIfLoopingStack()) {
+ TryFallbackUnwindPlan();
+ if (CheckIfLoopingStack()) {
+ UnwindLogMsg("same CFA address as next frame, assuming the unwind is "
+ "looping - stopping");
+ m_frame_type = eNotAValidFrame;
+ return;
}
+ }
- UnwindLogMsg ("initialized frame current pc is 0x%" PRIx64 " cfa is 0x%" PRIx64,
- (uint64_t) m_current_pc.GetLoadAddress (exe_ctx.GetTargetPtr()), (uint64_t) m_cfa);
+ UnwindLogMsg("initialized frame current pc is 0x%" PRIx64
+ " cfa is 0x%" PRIx64,
+ (uint64_t)m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr()),
+ (uint64_t)m_cfa);
}
-bool
-RegisterContextLLDB::CheckIfLoopingStack ()
-{
- // If we have a bad stack setup, we can get the same CFA value multiple times -- or even
- // more devious, we can actually oscillate between two CFA values. Detect that here and
- // break out to avoid a possible infinite loop in lldb trying to unwind the stack.
- // To detect when we have the same CFA value multiple times, we compare the CFA of the current
- // frame with the 2nd next frame because in some specail case (e.g. signal hanlders, hand
- // written assembly without ABI compiance) we can have 2 frames with the same CFA (in theory we
- // can have arbitrary number of frames with the same CFA, but more then 2 is very very unlikely)
-
- RegisterContextLLDB::SharedPtr next_frame = GetNextFrame();
- if (next_frame)
- {
- RegisterContextLLDB::SharedPtr next_next_frame = next_frame->GetNextFrame();
- addr_t next_next_frame_cfa = LLDB_INVALID_ADDRESS;
- if (next_next_frame && next_next_frame->GetCFA(next_next_frame_cfa))
- {
- if (next_next_frame_cfa == m_cfa)
- {
- // We have a loop in the stack unwind
- return true;
- }
- }
+bool RegisterContextLLDB::CheckIfLoopingStack() {
+ // If we have a bad stack setup, we can get the same CFA value multiple times
+ // -- or even
+ // more devious, we can actually oscillate between two CFA values. Detect that
+ // here and
+ // break out to avoid a possible infinite loop in lldb trying to unwind the
+ // stack.
+ // To detect when we have the same CFA value multiple times, we compare the
+ // CFA of the current
+ // frame with the 2nd next frame because in some specail case (e.g. signal
+ // hanlders, hand
+ // written assembly without ABI compiance) we can have 2 frames with the same
+ // CFA (in theory we
+ // can have arbitrary number of frames with the same CFA, but more then 2 is
+ // very very unlikely)
+
+ RegisterContextLLDB::SharedPtr next_frame = GetNextFrame();
+ if (next_frame) {
+ RegisterContextLLDB::SharedPtr next_next_frame = next_frame->GetNextFrame();
+ addr_t next_next_frame_cfa = LLDB_INVALID_ADDRESS;
+ if (next_next_frame && next_next_frame->GetCFA(next_next_frame_cfa)) {
+ if (next_next_frame_cfa == m_cfa) {
+ // We have a loop in the stack unwind
+ return true;
+ }
}
- return false;
-}
-
-bool
-RegisterContextLLDB::IsFrameZero () const
-{
- return m_frame_number == 0;
+ }
+ return false;
}
+bool RegisterContextLLDB::IsFrameZero() const { return m_frame_number == 0; }
// Find a fast unwind plan for this frame, if possible.
//
// On entry to this method,
//
-// 1. m_frame_type should already be set to eTrapHandlerFrame/eDebuggerFrame if either of those are correct,
+// 1. m_frame_type should already be set to eTrapHandlerFrame/eDebuggerFrame
+// if either of those are correct,
// 2. m_sym_ctx should already be filled in, and
// 3. m_current_pc should have the current pc value for this frame
-// 4. m_current_offset_backed_up_one should have the current byte offset into the function, maybe backed up by 1, -1 if unknown
+// 4. m_current_offset_backed_up_one should have the current byte offset into
+// the function, maybe backed up by 1, -1 if unknown
-UnwindPlanSP
-RegisterContextLLDB::GetFastUnwindPlanForFrame ()
-{
- UnwindPlanSP unwind_plan_sp;
- ModuleSP pc_module_sp (m_current_pc.GetModule());
+UnwindPlanSP RegisterContextLLDB::GetFastUnwindPlanForFrame() {
+ UnwindPlanSP unwind_plan_sp;
+ ModuleSP pc_module_sp(m_current_pc.GetModule());
- if (!m_current_pc.IsValid() || !pc_module_sp || pc_module_sp->GetObjectFile() == NULL)
- return unwind_plan_sp;
+ if (!m_current_pc.IsValid() || !pc_module_sp ||
+ pc_module_sp->GetObjectFile() == NULL)
+ return unwind_plan_sp;
- if (IsFrameZero ())
- return unwind_plan_sp;
+ if (IsFrameZero())
+ return unwind_plan_sp;
- FuncUnwindersSP func_unwinders_sp (pc_module_sp->GetObjectFile()->GetUnwindTable().GetFuncUnwindersContainingAddress (m_current_pc, m_sym_ctx));
- if (!func_unwinders_sp)
- return unwind_plan_sp;
+ FuncUnwindersSP func_unwinders_sp(
+ pc_module_sp->GetObjectFile()
+ ->GetUnwindTable()
+ .GetFuncUnwindersContainingAddress(m_current_pc, m_sym_ctx));
+ if (!func_unwinders_sp)
+ return unwind_plan_sp;
- // If we're in _sigtramp(), unwinding past this frame requires special knowledge.
- if (m_frame_type == eTrapHandlerFrame || m_frame_type == eDebuggerFrame)
- return unwind_plan_sp;
+ // If we're in _sigtramp(), unwinding past this frame requires special
+ // knowledge.
+ if (m_frame_type == eTrapHandlerFrame || m_frame_type == eDebuggerFrame)
+ return unwind_plan_sp;
- unwind_plan_sp = func_unwinders_sp->GetUnwindPlanFastUnwind (*m_thread.CalculateTarget(), m_thread);
- if (unwind_plan_sp)
- {
- if (unwind_plan_sp->PlanValidAtAddress (m_current_pc))
- {
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
- if (log && log->GetVerbose())
- {
- if (m_fast_unwind_plan_sp)
- UnwindLogMsgVerbose ("frame, and has a fast UnwindPlan");
- else
- UnwindLogMsgVerbose ("frame");
- }
- m_frame_type = eNormalFrame;
- return unwind_plan_sp;
- }
+ unwind_plan_sp = func_unwinders_sp->GetUnwindPlanFastUnwind(
+ *m_thread.CalculateTarget(), m_thread);
+ if (unwind_plan_sp) {
+ if (unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
+ if (log && log->GetVerbose()) {
+ if (m_fast_unwind_plan_sp)
+ UnwindLogMsgVerbose("frame, and has a fast UnwindPlan");
else
- {
- unwind_plan_sp.reset();
- }
- }
- return unwind_plan_sp;
+ UnwindLogMsgVerbose("frame");
+ }
+ m_frame_type = eNormalFrame;
+ return unwind_plan_sp;
+ } else {
+ unwind_plan_sp.reset();
+ }
+ }
+ return unwind_plan_sp;
}
// On entry to this method,
//
-// 1. m_frame_type should already be set to eTrapHandlerFrame/eDebuggerFrame if either of those are correct,
+// 1. m_frame_type should already be set to eTrapHandlerFrame/eDebuggerFrame
+// if either of those are correct,
// 2. m_sym_ctx should already be filled in, and
// 3. m_current_pc should have the current pc value for this frame
-// 4. m_current_offset_backed_up_one should have the current byte offset into the function, maybe backed up by 1, -1 if unknown
-
-UnwindPlanSP
-RegisterContextLLDB::GetFullUnwindPlanForFrame ()
-{
- UnwindPlanSP unwind_plan_sp;
- UnwindPlanSP arch_default_unwind_plan_sp;
- ExecutionContext exe_ctx(m_thread.shared_from_this());
- Process *process = exe_ctx.GetProcessPtr();
- ABI *abi = process ? process->GetABI().get() : NULL;
- if (abi)
- {
- arch_default_unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
- abi->CreateDefaultUnwindPlan(*arch_default_unwind_plan_sp);
- }
- else
- {
- UnwindLogMsg ("unable to get architectural default UnwindPlan from ABI plugin");
- }
-
- bool behaves_like_zeroth_frame = false;
- if (IsFrameZero ()
- || GetNextFrame()->m_frame_type == eTrapHandlerFrame
- || GetNextFrame()->m_frame_type == eDebuggerFrame)
- {
- behaves_like_zeroth_frame = true;
- // If this frame behaves like a 0th frame (currently executing or
- // interrupted asynchronously), all registers can be retrieved.
- m_all_registers_available = true;
- }
-
- // If we've done a jmp 0x0 / bl 0x0 (called through a null function pointer) so the pc is 0x0
- // in the zeroth frame, we need to use the "unwind at first instruction" arch default UnwindPlan
- // Also, if this Process can report on memory region attributes, any non-executable region means
- // we jumped through a bad function pointer - handle the same way as 0x0.
- // Note, if we have a symbol context & a symbol, we don't want to follow this code path. This is
- // for jumping to memory regions without any information available.
-
- if ((!m_sym_ctx_valid || (m_sym_ctx.function == NULL && m_sym_ctx.symbol == NULL)) && behaves_like_zeroth_frame && m_current_pc.IsValid())
- {
- uint32_t permissions;
- addr_t current_pc_addr = m_current_pc.GetLoadAddress (exe_ctx.GetTargetPtr());
- if (current_pc_addr == 0
- || (process &&
- process->GetLoadAddressPermissions (current_pc_addr, permissions)
- && (permissions & ePermissionsExecutable) == 0))
- {
- if (abi)
- {
- unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
- abi->CreateFunctionEntryUnwindPlan(*unwind_plan_sp);
- m_frame_type = eNormalFrame;
- return unwind_plan_sp;
- }
- }
- }
-
- // No Module for the current pc, try using the architecture default unwind.
- ModuleSP pc_module_sp (m_current_pc.GetModule());
- if (!m_current_pc.IsValid() || !pc_module_sp || pc_module_sp->GetObjectFile() == NULL)
- {
+// 4. m_current_offset_backed_up_one should have the current byte offset into
+// the function, maybe backed up by 1, -1 if unknown
+
+UnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame() {
+ UnwindPlanSP unwind_plan_sp;
+ UnwindPlanSP arch_default_unwind_plan_sp;
+ ExecutionContext exe_ctx(m_thread.shared_from_this());
+ Process *process = exe_ctx.GetProcessPtr();
+ ABI *abi = process ? process->GetABI().get() : NULL;
+ if (abi) {
+ arch_default_unwind_plan_sp.reset(
+ new UnwindPlan(lldb::eRegisterKindGeneric));
+ abi->CreateDefaultUnwindPlan(*arch_default_unwind_plan_sp);
+ } else {
+ UnwindLogMsg(
+ "unable to get architectural default UnwindPlan from ABI plugin");
+ }
+
+ bool behaves_like_zeroth_frame = false;
+ if (IsFrameZero() || GetNextFrame()->m_frame_type == eTrapHandlerFrame ||
+ GetNextFrame()->m_frame_type == eDebuggerFrame) {
+ behaves_like_zeroth_frame = true;
+ // If this frame behaves like a 0th frame (currently executing or
+ // interrupted asynchronously), all registers can be retrieved.
+ m_all_registers_available = true;
+ }
+
+ // If we've done a jmp 0x0 / bl 0x0 (called through a null function pointer)
+ // so the pc is 0x0
+ // in the zeroth frame, we need to use the "unwind at first instruction" arch
+ // default UnwindPlan
+ // Also, if this Process can report on memory region attributes, any
+ // non-executable region means
+ // we jumped through a bad function pointer - handle the same way as 0x0.
+ // Note, if we have a symbol context & a symbol, we don't want to follow this
+ // code path. This is
+ // for jumping to memory regions without any information available.
+
+ if ((!m_sym_ctx_valid ||
+ (m_sym_ctx.function == NULL && m_sym_ctx.symbol == NULL)) &&
+ behaves_like_zeroth_frame && m_current_pc.IsValid()) {
+ uint32_t permissions;
+ addr_t current_pc_addr =
+ m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr());
+ if (current_pc_addr == 0 ||
+ (process &&
+ process->GetLoadAddressPermissions(current_pc_addr, permissions) &&
+ (permissions & ePermissionsExecutable) == 0)) {
+ if (abi) {
+ unwind_plan_sp.reset(new UnwindPlan(lldb::eRegisterKindGeneric));
+ abi->CreateFunctionEntryUnwindPlan(*unwind_plan_sp);
m_frame_type = eNormalFrame;
- return arch_default_unwind_plan_sp;
- }
-
- FuncUnwindersSP func_unwinders_sp;
- if (m_sym_ctx_valid)
- {
- func_unwinders_sp = pc_module_sp->GetObjectFile()->GetUnwindTable().GetFuncUnwindersContainingAddress (m_current_pc, m_sym_ctx);
- }
-
- // No FuncUnwinders available for this pc (stripped function symbols, lldb could not augment its
- // function table with another source, like LC_FUNCTION_STARTS or eh_frame in ObjectFileMachO).
- // See if eh_frame or the .ARM.exidx tables have unwind information for this address, else fall
- // back to the architectural default unwind.
- if (!func_unwinders_sp)
- {
- m_frame_type = eNormalFrame;
-
- if (!pc_module_sp || !pc_module_sp->GetObjectFile() || !m_current_pc.IsValid())
- return arch_default_unwind_plan_sp;
-
- // Even with -fomit-frame-pointer, we can try eh_frame to get back on track.
- DWARFCallFrameInfo *eh_frame = pc_module_sp->GetObjectFile()->GetUnwindTable().GetEHFrameInfo();
- if (eh_frame)
- {
- unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
- if (eh_frame->GetUnwindPlan (m_current_pc, *unwind_plan_sp))
- return unwind_plan_sp;
- else
- unwind_plan_sp.reset();
- }
-
- ArmUnwindInfo *arm_exidx = pc_module_sp->GetObjectFile()->GetUnwindTable().GetArmUnwindInfo();
- if (arm_exidx)
- {
- unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
- if (arm_exidx->GetUnwindPlan (exe_ctx.GetTargetRef(), m_current_pc, *unwind_plan_sp))
- return unwind_plan_sp;
- else
- unwind_plan_sp.reset();
- }
-
- return arch_default_unwind_plan_sp;
- }
-
- // If we're in _sigtramp(), unwinding past this frame requires special knowledge. On Mac OS X this knowledge
- // is properly encoded in the eh_frame section, so prefer that if available.
- // On other platforms we may need to provide a platform-specific UnwindPlan which encodes the details of
- // how to unwind out of sigtramp.
- if (m_frame_type == eTrapHandlerFrame && process)
- {
- m_fast_unwind_plan_sp.reset();
- unwind_plan_sp = func_unwinders_sp->GetEHFrameUnwindPlan (process->GetTarget(), m_current_offset_backed_up_one);
- if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc) && unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes)
- {
- return unwind_plan_sp;
- }
- }
-
- // Ask the DynamicLoader if the eh_frame CFI should be trusted in this frame even when it's frame zero
- // This comes up if we have hand-written functions in a Module and hand-written eh_frame. The assembly
- // instruction inspection may fail and the eh_frame CFI were probably written with some care to do the
- // right thing. It'd be nice if there was a way to ask the eh_frame directly if it is asynchronous
- // (can be trusted at every instruction point) or synchronous (the normal case - only at call sites).
- // But there is not.
- if (process && process->GetDynamicLoader() && process->GetDynamicLoader()->AlwaysRelyOnEHUnwindInfo (m_sym_ctx))
- {
- // We must specifically call the GetEHFrameUnwindPlan() method here -- normally we would
- // call GetUnwindPlanAtCallSite() -- because CallSite may return an unwind plan sourced from
- // either eh_frame (that's what we intend) or compact unwind (this won't work)
- unwind_plan_sp = func_unwinders_sp->GetEHFrameUnwindPlan (process->GetTarget(), m_current_offset_backed_up_one);
- if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc))
- {
- UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan because the DynamicLoader suggested we prefer it",
- unwind_plan_sp->GetSourceName().GetCString());
- return unwind_plan_sp;
- }
+ return unwind_plan_sp;
+ }
}
+ }
- // Typically the NonCallSite UnwindPlan is the unwind created by inspecting the assembly language instructions
- if (behaves_like_zeroth_frame && process)
- {
- unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite (process->GetTarget(), m_thread, m_current_offset_backed_up_one);
- if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc))
- {
- if (unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolNo)
- {
- // We probably have an UnwindPlan created by inspecting assembly instructions. The
- // assembly profilers work really well with compiler-generated functions but hand-
- // written assembly can be problematic. We set the eh_frame based unwind plan as our
- // fallback unwind plan if instruction emulation doesn't work out even for non call
- // sites if it is available and use the architecture default unwind plan if it is
- // not available. The eh_frame unwind plan is more reliable even on non call sites
- // then the architecture default plan and for hand written assembly code it is often
- // written in a way that it valid at all location what helps in the most common
- // cases when the instruction emulation fails.
- UnwindPlanSP call_site_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget(), m_current_offset_backed_up_one);
- if (call_site_unwind_plan &&
- call_site_unwind_plan.get() != unwind_plan_sp.get() &&
- call_site_unwind_plan->GetSourceName() != unwind_plan_sp->GetSourceName())
- {
- m_fallback_unwind_plan_sp = call_site_unwind_plan;
- }
- else
- {
- m_fallback_unwind_plan_sp = arch_default_unwind_plan_sp;
- }
- }
- UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan", unwind_plan_sp->GetSourceName().GetCString());
- return unwind_plan_sp;
- }
+ // No Module for the current pc, try using the architecture default unwind.
+ ModuleSP pc_module_sp(m_current_pc.GetModule());
+ if (!m_current_pc.IsValid() || !pc_module_sp ||
+ pc_module_sp->GetObjectFile() == NULL) {
+ m_frame_type = eNormalFrame;
+ return arch_default_unwind_plan_sp;
+ }
+
+ FuncUnwindersSP func_unwinders_sp;
+ if (m_sym_ctx_valid) {
+ func_unwinders_sp =
+ pc_module_sp->GetObjectFile()
+ ->GetUnwindTable()
+ .GetFuncUnwindersContainingAddress(m_current_pc, m_sym_ctx);
+ }
+
+ // No FuncUnwinders available for this pc (stripped function symbols, lldb
+ // could not augment its
+ // function table with another source, like LC_FUNCTION_STARTS or eh_frame in
+ // ObjectFileMachO).
+ // See if eh_frame or the .ARM.exidx tables have unwind information for this
+ // address, else fall
+ // back to the architectural default unwind.
+ if (!func_unwinders_sp) {
+ m_frame_type = eNormalFrame;
+
+ if (!pc_module_sp || !pc_module_sp->GetObjectFile() ||
+ !m_current_pc.IsValid())
+ return arch_default_unwind_plan_sp;
+
+ // Even with -fomit-frame-pointer, we can try eh_frame to get back on track.
+ DWARFCallFrameInfo *eh_frame =
+ pc_module_sp->GetObjectFile()->GetUnwindTable().GetEHFrameInfo();
+ if (eh_frame) {
+ unwind_plan_sp.reset(new UnwindPlan(lldb::eRegisterKindGeneric));
+ if (eh_frame->GetUnwindPlan(m_current_pc, *unwind_plan_sp))
+ return unwind_plan_sp;
+ else
+ unwind_plan_sp.reset();
}
- // Typically this is unwind info from an eh_frame section intended for exception handling; only valid at call sites
- if (process)
- {
- unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite (process->GetTarget(), m_current_offset_backed_up_one);
- }
- int valid_offset = -1;
- if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp, valid_offset))
- {
- UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan", unwind_plan_sp->GetSourceName().GetCString());
+ ArmUnwindInfo *arm_exidx =
+ pc_module_sp->GetObjectFile()->GetUnwindTable().GetArmUnwindInfo();
+ if (arm_exidx) {
+ unwind_plan_sp.reset(new UnwindPlan(lldb::eRegisterKindGeneric));
+ if (arm_exidx->GetUnwindPlan(exe_ctx.GetTargetRef(), m_current_pc,
+ *unwind_plan_sp))
return unwind_plan_sp;
+ else
+ unwind_plan_sp.reset();
}
- // We'd prefer to use an UnwindPlan intended for call sites when we're at a call site but if we've
- // struck out on that, fall back to using the non-call-site assembly inspection UnwindPlan if possible.
- if (process)
- {
- unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite (process->GetTarget(), m_thread, m_current_offset_backed_up_one);
- }
- if (unwind_plan_sp && unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolNo)
- {
- // We probably have an UnwindPlan created by inspecting assembly instructions. The assembly
- // profilers work really well with compiler-generated functions but hand- written assembly
- // can be problematic. We set the eh_frame based unwind plan as our fallback unwind plan if
- // instruction emulation doesn't work out even for non call sites if it is available and use
- // the architecture default unwind plan if it is not available. The eh_frame unwind plan is
- // more reliable even on non call sites then the architecture default plan and for hand
- // written assembly code it is often written in a way that it valid at all location what
- // helps in the most common cases when the instruction emulation fails.
- UnwindPlanSP call_site_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget(), m_current_offset_backed_up_one);
+ return arch_default_unwind_plan_sp;
+ }
+
+ // If we're in _sigtramp(), unwinding past this frame requires special
+ // knowledge. On Mac OS X this knowledge
+ // is properly encoded in the eh_frame section, so prefer that if available.
+ // On other platforms we may need to provide a platform-specific UnwindPlan
+ // which encodes the details of
+ // how to unwind out of sigtramp.
+ if (m_frame_type == eTrapHandlerFrame && process) {
+ m_fast_unwind_plan_sp.reset();
+ unwind_plan_sp = func_unwinders_sp->GetEHFrameUnwindPlan(
+ process->GetTarget(), m_current_offset_backed_up_one);
+ if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc) &&
+ unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes) {
+ return unwind_plan_sp;
+ }
+ }
+
+ // Ask the DynamicLoader if the eh_frame CFI should be trusted in this frame
+ // even when it's frame zero
+ // This comes up if we have hand-written functions in a Module and
+ // hand-written eh_frame. The assembly
+ // instruction inspection may fail and the eh_frame CFI were probably written
+ // with some care to do the
+ // right thing. It'd be nice if there was a way to ask the eh_frame directly
+ // if it is asynchronous
+ // (can be trusted at every instruction point) or synchronous (the normal case
+ // - only at call sites).
+ // But there is not.
+ if (process && process->GetDynamicLoader() &&
+ process->GetDynamicLoader()->AlwaysRelyOnEHUnwindInfo(m_sym_ctx)) {
+ // We must specifically call the GetEHFrameUnwindPlan() method here --
+ // normally we would
+ // call GetUnwindPlanAtCallSite() -- because CallSite may return an unwind
+ // plan sourced from
+ // either eh_frame (that's what we intend) or compact unwind (this won't
+ // work)
+ unwind_plan_sp = func_unwinders_sp->GetEHFrameUnwindPlan(
+ process->GetTarget(), m_current_offset_backed_up_one);
+ if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
+ UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because the "
+ "DynamicLoader suggested we prefer it",
+ unwind_plan_sp->GetSourceName().GetCString());
+ return unwind_plan_sp;
+ }
+ }
+
+ // Typically the NonCallSite UnwindPlan is the unwind created by inspecting
+ // the assembly language instructions
+ if (behaves_like_zeroth_frame && process) {
+ unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite(
+ process->GetTarget(), m_thread, m_current_offset_backed_up_one);
+ if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
+ if (unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolNo) {
+ // We probably have an UnwindPlan created by inspecting assembly
+ // instructions. The
+ // assembly profilers work really well with compiler-generated functions
+ // but hand-
+ // written assembly can be problematic. We set the eh_frame based unwind
+ // plan as our
+ // fallback unwind plan if instruction emulation doesn't work out even
+ // for non call
+ // sites if it is available and use the architecture default unwind plan
+ // if it is
+ // not available. The eh_frame unwind plan is more reliable even on non
+ // call sites
+ // then the architecture default plan and for hand written assembly code
+ // it is often
+ // written in a way that it valid at all location what helps in the most
+ // common
+ // cases when the instruction emulation fails.
+ UnwindPlanSP call_site_unwind_plan =
+ func_unwinders_sp->GetUnwindPlanAtCallSite(
+ process->GetTarget(), m_current_offset_backed_up_one);
if (call_site_unwind_plan &&
call_site_unwind_plan.get() != unwind_plan_sp.get() &&
- call_site_unwind_plan->GetSourceName() != unwind_plan_sp->GetSourceName())
- {
- m_fallback_unwind_plan_sp = call_site_unwind_plan;
- }
- else
- {
- m_fallback_unwind_plan_sp = arch_default_unwind_plan_sp;
+ call_site_unwind_plan->GetSourceName() !=
+ unwind_plan_sp->GetSourceName()) {
+ m_fallback_unwind_plan_sp = call_site_unwind_plan;
+ } else {
+ m_fallback_unwind_plan_sp = arch_default_unwind_plan_sp;
}
- }
-
- if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp, valid_offset))
- {
- UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan", unwind_plan_sp->GetSourceName().GetCString());
- return unwind_plan_sp;
- }
-
- // If we're on the first instruction of a function, and we have an architectural default UnwindPlan
- // for the initial instruction of a function, use that.
- if (m_current_offset_backed_up_one == 0)
- {
- unwind_plan_sp = func_unwinders_sp->GetUnwindPlanArchitectureDefaultAtFunctionEntry (m_thread);
- if (unwind_plan_sp)
- {
- UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan", unwind_plan_sp->GetSourceName().GetCString());
- return unwind_plan_sp;
- }
- }
-
- // If nothing else, use the architectural default UnwindPlan and hope that does the job.
- if (arch_default_unwind_plan_sp)
- UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan", arch_default_unwind_plan_sp->GetSourceName().GetCString());
- else
- UnwindLogMsg ("Unable to find any UnwindPlan for full unwind of this frame.");
-
- return arch_default_unwind_plan_sp;
+ }
+ UnwindLogMsgVerbose("frame uses %s for full UnwindPlan",
+ unwind_plan_sp->GetSourceName().GetCString());
+ return unwind_plan_sp;
+ }
+ }
+
+ // Typically this is unwind info from an eh_frame section intended for
+ // exception handling; only valid at call sites
+ if (process) {
+ unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite(
+ process->GetTarget(), m_current_offset_backed_up_one);
+ }
+ int valid_offset = -1;
+ if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp, valid_offset)) {
+ UnwindLogMsgVerbose("frame uses %s for full UnwindPlan",
+ unwind_plan_sp->GetSourceName().GetCString());
+ return unwind_plan_sp;
+ }
+
+ // We'd prefer to use an UnwindPlan intended for call sites when we're at a
+ // call site but if we've
+ // struck out on that, fall back to using the non-call-site assembly
+ // inspection UnwindPlan if possible.
+ if (process) {
+ unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite(
+ process->GetTarget(), m_thread, m_current_offset_backed_up_one);
+ }
+ if (unwind_plan_sp &&
+ unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolNo) {
+ // We probably have an UnwindPlan created by inspecting assembly
+ // instructions. The assembly
+ // profilers work really well with compiler-generated functions but hand-
+ // written assembly
+ // can be problematic. We set the eh_frame based unwind plan as our fallback
+ // unwind plan if
+ // instruction emulation doesn't work out even for non call sites if it is
+ // available and use
+ // the architecture default unwind plan if it is not available. The eh_frame
+ // unwind plan is
+ // more reliable even on non call sites then the architecture default plan
+ // and for hand
+ // written assembly code it is often written in a way that it valid at all
+ // location what
+ // helps in the most common cases when the instruction emulation fails.
+ UnwindPlanSP call_site_unwind_plan =
+ func_unwinders_sp->GetUnwindPlanAtCallSite(
+ process->GetTarget(), m_current_offset_backed_up_one);
+ if (call_site_unwind_plan &&
+ call_site_unwind_plan.get() != unwind_plan_sp.get() &&
+ call_site_unwind_plan->GetSourceName() !=
+ unwind_plan_sp->GetSourceName()) {
+ m_fallback_unwind_plan_sp = call_site_unwind_plan;
+ } else {
+ m_fallback_unwind_plan_sp = arch_default_unwind_plan_sp;
+ }
+ }
+
+ if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp, valid_offset)) {
+ UnwindLogMsgVerbose("frame uses %s for full UnwindPlan",
+ unwind_plan_sp->GetSourceName().GetCString());
+ return unwind_plan_sp;
+ }
+
+ // If we're on the first instruction of a function, and we have an
+ // architectural default UnwindPlan
+ // for the initial instruction of a function, use that.
+ if (m_current_offset_backed_up_one == 0) {
+ unwind_plan_sp =
+ func_unwinders_sp->GetUnwindPlanArchitectureDefaultAtFunctionEntry(
+ m_thread);
+ if (unwind_plan_sp) {
+ UnwindLogMsgVerbose("frame uses %s for full UnwindPlan",
+ unwind_plan_sp->GetSourceName().GetCString());
+ return unwind_plan_sp;
+ }
+ }
+
+ // If nothing else, use the architectural default UnwindPlan and hope that
+ // does the job.
+ if (arch_default_unwind_plan_sp)
+ UnwindLogMsgVerbose(
+ "frame uses %s for full UnwindPlan",
+ arch_default_unwind_plan_sp->GetSourceName().GetCString());
+ else
+ UnwindLogMsg(
+ "Unable to find any UnwindPlan for full unwind of this frame.");
+
+ return arch_default_unwind_plan_sp;
}
-
-void
-RegisterContextLLDB::InvalidateAllRegisters ()
-{
- m_frame_type = eNotAValidFrame;
+void RegisterContextLLDB::InvalidateAllRegisters() {
+ m_frame_type = eNotAValidFrame;
}
-size_t
-RegisterContextLLDB::GetRegisterCount ()
-{
- return m_thread.GetRegisterContext()->GetRegisterCount();
+size_t RegisterContextLLDB::GetRegisterCount() {
+ return m_thread.GetRegisterContext()->GetRegisterCount();
}
-const RegisterInfo *
-RegisterContextLLDB::GetRegisterInfoAtIndex (size_t reg)
-{
- return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex (reg);
+const RegisterInfo *RegisterContextLLDB::GetRegisterInfoAtIndex(size_t reg) {
+ return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex(reg);
}
-size_t
-RegisterContextLLDB::GetRegisterSetCount ()
-{
- return m_thread.GetRegisterContext()->GetRegisterSetCount ();
+size_t RegisterContextLLDB::GetRegisterSetCount() {
+ return m_thread.GetRegisterContext()->GetRegisterSetCount();
}
-const RegisterSet *
-RegisterContextLLDB::GetRegisterSet (size_t reg_set)
-{
- return m_thread.GetRegisterContext()->GetRegisterSet (reg_set);
+const RegisterSet *RegisterContextLLDB::GetRegisterSet(size_t reg_set) {
+ return m_thread.GetRegisterContext()->GetRegisterSet(reg_set);
}
-uint32_t
-RegisterContextLLDB::ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t num)
-{
- return m_thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber (kind, num);
+uint32_t RegisterContextLLDB::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t num) {
+ return m_thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber(
+ kind, num);
}
-bool
-RegisterContextLLDB::ReadRegisterValueFromRegisterLocation (lldb_private::UnwindLLDB::RegisterLocation regloc,
- const RegisterInfo *reg_info,
- RegisterValue &value)
-{
- if (!IsValid())
- return false;
- bool success = false;
-
- switch (regloc.type)
- {
- case UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext:
- {
- const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number);
-
- if (!other_reg_info)
- return false;
-
- success = m_thread.GetRegisterContext()->ReadRegister (other_reg_info, value);
- }
- break;
- case UnwindLLDB::RegisterLocation::eRegisterInRegister:
- {
- const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number);
-
- if (!other_reg_info)
- return false;
-
- if (IsFrameZero ())
- {
- success = m_thread.GetRegisterContext()->ReadRegister (other_reg_info, value);
- }
- else
- {
- success = GetNextFrame()->ReadRegister (other_reg_info, value);
- }
- }
- break;
- case UnwindLLDB::RegisterLocation::eRegisterValueInferred:
- success = value.SetUInt (regloc.location.inferred_value, reg_info->byte_size);
- break;
-
- case UnwindLLDB::RegisterLocation::eRegisterNotSaved:
- break;
- case UnwindLLDB::RegisterLocation::eRegisterSavedAtHostMemoryLocation:
- assert ("FIXME debugger inferior function call unwind");
- break;
- case UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation:
- {
- Error error (ReadRegisterValueFromMemory(reg_info,
- regloc.location.target_memory_location,
- reg_info->byte_size,
- value));
- success = error.Success();
- }
- break;
- default:
- assert ("Unknown RegisterLocation type.");
- break;
- }
- return success;
+bool RegisterContextLLDB::ReadRegisterValueFromRegisterLocation(
+ lldb_private::UnwindLLDB::RegisterLocation regloc,
+ const RegisterInfo *reg_info, RegisterValue &value) {
+ if (!IsValid())
+ return false;
+ bool success = false;
+
+ switch (regloc.type) {
+ case UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext: {
+ const RegisterInfo *other_reg_info =
+ GetRegisterInfoAtIndex(regloc.location.register_number);
+
+ if (!other_reg_info)
+ return false;
+
+ success =
+ m_thread.GetRegisterContext()->ReadRegister(other_reg_info, value);
+ } break;
+ case UnwindLLDB::RegisterLocation::eRegisterInRegister: {
+ const RegisterInfo *other_reg_info =
+ GetRegisterInfoAtIndex(regloc.location.register_number);
+
+ if (!other_reg_info)
+ return false;
+
+ if (IsFrameZero()) {
+ success =
+ m_thread.GetRegisterContext()->ReadRegister(other_reg_info, value);
+ } else {
+ success = GetNextFrame()->ReadRegister(other_reg_info, value);
+ }
+ } break;
+ case UnwindLLDB::RegisterLocation::eRegisterValueInferred:
+ success =
+ value.SetUInt(regloc.location.inferred_value, reg_info->byte_size);
+ break;
+
+ case UnwindLLDB::RegisterLocation::eRegisterNotSaved:
+ break;
+ case UnwindLLDB::RegisterLocation::eRegisterSavedAtHostMemoryLocation:
+ assert("FIXME debugger inferior function call unwind");
+ break;
+ case UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation: {
+ Error error(ReadRegisterValueFromMemory(
+ reg_info, regloc.location.target_memory_location, reg_info->byte_size,
+ value));
+ success = error.Success();
+ } break;
+ default:
+ assert("Unknown RegisterLocation type.");
+ break;
+ }
+ return success;
}
-bool
-RegisterContextLLDB::WriteRegisterValueToRegisterLocation (lldb_private::UnwindLLDB::RegisterLocation regloc,
- const RegisterInfo *reg_info,
- const RegisterValue &value)
-{
- if (!IsValid())
- return false;
-
- bool success = false;
+bool RegisterContextLLDB::WriteRegisterValueToRegisterLocation(
+ lldb_private::UnwindLLDB::RegisterLocation regloc,
+ const RegisterInfo *reg_info, const RegisterValue &value) {
+ if (!IsValid())
+ return false;
- switch (regloc.type)
- {
- case UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext:
- {
- const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number);
- success = m_thread.GetRegisterContext()->WriteRegister (other_reg_info, value);
- }
- break;
- case UnwindLLDB::RegisterLocation::eRegisterInRegister:
- {
- const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number);
- if (IsFrameZero ())
- {
- success = m_thread.GetRegisterContext()->WriteRegister (other_reg_info, value);
- }
- else
- {
- success = GetNextFrame()->WriteRegister (other_reg_info, value);
- }
- }
- break;
- case UnwindLLDB::RegisterLocation::eRegisterValueInferred:
- case UnwindLLDB::RegisterLocation::eRegisterNotSaved:
- break;
- case UnwindLLDB::RegisterLocation::eRegisterSavedAtHostMemoryLocation:
- assert ("FIXME debugger inferior function call unwind");
- break;
- case UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation:
- {
- Error error (WriteRegisterValueToMemory (reg_info,
- regloc.location.target_memory_location,
- reg_info->byte_size,
- value));
- success = error.Success();
- }
- break;
- default:
- assert ("Unknown RegisterLocation type.");
- break;
- }
- return success;
+ bool success = false;
+
+ switch (regloc.type) {
+ case UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext: {
+ const RegisterInfo *other_reg_info =
+ GetRegisterInfoAtIndex(regloc.location.register_number);
+ success =
+ m_thread.GetRegisterContext()->WriteRegister(other_reg_info, value);
+ } break;
+ case UnwindLLDB::RegisterLocation::eRegisterInRegister: {
+ const RegisterInfo *other_reg_info =
+ GetRegisterInfoAtIndex(regloc.location.register_number);
+ if (IsFrameZero()) {
+ success =
+ m_thread.GetRegisterContext()->WriteRegister(other_reg_info, value);
+ } else {
+ success = GetNextFrame()->WriteRegister(other_reg_info, value);
+ }
+ } break;
+ case UnwindLLDB::RegisterLocation::eRegisterValueInferred:
+ case UnwindLLDB::RegisterLocation::eRegisterNotSaved:
+ break;
+ case UnwindLLDB::RegisterLocation::eRegisterSavedAtHostMemoryLocation:
+ assert("FIXME debugger inferior function call unwind");
+ break;
+ case UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation: {
+ Error error(WriteRegisterValueToMemory(
+ reg_info, regloc.location.target_memory_location, reg_info->byte_size,
+ value));
+ success = error.Success();
+ } break;
+ default:
+ assert("Unknown RegisterLocation type.");
+ break;
+ }
+ return success;
}
-
-bool
-RegisterContextLLDB::IsValid () const
-{
- return m_frame_type != eNotAValidFrame;
+bool RegisterContextLLDB::IsValid() const {
+ return m_frame_type != eNotAValidFrame;
}
-// After the final stack frame in a stack walk we'll get one invalid (eNotAValidFrame) stack frame --
-// one past the end of the stack walk. But higher-level code will need to tell the differnece between
-// "the unwind plan below this frame failed" versus "we successfully completed the stack walk" so
+// After the final stack frame in a stack walk we'll get one invalid
+// (eNotAValidFrame) stack frame --
+// one past the end of the stack walk. But higher-level code will need to tell
+// the differnece between
+// "the unwind plan below this frame failed" versus "we successfully completed
+// the stack walk" so
// this method helps to disambiguate that.
-bool
-RegisterContextLLDB::IsTrapHandlerFrame () const
-{
- return m_frame_type == eTrapHandlerFrame;
+bool RegisterContextLLDB::IsTrapHandlerFrame() const {
+ return m_frame_type == eTrapHandlerFrame;
}
-// A skip frame is a bogus frame on the stack -- but one where we're likely to find a real frame farther
-// up the stack if we keep looking. It's always the second frame in an unwind (i.e. the first frame after
-// frame zero) where unwinding can be the trickiest. Ideally we'll mark up this frame in some way so the
-// user knows we're displaying bad data and we may have skipped one frame of their real program in the
+// A skip frame is a bogus frame on the stack -- but one where we're likely to
+// find a real frame farther
+// up the stack if we keep looking. It's always the second frame in an unwind
+// (i.e. the first frame after
+// frame zero) where unwinding can be the trickiest. Ideally we'll mark up this
+// frame in some way so the
+// user knows we're displaying bad data and we may have skipped one frame of
+// their real program in the
// process of getting back on track.
-bool
-RegisterContextLLDB::IsSkipFrame () const
-{
- return m_frame_type == eSkipFrame;
+bool RegisterContextLLDB::IsSkipFrame() const {
+ return m_frame_type == eSkipFrame;
}
-bool
-RegisterContextLLDB::IsTrapHandlerSymbol (lldb_private::Process *process, const lldb_private::SymbolContext &m_sym_ctx) const
-{
- PlatformSP platform_sp (process->GetTarget().GetPlatform());
- if (platform_sp)
- {
- const std::vector<ConstString> trap_handler_names (platform_sp->GetTrapHandlerSymbolNames());
- for (ConstString name : trap_handler_names)
- {
- if ((m_sym_ctx.function && m_sym_ctx.function->GetName() == name) ||
- (m_sym_ctx.symbol && m_sym_ctx.symbol->GetName() == name))
- {
- return true;
- }
- }
+bool RegisterContextLLDB::IsTrapHandlerSymbol(
+ lldb_private::Process *process,
+ const lldb_private::SymbolContext &m_sym_ctx) const {
+ PlatformSP platform_sp(process->GetTarget().GetPlatform());
+ if (platform_sp) {
+ const std::vector<ConstString> trap_handler_names(
+ platform_sp->GetTrapHandlerSymbolNames());
+ for (ConstString name : trap_handler_names) {
+ if ((m_sym_ctx.function && m_sym_ctx.function->GetName() == name) ||
+ (m_sym_ctx.symbol && m_sym_ctx.symbol->GetName() == name)) {
+ return true;
+ }
}
- const std::vector<ConstString> user_specified_trap_handler_names (m_parent_unwind.GetUserSpecifiedTrapHandlerFunctionNames());
- for (ConstString name : user_specified_trap_handler_names)
- {
- if ((m_sym_ctx.function && m_sym_ctx.function->GetName() == name) ||
- (m_sym_ctx.symbol && m_sym_ctx.symbol->GetName() == name))
- {
- return true;
- }
- }
+ }
+ const std::vector<ConstString> user_specified_trap_handler_names(
+ m_parent_unwind.GetUserSpecifiedTrapHandlerFunctionNames());
+ for (ConstString name : user_specified_trap_handler_names) {
+ if ((m_sym_ctx.function && m_sym_ctx.function->GetName() == name) ||
+ (m_sym_ctx.symbol && m_sym_ctx.symbol->GetName() == name)) {
+ return true;
+ }
+ }
- return false;
+ return false;
}
-// Answer the question: Where did THIS frame save the CALLER frame ("previous" frame)'s register value?
+// Answer the question: Where did THIS frame save the CALLER frame ("previous"
+// frame)'s register value?
enum UnwindLLDB::RegisterSearchResult
-RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc)
-{
- RegisterNumber regnum (m_thread, eRegisterKindLLDB, lldb_regnum);
-
- // Have we already found this register location?
- if (!m_registers.empty())
- {
- std::map<uint32_t, lldb_private::UnwindLLDB::RegisterLocation>::const_iterator iterator;
- iterator = m_registers.find (regnum.GetAsKind (eRegisterKindLLDB));
- if (iterator != m_registers.end())
- {
- regloc = iterator->second;
- UnwindLogMsg ("supplying caller's saved %s (%d)'s location, cached",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterFound;
+RegisterContextLLDB::SavedLocationForRegister(
+ uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc) {
+ RegisterNumber regnum(m_thread, eRegisterKindLLDB, lldb_regnum);
+
+ // Have we already found this register location?
+ if (!m_registers.empty()) {
+ std::map<uint32_t,
+ lldb_private::UnwindLLDB::RegisterLocation>::const_iterator
+ iterator;
+ iterator = m_registers.find(regnum.GetAsKind(eRegisterKindLLDB));
+ if (iterator != m_registers.end()) {
+ regloc = iterator->second;
+ UnwindLogMsg("supplying caller's saved %s (%d)'s location, cached",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
+ }
+ }
+
+ // Look through the available UnwindPlans for the register location.
+
+ UnwindPlan::Row::RegisterLocation unwindplan_regloc;
+ bool have_unwindplan_regloc = false;
+ RegisterKind unwindplan_registerkind = kNumRegisterKinds;
+
+ if (m_fast_unwind_plan_sp) {
+ UnwindPlan::RowSP active_row =
+ m_fast_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
+ unwindplan_registerkind = m_fast_unwind_plan_sp->GetRegisterKind();
+ if (regnum.GetAsKind(unwindplan_registerkind) == LLDB_INVALID_REGNUM) {
+ UnwindLogMsg("could not convert lldb regnum %s (%d) into %d RegisterKind "
+ "reg numbering scheme",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB),
+ (int)unwindplan_registerkind);
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
+ }
+ if (active_row->GetRegisterInfo(regnum.GetAsKind(unwindplan_registerkind),
+ unwindplan_regloc)) {
+ UnwindLogMsg(
+ "supplying caller's saved %s (%d)'s location using FastUnwindPlan",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
+ have_unwindplan_regloc = true;
+ }
+ }
+
+ if (!have_unwindplan_regloc) {
+ // m_full_unwind_plan_sp being NULL means that we haven't tried to find a
+ // full UnwindPlan yet
+ if (!m_full_unwind_plan_sp)
+ m_full_unwind_plan_sp = GetFullUnwindPlanForFrame();
+
+ if (m_full_unwind_plan_sp) {
+ RegisterNumber pc_regnum(m_thread, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_PC);
+
+ UnwindPlan::RowSP active_row =
+ m_full_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
+ unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind();
+
+ RegisterNumber return_address_reg;
+
+ // If we're fetching the saved pc and this UnwindPlan defines a
+ // ReturnAddress register (e.g. lr on arm),
+ // look for the return address register number in the UnwindPlan's row.
+ if (pc_regnum.IsValid() && pc_regnum == regnum &&
+ m_full_unwind_plan_sp->GetReturnAddressRegister() !=
+ LLDB_INVALID_REGNUM) {
+
+ return_address_reg.init(
+ m_thread, m_full_unwind_plan_sp->GetRegisterKind(),
+ m_full_unwind_plan_sp->GetReturnAddressRegister());
+ regnum = return_address_reg;
+ UnwindLogMsg("requested caller's saved PC but this UnwindPlan uses a "
+ "RA reg; getting %s (%d) instead",
+ return_address_reg.GetName(),
+ return_address_reg.GetAsKind(eRegisterKindLLDB));
+ } else {
+ if (regnum.GetAsKind(unwindplan_registerkind) == LLDB_INVALID_REGNUM) {
+ if (unwindplan_registerkind == eRegisterKindGeneric) {
+ UnwindLogMsg("could not convert lldb regnum %s (%d) into "
+ "eRegisterKindGeneric reg numbering scheme",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
+ } else {
+ UnwindLogMsg("could not convert lldb regnum %s (%d) into %d "
+ "RegisterKind reg numbering scheme",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB),
+ (int)unwindplan_registerkind);
+ }
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
}
- }
-
- // Look through the available UnwindPlans for the register location.
-
- UnwindPlan::Row::RegisterLocation unwindplan_regloc;
- bool have_unwindplan_regloc = false;
- RegisterKind unwindplan_registerkind = kNumRegisterKinds;
-
- if (m_fast_unwind_plan_sp)
- {
- UnwindPlan::RowSP active_row = m_fast_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
- unwindplan_registerkind = m_fast_unwind_plan_sp->GetRegisterKind ();
- if (regnum.GetAsKind (unwindplan_registerkind) == LLDB_INVALID_REGNUM)
- {
- UnwindLogMsg ("could not convert lldb regnum %s (%d) into %d RegisterKind reg numbering scheme",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB), (int) unwindplan_registerkind);
- return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
- }
- if (active_row->GetRegisterInfo (regnum.GetAsKind (unwindplan_registerkind), unwindplan_regloc))
- {
- UnwindLogMsg ("supplying caller's saved %s (%d)'s location using FastUnwindPlan",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
- have_unwindplan_regloc = true;
+ }
+
+ if (regnum.IsValid() &&
+ active_row->GetRegisterInfo(regnum.GetAsKind(unwindplan_registerkind),
+ unwindplan_regloc)) {
+ have_unwindplan_regloc = true;
+ UnwindLogMsg(
+ "supplying caller's saved %s (%d)'s location using %s UnwindPlan",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB),
+ m_full_unwind_plan_sp->GetSourceName().GetCString());
+ }
+
+ // This is frame 0 and we're retrieving the PC and it's saved in a Return
+ // Address register and
+ // it hasn't been saved anywhere yet -- that is, it's still live in the
+ // actual register.
+ // Handle this specially.
+
+ if (have_unwindplan_regloc == false && return_address_reg.IsValid() &&
+ IsFrameZero()) {
+ if (return_address_reg.GetAsKind(eRegisterKindLLDB) !=
+ LLDB_INVALID_REGNUM) {
+ lldb_private::UnwindLLDB::RegisterLocation new_regloc;
+ new_regloc.type =
+ UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext;
+ new_regloc.location.register_number =
+ return_address_reg.GetAsKind(eRegisterKindLLDB);
+ m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = new_regloc;
+ regloc = new_regloc;
+ UnwindLogMsg("supplying caller's register %s (%d) from the live "
+ "RegisterContext at frame 0, saved in %d",
+ return_address_reg.GetName(),
+ return_address_reg.GetAsKind(eRegisterKindLLDB),
+ return_address_reg.GetAsKind(eRegisterKindLLDB));
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
}
- }
-
- if (!have_unwindplan_regloc)
- {
- // m_full_unwind_plan_sp being NULL means that we haven't tried to find a full UnwindPlan yet
- if (!m_full_unwind_plan_sp)
- m_full_unwind_plan_sp = GetFullUnwindPlanForFrame ();
-
- if (m_full_unwind_plan_sp)
- {
- RegisterNumber pc_regnum (m_thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
-
- UnwindPlan::RowSP active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
- unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind ();
-
- RegisterNumber return_address_reg;
-
- // If we're fetching the saved pc and this UnwindPlan defines a ReturnAddress register (e.g. lr on arm),
- // look for the return address register number in the UnwindPlan's row.
- if (pc_regnum.IsValid()
- && pc_regnum == regnum
- && m_full_unwind_plan_sp->GetReturnAddressRegister() != LLDB_INVALID_REGNUM)
- {
-
- return_address_reg.init (m_thread, m_full_unwind_plan_sp->GetRegisterKind(), m_full_unwind_plan_sp->GetReturnAddressRegister());
- regnum = return_address_reg;
- UnwindLogMsg ("requested caller's saved PC but this UnwindPlan uses a RA reg; getting %s (%d) instead",
- return_address_reg.GetName(), return_address_reg.GetAsKind (eRegisterKindLLDB));
- }
- else
- {
- if (regnum.GetAsKind (unwindplan_registerkind) == LLDB_INVALID_REGNUM)
- {
- if (unwindplan_registerkind == eRegisterKindGeneric)
- {
- UnwindLogMsg ("could not convert lldb regnum %s (%d) into eRegisterKindGeneric reg numbering scheme",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
- }
- else
- {
- UnwindLogMsg ("could not convert lldb regnum %s (%d) into %d RegisterKind reg numbering scheme",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB), (int) unwindplan_registerkind);
- }
- return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
- }
+ }
+
+ // If this architecture stores the return address in a register (it
+ // defines a Return Address register)
+ // and we're on a non-zero stack frame and the Full UnwindPlan says that
+ // the pc is stored in the
+ // RA registers (e.g. lr on arm), then we know that the full unwindplan is
+ // not trustworthy -- this
+ // is an impossible situation and the instruction emulation code has
+ // likely been misled.
+ // If this stack frame meets those criteria, we need to throw away the
+ // Full UnwindPlan that the
+ // instruction emulation came up with and fall back to the architecture's
+ // Default UnwindPlan so
+ // the stack walk can get past this point.
+
+ // Special note: If the Full UnwindPlan was generated from the compiler,
+ // don't second-guess it
+ // when we're at a call site location.
+
+ // arch_default_ra_regnum is the return address register # in the Full
+ // UnwindPlan register numbering
+ RegisterNumber arch_default_ra_regnum(m_thread, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_RA);
+
+ if (arch_default_ra_regnum.GetAsKind(unwindplan_registerkind) !=
+ LLDB_INVALID_REGNUM &&
+ pc_regnum == regnum && unwindplan_regloc.IsInOtherRegister() &&
+ unwindplan_regloc.GetRegisterNumber() ==
+ arch_default_ra_regnum.GetAsKind(unwindplan_registerkind) &&
+ m_full_unwind_plan_sp->GetSourcedFromCompiler() != eLazyBoolYes &&
+ !m_all_registers_available) {
+ UnwindLogMsg("%s UnwindPlan tried to restore the pc from the link "
+ "register but this is a non-zero frame",
+ m_full_unwind_plan_sp->GetSourceName().GetCString());
+
+ // Throw away the full unwindplan; install the arch default unwindplan
+ if (ForceSwitchToFallbackUnwindPlan()) {
+ // Update for the possibly new unwind plan
+ unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind();
+ UnwindPlan::RowSP active_row =
+ m_full_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
+
+ // Sanity check: Verify that we can fetch a pc value and CFA value
+ // with this unwind plan
+
+ RegisterNumber arch_default_pc_reg(m_thread, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_PC);
+ bool can_fetch_pc_value = false;
+ bool can_fetch_cfa = false;
+ addr_t cfa_value;
+ if (active_row) {
+ if (arch_default_pc_reg.GetAsKind(unwindplan_registerkind) !=
+ LLDB_INVALID_REGNUM &&
+ active_row->GetRegisterInfo(
+ arch_default_pc_reg.GetAsKind(unwindplan_registerkind),
+ unwindplan_regloc)) {
+ can_fetch_pc_value = true;
}
-
- if (regnum.IsValid()
- && active_row->GetRegisterInfo (regnum.GetAsKind (unwindplan_registerkind), unwindplan_regloc))
- {
- have_unwindplan_regloc = true;
- UnwindLogMsg ("supplying caller's saved %s (%d)'s location using %s UnwindPlan",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB),
- m_full_unwind_plan_sp->GetSourceName().GetCString());
- }
-
- // This is frame 0 and we're retrieving the PC and it's saved in a Return Address register and
- // it hasn't been saved anywhere yet -- that is, it's still live in the actual register.
- // Handle this specially.
-
- if (have_unwindplan_regloc == false
- && return_address_reg.IsValid()
- && IsFrameZero())
- {
- if (return_address_reg.GetAsKind (eRegisterKindLLDB) != LLDB_INVALID_REGNUM)
- {
- lldb_private::UnwindLLDB::RegisterLocation new_regloc;
- new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext;
- new_regloc.location.register_number = return_address_reg.GetAsKind (eRegisterKindLLDB);
- m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = new_regloc;
- regloc = new_regloc;
- UnwindLogMsg ("supplying caller's register %s (%d) from the live RegisterContext at frame 0, saved in %d",
- return_address_reg.GetName(), return_address_reg.GetAsKind (eRegisterKindLLDB),
- return_address_reg.GetAsKind (eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterFound;
- }
- }
-
- // If this architecture stores the return address in a register (it defines a Return Address register)
- // and we're on a non-zero stack frame and the Full UnwindPlan says that the pc is stored in the
- // RA registers (e.g. lr on arm), then we know that the full unwindplan is not trustworthy -- this
- // is an impossible situation and the instruction emulation code has likely been misled.
- // If this stack frame meets those criteria, we need to throw away the Full UnwindPlan that the
- // instruction emulation came up with and fall back to the architecture's Default UnwindPlan so
- // the stack walk can get past this point.
-
- // Special note: If the Full UnwindPlan was generated from the compiler, don't second-guess it
- // when we're at a call site location.
-
- // arch_default_ra_regnum is the return address register # in the Full UnwindPlan register numbering
- RegisterNumber arch_default_ra_regnum (m_thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
-
- if (arch_default_ra_regnum.GetAsKind (unwindplan_registerkind) != LLDB_INVALID_REGNUM
- && pc_regnum == regnum
- && unwindplan_regloc.IsInOtherRegister()
- && unwindplan_regloc.GetRegisterNumber() == arch_default_ra_regnum.GetAsKind (unwindplan_registerkind)
- && m_full_unwind_plan_sp->GetSourcedFromCompiler() != eLazyBoolYes
- && !m_all_registers_available)
- {
- UnwindLogMsg ("%s UnwindPlan tried to restore the pc from the link register but this is a non-zero frame",
- m_full_unwind_plan_sp->GetSourceName().GetCString());
-
- // Throw away the full unwindplan; install the arch default unwindplan
- if (ForceSwitchToFallbackUnwindPlan())
- {
- // Update for the possibly new unwind plan
- unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind ();
- UnwindPlan::RowSP active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
-
- // Sanity check: Verify that we can fetch a pc value and CFA value with this unwind plan
-
- RegisterNumber arch_default_pc_reg (m_thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
- bool can_fetch_pc_value = false;
- bool can_fetch_cfa = false;
- addr_t cfa_value;
- if (active_row)
- {
- if (arch_default_pc_reg.GetAsKind (unwindplan_registerkind) != LLDB_INVALID_REGNUM
- && active_row->GetRegisterInfo (arch_default_pc_reg.GetAsKind (unwindplan_registerkind), unwindplan_regloc))
- {
- can_fetch_pc_value = true;
- }
- if (ReadCFAValueForRow (unwindplan_registerkind, active_row, cfa_value))
- {
- can_fetch_cfa = true;
- }
- }
-
- if (can_fetch_pc_value && can_fetch_cfa)
- {
- have_unwindplan_regloc = true;
- }
- else
- {
- have_unwindplan_regloc = false;
- }
- }
- else
- {
- // We were unable to fall back to another unwind plan
- have_unwindplan_regloc = false;
- }
+ if (ReadCFAValueForRow(unwindplan_registerkind, active_row,
+ cfa_value)) {
+ can_fetch_cfa = true;
}
- }
- }
+ }
- ExecutionContext exe_ctx(m_thread.shared_from_this());
- Process *process = exe_ctx.GetProcessPtr();
- if (have_unwindplan_regloc == false)
- {
- // If the UnwindPlan failed to give us an unwind location for this register, we may be able to fall back
- // to some ABI-defined default. For example, some ABIs allow to determine the caller's SP via the CFA.
- // Also, the ABI may set volatile registers to the undefined state.
- ABI *abi = process ? process->GetABI().get() : NULL;
- if (abi)
- {
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(regnum.GetAsKind (eRegisterKindLLDB));
- if (reg_info && abi->GetFallbackRegisterLocation (reg_info, unwindplan_regloc))
- {
- UnwindLogMsg ("supplying caller's saved %s (%d)'s location using ABI default",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
- have_unwindplan_regloc = true;
- }
- }
- }
-
- if (have_unwindplan_regloc == false)
- {
- if (IsFrameZero ())
- {
- // This is frame 0 - we should return the actual live register context value
- lldb_private::UnwindLLDB::RegisterLocation new_regloc;
- new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext;
- new_regloc.location.register_number = regnum.GetAsKind (eRegisterKindLLDB);
- m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = new_regloc;
- regloc = new_regloc;
- UnwindLogMsg ("supplying caller's register %s (%d) from the live RegisterContext at frame 0",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterFound;
- }
- else
- {
- std::string unwindplan_name ("");
- if (m_full_unwind_plan_sp)
- {
- unwindplan_name += "via '";
- unwindplan_name += m_full_unwind_plan_sp->GetSourceName().AsCString();
- unwindplan_name += "'";
- }
- UnwindLogMsg ("no save location for %s (%d) %s",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB),
- unwindplan_name.c_str());
- }
- return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
- }
-
- // unwindplan_regloc has valid contents about where to retrieve the register
- if (unwindplan_regloc.IsUnspecified())
- {
- lldb_private::UnwindLLDB::RegisterLocation new_regloc;
- new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterNotSaved;
- m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = new_regloc;
- UnwindLogMsg ("save location for %s (%d) is unspecified, continue searching",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
- }
-
- if (unwindplan_regloc.IsUndefined())
- {
- UnwindLogMsg ("did not supply reg location for %s (%d) because it is volatile",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile;
- }
-
- if (unwindplan_regloc.IsSame())
- {
- if (IsFrameZero() == false
- && (regnum.GetAsKind (eRegisterKindGeneric) == LLDB_REGNUM_GENERIC_PC
- || regnum.GetAsKind (eRegisterKindGeneric) == LLDB_REGNUM_GENERIC_RA))
- {
- UnwindLogMsg ("register %s (%d) is marked as 'IsSame' - it is a pc or return address reg on a non-zero frame -- treat as if we have no information",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
- }
- else
- {
- regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister;
- regloc.location.register_number = regnum.GetAsKind (eRegisterKindLLDB);
- m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc;
- UnwindLogMsg ("supplying caller's register %s (%d), saved in register %s (%d)",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB),
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterFound;
+ if (can_fetch_pc_value && can_fetch_cfa) {
+ have_unwindplan_regloc = true;
+ } else {
+ have_unwindplan_regloc = false;
+ }
+ } else {
+ // We were unable to fall back to another unwind plan
+ have_unwindplan_regloc = false;
}
+ }
+ }
+ }
+
+ ExecutionContext exe_ctx(m_thread.shared_from_this());
+ Process *process = exe_ctx.GetProcessPtr();
+ if (have_unwindplan_regloc == false) {
+ // If the UnwindPlan failed to give us an unwind location for this register,
+ // we may be able to fall back
+ // to some ABI-defined default. For example, some ABIs allow to determine
+ // the caller's SP via the CFA.
+ // Also, the ABI may set volatile registers to the undefined state.
+ ABI *abi = process ? process->GetABI().get() : NULL;
+ if (abi) {
+ const RegisterInfo *reg_info =
+ GetRegisterInfoAtIndex(regnum.GetAsKind(eRegisterKindLLDB));
+ if (reg_info &&
+ abi->GetFallbackRegisterLocation(reg_info, unwindplan_regloc)) {
+ UnwindLogMsg(
+ "supplying caller's saved %s (%d)'s location using ABI default",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
+ have_unwindplan_regloc = true;
+ }
+ }
+ }
+
+ if (have_unwindplan_regloc == false) {
+ if (IsFrameZero()) {
+ // This is frame 0 - we should return the actual live register context
+ // value
+ lldb_private::UnwindLLDB::RegisterLocation new_regloc;
+ new_regloc.type =
+ UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext;
+ new_regloc.location.register_number = regnum.GetAsKind(eRegisterKindLLDB);
+ m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = new_regloc;
+ regloc = new_regloc;
+ UnwindLogMsg("supplying caller's register %s (%d) from the live "
+ "RegisterContext at frame 0",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
+ } else {
+ std::string unwindplan_name("");
+ if (m_full_unwind_plan_sp) {
+ unwindplan_name += "via '";
+ unwindplan_name += m_full_unwind_plan_sp->GetSourceName().AsCString();
+ unwindplan_name += "'";
+ }
+ UnwindLogMsg("no save location for %s (%d) %s", regnum.GetName(),
+ regnum.GetAsKind(eRegisterKindLLDB),
+ unwindplan_name.c_str());
}
-
- if (unwindplan_regloc.IsCFAPlusOffset())
- {
- int offset = unwindplan_regloc.GetOffset();
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
+ }
+
+ // unwindplan_regloc has valid contents about where to retrieve the register
+ if (unwindplan_regloc.IsUnspecified()) {
+ lldb_private::UnwindLLDB::RegisterLocation new_regloc;
+ new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterNotSaved;
+ m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = new_regloc;
+ UnwindLogMsg("save location for %s (%d) is unspecified, continue searching",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
+ }
+
+ if (unwindplan_regloc.IsUndefined()) {
+ UnwindLogMsg(
+ "did not supply reg location for %s (%d) because it is volatile",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
+ return UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile;
+ }
+
+ if (unwindplan_regloc.IsSame()) {
+ if (IsFrameZero() == false &&
+ (regnum.GetAsKind(eRegisterKindGeneric) == LLDB_REGNUM_GENERIC_PC ||
+ regnum.GetAsKind(eRegisterKindGeneric) == LLDB_REGNUM_GENERIC_RA)) {
+ UnwindLogMsg("register %s (%d) is marked as 'IsSame' - it is a pc or "
+ "return address reg on a non-zero frame -- treat as if we "
+ "have no information",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
+ } else {
+ regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister;
+ regloc.location.register_number = regnum.GetAsKind(eRegisterKindLLDB);
+ m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
+ UnwindLogMsg(
+ "supplying caller's register %s (%d), saved in register %s (%d)",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB),
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
+ }
+ }
+
+ if (unwindplan_regloc.IsCFAPlusOffset()) {
+ int offset = unwindplan_regloc.GetOffset();
+ regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred;
+ regloc.location.inferred_value = m_cfa + offset;
+ m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
+ UnwindLogMsg("supplying caller's register %s (%d), value is CFA plus "
+ "offset %d [value is 0x%" PRIx64 "]",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), offset,
+ regloc.location.inferred_value);
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
+ }
+
+ if (unwindplan_regloc.IsAtCFAPlusOffset()) {
+ int offset = unwindplan_regloc.GetOffset();
+ regloc.type = UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation;
+ regloc.location.target_memory_location = m_cfa + offset;
+ m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
+ UnwindLogMsg("supplying caller's register %s (%d) from the stack, saved at "
+ "CFA plus offset %d [saved at 0x%" PRIx64 "]",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), offset,
+ regloc.location.target_memory_location);
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
+ }
+
+ if (unwindplan_regloc.IsInOtherRegister()) {
+ uint32_t unwindplan_regnum = unwindplan_regloc.GetRegisterNumber();
+ RegisterNumber row_regnum(m_thread, unwindplan_registerkind,
+ unwindplan_regnum);
+ if (row_regnum.GetAsKind(eRegisterKindLLDB) == LLDB_INVALID_REGNUM) {
+ UnwindLogMsg("could not supply caller's %s (%d) location - was saved in "
+ "another reg but couldn't convert that regnum",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
+ }
+ regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister;
+ regloc.location.register_number = row_regnum.GetAsKind(eRegisterKindLLDB);
+ m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
+ UnwindLogMsg(
+ "supplying caller's register %s (%d), saved in register %s (%d)",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB),
+ row_regnum.GetName(), row_regnum.GetAsKind(eRegisterKindLLDB));
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
+ }
+
+ if (unwindplan_regloc.IsDWARFExpression() ||
+ unwindplan_regloc.IsAtDWARFExpression()) {
+ DataExtractor dwarfdata(unwindplan_regloc.GetDWARFExpressionBytes(),
+ unwindplan_regloc.GetDWARFExpressionLength(),
+ process->GetByteOrder(),
+ process->GetAddressByteSize());
+ ModuleSP opcode_ctx;
+ DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr, 0,
+ unwindplan_regloc.GetDWARFExpressionLength());
+ dwarfexpr.SetRegisterKind(unwindplan_registerkind);
+ Value result;
+ Error error;
+ if (dwarfexpr.Evaluate(&exe_ctx, nullptr, nullptr, this, 0, nullptr,
+ nullptr, result, &error)) {
+ addr_t val;
+ val = result.GetScalar().ULongLong();
+ if (unwindplan_regloc.IsDWARFExpression()) {
regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred;
- regloc.location.inferred_value = m_cfa + offset;
- m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc;
- UnwindLogMsg ("supplying caller's register %s (%d), value is CFA plus offset %d [value is 0x%" PRIx64 "]",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB),
- offset, regloc.location.inferred_value);
+ regloc.location.inferred_value = val;
+ m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
+ UnwindLogMsg("supplying caller's register %s (%d) via DWARF expression "
+ "(IsDWARFExpression)",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
return UnwindLLDB::RegisterSearchResult::eRegisterFound;
- }
-
- if (unwindplan_regloc.IsAtCFAPlusOffset())
- {
- int offset = unwindplan_regloc.GetOffset();
- regloc.type = UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation;
- regloc.location.target_memory_location = m_cfa + offset;
- m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc;
- UnwindLogMsg ("supplying caller's register %s (%d) from the stack, saved at CFA plus offset %d [saved at 0x%" PRIx64 "]",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB),
- offset, regloc.location.target_memory_location);
+ } else {
+ regloc.type =
+ UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation;
+ regloc.location.target_memory_location = val;
+ m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
+ UnwindLogMsg("supplying caller's register %s (%d) via DWARF expression "
+ "(IsAtDWARFExpression)",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
return UnwindLLDB::RegisterSearchResult::eRegisterFound;
+ }
}
+ UnwindLogMsg("tried to use IsDWARFExpression or IsAtDWARFExpression for %s "
+ "(%d) but failed",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
+ }
- if (unwindplan_regloc.IsInOtherRegister())
- {
- uint32_t unwindplan_regnum = unwindplan_regloc.GetRegisterNumber();
- RegisterNumber row_regnum (m_thread, unwindplan_registerkind, unwindplan_regnum);
- if (row_regnum.GetAsKind (eRegisterKindLLDB) == LLDB_INVALID_REGNUM)
- {
- UnwindLogMsg ("could not supply caller's %s (%d) location - was saved in another reg but couldn't convert that regnum",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
- }
- regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister;
- regloc.location.register_number = row_regnum.GetAsKind (eRegisterKindLLDB);
- m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc;
- UnwindLogMsg ("supplying caller's register %s (%d), saved in register %s (%d)",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB),
- row_regnum.GetName(), row_regnum.GetAsKind (eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterFound;
- }
-
- if (unwindplan_regloc.IsDWARFExpression() || unwindplan_regloc.IsAtDWARFExpression())
- {
- DataExtractor dwarfdata (unwindplan_regloc.GetDWARFExpressionBytes(),
- unwindplan_regloc.GetDWARFExpressionLength(),
- process->GetByteOrder(), process->GetAddressByteSize());
- ModuleSP opcode_ctx;
- DWARFExpression dwarfexpr (opcode_ctx,
- dwarfdata,
- nullptr,
- 0,
- unwindplan_regloc.GetDWARFExpressionLength());
- dwarfexpr.SetRegisterKind (unwindplan_registerkind);
- Value result;
- Error error;
- if (dwarfexpr.Evaluate (&exe_ctx, nullptr, nullptr, this, 0, nullptr, nullptr, result, &error))
- {
- addr_t val;
- val = result.GetScalar().ULongLong();
- if (unwindplan_regloc.IsDWARFExpression())
- {
- regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred;
- regloc.location.inferred_value = val;
- m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc;
- UnwindLogMsg ("supplying caller's register %s (%d) via DWARF expression (IsDWARFExpression)",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterFound;
- }
- else
- {
- regloc.type = UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation;
- regloc.location.target_memory_location = val;
- m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc;
- UnwindLogMsg ("supplying caller's register %s (%d) via DWARF expression (IsAtDWARFExpression)",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterFound;
- }
- }
- UnwindLogMsg ("tried to use IsDWARFExpression or IsAtDWARFExpression for %s (%d) but failed",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
- return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
- }
-
- UnwindLogMsg ("no save location for %s (%d) in this stack frame",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
+ UnwindLogMsg("no save location for %s (%d) in this stack frame",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
- // FIXME UnwindPlan::Row types atDWARFExpression and isDWARFExpression are unsupported.
+ // FIXME UnwindPlan::Row types atDWARFExpression and isDWARFExpression are
+ // unsupported.
- return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
}
// TryFallbackUnwindPlan() -- this method is a little tricky.
-//
-// When this is called, the frame above -- the caller frame, the "previous" frame --
-// is invalid or bad.
//
-// Instead of stopping the stack walk here, we'll try a different UnwindPlan and see
-// if we can get a valid frame above us.
+// When this is called, the frame above -- the caller frame, the "previous"
+// frame --
+// is invalid or bad.
+//
+// Instead of stopping the stack walk here, we'll try a different UnwindPlan and
+// see
+// if we can get a valid frame above us.
//
-// This most often happens when an unwind plan based on assembly instruction inspection
-// is not correct -- mostly with hand-written assembly functions or functions where the
-// stack frame is set up "out of band", e.g. the kernel saved the register context and
+// This most often happens when an unwind plan based on assembly instruction
+// inspection
+// is not correct -- mostly with hand-written assembly functions or functions
+// where the
+// stack frame is set up "out of band", e.g. the kernel saved the register
+// context and
// then called an asynchronous trap handler like _sigtramp.
//
-// Often in these cases, if we just do a dumb stack walk we'll get past this tricky
+// Often in these cases, if we just do a dumb stack walk we'll get past this
+// tricky
// frame and our usual techniques can continue to be used.
-bool
-RegisterContextLLDB::TryFallbackUnwindPlan ()
-{
- if (m_fallback_unwind_plan_sp.get() == nullptr)
- return false;
-
- if (m_full_unwind_plan_sp.get() == nullptr)
- return false;
-
- if (m_full_unwind_plan_sp.get() == m_fallback_unwind_plan_sp.get()
- || m_full_unwind_plan_sp->GetSourceName() == m_fallback_unwind_plan_sp->GetSourceName())
- {
- return false;
- }
+bool RegisterContextLLDB::TryFallbackUnwindPlan() {
+ if (m_fallback_unwind_plan_sp.get() == nullptr)
+ return false;
- // If a compiler generated unwind plan failed, trying the arch default unwindplan
- // isn't going to do any better.
- if (m_full_unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes)
- return false;
+ if (m_full_unwind_plan_sp.get() == nullptr)
+ return false;
+ if (m_full_unwind_plan_sp.get() == m_fallback_unwind_plan_sp.get() ||
+ m_full_unwind_plan_sp->GetSourceName() ==
+ m_fallback_unwind_plan_sp->GetSourceName()) {
+ return false;
+ }
- // Get the caller's pc value and our own CFA value.
- // Swap in the fallback unwind plan, re-fetch the caller's pc value and CFA value.
- // If they're the same, then the fallback unwind plan provides no benefit.
+ // If a compiler generated unwind plan failed, trying the arch default
+ // unwindplan
+ // isn't going to do any better.
+ if (m_full_unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes)
+ return false;
- RegisterNumber pc_regnum (m_thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+ // Get the caller's pc value and our own CFA value.
+ // Swap in the fallback unwind plan, re-fetch the caller's pc value and CFA
+ // value.
+ // If they're the same, then the fallback unwind plan provides no benefit.
+
+ RegisterNumber pc_regnum(m_thread, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_PC);
+
+ addr_t old_caller_pc_value = LLDB_INVALID_ADDRESS;
+ addr_t new_caller_pc_value = LLDB_INVALID_ADDRESS;
+ addr_t old_this_frame_cfa_value = m_cfa;
+ UnwindLLDB::RegisterLocation regloc;
+ if (SavedLocationForRegister(pc_regnum.GetAsKind(eRegisterKindLLDB),
+ regloc) ==
+ UnwindLLDB::RegisterSearchResult::eRegisterFound) {
+ const RegisterInfo *reg_info =
+ GetRegisterInfoAtIndex(pc_regnum.GetAsKind(eRegisterKindLLDB));
+ if (reg_info) {
+ RegisterValue reg_value;
+ if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) {
+ old_caller_pc_value = reg_value.GetAsUInt64();
+ }
+ }
+ }
+
+ // This is a tricky wrinkle! If SavedLocationForRegister() detects a really
+ // impossible
+ // register location for the full unwind plan, it may call
+ // ForceSwitchToFallbackUnwindPlan()
+ // which in turn replaces the full unwindplan with the fallback... in short,
+ // we're done,
+ // we're using the fallback UnwindPlan.
+ // We checked if m_fallback_unwind_plan_sp was nullptr at the top -- the only
+ // way it
+ // became nullptr since then is via SavedLocationForRegister().
+ if (m_fallback_unwind_plan_sp.get() == nullptr)
+ return true;
- addr_t old_caller_pc_value = LLDB_INVALID_ADDRESS;
- addr_t new_caller_pc_value = LLDB_INVALID_ADDRESS;
- addr_t old_this_frame_cfa_value = m_cfa;
- UnwindLLDB::RegisterLocation regloc;
- if (SavedLocationForRegister (pc_regnum.GetAsKind (eRegisterKindLLDB), regloc) == UnwindLLDB::RegisterSearchResult::eRegisterFound)
- {
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(pc_regnum.GetAsKind (eRegisterKindLLDB));
- if (reg_info)
- {
- RegisterValue reg_value;
- if (ReadRegisterValueFromRegisterLocation (regloc, reg_info, reg_value))
- {
- old_caller_pc_value = reg_value.GetAsUInt64();
- }
+ // Switch the full UnwindPlan to be the fallback UnwindPlan. If we decide
+ // this isn't
+ // working, we need to restore.
+ // We'll also need to save & restore the value of the m_cfa ivar. Save is
+ // down below a bit in 'old_cfa'.
+ UnwindPlanSP original_full_unwind_plan_sp = m_full_unwind_plan_sp;
+ addr_t old_cfa = m_cfa;
+
+ m_registers.clear();
+
+ m_full_unwind_plan_sp = m_fallback_unwind_plan_sp;
+
+ UnwindPlan::RowSP active_row =
+ m_fallback_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
+
+ if (active_row &&
+ active_row->GetCFAValue().GetValueType() !=
+ UnwindPlan::Row::CFAValue::unspecified) {
+ addr_t new_cfa;
+ if (!ReadCFAValueForRow(m_fallback_unwind_plan_sp->GetRegisterKind(),
+ active_row, new_cfa) ||
+ new_cfa == 0 || new_cfa == 1 || new_cfa == LLDB_INVALID_ADDRESS) {
+ UnwindLogMsg("failed to get cfa with fallback unwindplan");
+ m_fallback_unwind_plan_sp.reset();
+ m_full_unwind_plan_sp = original_full_unwind_plan_sp;
+ m_cfa = old_cfa;
+ return false;
+ }
+ m_cfa = new_cfa;
+
+ if (SavedLocationForRegister(pc_regnum.GetAsKind(eRegisterKindLLDB),
+ regloc) ==
+ UnwindLLDB::RegisterSearchResult::eRegisterFound) {
+ const RegisterInfo *reg_info =
+ GetRegisterInfoAtIndex(pc_regnum.GetAsKind(eRegisterKindLLDB));
+ if (reg_info) {
+ RegisterValue reg_value;
+ if (ReadRegisterValueFromRegisterLocation(regloc, reg_info,
+ reg_value)) {
+ new_caller_pc_value = reg_value.GetAsUInt64();
}
+ }
}
- // This is a tricky wrinkle! If SavedLocationForRegister() detects a really impossible
- // register location for the full unwind plan, it may call ForceSwitchToFallbackUnwindPlan()
- // which in turn replaces the full unwindplan with the fallback... in short, we're done,
- // we're using the fallback UnwindPlan.
- // We checked if m_fallback_unwind_plan_sp was nullptr at the top -- the only way it
- // became nullptr since then is via SavedLocationForRegister().
- if (m_fallback_unwind_plan_sp.get() == nullptr)
- return true;
-
-
- // Switch the full UnwindPlan to be the fallback UnwindPlan. If we decide this isn't
- // working, we need to restore.
- // We'll also need to save & restore the value of the m_cfa ivar. Save is down below a bit in 'old_cfa'.
- UnwindPlanSP original_full_unwind_plan_sp = m_full_unwind_plan_sp;
- addr_t old_cfa = m_cfa;
-
- m_registers.clear();
-
- m_full_unwind_plan_sp = m_fallback_unwind_plan_sp;
-
- UnwindPlan::RowSP active_row = m_fallback_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
-
- if (active_row && active_row->GetCFAValue().GetValueType() != UnwindPlan::Row::CFAValue::unspecified)
- {
- addr_t new_cfa;
- if (!ReadCFAValueForRow (m_fallback_unwind_plan_sp->GetRegisterKind(), active_row, new_cfa)
- || new_cfa == 0 || new_cfa == 1 || new_cfa == LLDB_INVALID_ADDRESS)
- {
- UnwindLogMsg ("failed to get cfa with fallback unwindplan");
- m_fallback_unwind_plan_sp.reset();
- m_full_unwind_plan_sp = original_full_unwind_plan_sp;
- m_cfa = old_cfa;
- return false;
- }
- m_cfa = new_cfa;
-
- if (SavedLocationForRegister (pc_regnum.GetAsKind (eRegisterKindLLDB), regloc) == UnwindLLDB::RegisterSearchResult::eRegisterFound)
- {
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(pc_regnum.GetAsKind (eRegisterKindLLDB));
- if (reg_info)
- {
- RegisterValue reg_value;
- if (ReadRegisterValueFromRegisterLocation (regloc, reg_info, reg_value))
- {
- new_caller_pc_value = reg_value.GetAsUInt64();
- }
- }
- }
+ if (new_caller_pc_value == LLDB_INVALID_ADDRESS) {
+ UnwindLogMsg("failed to get a pc value for the caller frame with the "
+ "fallback unwind plan");
+ m_fallback_unwind_plan_sp.reset();
+ m_full_unwind_plan_sp = original_full_unwind_plan_sp;
+ m_cfa = old_cfa;
+ return false;
+ }
+ if (old_caller_pc_value != LLDB_INVALID_ADDRESS) {
+ if (old_caller_pc_value == new_caller_pc_value &&
+ new_cfa == old_this_frame_cfa_value) {
+ UnwindLogMsg("fallback unwind plan got the same values for this frame "
+ "CFA and caller frame pc, not using");
+ m_fallback_unwind_plan_sp.reset();
+ m_full_unwind_plan_sp = original_full_unwind_plan_sp;
+ m_cfa = old_cfa;
+ return false;
+ }
+ }
- if (new_caller_pc_value == LLDB_INVALID_ADDRESS)
- {
- UnwindLogMsg ("failed to get a pc value for the caller frame with the fallback unwind plan");
- m_fallback_unwind_plan_sp.reset();
- m_full_unwind_plan_sp = original_full_unwind_plan_sp;
- m_cfa = old_cfa;
- return false;
- }
+ UnwindLogMsg("trying to unwind from this function with the UnwindPlan '%s' "
+ "because UnwindPlan '%s' failed.",
+ m_fallback_unwind_plan_sp->GetSourceName().GetCString(),
+ original_full_unwind_plan_sp->GetSourceName().GetCString());
- if (old_caller_pc_value != LLDB_INVALID_ADDRESS)
- {
- if (old_caller_pc_value == new_caller_pc_value && new_cfa == old_this_frame_cfa_value)
- {
- UnwindLogMsg ("fallback unwind plan got the same values for this frame CFA and caller frame pc, not using");
- m_fallback_unwind_plan_sp.reset();
- m_full_unwind_plan_sp = original_full_unwind_plan_sp;
- m_cfa = old_cfa;
- return false;
- }
- }
+ // We've copied the fallback unwind plan into the full - now clear the
+ // fallback.
+ m_fallback_unwind_plan_sp.reset();
+ }
- UnwindLogMsg ("trying to unwind from this function with the UnwindPlan '%s' because UnwindPlan '%s' failed.",
- m_fallback_unwind_plan_sp->GetSourceName().GetCString(),
- original_full_unwind_plan_sp->GetSourceName().GetCString());
+ return true;
+}
- // We've copied the fallback unwind plan into the full - now clear the fallback.
- m_fallback_unwind_plan_sp.reset();
- }
+bool RegisterContextLLDB::ForceSwitchToFallbackUnwindPlan() {
+ if (m_fallback_unwind_plan_sp.get() == NULL)
+ return false;
- return true;
-}
+ if (m_full_unwind_plan_sp.get() == NULL)
+ return false;
-bool
-RegisterContextLLDB::ForceSwitchToFallbackUnwindPlan ()
-{
- if (m_fallback_unwind_plan_sp.get() == NULL)
- return false;
+ if (m_full_unwind_plan_sp.get() == m_fallback_unwind_plan_sp.get() ||
+ m_full_unwind_plan_sp->GetSourceName() ==
+ m_fallback_unwind_plan_sp->GetSourceName()) {
+ return false;
+ }
- if (m_full_unwind_plan_sp.get() == NULL)
- return false;
+ UnwindPlan::RowSP active_row =
+ m_fallback_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
- if (m_full_unwind_plan_sp.get() == m_fallback_unwind_plan_sp.get()
- || m_full_unwind_plan_sp->GetSourceName() == m_fallback_unwind_plan_sp->GetSourceName())
- {
- return false;
+ if (active_row &&
+ active_row->GetCFAValue().GetValueType() !=
+ UnwindPlan::Row::CFAValue::unspecified) {
+ addr_t new_cfa;
+ if (!ReadCFAValueForRow(m_fallback_unwind_plan_sp->GetRegisterKind(),
+ active_row, new_cfa) ||
+ new_cfa == 0 || new_cfa == 1 || new_cfa == LLDB_INVALID_ADDRESS) {
+ UnwindLogMsg("failed to get cfa with fallback unwindplan");
+ m_fallback_unwind_plan_sp.reset();
+ return false;
}
- UnwindPlan::RowSP active_row = m_fallback_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
-
- if (active_row && active_row->GetCFAValue().GetValueType() != UnwindPlan::Row::CFAValue::unspecified)
- {
- addr_t new_cfa;
- if (!ReadCFAValueForRow (m_fallback_unwind_plan_sp->GetRegisterKind(), active_row, new_cfa)
- || new_cfa == 0 || new_cfa == 1 || new_cfa == LLDB_INVALID_ADDRESS)
- {
- UnwindLogMsg ("failed to get cfa with fallback unwindplan");
- m_fallback_unwind_plan_sp.reset();
- return false;
- }
-
- m_full_unwind_plan_sp = m_fallback_unwind_plan_sp;
- m_fallback_unwind_plan_sp.reset();
+ m_full_unwind_plan_sp = m_fallback_unwind_plan_sp;
+ m_fallback_unwind_plan_sp.reset();
- m_registers.clear();
+ m_registers.clear();
- m_cfa = new_cfa;
+ m_cfa = new_cfa;
- UnwindLogMsg ("switched unconditionally to the fallback unwindplan %s", m_full_unwind_plan_sp->GetSourceName().GetCString());
- return true;
- }
- return false;
+ UnwindLogMsg("switched unconditionally to the fallback unwindplan %s",
+ m_full_unwind_plan_sp->GetSourceName().GetCString());
+ return true;
+ }
+ return false;
}
-bool
-RegisterContextLLDB::ReadCFAValueForRow (lldb::RegisterKind row_register_kind,
- const UnwindPlan::RowSP &row,
- addr_t &cfa_value)
-{
- RegisterValue reg_value;
-
- cfa_value = LLDB_INVALID_ADDRESS;
- addr_t cfa_reg_contents;
-
- switch (row->GetCFAValue().GetValueType())
- {
- case UnwindPlan::Row::CFAValue::isRegisterDereferenced:
- {
- RegisterNumber cfa_reg (m_thread, row_register_kind, row->GetCFAValue().GetRegisterNumber());
- if (ReadGPRValue (cfa_reg, cfa_reg_contents))
- {
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex (cfa_reg.GetAsKind (eRegisterKindLLDB));
- RegisterValue reg_value;
- if (reg_info)
- {
- Error error = ReadRegisterValueFromMemory(reg_info,
- cfa_reg_contents,
- reg_info->byte_size,
- reg_value);
- if (error.Success ())
- {
- cfa_value = reg_value.GetAsUInt64();
- UnwindLogMsg ("CFA value via dereferencing reg %s (%d): reg has val 0x%" PRIx64 ", CFA value is 0x%" PRIx64,
- cfa_reg.GetName(), cfa_reg.GetAsKind (eRegisterKindLLDB),
- cfa_reg_contents, cfa_value);
- return true;
- }
- else
- {
- UnwindLogMsg ("Tried to deref reg %s (%d) [0x%" PRIx64 "] but memory read failed.",
- cfa_reg.GetName(), cfa_reg.GetAsKind (eRegisterKindLLDB),
- cfa_reg_contents);
- }
- }
- }
- break;
- }
- case UnwindPlan::Row::CFAValue::isRegisterPlusOffset:
- {
- RegisterNumber cfa_reg (m_thread, row_register_kind, row->GetCFAValue().GetRegisterNumber());
- if (ReadGPRValue (cfa_reg, cfa_reg_contents))
- {
- if (cfa_reg_contents == LLDB_INVALID_ADDRESS || cfa_reg_contents == 0 || cfa_reg_contents == 1)
- {
- UnwindLogMsg ("Got an invalid CFA register value - reg %s (%d), value 0x%" PRIx64,
- cfa_reg.GetName(), cfa_reg.GetAsKind (eRegisterKindLLDB),
- cfa_reg_contents);
- cfa_reg_contents = LLDB_INVALID_ADDRESS;
- return false;
- }
- cfa_value = cfa_reg_contents + row->GetCFAValue().GetOffset();
- UnwindLogMsg ("CFA is 0x%" PRIx64 ": Register %s (%d) contents are 0x%" PRIx64 ", offset is %d",
- cfa_value,
- cfa_reg.GetName(), cfa_reg.GetAsKind (eRegisterKindLLDB),
- cfa_reg_contents, row->GetCFAValue().GetOffset());
- return true;
- }
- break;
+bool RegisterContextLLDB::ReadCFAValueForRow(
+ lldb::RegisterKind row_register_kind, const UnwindPlan::RowSP &row,
+ addr_t &cfa_value) {
+ RegisterValue reg_value;
+
+ cfa_value = LLDB_INVALID_ADDRESS;
+ addr_t cfa_reg_contents;
+
+ switch (row->GetCFAValue().GetValueType()) {
+ case UnwindPlan::Row::CFAValue::isRegisterDereferenced: {
+ RegisterNumber cfa_reg(m_thread, row_register_kind,
+ row->GetCFAValue().GetRegisterNumber());
+ if (ReadGPRValue(cfa_reg, cfa_reg_contents)) {
+ const RegisterInfo *reg_info =
+ GetRegisterInfoAtIndex(cfa_reg.GetAsKind(eRegisterKindLLDB));
+ RegisterValue reg_value;
+ if (reg_info) {
+ Error error = ReadRegisterValueFromMemory(
+ reg_info, cfa_reg_contents, reg_info->byte_size, reg_value);
+ if (error.Success()) {
+ cfa_value = reg_value.GetAsUInt64();
+ UnwindLogMsg(
+ "CFA value via dereferencing reg %s (%d): reg has val 0x%" PRIx64
+ ", CFA value is 0x%" PRIx64,
+ cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB),
+ cfa_reg_contents, cfa_value);
+ return true;
+ } else {
+ UnwindLogMsg("Tried to deref reg %s (%d) [0x%" PRIx64
+ "] but memory read failed.",
+ cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB),
+ cfa_reg_contents);
}
- case UnwindPlan::Row::CFAValue::isDWARFExpression:
- {
- ExecutionContext exe_ctx(m_thread.shared_from_this());
- Process *process = exe_ctx.GetProcessPtr();
- DataExtractor dwarfdata (row->GetCFAValue().GetDWARFExpressionBytes(),
- row->GetCFAValue().GetDWARFExpressionLength(),
- process->GetByteOrder(), process->GetAddressByteSize());
- ModuleSP opcode_ctx;
- DWARFExpression dwarfexpr (opcode_ctx,
- dwarfdata,
- nullptr,
- 0,
- row->GetCFAValue().GetDWARFExpressionLength());
- dwarfexpr.SetRegisterKind (row_register_kind);
- Value result;
- Error error;
- if (dwarfexpr.Evaluate (&exe_ctx, nullptr, nullptr, this, 0, nullptr, nullptr, result, &error))
- {
- cfa_value = result.GetScalar().ULongLong();
-
- UnwindLogMsg ("CFA value set by DWARF expression is 0x%" PRIx64, cfa_value);
- return true;
- }
- UnwindLogMsg ("Failed to set CFA value via DWARF expression: %s", error.AsCString());
- break;
- }
- default:
+ }
+ }
+ break;
+ }
+ case UnwindPlan::Row::CFAValue::isRegisterPlusOffset: {
+ RegisterNumber cfa_reg(m_thread, row_register_kind,
+ row->GetCFAValue().GetRegisterNumber());
+ if (ReadGPRValue(cfa_reg, cfa_reg_contents)) {
+ if (cfa_reg_contents == LLDB_INVALID_ADDRESS || cfa_reg_contents == 0 ||
+ cfa_reg_contents == 1) {
+ UnwindLogMsg(
+ "Got an invalid CFA register value - reg %s (%d), value 0x%" PRIx64,
+ cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB),
+ cfa_reg_contents);
+ cfa_reg_contents = LLDB_INVALID_ADDRESS;
return false;
- }
+ }
+ cfa_value = cfa_reg_contents + row->GetCFAValue().GetOffset();
+ UnwindLogMsg(
+ "CFA is 0x%" PRIx64 ": Register %s (%d) contents are 0x%" PRIx64
+ ", offset is %d",
+ cfa_value, cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB),
+ cfa_reg_contents, row->GetCFAValue().GetOffset());
+ return true;
+ }
+ break;
+ }
+ case UnwindPlan::Row::CFAValue::isDWARFExpression: {
+ ExecutionContext exe_ctx(m_thread.shared_from_this());
+ Process *process = exe_ctx.GetProcessPtr();
+ DataExtractor dwarfdata(row->GetCFAValue().GetDWARFExpressionBytes(),
+ row->GetCFAValue().GetDWARFExpressionLength(),
+ process->GetByteOrder(),
+ process->GetAddressByteSize());
+ ModuleSP opcode_ctx;
+ DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr, 0,
+ row->GetCFAValue().GetDWARFExpressionLength());
+ dwarfexpr.SetRegisterKind(row_register_kind);
+ Value result;
+ Error error;
+ if (dwarfexpr.Evaluate(&exe_ctx, nullptr, nullptr, this, 0, nullptr,
+ nullptr, result, &error)) {
+ cfa_value = result.GetScalar().ULongLong();
+
+ UnwindLogMsg("CFA value set by DWARF expression is 0x%" PRIx64,
+ cfa_value);
+ return true;
+ }
+ UnwindLogMsg("Failed to set CFA value via DWARF expression: %s",
+ error.AsCString());
+ break;
+ }
+ default:
return false;
+ }
+ return false;
}
-// Retrieve a general purpose register value for THIS frame, as saved by the NEXT frame, i.e. the frame that
+// Retrieve a general purpose register value for THIS frame, as saved by the
+// NEXT frame, i.e. the frame that
// this frame called. e.g.
//
// foo () { }
@@ -1866,278 +1859,241 @@ RegisterContextLLDB::ReadCFAValueForRow (lldb::RegisterKind row_register_kind,
// frame 0 - foo
// frame 1 - bar
// frame 2 - main
-// and this RegisterContext is for frame 1 (bar) - if we want to get the pc value for frame 1, we need to ask
+// and this RegisterContext is for frame 1 (bar) - if we want to get the pc
+// value for frame 1, we need to ask
// where frame 0 (the "next" frame) saved that and retrieve the value.
-bool
-RegisterContextLLDB::ReadGPRValue (lldb::RegisterKind register_kind, uint32_t regnum, addr_t &value)
-{
- if (!IsValid())
- return false;
-
- uint32_t lldb_regnum;
- if (register_kind == eRegisterKindLLDB)
- {
- lldb_regnum = regnum;
- }
- else if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (register_kind, regnum, eRegisterKindLLDB, lldb_regnum))
- {
- return false;
- }
+bool RegisterContextLLDB::ReadGPRValue(lldb::RegisterKind register_kind,
+ uint32_t regnum, addr_t &value) {
+ if (!IsValid())
+ return false;
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(lldb_regnum);
- RegisterValue reg_value;
- // if this is frame 0 (currently executing frame), get the requested reg contents from the actual thread registers
- if (IsFrameZero ())
- {
- if (m_thread.GetRegisterContext()->ReadRegister (reg_info, reg_value))
- {
- value = reg_value.GetAsUInt64();
- return true;
- }
- return false;
- }
+ uint32_t lldb_regnum;
+ if (register_kind == eRegisterKindLLDB) {
+ lldb_regnum = regnum;
+ } else if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds(
+ register_kind, regnum, eRegisterKindLLDB, lldb_regnum)) {
+ return false;
+ }
- bool pc_register = false;
- uint32_t generic_regnum;
- if (register_kind == eRegisterKindGeneric
- && (regnum == LLDB_REGNUM_GENERIC_PC || regnum == LLDB_REGNUM_GENERIC_RA))
- {
- pc_register = true;
- }
- else if (m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (register_kind, regnum, eRegisterKindGeneric, generic_regnum)
- && (generic_regnum == LLDB_REGNUM_GENERIC_PC || generic_regnum == LLDB_REGNUM_GENERIC_RA))
- {
- pc_register = true;
- }
-
- lldb_private::UnwindLLDB::RegisterLocation regloc;
- if (!m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1, pc_register))
- {
- return false;
- }
- if (ReadRegisterValueFromRegisterLocation (regloc, reg_info, reg_value))
- {
- value = reg_value.GetAsUInt64();
- return true;
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(lldb_regnum);
+ RegisterValue reg_value;
+ // if this is frame 0 (currently executing frame), get the requested reg
+ // contents from the actual thread registers
+ if (IsFrameZero()) {
+ if (m_thread.GetRegisterContext()->ReadRegister(reg_info, reg_value)) {
+ value = reg_value.GetAsUInt64();
+ return true;
}
return false;
+ }
+
+ bool pc_register = false;
+ uint32_t generic_regnum;
+ if (register_kind == eRegisterKindGeneric &&
+ (regnum == LLDB_REGNUM_GENERIC_PC || regnum == LLDB_REGNUM_GENERIC_RA)) {
+ pc_register = true;
+ } else if (m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds(
+ register_kind, regnum, eRegisterKindGeneric, generic_regnum) &&
+ (generic_regnum == LLDB_REGNUM_GENERIC_PC ||
+ generic_regnum == LLDB_REGNUM_GENERIC_RA)) {
+ pc_register = true;
+ }
+
+ lldb_private::UnwindLLDB::RegisterLocation regloc;
+ if (!m_parent_unwind.SearchForSavedLocationForRegister(
+ lldb_regnum, regloc, m_frame_number - 1, pc_register)) {
+ return false;
+ }
+ if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) {
+ value = reg_value.GetAsUInt64();
+ return true;
+ }
+ return false;
}
-bool
-RegisterContextLLDB::ReadGPRValue (const RegisterNumber &regnum, addr_t &value)
-{
- return ReadGPRValue (regnum.GetRegisterKind(), regnum.GetRegisterNumber(), value);
+bool RegisterContextLLDB::ReadGPRValue(const RegisterNumber &regnum,
+ addr_t &value) {
+ return ReadGPRValue(regnum.GetRegisterKind(), regnum.GetRegisterNumber(),
+ value);
}
// Find the value of a register in THIS frame
-bool
-RegisterContextLLDB::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value)
-{
- if (!IsValid())
- return false;
-
- const uint32_t lldb_regnum = reg_info->kinds[eRegisterKindLLDB];
- UnwindLogMsgVerbose ("looking for register saved location for reg %d", lldb_regnum);
-
- // If this is the 0th frame, hand this over to the live register context
- if (IsFrameZero ())
- {
- UnwindLogMsgVerbose ("passing along to the live register context for reg %d", lldb_regnum);
- return m_thread.GetRegisterContext()->ReadRegister (reg_info, value);
- }
-
- bool is_pc_regnum = false;
- if (reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_PC
- || reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_RA)
- {
- is_pc_regnum = true;
- }
+bool RegisterContextLLDB::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &value) {
+ if (!IsValid())
+ return false;
- lldb_private::UnwindLLDB::RegisterLocation regloc;
- // Find out where the NEXT frame saved THIS frame's register contents
- if (!m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1, is_pc_regnum))
- return false;
+ const uint32_t lldb_regnum = reg_info->kinds[eRegisterKindLLDB];
+ UnwindLogMsgVerbose("looking for register saved location for reg %d",
+ lldb_regnum);
+
+ // If this is the 0th frame, hand this over to the live register context
+ if (IsFrameZero()) {
+ UnwindLogMsgVerbose("passing along to the live register context for reg %d",
+ lldb_regnum);
+ return m_thread.GetRegisterContext()->ReadRegister(reg_info, value);
+ }
+
+ bool is_pc_regnum = false;
+ if (reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_PC ||
+ reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_RA) {
+ is_pc_regnum = true;
+ }
+
+ lldb_private::UnwindLLDB::RegisterLocation regloc;
+ // Find out where the NEXT frame saved THIS frame's register contents
+ if (!m_parent_unwind.SearchForSavedLocationForRegister(
+ lldb_regnum, regloc, m_frame_number - 1, is_pc_regnum))
+ return false;
- return ReadRegisterValueFromRegisterLocation (regloc, reg_info, value);
+ return ReadRegisterValueFromRegisterLocation(regloc, reg_info, value);
}
-bool
-RegisterContextLLDB::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &value)
-{
- if (!IsValid())
- return false;
-
- const uint32_t lldb_regnum = reg_info->kinds[eRegisterKindLLDB];
- UnwindLogMsgVerbose ("looking for register saved location for reg %d", lldb_regnum);
-
- // If this is the 0th frame, hand this over to the live register context
- if (IsFrameZero ())
- {
- UnwindLogMsgVerbose ("passing along to the live register context for reg %d", lldb_regnum);
- return m_thread.GetRegisterContext()->WriteRegister (reg_info, value);
- }
+bool RegisterContextLLDB::WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &value) {
+ if (!IsValid())
+ return false;
- lldb_private::UnwindLLDB::RegisterLocation regloc;
- // Find out where the NEXT frame saved THIS frame's register contents
- if (!m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1, false))
- return false;
+ const uint32_t lldb_regnum = reg_info->kinds[eRegisterKindLLDB];
+ UnwindLogMsgVerbose("looking for register saved location for reg %d",
+ lldb_regnum);
+
+ // If this is the 0th frame, hand this over to the live register context
+ if (IsFrameZero()) {
+ UnwindLogMsgVerbose("passing along to the live register context for reg %d",
+ lldb_regnum);
+ return m_thread.GetRegisterContext()->WriteRegister(reg_info, value);
+ }
+
+ lldb_private::UnwindLLDB::RegisterLocation regloc;
+ // Find out where the NEXT frame saved THIS frame's register contents
+ if (!m_parent_unwind.SearchForSavedLocationForRegister(
+ lldb_regnum, regloc, m_frame_number - 1, false))
+ return false;
- return WriteRegisterValueToRegisterLocation (regloc, reg_info, value);
+ return WriteRegisterValueToRegisterLocation(regloc, reg_info, value);
}
// Don't need to implement this one
-bool
-RegisterContextLLDB::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextLLDB::ReadAllRegisterValues(lldb::DataBufferSP &data_sp) {
+ return false;
}
// Don't need to implement this one
-bool
-RegisterContextLLDB::WriteAllRegisterValues (const lldb::DataBufferSP& data_sp)
-{
- return false;
+bool RegisterContextLLDB::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ return false;
}
// Retrieve the pc value for THIS from
-bool
-RegisterContextLLDB::GetCFA (addr_t& cfa)
-{
- if (!IsValid())
- {
- return false;
- }
- if (m_cfa == LLDB_INVALID_ADDRESS)
- {
- return false;
- }
- cfa = m_cfa;
- return true;
+bool RegisterContextLLDB::GetCFA(addr_t &cfa) {
+ if (!IsValid()) {
+ return false;
+ }
+ if (m_cfa == LLDB_INVALID_ADDRESS) {
+ return false;
+ }
+ cfa = m_cfa;
+ return true;
}
-
-RegisterContextLLDB::SharedPtr
-RegisterContextLLDB::GetNextFrame () const
-{
- RegisterContextLLDB::SharedPtr regctx;
- if (m_frame_number == 0)
- return regctx;
- return m_parent_unwind.GetRegisterContextForFrameNum (m_frame_number - 1);
+RegisterContextLLDB::SharedPtr RegisterContextLLDB::GetNextFrame() const {
+ RegisterContextLLDB::SharedPtr regctx;
+ if (m_frame_number == 0)
+ return regctx;
+ return m_parent_unwind.GetRegisterContextForFrameNum(m_frame_number - 1);
}
-RegisterContextLLDB::SharedPtr
-RegisterContextLLDB::GetPrevFrame () const
-{
- RegisterContextLLDB::SharedPtr regctx;
- return m_parent_unwind.GetRegisterContextForFrameNum (m_frame_number + 1);
+RegisterContextLLDB::SharedPtr RegisterContextLLDB::GetPrevFrame() const {
+ RegisterContextLLDB::SharedPtr regctx;
+ return m_parent_unwind.GetRegisterContextForFrameNum(m_frame_number + 1);
}
// Retrieve the address of the start of the function of THIS frame
-bool
-RegisterContextLLDB::GetStartPC (addr_t& start_pc)
-{
- if (!IsValid())
- return false;
+bool RegisterContextLLDB::GetStartPC(addr_t &start_pc) {
+ if (!IsValid())
+ return false;
- if (!m_start_pc.IsValid())
- {
- return ReadPC (start_pc);
- }
- start_pc = m_start_pc.GetLoadAddress (CalculateTarget().get());
- return true;
+ if (!m_start_pc.IsValid()) {
+ return ReadPC(start_pc);
+ }
+ start_pc = m_start_pc.GetLoadAddress(CalculateTarget().get());
+ return true;
}
// Retrieve the current pc value for THIS frame, as saved by the NEXT frame.
-bool
-RegisterContextLLDB::ReadPC (addr_t& pc)
-{
- if (!IsValid())
- return false;
-
- bool above_trap_handler = false;
- if (GetNextFrame().get() && GetNextFrame()->IsValid() && GetNextFrame()->IsTrapHandlerFrame())
- above_trap_handler = true;
+bool RegisterContextLLDB::ReadPC(addr_t &pc) {
+ if (!IsValid())
+ return false;
- if (ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc))
- {
- // A pc value of 0 or 1 is impossible in the middle of the stack -- it indicates the end of a stack walk.
- // On the currently executing frame (or such a frame interrupted asynchronously by sigtramp et al) this may
- // occur if code has jumped through a NULL pointer -- we want to be able to unwind past that frame to help
- // find the bug.
-
- if (m_all_registers_available == false
- && above_trap_handler == false
- && (pc == 0 || pc == 1))
- {
- return false;
- }
- else
- {
- return true;
- }
- }
- else
- {
- return false;
- }
+ bool above_trap_handler = false;
+ if (GetNextFrame().get() && GetNextFrame()->IsValid() &&
+ GetNextFrame()->IsTrapHandlerFrame())
+ above_trap_handler = true;
+
+ if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc)) {
+ // A pc value of 0 or 1 is impossible in the middle of the stack -- it
+ // indicates the end of a stack walk.
+ // On the currently executing frame (or such a frame interrupted
+ // asynchronously by sigtramp et al) this may
+ // occur if code has jumped through a NULL pointer -- we want to be able to
+ // unwind past that frame to help
+ // find the bug.
+
+ if (m_all_registers_available == false && above_trap_handler == false &&
+ (pc == 0 || pc == 1)) {
+ return false;
+ } else {
+ return true;
+ }
+ } else {
+ return false;
+ }
}
-
-void
-RegisterContextLLDB::UnwindLogMsg (const char *fmt, ...)
-{
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
- if (log)
- {
- va_list args;
- va_start (args, fmt);
-
- char *logmsg;
- if (vasprintf (&logmsg, fmt, args) == -1 || logmsg == NULL)
- {
- if (logmsg)
- free (logmsg);
- va_end (args);
- return;
- }
- va_end (args);
-
- log->Printf ("%*sth%d/fr%u %s",
- m_frame_number < 100 ? m_frame_number : 100, "", m_thread.GetIndexID(), m_frame_number,
- logmsg);
- free (logmsg);
- }
+void RegisterContextLLDB::UnwindLogMsg(const char *fmt, ...) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
+ if (log) {
+ va_list args;
+ va_start(args, fmt);
+
+ char *logmsg;
+ if (vasprintf(&logmsg, fmt, args) == -1 || logmsg == NULL) {
+ if (logmsg)
+ free(logmsg);
+ va_end(args);
+ return;
+ }
+ va_end(args);
+
+ log->Printf("%*sth%d/fr%u %s", m_frame_number < 100 ? m_frame_number : 100,
+ "", m_thread.GetIndexID(), m_frame_number, logmsg);
+ free(logmsg);
+ }
}
-void
-RegisterContextLLDB::UnwindLogMsgVerbose (const char *fmt, ...)
-{
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
- if (log && log->GetVerbose())
- {
- va_list args;
- va_start (args, fmt);
-
- char *logmsg;
- if (vasprintf (&logmsg, fmt, args) == -1 || logmsg == NULL)
- {
- if (logmsg)
- free (logmsg);
- va_end (args);
- return;
- }
- va_end (args);
-
- log->Printf ("%*sth%d/fr%u %s",
- m_frame_number < 100 ? m_frame_number : 100, "", m_thread.GetIndexID(), m_frame_number,
- logmsg);
- free (logmsg);
- }
+void RegisterContextLLDB::UnwindLogMsgVerbose(const char *fmt, ...) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
+ if (log && log->GetVerbose()) {
+ va_list args;
+ va_start(args, fmt);
+
+ char *logmsg;
+ if (vasprintf(&logmsg, fmt, args) == -1 || logmsg == NULL) {
+ if (logmsg)
+ free(logmsg);
+ va_end(args);
+ return;
+ }
+ va_end(args);
+
+ log->Printf("%*sth%d/fr%u %s", m_frame_number < 100 ? m_frame_number : 100,
+ "", m_thread.GetIndexID(), m_frame_number, logmsg);
+ free(logmsg);
+ }
}
-
-
diff --git a/source/Plugins/Process/Utility/RegisterContextLLDB.h b/source/Plugins/Process/Utility/RegisterContextLLDB.h
index 68dca3d4965f..cb22eedd560a 100644
--- a/source/Plugins/Process/Utility/RegisterContextLLDB.h
+++ b/source/Plugins/Process/Utility/RegisterContextLLDB.h
@@ -1,4 +1,5 @@
-//===-- RegisterContextLLDB.h --------------------------------------------*- C++ -*-===//
+//===-- RegisterContextLLDB.h --------------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,253 +17,247 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Symbol/UnwindPlan.h"
+#include "UnwindLLDB.h"
#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Symbol/UnwindPlan.h"
+#include "lldb/Target/RegisterContext.h"
#include "lldb/Utility/RegisterNumber.h"
-#include "UnwindLLDB.h"
+#include "lldb/lldb-private.h"
namespace lldb_private {
class UnwindLLDB;
-class RegisterContextLLDB : public lldb_private::RegisterContext
-{
+class RegisterContextLLDB : public lldb_private::RegisterContext {
public:
- typedef std::shared_ptr<RegisterContextLLDB> SharedPtr;
+ typedef std::shared_ptr<RegisterContextLLDB> SharedPtr;
- RegisterContextLLDB (lldb_private::Thread &thread,
- const SharedPtr& next_frame,
- lldb_private::SymbolContext& sym_ctx,
- uint32_t frame_number, lldb_private::UnwindLLDB& unwind_lldb);
+ RegisterContextLLDB(lldb_private::Thread &thread, const SharedPtr &next_frame,
+ lldb_private::SymbolContext &sym_ctx,
+ uint32_t frame_number,
+ lldb_private::UnwindLLDB &unwind_lldb);
- ~RegisterContextLLDB() override = default;
+ ~RegisterContextLLDB() override = default;
- void
- InvalidateAllRegisters() override;
+ void InvalidateAllRegisters() override;
- size_t
- GetRegisterCount() override;
+ size_t GetRegisterCount() override;
- const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex(size_t reg) override;
+ const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
- size_t
- GetRegisterSetCount() override;
+ size_t GetRegisterSetCount() override;
- const lldb_private::RegisterSet *
- GetRegisterSet(size_t reg_set) override;
+ const lldb_private::RegisterSet *GetRegisterSet(size_t reg_set) override;
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value) override;
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) override;
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value) override;
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) override;
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- uint32_t
- ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
- bool
- IsValid () const;
+ bool IsValid() const;
- bool
- IsTrapHandlerFrame () const;
+ bool IsTrapHandlerFrame() const;
- bool
- GetCFA (lldb::addr_t& cfa);
+ bool GetCFA(lldb::addr_t &cfa);
- bool
- GetStartPC (lldb::addr_t& start_pc);
+ bool GetStartPC(lldb::addr_t &start_pc);
- bool
- ReadPC (lldb::addr_t& start_pc);
+ bool ReadPC(lldb::addr_t &start_pc);
private:
-
- enum FrameType
- {
- eNormalFrame,
- eTrapHandlerFrame,
- eDebuggerFrame, // a debugger inferior function call frame; we get caller's registers from debugger
- eSkipFrame, // The unwind resulted in a bogus frame but may get back on track so we don't want to give up yet
- eNotAValidFrame // this frame is invalid for some reason - most likely it is past the top (end) of the stack
- };
-
- // UnwindLLDB needs to pass around references to RegisterLocations
- friend class UnwindLLDB;
-
- // Returns true if we have an unwind loop -- the same stack frame unwinding
- // multiple times.
- bool
- CheckIfLoopingStack ();
-
- // Indicates whether this frame is frame zero -- the currently
- // executing frame -- or not.
- bool
- IsFrameZero () const;
-
- void
- InitializeZerothFrame ();
-
- void
- InitializeNonZerothFrame();
-
- SharedPtr
- GetNextFrame () const;
-
- SharedPtr
- GetPrevFrame () const;
-
- // A SkipFrame occurs when the unwind out of frame 0 didn't go right -- we've got one bogus frame at frame #1.
- // There is a good chance we'll get back on track if we follow the frame pointer chain (or whatever is appropriate
- // on this ABI) so we allow one invalid frame to be in the stack. Ideally we'll mark this frame specially at some
- // point and indicate to the user that the unwinder had a hiccup. Often when this happens we will miss a frame of
- // the program's actual stack in the unwind and we want to flag that for the user somehow.
- bool
- IsSkipFrame () const;
-
- //------------------------------------------------------------------
- /// Determines if a SymbolContext is a trap handler or not
- ///
- /// Given a SymbolContext, determines if this is a trap handler function
- /// aka asynchronous signal handler.
- ///
- /// @return
- /// Returns true if the SymbolContext is a trap handler.
- //------------------------------------------------------------------
- bool
- IsTrapHandlerSymbol (lldb_private::Process *process, const lldb_private::SymbolContext &m_sym_ctx) const;
-
- // Provide a location for where THIS function saved the CALLER's register value
- // Or a frame "below" this one saved it, i.e. a function called by this one, preserved a register that this
- // function didn't modify/use.
- //
- // The RegisterLocation type may be set to eRegisterNotAvailable -- this will happen for a volatile register
- // being queried mid-stack. Instead of floating frame 0's contents of that register up the stack (which may
- // or may not be the value of that reg when the function was executing), we won't return any value.
- //
- // If a non-volatile register (a "preserved" register) is requested mid-stack and no frames "below" the requested
- // stack have saved the register anywhere, it is safe to assume that frame 0's register values are still the same
- // as the requesting frame's.
- lldb_private::UnwindLLDB::RegisterSearchResult
- SavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc);
-
- bool
- ReadRegisterValueFromRegisterLocation (lldb_private::UnwindLLDB::RegisterLocation regloc,
- const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value);
-
- bool
- WriteRegisterValueToRegisterLocation (lldb_private::UnwindLLDB::RegisterLocation regloc,
- const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value);
-
- //------------------------------------------------------------------
- /// If the unwind has to the caller frame has failed, try something else
- ///
- /// If lldb is using an assembly language based UnwindPlan for a frame and
- /// the unwind to the caller frame fails, try falling back to a generic
- /// UnwindPlan (architecture default unwindplan) to see if that might work
- /// better. This is mostly helping to work around problems where the
- /// assembly language inspection fails on hand-written assembly code.
- ///
- /// @return
- /// Returns true if a fallback unwindplan was found & was installed.
- //------------------------------------------------------------------
- bool
- TryFallbackUnwindPlan ();
-
- //------------------------------------------------------------------
- /// Switch to the fallback unwind plan unconditionally without any safety
- /// checks that it is providing better results than the normal unwind plan.
- ///
- /// The only time it is valid to call this method is if the full unwindplan is
- /// found to be fundamentally incorrect/impossible.
- ///
- /// Returns true if it was able to install the fallback unwind plan.
- //------------------------------------------------------------------
- bool
- ForceSwitchToFallbackUnwindPlan ();
-
- // Get the contents of a general purpose (address-size) register for this frame
- // (usually retrieved from the next frame)
- bool
- ReadGPRValue (lldb::RegisterKind register_kind, uint32_t regnum, lldb::addr_t &value);
-
- bool
- ReadGPRValue (const RegisterNumber &reg_num, lldb::addr_t &value);
-
- // Get the CFA register for a given frame.
- bool
- ReadCFAValueForRow (lldb::RegisterKind register_kind, const UnwindPlan::RowSP &row, lldb::addr_t &value);
-
- lldb::UnwindPlanSP
- GetFastUnwindPlanForFrame ();
-
- lldb::UnwindPlanSP
- GetFullUnwindPlanForFrame ();
-
- void
- UnwindLogMsg (const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
-
- void
- UnwindLogMsgVerbose (const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
-
- bool
- IsUnwindPlanValidForCurrentPC(lldb::UnwindPlanSP unwind_plan_sp, int &valid_pc_offset);
-
- lldb_private::Thread& m_thread;
-
- ///
- // The following tell us how to retrieve the CALLER's register values (ie the "previous" frame, aka the frame above)
- // i.e. where THIS frame saved them
- ///
-
- lldb::UnwindPlanSP m_fast_unwind_plan_sp; // may be NULL
- lldb::UnwindPlanSP m_full_unwind_plan_sp;
- lldb::UnwindPlanSP m_fallback_unwind_plan_sp; // may be NULL
-
- bool m_all_registers_available; // Can we retrieve all regs or just nonvolatile regs?
- int m_frame_type; // enum FrameType
-
- lldb::addr_t m_cfa;
- lldb_private::Address m_start_pc;
- lldb_private::Address m_current_pc;
-
- int m_current_offset; // how far into the function we've executed; -1 if unknown
- // 0 if no instructions have been executed yet.
-
- int m_current_offset_backed_up_one; // how far into the function we've executed; -1 if unknown
- // 0 if no instructions have been executed yet.
- // On architectures where the return address on the stack points
- // to the instruction after the CALL, this value will have 1
- // subtracted from it. Else a function that ends in a CALL will
- // have an offset pointing into the next function's address range.
- // m_current_pc has the actual address of the "current" pc.
-
- lldb_private::SymbolContext& m_sym_ctx;
- bool m_sym_ctx_valid; // if ResolveSymbolContextForAddress fails, don't try to use m_sym_ctx
-
- uint32_t m_frame_number; // What stack frame this RegisterContext is
-
- std::map<uint32_t, lldb_private::UnwindLLDB::RegisterLocation> m_registers; // where to find reg values for this frame
-
- lldb_private::UnwindLLDB& m_parent_unwind; // The UnwindLLDB that is creating this RegisterContextLLDB
-
- //------------------------------------------------------------------
- // For RegisterContextLLDB only
- //------------------------------------------------------------------
-
- DISALLOW_COPY_AND_ASSIGN (RegisterContextLLDB);
+ enum FrameType {
+ eNormalFrame,
+ eTrapHandlerFrame,
+ eDebuggerFrame, // a debugger inferior function call frame; we get caller's
+ // registers from debugger
+ eSkipFrame, // The unwind resulted in a bogus frame but may get back on
+ // track so we don't want to give up yet
+ eNotAValidFrame // this frame is invalid for some reason - most likely it is
+ // past the top (end) of the stack
+ };
+
+ // UnwindLLDB needs to pass around references to RegisterLocations
+ friend class UnwindLLDB;
+
+ // Returns true if we have an unwind loop -- the same stack frame unwinding
+ // multiple times.
+ bool CheckIfLoopingStack();
+
+ // Indicates whether this frame is frame zero -- the currently
+ // executing frame -- or not.
+ bool IsFrameZero() const;
+
+ void InitializeZerothFrame();
+
+ void InitializeNonZerothFrame();
+
+ SharedPtr GetNextFrame() const;
+
+ SharedPtr GetPrevFrame() const;
+
+ // A SkipFrame occurs when the unwind out of frame 0 didn't go right -- we've
+ // got one bogus frame at frame #1.
+ // There is a good chance we'll get back on track if we follow the frame
+ // pointer chain (or whatever is appropriate
+ // on this ABI) so we allow one invalid frame to be in the stack. Ideally
+ // we'll mark this frame specially at some
+ // point and indicate to the user that the unwinder had a hiccup. Often when
+ // this happens we will miss a frame of
+ // the program's actual stack in the unwind and we want to flag that for the
+ // user somehow.
+ bool IsSkipFrame() const;
+
+ //------------------------------------------------------------------
+ /// Determines if a SymbolContext is a trap handler or not
+ ///
+ /// Given a SymbolContext, determines if this is a trap handler function
+ /// aka asynchronous signal handler.
+ ///
+ /// @return
+ /// Returns true if the SymbolContext is a trap handler.
+ //------------------------------------------------------------------
+ bool IsTrapHandlerSymbol(lldb_private::Process *process,
+ const lldb_private::SymbolContext &m_sym_ctx) const;
+
+ // Provide a location for where THIS function saved the CALLER's register
+ // value
+ // Or a frame "below" this one saved it, i.e. a function called by this one,
+ // preserved a register that this
+ // function didn't modify/use.
+ //
+ // The RegisterLocation type may be set to eRegisterNotAvailable -- this will
+ // happen for a volatile register
+ // being queried mid-stack. Instead of floating frame 0's contents of that
+ // register up the stack (which may
+ // or may not be the value of that reg when the function was executing), we
+ // won't return any value.
+ //
+ // If a non-volatile register (a "preserved" register) is requested mid-stack
+ // and no frames "below" the requested
+ // stack have saved the register anywhere, it is safe to assume that frame 0's
+ // register values are still the same
+ // as the requesting frame's.
+ lldb_private::UnwindLLDB::RegisterSearchResult
+ SavedLocationForRegister(uint32_t lldb_regnum,
+ lldb_private::UnwindLLDB::RegisterLocation &regloc);
+
+ bool ReadRegisterValueFromRegisterLocation(
+ lldb_private::UnwindLLDB::RegisterLocation regloc,
+ const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value);
+
+ bool WriteRegisterValueToRegisterLocation(
+ lldb_private::UnwindLLDB::RegisterLocation regloc,
+ const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value);
+
+ //------------------------------------------------------------------
+ /// If the unwind has to the caller frame has failed, try something else
+ ///
+ /// If lldb is using an assembly language based UnwindPlan for a frame and
+ /// the unwind to the caller frame fails, try falling back to a generic
+ /// UnwindPlan (architecture default unwindplan) to see if that might work
+ /// better. This is mostly helping to work around problems where the
+ /// assembly language inspection fails on hand-written assembly code.
+ ///
+ /// @return
+ /// Returns true if a fallback unwindplan was found & was installed.
+ //------------------------------------------------------------------
+ bool TryFallbackUnwindPlan();
+
+ //------------------------------------------------------------------
+ /// Switch to the fallback unwind plan unconditionally without any safety
+ /// checks that it is providing better results than the normal unwind plan.
+ ///
+ /// The only time it is valid to call this method is if the full unwindplan is
+ /// found to be fundamentally incorrect/impossible.
+ ///
+ /// Returns true if it was able to install the fallback unwind plan.
+ //------------------------------------------------------------------
+ bool ForceSwitchToFallbackUnwindPlan();
+
+ // Get the contents of a general purpose (address-size) register for this
+ // frame
+ // (usually retrieved from the next frame)
+ bool ReadGPRValue(lldb::RegisterKind register_kind, uint32_t regnum,
+ lldb::addr_t &value);
+
+ bool ReadGPRValue(const RegisterNumber &reg_num, lldb::addr_t &value);
+
+ // Get the CFA register for a given frame.
+ bool ReadCFAValueForRow(lldb::RegisterKind register_kind,
+ const UnwindPlan::RowSP &row, lldb::addr_t &value);
+
+ lldb::UnwindPlanSP GetFastUnwindPlanForFrame();
+
+ lldb::UnwindPlanSP GetFullUnwindPlanForFrame();
+
+ void UnwindLogMsg(const char *fmt, ...) __attribute__((format(printf, 2, 3)));
+
+ void UnwindLogMsgVerbose(const char *fmt, ...)
+ __attribute__((format(printf, 2, 3)));
+
+ bool IsUnwindPlanValidForCurrentPC(lldb::UnwindPlanSP unwind_plan_sp,
+ int &valid_pc_offset);
+
+ lldb_private::Thread &m_thread;
+
+ ///
+ // The following tell us how to retrieve the CALLER's register values (ie the
+ // "previous" frame, aka the frame above)
+ // i.e. where THIS frame saved them
+ ///
+
+ lldb::UnwindPlanSP m_fast_unwind_plan_sp; // may be NULL
+ lldb::UnwindPlanSP m_full_unwind_plan_sp;
+ lldb::UnwindPlanSP m_fallback_unwind_plan_sp; // may be NULL
+
+ bool m_all_registers_available; // Can we retrieve all regs or just
+ // nonvolatile regs?
+ int m_frame_type; // enum FrameType
+
+ lldb::addr_t m_cfa;
+ lldb_private::Address m_start_pc;
+ lldb_private::Address m_current_pc;
+
+ int m_current_offset; // how far into the function we've executed; -1 if
+ // unknown
+ // 0 if no instructions have been executed yet.
+
+ int m_current_offset_backed_up_one; // how far into the function we've
+ // executed; -1 if unknown
+ // 0 if no instructions have been executed yet.
+ // On architectures where the return address on the stack points
+ // to the instruction after the CALL, this value will have 1
+ // subtracted from it. Else a function that ends in a CALL will
+ // have an offset pointing into the next function's address range.
+ // m_current_pc has the actual address of the "current" pc.
+
+ lldb_private::SymbolContext &m_sym_ctx;
+ bool m_sym_ctx_valid; // if ResolveSymbolContextForAddress fails, don't try to
+ // use m_sym_ctx
+
+ uint32_t m_frame_number; // What stack frame this RegisterContext is
+
+ std::map<uint32_t, lldb_private::UnwindLLDB::RegisterLocation>
+ m_registers; // where to find reg values for this frame
+
+ lldb_private::UnwindLLDB &m_parent_unwind; // The UnwindLLDB that is creating
+ // this RegisterContextLLDB
+
+ //------------------------------------------------------------------
+ // For RegisterContextLLDB only
+ //------------------------------------------------------------------
+
+ DISALLOW_COPY_AND_ASSIGN(RegisterContextLLDB);
};
} // namespace lldb_private
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_arm.cpp b/source/Plugins/Process/Utility/RegisterContextLinux_arm.cpp
index a4d8738d79bf..afa105f25404 100644
--- a/source/Plugins/Process/Utility/RegisterContextLinux_arm.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_arm.cpp
@@ -7,12 +7,12 @@
//
//===---------------------------------------------------------------------===//
+#include <cassert>
#include <stddef.h>
#include <vector>
-#include <cassert>
-#include "llvm/Support/Compiler.h"
#include "lldb/lldb-defines.h"
+#include "llvm/Support/Compiler.h"
#include "RegisterContextLinux_arm.h"
@@ -20,14 +20,31 @@ using namespace lldb;
using namespace lldb_private;
// Based on RegisterContextDarwin_arm.cpp
-#define GPR_OFFSET(idx) ((idx) * 4)
-#define FPU_OFFSET(idx) ((idx) * 4 + sizeof (RegisterContextLinux_arm::GPR))
-#define FPSCR_OFFSET (LLVM_EXTENSION offsetof (RegisterContextLinux_arm::FPU, fpscr) + sizeof (RegisterContextLinux_arm::GPR))
-#define EXC_OFFSET(idx) ((idx) * 4 + sizeof (RegisterContextLinux_arm::GPR) + sizeof (RegisterContextLinux_arm::FPU))
-#define DBG_OFFSET(reg) ((LLVM_EXTENSION offsetof (RegisterContextLinux_arm::DBG, reg) + sizeof (RegisterContextLinux_arm::GPR) + sizeof (RegisterContextLinux_arm::FPU) + sizeof (RegisterContextLinux_arm::EXC)))
+#define GPR_OFFSET(idx) ((idx)*4)
+#define FPU_OFFSET(idx) ((idx)*4 + sizeof(RegisterContextLinux_arm::GPR))
+#define FPSCR_OFFSET \
+ (LLVM_EXTENSION offsetof(RegisterContextLinux_arm::FPU, fpscr) + \
+ sizeof(RegisterContextLinux_arm::GPR))
+#define EXC_OFFSET(idx) \
+ ((idx)*4 + sizeof(RegisterContextLinux_arm::GPR) + \
+ sizeof(RegisterContextLinux_arm::FPU))
+#define DBG_OFFSET(reg) \
+ ((LLVM_EXTENSION offsetof(RegisterContextLinux_arm::DBG, reg) + \
+ sizeof(RegisterContextLinux_arm::GPR) + \
+ sizeof(RegisterContextLinux_arm::FPU) + \
+ sizeof(RegisterContextLinux_arm::EXC)))
-#define DEFINE_DBG(reg, i) #reg, NULL, sizeof(((RegisterContextLinux_arm::DBG *)NULL)->reg[i]), DBG_OFFSET(reg[i]), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, dbg_##reg##i }, NULL, NULL, NULL, 0
-#define REG_CONTEXT_SIZE (sizeof (RegisterContextLinux_arm::GPR) + sizeof (RegisterContextLinux_arm::FPU) + sizeof (RegisterContextLinux_arm::EXC))
+#define DEFINE_DBG(reg, i) \
+ #reg, NULL, sizeof(((RegisterContextLinux_arm::DBG *) NULL)->reg[i]), \
+ DBG_OFFSET(reg[i]), eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ dbg_##reg##i }, \
+ NULL, NULL, NULL, 0
+#define REG_CONTEXT_SIZE \
+ (sizeof(RegisterContextLinux_arm::GPR) + \
+ sizeof(RegisterContextLinux_arm::FPU) + \
+ sizeof(RegisterContextLinux_arm::EXC))
//-----------------------------------------------------------------------------
// Include RegisterInfos_arm to declare our g_register_infos_arm structure.
@@ -37,52 +54,43 @@ using namespace lldb_private;
#undef DECLARE_REGISTER_INFOS_ARM_STRUCT
static const lldb_private::RegisterInfo *
-GetRegisterInfoPtr (const lldb_private::ArchSpec &target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::arm:
- return g_register_infos_arm;
- default:
- assert(false && "Unhandled target architecture.");
- return NULL;
- }
+GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::arm:
+ return g_register_infos_arm;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return NULL;
+ }
}
static uint32_t
-GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::arm:
- return static_cast<uint32_t>(sizeof(g_register_infos_arm) / sizeof(g_register_infos_arm[0]));
- default:
- assert(false && "Unhandled target architecture.");
- return 0;
- }
+GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::arm:
+ return static_cast<uint32_t>(sizeof(g_register_infos_arm) /
+ sizeof(g_register_infos_arm[0]));
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
}
-RegisterContextLinux_arm::RegisterContextLinux_arm(const lldb_private::ArchSpec &target_arch) :
- lldb_private::RegisterInfoInterface(target_arch),
- m_register_info_p(GetRegisterInfoPtr(target_arch)),
- m_register_info_count(GetRegisterInfoCount(target_arch))
-{
-}
+RegisterContextLinux_arm::RegisterContextLinux_arm(
+ const lldb_private::ArchSpec &target_arch)
+ : lldb_private::RegisterInfoInterface(target_arch),
+ m_register_info_p(GetRegisterInfoPtr(target_arch)),
+ m_register_info_count(GetRegisterInfoCount(target_arch)) {}
-size_t
-RegisterContextLinux_arm::GetGPRSize() const
-{
- return sizeof(struct RegisterContextLinux_arm::GPR);
+size_t RegisterContextLinux_arm::GetGPRSize() const {
+ return sizeof(struct RegisterContextLinux_arm::GPR);
}
const lldb_private::RegisterInfo *
-RegisterContextLinux_arm::GetRegisterInfo() const
-{
- return m_register_info_p;
+RegisterContextLinux_arm::GetRegisterInfo() const {
+ return m_register_info_p;
}
-uint32_t
-RegisterContextLinux_arm::GetRegisterCount() const
-{
- return m_register_info_count;
+uint32_t RegisterContextLinux_arm::GetRegisterCount() const {
+ return m_register_info_count;
}
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_arm.h b/source/Plugins/Process/Utility/RegisterContextLinux_arm.h
index c3d41f686dcd..9065bc0e08d2 100644
--- a/source/Plugins/Process/Utility/RegisterContextLinux_arm.h
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_arm.h
@@ -10,66 +10,53 @@
#ifndef liblldb_RegisterContextLinux_arm_h_
#define liblldb_RegisterContextLinux_arm_h_
-#include "lldb/lldb-private.h"
-#include "lldb/Target/RegisterContext.h"
#include "RegisterInfoInterface.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/lldb-private.h"
-class RegisterContextLinux_arm
- : public lldb_private::RegisterInfoInterface
-{
+class RegisterContextLinux_arm : public lldb_private::RegisterInfoInterface {
public:
-
- struct GPR
- {
- uint32_t r[16]; // R0-R15
- uint32_t cpsr; // CPSR
- };
-
-
- struct QReg
- {
- uint8_t bytes[16];
- };
-
- struct FPU
- {
- union {
- uint32_t s[32];
- uint64_t d[32];
- QReg q[16]; // the 128-bit NEON registers
- } floats;
- uint32_t fpscr;
- };
- struct EXC
- {
- uint32_t exception;
- uint32_t fsr; /* Fault status */
- uint32_t far; /* Virtual Fault Address */
- };
-
- struct DBG
- {
- uint32_t bvr[16];
- uint32_t bcr[16];
- uint32_t wvr[16];
- uint32_t wcr[16];
- };
-
- RegisterContextLinux_arm(const lldb_private::ArchSpec &target_arch);
-
- size_t
- GetGPRSize() const override;
-
- const lldb_private::RegisterInfo *
- GetRegisterInfo() const override;
-
- uint32_t
- GetRegisterCount () const override;
+ struct GPR {
+ uint32_t r[16]; // R0-R15
+ uint32_t cpsr; // CPSR
+ };
+
+ struct QReg {
+ uint8_t bytes[16];
+ };
+
+ struct FPU {
+ union {
+ uint32_t s[32];
+ uint64_t d[32];
+ QReg q[16]; // the 128-bit NEON registers
+ } floats;
+ uint32_t fpscr;
+ };
+ struct EXC {
+ uint32_t exception;
+ uint32_t fsr; /* Fault status */
+ uint32_t far; /* Virtual Fault Address */
+ };
+
+ struct DBG {
+ uint32_t bvr[16];
+ uint32_t bcr[16];
+ uint32_t wvr[16];
+ uint32_t wcr[16];
+ };
+
+ RegisterContextLinux_arm(const lldb_private::ArchSpec &target_arch);
+
+ size_t GetGPRSize() const override;
+
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
+
+ uint32_t GetRegisterCount() const override;
private:
- const lldb_private::RegisterInfo *m_register_info_p;
- uint32_t m_register_info_count;
+ const lldb_private::RegisterInfo *m_register_info_p;
+ uint32_t m_register_info_count;
};
-#endif // liblldb_RegisterContextLinux_arm_h_
-
+#endif // liblldb_RegisterContextLinux_arm_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_arm64.cpp b/source/Plugins/Process/Utility/RegisterContextLinux_arm64.cpp
deleted file mode 100644
index e65537af729a..000000000000
--- a/source/Plugins/Process/Utility/RegisterContextLinux_arm64.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-//===-- RegisterContextLinux_arm64.cpp -------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===---------------------------------------------------------------------===//
-
-#include <stddef.h>
-#include <vector>
-#include <cassert>
-
-#include "llvm/Support/Compiler.h"
-#include "lldb/lldb-defines.h"
-
-#include "RegisterContextLinux_arm64.h"
-
-// Based on RegisterContextDarwin_arm64.cpp
-#define GPR_OFFSET(idx) ((idx) * 8)
-#define GPR_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextLinux_arm64::GPR, reg))
-
-#define FPU_OFFSET(idx) ((idx) * 16 + sizeof (RegisterContextLinux_arm64::GPR))
-#define FPU_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextLinux_arm64::FPU, reg) + sizeof (RegisterContextLinux_arm64::GPR))
-
-#define EXC_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextLinux_arm64::EXC, reg) + sizeof (RegisterContextLinux_arm64::GPR) + sizeof (RegisterContextLinux_arm64::FPU))
-#define DBG_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextLinux_arm64::DBG, reg) + sizeof (RegisterContextLinux_arm64::GPR) + sizeof (RegisterContextLinux_arm64::FPU) + sizeof (RegisterContextLinux_arm64::EXC))
-
-#define DEFINE_DBG(reg, i) #reg, NULL, sizeof(((RegisterContextLinux_arm64::DBG *)NULL)->reg[i]), DBG_OFFSET_NAME(reg[i]), lldb::eEncodingUint, lldb::eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, dbg_##reg##i }, NULL, NULL, NULL, 0
-#define REG_CONTEXT_SIZE (sizeof (RegisterContextLinux_arm64::GPR) + sizeof (RegisterContextLinux_arm64::FPU) + sizeof (RegisterContextLinux_arm64::EXC))
-
-
-//-----------------------------------------------------------------------------
-// Include RegisterInfos_arm64 to declare our g_register_infos_arm64 structure.
-//-----------------------------------------------------------------------------
-#define DECLARE_REGISTER_INFOS_ARM64_STRUCT
-#include "RegisterInfos_arm64.h"
-#undef DECLARE_REGISTER_INFOS_ARM64_STRUCT
-
-static const lldb_private::RegisterInfo *
-GetRegisterInfoPtr (const lldb_private::ArchSpec &target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::aarch64:
- return g_register_infos_arm64;
- default:
- assert(false && "Unhandled target architecture.");
- return NULL;
- }
-}
-
-static uint32_t
-GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::aarch64:
- return static_cast<uint32_t>(sizeof(g_register_infos_arm64) / sizeof(g_register_infos_arm64[0]));
- default:
- assert(false && "Unhandled target architecture.");
- return 0;
- }
-}
-
-RegisterContextLinux_arm64::RegisterContextLinux_arm64(const lldb_private::ArchSpec &target_arch) :
- lldb_private::RegisterInfoInterface(target_arch),
- m_register_info_p(GetRegisterInfoPtr(target_arch)),
- m_register_info_count(GetRegisterInfoCount(target_arch))
-{
-}
-
-size_t
-RegisterContextLinux_arm64::GetGPRSize() const
-{
- return sizeof(struct RegisterContextLinux_arm64::GPR);
-}
-
-const lldb_private::RegisterInfo *
-RegisterContextLinux_arm64::GetRegisterInfo() const
-{
- return m_register_info_p;
-}
-
-uint32_t
-RegisterContextLinux_arm64::GetRegisterCount() const
-{
- return m_register_info_count;
-}
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_arm64.h b/source/Plugins/Process/Utility/RegisterContextLinux_arm64.h
deleted file mode 100644
index 3de94b862583..000000000000
--- a/source/Plugins/Process/Utility/RegisterContextLinux_arm64.h
+++ /dev/null
@@ -1,80 +0,0 @@
-//===-- RegisterContextLinux_arm64.h ----------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_RegisterContextLinux_arm64_H_
-#define liblldb_RegisterContextLinux_arm64_H_
-
-#include "lldb/lldb-private.h"
-#include "lldb/Target/RegisterContext.h"
-#include "RegisterInfoInterface.h"
-
-class RegisterContextLinux_arm64
- : public lldb_private::RegisterInfoInterface
-{
-public:
- // based on RegisterContextDarwin_arm64.h
- struct GPR
- {
- uint64_t x[29]; // x0-x28
- uint64_t fp; // x29
- uint64_t lr; // x30
- uint64_t sp; // x31
- uint64_t pc; // pc
- uint32_t cpsr; // cpsr
- };
-
- // based on RegisterContextDarwin_arm64.h
- struct VReg
- {
- uint8_t bytes[16];
- };
-
- // based on RegisterContextDarwin_arm64.h
- struct FPU
- {
- VReg v[32];
- uint32_t fpsr;
- uint32_t fpcr;
- };
-
- // based on RegisterContextDarwin_arm64.h
- struct EXC
- {
- uint64_t far; // Virtual Fault Address
- uint32_t esr; // Exception syndrome
- uint32_t exception; // number of arm exception token
- };
-
- // based on RegisterContextDarwin_arm64.h
- struct DBG
- {
- uint64_t bvr[16];
- uint64_t bcr[16];
- uint64_t wvr[16];
- uint64_t wcr[16];
- uint64_t mdscr_el1;
- };
-
- RegisterContextLinux_arm64(const lldb_private::ArchSpec &target_arch);
-
- size_t
- GetGPRSize() const override;
-
- const lldb_private::RegisterInfo *
- GetRegisterInfo() const override;
-
- uint32_t
- GetRegisterCount () const override;
-
-private:
- const lldb_private::RegisterInfo *m_register_info_p;
- uint32_t m_register_info_count;
-};
-
-#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp b/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp
index e39beef42888..6563796db12c 100644
--- a/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp
@@ -7,87 +7,81 @@
//
//===---------------------------------------------------------------------===//
-#include "RegisterContextPOSIX_x86.h"
#include "RegisterContextLinux_i386.h"
+#include "RegisterContextPOSIX_x86.h"
using namespace lldb_private;
using namespace lldb;
-struct GPR
-{
- uint32_t ebx;
- uint32_t ecx;
- uint32_t edx;
- uint32_t esi;
- uint32_t edi;
- uint32_t ebp;
- uint32_t eax;
- uint32_t ds;
- uint32_t es;
- uint32_t fs;
- uint32_t gs;
- uint32_t orig_eax;
- uint32_t eip;
- uint32_t cs;
- uint32_t eflags;
- uint32_t esp;
- uint32_t ss;
+struct GPR {
+ uint32_t ebx;
+ uint32_t ecx;
+ uint32_t edx;
+ uint32_t esi;
+ uint32_t edi;
+ uint32_t ebp;
+ uint32_t eax;
+ uint32_t ds;
+ uint32_t es;
+ uint32_t fs;
+ uint32_t gs;
+ uint32_t orig_eax;
+ uint32_t eip;
+ uint32_t cs;
+ uint32_t eflags;
+ uint32_t esp;
+ uint32_t ss;
};
-struct FPR_i386
-{
- uint16_t fctrl; // FPU Control Word (fcw)
- uint16_t fstat; // FPU Status Word (fsw)
- uint8_t ftag; // FPU Tag Word (ftw)
- uint8_t reserved_1; // Reserved
- uint16_t fop; // Last Instruction Opcode (fop)
- union
- {
- struct
- {
- uint64_t fip; // Instruction Pointer
- uint64_t fdp; // Data Pointer
- } x86_64;
- struct
- {
- uint32_t fioff; // FPU IP Offset (fip)
- uint32_t fiseg; // FPU IP Selector (fcs)
- uint32_t fooff; // FPU Operand Pointer Offset (foo)
- uint32_t foseg; // FPU Operand Pointer Selector (fos)
- } i386_;// Added _ in the end to avoid error with gcc defining i386 in some cases
- } ptr;
- uint32_t mxcsr; // MXCSR Register State
- uint32_t mxcsrmask; // MXCSR Mask
- MMSReg stmm[8]; // 8*16 bytes for each FP-reg = 128 bytes
- XMMReg xmm[8]; // 8*16 bytes for each XMM-reg = 128 bytes
- uint32_t padding[56];
+struct FPR_i386 {
+ uint16_t fctrl; // FPU Control Word (fcw)
+ uint16_t fstat; // FPU Status Word (fsw)
+ uint8_t ftag; // FPU Tag Word (ftw)
+ uint8_t reserved_1; // Reserved
+ uint16_t fop; // Last Instruction Opcode (fop)
+ union {
+ struct {
+ uint64_t fip; // Instruction Pointer
+ uint64_t fdp; // Data Pointer
+ } x86_64;
+ struct {
+ uint32_t fioff; // FPU IP Offset (fip)
+ uint32_t fiseg; // FPU IP Selector (fcs)
+ uint32_t fooff; // FPU Operand Pointer Offset (foo)
+ uint32_t foseg; // FPU Operand Pointer Selector (fos)
+ } i386_; // Added _ in the end to avoid error with gcc defining i386 in some
+ // cases
+ } ptr;
+ uint32_t mxcsr; // MXCSR Register State
+ uint32_t mxcsrmask; // MXCSR Mask
+ MMSReg stmm[8]; // 8*16 bytes for each FP-reg = 128 bytes
+ XMMReg xmm[8]; // 8*16 bytes for each XMM-reg = 128 bytes
+ uint32_t padding[56];
};
-struct UserArea
-{
- GPR regs; // General purpose registers.
- int32_t fpvalid; // True if FPU is being used.
- FPR_i386 i387; // FPU registers.
- uint32_t tsize; // Text segment size.
- uint32_t dsize; // Data segment size.
- uint32_t ssize; // Stack segment size.
- uint32_t start_code; // VM address of text.
- uint32_t start_stack; // VM address of stack bottom (top in rsp).
- int32_t signal; // Signal causing core dump.
- int32_t reserved; // Unused.
- uint32_t ar0; // Location of GPR's.
- uint32_t fpstate; // Location of FPR's. Should be a FXSTATE *, but this
- // has to be 32-bits even on 64-bit systems.
- uint32_t magic; // Identifier for core dumps.
- char u_comm[32]; // Command causing core dump.
- uint32_t u_debugreg[8]; // Debug registers (DR0 - DR7).
+struct UserArea {
+ GPR regs; // General purpose registers.
+ int32_t fpvalid; // True if FPU is being used.
+ FPR_i386 i387; // FPU registers.
+ uint32_t tsize; // Text segment size.
+ uint32_t dsize; // Data segment size.
+ uint32_t ssize; // Stack segment size.
+ uint32_t start_code; // VM address of text.
+ uint32_t start_stack; // VM address of stack bottom (top in rsp).
+ int32_t signal; // Signal causing core dump.
+ int32_t reserved; // Unused.
+ uint32_t ar0; // Location of GPR's.
+ uint32_t fpstate; // Location of FPR's. Should be a FXSTATE *, but this
+ // has to be 32-bits even on 64-bit systems.
+ uint32_t magic; // Identifier for core dumps.
+ char u_comm[32]; // Command causing core dump.
+ uint32_t u_debugreg[8]; // Debug registers (DR0 - DR7).
};
-#define DR_SIZE sizeof(((UserArea*)NULL)->u_debugreg[0])
+#define DR_SIZE sizeof(((UserArea *)NULL)->u_debugreg[0])
#define DR_0_OFFSET 0xFC
-#define DR_OFFSET(reg_index) \
- (DR_0_OFFSET + (reg_index * 4))
-#define FPR_SIZE(reg) sizeof(((FPR_i386*)NULL)->reg)
+#define DR_OFFSET(reg_index) (DR_0_OFFSET + (reg_index * 4))
+#define FPR_SIZE(reg) sizeof(((FPR_i386 *)NULL)->reg)
//---------------------------------------------------------------------------
// Include RegisterInfos_i386 to declare our g_register_infos_i386 structure.
@@ -96,48 +90,48 @@ struct UserArea
#include "RegisterInfos_i386.h"
#undef DECLARE_REGISTER_INFOS_I386_STRUCT
-RegisterContextLinux_i386::RegisterContextLinux_i386(const ArchSpec &target_arch) :
- RegisterInfoInterface(target_arch)
-{
- RegisterInfo orig_ax = { "orig_eax", NULL, sizeof(((GPR*)NULL)->orig_eax), (LLVM_EXTENSION offsetof(GPR, orig_eax)), eEncodingUint, \
- eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL };
- d_register_infos.push_back(orig_ax);
+RegisterContextLinux_i386::RegisterContextLinux_i386(
+ const ArchSpec &target_arch)
+ : RegisterInfoInterface(target_arch) {
+ RegisterInfo orig_ax = {"orig_eax",
+ NULL,
+ sizeof(((GPR *)NULL)->orig_eax),
+ (LLVM_EXTENSION offsetof(GPR, orig_eax)),
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0};
+ d_register_infos.push_back(orig_ax);
}
-size_t
-RegisterContextLinux_i386::GetGPRSize() const
-{
- return sizeof(GPR);
-}
+size_t RegisterContextLinux_i386::GetGPRSize() const { return sizeof(GPR); }
-const RegisterInfo *
-RegisterContextLinux_i386::GetRegisterInfo() const
-{
- switch (m_target_arch.GetMachine())
- {
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- return g_register_infos_i386;
- default:
- assert(false && "Unhandled target architecture.");
- return NULL;
- }
+const RegisterInfo *RegisterContextLinux_i386::GetRegisterInfo() const {
+ switch (m_target_arch.GetMachine()) {
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ return g_register_infos_i386;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return NULL;
+ }
}
-uint32_t
-RegisterContextLinux_i386::GetRegisterCount () const
-{
- return static_cast<uint32_t> (sizeof (g_register_infos_i386) / sizeof (g_register_infos_i386 [0]));
+uint32_t RegisterContextLinux_i386::GetRegisterCount() const {
+ return static_cast<uint32_t>(sizeof(g_register_infos_i386) /
+ sizeof(g_register_infos_i386[0]));
}
-uint32_t
-RegisterContextLinux_i386::GetUserRegisterCount () const
-{
- return static_cast<uint32_t> (k_num_user_registers_i386);
+uint32_t RegisterContextLinux_i386::GetUserRegisterCount() const {
+ return static_cast<uint32_t>(k_num_user_registers_i386);
}
const std::vector<lldb_private::RegisterInfo> *
-RegisterContextLinux_i386::GetDynamicRegisterInfoP() const
-{
- return &d_register_infos;
+RegisterContextLinux_i386::GetDynamicRegisterInfoP() const {
+ return &d_register_infos;
}
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_i386.h b/source/Plugins/Process/Utility/RegisterContextLinux_i386.h
index 6c4768f49ac1..fbf803789cc1 100644
--- a/source/Plugins/Process/Utility/RegisterContextLinux_i386.h
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_i386.h
@@ -12,29 +12,23 @@
#include "RegisterInfoInterface.h"
-class RegisterContextLinux_i386
- : public lldb_private::RegisterInfoInterface
-{
+class RegisterContextLinux_i386 : public lldb_private::RegisterInfoInterface {
public:
- RegisterContextLinux_i386(const lldb_private::ArchSpec &target_arch);
+ RegisterContextLinux_i386(const lldb_private::ArchSpec &target_arch);
- size_t
- GetGPRSize() const override;
+ size_t GetGPRSize() const override;
- const lldb_private::RegisterInfo *
- GetRegisterInfo() const override;
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
- uint32_t
- GetRegisterCount () const override;
+ uint32_t GetRegisterCount() const override;
- uint32_t
- GetUserRegisterCount () const override;
+ uint32_t GetUserRegisterCount() const override;
- const std::vector<lldb_private::RegisterInfo> *
- GetDynamicRegisterInfoP() const override;
+ const std::vector<lldb_private::RegisterInfo> *
+ GetDynamicRegisterInfoP() const override;
private:
- std::vector<lldb_private::RegisterInfo> d_register_infos;
+ std::vector<lldb_private::RegisterInfo> d_register_infos;
};
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp b/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp
index 1b2281004d26..982eefea9ba6 100644
--- a/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp
@@ -7,8 +7,8 @@
//
//===---------------------------------------------------------------------===//
-#include <vector>
#include <stddef.h>
+#include <vector>
// For eh_frame and DWARF Register numbers
#include "RegisterContextLinux_mips.h"
@@ -29,48 +29,38 @@ using namespace lldb;
#include "RegisterInfos_mips.h"
#undef DECLARE_REGISTER_INFOS_MIPS_STRUCT
-uint32_t
-GetUserRegisterInfoCount (bool msa_present)
-{
- if (msa_present)
- return static_cast<uint32_t> (k_num_user_registers_mips);
- return static_cast<uint32_t> (k_num_user_registers_mips - k_num_msa_registers_mips);
+uint32_t GetUserRegisterInfoCount(bool msa_present) {
+ if (msa_present)
+ return static_cast<uint32_t>(k_num_user_registers_mips);
+ return static_cast<uint32_t>(k_num_user_registers_mips -
+ k_num_msa_registers_mips);
}
-RegisterContextLinux_mips::RegisterContextLinux_mips(const ArchSpec &target_arch, bool msa_present) :
- RegisterInfoInterface(target_arch),
- m_user_register_count (GetUserRegisterInfoCount (msa_present))
-{
-}
+RegisterContextLinux_mips::RegisterContextLinux_mips(
+ const ArchSpec &target_arch, bool msa_present)
+ : RegisterInfoInterface(target_arch),
+ m_user_register_count(GetUserRegisterInfoCount(msa_present)) {}
-size_t
-RegisterContextLinux_mips::GetGPRSize() const
-{
- return sizeof(GPR_linux_mips);
+size_t RegisterContextLinux_mips::GetGPRSize() const {
+ return sizeof(GPR_linux_mips);
}
-const RegisterInfo *
-RegisterContextLinux_mips::GetRegisterInfo() const
-{
- switch (m_target_arch.GetMachine())
- {
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- return g_register_infos_mips;
- default:
- assert(false && "Unhandled target architecture.");
- return NULL;
- }
+const RegisterInfo *RegisterContextLinux_mips::GetRegisterInfo() const {
+ switch (m_target_arch.GetMachine()) {
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
+ return g_register_infos_mips;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return NULL;
+ }
}
-uint32_t
-RegisterContextLinux_mips::GetRegisterCount () const
-{
- return static_cast<uint32_t> (sizeof (g_register_infos_mips) / sizeof (g_register_infos_mips [0]));
+uint32_t RegisterContextLinux_mips::GetRegisterCount() const {
+ return static_cast<uint32_t>(sizeof(g_register_infos_mips) /
+ sizeof(g_register_infos_mips[0]));
}
-uint32_t
-RegisterContextLinux_mips::GetUserRegisterCount () const
-{
- return static_cast<uint32_t> (m_user_register_count);
+uint32_t RegisterContextLinux_mips::GetUserRegisterCount() const {
+ return static_cast<uint32_t>(m_user_register_count);
}
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_mips.h b/source/Plugins/Process/Utility/RegisterContextLinux_mips.h
index c0bd5ad4f4f9..cba4ee6cd2b0 100644
--- a/source/Plugins/Process/Utility/RegisterContextLinux_mips.h
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_mips.h
@@ -10,29 +10,24 @@
#ifndef liblldb_RegisterContextLinux_mips_H_
#define liblldb_RegisterContextLinux_mips_H_
-#include "lldb/lldb-private.h"
#include "RegisterInfoInterface.h"
+#include "lldb/lldb-private.h"
-class RegisterContextLinux_mips
- : public lldb_private::RegisterInfoInterface
-{
+class RegisterContextLinux_mips : public lldb_private::RegisterInfoInterface {
public:
- RegisterContextLinux_mips(const lldb_private::ArchSpec &target_arch, bool msa_present = true);
+ RegisterContextLinux_mips(const lldb_private::ArchSpec &target_arch,
+ bool msa_present = true);
- size_t
- GetGPRSize() const override;
+ size_t GetGPRSize() const override;
- const lldb_private::RegisterInfo *
- GetRegisterInfo() const override;
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
- uint32_t
- GetRegisterCount () const override;
+ uint32_t GetRegisterCount() const override;
- uint32_t
- GetUserRegisterCount () const override;
+ uint32_t GetUserRegisterCount() const override;
private:
- uint32_t m_user_register_count;
+ uint32_t m_user_register_count;
};
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp b/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp
index f2871e3b7352..c40f69492624 100644
--- a/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp
@@ -7,10 +7,10 @@
//
//===---------------------------------------------------------------------===//
-#if defined (__mips__)
+#if defined(__mips__)
-#include <vector>
#include <stddef.h>
+#include <vector>
// For eh_frame and DWARF Register numbers
#include "RegisterContextLinux_mips64.h"
@@ -25,7 +25,8 @@ using namespace lldb;
using namespace lldb_private;
//---------------------------------------------------------------------------
-// Include RegisterInfos_mips64 to declare our g_register_infos_mips64 structure.
+// Include RegisterInfos_mips64 to declare our g_register_infos_mips64
+// structure.
//---------------------------------------------------------------------------
#define DECLARE_REGISTER_INFOS_MIPS64_STRUCT
#define LINUX_MIPS64
@@ -40,91 +41,79 @@ using namespace lldb_private;
#include "RegisterInfos_mips.h"
#undef DECLARE_REGISTER_INFOS_MIPS_STRUCT
-static const RegisterInfo *
-GetRegisterInfoPtr (const ArchSpec &target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el:
- return g_register_infos_mips64;
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- return g_register_infos_mips;
- default:
- assert(false && "Unhandled target architecture.");
- return nullptr;
- }
+static const RegisterInfo *GetRegisterInfoPtr(const ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::mips64:
+ case llvm::Triple::mips64el:
+ return g_register_infos_mips64;
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
+ return g_register_infos_mips;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return nullptr;
+ }
}
-static uint32_t
-GetRegisterInfoCount (const ArchSpec &target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el:
- return static_cast<uint32_t> (sizeof (g_register_infos_mips64) / sizeof (g_register_infos_mips64 [0]));
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- return static_cast<uint32_t> (sizeof (g_register_infos_mips) / sizeof (g_register_infos_mips [0]));
- default:
- assert(false && "Unhandled target architecture.");
- return 0;
- }
+static uint32_t GetRegisterInfoCount(const ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::mips64:
+ case llvm::Triple::mips64el:
+ return static_cast<uint32_t>(sizeof(g_register_infos_mips64) /
+ sizeof(g_register_infos_mips64[0]));
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
+ return static_cast<uint32_t>(sizeof(g_register_infos_mips) /
+ sizeof(g_register_infos_mips[0]));
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
}
-uint32_t
-GetUserRegisterInfoCount (const ArchSpec &target_arch, bool msa_present)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- if (msa_present)
- return static_cast<uint32_t> (k_num_user_registers_mips);
- return static_cast<uint32_t> (k_num_user_registers_mips - k_num_msa_registers_mips);
- case llvm::Triple::mips64el:
- case llvm::Triple::mips64:
- if (msa_present)
- return static_cast<uint32_t> (k_num_user_registers_mips64);
- return static_cast<uint32_t> (k_num_user_registers_mips64 - k_num_msa_registers_mips64);
- default:
- assert(false && "Unhandled target architecture.");
- return 0;
- }
+uint32_t GetUserRegisterInfoCount(const ArchSpec &target_arch,
+ bool msa_present) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
+ if (msa_present)
+ return static_cast<uint32_t>(k_num_user_registers_mips);
+ return static_cast<uint32_t>(k_num_user_registers_mips -
+ k_num_msa_registers_mips);
+ case llvm::Triple::mips64el:
+ case llvm::Triple::mips64:
+ if (msa_present)
+ return static_cast<uint32_t>(k_num_user_registers_mips64);
+ return static_cast<uint32_t>(k_num_user_registers_mips64 -
+ k_num_msa_registers_mips64);
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
}
-RegisterContextLinux_mips64::RegisterContextLinux_mips64(const ArchSpec &target_arch, bool msa_present) :
- lldb_private::RegisterInfoInterface(target_arch),
- m_register_info_p (GetRegisterInfoPtr (target_arch)),
- m_register_info_count (GetRegisterInfoCount (target_arch)),
- m_user_register_count (GetUserRegisterInfoCount (target_arch, msa_present))
-{
-}
+RegisterContextLinux_mips64::RegisterContextLinux_mips64(
+ const ArchSpec &target_arch, bool msa_present)
+ : lldb_private::RegisterInfoInterface(target_arch),
+ m_register_info_p(GetRegisterInfoPtr(target_arch)),
+ m_register_info_count(GetRegisterInfoCount(target_arch)),
+ m_user_register_count(
+ GetUserRegisterInfoCount(target_arch, msa_present)) {}
-size_t
-RegisterContextLinux_mips64::GetGPRSize() const
-{
- return sizeof(GPR_linux_mips);
+size_t RegisterContextLinux_mips64::GetGPRSize() const {
+ return sizeof(GPR_linux_mips);
}
-const RegisterInfo *
-RegisterContextLinux_mips64::GetRegisterInfo() const
-{
- return m_register_info_p;
+const RegisterInfo *RegisterContextLinux_mips64::GetRegisterInfo() const {
+ return m_register_info_p;
}
-uint32_t
-RegisterContextLinux_mips64::GetRegisterCount () const
-{
- return m_register_info_count;
+uint32_t RegisterContextLinux_mips64::GetRegisterCount() const {
+ return m_register_info_count;
}
-uint32_t
-RegisterContextLinux_mips64::GetUserRegisterCount () const
-{
- return m_user_register_count;
+uint32_t RegisterContextLinux_mips64::GetUserRegisterCount() const {
+ return m_user_register_count;
}
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h b/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h
index 843328c92e43..9669b0d84997 100644
--- a/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h
@@ -7,36 +7,31 @@
//
//===----------------------------------------------------------------------===//
-#if defined (__mips__)
+#if defined(__mips__)
#ifndef liblldb_RegisterContextLinux_mips64_H_
#define liblldb_RegisterContextLinux_mips64_H_
-#include "lldb/lldb-private.h"
#include "RegisterInfoInterface.h"
+#include "lldb/lldb-private.h"
-class RegisterContextLinux_mips64
- : public lldb_private::RegisterInfoInterface
-{
+class RegisterContextLinux_mips64 : public lldb_private::RegisterInfoInterface {
public:
- RegisterContextLinux_mips64(const lldb_private::ArchSpec &target_arch, bool msa_present = true);
+ RegisterContextLinux_mips64(const lldb_private::ArchSpec &target_arch,
+ bool msa_present = true);
- size_t
- GetGPRSize() const override;
+ size_t GetGPRSize() const override;
- const lldb_private::RegisterInfo *
- GetRegisterInfo() const override;
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
- uint32_t
- GetRegisterCount () const override;
+ uint32_t GetRegisterCount() const override;
- uint32_t
- GetUserRegisterCount () const override;
+ uint32_t GetUserRegisterCount() const override;
private:
- const lldb_private::RegisterInfo *m_register_info_p;
- uint32_t m_register_info_count;
- uint32_t m_user_register_count;
+ const lldb_private::RegisterInfo *m_register_info_p;
+ uint32_t m_register_info_count;
+ uint32_t m_user_register_count;
};
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp b/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp
index 9aef1e9830e2..5a7f5a125246 100644
--- a/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#include "RegisterContextPOSIX_s390x.h"
#include "RegisterContextLinux_s390x.h"
+#include "RegisterContextPOSIX_s390x.h"
using namespace lldb_private;
using namespace lldb;
@@ -20,79 +20,58 @@ using namespace lldb;
#include "RegisterInfos_s390x.h"
#undef DECLARE_REGISTER_INFOS_S390X_STRUCT
-static const RegisterInfo *
-GetRegisterInfoPtr(const ArchSpec &target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::systemz:
- return g_register_infos_s390x;
- default:
- assert(false && "Unhandled target architecture.");
- return nullptr;
- }
+static const RegisterInfo *GetRegisterInfoPtr(const ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::systemz:
+ return g_register_infos_s390x;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return nullptr;
+ }
}
-static uint32_t
-GetRegisterInfoCount(const ArchSpec &target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::systemz:
- return k_num_registers_s390x;
- default:
- assert(false && "Unhandled target architecture.");
- return 0;
- }
+static uint32_t GetRegisterInfoCount(const ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::systemz:
+ return k_num_registers_s390x;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
}
-static uint32_t
-GetUserRegisterInfoCount(const ArchSpec &target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::systemz:
- return k_num_user_registers_s390x + k_num_linux_registers_s390x;
- default:
- assert(false && "Unhandled target architecture.");
- return 0;
- }
+static uint32_t GetUserRegisterInfoCount(const ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::systemz:
+ return k_num_user_registers_s390x + k_num_linux_registers_s390x;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
}
-RegisterContextLinux_s390x::RegisterContextLinux_s390x(const ArchSpec &target_arch)
+RegisterContextLinux_s390x::RegisterContextLinux_s390x(
+ const ArchSpec &target_arch)
: lldb_private::RegisterInfoInterface(target_arch),
m_register_info_p(GetRegisterInfoPtr(target_arch)),
m_register_info_count(GetRegisterInfoCount(target_arch)),
- m_user_register_count(GetUserRegisterInfoCount(target_arch))
-{
-}
+ m_user_register_count(GetUserRegisterInfoCount(target_arch)) {}
const std::vector<lldb_private::RegisterInfo> *
-RegisterContextLinux_s390x::GetDynamicRegisterInfoP() const
-{
- return &d_register_infos;
+RegisterContextLinux_s390x::GetDynamicRegisterInfoP() const {
+ return &d_register_infos;
}
-const RegisterInfo *
-RegisterContextLinux_s390x::GetRegisterInfo() const
-{
- return m_register_info_p;
+const RegisterInfo *RegisterContextLinux_s390x::GetRegisterInfo() const {
+ return m_register_info_p;
}
-uint32_t
-RegisterContextLinux_s390x::GetRegisterCount() const
-{
- return m_register_info_count;
+uint32_t RegisterContextLinux_s390x::GetRegisterCount() const {
+ return m_register_info_count;
}
-uint32_t
-RegisterContextLinux_s390x::GetUserRegisterCount() const
-{
- return m_user_register_count;
+uint32_t RegisterContextLinux_s390x::GetUserRegisterCount() const {
+ return m_user_register_count;
}
-size_t
-RegisterContextLinux_s390x::GetGPRSize() const
-{
- return 0;
-}
+size_t RegisterContextLinux_s390x::GetGPRSize() const { return 0; }
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h b/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h
index bdc7f34f62e7..556cc2e12484 100644
--- a/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h
@@ -12,31 +12,26 @@
#include "RegisterInfoInterface.h"
-class RegisterContextLinux_s390x : public lldb_private::RegisterInfoInterface
-{
+class RegisterContextLinux_s390x : public lldb_private::RegisterInfoInterface {
public:
- RegisterContextLinux_s390x(const lldb_private::ArchSpec &target_arch);
+ RegisterContextLinux_s390x(const lldb_private::ArchSpec &target_arch);
- size_t
- GetGPRSize() const override;
+ size_t GetGPRSize() const override;
- const lldb_private::RegisterInfo *
- GetRegisterInfo() const override;
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
- uint32_t
- GetRegisterCount() const override;
+ uint32_t GetRegisterCount() const override;
- uint32_t
- GetUserRegisterCount() const override;
+ uint32_t GetUserRegisterCount() const override;
- const std::vector<lldb_private::RegisterInfo> *
- GetDynamicRegisterInfoP() const override;
+ const std::vector<lldb_private::RegisterInfo> *
+ GetDynamicRegisterInfoP() const override;
private:
- const lldb_private::RegisterInfo *m_register_info_p;
- uint32_t m_register_info_count;
- uint32_t m_user_register_count;
- std::vector<lldb_private::RegisterInfo> d_register_infos;
+ const lldb_private::RegisterInfo *m_register_info_p;
+ uint32_t m_register_info_count;
+ uint32_t m_user_register_count;
+ std::vector<lldb_private::RegisterInfo> d_register_infos;
};
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp b/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp
index 78afe72fcfa9..526b3eca81ae 100644
--- a/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp
@@ -7,201 +7,191 @@
//
//===---------------------------------------------------------------------===//
-#include <vector>
-#include "RegisterContextPOSIX_x86.h"
-#include "RegisterContextLinux_i386.h"
#include "RegisterContextLinux_x86_64.h"
+#include "RegisterContextLinux_i386.h"
+#include "RegisterContextPOSIX_x86.h"
+#include <vector>
using namespace lldb_private;
using namespace lldb;
-typedef struct _GPR
-{
- uint64_t r15;
- uint64_t r14;
- uint64_t r13;
- uint64_t r12;
- uint64_t rbp;
- uint64_t rbx;
- uint64_t r11;
- uint64_t r10;
- uint64_t r9;
- uint64_t r8;
- uint64_t rax;
- uint64_t rcx;
- uint64_t rdx;
- uint64_t rsi;
- uint64_t rdi;
- uint64_t orig_rax;
- uint64_t rip;
- uint64_t cs;
- uint64_t rflags;
- uint64_t rsp;
- uint64_t ss;
- uint64_t fs_base;
- uint64_t gs_base;
- uint64_t ds;
- uint64_t es;
- uint64_t fs;
- uint64_t gs;
+typedef struct _GPR {
+ uint64_t r15;
+ uint64_t r14;
+ uint64_t r13;
+ uint64_t r12;
+ uint64_t rbp;
+ uint64_t rbx;
+ uint64_t r11;
+ uint64_t r10;
+ uint64_t r9;
+ uint64_t r8;
+ uint64_t rax;
+ uint64_t rcx;
+ uint64_t rdx;
+ uint64_t rsi;
+ uint64_t rdi;
+ uint64_t orig_rax;
+ uint64_t rip;
+ uint64_t cs;
+ uint64_t rflags;
+ uint64_t rsp;
+ uint64_t ss;
+ uint64_t fs_base;
+ uint64_t gs_base;
+ uint64_t ds;
+ uint64_t es;
+ uint64_t fs;
+ uint64_t gs;
} GPR;
struct DBG {
- uint64_t dr[8];
+ uint64_t dr[8];
};
-struct UserArea
-{
- GPR gpr; // General purpose registers.
- int32_t fpvalid; // True if FPU is being used.
- int32_t pad0;
- FXSAVE fpr; // General purpose floating point registers (see FPR for extended register sets).
- uint64_t tsize; // Text segment size.
- uint64_t dsize; // Data segment size.
- uint64_t ssize; // Stack segment size.
- uint64_t start_code; // VM address of text.
- uint64_t start_stack; // VM address of stack bottom (top in rsp).
- int64_t signal; // Signal causing core dump.
- int32_t reserved; // Unused.
- int32_t pad1;
- uint64_t ar0; // Location of GPR's.
- FXSAVE* fpstate; // Location of FPR's.
- uint64_t magic; // Identifier for core dumps.
- char u_comm[32]; // Command causing core dump.
- DBG dbg; // Debug registers.
- uint64_t error_code; // CPU error code.
- uint64_t fault_address; // Control register CR3.
+struct UserArea {
+ GPR gpr; // General purpose registers.
+ int32_t fpvalid; // True if FPU is being used.
+ int32_t pad0;
+ FXSAVE fpr; // General purpose floating point registers (see FPR for extended
+ // register sets).
+ uint64_t tsize; // Text segment size.
+ uint64_t dsize; // Data segment size.
+ uint64_t ssize; // Stack segment size.
+ uint64_t start_code; // VM address of text.
+ uint64_t start_stack; // VM address of stack bottom (top in rsp).
+ int64_t signal; // Signal causing core dump.
+ int32_t reserved; // Unused.
+ int32_t pad1;
+ uint64_t ar0; // Location of GPR's.
+ FXSAVE *fpstate; // Location of FPR's.
+ uint64_t magic; // Identifier for core dumps.
+ char u_comm[32]; // Command causing core dump.
+ DBG dbg; // Debug registers.
+ uint64_t error_code; // CPU error code.
+ uint64_t fault_address; // Control register CR3.
};
-
-#define DR_OFFSET(reg_index) \
- (LLVM_EXTENSION offsetof(UserArea, dbg) + \
- LLVM_EXTENSION offsetof(DBG, dr[reg_index]))
+#define DR_OFFSET(reg_index) \
+ (LLVM_EXTENSION offsetof(UserArea, dbg) + \
+ LLVM_EXTENSION offsetof(DBG, dr[reg_index]))
//---------------------------------------------------------------------------
-// Include RegisterInfos_x86_64 to declare our g_register_infos_x86_64 structure.
+// Include RegisterInfos_x86_64 to declare our g_register_infos_x86_64
+// structure.
//---------------------------------------------------------------------------
#define DECLARE_REGISTER_INFOS_X86_64_STRUCT
#include "RegisterInfos_x86_64.h"
#undef DECLARE_REGISTER_INFOS_X86_64_STRUCT
-static std::vector<lldb_private::RegisterInfo>&
-GetPrivateRegisterInfoVector ()
-{
- static std::vector<lldb_private::RegisterInfo> g_register_infos;
- return g_register_infos;
+static std::vector<lldb_private::RegisterInfo> &GetPrivateRegisterInfoVector() {
+ static std::vector<lldb_private::RegisterInfo> g_register_infos;
+ return g_register_infos;
}
static const RegisterInfo *
-GetRegisterInfo_i386(const lldb_private::ArchSpec &arch)
-{
- std::vector<lldb_private::RegisterInfo> &g_register_infos = GetPrivateRegisterInfoVector ();
-
- // Allocate RegisterInfo only once
- if (g_register_infos.empty())
- {
- // Copy the register information from base class
- std::unique_ptr<RegisterContextLinux_i386> reg_interface(new RegisterContextLinux_i386 (arch));
- const RegisterInfo *base_info = reg_interface->GetRegisterInfo();
- g_register_infos.insert(g_register_infos.end(), &base_info[0], &base_info[k_num_registers_i386]);
-
- //---------------------------------------------------------------------------
- // Include RegisterInfos_x86_64 to update the g_register_infos structure
- // with x86_64 offsets.
- //---------------------------------------------------------------------------
- #define UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
- #include "RegisterInfos_x86_64.h"
- #undef UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
- }
-
- return &g_register_infos[0];
-}
+GetRegisterInfo_i386(const lldb_private::ArchSpec &arch) {
+ std::vector<lldb_private::RegisterInfo> &g_register_infos =
+ GetPrivateRegisterInfoVector();
+
+ // Allocate RegisterInfo only once
+ if (g_register_infos.empty()) {
+ // Copy the register information from base class
+ std::unique_ptr<RegisterContextLinux_i386> reg_interface(
+ new RegisterContextLinux_i386(arch));
+ const RegisterInfo *base_info = reg_interface->GetRegisterInfo();
+ g_register_infos.insert(g_register_infos.end(), &base_info[0],
+ &base_info[k_num_registers_i386]);
-static const RegisterInfo *
-GetRegisterInfoPtr (const ArchSpec &target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::x86:
- return GetRegisterInfo_i386 (target_arch);
- case llvm::Triple::x86_64:
- return g_register_infos_x86_64;
- default:
- assert(false && "Unhandled target architecture.");
- return nullptr;
- }
+//---------------------------------------------------------------------------
+// Include RegisterInfos_x86_64 to update the g_register_infos structure
+// with x86_64 offsets.
+//---------------------------------------------------------------------------
+#define UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
+#include "RegisterInfos_x86_64.h"
+#undef UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
+ }
+
+ return &g_register_infos[0];
}
-static uint32_t
-GetRegisterInfoCount (const ArchSpec &target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::x86:
- {
- assert (!GetPrivateRegisterInfoVector ().empty () && "i386 register info not yet filled.");
- return static_cast<uint32_t> (GetPrivateRegisterInfoVector ().size ());
- }
- case llvm::Triple::x86_64:
- return static_cast<uint32_t> (sizeof (g_register_infos_x86_64) / sizeof (g_register_infos_x86_64 [0]));
- default:
- assert(false && "Unhandled target architecture.");
- return 0;
- }
+static const RegisterInfo *GetRegisterInfoPtr(const ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::x86:
+ return GetRegisterInfo_i386(target_arch);
+ case llvm::Triple::x86_64:
+ return g_register_infos_x86_64;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return nullptr;
+ }
}
-static uint32_t
-GetUserRegisterInfoCount (const ArchSpec &target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::x86:
- return static_cast<uint32_t> (k_num_user_registers_i386);
- case llvm::Triple::x86_64:
- return static_cast<uint32_t> (k_num_user_registers_x86_64);
- default:
- assert(false && "Unhandled target architecture.");
- return 0;
- }
+static uint32_t GetRegisterInfoCount(const ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::x86: {
+ assert(!GetPrivateRegisterInfoVector().empty() &&
+ "i386 register info not yet filled.");
+ return static_cast<uint32_t>(GetPrivateRegisterInfoVector().size());
+ }
+ case llvm::Triple::x86_64:
+ return static_cast<uint32_t>(sizeof(g_register_infos_x86_64) /
+ sizeof(g_register_infos_x86_64[0]));
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
}
-RegisterContextLinux_x86_64::RegisterContextLinux_x86_64(const ArchSpec &target_arch) :
- lldb_private::RegisterInfoInterface(target_arch),
- m_register_info_p (GetRegisterInfoPtr (target_arch)),
- m_register_info_count (GetRegisterInfoCount (target_arch)),
- m_user_register_count (GetUserRegisterInfoCount (target_arch))
-{
- RegisterInfo orig_ax = { "orig_rax", NULL, sizeof(((GPR*)NULL)->orig_rax), (LLVM_EXTENSION offsetof(GPR, orig_rax)), eEncodingUint, \
- eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL };
- d_register_infos.push_back(orig_ax);
+static uint32_t GetUserRegisterInfoCount(const ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::x86:
+ return static_cast<uint32_t>(k_num_user_registers_i386);
+ case llvm::Triple::x86_64:
+ return static_cast<uint32_t>(k_num_user_registers_x86_64);
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
}
-size_t
-RegisterContextLinux_x86_64::GetGPRSize() const
-{
- return sizeof(GPR);
+RegisterContextLinux_x86_64::RegisterContextLinux_x86_64(
+ const ArchSpec &target_arch)
+ : lldb_private::RegisterInfoInterface(target_arch),
+ m_register_info_p(GetRegisterInfoPtr(target_arch)),
+ m_register_info_count(GetRegisterInfoCount(target_arch)),
+ m_user_register_count(GetUserRegisterInfoCount(target_arch)) {
+ RegisterInfo orig_ax = {"orig_rax",
+ NULL,
+ sizeof(((GPR *)NULL)->orig_rax),
+ (LLVM_EXTENSION offsetof(GPR, orig_rax)),
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0};
+ d_register_infos.push_back(orig_ax);
}
+size_t RegisterContextLinux_x86_64::GetGPRSize() const { return sizeof(GPR); }
+
const std::vector<lldb_private::RegisterInfo> *
-RegisterContextLinux_x86_64::GetDynamicRegisterInfoP() const
-{
- return &d_register_infos;
+RegisterContextLinux_x86_64::GetDynamicRegisterInfoP() const {
+ return &d_register_infos;
}
-const RegisterInfo *
-RegisterContextLinux_x86_64::GetRegisterInfo() const
-{
- return m_register_info_p;
+const RegisterInfo *RegisterContextLinux_x86_64::GetRegisterInfo() const {
+ return m_register_info_p;
}
-uint32_t
-RegisterContextLinux_x86_64::GetRegisterCount () const
-{
- return m_register_info_count;
+uint32_t RegisterContextLinux_x86_64::GetRegisterCount() const {
+ return m_register_info_count;
}
-uint32_t
-RegisterContextLinux_x86_64::GetUserRegisterCount () const
-{
- return m_user_register_count;
+uint32_t RegisterContextLinux_x86_64::GetUserRegisterCount() const {
+ return m_user_register_count;
}
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h b/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h
index ed0b7de9aae8..99a4cb736790 100644
--- a/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h
@@ -12,33 +12,26 @@
#include "RegisterInfoInterface.h"
-class RegisterContextLinux_x86_64
- : public lldb_private::RegisterInfoInterface
-{
+class RegisterContextLinux_x86_64 : public lldb_private::RegisterInfoInterface {
public:
- RegisterContextLinux_x86_64(const lldb_private::ArchSpec &target_arch);
+ RegisterContextLinux_x86_64(const lldb_private::ArchSpec &target_arch);
- size_t
- GetGPRSize() const override;
+ size_t GetGPRSize() const override;
- const lldb_private::RegisterInfo *
- GetRegisterInfo() const override;
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
- uint32_t
- GetRegisterCount () const override;
+ uint32_t GetRegisterCount() const override;
- uint32_t
- GetUserRegisterCount () const override;
+ uint32_t GetUserRegisterCount() const override;
- const std::vector<lldb_private::RegisterInfo> *
- GetDynamicRegisterInfoP() const override;
+ const std::vector<lldb_private::RegisterInfo> *
+ GetDynamicRegisterInfoP() const override;
private:
- const lldb_private::RegisterInfo *m_register_info_p;
- uint32_t m_register_info_count;
- uint32_t m_user_register_count;
- std::vector<lldb_private::RegisterInfo> d_register_infos;
-
+ const lldb_private::RegisterInfo *m_register_info_p;
+ uint32_t m_register_info_count;
+ uint32_t m_user_register_count;
+ std::vector<lldb_private::RegisterInfo> d_register_infos;
};
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp b/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp
index a2ab67438b75..95b106d68bb3 100644
--- a/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp
@@ -27,181 +27,143 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// RegisterContextMacOSXFrameBackchain constructor
//----------------------------------------------------------------------
-RegisterContextMacOSXFrameBackchain::RegisterContextMacOSXFrameBackchain
-(
- Thread &thread,
- uint32_t concrete_frame_idx,
- const UnwindMacOSXFrameBackchain::Cursor &cursor
-) :
- RegisterContext (thread, concrete_frame_idx),
- m_cursor (cursor),
- m_cursor_is_valid (true)
-{
-}
+RegisterContextMacOSXFrameBackchain::RegisterContextMacOSXFrameBackchain(
+ Thread &thread, uint32_t concrete_frame_idx,
+ const UnwindMacOSXFrameBackchain::Cursor &cursor)
+ : RegisterContext(thread, concrete_frame_idx), m_cursor(cursor),
+ m_cursor_is_valid(true) {}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-RegisterContextMacOSXFrameBackchain::~RegisterContextMacOSXFrameBackchain()
-{
-}
+RegisterContextMacOSXFrameBackchain::~RegisterContextMacOSXFrameBackchain() {}
-void
-RegisterContextMacOSXFrameBackchain::InvalidateAllRegisters ()
-{
- m_cursor_is_valid = false;
+void RegisterContextMacOSXFrameBackchain::InvalidateAllRegisters() {
+ m_cursor_is_valid = false;
}
-size_t
-RegisterContextMacOSXFrameBackchain::GetRegisterCount ()
-{
- return m_thread.GetRegisterContext()->GetRegisterCount();
+size_t RegisterContextMacOSXFrameBackchain::GetRegisterCount() {
+ return m_thread.GetRegisterContext()->GetRegisterCount();
}
const RegisterInfo *
-RegisterContextMacOSXFrameBackchain::GetRegisterInfoAtIndex (size_t reg)
-{
- return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex(reg);
+RegisterContextMacOSXFrameBackchain::GetRegisterInfoAtIndex(size_t reg) {
+ return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex(reg);
}
-size_t
-RegisterContextMacOSXFrameBackchain::GetRegisterSetCount ()
-{
- return m_thread.GetRegisterContext()->GetRegisterSetCount();
+size_t RegisterContextMacOSXFrameBackchain::GetRegisterSetCount() {
+ return m_thread.GetRegisterContext()->GetRegisterSetCount();
}
-
-
const RegisterSet *
-RegisterContextMacOSXFrameBackchain::GetRegisterSet (size_t reg_set)
-{
- return m_thread.GetRegisterContext()->GetRegisterSet (reg_set);
+RegisterContextMacOSXFrameBackchain::GetRegisterSet(size_t reg_set) {
+ return m_thread.GetRegisterContext()->GetRegisterSet(reg_set);
}
+bool RegisterContextMacOSXFrameBackchain::ReadRegister(
+ const RegisterInfo *reg_info, RegisterValue &value) {
+ if (!m_cursor_is_valid)
+ return false;
+
+ uint64_t reg_value = LLDB_INVALID_ADDRESS;
+ switch (reg_info->kinds[eRegisterKindGeneric]) {
+ case LLDB_REGNUM_GENERIC_PC:
+ if (m_cursor.pc == LLDB_INVALID_ADDRESS)
+ return false;
+ reg_value = m_cursor.pc;
+ break;
-bool
-RegisterContextMacOSXFrameBackchain::ReadRegister (const RegisterInfo *reg_info,
- RegisterValue &value)
-{
- if (!m_cursor_is_valid)
- return false;
-
- uint64_t reg_value = LLDB_INVALID_ADDRESS;
-
- switch (reg_info->kinds[eRegisterKindGeneric])
- {
- case LLDB_REGNUM_GENERIC_PC:
- if (m_cursor.pc == LLDB_INVALID_ADDRESS)
- return false;
- reg_value = m_cursor.pc;
- break;
-
- case LLDB_REGNUM_GENERIC_FP:
- if (m_cursor.fp == LLDB_INVALID_ADDRESS)
- return false;
- reg_value = m_cursor.fp;
- break;
-
- default:
- return false;
- }
-
- switch (reg_info->encoding)
- {
- case eEncodingInvalid:
- case eEncodingVector:
- break;
-
- case eEncodingUint:
- case eEncodingSint:
- value.SetUInt(reg_value, reg_info->byte_size);
+ case LLDB_REGNUM_GENERIC_FP:
+ if (m_cursor.fp == LLDB_INVALID_ADDRESS)
+ return false;
+ reg_value = m_cursor.fp;
+ break;
+
+ default:
+ return false;
+ }
+
+ switch (reg_info->encoding) {
+ case eEncodingInvalid:
+ case eEncodingVector:
+ break;
+
+ case eEncodingUint:
+ case eEncodingSint:
+ value.SetUInt(reg_value, reg_info->byte_size);
+ return true;
+
+ case eEncodingIEEE754:
+ switch (reg_info->byte_size) {
+ case sizeof(float):
+ if (sizeof(float) == sizeof(uint32_t)) {
+ value.SetUInt32(reg_value, RegisterValue::eTypeFloat);
+ return true;
+ } else if (sizeof(float) == sizeof(uint64_t)) {
+ value.SetUInt64(reg_value, RegisterValue::eTypeFloat);
return true;
+ }
+ break;
- case eEncodingIEEE754:
- switch (reg_info->byte_size)
- {
- case sizeof (float):
- if (sizeof (float) == sizeof(uint32_t))
- {
- value.SetUInt32(reg_value, RegisterValue::eTypeFloat);
- return true;
- }
- else if (sizeof (float) == sizeof(uint64_t))
- {
- value.SetUInt64(reg_value, RegisterValue::eTypeFloat);
- return true;
- }
- break;
-
- case sizeof (double):
- if (sizeof (double) == sizeof(uint32_t))
- {
- value.SetUInt32(reg_value, RegisterValue::eTypeDouble);
- return true;
- }
- else if (sizeof (double) == sizeof(uint64_t))
- {
- value.SetUInt64(reg_value, RegisterValue::eTypeDouble);
- return true;
- }
- break;
-
- // TOOD: need a better way to detect when "long double" types are
- // the same bytes size as "double"
-#if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__) && !defined(_MSC_VER) && \
- !defined(__mips__) && !defined(__powerpc__) && !defined(__ANDROID_NDK__)
- case sizeof (long double):
- if (sizeof (long double) == sizeof(uint32_t))
- {
- value.SetUInt32(reg_value, RegisterValue::eTypeLongDouble);
- return true;
- }
- else if (sizeof (long double) == sizeof(uint64_t))
- {
- value.SetUInt64(reg_value, RegisterValue::eTypeLongDouble);
- return true;
- }
- break;
+ case sizeof(double):
+ if (sizeof(double) == sizeof(uint32_t)) {
+ value.SetUInt32(reg_value, RegisterValue::eTypeDouble);
+ return true;
+ } else if (sizeof(double) == sizeof(uint64_t)) {
+ value.SetUInt64(reg_value, RegisterValue::eTypeDouble);
+ return true;
+ }
+ break;
+
+// TOOD: need a better way to detect when "long double" types are
+// the same bytes size as "double"
+#if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__) && \
+ !defined(_MSC_VER) && !defined(__mips__) && !defined(__powerpc__) && \
+ !defined(__ANDROID__)
+ case sizeof(long double):
+ if (sizeof(long double) == sizeof(uint32_t)) {
+ value.SetUInt32(reg_value, RegisterValue::eTypeLongDouble);
+ return true;
+ } else if (sizeof(long double) == sizeof(uint64_t)) {
+ value.SetUInt64(reg_value, RegisterValue::eTypeLongDouble);
+ return true;
+ }
+ break;
#endif
- }
- break;
}
- return false;
+ break;
+ }
+ return false;
}
-bool
-RegisterContextMacOSXFrameBackchain::WriteRegister (const RegisterInfo *reg_info,
- const RegisterValue &value)
-{
- // Not supported yet. We could easily add support for this by remembering
- // the address of each entry (it would need to be part of the cursor)
- return false;
+bool RegisterContextMacOSXFrameBackchain::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &value) {
+ // Not supported yet. We could easily add support for this by remembering
+ // the address of each entry (it would need to be part of the cursor)
+ return false;
}
-bool
-RegisterContextMacOSXFrameBackchain::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
-{
- // libunwind frames can't handle this it doesn't always have all register
- // values. This call should only be called on frame zero anyway so there
- // shouldn't be any problem
- return false;
+bool RegisterContextMacOSXFrameBackchain::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ // libunwind frames can't handle this it doesn't always have all register
+ // values. This call should only be called on frame zero anyway so there
+ // shouldn't be any problem
+ return false;
}
-bool
-RegisterContextMacOSXFrameBackchain::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
-{
- // Since this class doesn't respond to "ReadAllRegisterValues()", it must
- // not have been the one that saved all the register values. So we just let
- // the thread's register context (the register context for frame zero) do
- // the writing.
- return m_thread.GetRegisterContext()->WriteAllRegisterValues(data_sp);
+bool RegisterContextMacOSXFrameBackchain::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ // Since this class doesn't respond to "ReadAllRegisterValues()", it must
+ // not have been the one that saved all the register values. So we just let
+ // the thread's register context (the register context for frame zero) do
+ // the writing.
+ return m_thread.GetRegisterContext()->WriteAllRegisterValues(data_sp);
}
-
uint32_t
-RegisterContextMacOSXFrameBackchain::ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t num)
-{
- return m_thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber (kind, num);
+RegisterContextMacOSXFrameBackchain::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t num) {
+ return m_thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber(
+ kind, num);
}
-
diff --git a/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h b/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h
index 0ddadbed01e0..4f5816aa4909 100644
--- a/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h
+++ b/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h
@@ -14,57 +14,48 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/lldb-private.h"
#include "UnwindMacOSXFrameBackchain.h"
-class RegisterContextMacOSXFrameBackchain : public lldb_private::RegisterContext
-{
+class RegisterContextMacOSXFrameBackchain
+ : public lldb_private::RegisterContext {
public:
- RegisterContextMacOSXFrameBackchain (lldb_private::Thread &thread,
- uint32_t concrete_frame_idx,
- const UnwindMacOSXFrameBackchain::Cursor &cursor);
+ RegisterContextMacOSXFrameBackchain(
+ lldb_private::Thread &thread, uint32_t concrete_frame_idx,
+ const UnwindMacOSXFrameBackchain::Cursor &cursor);
+
+ ~RegisterContextMacOSXFrameBackchain() override;
+
+ void InvalidateAllRegisters() override;
- ~RegisterContextMacOSXFrameBackchain() override;
+ size_t GetRegisterCount() override;
- void
- InvalidateAllRegisters() override;
+ const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
- size_t
- GetRegisterCount() override;
+ size_t GetRegisterSetCount() override;
- const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex(size_t reg) override;
+ const lldb_private::RegisterSet *GetRegisterSet(size_t reg_set) override;
- size_t
- GetRegisterSetCount() override;
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) override;
- const lldb_private::RegisterSet *
- GetRegisterSet(size_t reg_set) override;
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) override;
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value) override;
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value) override;
-
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
- uint32_t
- ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
-
private:
- UnwindMacOSXFrameBackchain::Cursor m_cursor;
- bool m_cursor_is_valid;
+ UnwindMacOSXFrameBackchain::Cursor m_cursor;
+ bool m_cursor_is_valid;
- DISALLOW_COPY_AND_ASSIGN (RegisterContextMacOSXFrameBackchain);
+ DISALLOW_COPY_AND_ASSIGN(RegisterContextMacOSXFrameBackchain);
};
#endif // lldb_RegisterContextMacOSXFrameBackchain_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp b/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp
index 7ceb536272f4..a4cf07710194 100644
--- a/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp
@@ -22,66 +22,50 @@
using namespace lldb;
using namespace lldb_private;
+RegisterContextMach_arm::RegisterContextMach_arm(Thread &thread,
+ uint32_t concrete_frame_idx)
+ : RegisterContextDarwin_arm(thread, concrete_frame_idx) {}
-RegisterContextMach_arm::RegisterContextMach_arm(Thread &thread, uint32_t concrete_frame_idx) :
- RegisterContextDarwin_arm (thread, concrete_frame_idx)
-{
-}
-
-RegisterContextMach_arm::~RegisterContextMach_arm()
-{
-}
+RegisterContextMach_arm::~RegisterContextMach_arm() {}
-int
-RegisterContextMach_arm::DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
-{
- mach_msg_type_number_t count = GPRWordCount;
- return ::thread_get_state(tid, flavor, (thread_state_t)&gpr, &count);
+int RegisterContextMach_arm::DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) {
+ mach_msg_type_number_t count = GPRWordCount;
+ return ::thread_get_state(tid, flavor, (thread_state_t)&gpr, &count);
}
-int
-RegisterContextMach_arm::DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
-{
- mach_msg_type_number_t count = FPUWordCount;
- return ::thread_get_state(tid, flavor, (thread_state_t)&fpu, &count);
+int RegisterContextMach_arm::DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) {
+ mach_msg_type_number_t count = FPUWordCount;
+ return ::thread_get_state(tid, flavor, (thread_state_t)&fpu, &count);
}
-int
-RegisterContextMach_arm::DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
-{
- mach_msg_type_number_t count = EXCWordCount;
- return ::thread_get_state(tid, flavor, (thread_state_t)&exc, &count);
+int RegisterContextMach_arm::DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) {
+ mach_msg_type_number_t count = EXCWordCount;
+ return ::thread_get_state(tid, flavor, (thread_state_t)&exc, &count);
}
-int
-RegisterContextMach_arm::DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg)
-{
- mach_msg_type_number_t count = DBGWordCount;
- return ::thread_get_state(tid, flavor, (thread_state_t)&dbg, &count);
+int RegisterContextMach_arm::DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) {
+ mach_msg_type_number_t count = DBGWordCount;
+ return ::thread_get_state(tid, flavor, (thread_state_t)&dbg, &count);
}
-int
-RegisterContextMach_arm::DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
-{
- return ::thread_set_state(tid, flavor, (thread_state_t)&gpr, GPRWordCount);
+int RegisterContextMach_arm::DoWriteGPR(lldb::tid_t tid, int flavor,
+ const GPR &gpr) {
+ return ::thread_set_state(tid, flavor, (thread_state_t)&gpr, GPRWordCount);
}
-int
-RegisterContextMach_arm::DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
-{
- return ::thread_set_state(tid, flavor, (thread_state_t)&fpu, FPUWordCount);
+int RegisterContextMach_arm::DoWriteFPU(lldb::tid_t tid, int flavor,
+ const FPU &fpu) {
+ return ::thread_set_state(tid, flavor, (thread_state_t)&fpu, FPUWordCount);
}
-int
-RegisterContextMach_arm::DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
-{
- return ::thread_set_state(tid, flavor, (thread_state_t)&exc, EXCWordCount);
+int RegisterContextMach_arm::DoWriteEXC(lldb::tid_t tid, int flavor,
+ const EXC &exc) {
+ return ::thread_set_state(tid, flavor, (thread_state_t)&exc, EXCWordCount);
}
-int
-RegisterContextMach_arm::DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg)
-{
- return ::thread_set_state(tid, flavor, (thread_state_t)&dbg, DBGWordCount);
+int RegisterContextMach_arm::DoWriteDBG(lldb::tid_t tid, int flavor,
+ const DBG &dbg) {
+ return ::thread_set_state(tid, flavor, (thread_state_t)&dbg, DBGWordCount);
}
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextMach_arm.h b/source/Plugins/Process/Utility/RegisterContextMach_arm.h
index e97a4bfff2b6..a2cf6bfcbe4a 100644
--- a/source/Plugins/Process/Utility/RegisterContextMach_arm.h
+++ b/source/Plugins/Process/Utility/RegisterContextMach_arm.h
@@ -17,40 +17,29 @@
// Project includes
#include "RegisterContextDarwin_arm.h"
-class RegisterContextMach_arm : public RegisterContextDarwin_arm
-{
+class RegisterContextMach_arm : public RegisterContextDarwin_arm {
public:
+ RegisterContextMach_arm(lldb_private::Thread &thread,
+ uint32_t concrete_frame_idx);
- RegisterContextMach_arm(lldb_private::Thread &thread, uint32_t concrete_frame_idx);
-
- virtual
- ~RegisterContextMach_arm();
+ virtual ~RegisterContextMach_arm();
protected:
+ virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr);
+
+ int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu);
+
+ int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc);
+
+ int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg);
+
+ int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr);
+
+ int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu);
+
+ int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc);
- virtual int
- DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr);
-
- int
- DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu);
-
- int
- DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc);
-
- int
- DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg);
-
- int
- DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr);
-
- int
- DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu);
-
- int
- DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc);
-
- int
- DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg);
+ int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg);
};
-#endif // liblldb_RegisterContextMach_arm_h_
+#endif // liblldb_RegisterContextMach_arm_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp b/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp
index 3d6c9a6baca6..959149edbc3e 100644
--- a/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp
@@ -20,53 +20,40 @@
using namespace lldb;
using namespace lldb_private;
+RegisterContextMach_i386::RegisterContextMach_i386(Thread &thread,
+ uint32_t concrete_frame_idx)
+ : RegisterContextDarwin_i386(thread, concrete_frame_idx) {}
-RegisterContextMach_i386::RegisterContextMach_i386(Thread &thread, uint32_t concrete_frame_idx) :
- RegisterContextDarwin_i386 (thread, concrete_frame_idx)
-{
-}
-
-RegisterContextMach_i386::~RegisterContextMach_i386()
-{
-}
+RegisterContextMach_i386::~RegisterContextMach_i386() {}
-int
-RegisterContextMach_i386::DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
-{
- mach_msg_type_number_t count = GPRWordCount;
- return ::thread_get_state(tid, flavor, (thread_state_t)&gpr, &count);
+int RegisterContextMach_i386::DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) {
+ mach_msg_type_number_t count = GPRWordCount;
+ return ::thread_get_state(tid, flavor, (thread_state_t)&gpr, &count);
}
-int
-RegisterContextMach_i386::DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
-{
- mach_msg_type_number_t count = FPUWordCount;
- return ::thread_get_state(tid, flavor, (thread_state_t)&fpu, &count);
+int RegisterContextMach_i386::DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) {
+ mach_msg_type_number_t count = FPUWordCount;
+ return ::thread_get_state(tid, flavor, (thread_state_t)&fpu, &count);
}
-int
-RegisterContextMach_i386::DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
-{
- mach_msg_type_number_t count = EXCWordCount;
- return ::thread_get_state(tid, flavor, (thread_state_t)&exc, &count);
+int RegisterContextMach_i386::DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) {
+ mach_msg_type_number_t count = EXCWordCount;
+ return ::thread_get_state(tid, flavor, (thread_state_t)&exc, &count);
}
-int
-RegisterContextMach_i386::DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
-{
- return ::thread_set_state(tid, flavor, (thread_state_t)&gpr, GPRWordCount);
+int RegisterContextMach_i386::DoWriteGPR(lldb::tid_t tid, int flavor,
+ const GPR &gpr) {
+ return ::thread_set_state(tid, flavor, (thread_state_t)&gpr, GPRWordCount);
}
-int
-RegisterContextMach_i386::DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
-{
- return ::thread_set_state(tid, flavor, (thread_state_t)&fpu, FPUWordCount);
+int RegisterContextMach_i386::DoWriteFPU(lldb::tid_t tid, int flavor,
+ const FPU &fpu) {
+ return ::thread_set_state(tid, flavor, (thread_state_t)&fpu, FPUWordCount);
}
-int
-RegisterContextMach_i386::DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
-{
- return ::thread_set_state(tid, flavor, (thread_state_t)&exc, EXCWordCount);
+int RegisterContextMach_i386::DoWriteEXC(lldb::tid_t tid, int flavor,
+ const EXC &exc) {
+ return ::thread_set_state(tid, flavor, (thread_state_t)&exc, EXCWordCount);
}
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextMach_i386.h b/source/Plugins/Process/Utility/RegisterContextMach_i386.h
index ad0f69d1c052..8ac693a55584 100644
--- a/source/Plugins/Process/Utility/RegisterContextMach_i386.h
+++ b/source/Plugins/Process/Utility/RegisterContextMach_i386.h
@@ -16,34 +16,25 @@
// Project includes
#include "RegisterContextDarwin_i386.h"
-class RegisterContextMach_i386 : public RegisterContextDarwin_i386
-{
+class RegisterContextMach_i386 : public RegisterContextDarwin_i386 {
public:
-
- RegisterContextMach_i386(lldb_private::Thread &thread, uint32_t concrete_frame_idx);
-
- virtual
- ~RegisterContextMach_i386();
-
+ RegisterContextMach_i386(lldb_private::Thread &thread,
+ uint32_t concrete_frame_idx);
+
+ virtual ~RegisterContextMach_i386();
+
protected:
-
- virtual int
- DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr);
-
- int
- DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu);
-
- int
- DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc);
-
- int
- DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr);
-
- int
- DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu);
-
- int
- DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc);
+ virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr);
+
+ int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu);
+
+ int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc);
+
+ int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr);
+
+ int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu);
+
+ int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc);
};
-#endif // liblldb_RegisterContextMach_i386_h_
+#endif // liblldb_RegisterContextMach_i386_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp b/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp
index f03685e1313f..522b73a2888e 100644
--- a/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp
@@ -20,53 +20,43 @@
using namespace lldb;
using namespace lldb_private;
+RegisterContextMach_x86_64::RegisterContextMach_x86_64(
+ Thread &thread, uint32_t concrete_frame_idx)
+ : RegisterContextDarwin_x86_64(thread, concrete_frame_idx) {}
-RegisterContextMach_x86_64::RegisterContextMach_x86_64(Thread &thread, uint32_t concrete_frame_idx) :
- RegisterContextDarwin_x86_64 (thread, concrete_frame_idx)
-{
-}
-
-RegisterContextMach_x86_64::~RegisterContextMach_x86_64()
-{
-}
+RegisterContextMach_x86_64::~RegisterContextMach_x86_64() {}
-int
-RegisterContextMach_x86_64::DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
-{
- mach_msg_type_number_t count = GPRWordCount;
- return ::thread_get_state(tid, flavor, (thread_state_t)&gpr, &count);
+int RegisterContextMach_x86_64::DoReadGPR(lldb::tid_t tid, int flavor,
+ GPR &gpr) {
+ mach_msg_type_number_t count = GPRWordCount;
+ return ::thread_get_state(tid, flavor, (thread_state_t)&gpr, &count);
}
-int
-RegisterContextMach_x86_64::DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
-{
- mach_msg_type_number_t count = FPUWordCount;
- return ::thread_get_state(tid, flavor, (thread_state_t)&fpu, &count);
+int RegisterContextMach_x86_64::DoReadFPU(lldb::tid_t tid, int flavor,
+ FPU &fpu) {
+ mach_msg_type_number_t count = FPUWordCount;
+ return ::thread_get_state(tid, flavor, (thread_state_t)&fpu, &count);
}
-int
-RegisterContextMach_x86_64::DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
-{
- mach_msg_type_number_t count = EXCWordCount;
- return ::thread_get_state(tid, flavor, (thread_state_t)&exc, &count);
+int RegisterContextMach_x86_64::DoReadEXC(lldb::tid_t tid, int flavor,
+ EXC &exc) {
+ mach_msg_type_number_t count = EXCWordCount;
+ return ::thread_get_state(tid, flavor, (thread_state_t)&exc, &count);
}
-int
-RegisterContextMach_x86_64::DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
-{
- return ::thread_set_state(tid, flavor, (thread_state_t)&gpr, GPRWordCount);
+int RegisterContextMach_x86_64::DoWriteGPR(lldb::tid_t tid, int flavor,
+ const GPR &gpr) {
+ return ::thread_set_state(tid, flavor, (thread_state_t)&gpr, GPRWordCount);
}
-int
-RegisterContextMach_x86_64::DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
-{
- return ::thread_set_state(tid, flavor, (thread_state_t)&fpu, FPUWordCount);
+int RegisterContextMach_x86_64::DoWriteFPU(lldb::tid_t tid, int flavor,
+ const FPU &fpu) {
+ return ::thread_set_state(tid, flavor, (thread_state_t)&fpu, FPUWordCount);
}
-int
-RegisterContextMach_x86_64::DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
-{
- return ::thread_set_state(tid, flavor, (thread_state_t)&exc, EXCWordCount);
+int RegisterContextMach_x86_64::DoWriteEXC(lldb::tid_t tid, int flavor,
+ const EXC &exc) {
+ return ::thread_set_state(tid, flavor, (thread_state_t)&exc, EXCWordCount);
}
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h b/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h
index 9e6dfa395500..cd425046b08e 100644
--- a/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h
+++ b/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h
@@ -1,4 +1,5 @@
-//===-- RegisterContextMach_x86_64.h ------------------------------*- C++ -*-===//
+//===-- RegisterContextMach_x86_64.h ------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,34 +17,25 @@
// Project includes
#include "RegisterContextDarwin_x86_64.h"
-class RegisterContextMach_x86_64 : public RegisterContextDarwin_x86_64
-{
+class RegisterContextMach_x86_64 : public RegisterContextDarwin_x86_64 {
public:
-
- RegisterContextMach_x86_64(lldb_private::Thread &thread, uint32_t concrete_frame_idx);
-
- virtual
- ~RegisterContextMach_x86_64();
-
+ RegisterContextMach_x86_64(lldb_private::Thread &thread,
+ uint32_t concrete_frame_idx);
+
+ virtual ~RegisterContextMach_x86_64();
+
protected:
-
- virtual int
- DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr);
-
- int
- DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu);
-
- int
- DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc);
-
- int
- DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr);
-
- int
- DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu);
-
- int
- DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc);
+ virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr);
+
+ int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu);
+
+ int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc);
+
+ int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr);
+
+ int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu);
+
+ int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc);
};
-#endif // liblldb_RegisterContextMach_x86_64_h_
+#endif // liblldb_RegisterContextMach_x86_64_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextMemory.cpp b/source/Plugins/Process/Utility/RegisterContextMemory.cpp
index 40d00b1eed80..57966e1729a6 100644
--- a/source/Plugins/Process/Utility/RegisterContextMemory.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextMemory.cpp
@@ -26,149 +26,123 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// RegisterContextMemory constructor
//----------------------------------------------------------------------
-RegisterContextMemory::RegisterContextMemory
-(
- Thread &thread,
- uint32_t concrete_frame_idx,
- DynamicRegisterInfo &reg_infos,
- addr_t reg_data_addr
-) :
- RegisterContext (thread, concrete_frame_idx),
- m_reg_infos (reg_infos),
- m_reg_valid (),
- m_reg_data (),
- m_reg_data_addr (reg_data_addr)
-{
- // Resize our vector of bools to contain one bool for every register.
- // We will use these boolean values to know when a register value
- // is valid in m_reg_data.
- const size_t num_regs = reg_infos.GetNumRegisters();
- assert (num_regs > 0);
- m_reg_valid.resize (num_regs);
-
- // Make a heap based buffer that is big enough to store all registers
- DataBufferSP reg_data_sp(new DataBufferHeap (reg_infos.GetRegisterDataByteSize(), 0));
- m_reg_data.SetData (reg_data_sp);
+RegisterContextMemory::RegisterContextMemory(Thread &thread,
+ uint32_t concrete_frame_idx,
+ DynamicRegisterInfo &reg_infos,
+ addr_t reg_data_addr)
+ : RegisterContext(thread, concrete_frame_idx), m_reg_infos(reg_infos),
+ m_reg_valid(), m_reg_data(), m_reg_data_addr(reg_data_addr) {
+ // Resize our vector of bools to contain one bool for every register.
+ // We will use these boolean values to know when a register value
+ // is valid in m_reg_data.
+ const size_t num_regs = reg_infos.GetNumRegisters();
+ assert(num_regs > 0);
+ m_reg_valid.resize(num_regs);
+
+ // Make a heap based buffer that is big enough to store all registers
+ DataBufferSP reg_data_sp(
+ new DataBufferHeap(reg_infos.GetRegisterDataByteSize(), 0));
+ m_reg_data.SetData(reg_data_sp);
}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-RegisterContextMemory::~RegisterContextMemory()
-{
-}
+RegisterContextMemory::~RegisterContextMemory() {}
-void
-RegisterContextMemory::InvalidateAllRegisters ()
-{
- if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
- SetAllRegisterValid (false);
+void RegisterContextMemory::InvalidateAllRegisters() {
+ if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
+ SetAllRegisterValid(false);
}
-void
-RegisterContextMemory::SetAllRegisterValid (bool b)
-{
- std::vector<bool>::iterator pos, end = m_reg_valid.end();
- for (pos = m_reg_valid.begin(); pos != end; ++pos)
- *pos = b;
+void RegisterContextMemory::SetAllRegisterValid(bool b) {
+ std::vector<bool>::iterator pos, end = m_reg_valid.end();
+ for (pos = m_reg_valid.begin(); pos != end; ++pos)
+ *pos = b;
}
-size_t
-RegisterContextMemory::GetRegisterCount ()
-{
- return m_reg_infos.GetNumRegisters ();
+size_t RegisterContextMemory::GetRegisterCount() {
+ return m_reg_infos.GetNumRegisters();
}
-const RegisterInfo *
-RegisterContextMemory::GetRegisterInfoAtIndex (size_t reg)
-{
- return m_reg_infos.GetRegisterInfoAtIndex (reg);
+const RegisterInfo *RegisterContextMemory::GetRegisterInfoAtIndex(size_t reg) {
+ return m_reg_infos.GetRegisterInfoAtIndex(reg);
}
-size_t
-RegisterContextMemory::GetRegisterSetCount ()
-{
- return m_reg_infos.GetNumRegisterSets ();
+size_t RegisterContextMemory::GetRegisterSetCount() {
+ return m_reg_infos.GetNumRegisterSets();
}
-const RegisterSet *
-RegisterContextMemory::GetRegisterSet (size_t reg_set)
-{
- return m_reg_infos.GetRegisterSet (reg_set);
+const RegisterSet *RegisterContextMemory::GetRegisterSet(size_t reg_set) {
+ return m_reg_infos.GetRegisterSet(reg_set);
}
-uint32_t
-RegisterContextMemory::ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t num)
-{
- return m_reg_infos.ConvertRegisterKindToRegisterNumber (kind, num);
+uint32_t RegisterContextMemory::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t num) {
+ return m_reg_infos.ConvertRegisterKindToRegisterNumber(kind, num);
}
-bool
-RegisterContextMemory::ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value)
-{
- const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB];
- if (!m_reg_valid[reg_num])
- {
- if (!ReadAllRegisterValues(m_reg_data.GetSharedDataBuffer ()))
- return false;
- }
- const bool partial_data_ok = false;
- return reg_value.SetValueFromData(reg_info, m_reg_data, reg_info->byte_offset, partial_data_ok).Success();
+bool RegisterContextMemory::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) {
+ const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB];
+ if (!m_reg_valid[reg_num]) {
+ if (!ReadAllRegisterValues(m_reg_data.GetSharedDataBuffer()))
+ return false;
+ }
+ const bool partial_data_ok = false;
+ return reg_value
+ .SetValueFromData(reg_info, m_reg_data, reg_info->byte_offset,
+ partial_data_ok)
+ .Success();
}
-bool
-RegisterContextMemory::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value)
-{
- if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
- {
- const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB];
- addr_t reg_addr = m_reg_data_addr + reg_info->byte_offset;
- Error error (WriteRegisterValueToMemory(reg_info, reg_addr, reg_info->byte_size, reg_value));
- m_reg_valid[reg_num] = false;
- return error.Success();
- }
- return false;
+bool RegisterContextMemory::WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) {
+ if (m_reg_data_addr != LLDB_INVALID_ADDRESS) {
+ const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB];
+ addr_t reg_addr = m_reg_data_addr + reg_info->byte_offset;
+ Error error(WriteRegisterValueToMemory(reg_info, reg_addr,
+ reg_info->byte_size, reg_value));
+ m_reg_valid[reg_num] = false;
+ return error.Success();
+ }
+ return false;
}
-bool
-RegisterContextMemory::ReadAllRegisterValues (DataBufferSP &data_sp)
-{
- if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
- {
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- if (process_sp->ReadMemory(m_reg_data_addr, data_sp->GetBytes(), data_sp->GetByteSize(), error) == data_sp->GetByteSize())
- {
- SetAllRegisterValid (true);
- return true;
- }
- }
+bool RegisterContextMemory::ReadAllRegisterValues(DataBufferSP &data_sp) {
+ if (m_reg_data_addr != LLDB_INVALID_ADDRESS) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ if (process_sp->ReadMemory(m_reg_data_addr, data_sp->GetBytes(),
+ data_sp->GetByteSize(),
+ error) == data_sp->GetByteSize()) {
+ SetAllRegisterValid(true);
+ return true;
+ }
}
- return false;
+ }
+ return false;
}
-bool
-RegisterContextMemory::WriteAllRegisterValues (const DataBufferSP &data_sp)
-{
- if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
- {
- ProcessSP process_sp (CalculateProcess());
- if (process_sp)
- {
- Error error;
- SetAllRegisterValid (false);
- if (process_sp->WriteMemory(m_reg_data_addr, data_sp->GetBytes(), data_sp->GetByteSize(), error) == data_sp->GetByteSize())
- return true;
- }
+bool RegisterContextMemory::WriteAllRegisterValues(
+ const DataBufferSP &data_sp) {
+ if (m_reg_data_addr != LLDB_INVALID_ADDRESS) {
+ ProcessSP process_sp(CalculateProcess());
+ if (process_sp) {
+ Error error;
+ SetAllRegisterValid(false);
+ if (process_sp->WriteMemory(m_reg_data_addr, data_sp->GetBytes(),
+ data_sp->GetByteSize(),
+ error) == data_sp->GetByteSize())
+ return true;
}
- return false;
+ }
+ return false;
}
-void
-RegisterContextMemory::SetAllRegisterData (const lldb::DataBufferSP &data_sp)
-{
- m_reg_data.SetData(data_sp);
- SetAllRegisterValid (true);
+void RegisterContextMemory::SetAllRegisterData(
+ const lldb::DataBufferSP &data_sp) {
+ m_reg_data.SetData(data_sp);
+ SetAllRegisterValid(true);
}
diff --git a/source/Plugins/Process/Utility/RegisterContextMemory.h b/source/Plugins/Process/Utility/RegisterContextMemory.h
index d61aba9543d4..55de0412b094 100644
--- a/source/Plugins/Process/Utility/RegisterContextMemory.h
+++ b/source/Plugins/Process/Utility/RegisterContextMemory.h
@@ -16,76 +16,65 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/lldb-private.h"
class DynamicRegisterInfo;
-class RegisterContextMemory : public lldb_private::RegisterContext
-{
+class RegisterContextMemory : public lldb_private::RegisterContext {
public:
- RegisterContextMemory (lldb_private::Thread &thread,
- uint32_t concrete_frame_idx,
- DynamicRegisterInfo &reg_info,
- lldb::addr_t reg_data_addr);
-
- ~RegisterContextMemory() override;
-
- void
- InvalidateAllRegisters() override;
-
- size_t
- GetRegisterCount() override;
-
- const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex(size_t reg) override;
-
- size_t
- GetRegisterSetCount() override;
-
- const lldb_private::RegisterSet *
- GetRegisterSet(size_t reg_set) override;
-
- uint32_t
- ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
-
- //------------------------------------------------------------------
- // If all of the thread register are in a contiguous buffer in
- // memory, then the default ReadRegister/WriteRegister and
- // ReadAllRegisterValues/WriteAllRegisterValues will work. If thread
- // registers are not contiguous, clients will want to subclass this
- // class and modify the read/write functions as needed.
- //------------------------------------------------------------------
-
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &reg_value) override;
-
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &reg_value) override;
-
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
-
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
-
- void
- SetAllRegisterData (const lldb::DataBufferSP &data_sp);
+ RegisterContextMemory(lldb_private::Thread &thread,
+ uint32_t concrete_frame_idx,
+ DynamicRegisterInfo &reg_info,
+ lldb::addr_t reg_data_addr);
+
+ ~RegisterContextMemory() override;
+
+ void InvalidateAllRegisters() override;
+
+ size_t GetRegisterCount() override;
+
+ const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
+
+ size_t GetRegisterSetCount() override;
+
+ const lldb_private::RegisterSet *GetRegisterSet(size_t reg_set) override;
+
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
+
+ //------------------------------------------------------------------
+ // If all of the thread register are in a contiguous buffer in
+ // memory, then the default ReadRegister/WriteRegister and
+ // ReadAllRegisterValues/WriteAllRegisterValues will work. If thread
+ // registers are not contiguous, clients will want to subclass this
+ // class and modify the read/write functions as needed.
+ //------------------------------------------------------------------
+
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &reg_value) override;
+
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &reg_value) override;
+
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+
+ void SetAllRegisterData(const lldb::DataBufferSP &data_sp);
protected:
- void
- SetAllRegisterValid (bool b);
+ void SetAllRegisterValid(bool b);
- DynamicRegisterInfo &m_reg_infos;
- std::vector<bool> m_reg_valid;
- lldb_private::DataExtractor m_reg_data;
- lldb::addr_t m_reg_data_addr; // If this is valid, then we have a register context that is stored in memmory
+ DynamicRegisterInfo &m_reg_infos;
+ std::vector<bool> m_reg_valid;
+ lldb_private::DataExtractor m_reg_data;
+ lldb::addr_t m_reg_data_addr; // If this is valid, then we have a register
+ // context that is stored in memmory
private:
- DISALLOW_COPY_AND_ASSIGN (RegisterContextMemory);
+ DISALLOW_COPY_AND_ASSIGN(RegisterContextMemory);
};
#endif // lldb_RegisterContextMemory_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp b/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp
index 71ece160d4d4..4f64a8c4f321 100644
--- a/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp
@@ -1,52 +1,50 @@
-//===-- RegisterContextNetBSD_x86_64.cpp ----------------------*- C++ -*-===//
+//===-- RegisterContextNetBSD_x86_64.cpp ------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
-//===---------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
-#include <cstddef>
-#include <vector>
-
-#include "llvm/Support/Compiler.h"
-
-#include "RegisterContextPOSIX_x86.h"
#include "RegisterContextNetBSD_x86_64.h"
+#include "RegisterContextPOSIX_x86.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/Compiler.h"
+#include <cassert>
+#include <cstddef>
using namespace lldb_private;
using namespace lldb;
// src/sys/arch/amd64/include/frame_regs.h
-typedef struct _GPR
-{
- uint64_t rdi; /* 0 */
- uint64_t rsi; /* 1 */
- uint64_t rdx; /* 2 */
- uint64_t rcx; /* 3 */
- uint64_t r8; /* 4 */
- uint64_t r9; /* 5 */
- uint64_t r10; /* 6 */
- uint64_t r11; /* 7 */
- uint64_t r12; /* 8 */
- uint64_t r13; /* 9 */
- uint64_t r14; /* 10 */
- uint64_t r15; /* 11 */
- uint64_t rbp; /* 12 */
- uint64_t rbx; /* 13 */
- uint64_t rax; /* 14 */
- uint64_t gs; /* 15 */
- uint64_t fs; /* 16 */
- uint64_t es; /* 17 */
- uint64_t ds; /* 18 */
- uint64_t trapno; /* 19 */
- uint64_t err; /* 20 */
- uint64_t rip; /* 21 */
- uint64_t cs; /* 22 */
- uint64_t rflags; /* 23 */
- uint64_t rsp; /* 24 */
- uint64_t ss; /* 25 */
+typedef struct _GPR {
+ uint64_t rdi; /* 0 */
+ uint64_t rsi; /* 1 */
+ uint64_t rdx; /* 2 */
+ uint64_t rcx; /* 3 */
+ uint64_t r8; /* 4 */
+ uint64_t r9; /* 5 */
+ uint64_t r10; /* 6 */
+ uint64_t r11; /* 7 */
+ uint64_t r12; /* 8 */
+ uint64_t r13; /* 9 */
+ uint64_t r14; /* 10 */
+ uint64_t r15; /* 11 */
+ uint64_t rbp; /* 12 */
+ uint64_t rbx; /* 13 */
+ uint64_t rax; /* 14 */
+ uint64_t gs; /* 15 */
+ uint64_t fs; /* 16 */
+ uint64_t es; /* 17 */
+ uint64_t ds; /* 18 */
+ uint64_t trapno; /* 19 */
+ uint64_t err; /* 20 */
+ uint64_t rip; /* 21 */
+ uint64_t cs; /* 22 */
+ uint64_t rflags; /* 23 */
+ uint64_t rsp; /* 24 */
+ uint64_t ss; /* 25 */
} GPR;
/*
@@ -65,38 +63,35 @@ typedef struct _GPR
*/
struct UserArea {
- GPR gpr;
- uint64_t mc_tlsbase;
- FPR fpr;
+ GPR gpr;
+ uint64_t mc_tlsbase;
+ FPR fpr;
};
-
//---------------------------------------------------------------------------
// Cherry-pick parts of RegisterInfos_x86_64.h, without debug registers
//---------------------------------------------------------------------------
// Computes the offset of the given GPR in the user data area.
-#define GPR_OFFSET(regname) \
- (LLVM_EXTENSION offsetof(GPR, regname))
+#define GPR_OFFSET(regname) (LLVM_EXTENSION offsetof(GPR, regname))
// Computes the offset of the given FPR in the extended data area.
-#define FPR_OFFSET(regname) \
- (LLVM_EXTENSION offsetof(UserArea, fpr) + \
- LLVM_EXTENSION offsetof(FPR, xstate) + \
- LLVM_EXTENSION offsetof(FXSAVE, regname))
+#define FPR_OFFSET(regname) \
+ (LLVM_EXTENSION offsetof(UserArea, fpr) + \
+ LLVM_EXTENSION offsetof(FPR, xstate) + \
+ LLVM_EXTENSION offsetof(FXSAVE, regname))
// Computes the offset of the YMM register assembled from register halves.
// Based on DNBArchImplX86_64.cpp from debugserver
-#define YMM_OFFSET(reg_index) \
- (LLVM_EXTENSION offsetof(UserArea, fpr) + \
- LLVM_EXTENSION offsetof(FPR, xstate) + \
- LLVM_EXTENSION offsetof(XSAVE, ymmh[0]) + \
- (32 * reg_index))
+#define YMM_OFFSET(reg_index) \
+ (LLVM_EXTENSION offsetof(UserArea, fpr) + \
+ LLVM_EXTENSION offsetof(FPR, xstate) + \
+ LLVM_EXTENSION offsetof(XSAVE, ymmh[0]) + (32 * reg_index))
// Number of bytes needed to represent a FPR.
-#define FPR_SIZE(reg) sizeof(((FXSAVE*)NULL)->reg)
+#define FPR_SIZE(reg) sizeof(((FXSAVE *)nullptr)->reg)
// Number of bytes needed to represent the i'th FP register.
-#define FP_SIZE sizeof(((MMSReg*)NULL)->bytes)
+#define FP_SIZE sizeof(((MMSReg *)nullptr)->bytes)
// Number of bytes needed to represent an XMM register.
#define XMM_SIZE sizeof(XMMReg)
@@ -107,197 +102,234 @@ struct UserArea {
// RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB
// Note that the size and offset will be updated by platform-specific classes.
-#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
- { #reg, alt, sizeof(((GPR*)NULL)->reg), GPR_OFFSET(reg), eEncodingUint, \
- eFormatHex, { kind1, kind2, kind3, kind4, lldb_##reg##_x86_64 }, NULL, NULL }
-
-#define DEFINE_FPR(name, reg, kind1, kind2, kind3, kind4) \
- { #name, NULL, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, \
- eFormatHex, { kind1, kind2, kind3, kind4, lldb_##name##_x86_64 }, NULL, NULL }
-
-#define DEFINE_FP_ST(reg, i) \
- { #reg#i, NULL, FP_SIZE, LLVM_EXTENSION FPR_OFFSET(stmm[i]), \
- eEncodingVector, eFormatVectorOfUInt8, \
- { dwarf_st##i##_x86_64, dwarf_st##i##_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_st##i##_x86_64 }, \
- NULL, NULL }
-
-#define DEFINE_FP_MM(reg, i) \
- { #reg#i, NULL, sizeof(uint64_t), LLVM_EXTENSION FPR_OFFSET(stmm[i]), \
- eEncodingUint, eFormatHex, \
- { dwarf_mm##i##_x86_64, dwarf_mm##i##_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_mm##i##_x86_64 }, \
- NULL, NULL }
-
-#define DEFINE_XMM(reg, i) \
- { #reg#i, NULL, XMM_SIZE, LLVM_EXTENSION FPR_OFFSET(reg[i]), \
- eEncodingVector, eFormatVectorOfUInt8, \
- { dwarf_##reg##i##_x86_64, dwarf_##reg##i##_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg##i##_x86_64}, \
- NULL, NULL }
-
-#define DEFINE_YMM(reg, i) \
- { #reg#i, NULL, YMM_SIZE, LLVM_EXTENSION YMM_OFFSET(i), \
- eEncodingVector, eFormatVectorOfUInt8, \
- { dwarf_##reg##i##h_x86_64, dwarf_##reg##i##h_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg##i##_x86_64 }, \
- NULL, NULL }
-
-#define DEFINE_GPR_PSEUDO_32(reg32, reg64) \
- { #reg32, NULL, 4, GPR_OFFSET(reg64), eEncodingUint, \
- eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg32##_x86_64 }, RegisterContextPOSIX_x86::g_contained_##reg64, RegisterContextPOSIX_x86::g_invalidate_##reg64 }
-#define DEFINE_GPR_PSEUDO_16(reg16, reg64) \
- { #reg16, NULL, 2, GPR_OFFSET(reg64), eEncodingUint, \
- eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg16##_x86_64 }, RegisterContextPOSIX_x86::g_contained_##reg64, RegisterContextPOSIX_x86::g_invalidate_##reg64 }
-#define DEFINE_GPR_PSEUDO_8H(reg8, reg64) \
- { #reg8, NULL, 1, GPR_OFFSET(reg64)+1, eEncodingUint, \
- eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg8##_x86_64 }, RegisterContextPOSIX_x86::g_contained_##reg64, RegisterContextPOSIX_x86::g_invalidate_##reg64 }
-#define DEFINE_GPR_PSEUDO_8L(reg8, reg64) \
- { #reg8, NULL, 1, GPR_OFFSET(reg64), eEncodingUint, \
- eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg8##_x86_64 }, RegisterContextPOSIX_x86::g_contained_##reg64, RegisterContextPOSIX_x86::g_invalidate_##reg64 }
-
-static RegisterInfo
-g_register_infos_x86_64[] =
-{
- // General purpose registers. EH_Frame, DWARF, Generic, Process Plugin
- DEFINE_GPR(rax, nullptr, dwarf_rax_x86_64, dwarf_rax_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rbx, nullptr, dwarf_rbx_x86_64, dwarf_rbx_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rcx, "arg4", dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rdx, "arg3", dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rdi, "arg1", dwarf_rdi_x86_64, dwarf_rdi_x86_64, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rsi, "arg2", dwarf_rsi_x86_64, dwarf_rsi_x86_64, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rbp, "fp", dwarf_rbp_x86_64, dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rsp, "sp", dwarf_rsp_x86_64, dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r8, "arg5", dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r9, "arg6", dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r10, nullptr, dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r11, nullptr, dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r12, nullptr, dwarf_r12_x86_64, dwarf_r12_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r13, nullptr, dwarf_r13_x86_64, dwarf_r13_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r14, nullptr, dwarf_r14_x86_64, dwarf_r14_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r15, nullptr, dwarf_r15_x86_64, dwarf_r15_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rip, "pc", dwarf_rip_x86_64, dwarf_rip_x86_64, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rflags, "flags", dwarf_rflags_x86_64, dwarf_rflags_x86_64, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM),
- DEFINE_GPR(cs, nullptr, dwarf_cs_x86_64, dwarf_cs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(fs, nullptr, dwarf_fs_x86_64, dwarf_fs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(gs, nullptr, dwarf_gs_x86_64, dwarf_gs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(ss, nullptr, dwarf_ss_x86_64, dwarf_ss_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(ds, nullptr, dwarf_ds_x86_64, dwarf_ds_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(es, nullptr, dwarf_es_x86_64, dwarf_es_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-
- DEFINE_GPR_PSEUDO_32(eax, rax),
- DEFINE_GPR_PSEUDO_32(ebx, rbx),
- DEFINE_GPR_PSEUDO_32(ecx, rcx),
- DEFINE_GPR_PSEUDO_32(edx, rdx),
- DEFINE_GPR_PSEUDO_32(edi, rdi),
- DEFINE_GPR_PSEUDO_32(esi, rsi),
- DEFINE_GPR_PSEUDO_32(ebp, rbp),
- DEFINE_GPR_PSEUDO_32(esp, rsp),
- DEFINE_GPR_PSEUDO_32(r8d, r8),
- DEFINE_GPR_PSEUDO_32(r9d, r9),
- DEFINE_GPR_PSEUDO_32(r10d, r10),
- DEFINE_GPR_PSEUDO_32(r11d, r11),
- DEFINE_GPR_PSEUDO_32(r12d, r12),
- DEFINE_GPR_PSEUDO_32(r13d, r13),
- DEFINE_GPR_PSEUDO_32(r14d, r14),
- DEFINE_GPR_PSEUDO_32(r15d, r15),
- DEFINE_GPR_PSEUDO_16(ax, rax),
- DEFINE_GPR_PSEUDO_16(bx, rbx),
- DEFINE_GPR_PSEUDO_16(cx, rcx),
- DEFINE_GPR_PSEUDO_16(dx, rdx),
- DEFINE_GPR_PSEUDO_16(di, rdi),
- DEFINE_GPR_PSEUDO_16(si, rsi),
- DEFINE_GPR_PSEUDO_16(bp, rbp),
- DEFINE_GPR_PSEUDO_16(sp, rsp),
- DEFINE_GPR_PSEUDO_16(r8w, r8),
- DEFINE_GPR_PSEUDO_16(r9w, r9),
- DEFINE_GPR_PSEUDO_16(r10w, r10),
- DEFINE_GPR_PSEUDO_16(r11w, r11),
- DEFINE_GPR_PSEUDO_16(r12w, r12),
- DEFINE_GPR_PSEUDO_16(r13w, r13),
- DEFINE_GPR_PSEUDO_16(r14w, r14),
- DEFINE_GPR_PSEUDO_16(r15w, r15),
- DEFINE_GPR_PSEUDO_8H(ah, rax),
- DEFINE_GPR_PSEUDO_8H(bh, rbx),
- DEFINE_GPR_PSEUDO_8H(ch, rcx),
- DEFINE_GPR_PSEUDO_8H(dh, rdx),
- DEFINE_GPR_PSEUDO_8L(al, rax),
- DEFINE_GPR_PSEUDO_8L(bl, rbx),
- DEFINE_GPR_PSEUDO_8L(cl, rcx),
- DEFINE_GPR_PSEUDO_8L(dl, rdx),
- DEFINE_GPR_PSEUDO_8L(dil, rdi),
- DEFINE_GPR_PSEUDO_8L(sil, rsi),
- DEFINE_GPR_PSEUDO_8L(bpl, rbp),
- DEFINE_GPR_PSEUDO_8L(spl, rsp),
- DEFINE_GPR_PSEUDO_8L(r8l, r8),
- DEFINE_GPR_PSEUDO_8L(r9l, r9),
- DEFINE_GPR_PSEUDO_8L(r10l, r10),
- DEFINE_GPR_PSEUDO_8L(r11l, r11),
- DEFINE_GPR_PSEUDO_8L(r12l, r12),
- DEFINE_GPR_PSEUDO_8L(r13l, r13),
- DEFINE_GPR_PSEUDO_8L(r14l, r14),
- DEFINE_GPR_PSEUDO_8L(r15l, r15),
-
- // i387 Floating point registers. EH_frame, DWARF, Generic, Process Plugin
- DEFINE_FPR(fctrl, fctrl, dwarf_fctrl_x86_64, dwarf_fctrl_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(fstat, fstat, dwarf_fstat_x86_64, dwarf_fstat_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(ftag, ftag, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(fop, fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(fiseg, ptr.i386_.fiseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(fioff, ptr.i386_.fioff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(foseg, ptr.i386_.foseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(fooff, ptr.i386_.fooff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(mxcsr, mxcsr, dwarf_mxcsr_x86_64, dwarf_mxcsr_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(mxcsrmask, mxcsrmask, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
+ { \
+ #reg, alt, sizeof(((GPR *)nullptr)->reg), \
+ GPR_OFFSET(reg), eEncodingUint, eFormatHex, \
+ {kind1, kind2, kind3, kind4, \
+ lldb_##reg##_x86_64 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_FPR(name, reg, kind1, kind2, kind3, kind4) \
+ { \
+ #name, nullptr, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, eFormatHex, \
+ {kind1, kind2, kind3, kind4, \
+ lldb_##name##_x86_64 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_FP_ST(reg, i) \
+ { \
+ #reg #i, nullptr, FP_SIZE, \
+ LLVM_EXTENSION FPR_OFFSET( \
+ stmm[i]), eEncodingVector, eFormatVectorOfUInt8, \
+ {dwarf_st##i##_x86_64, dwarf_st##i##_x86_64, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, lldb_st##i##_x86_64 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_FP_MM(reg, i) \
+ { \
+ #reg #i, nullptr, sizeof(uint64_t), \
+ LLVM_EXTENSION FPR_OFFSET( \
+ stmm[i]), eEncodingUint, eFormatHex, \
+ {dwarf_mm##i##_x86_64, dwarf_mm##i##_x86_64, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_mm##i##_x86_64 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_XMM(reg, i) \
+ { \
+ #reg #i, nullptr, XMM_SIZE, \
+ LLVM_EXTENSION FPR_OFFSET( \
+ reg[i]), eEncodingVector, eFormatVectorOfUInt8, \
+ {dwarf_##reg##i##_x86_64, dwarf_##reg##i##_x86_64, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg##i##_x86_64 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_YMM(reg, i) \
+ { \
+ #reg #i, nullptr, YMM_SIZE, \
+ LLVM_EXTENSION YMM_OFFSET(i), eEncodingVector, eFormatVectorOfUInt8, \
+ {dwarf_##reg##i##h_x86_64, \
+ dwarf_##reg##i##h_x86_64, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg##i##_x86_64 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_GPR_PSEUDO_32(reg32, reg64) \
+ { \
+ #reg32, nullptr, 4, \
+ GPR_OFFSET(reg64), eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg32##_x86_64 }, \
+ RegisterContextPOSIX_x86::g_contained_##reg64, \
+ RegisterContextPOSIX_x86::g_invalidate_##reg64, nullptr, 0 \
+ }
+
+#define DEFINE_GPR_PSEUDO_16(reg16, reg64) \
+ { \
+ #reg16, nullptr, 2, \
+ GPR_OFFSET(reg64), eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg16##_x86_64 }, \
+ RegisterContextPOSIX_x86::g_contained_##reg64, \
+ RegisterContextPOSIX_x86::g_invalidate_##reg64, nullptr, 0 \
+ }
+
+#define DEFINE_GPR_PSEUDO_8H(reg8, reg64) \
+ { \
+ #reg8, nullptr, 1, GPR_OFFSET(reg64) + 1, eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg8##_x86_64 }, \
+ RegisterContextPOSIX_x86::g_contained_##reg64, \
+ RegisterContextPOSIX_x86::g_invalidate_##reg64,\
+ nullptr, 0 \
+ }
+
+#define DEFINE_GPR_PSEUDO_8L(reg8, reg64) \
+ { \
+ #reg8, nullptr, 1, GPR_OFFSET(reg64), eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg8##_x86_64 }, \
+ RegisterContextPOSIX_x86::g_contained_##reg64, \
+ RegisterContextPOSIX_x86::g_invalidate_##reg64,\
+ nullptr, 0 \
+ }
+
+static RegisterInfo g_register_infos_x86_64[] = {
+ // General purpose registers. EH_Frame, DWARF,
+ // Generic, Process Plugin
+ DEFINE_GPR(rax, nullptr, dwarf_rax_x86_64, dwarf_rax_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rbx, nullptr, dwarf_rbx_x86_64, dwarf_rbx_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rcx, "arg4", dwarf_rcx_x86_64, dwarf_rcx_x86_64,
+ LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rdx, "arg3", dwarf_rdx_x86_64, dwarf_rdx_x86_64,
+ LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rdi, "arg1", dwarf_rdi_x86_64, dwarf_rdi_x86_64,
+ LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rsi, "arg2", dwarf_rsi_x86_64, dwarf_rsi_x86_64,
+ LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rbp, "fp", dwarf_rbp_x86_64, dwarf_rbp_x86_64,
+ LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rsp, "sp", dwarf_rsp_x86_64, dwarf_rsp_x86_64,
+ LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r8, "arg5", dwarf_r8_x86_64, dwarf_r8_x86_64,
+ LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r9, "arg6", dwarf_r9_x86_64, dwarf_r9_x86_64,
+ LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r10, nullptr, dwarf_r10_x86_64, dwarf_r10_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r11, nullptr, dwarf_r11_x86_64, dwarf_r11_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r12, nullptr, dwarf_r12_x86_64, dwarf_r12_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r13, nullptr, dwarf_r13_x86_64, dwarf_r13_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r14, nullptr, dwarf_r14_x86_64, dwarf_r14_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r15, nullptr, dwarf_r15_x86_64, dwarf_r15_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rip, "pc", dwarf_rip_x86_64, dwarf_rip_x86_64,
+ LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rflags, "flags", dwarf_rflags_x86_64, dwarf_rflags_x86_64,
+ LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(cs, nullptr, dwarf_cs_x86_64, dwarf_cs_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(fs, nullptr, dwarf_fs_x86_64, dwarf_fs_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(gs, nullptr, dwarf_gs_x86_64, dwarf_gs_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ss, nullptr, dwarf_ss_x86_64, dwarf_ss_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ds, nullptr, dwarf_ds_x86_64, dwarf_ds_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(es, nullptr, dwarf_es_x86_64, dwarf_es_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+
+ DEFINE_GPR_PSEUDO_32(eax, rax), DEFINE_GPR_PSEUDO_32(ebx, rbx),
+ DEFINE_GPR_PSEUDO_32(ecx, rcx), DEFINE_GPR_PSEUDO_32(edx, rdx),
+ DEFINE_GPR_PSEUDO_32(edi, rdi), DEFINE_GPR_PSEUDO_32(esi, rsi),
+ DEFINE_GPR_PSEUDO_32(ebp, rbp), DEFINE_GPR_PSEUDO_32(esp, rsp),
+ DEFINE_GPR_PSEUDO_32(r8d, r8), DEFINE_GPR_PSEUDO_32(r9d, r9),
+ DEFINE_GPR_PSEUDO_32(r10d, r10), DEFINE_GPR_PSEUDO_32(r11d, r11),
+ DEFINE_GPR_PSEUDO_32(r12d, r12), DEFINE_GPR_PSEUDO_32(r13d, r13),
+ DEFINE_GPR_PSEUDO_32(r14d, r14), DEFINE_GPR_PSEUDO_32(r15d, r15),
+ DEFINE_GPR_PSEUDO_16(ax, rax), DEFINE_GPR_PSEUDO_16(bx, rbx),
+ DEFINE_GPR_PSEUDO_16(cx, rcx), DEFINE_GPR_PSEUDO_16(dx, rdx),
+ DEFINE_GPR_PSEUDO_16(di, rdi), DEFINE_GPR_PSEUDO_16(si, rsi),
+ DEFINE_GPR_PSEUDO_16(bp, rbp), DEFINE_GPR_PSEUDO_16(sp, rsp),
+ DEFINE_GPR_PSEUDO_16(r8w, r8), DEFINE_GPR_PSEUDO_16(r9w, r9),
+ DEFINE_GPR_PSEUDO_16(r10w, r10), DEFINE_GPR_PSEUDO_16(r11w, r11),
+ DEFINE_GPR_PSEUDO_16(r12w, r12), DEFINE_GPR_PSEUDO_16(r13w, r13),
+ DEFINE_GPR_PSEUDO_16(r14w, r14), DEFINE_GPR_PSEUDO_16(r15w, r15),
+ DEFINE_GPR_PSEUDO_8H(ah, rax), DEFINE_GPR_PSEUDO_8H(bh, rbx),
+ DEFINE_GPR_PSEUDO_8H(ch, rcx), DEFINE_GPR_PSEUDO_8H(dh, rdx),
+ DEFINE_GPR_PSEUDO_8L(al, rax), DEFINE_GPR_PSEUDO_8L(bl, rbx),
+ DEFINE_GPR_PSEUDO_8L(cl, rcx), DEFINE_GPR_PSEUDO_8L(dl, rdx),
+ DEFINE_GPR_PSEUDO_8L(dil, rdi), DEFINE_GPR_PSEUDO_8L(sil, rsi),
+ DEFINE_GPR_PSEUDO_8L(bpl, rbp), DEFINE_GPR_PSEUDO_8L(spl, rsp),
+ DEFINE_GPR_PSEUDO_8L(r8l, r8), DEFINE_GPR_PSEUDO_8L(r9l, r9),
+ DEFINE_GPR_PSEUDO_8L(r10l, r10), DEFINE_GPR_PSEUDO_8L(r11l, r11),
+ DEFINE_GPR_PSEUDO_8L(r12l, r12), DEFINE_GPR_PSEUDO_8L(r13l, r13),
+ DEFINE_GPR_PSEUDO_8L(r14l, r14), DEFINE_GPR_PSEUDO_8L(r15l, r15),
+
+ // i387 Floating point registers. EH_frame,
+ // DWARF, Generic, Process Plugin
+ DEFINE_FPR(fctrl, fctrl, dwarf_fctrl_x86_64, dwarf_fctrl_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fstat, fstat, dwarf_fstat_x86_64, dwarf_fstat_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(ftag, ftag, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fop, fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fiseg, ptr.i386_.fiseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fioff, ptr.i386_.fioff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(foseg, ptr.i386_.foseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fooff, ptr.i386_.fooff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(mxcsr, mxcsr, dwarf_mxcsr_x86_64, dwarf_mxcsr_x86_64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(mxcsrmask, mxcsrmask, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
// FP registers.
- DEFINE_FP_ST(st, 0),
- DEFINE_FP_ST(st, 1),
- DEFINE_FP_ST(st, 2),
- DEFINE_FP_ST(st, 3),
- DEFINE_FP_ST(st, 4),
- DEFINE_FP_ST(st, 5),
- DEFINE_FP_ST(st, 6),
- DEFINE_FP_ST(st, 7),
- DEFINE_FP_MM(mm, 0),
- DEFINE_FP_MM(mm, 1),
- DEFINE_FP_MM(mm, 2),
- DEFINE_FP_MM(mm, 3),
- DEFINE_FP_MM(mm, 4),
- DEFINE_FP_MM(mm, 5),
- DEFINE_FP_MM(mm, 6),
+ DEFINE_FP_ST(st, 0), DEFINE_FP_ST(st, 1), DEFINE_FP_ST(st, 2),
+ DEFINE_FP_ST(st, 3), DEFINE_FP_ST(st, 4), DEFINE_FP_ST(st, 5),
+ DEFINE_FP_ST(st, 6), DEFINE_FP_ST(st, 7), DEFINE_FP_MM(mm, 0),
+ DEFINE_FP_MM(mm, 1), DEFINE_FP_MM(mm, 2), DEFINE_FP_MM(mm, 3),
+ DEFINE_FP_MM(mm, 4), DEFINE_FP_MM(mm, 5), DEFINE_FP_MM(mm, 6),
DEFINE_FP_MM(mm, 7),
// XMM registers
- DEFINE_XMM(xmm, 0),
- DEFINE_XMM(xmm, 1),
- DEFINE_XMM(xmm, 2),
- DEFINE_XMM(xmm, 3),
- DEFINE_XMM(xmm, 4),
- DEFINE_XMM(xmm, 5),
- DEFINE_XMM(xmm, 6),
- DEFINE_XMM(xmm, 7),
- DEFINE_XMM(xmm, 8),
- DEFINE_XMM(xmm, 9),
- DEFINE_XMM(xmm, 10),
- DEFINE_XMM(xmm, 11),
- DEFINE_XMM(xmm, 12),
- DEFINE_XMM(xmm, 13),
- DEFINE_XMM(xmm, 14),
+ DEFINE_XMM(xmm, 0), DEFINE_XMM(xmm, 1), DEFINE_XMM(xmm, 2),
+ DEFINE_XMM(xmm, 3), DEFINE_XMM(xmm, 4), DEFINE_XMM(xmm, 5),
+ DEFINE_XMM(xmm, 6), DEFINE_XMM(xmm, 7), DEFINE_XMM(xmm, 8),
+ DEFINE_XMM(xmm, 9), DEFINE_XMM(xmm, 10), DEFINE_XMM(xmm, 11),
+ DEFINE_XMM(xmm, 12), DEFINE_XMM(xmm, 13), DEFINE_XMM(xmm, 14),
DEFINE_XMM(xmm, 15),
// Copy of YMM registers assembled from xmm and ymmh
- DEFINE_YMM(ymm, 0),
- DEFINE_YMM(ymm, 1),
- DEFINE_YMM(ymm, 2),
- DEFINE_YMM(ymm, 3),
- DEFINE_YMM(ymm, 4),
- DEFINE_YMM(ymm, 5),
- DEFINE_YMM(ymm, 6),
- DEFINE_YMM(ymm, 7),
- DEFINE_YMM(ymm, 8),
- DEFINE_YMM(ymm, 9),
- DEFINE_YMM(ymm, 10),
- DEFINE_YMM(ymm, 11),
- DEFINE_YMM(ymm, 12),
- DEFINE_YMM(ymm, 13),
- DEFINE_YMM(ymm, 14),
+ DEFINE_YMM(ymm, 0), DEFINE_YMM(ymm, 1), DEFINE_YMM(ymm, 2),
+ DEFINE_YMM(ymm, 3), DEFINE_YMM(ymm, 4), DEFINE_YMM(ymm, 5),
+ DEFINE_YMM(ymm, 6), DEFINE_YMM(ymm, 7), DEFINE_YMM(ymm, 8),
+ DEFINE_YMM(ymm, 9), DEFINE_YMM(ymm, 10), DEFINE_YMM(ymm, 11),
+ DEFINE_YMM(ymm, 12), DEFINE_YMM(ymm, 13), DEFINE_YMM(ymm, 14),
DEFINE_YMM(ymm, 15),
};
@@ -306,52 +338,40 @@ g_register_infos_x86_64[] =
//---------------------------------------------------------------------------
static const RegisterInfo *
-PrivateGetRegisterInfoPtr (const lldb_private::ArchSpec& target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::x86_64:
- return g_register_infos_x86_64;
- default:
- assert(false && "Unhandled target architecture.");
- return nullptr;
- }
+PrivateGetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::x86_64:
+ return g_register_infos_x86_64;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return nullptr;
+ }
}
static uint32_t
-PrivateGetRegisterCount (const lldb_private::ArchSpec& target_arch)
-{
- switch (target_arch.GetMachine())
- {
- case llvm::Triple::x86_64:
- return static_cast<uint32_t> (sizeof (g_register_infos_x86_64) / sizeof (g_register_infos_x86_64 [0]));
- default:
- assert(false && "Unhandled target architecture.");
- return 0;
- }
+PrivateGetRegisterCount(const lldb_private::ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::x86_64:
+ return static_cast<uint32_t>(sizeof(g_register_infos_x86_64) /
+ sizeof(g_register_infos_x86_64[0]));
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
}
-RegisterContextNetBSD_x86_64::RegisterContextNetBSD_x86_64(const ArchSpec &target_arch) :
- lldb_private::RegisterInfoInterface(target_arch),
- m_register_info_p (PrivateGetRegisterInfoPtr (target_arch)),
- m_register_count (PrivateGetRegisterCount (target_arch))
-{
-}
+RegisterContextNetBSD_x86_64::RegisterContextNetBSD_x86_64(
+ const ArchSpec &target_arch)
+ : lldb_private::RegisterInfoInterface(target_arch),
+ m_register_info_p(PrivateGetRegisterInfoPtr(target_arch)),
+ m_register_count(PrivateGetRegisterCount(target_arch)) {}
-size_t
-RegisterContextNetBSD_x86_64::GetGPRSize() const
-{
- return sizeof(GPR);
-}
+size_t RegisterContextNetBSD_x86_64::GetGPRSize() const { return sizeof(GPR); }
-const RegisterInfo *
-RegisterContextNetBSD_x86_64::GetRegisterInfo() const
-{
- return m_register_info_p;
+const RegisterInfo *RegisterContextNetBSD_x86_64::GetRegisterInfo() const {
+ return m_register_info_p;
}
-uint32_t
-RegisterContextNetBSD_x86_64::GetRegisterCount () const
-{
- return m_register_count;
+uint32_t RegisterContextNetBSD_x86_64::GetRegisterCount() const {
+ return m_register_count;
}
diff --git a/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h b/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h
index c267278c418c..6b1998148d61 100644
--- a/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h
+++ b/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h
@@ -12,24 +12,20 @@
#include "RegisterInfoInterface.h"
-class RegisterContextNetBSD_x86_64:
- public lldb_private::RegisterInfoInterface
-{
+class RegisterContextNetBSD_x86_64
+ : public lldb_private::RegisterInfoInterface {
public:
- RegisterContextNetBSD_x86_64(const lldb_private::ArchSpec &target_arch);
+ RegisterContextNetBSD_x86_64(const lldb_private::ArchSpec &target_arch);
- size_t
- GetGPRSize() const override;
+ size_t GetGPRSize() const override;
- const lldb_private::RegisterInfo *
- GetRegisterInfo() const override;
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
- uint32_t
- GetRegisterCount () const override;
+ uint32_t GetRegisterCount() const override;
private:
- const lldb_private::RegisterInfo *m_register_info_p;
- const uint32_t m_register_count;
+ const lldb_private::RegisterInfo *m_register_info_p;
+ const uint32_t m_register_count;
};
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp
index 029a0e7352ec..15d155e315fa 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp
@@ -15,321 +15,204 @@
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h"
+#include "lldb/Host/Endian.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-#include "lldb/Host/Endian.h"
#include "llvm/Support/Compiler.h"
-#include "RegisterContextPOSIX_arm.h"
#include "Plugins/Process/elf-core/ProcessElfCore.h"
+#include "RegisterContextPOSIX_arm.h"
using namespace lldb;
using namespace lldb_private;
// arm general purpose registers.
-const uint32_t g_gpr_regnums_arm[] =
-{
- gpr_r0_arm,
- gpr_r1_arm,
- gpr_r2_arm,
- gpr_r3_arm,
- gpr_r4_arm,
- gpr_r5_arm,
- gpr_r6_arm,
- gpr_r7_arm,
- gpr_r8_arm,
- gpr_r9_arm,
- gpr_r10_arm,
- gpr_r11_arm,
- gpr_r12_arm,
- gpr_sp_arm,
- gpr_lr_arm,
- gpr_pc_arm,
- gpr_cpsr_arm,
+const uint32_t g_gpr_regnums_arm[] = {
+ gpr_r0_arm, gpr_r1_arm, gpr_r2_arm, gpr_r3_arm, gpr_r4_arm,
+ gpr_r5_arm, gpr_r6_arm, gpr_r7_arm, gpr_r8_arm, gpr_r9_arm,
+ gpr_r10_arm, gpr_r11_arm, gpr_r12_arm, gpr_sp_arm, gpr_lr_arm,
+ gpr_pc_arm, gpr_cpsr_arm,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
-static_assert(((sizeof g_gpr_regnums_arm / sizeof g_gpr_regnums_arm[0]) - 1) == k_num_gpr_registers_arm, \
+static_assert(((sizeof g_gpr_regnums_arm / sizeof g_gpr_regnums_arm[0]) - 1) ==
+ k_num_gpr_registers_arm,
"g_gpr_regnums_arm has wrong number of register infos");
// arm floating point registers.
-static const uint32_t g_fpu_regnums_arm[] =
-{
- fpu_s0_arm,
- fpu_s1_arm,
- fpu_s2_arm,
- fpu_s3_arm,
- fpu_s4_arm,
- fpu_s5_arm,
- fpu_s6_arm,
- fpu_s7_arm,
- fpu_s8_arm,
- fpu_s9_arm,
- fpu_s10_arm,
- fpu_s11_arm,
- fpu_s12_arm,
- fpu_s13_arm,
- fpu_s14_arm,
- fpu_s15_arm,
- fpu_s16_arm,
- fpu_s17_arm,
- fpu_s18_arm,
- fpu_s19_arm,
- fpu_s20_arm,
- fpu_s21_arm,
- fpu_s22_arm,
- fpu_s23_arm,
- fpu_s24_arm,
- fpu_s25_arm,
- fpu_s26_arm,
- fpu_s27_arm,
- fpu_s28_arm,
- fpu_s29_arm,
- fpu_s30_arm,
- fpu_s31_arm,
- fpu_fpscr_arm,
- fpu_d0_arm,
- fpu_d1_arm,
- fpu_d2_arm,
- fpu_d3_arm,
- fpu_d4_arm,
- fpu_d5_arm,
- fpu_d6_arm,
- fpu_d7_arm,
- fpu_d8_arm,
- fpu_d9_arm,
- fpu_d10_arm,
- fpu_d11_arm,
- fpu_d12_arm,
- fpu_d13_arm,
- fpu_d14_arm,
- fpu_d15_arm,
- fpu_d16_arm,
- fpu_d17_arm,
- fpu_d18_arm,
- fpu_d19_arm,
- fpu_d20_arm,
- fpu_d21_arm,
- fpu_d22_arm,
- fpu_d23_arm,
- fpu_d24_arm,
- fpu_d25_arm,
- fpu_d26_arm,
- fpu_d27_arm,
- fpu_d28_arm,
- fpu_d29_arm,
- fpu_d30_arm,
- fpu_d31_arm,
- fpu_q0_arm,
- fpu_q1_arm,
- fpu_q2_arm,
- fpu_q3_arm,
- fpu_q4_arm,
- fpu_q5_arm,
- fpu_q6_arm,
- fpu_q7_arm,
- fpu_q8_arm,
- fpu_q9_arm,
- fpu_q10_arm,
- fpu_q11_arm,
- fpu_q12_arm,
- fpu_q13_arm,
- fpu_q14_arm,
+static const uint32_t g_fpu_regnums_arm[] = {
+ fpu_s0_arm, fpu_s1_arm, fpu_s2_arm, fpu_s3_arm, fpu_s4_arm,
+ fpu_s5_arm, fpu_s6_arm, fpu_s7_arm, fpu_s8_arm, fpu_s9_arm,
+ fpu_s10_arm, fpu_s11_arm, fpu_s12_arm, fpu_s13_arm, fpu_s14_arm,
+ fpu_s15_arm, fpu_s16_arm, fpu_s17_arm, fpu_s18_arm, fpu_s19_arm,
+ fpu_s20_arm, fpu_s21_arm, fpu_s22_arm, fpu_s23_arm, fpu_s24_arm,
+ fpu_s25_arm, fpu_s26_arm, fpu_s27_arm, fpu_s28_arm, fpu_s29_arm,
+ fpu_s30_arm, fpu_s31_arm, fpu_fpscr_arm, fpu_d0_arm, fpu_d1_arm,
+ fpu_d2_arm, fpu_d3_arm, fpu_d4_arm, fpu_d5_arm, fpu_d6_arm,
+ fpu_d7_arm, fpu_d8_arm, fpu_d9_arm, fpu_d10_arm, fpu_d11_arm,
+ fpu_d12_arm, fpu_d13_arm, fpu_d14_arm, fpu_d15_arm, fpu_d16_arm,
+ fpu_d17_arm, fpu_d18_arm, fpu_d19_arm, fpu_d20_arm, fpu_d21_arm,
+ fpu_d22_arm, fpu_d23_arm, fpu_d24_arm, fpu_d25_arm, fpu_d26_arm,
+ fpu_d27_arm, fpu_d28_arm, fpu_d29_arm, fpu_d30_arm, fpu_d31_arm,
+ fpu_q0_arm, fpu_q1_arm, fpu_q2_arm, fpu_q3_arm, fpu_q4_arm,
+ fpu_q5_arm, fpu_q6_arm, fpu_q7_arm, fpu_q8_arm, fpu_q9_arm,
+ fpu_q10_arm, fpu_q11_arm, fpu_q12_arm, fpu_q13_arm, fpu_q14_arm,
fpu_q15_arm,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
-static_assert(((sizeof g_fpu_regnums_arm / sizeof g_fpu_regnums_arm[0]) - 1) == k_num_fpr_registers_arm, \
+static_assert(((sizeof g_fpu_regnums_arm / sizeof g_fpu_regnums_arm[0]) - 1) ==
+ k_num_fpr_registers_arm,
"g_fpu_regnums_arm has wrong number of register infos");
// Number of register sets provided by this context.
-enum
-{
- k_num_register_sets = 2
-};
+enum { k_num_register_sets = 2 };
// Register sets for arm.
-static const lldb_private::RegisterSet
-g_reg_sets_arm[k_num_register_sets] =
-{
- { "General Purpose Registers", "gpr", k_num_gpr_registers_arm, g_gpr_regnums_arm },
- { "Floating Point Registers", "fpu", k_num_fpr_registers_arm, g_fpu_regnums_arm }
-};
+static const lldb_private::RegisterSet g_reg_sets_arm[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_arm,
+ g_gpr_regnums_arm},
+ {"Floating Point Registers", "fpu", k_num_fpr_registers_arm,
+ g_fpu_regnums_arm}};
-bool RegisterContextPOSIX_arm::IsGPR(unsigned reg)
-{
- return reg <= m_reg_info.last_gpr; // GPR's come first.
+bool RegisterContextPOSIX_arm::IsGPR(unsigned reg) {
+ return reg <= m_reg_info.last_gpr; // GPR's come first.
}
-bool RegisterContextPOSIX_arm::IsFPR(unsigned reg)
-{
- return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
+bool RegisterContextPOSIX_arm::IsFPR(unsigned reg) {
+ return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
}
-RegisterContextPOSIX_arm::RegisterContextPOSIX_arm(lldb_private::Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info)
- : lldb_private::RegisterContext(thread, concrete_frame_idx)
-{
- m_register_info_ap.reset(register_info);
-
- switch (register_info->m_target_arch.GetMachine())
- {
- case llvm::Triple::arm:
- m_reg_info.num_registers = k_num_registers_arm;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_arm;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_arm;
- m_reg_info.last_gpr = k_last_gpr_arm;
- m_reg_info.first_fpr = k_first_fpr_arm;
- m_reg_info.last_fpr = k_last_fpr_arm;
- m_reg_info.first_fpr_v = fpu_s0_arm;
- m_reg_info.last_fpr_v = fpu_s31_arm;
- m_reg_info.gpr_flags = gpr_cpsr_arm;
- break;
- default:
- assert(false && "Unhandled target architecture.");
- break;
- }
+RegisterContextPOSIX_arm::RegisterContextPOSIX_arm(
+ lldb_private::Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info)
+ : lldb_private::RegisterContext(thread, concrete_frame_idx) {
+ m_register_info_ap.reset(register_info);
- ::memset(&m_fpr, 0, sizeof m_fpr);
+ switch (register_info->m_target_arch.GetMachine()) {
+ case llvm::Triple::arm:
+ m_reg_info.num_registers = k_num_registers_arm;
+ m_reg_info.num_gpr_registers = k_num_gpr_registers_arm;
+ m_reg_info.num_fpr_registers = k_num_fpr_registers_arm;
+ m_reg_info.last_gpr = k_last_gpr_arm;
+ m_reg_info.first_fpr = k_first_fpr_arm;
+ m_reg_info.last_fpr = k_last_fpr_arm;
+ m_reg_info.first_fpr_v = fpu_s0_arm;
+ m_reg_info.last_fpr_v = fpu_s31_arm;
+ m_reg_info.gpr_flags = gpr_cpsr_arm;
+ break;
+ default:
+ assert(false && "Unhandled target architecture.");
+ break;
+ }
- // elf-core yet to support ReadFPR()
- lldb::ProcessSP base = CalculateProcess();
- if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic())
- return;
-}
+ ::memset(&m_fpr, 0, sizeof m_fpr);
-RegisterContextPOSIX_arm::~RegisterContextPOSIX_arm()
-{
+ // elf-core yet to support ReadFPR()
+ lldb::ProcessSP base = CalculateProcess();
+ if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic())
+ return;
}
-void
-RegisterContextPOSIX_arm::Invalidate()
-{
-}
+RegisterContextPOSIX_arm::~RegisterContextPOSIX_arm() {}
-void
-RegisterContextPOSIX_arm::InvalidateAllRegisters()
-{
-}
+void RegisterContextPOSIX_arm::Invalidate() {}
+
+void RegisterContextPOSIX_arm::InvalidateAllRegisters() {}
-unsigned
-RegisterContextPOSIX_arm::GetRegisterOffset(unsigned reg)
-{
- assert(reg < m_reg_info.num_registers && "Invalid register number.");
- return GetRegisterInfo()[reg].byte_offset;
+unsigned RegisterContextPOSIX_arm::GetRegisterOffset(unsigned reg) {
+ assert(reg < m_reg_info.num_registers && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_offset;
}
-unsigned
-RegisterContextPOSIX_arm::GetRegisterSize(unsigned reg)
-{
- assert(reg < m_reg_info.num_registers && "Invalid register number.");
- return GetRegisterInfo()[reg].byte_size;
+unsigned RegisterContextPOSIX_arm::GetRegisterSize(unsigned reg) {
+ assert(reg < m_reg_info.num_registers && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_size;
}
-size_t
-RegisterContextPOSIX_arm::GetRegisterCount()
-{
- size_t num_registers = m_reg_info.num_gpr_registers + m_reg_info.num_fpr_registers;
- return num_registers;
+size_t RegisterContextPOSIX_arm::GetRegisterCount() {
+ size_t num_registers =
+ m_reg_info.num_gpr_registers + m_reg_info.num_fpr_registers;
+ return num_registers;
}
-size_t
-RegisterContextPOSIX_arm::GetGPRSize()
-{
- return m_register_info_ap->GetGPRSize ();
+size_t RegisterContextPOSIX_arm::GetGPRSize() {
+ return m_register_info_ap->GetGPRSize();
}
-const lldb_private::RegisterInfo *
-RegisterContextPOSIX_arm::GetRegisterInfo()
-{
- // Commonly, this method is overridden and g_register_infos is copied and specialized.
- // So, use GetRegisterInfo() rather than g_register_infos in this scope.
- return m_register_info_ap->GetRegisterInfo ();
+const lldb_private::RegisterInfo *RegisterContextPOSIX_arm::GetRegisterInfo() {
+ // Commonly, this method is overridden and g_register_infos is copied and
+ // specialized.
+ // So, use GetRegisterInfo() rather than g_register_infos in this scope.
+ return m_register_info_ap->GetRegisterInfo();
}
const lldb_private::RegisterInfo *
-RegisterContextPOSIX_arm::GetRegisterInfoAtIndex(size_t reg)
-{
- if (reg < m_reg_info.num_registers)
- return &GetRegisterInfo()[reg];
- else
- return NULL;
+RegisterContextPOSIX_arm::GetRegisterInfoAtIndex(size_t reg) {
+ if (reg < m_reg_info.num_registers)
+ return &GetRegisterInfo()[reg];
+ else
+ return NULL;
}
-size_t
-RegisterContextPOSIX_arm::GetRegisterSetCount()
-{
- size_t sets = 0;
- for (size_t set = 0; set < k_num_register_sets; ++set)
- {
- if (IsRegisterSetAvailable(set))
- ++sets;
- }
+size_t RegisterContextPOSIX_arm::GetRegisterSetCount() {
+ size_t sets = 0;
+ for (size_t set = 0; set < k_num_register_sets; ++set) {
+ if (IsRegisterSetAvailable(set))
+ ++sets;
+ }
- return sets;
+ return sets;
}
const lldb_private::RegisterSet *
-RegisterContextPOSIX_arm::GetRegisterSet(size_t set)
-{
- if (IsRegisterSetAvailable(set))
- {
- switch (m_register_info_ap->m_target_arch.GetMachine())
- {
- case llvm::Triple::arm:
- return &g_reg_sets_arm[set];
- default:
- assert(false && "Unhandled target architecture.");
- return NULL;
- }
+RegisterContextPOSIX_arm::GetRegisterSet(size_t set) {
+ if (IsRegisterSetAvailable(set)) {
+ switch (m_register_info_ap->m_target_arch.GetMachine()) {
+ case llvm::Triple::arm:
+ return &g_reg_sets_arm[set];
+ default:
+ assert(false && "Unhandled target architecture.");
+ return NULL;
}
- return NULL;
+ }
+ return NULL;
}
-const char *
-RegisterContextPOSIX_arm::GetRegisterName(unsigned reg)
-{
- assert(reg < m_reg_info.num_registers && "Invalid register offset.");
- return GetRegisterInfo()[reg].name;
+const char *RegisterContextPOSIX_arm::GetRegisterName(unsigned reg) {
+ assert(reg < m_reg_info.num_registers && "Invalid register offset.");
+ return GetRegisterInfo()[reg].name;
}
-lldb::ByteOrder
-RegisterContextPOSIX_arm::GetByteOrder()
-{
- // Get the target process whose privileged thread was used for the register read.
- lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
- lldb_private::Process *process = CalculateProcess().get();
+lldb::ByteOrder RegisterContextPOSIX_arm::GetByteOrder() {
+ // Get the target process whose privileged thread was used for the register
+ // read.
+ lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
+ lldb_private::Process *process = CalculateProcess().get();
- if (process)
- byte_order = process->GetByteOrder();
- return byte_order;
+ if (process)
+ byte_order = process->GetByteOrder();
+ return byte_order;
}
-bool
-RegisterContextPOSIX_arm::IsRegisterSetAvailable(size_t set_index)
-{
- return set_index < k_num_register_sets;
+bool RegisterContextPOSIX_arm::IsRegisterSetAvailable(size_t set_index) {
+ return set_index < k_num_register_sets;
}
-
// Used when parsing DWARF and EH frame information and any other
-// object file sections that contain register numbers in them.
-uint32_t
-RegisterContextPOSIX_arm::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
- uint32_t num)
-{
- const uint32_t num_regs = GetRegisterCount();
-
- assert (kind < lldb::kNumRegisterKinds);
- for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
- {
- const lldb_private::RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg_idx);
-
- if (reg_info->kinds[kind] == num)
- return reg_idx;
- }
+// object file sections that contain register numbers in them.
+uint32_t RegisterContextPOSIX_arm::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t num) {
+ const uint32_t num_regs = GetRegisterCount();
- return LLDB_INVALID_REGNUM;
-}
+ assert(kind < lldb::kNumRegisterKinds);
+ for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {
+ const lldb_private::RegisterInfo *reg_info =
+ GetRegisterInfoAtIndex(reg_idx);
+ if (reg_info->kinds[kind] == num)
+ return reg_idx;
+ }
+
+ return LLDB_INVALID_REGNUM;
+}
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h
index fbbcb9402911..817649e7c498 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h
@@ -14,112 +14,98 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/Log.h"
-#include "lldb/Target/RegisterContext.h"
#include "RegisterInfoInterface.h"
#include "lldb-arm-register-enums.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Target/RegisterContext.h"
class ProcessMonitor;
-class RegisterContextPOSIX_arm
- : public lldb_private::RegisterContext
-{
+class RegisterContextPOSIX_arm : public lldb_private::RegisterContext {
public:
- RegisterContextPOSIX_arm (lldb_private::Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info);
+ RegisterContextPOSIX_arm(lldb_private::Thread &thread,
+ uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info);
- ~RegisterContextPOSIX_arm() override;
+ ~RegisterContextPOSIX_arm() override;
- void
- Invalidate();
+ void Invalidate();
- void
- InvalidateAllRegisters() override;
+ void InvalidateAllRegisters() override;
- size_t
- GetRegisterCount() override;
+ size_t GetRegisterCount() override;
- virtual size_t
- GetGPRSize();
+ virtual size_t GetGPRSize();
- virtual unsigned
- GetRegisterSize(unsigned reg);
+ virtual unsigned GetRegisterSize(unsigned reg);
- virtual unsigned
- GetRegisterOffset(unsigned reg);
+ virtual unsigned GetRegisterOffset(unsigned reg);
- const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex(size_t reg) override;
+ const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
- size_t
- GetRegisterSetCount() override;
+ size_t GetRegisterSetCount() override;
- const lldb_private::RegisterSet *
- GetRegisterSet(size_t set) override;
+ const lldb_private::RegisterSet *GetRegisterSet(size_t set) override;
- const char *
- GetRegisterName(unsigned reg);
+ const char *GetRegisterName(unsigned reg);
- uint32_t
- ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
protected:
- struct RegInfo
- {
- uint32_t num_registers;
- uint32_t num_gpr_registers;
- uint32_t num_fpr_registers;
-
- uint32_t last_gpr;
- uint32_t first_fpr;
- uint32_t last_fpr;
-
- uint32_t first_fpr_v;
- uint32_t last_fpr_v;
-
- uint32_t gpr_flags;
- };
-
- struct QReg
- {
- uint8_t bytes[16];
- };
-
- struct FPU
- {
- union {
- uint32_t s[32];
- uint64_t d[32];
- QReg q[16]; // the 128-bit NEON registers
- } floats;
- uint32_t fpscr;
- };
-
- uint32_t m_gpr_arm[lldb_private::k_num_gpr_registers_arm]; // 32-bit general purpose registers.
- RegInfo m_reg_info;
- struct RegisterContextPOSIX_arm::FPU m_fpr; // floating-point registers including extended register sets.
- std::unique_ptr<lldb_private::RegisterInfoInterface> m_register_info_ap; // Register Info Interface (FreeBSD or Linux)
-
- // Determines if an extended register set is supported on the processor running the inferior process.
- virtual bool
- IsRegisterSetAvailable(size_t set_index);
-
- virtual const lldb_private::RegisterInfo *
- GetRegisterInfo();
-
- bool
- IsGPR(unsigned reg);
-
- bool
- IsFPR(unsigned reg);
-
- lldb::ByteOrder GetByteOrder();
-
- virtual bool ReadGPR() = 0;
- virtual bool ReadFPR() = 0;
- virtual bool WriteGPR() = 0;
- virtual bool WriteFPR() = 0;
+ struct RegInfo {
+ uint32_t num_registers;
+ uint32_t num_gpr_registers;
+ uint32_t num_fpr_registers;
+
+ uint32_t last_gpr;
+ uint32_t first_fpr;
+ uint32_t last_fpr;
+
+ uint32_t first_fpr_v;
+ uint32_t last_fpr_v;
+
+ uint32_t gpr_flags;
+ };
+
+ struct QReg {
+ uint8_t bytes[16];
+ };
+
+ struct FPU {
+ union {
+ uint32_t s[32];
+ uint64_t d[32];
+ QReg q[16]; // the 128-bit NEON registers
+ } floats;
+ uint32_t fpscr;
+ };
+
+ uint32_t m_gpr_arm[lldb_private::k_num_gpr_registers_arm]; // 32-bit general
+ // purpose
+ // registers.
+ RegInfo m_reg_info;
+ struct RegisterContextPOSIX_arm::FPU
+ m_fpr; // floating-point registers including extended register sets.
+ std::unique_ptr<lldb_private::RegisterInfoInterface>
+ m_register_info_ap; // Register Info Interface (FreeBSD or Linux)
+
+ // Determines if an extended register set is supported on the processor
+ // running the inferior process.
+ virtual bool IsRegisterSetAvailable(size_t set_index);
+
+ virtual const lldb_private::RegisterInfo *GetRegisterInfo();
+
+ bool IsGPR(unsigned reg);
+
+ bool IsFPR(unsigned reg);
+
+ lldb::ByteOrder GetByteOrder();
+
+ virtual bool ReadGPR() = 0;
+ virtual bool ReadFPR() = 0;
+ virtual bool WriteGPR() = 0;
+ virtual bool WriteFPR() = 0;
};
#endif // liblldb_RegisterContextPOSIX_arm_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
index 96508eafcce2..17c9dc301b50 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
@@ -15,288 +15,224 @@
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h"
+#include "lldb/Host/Endian.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-#include "lldb/Host/Endian.h"
#include "llvm/Support/Compiler.h"
-#include "RegisterContextPOSIX_arm64.h"
#include "Plugins/Process/elf-core/ProcessElfCore.h"
+#include "RegisterContextPOSIX_arm64.h"
using namespace lldb;
using namespace lldb_private;
// ARM64 general purpose registers.
-const uint32_t g_gpr_regnums_arm64[] =
-{
- gpr_x0_arm64,
- gpr_x1_arm64,
- gpr_x2_arm64,
- gpr_x3_arm64,
- gpr_x4_arm64,
- gpr_x5_arm64,
- gpr_x6_arm64,
- gpr_x7_arm64,
- gpr_x8_arm64,
- gpr_x9_arm64,
- gpr_x10_arm64,
- gpr_x11_arm64,
- gpr_x12_arm64,
- gpr_x13_arm64,
- gpr_x14_arm64,
- gpr_x15_arm64,
- gpr_x16_arm64,
- gpr_x17_arm64,
- gpr_x18_arm64,
- gpr_x19_arm64,
- gpr_x20_arm64,
- gpr_x21_arm64,
- gpr_x22_arm64,
- gpr_x23_arm64,
- gpr_x24_arm64,
- gpr_x25_arm64,
- gpr_x26_arm64,
- gpr_x27_arm64,
- gpr_x28_arm64,
- gpr_fp_arm64,
- gpr_lr_arm64,
- gpr_sp_arm64,
- gpr_pc_arm64,
- gpr_cpsr_arm64,
+const uint32_t g_gpr_regnums_arm64[] = {
+ gpr_x0_arm64, gpr_x1_arm64, gpr_x2_arm64, gpr_x3_arm64,
+ gpr_x4_arm64, gpr_x5_arm64, gpr_x6_arm64, gpr_x7_arm64,
+ gpr_x8_arm64, gpr_x9_arm64, gpr_x10_arm64, gpr_x11_arm64,
+ gpr_x12_arm64, gpr_x13_arm64, gpr_x14_arm64, gpr_x15_arm64,
+ gpr_x16_arm64, gpr_x17_arm64, gpr_x18_arm64, gpr_x19_arm64,
+ gpr_x20_arm64, gpr_x21_arm64, gpr_x22_arm64, gpr_x23_arm64,
+ gpr_x24_arm64, gpr_x25_arm64, gpr_x26_arm64, gpr_x27_arm64,
+ gpr_x28_arm64, gpr_fp_arm64, gpr_lr_arm64, gpr_sp_arm64,
+ gpr_pc_arm64, gpr_cpsr_arm64, gpr_w0_arm64, gpr_w1_arm64,
+ gpr_w2_arm64, gpr_w3_arm64, gpr_w4_arm64, gpr_w5_arm64,
+ gpr_w6_arm64, gpr_w7_arm64, gpr_w8_arm64, gpr_w9_arm64,
+ gpr_w10_arm64, gpr_w11_arm64, gpr_w12_arm64, gpr_w13_arm64,
+ gpr_w14_arm64, gpr_w15_arm64, gpr_w16_arm64, gpr_w17_arm64,
+ gpr_w18_arm64, gpr_w19_arm64, gpr_w20_arm64, gpr_w21_arm64,
+ gpr_w22_arm64, gpr_w23_arm64, gpr_w24_arm64, gpr_w25_arm64,
+ gpr_w26_arm64, gpr_w27_arm64, gpr_w28_arm64,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
-static_assert(((sizeof g_gpr_regnums_arm64 / sizeof g_gpr_regnums_arm64[0]) - 1) == k_num_gpr_registers_arm64, \
+static_assert(((sizeof g_gpr_regnums_arm64 / sizeof g_gpr_regnums_arm64[0]) -
+ 1) == k_num_gpr_registers_arm64,
"g_gpr_regnums_arm64 has wrong number of register infos");
// ARM64 floating point registers.
-static const uint32_t g_fpu_regnums_arm64[] =
-{
- fpu_v0_arm64,
- fpu_v1_arm64,
- fpu_v2_arm64,
- fpu_v3_arm64,
- fpu_v4_arm64,
- fpu_v5_arm64,
- fpu_v6_arm64,
- fpu_v7_arm64,
- fpu_v8_arm64,
- fpu_v9_arm64,
- fpu_v10_arm64,
- fpu_v11_arm64,
- fpu_v12_arm64,
- fpu_v13_arm64,
- fpu_v14_arm64,
- fpu_v15_arm64,
- fpu_v16_arm64,
- fpu_v17_arm64,
- fpu_v18_arm64,
- fpu_v19_arm64,
- fpu_v20_arm64,
- fpu_v21_arm64,
- fpu_v22_arm64,
- fpu_v23_arm64,
- fpu_v24_arm64,
- fpu_v25_arm64,
- fpu_v26_arm64,
- fpu_v27_arm64,
- fpu_v28_arm64,
- fpu_v29_arm64,
- fpu_v30_arm64,
- fpu_v31_arm64,
- fpu_fpsr_arm64,
- fpu_fpcr_arm64,
+static const uint32_t g_fpu_regnums_arm64[] = {
+ fpu_v0_arm64, fpu_v1_arm64, fpu_v2_arm64, fpu_v3_arm64,
+ fpu_v4_arm64, fpu_v5_arm64, fpu_v6_arm64, fpu_v7_arm64,
+ fpu_v8_arm64, fpu_v9_arm64, fpu_v10_arm64, fpu_v11_arm64,
+ fpu_v12_arm64, fpu_v13_arm64, fpu_v14_arm64, fpu_v15_arm64,
+ fpu_v16_arm64, fpu_v17_arm64, fpu_v18_arm64, fpu_v19_arm64,
+ fpu_v20_arm64, fpu_v21_arm64, fpu_v22_arm64, fpu_v23_arm64,
+ fpu_v24_arm64, fpu_v25_arm64, fpu_v26_arm64, fpu_v27_arm64,
+ fpu_v28_arm64, fpu_v29_arm64, fpu_v30_arm64, fpu_v31_arm64,
+ fpu_s0_arm64, fpu_s1_arm64, fpu_s2_arm64, fpu_s3_arm64,
+ fpu_s4_arm64, fpu_s5_arm64, fpu_s6_arm64, fpu_s7_arm64,
+ fpu_s8_arm64, fpu_s9_arm64, fpu_s10_arm64, fpu_s11_arm64,
+ fpu_s12_arm64, fpu_s13_arm64, fpu_s14_arm64, fpu_s15_arm64,
+ fpu_s16_arm64, fpu_s17_arm64, fpu_s18_arm64, fpu_s19_arm64,
+ fpu_s20_arm64, fpu_s21_arm64, fpu_s22_arm64, fpu_s23_arm64,
+ fpu_s24_arm64, fpu_s25_arm64, fpu_s26_arm64, fpu_s27_arm64,
+ fpu_s28_arm64, fpu_s29_arm64, fpu_s30_arm64, fpu_s31_arm64,
+
+ fpu_d0_arm64, fpu_d1_arm64, fpu_d2_arm64, fpu_d3_arm64,
+ fpu_d4_arm64, fpu_d5_arm64, fpu_d6_arm64, fpu_d7_arm64,
+ fpu_d8_arm64, fpu_d9_arm64, fpu_d10_arm64, fpu_d11_arm64,
+ fpu_d12_arm64, fpu_d13_arm64, fpu_d14_arm64, fpu_d15_arm64,
+ fpu_d16_arm64, fpu_d17_arm64, fpu_d18_arm64, fpu_d19_arm64,
+ fpu_d20_arm64, fpu_d21_arm64, fpu_d22_arm64, fpu_d23_arm64,
+ fpu_d24_arm64, fpu_d25_arm64, fpu_d26_arm64, fpu_d27_arm64,
+ fpu_d28_arm64, fpu_d29_arm64, fpu_d30_arm64, fpu_d31_arm64,
+ fpu_fpsr_arm64, fpu_fpcr_arm64,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
-static_assert(((sizeof g_fpu_regnums_arm64 / sizeof g_fpu_regnums_arm64[0]) - 1) == k_num_fpr_registers_arm64, \
+static_assert(((sizeof g_fpu_regnums_arm64 / sizeof g_fpu_regnums_arm64[0]) -
+ 1) == k_num_fpr_registers_arm64,
"g_fpu_regnums_arm64 has wrong number of register infos");
// Number of register sets provided by this context.
-enum
-{
- k_num_register_sets = 2
-};
+enum { k_num_register_sets = 2 };
// Register sets for ARM64.
-static const lldb_private::RegisterSet
-g_reg_sets_arm64[k_num_register_sets] =
-{
- { "General Purpose Registers", "gpr", k_num_gpr_registers_arm64, g_gpr_regnums_arm64 },
- { "Floating Point Registers", "fpu", k_num_fpr_registers_arm64, g_fpu_regnums_arm64 }
-};
+static const lldb_private::RegisterSet g_reg_sets_arm64[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_arm64,
+ g_gpr_regnums_arm64},
+ {"Floating Point Registers", "fpu", k_num_fpr_registers_arm64,
+ g_fpu_regnums_arm64}};
-bool RegisterContextPOSIX_arm64::IsGPR(unsigned reg)
-{
- return reg <= m_reg_info.last_gpr; // GPR's come first.
+bool RegisterContextPOSIX_arm64::IsGPR(unsigned reg) {
+ return reg <= m_reg_info.last_gpr; // GPR's come first.
}
-bool RegisterContextPOSIX_arm64::IsFPR(unsigned reg)
-{
- return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
+bool RegisterContextPOSIX_arm64::IsFPR(unsigned reg) {
+ return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
}
-RegisterContextPOSIX_arm64::RegisterContextPOSIX_arm64(lldb_private::Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info)
- : lldb_private::RegisterContext(thread, concrete_frame_idx)
-{
- m_register_info_ap.reset(register_info);
-
- switch (register_info->m_target_arch.GetMachine())
- {
- case llvm::Triple::aarch64:
- m_reg_info.num_registers = k_num_registers_arm64;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_arm64;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_arm64;
- m_reg_info.last_gpr = k_last_gpr_arm64;
- m_reg_info.first_fpr = k_first_fpr_arm64;
- m_reg_info.last_fpr = k_last_fpr_arm64;
- m_reg_info.first_fpr_v = fpu_v0_arm64;
- m_reg_info.last_fpr_v = fpu_v31_arm64;
- m_reg_info.gpr_flags = gpr_cpsr_arm64;
- break;
- default:
- assert(false && "Unhandled target architecture.");
- break;
- }
+RegisterContextPOSIX_arm64::RegisterContextPOSIX_arm64(
+ lldb_private::Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info)
+ : lldb_private::RegisterContext(thread, concrete_frame_idx) {
+ m_register_info_ap.reset(register_info);
- ::memset(&m_fpr, 0, sizeof m_fpr);
+ switch (register_info->m_target_arch.GetMachine()) {
+ case llvm::Triple::aarch64:
+ m_reg_info.num_registers = k_num_registers_arm64;
+ m_reg_info.num_gpr_registers = k_num_gpr_registers_arm64;
+ m_reg_info.num_fpr_registers = k_num_fpr_registers_arm64;
+ m_reg_info.last_gpr = k_last_gpr_arm64;
+ m_reg_info.first_fpr = k_first_fpr_arm64;
+ m_reg_info.last_fpr = k_last_fpr_arm64;
+ m_reg_info.first_fpr_v = fpu_v0_arm64;
+ m_reg_info.last_fpr_v = fpu_v31_arm64;
+ m_reg_info.gpr_flags = gpr_cpsr_arm64;
+ break;
+ default:
+ assert(false && "Unhandled target architecture.");
+ break;
+ }
- // elf-core yet to support ReadFPR()
- lldb::ProcessSP base = CalculateProcess();
- if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic())
- return;
-}
+ ::memset(&m_fpr, 0, sizeof m_fpr);
-RegisterContextPOSIX_arm64::~RegisterContextPOSIX_arm64()
-{
+ // elf-core yet to support ReadFPR()
+ lldb::ProcessSP base = CalculateProcess();
+ if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic())
+ return;
}
-void
-RegisterContextPOSIX_arm64::Invalidate()
-{
-}
+RegisterContextPOSIX_arm64::~RegisterContextPOSIX_arm64() {}
-void
-RegisterContextPOSIX_arm64::InvalidateAllRegisters()
-{
-}
+void RegisterContextPOSIX_arm64::Invalidate() {}
-unsigned
-RegisterContextPOSIX_arm64::GetRegisterOffset(unsigned reg)
-{
- assert(reg < m_reg_info.num_registers && "Invalid register number.");
- return GetRegisterInfo()[reg].byte_offset;
+void RegisterContextPOSIX_arm64::InvalidateAllRegisters() {}
+
+unsigned RegisterContextPOSIX_arm64::GetRegisterOffset(unsigned reg) {
+ assert(reg < m_reg_info.num_registers && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_offset;
}
-unsigned
-RegisterContextPOSIX_arm64::GetRegisterSize(unsigned reg)
-{
- assert(reg < m_reg_info.num_registers && "Invalid register number.");
- return GetRegisterInfo()[reg].byte_size;
+unsigned RegisterContextPOSIX_arm64::GetRegisterSize(unsigned reg) {
+ assert(reg < m_reg_info.num_registers && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_size;
}
-size_t
-RegisterContextPOSIX_arm64::GetRegisterCount()
-{
- size_t num_registers = m_reg_info.num_gpr_registers + m_reg_info.num_fpr_registers;
- return num_registers;
+size_t RegisterContextPOSIX_arm64::GetRegisterCount() {
+ size_t num_registers =
+ m_reg_info.num_gpr_registers + m_reg_info.num_fpr_registers;
+ return num_registers;
}
-size_t
-RegisterContextPOSIX_arm64::GetGPRSize()
-{
- return m_register_info_ap->GetGPRSize ();
+size_t RegisterContextPOSIX_arm64::GetGPRSize() {
+ return m_register_info_ap->GetGPRSize();
}
const lldb_private::RegisterInfo *
-RegisterContextPOSIX_arm64::GetRegisterInfo()
-{
- // Commonly, this method is overridden and g_register_infos is copied and specialized.
- // So, use GetRegisterInfo() rather than g_register_infos in this scope.
- return m_register_info_ap->GetRegisterInfo ();
+RegisterContextPOSIX_arm64::GetRegisterInfo() {
+ // Commonly, this method is overridden and g_register_infos is copied and
+ // specialized.
+ // So, use GetRegisterInfo() rather than g_register_infos in this scope.
+ return m_register_info_ap->GetRegisterInfo();
}
const lldb_private::RegisterInfo *
-RegisterContextPOSIX_arm64::GetRegisterInfoAtIndex(size_t reg)
-{
- if (reg < m_reg_info.num_registers)
- return &GetRegisterInfo()[reg];
- else
- return NULL;
+RegisterContextPOSIX_arm64::GetRegisterInfoAtIndex(size_t reg) {
+ if (reg < m_reg_info.num_registers)
+ return &GetRegisterInfo()[reg];
+ else
+ return NULL;
}
-size_t
-RegisterContextPOSIX_arm64::GetRegisterSetCount()
-{
- size_t sets = 0;
- for (size_t set = 0; set < k_num_register_sets; ++set)
- {
- if (IsRegisterSetAvailable(set))
- ++sets;
- }
+size_t RegisterContextPOSIX_arm64::GetRegisterSetCount() {
+ size_t sets = 0;
+ for (size_t set = 0; set < k_num_register_sets; ++set) {
+ if (IsRegisterSetAvailable(set))
+ ++sets;
+ }
- return sets;
+ return sets;
}
const lldb_private::RegisterSet *
-RegisterContextPOSIX_arm64::GetRegisterSet(size_t set)
-{
- if (IsRegisterSetAvailable(set))
- {
- switch (m_register_info_ap->m_target_arch.GetMachine())
- {
- case llvm::Triple::aarch64:
- return &g_reg_sets_arm64[set];
- default:
- assert(false && "Unhandled target architecture.");
- return NULL;
- }
+RegisterContextPOSIX_arm64::GetRegisterSet(size_t set) {
+ if (IsRegisterSetAvailable(set)) {
+ switch (m_register_info_ap->m_target_arch.GetMachine()) {
+ case llvm::Triple::aarch64:
+ return &g_reg_sets_arm64[set];
+ default:
+ assert(false && "Unhandled target architecture.");
+ return NULL;
}
- return NULL;
+ }
+ return NULL;
}
-const char *
-RegisterContextPOSIX_arm64::GetRegisterName(unsigned reg)
-{
- assert(reg < m_reg_info.num_registers && "Invalid register offset.");
- return GetRegisterInfo()[reg].name;
+const char *RegisterContextPOSIX_arm64::GetRegisterName(unsigned reg) {
+ assert(reg < m_reg_info.num_registers && "Invalid register offset.");
+ return GetRegisterInfo()[reg].name;
}
-lldb::ByteOrder
-RegisterContextPOSIX_arm64::GetByteOrder()
-{
- // Get the target process whose privileged thread was used for the register read.
- lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
- lldb_private::Process *process = CalculateProcess().get();
+lldb::ByteOrder RegisterContextPOSIX_arm64::GetByteOrder() {
+ // Get the target process whose privileged thread was used for the register
+ // read.
+ lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
+ lldb_private::Process *process = CalculateProcess().get();
- if (process)
- byte_order = process->GetByteOrder();
- return byte_order;
+ if (process)
+ byte_order = process->GetByteOrder();
+ return byte_order;
}
-bool
-RegisterContextPOSIX_arm64::IsRegisterSetAvailable(size_t set_index)
-{
- return set_index < k_num_register_sets;
+bool RegisterContextPOSIX_arm64::IsRegisterSetAvailable(size_t set_index) {
+ return set_index < k_num_register_sets;
}
-
// Used when parsing DWARF and EH frame information and any other
-// object file sections that contain register numbers in them.
-uint32_t
-RegisterContextPOSIX_arm64::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
- uint32_t num)
-{
- const uint32_t num_regs = GetRegisterCount();
-
- assert (kind < lldb::kNumRegisterKinds);
- for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
- {
- const lldb_private::RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg_idx);
-
- if (reg_info->kinds[kind] == num)
- return reg_idx;
- }
+// object file sections that contain register numbers in them.
+uint32_t RegisterContextPOSIX_arm64::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t num) {
+ const uint32_t num_regs = GetRegisterCount();
+
+ assert(kind < lldb::kNumRegisterKinds);
+ for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {
+ const lldb_private::RegisterInfo *reg_info =
+ GetRegisterInfoAtIndex(reg_idx);
+
+ if (reg_info->kinds[kind] == num)
+ return reg_idx;
+ }
- return LLDB_INVALID_REGNUM;
+ return LLDB_INVALID_REGNUM;
}
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
index 225d4f25168e..923e786dd045 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
@@ -14,111 +14,98 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/Log.h"
-#include "lldb/Target/RegisterContext.h"
#include "RegisterInfoInterface.h"
#include "lldb-arm64-register-enums.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Target/RegisterContext.h"
class ProcessMonitor;
-class RegisterContextPOSIX_arm64
- : public lldb_private::RegisterContext
-{
+class RegisterContextPOSIX_arm64 : public lldb_private::RegisterContext {
public:
- RegisterContextPOSIX_arm64 (lldb_private::Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info);
+ RegisterContextPOSIX_arm64(
+ lldb_private::Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info);
- ~RegisterContextPOSIX_arm64() override;
+ ~RegisterContextPOSIX_arm64() override;
- void
- Invalidate();
+ void Invalidate();
- void
- InvalidateAllRegisters() override;
+ void InvalidateAllRegisters() override;
- size_t
- GetRegisterCount() override;
+ size_t GetRegisterCount() override;
- virtual size_t
- GetGPRSize();
+ virtual size_t GetGPRSize();
- virtual unsigned
- GetRegisterSize(unsigned reg);
+ virtual unsigned GetRegisterSize(unsigned reg);
- virtual unsigned
- GetRegisterOffset(unsigned reg);
+ virtual unsigned GetRegisterOffset(unsigned reg);
- const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex(size_t reg) override;
+ const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
- size_t
- GetRegisterSetCount() override;
+ size_t GetRegisterSetCount() override;
- const lldb_private::RegisterSet *
- GetRegisterSet(size_t set) override;
+ const lldb_private::RegisterSet *GetRegisterSet(size_t set) override;
- const char *
- GetRegisterName(unsigned reg);
+ const char *GetRegisterName(unsigned reg);
- uint32_t
- ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
protected:
- struct RegInfo
- {
- uint32_t num_registers;
- uint32_t num_gpr_registers;
- uint32_t num_fpr_registers;
-
- uint32_t last_gpr;
- uint32_t first_fpr;
- uint32_t last_fpr;
-
- uint32_t first_fpr_v;
- uint32_t last_fpr_v;
-
- uint32_t gpr_flags;
- };
-
- // based on RegisterContextDarwin_arm64.h
- struct VReg
- {
- uint8_t bytes[16];
- };
-
- // based on RegisterContextDarwin_arm64.h
- struct FPU
- {
- VReg v[32];
- uint32_t fpsr;
- uint32_t fpcr;
- };
-
- uint64_t m_gpr_arm64[lldb_private::k_num_gpr_registers_arm64]; // 64-bit general purpose registers.
- RegInfo m_reg_info;
- struct RegisterContextPOSIX_arm64::FPU m_fpr; // floating-point registers including extended register sets.
- std::unique_ptr<lldb_private::RegisterInfoInterface> m_register_info_ap; // Register Info Interface (FreeBSD or Linux)
-
- // Determines if an extended register set is supported on the processor running the inferior process.
- virtual bool
- IsRegisterSetAvailable(size_t set_index);
-
- virtual const lldb_private::RegisterInfo *
- GetRegisterInfo();
-
- bool
- IsGPR(unsigned reg);
-
- bool
- IsFPR(unsigned reg);
-
- lldb::ByteOrder GetByteOrder();
-
- virtual bool ReadGPR() = 0;
- virtual bool ReadFPR() = 0;
- virtual bool WriteGPR() = 0;
- virtual bool WriteFPR() = 0;
+ struct RegInfo {
+ uint32_t num_registers;
+ uint32_t num_gpr_registers;
+ uint32_t num_fpr_registers;
+
+ uint32_t last_gpr;
+ uint32_t first_fpr;
+ uint32_t last_fpr;
+
+ uint32_t first_fpr_v;
+ uint32_t last_fpr_v;
+
+ uint32_t gpr_flags;
+ };
+
+ // based on RegisterContextDarwin_arm64.h
+ struct VReg {
+ uint8_t bytes[16];
+ };
+
+ // based on RegisterContextDarwin_arm64.h
+ struct FPU {
+ VReg v[32];
+ uint32_t fpsr;
+ uint32_t fpcr;
+ };
+
+ uint64_t m_gpr_arm64[lldb_private::k_num_gpr_registers_arm64]; // 64-bit
+ // general
+ // purpose
+ // registers.
+ RegInfo m_reg_info;
+ struct RegisterContextPOSIX_arm64::FPU
+ m_fpr; // floating-point registers including extended register sets.
+ std::unique_ptr<lldb_private::RegisterInfoInterface>
+ m_register_info_ap; // Register Info Interface (FreeBSD or Linux)
+
+ // Determines if an extended register set is supported on the processor
+ // running the inferior process.
+ virtual bool IsRegisterSetAvailable(size_t set_index);
+
+ virtual const lldb_private::RegisterInfo *GetRegisterInfo();
+
+ bool IsGPR(unsigned reg);
+
+ bool IsFPR(unsigned reg);
+
+ lldb::ByteOrder GetByteOrder();
+
+ virtual bool ReadGPR() = 0;
+ virtual bool ReadFPR() = 0;
+ virtual bool WriteGPR() = 0;
+ virtual bool WriteFPR() = 0;
};
#endif // liblldb_RegisterContextPOSIX_arm64_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp
index cefedaec63c1..8c67fb89d08e 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp
@@ -15,223 +15,150 @@
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h"
+#include "lldb/Host/Endian.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-#include "lldb/Host/Endian.h"
#include "llvm/Support/Compiler.h"
-#include "RegisterContextPOSIX_mips64.h"
#include "Plugins/Process/elf-core/ProcessElfCore.h"
+#include "RegisterContextPOSIX_mips64.h"
using namespace lldb_private;
using namespace lldb;
-static const
-uint32_t g_gpr_regnums[] =
-{
- gpr_zero_mips64,
- gpr_r1_mips64,
- gpr_r2_mips64,
- gpr_r3_mips64,
- gpr_r4_mips64,
- gpr_r5_mips64,
- gpr_r6_mips64,
- gpr_r7_mips64,
- gpr_r8_mips64,
- gpr_r9_mips64,
- gpr_r10_mips64,
- gpr_r11_mips64,
- gpr_r12_mips64,
- gpr_r13_mips64,
- gpr_r14_mips64,
- gpr_r15_mips64,
- gpr_r16_mips64,
- gpr_r17_mips64,
- gpr_r18_mips64,
- gpr_r19_mips64,
- gpr_r20_mips64,
- gpr_r21_mips64,
- gpr_r22_mips64,
- gpr_r23_mips64,
- gpr_r24_mips64,
- gpr_r25_mips64,
- gpr_r26_mips64,
- gpr_r27_mips64,
- gpr_gp_mips64,
- gpr_sp_mips64,
- gpr_r30_mips64,
- gpr_ra_mips64,
- gpr_sr_mips64,
- gpr_mullo_mips64,
- gpr_mulhi_mips64,
- gpr_badvaddr_mips64,
- gpr_cause_mips64,
- gpr_pc_mips64,
- gpr_ic_mips64,
- gpr_dummy_mips64
-};
+static const uint32_t g_gpr_regnums[] = {
+ gpr_zero_mips64, gpr_r1_mips64, gpr_r2_mips64, gpr_r3_mips64,
+ gpr_r4_mips64, gpr_r5_mips64, gpr_r6_mips64, gpr_r7_mips64,
+ gpr_r8_mips64, gpr_r9_mips64, gpr_r10_mips64, gpr_r11_mips64,
+ gpr_r12_mips64, gpr_r13_mips64, gpr_r14_mips64, gpr_r15_mips64,
+ gpr_r16_mips64, gpr_r17_mips64, gpr_r18_mips64, gpr_r19_mips64,
+ gpr_r20_mips64, gpr_r21_mips64, gpr_r22_mips64, gpr_r23_mips64,
+ gpr_r24_mips64, gpr_r25_mips64, gpr_r26_mips64, gpr_r27_mips64,
+ gpr_gp_mips64, gpr_sp_mips64, gpr_r30_mips64, gpr_ra_mips64,
+ gpr_sr_mips64, gpr_mullo_mips64, gpr_mulhi_mips64, gpr_badvaddr_mips64,
+ gpr_cause_mips64, gpr_pc_mips64, gpr_ic_mips64, gpr_dummy_mips64};
// Number of register sets provided by this context.
-enum
-{
- k_num_register_sets = 1
-};
+enum { k_num_register_sets = 1 };
-static const RegisterSet
-g_reg_sets_mips64[k_num_register_sets] =
-{
- { "General Purpose Registers", "gpr", k_num_gpr_registers_mips64, g_gpr_regnums },
+static const RegisterSet g_reg_sets_mips64[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_mips64,
+ g_gpr_regnums},
};
-bool RegisterContextPOSIX_mips64::IsGPR(unsigned reg)
-{
- return reg <= k_num_gpr_registers_mips64; // GPR's come first.
+bool RegisterContextPOSIX_mips64::IsGPR(unsigned reg) {
+ return reg <= k_num_gpr_registers_mips64; // GPR's come first.
}
-bool
-RegisterContextPOSIX_mips64::IsFPR(unsigned reg)
-{
- // XXX
- return false;
+bool RegisterContextPOSIX_mips64::IsFPR(unsigned reg) {
+ // XXX
+ return false;
}
-RegisterContextPOSIX_mips64::RegisterContextPOSIX_mips64(Thread &thread,
- uint32_t concrete_frame_idx,
- RegisterInfoInterface *register_info)
- : RegisterContext(thread, concrete_frame_idx)
-{
- m_register_info_ap.reset(register_info);
-
- // elf-core yet to support ReadFPR()
- ProcessSP base = CalculateProcess();
- if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic())
- return;
-}
+RegisterContextPOSIX_mips64::RegisterContextPOSIX_mips64(
+ Thread &thread, uint32_t concrete_frame_idx,
+ RegisterInfoInterface *register_info)
+ : RegisterContext(thread, concrete_frame_idx) {
+ m_register_info_ap.reset(register_info);
-RegisterContextPOSIX_mips64::~RegisterContextPOSIX_mips64()
-{
+ // elf-core yet to support ReadFPR()
+ ProcessSP base = CalculateProcess();
+ if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic())
+ return;
}
-void
-RegisterContextPOSIX_mips64::Invalidate()
-{
-}
+RegisterContextPOSIX_mips64::~RegisterContextPOSIX_mips64() {}
-void
-RegisterContextPOSIX_mips64::InvalidateAllRegisters()
-{
-}
+void RegisterContextPOSIX_mips64::Invalidate() {}
-unsigned
-RegisterContextPOSIX_mips64::GetRegisterOffset(unsigned reg)
-{
- assert(reg < k_num_registers_mips64 && "Invalid register number.");
- return GetRegisterInfo()[reg].byte_offset;
+void RegisterContextPOSIX_mips64::InvalidateAllRegisters() {}
+
+unsigned RegisterContextPOSIX_mips64::GetRegisterOffset(unsigned reg) {
+ assert(reg < k_num_registers_mips64 && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_offset;
}
-unsigned
-RegisterContextPOSIX_mips64::GetRegisterSize(unsigned reg)
-{
- assert(reg < k_num_registers_mips64 && "Invalid register number.");
- return GetRegisterInfo()[reg].byte_size;
+unsigned RegisterContextPOSIX_mips64::GetRegisterSize(unsigned reg) {
+ assert(reg < k_num_registers_mips64 && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_size;
}
-size_t
-RegisterContextPOSIX_mips64::GetRegisterCount()
-{
- size_t num_registers = k_num_registers_mips64;
- return num_registers;
+size_t RegisterContextPOSIX_mips64::GetRegisterCount() {
+ size_t num_registers = k_num_registers_mips64;
+ return num_registers;
}
-size_t
-RegisterContextPOSIX_mips64::GetGPRSize()
-{
- return m_register_info_ap->GetGPRSize();
+size_t RegisterContextPOSIX_mips64::GetGPRSize() {
+ return m_register_info_ap->GetGPRSize();
}
-const RegisterInfo *
-RegisterContextPOSIX_mips64::GetRegisterInfo()
-{
- // Commonly, this method is overridden and g_register_infos is copied and specialized.
- // So, use GetRegisterInfo() rather than g_register_infos in this scope.
- return m_register_info_ap->GetRegisterInfo ();
+const RegisterInfo *RegisterContextPOSIX_mips64::GetRegisterInfo() {
+ // Commonly, this method is overridden and g_register_infos is copied and
+ // specialized.
+ // So, use GetRegisterInfo() rather than g_register_infos in this scope.
+ return m_register_info_ap->GetRegisterInfo();
}
const RegisterInfo *
-RegisterContextPOSIX_mips64::GetRegisterInfoAtIndex(size_t reg)
-{
- if (reg < k_num_registers_mips64)
- return &GetRegisterInfo()[reg];
- else
- return NULL;
+RegisterContextPOSIX_mips64::GetRegisterInfoAtIndex(size_t reg) {
+ if (reg < k_num_registers_mips64)
+ return &GetRegisterInfo()[reg];
+ else
+ return NULL;
}
-size_t
-RegisterContextPOSIX_mips64::GetRegisterSetCount()
-{
- size_t sets = 0;
- for (size_t set = 0; set < k_num_register_sets; ++set)
- {
- if (IsRegisterSetAvailable(set))
- ++sets;
- }
-
- return sets;
+size_t RegisterContextPOSIX_mips64::GetRegisterSetCount() {
+ size_t sets = 0;
+ for (size_t set = 0; set < k_num_register_sets; ++set) {
+ if (IsRegisterSetAvailable(set))
+ ++sets;
+ }
+
+ return sets;
}
-const RegisterSet *
-RegisterContextPOSIX_mips64::GetRegisterSet(size_t set)
-{
- if (IsRegisterSetAvailable(set))
- return &g_reg_sets_mips64[set];
- else
- return NULL;
+const RegisterSet *RegisterContextPOSIX_mips64::GetRegisterSet(size_t set) {
+ if (IsRegisterSetAvailable(set))
+ return &g_reg_sets_mips64[set];
+ else
+ return NULL;
}
-const char *
-RegisterContextPOSIX_mips64::GetRegisterName(unsigned reg)
-{
- assert(reg < k_num_registers_mips64 && "Invalid register offset.");
- return GetRegisterInfo()[reg].name;
+const char *RegisterContextPOSIX_mips64::GetRegisterName(unsigned reg) {
+ assert(reg < k_num_registers_mips64 && "Invalid register offset.");
+ return GetRegisterInfo()[reg].name;
}
-lldb::ByteOrder
-RegisterContextPOSIX_mips64::GetByteOrder()
-{
- // Get the target process whose privileged thread was used for the register read.
- lldb::ByteOrder byte_order = eByteOrderInvalid;
- Process *process = CalculateProcess().get();
+lldb::ByteOrder RegisterContextPOSIX_mips64::GetByteOrder() {
+ // Get the target process whose privileged thread was used for the register
+ // read.
+ lldb::ByteOrder byte_order = eByteOrderInvalid;
+ Process *process = CalculateProcess().get();
- if (process)
- byte_order = process->GetByteOrder();
- return byte_order;
+ if (process)
+ byte_order = process->GetByteOrder();
+ return byte_order;
}
-bool
-RegisterContextPOSIX_mips64::IsRegisterSetAvailable(size_t set_index)
-{
- size_t num_sets = k_num_register_sets;
+bool RegisterContextPOSIX_mips64::IsRegisterSetAvailable(size_t set_index) {
+ size_t num_sets = k_num_register_sets;
- return (set_index < num_sets);
+ return (set_index < num_sets);
}
// Used when parsing DWARF and EH frame information and any other
// object file sections that contain register numbers in them.
-uint32_t
-RegisterContextPOSIX_mips64::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
- uint32_t num)
-{
- const uint32_t num_regs = GetRegisterCount();
-
- assert (kind < kNumRegisterKinds);
- for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
- {
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg_idx);
-
- if (reg_info->kinds[kind] == num)
- return reg_idx;
- }
-
- return LLDB_INVALID_REGNUM;
-}
+uint32_t RegisterContextPOSIX_mips64::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t num) {
+ const uint32_t num_regs = GetRegisterCount();
+
+ assert(kind < kNumRegisterKinds);
+ for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx);
+ if (reg_info->kinds[kind] == num)
+ return reg_idx;
+ }
+
+ return LLDB_INVALID_REGNUM;
+}
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h b/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h
index 07552d8d681d..90ff9d659491 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h
@@ -14,82 +14,69 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/Log.h"
-#include "lldb/Target/RegisterContext.h"
-#include "RegisterInfoInterface.h"
#include "RegisterContext_mips.h"
+#include "RegisterInfoInterface.h"
#include "lldb-mips-freebsd-register-enums.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Target/RegisterContext.h"
using namespace lldb_private;
class ProcessMonitor;
-class RegisterContextPOSIX_mips64
- : public lldb_private::RegisterContext
-{
+class RegisterContextPOSIX_mips64 : public lldb_private::RegisterContext {
public:
- RegisterContextPOSIX_mips64 (lldb_private::Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info);
+ RegisterContextPOSIX_mips64(
+ lldb_private::Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info);
- ~RegisterContextPOSIX_mips64() override;
+ ~RegisterContextPOSIX_mips64() override;
- void
- Invalidate();
+ void Invalidate();
- void
- InvalidateAllRegisters() override;
+ void InvalidateAllRegisters() override;
- size_t
- GetRegisterCount() override;
+ size_t GetRegisterCount() override;
- virtual size_t
- GetGPRSize();
+ virtual size_t GetGPRSize();
- virtual unsigned
- GetRegisterSize(unsigned reg);
+ virtual unsigned GetRegisterSize(unsigned reg);
- virtual unsigned
- GetRegisterOffset(unsigned reg);
+ virtual unsigned GetRegisterOffset(unsigned reg);
- const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex(size_t reg) override;
+ const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
- size_t
- GetRegisterSetCount() override;
+ size_t GetRegisterSetCount() override;
- const lldb_private::RegisterSet *
- GetRegisterSet(size_t set) override;
+ const lldb_private::RegisterSet *GetRegisterSet(size_t set) override;
- const char *
- GetRegisterName(unsigned reg);
+ const char *GetRegisterName(unsigned reg);
- uint32_t
- ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
protected:
- uint64_t m_gpr_mips64[k_num_gpr_registers_mips64]; // general purpose registers.
- std::unique_ptr<lldb_private::RegisterInfoInterface> m_register_info_ap; // Register Info Interface (FreeBSD or Linux)
+ uint64_t
+ m_gpr_mips64[k_num_gpr_registers_mips64]; // general purpose registers.
+ std::unique_ptr<lldb_private::RegisterInfoInterface>
+ m_register_info_ap; // Register Info Interface (FreeBSD or Linux)
- // Determines if an extended register set is supported on the processor running the inferior process.
- virtual bool
- IsRegisterSetAvailable(size_t set_index);
+ // Determines if an extended register set is supported on the processor
+ // running the inferior process.
+ virtual bool IsRegisterSetAvailable(size_t set_index);
- virtual const lldb_private::RegisterInfo *
- GetRegisterInfo();
+ virtual const lldb_private::RegisterInfo *GetRegisterInfo();
- bool
- IsGPR(unsigned reg);
+ bool IsGPR(unsigned reg);
- bool
- IsFPR(unsigned reg);
+ bool IsFPR(unsigned reg);
- lldb::ByteOrder GetByteOrder();
+ lldb::ByteOrder GetByteOrder();
- virtual bool ReadGPR() = 0;
- virtual bool ReadFPR() = 0;
- virtual bool WriteGPR() = 0;
- virtual bool WriteFPR() = 0;
+ virtual bool ReadGPR() = 0;
+ virtual bool ReadFPR() = 0;
+ virtual bool WriteGPR() = 0;
+ virtual bool WriteFPR() = 0;
};
#endif // liblldb_RegisterContextPOSIX_mips64_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp
index e353e8114765..6a9838a6fd0c 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp
@@ -1,4 +1,5 @@
-//===-- RegisterContextPOSIX_powerpc.cpp -------------------------*- C++ -*-===//
+//===-- RegisterContextPOSIX_powerpc.cpp -------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,305 +16,184 @@
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h"
+#include "lldb/Host/Endian.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-#include "lldb/Host/Endian.h"
#include "llvm/Support/Compiler.h"
-#include "RegisterContextPOSIX_powerpc.h"
#include "Plugins/Process/elf-core/ProcessElfCore.h"
+#include "RegisterContextPOSIX_powerpc.h"
using namespace lldb_private;
using namespace lldb;
-static const
-uint32_t g_gpr_regnums[] =
-{
- gpr_r0_powerpc,
- gpr_r1_powerpc,
- gpr_r2_powerpc,
- gpr_r3_powerpc,
- gpr_r4_powerpc,
- gpr_r5_powerpc,
- gpr_r6_powerpc,
- gpr_r7_powerpc,
- gpr_r8_powerpc,
- gpr_r9_powerpc,
- gpr_r10_powerpc,
- gpr_r11_powerpc,
- gpr_r12_powerpc,
- gpr_r13_powerpc,
- gpr_r14_powerpc,
- gpr_r15_powerpc,
- gpr_r16_powerpc,
- gpr_r17_powerpc,
- gpr_r18_powerpc,
- gpr_r19_powerpc,
- gpr_r20_powerpc,
- gpr_r21_powerpc,
- gpr_r22_powerpc,
- gpr_r23_powerpc,
- gpr_r24_powerpc,
- gpr_r25_powerpc,
- gpr_r26_powerpc,
- gpr_r27_powerpc,
- gpr_r28_powerpc,
- gpr_r29_powerpc,
- gpr_r30_powerpc,
- gpr_r31_powerpc,
- gpr_lr_powerpc,
- gpr_cr_powerpc,
- gpr_xer_powerpc,
- gpr_ctr_powerpc,
+static const uint32_t g_gpr_regnums[] = {
+ gpr_r0_powerpc, gpr_r1_powerpc, gpr_r2_powerpc, gpr_r3_powerpc,
+ gpr_r4_powerpc, gpr_r5_powerpc, gpr_r6_powerpc, gpr_r7_powerpc,
+ gpr_r8_powerpc, gpr_r9_powerpc, gpr_r10_powerpc, gpr_r11_powerpc,
+ gpr_r12_powerpc, gpr_r13_powerpc, gpr_r14_powerpc, gpr_r15_powerpc,
+ gpr_r16_powerpc, gpr_r17_powerpc, gpr_r18_powerpc, gpr_r19_powerpc,
+ gpr_r20_powerpc, gpr_r21_powerpc, gpr_r22_powerpc, gpr_r23_powerpc,
+ gpr_r24_powerpc, gpr_r25_powerpc, gpr_r26_powerpc, gpr_r27_powerpc,
+ gpr_r28_powerpc, gpr_r29_powerpc, gpr_r30_powerpc, gpr_r31_powerpc,
+ gpr_lr_powerpc, gpr_cr_powerpc, gpr_xer_powerpc, gpr_ctr_powerpc,
gpr_pc_powerpc,
};
-static const
-uint32_t g_fpr_regnums[] =
-{
- fpr_f0_powerpc,
- fpr_f1_powerpc,
- fpr_f2_powerpc,
- fpr_f3_powerpc,
- fpr_f4_powerpc,
- fpr_f5_powerpc,
- fpr_f6_powerpc,
- fpr_f7_powerpc,
- fpr_f8_powerpc,
- fpr_f9_powerpc,
- fpr_f10_powerpc,
- fpr_f11_powerpc,
- fpr_f12_powerpc,
- fpr_f13_powerpc,
- fpr_f14_powerpc,
- fpr_f15_powerpc,
- fpr_f16_powerpc,
- fpr_f17_powerpc,
- fpr_f18_powerpc,
- fpr_f19_powerpc,
- fpr_f20_powerpc,
- fpr_f21_powerpc,
- fpr_f22_powerpc,
- fpr_f23_powerpc,
- fpr_f24_powerpc,
- fpr_f25_powerpc,
- fpr_f26_powerpc,
- fpr_f27_powerpc,
- fpr_f28_powerpc,
- fpr_f29_powerpc,
- fpr_f30_powerpc,
- fpr_f31_powerpc,
+static const uint32_t g_fpr_regnums[] = {
+ fpr_f0_powerpc, fpr_f1_powerpc, fpr_f2_powerpc, fpr_f3_powerpc,
+ fpr_f4_powerpc, fpr_f5_powerpc, fpr_f6_powerpc, fpr_f7_powerpc,
+ fpr_f8_powerpc, fpr_f9_powerpc, fpr_f10_powerpc, fpr_f11_powerpc,
+ fpr_f12_powerpc, fpr_f13_powerpc, fpr_f14_powerpc, fpr_f15_powerpc,
+ fpr_f16_powerpc, fpr_f17_powerpc, fpr_f18_powerpc, fpr_f19_powerpc,
+ fpr_f20_powerpc, fpr_f21_powerpc, fpr_f22_powerpc, fpr_f23_powerpc,
+ fpr_f24_powerpc, fpr_f25_powerpc, fpr_f26_powerpc, fpr_f27_powerpc,
+ fpr_f28_powerpc, fpr_f29_powerpc, fpr_f30_powerpc, fpr_f31_powerpc,
fpr_fpscr_powerpc,
};
-static const
-uint32_t g_vmx_regnums[] =
-{
- vmx_v0_powerpc,
- vmx_v1_powerpc,
- vmx_v2_powerpc,
- vmx_v3_powerpc,
- vmx_v4_powerpc,
- vmx_v5_powerpc,
- vmx_v6_powerpc,
- vmx_v7_powerpc,
- vmx_v8_powerpc,
- vmx_v9_powerpc,
- vmx_v10_powerpc,
- vmx_v11_powerpc,
- vmx_v12_powerpc,
- vmx_v13_powerpc,
- vmx_v14_powerpc,
- vmx_v15_powerpc,
- vmx_v16_powerpc,
- vmx_v17_powerpc,
- vmx_v18_powerpc,
- vmx_v19_powerpc,
- vmx_v20_powerpc,
- vmx_v21_powerpc,
- vmx_v22_powerpc,
- vmx_v23_powerpc,
- vmx_v24_powerpc,
- vmx_v25_powerpc,
- vmx_v26_powerpc,
- vmx_v27_powerpc,
- vmx_v28_powerpc,
- vmx_v29_powerpc,
- vmx_v30_powerpc,
- vmx_v31_powerpc,
- vmx_vrsave_powerpc,
- vmx_vscr_powerpc,
+static const uint32_t g_vmx_regnums[] = {
+ vmx_v0_powerpc, vmx_v1_powerpc, vmx_v2_powerpc, vmx_v3_powerpc,
+ vmx_v4_powerpc, vmx_v5_powerpc, vmx_v6_powerpc, vmx_v7_powerpc,
+ vmx_v8_powerpc, vmx_v9_powerpc, vmx_v10_powerpc, vmx_v11_powerpc,
+ vmx_v12_powerpc, vmx_v13_powerpc, vmx_v14_powerpc, vmx_v15_powerpc,
+ vmx_v16_powerpc, vmx_v17_powerpc, vmx_v18_powerpc, vmx_v19_powerpc,
+ vmx_v20_powerpc, vmx_v21_powerpc, vmx_v22_powerpc, vmx_v23_powerpc,
+ vmx_v24_powerpc, vmx_v25_powerpc, vmx_v26_powerpc, vmx_v27_powerpc,
+ vmx_v28_powerpc, vmx_v29_powerpc, vmx_v30_powerpc, vmx_v31_powerpc,
+ vmx_vrsave_powerpc, vmx_vscr_powerpc,
};
// Number of register sets provided by this context.
-enum
-{
- k_num_register_sets = 3
+enum { k_num_register_sets = 3 };
+
+static const RegisterSet g_reg_sets_powerpc[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_powerpc,
+ g_gpr_regnums},
+ {"Floating Point Registers", "fpr", k_num_fpr_registers_powerpc,
+ g_fpr_regnums},
+ {"Altivec/VMX Registers", "vmx", k_num_vmx_registers_powerpc,
+ g_vmx_regnums},
};
-static const RegisterSet
-g_reg_sets_powerpc[k_num_register_sets] =
-{
- { "General Purpose Registers", "gpr", k_num_gpr_registers_powerpc, g_gpr_regnums },
- { "Floating Point Registers", "fpr", k_num_fpr_registers_powerpc, g_fpr_regnums },
- { "Altivec/VMX Registers", "vmx", k_num_vmx_registers_powerpc, g_vmx_regnums },
-};
-
-static_assert(k_first_gpr_powerpc == 0, "GPRs must index starting at 0, or fix IsGPR()");
-bool RegisterContextPOSIX_powerpc::IsGPR(unsigned reg)
-{
- return (reg <= k_last_gpr_powerpc); // GPR's come first.
+static_assert(k_first_gpr_powerpc == 0,
+ "GPRs must index starting at 0, or fix IsGPR()");
+bool RegisterContextPOSIX_powerpc::IsGPR(unsigned reg) {
+ return (reg <= k_last_gpr_powerpc); // GPR's come first.
}
-bool
-RegisterContextPOSIX_powerpc::IsFPR(unsigned reg)
-{
- return (reg >= k_first_fpr) && (reg <= k_last_fpr);
+bool RegisterContextPOSIX_powerpc::IsFPR(unsigned reg) {
+ return (reg >= k_first_fpr) && (reg <= k_last_fpr);
}
-bool
-RegisterContextPOSIX_powerpc::IsVMX(unsigned reg)
-{
- return (reg >= k_first_vmx) && (reg <= k_last_vmx);
+bool RegisterContextPOSIX_powerpc::IsVMX(unsigned reg) {
+ return (reg >= k_first_vmx) && (reg <= k_last_vmx);
}
-RegisterContextPOSIX_powerpc::RegisterContextPOSIX_powerpc(Thread &thread,
- uint32_t concrete_frame_idx,
- RegisterInfoInterface *register_info)
- : RegisterContext(thread, concrete_frame_idx)
-{
- m_register_info_ap.reset(register_info);
-
- // elf-core yet to support ReadFPR()
- ProcessSP base = CalculateProcess();
- if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic())
- return;
-}
+RegisterContextPOSIX_powerpc::RegisterContextPOSIX_powerpc(
+ Thread &thread, uint32_t concrete_frame_idx,
+ RegisterInfoInterface *register_info)
+ : RegisterContext(thread, concrete_frame_idx) {
+ m_register_info_ap.reset(register_info);
-RegisterContextPOSIX_powerpc::~RegisterContextPOSIX_powerpc()
-{
+ // elf-core yet to support ReadFPR()
+ ProcessSP base = CalculateProcess();
+ if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic())
+ return;
}
-void
-RegisterContextPOSIX_powerpc::Invalidate()
-{
-}
+RegisterContextPOSIX_powerpc::~RegisterContextPOSIX_powerpc() {}
-void
-RegisterContextPOSIX_powerpc::InvalidateAllRegisters()
-{
-}
+void RegisterContextPOSIX_powerpc::Invalidate() {}
-unsigned
-RegisterContextPOSIX_powerpc::GetRegisterOffset(unsigned reg)
-{
- assert(reg < k_num_registers_powerpc && "Invalid register number.");
- return GetRegisterInfo()[reg].byte_offset;
+void RegisterContextPOSIX_powerpc::InvalidateAllRegisters() {}
+
+unsigned RegisterContextPOSIX_powerpc::GetRegisterOffset(unsigned reg) {
+ assert(reg < k_num_registers_powerpc && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_offset;
}
-unsigned
-RegisterContextPOSIX_powerpc::GetRegisterSize(unsigned reg)
-{
- assert(reg < k_num_registers_powerpc && "Invalid register number.");
- return GetRegisterInfo()[reg].byte_size;
+unsigned RegisterContextPOSIX_powerpc::GetRegisterSize(unsigned reg) {
+ assert(reg < k_num_registers_powerpc && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_size;
}
-size_t
-RegisterContextPOSIX_powerpc::GetRegisterCount()
-{
- size_t num_registers = k_num_registers_powerpc;
- return num_registers;
+size_t RegisterContextPOSIX_powerpc::GetRegisterCount() {
+ size_t num_registers = k_num_registers_powerpc;
+ return num_registers;
}
-size_t
-RegisterContextPOSIX_powerpc::GetGPRSize()
-{
- return m_register_info_ap->GetGPRSize();
+size_t RegisterContextPOSIX_powerpc::GetGPRSize() {
+ return m_register_info_ap->GetGPRSize();
}
-const RegisterInfo *
-RegisterContextPOSIX_powerpc::GetRegisterInfo()
-{
- // Commonly, this method is overridden and g_register_infos is copied and specialized.
- // So, use GetRegisterInfo() rather than g_register_infos in this scope.
- return m_register_info_ap->GetRegisterInfo ();
+const RegisterInfo *RegisterContextPOSIX_powerpc::GetRegisterInfo() {
+ // Commonly, this method is overridden and g_register_infos is copied and
+ // specialized.
+ // So, use GetRegisterInfo() rather than g_register_infos in this scope.
+ return m_register_info_ap->GetRegisterInfo();
}
const RegisterInfo *
-RegisterContextPOSIX_powerpc::GetRegisterInfoAtIndex(size_t reg)
-{
- if (reg < k_num_registers_powerpc)
- return &GetRegisterInfo()[reg];
- else
- return NULL;
+RegisterContextPOSIX_powerpc::GetRegisterInfoAtIndex(size_t reg) {
+ if (reg < k_num_registers_powerpc)
+ return &GetRegisterInfo()[reg];
+ else
+ return NULL;
}
-size_t
-RegisterContextPOSIX_powerpc::GetRegisterSetCount()
-{
- size_t sets = 0;
- for (size_t set = 0; set < k_num_register_sets; ++set)
- {
- if (IsRegisterSetAvailable(set))
- ++sets;
- }
-
- return sets;
+size_t RegisterContextPOSIX_powerpc::GetRegisterSetCount() {
+ size_t sets = 0;
+ for (size_t set = 0; set < k_num_register_sets; ++set) {
+ if (IsRegisterSetAvailable(set))
+ ++sets;
+ }
+
+ return sets;
}
-const RegisterSet *
-RegisterContextPOSIX_powerpc::GetRegisterSet(size_t set)
-{
- if (IsRegisterSetAvailable(set))
- return &g_reg_sets_powerpc[set];
- else
- return NULL;
+const RegisterSet *RegisterContextPOSIX_powerpc::GetRegisterSet(size_t set) {
+ if (IsRegisterSetAvailable(set))
+ return &g_reg_sets_powerpc[set];
+ else
+ return NULL;
}
-const char *
-RegisterContextPOSIX_powerpc::GetRegisterName(unsigned reg)
-{
- assert(reg < k_num_registers_powerpc && "Invalid register offset.");
- return GetRegisterInfo()[reg].name;
+const char *RegisterContextPOSIX_powerpc::GetRegisterName(unsigned reg) {
+ assert(reg < k_num_registers_powerpc && "Invalid register offset.");
+ return GetRegisterInfo()[reg].name;
}
-lldb::ByteOrder
-RegisterContextPOSIX_powerpc::GetByteOrder()
-{
- // Get the target process whose privileged thread was used for the register read.
- lldb::ByteOrder byte_order = eByteOrderInvalid;
- Process *process = CalculateProcess().get();
+lldb::ByteOrder RegisterContextPOSIX_powerpc::GetByteOrder() {
+ // Get the target process whose privileged thread was used for the register
+ // read.
+ lldb::ByteOrder byte_order = eByteOrderInvalid;
+ Process *process = CalculateProcess().get();
- if (process)
- byte_order = process->GetByteOrder();
- return byte_order;
+ if (process)
+ byte_order = process->GetByteOrder();
+ return byte_order;
}
-bool
-RegisterContextPOSIX_powerpc::IsRegisterSetAvailable(size_t set_index)
-{
- size_t num_sets = k_num_register_sets;
+bool RegisterContextPOSIX_powerpc::IsRegisterSetAvailable(size_t set_index) {
+ size_t num_sets = k_num_register_sets;
- return (set_index < num_sets);
+ return (set_index < num_sets);
}
// Used when parsing DWARF and EH frame information and any other
// object file sections that contain register numbers in them.
-uint32_t
-RegisterContextPOSIX_powerpc::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
- uint32_t num)
-{
- const uint32_t num_regs = GetRegisterCount();
-
- assert (kind < kNumRegisterKinds);
- for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
- {
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg_idx);
-
- if (reg_info->kinds[kind] == num)
- return reg_idx;
- }
-
- return LLDB_INVALID_REGNUM;
-}
+uint32_t RegisterContextPOSIX_powerpc::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t num) {
+ const uint32_t num_regs = GetRegisterCount();
+
+ assert(kind < kNumRegisterKinds);
+ for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx);
+ if (reg_info->kinds[kind] == num)
+ return reg_idx;
+ }
+
+ return LLDB_INVALID_REGNUM;
+}
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h b/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h
index 4168e46ebd9a..79bb01f6740c 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h
@@ -14,210 +14,196 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
+#include "RegisterContext_powerpc.h"
+#include "RegisterInfoInterface.h"
#include "lldb/Core/Log.h"
#include "lldb/Target/RegisterContext.h"
-#include "RegisterInfoInterface.h"
-#include "RegisterContext_powerpc.h"
class ProcessMonitor;
// ---------------------------------------------------------------------------
// Internal codes for all powerpc registers.
// ---------------------------------------------------------------------------
-enum
-{
- k_first_gpr_powerpc,
- gpr_r0_powerpc = k_first_gpr_powerpc,
- gpr_r1_powerpc,
- gpr_r2_powerpc,
- gpr_r3_powerpc,
- gpr_r4_powerpc,
- gpr_r5_powerpc,
- gpr_r6_powerpc,
- gpr_r7_powerpc,
- gpr_r8_powerpc,
- gpr_r9_powerpc,
- gpr_r10_powerpc,
- gpr_r11_powerpc,
- gpr_r12_powerpc,
- gpr_r13_powerpc,
- gpr_r14_powerpc,
- gpr_r15_powerpc,
- gpr_r16_powerpc,
- gpr_r17_powerpc,
- gpr_r18_powerpc,
- gpr_r19_powerpc,
- gpr_r20_powerpc,
- gpr_r21_powerpc,
- gpr_r22_powerpc,
- gpr_r23_powerpc,
- gpr_r24_powerpc,
- gpr_r25_powerpc,
- gpr_r26_powerpc,
- gpr_r27_powerpc,
- gpr_r28_powerpc,
- gpr_r29_powerpc,
- gpr_r30_powerpc,
- gpr_r31_powerpc,
- gpr_lr_powerpc,
- gpr_cr_powerpc,
- gpr_xer_powerpc,
- gpr_ctr_powerpc,
- gpr_pc_powerpc,
- k_last_gpr_powerpc = gpr_pc_powerpc,
-
- k_first_fpr,
- fpr_f0_powerpc = k_first_fpr,
- fpr_f1_powerpc,
- fpr_f2_powerpc,
- fpr_f3_powerpc,
- fpr_f4_powerpc,
- fpr_f5_powerpc,
- fpr_f6_powerpc,
- fpr_f7_powerpc,
- fpr_f8_powerpc,
- fpr_f9_powerpc,
- fpr_f10_powerpc,
- fpr_f11_powerpc,
- fpr_f12_powerpc,
- fpr_f13_powerpc,
- fpr_f14_powerpc,
- fpr_f15_powerpc,
- fpr_f16_powerpc,
- fpr_f17_powerpc,
- fpr_f18_powerpc,
- fpr_f19_powerpc,
- fpr_f20_powerpc,
- fpr_f21_powerpc,
- fpr_f22_powerpc,
- fpr_f23_powerpc,
- fpr_f24_powerpc,
- fpr_f25_powerpc,
- fpr_f26_powerpc,
- fpr_f27_powerpc,
- fpr_f28_powerpc,
- fpr_f29_powerpc,
- fpr_f30_powerpc,
- fpr_f31_powerpc,
- fpr_fpscr_powerpc,
- k_last_fpr = fpr_fpscr_powerpc,
-
- k_first_vmx,
- vmx_v0_powerpc = k_first_vmx,
- vmx_v1_powerpc,
- vmx_v2_powerpc,
- vmx_v3_powerpc,
- vmx_v4_powerpc,
- vmx_v5_powerpc,
- vmx_v6_powerpc,
- vmx_v7_powerpc,
- vmx_v8_powerpc,
- vmx_v9_powerpc,
- vmx_v10_powerpc,
- vmx_v11_powerpc,
- vmx_v12_powerpc,
- vmx_v13_powerpc,
- vmx_v14_powerpc,
- vmx_v15_powerpc,
- vmx_v16_powerpc,
- vmx_v17_powerpc,
- vmx_v18_powerpc,
- vmx_v19_powerpc,
- vmx_v20_powerpc,
- vmx_v21_powerpc,
- vmx_v22_powerpc,
- vmx_v23_powerpc,
- vmx_v24_powerpc,
- vmx_v25_powerpc,
- vmx_v26_powerpc,
- vmx_v27_powerpc,
- vmx_v28_powerpc,
- vmx_v29_powerpc,
- vmx_v30_powerpc,
- vmx_v31_powerpc,
- vmx_vrsave_powerpc,
- vmx_vscr_powerpc,
- k_last_vmx = vmx_vscr_powerpc,
-
- k_num_registers_powerpc,
- k_num_gpr_registers_powerpc = k_last_gpr_powerpc - k_first_gpr_powerpc + 1,
- k_num_fpr_registers_powerpc = k_last_fpr - k_first_fpr + 1,
- k_num_vmx_registers_powerpc = k_last_vmx - k_first_vmx + 1,
+enum {
+ k_first_gpr_powerpc,
+ gpr_r0_powerpc = k_first_gpr_powerpc,
+ gpr_r1_powerpc,
+ gpr_r2_powerpc,
+ gpr_r3_powerpc,
+ gpr_r4_powerpc,
+ gpr_r5_powerpc,
+ gpr_r6_powerpc,
+ gpr_r7_powerpc,
+ gpr_r8_powerpc,
+ gpr_r9_powerpc,
+ gpr_r10_powerpc,
+ gpr_r11_powerpc,
+ gpr_r12_powerpc,
+ gpr_r13_powerpc,
+ gpr_r14_powerpc,
+ gpr_r15_powerpc,
+ gpr_r16_powerpc,
+ gpr_r17_powerpc,
+ gpr_r18_powerpc,
+ gpr_r19_powerpc,
+ gpr_r20_powerpc,
+ gpr_r21_powerpc,
+ gpr_r22_powerpc,
+ gpr_r23_powerpc,
+ gpr_r24_powerpc,
+ gpr_r25_powerpc,
+ gpr_r26_powerpc,
+ gpr_r27_powerpc,
+ gpr_r28_powerpc,
+ gpr_r29_powerpc,
+ gpr_r30_powerpc,
+ gpr_r31_powerpc,
+ gpr_lr_powerpc,
+ gpr_cr_powerpc,
+ gpr_xer_powerpc,
+ gpr_ctr_powerpc,
+ gpr_pc_powerpc,
+ k_last_gpr_powerpc = gpr_pc_powerpc,
+
+ k_first_fpr,
+ fpr_f0_powerpc = k_first_fpr,
+ fpr_f1_powerpc,
+ fpr_f2_powerpc,
+ fpr_f3_powerpc,
+ fpr_f4_powerpc,
+ fpr_f5_powerpc,
+ fpr_f6_powerpc,
+ fpr_f7_powerpc,
+ fpr_f8_powerpc,
+ fpr_f9_powerpc,
+ fpr_f10_powerpc,
+ fpr_f11_powerpc,
+ fpr_f12_powerpc,
+ fpr_f13_powerpc,
+ fpr_f14_powerpc,
+ fpr_f15_powerpc,
+ fpr_f16_powerpc,
+ fpr_f17_powerpc,
+ fpr_f18_powerpc,
+ fpr_f19_powerpc,
+ fpr_f20_powerpc,
+ fpr_f21_powerpc,
+ fpr_f22_powerpc,
+ fpr_f23_powerpc,
+ fpr_f24_powerpc,
+ fpr_f25_powerpc,
+ fpr_f26_powerpc,
+ fpr_f27_powerpc,
+ fpr_f28_powerpc,
+ fpr_f29_powerpc,
+ fpr_f30_powerpc,
+ fpr_f31_powerpc,
+ fpr_fpscr_powerpc,
+ k_last_fpr = fpr_fpscr_powerpc,
+
+ k_first_vmx,
+ vmx_v0_powerpc = k_first_vmx,
+ vmx_v1_powerpc,
+ vmx_v2_powerpc,
+ vmx_v3_powerpc,
+ vmx_v4_powerpc,
+ vmx_v5_powerpc,
+ vmx_v6_powerpc,
+ vmx_v7_powerpc,
+ vmx_v8_powerpc,
+ vmx_v9_powerpc,
+ vmx_v10_powerpc,
+ vmx_v11_powerpc,
+ vmx_v12_powerpc,
+ vmx_v13_powerpc,
+ vmx_v14_powerpc,
+ vmx_v15_powerpc,
+ vmx_v16_powerpc,
+ vmx_v17_powerpc,
+ vmx_v18_powerpc,
+ vmx_v19_powerpc,
+ vmx_v20_powerpc,
+ vmx_v21_powerpc,
+ vmx_v22_powerpc,
+ vmx_v23_powerpc,
+ vmx_v24_powerpc,
+ vmx_v25_powerpc,
+ vmx_v26_powerpc,
+ vmx_v27_powerpc,
+ vmx_v28_powerpc,
+ vmx_v29_powerpc,
+ vmx_v30_powerpc,
+ vmx_v31_powerpc,
+ vmx_vrsave_powerpc,
+ vmx_vscr_powerpc,
+ k_last_vmx = vmx_vscr_powerpc,
+
+ k_num_registers_powerpc,
+ k_num_gpr_registers_powerpc = k_last_gpr_powerpc - k_first_gpr_powerpc + 1,
+ k_num_fpr_registers_powerpc = k_last_fpr - k_first_fpr + 1,
+ k_num_vmx_registers_powerpc = k_last_vmx - k_first_vmx + 1,
};
-class RegisterContextPOSIX_powerpc
- : public lldb_private::RegisterContext
-{
+class RegisterContextPOSIX_powerpc : public lldb_private::RegisterContext {
public:
- RegisterContextPOSIX_powerpc (lldb_private::Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info);
+ RegisterContextPOSIX_powerpc(
+ lldb_private::Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info);
- ~RegisterContextPOSIX_powerpc() override;
+ ~RegisterContextPOSIX_powerpc() override;
- void
- Invalidate();
+ void Invalidate();
- void
- InvalidateAllRegisters() override;
+ void InvalidateAllRegisters() override;
- size_t
- GetRegisterCount() override;
+ size_t GetRegisterCount() override;
- virtual size_t
- GetGPRSize();
+ virtual size_t GetGPRSize();
- virtual unsigned
- GetRegisterSize(unsigned reg);
+ virtual unsigned GetRegisterSize(unsigned reg);
- virtual unsigned
- GetRegisterOffset(unsigned reg);
+ virtual unsigned GetRegisterOffset(unsigned reg);
- const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex(size_t reg) override;
+ const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
- size_t
- GetRegisterSetCount() override;
+ size_t GetRegisterSetCount() override;
- const lldb_private::RegisterSet *
- GetRegisterSet(size_t set) override;
+ const lldb_private::RegisterSet *GetRegisterSet(size_t set) override;
- const char *
- GetRegisterName(unsigned reg);
+ const char *GetRegisterName(unsigned reg);
- uint32_t
- ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
protected:
- uint64_t m_gpr_powerpc[k_num_gpr_registers_powerpc]; // general purpose registers.
- uint64_t m_fpr_powerpc[k_num_fpr_registers_powerpc]; // floating point registers.
- uint32_t m_vmx_powerpc[k_num_vmx_registers_powerpc][4];
- std::unique_ptr<lldb_private::RegisterInfoInterface> m_register_info_ap; // Register Info Interface (FreeBSD or Linux)
+ uint64_t
+ m_gpr_powerpc[k_num_gpr_registers_powerpc]; // general purpose registers.
+ uint64_t
+ m_fpr_powerpc[k_num_fpr_registers_powerpc]; // floating point registers.
+ uint32_t m_vmx_powerpc[k_num_vmx_registers_powerpc][4];
+ std::unique_ptr<lldb_private::RegisterInfoInterface>
+ m_register_info_ap; // Register Info Interface (FreeBSD or Linux)
- // Determines if an extended register set is supported on the processor running the inferior process.
- virtual bool
- IsRegisterSetAvailable(size_t set_index);
+ // Determines if an extended register set is supported on the processor
+ // running the inferior process.
+ virtual bool IsRegisterSetAvailable(size_t set_index);
- virtual const lldb_private::RegisterInfo *
- GetRegisterInfo();
+ virtual const lldb_private::RegisterInfo *GetRegisterInfo();
- bool
- IsGPR(unsigned reg);
+ bool IsGPR(unsigned reg);
- bool
- IsFPR(unsigned reg);
+ bool IsFPR(unsigned reg);
- bool
- IsVMX(unsigned reg);
+ bool IsVMX(unsigned reg);
- lldb::ByteOrder GetByteOrder();
+ lldb::ByteOrder GetByteOrder();
- virtual bool ReadGPR() = 0;
- virtual bool ReadFPR() = 0;
- virtual bool ReadVMX() = 0;
- virtual bool WriteGPR() = 0;
- virtual bool WriteFPR() = 0;
- virtual bool WriteVMX() = 0;
+ virtual bool ReadGPR() = 0;
+ virtual bool ReadFPR() = 0;
+ virtual bool ReadVMX() = 0;
+ virtual bool WriteGPR() = 0;
+ virtual bool WriteFPR() = 0;
+ virtual bool WriteVMX() = 0;
};
#endif // liblldb_RegisterContextPOSIX_powerpc_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp
index 960be50c7be3..e4dbe333a22d 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextPOSIX_x86.cpp ----------------------------*- C++ -*-===//
+//===-- RegisterContextPOSIX_s390x.cpp --------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -21,245 +21,172 @@
#include "lldb/Target/Thread.h"
#include "llvm/Support/Compiler.h"
-#include "RegisterContext_s390x.h"
#include "RegisterContextPOSIX_s390x.h"
+#include "RegisterContext_s390x.h"
using namespace lldb_private;
using namespace lldb;
// s390x 64-bit general purpose registers.
-static const uint32_t g_gpr_regnums_s390x[] =
-{
- lldb_r0_s390x,
- lldb_r1_s390x,
- lldb_r2_s390x,
- lldb_r3_s390x,
- lldb_r4_s390x,
- lldb_r5_s390x,
- lldb_r6_s390x,
- lldb_r7_s390x,
- lldb_r8_s390x,
- lldb_r9_s390x,
- lldb_r10_s390x,
- lldb_r11_s390x,
- lldb_r12_s390x,
- lldb_r13_s390x,
- lldb_r14_s390x,
- lldb_r15_s390x,
- lldb_acr0_s390x,
- lldb_acr1_s390x,
- lldb_acr2_s390x,
- lldb_acr3_s390x,
- lldb_acr4_s390x,
- lldb_acr5_s390x,
- lldb_acr6_s390x,
- lldb_acr7_s390x,
- lldb_acr8_s390x,
- lldb_acr9_s390x,
- lldb_acr10_s390x,
- lldb_acr11_s390x,
- lldb_acr12_s390x,
- lldb_acr13_s390x,
- lldb_acr14_s390x,
- lldb_acr15_s390x,
- lldb_pswm_s390x,
- lldb_pswa_s390x,
+static const uint32_t g_gpr_regnums_s390x[] = {
+ lldb_r0_s390x, lldb_r1_s390x, lldb_r2_s390x, lldb_r3_s390x,
+ lldb_r4_s390x, lldb_r5_s390x, lldb_r6_s390x, lldb_r7_s390x,
+ lldb_r8_s390x, lldb_r9_s390x, lldb_r10_s390x, lldb_r11_s390x,
+ lldb_r12_s390x, lldb_r13_s390x, lldb_r14_s390x, lldb_r15_s390x,
+ lldb_acr0_s390x, lldb_acr1_s390x, lldb_acr2_s390x, lldb_acr3_s390x,
+ lldb_acr4_s390x, lldb_acr5_s390x, lldb_acr6_s390x, lldb_acr7_s390x,
+ lldb_acr8_s390x, lldb_acr9_s390x, lldb_acr10_s390x, lldb_acr11_s390x,
+ lldb_acr12_s390x, lldb_acr13_s390x, lldb_acr14_s390x, lldb_acr15_s390x,
+ lldb_pswm_s390x, lldb_pswa_s390x,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
-static_assert((sizeof(g_gpr_regnums_s390x) / sizeof(g_gpr_regnums_s390x[0])) - 1 == k_num_gpr_registers_s390x,
+static_assert((sizeof(g_gpr_regnums_s390x) / sizeof(g_gpr_regnums_s390x[0])) -
+ 1 ==
+ k_num_gpr_registers_s390x,
"g_gpr_regnums_s390x has wrong number of register infos");
// s390x 64-bit floating point registers.
-static const uint32_t g_fpu_regnums_s390x[] =
-{
- lldb_f0_s390x,
- lldb_f1_s390x,
- lldb_f2_s390x,
- lldb_f3_s390x,
- lldb_f4_s390x,
- lldb_f5_s390x,
- lldb_f6_s390x,
- lldb_f7_s390x,
- lldb_f8_s390x,
- lldb_f9_s390x,
- lldb_f10_s390x,
- lldb_f11_s390x,
- lldb_f12_s390x,
- lldb_f13_s390x,
- lldb_f14_s390x,
- lldb_f15_s390x,
+static const uint32_t g_fpu_regnums_s390x[] = {
+ lldb_f0_s390x, lldb_f1_s390x, lldb_f2_s390x, lldb_f3_s390x,
+ lldb_f4_s390x, lldb_f5_s390x, lldb_f6_s390x, lldb_f7_s390x,
+ lldb_f8_s390x, lldb_f9_s390x, lldb_f10_s390x, lldb_f11_s390x,
+ lldb_f12_s390x, lldb_f13_s390x, lldb_f14_s390x, lldb_f15_s390x,
lldb_fpc_s390x,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
-static_assert((sizeof(g_fpu_regnums_s390x) / sizeof(g_fpu_regnums_s390x[0])) - 1 == k_num_fpr_registers_s390x,
+static_assert((sizeof(g_fpu_regnums_s390x) / sizeof(g_fpu_regnums_s390x[0])) -
+ 1 ==
+ k_num_fpr_registers_s390x,
"g_fpu_regnums_s390x has wrong number of register infos");
// Number of register sets provided by this context.
-enum
-{
- k_num_register_sets = 2
-};
+enum { k_num_register_sets = 2 };
// Register sets for s390x 64-bit.
-static const RegisterSet g_reg_sets_s390x[k_num_register_sets] =
-{
- { "General Purpose Registers", "gpr", k_num_gpr_registers_s390x, g_gpr_regnums_s390x },
- { "Floating Point Registers", "fpr", k_num_fpr_registers_s390x, g_fpu_regnums_s390x },
+static const RegisterSet g_reg_sets_s390x[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_s390x,
+ g_gpr_regnums_s390x},
+ {"Floating Point Registers", "fpr", k_num_fpr_registers_s390x,
+ g_fpu_regnums_s390x},
};
-bool
-RegisterContextPOSIX_s390x::IsGPR(unsigned reg)
-{
- return reg <= m_reg_info.last_gpr; // GPRs come first.
+bool RegisterContextPOSIX_s390x::IsGPR(unsigned reg) {
+ return reg <= m_reg_info.last_gpr; // GPRs come first.
}
-bool
-RegisterContextPOSIX_s390x::IsFPR(unsigned reg)
-{
- return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
+bool RegisterContextPOSIX_s390x::IsFPR(unsigned reg) {
+ return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
}
-RegisterContextPOSIX_s390x::RegisterContextPOSIX_s390x(Thread &thread, uint32_t concrete_frame_idx,
- RegisterInfoInterface *register_info)
- : RegisterContext(thread, concrete_frame_idx)
-{
- m_register_info_ap.reset(register_info);
+RegisterContextPOSIX_s390x::RegisterContextPOSIX_s390x(
+ Thread &thread, uint32_t concrete_frame_idx,
+ RegisterInfoInterface *register_info)
+ : RegisterContext(thread, concrete_frame_idx) {
+ m_register_info_ap.reset(register_info);
- switch (register_info->m_target_arch.GetMachine())
- {
- case llvm::Triple::systemz:
- m_reg_info.num_registers = k_num_registers_s390x;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_s390x;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_s390x;
- m_reg_info.last_gpr = k_last_gpr_s390x;
- m_reg_info.first_fpr = k_first_fpr_s390x;
- m_reg_info.last_fpr = k_last_fpr_s390x;
- break;
- default:
- assert(false && "Unhandled target architecture.");
- break;
- }
+ switch (register_info->m_target_arch.GetMachine()) {
+ case llvm::Triple::systemz:
+ m_reg_info.num_registers = k_num_registers_s390x;
+ m_reg_info.num_gpr_registers = k_num_gpr_registers_s390x;
+ m_reg_info.num_fpr_registers = k_num_fpr_registers_s390x;
+ m_reg_info.last_gpr = k_last_gpr_s390x;
+ m_reg_info.first_fpr = k_first_fpr_s390x;
+ m_reg_info.last_fpr = k_last_fpr_s390x;
+ break;
+ default:
+ assert(false && "Unhandled target architecture.");
+ break;
+ }
}
-RegisterContextPOSIX_s390x::~RegisterContextPOSIX_s390x()
-{
-}
+RegisterContextPOSIX_s390x::~RegisterContextPOSIX_s390x() {}
-void
-RegisterContextPOSIX_s390x::Invalidate()
-{
-}
+void RegisterContextPOSIX_s390x::Invalidate() {}
-void
-RegisterContextPOSIX_s390x::InvalidateAllRegisters()
-{
-}
+void RegisterContextPOSIX_s390x::InvalidateAllRegisters() {}
-const RegisterInfo *
-RegisterContextPOSIX_s390x::GetRegisterInfo()
-{
- return m_register_info_ap->GetRegisterInfo();
+const RegisterInfo *RegisterContextPOSIX_s390x::GetRegisterInfo() {
+ return m_register_info_ap->GetRegisterInfo();
}
const RegisterInfo *
-RegisterContextPOSIX_s390x::GetRegisterInfoAtIndex(size_t reg)
-{
- if (reg < m_reg_info.num_registers)
- return &GetRegisterInfo()[reg];
- else
- return NULL;
+RegisterContextPOSIX_s390x::GetRegisterInfoAtIndex(size_t reg) {
+ if (reg < m_reg_info.num_registers)
+ return &GetRegisterInfo()[reg];
+ else
+ return NULL;
}
-size_t
-RegisterContextPOSIX_s390x::GetRegisterCount()
-{
- return m_reg_info.num_registers;
+size_t RegisterContextPOSIX_s390x::GetRegisterCount() {
+ return m_reg_info.num_registers;
}
-unsigned
-RegisterContextPOSIX_s390x::GetRegisterOffset(unsigned reg)
-{
- assert(reg < m_reg_info.num_registers && "Invalid register number.");
- return GetRegisterInfo()[reg].byte_offset;
+unsigned RegisterContextPOSIX_s390x::GetRegisterOffset(unsigned reg) {
+ assert(reg < m_reg_info.num_registers && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_offset;
}
-unsigned
-RegisterContextPOSIX_s390x::GetRegisterSize(unsigned reg)
-{
- assert(reg < m_reg_info.num_registers && "Invalid register number.");
- return GetRegisterInfo()[reg].byte_size;
+unsigned RegisterContextPOSIX_s390x::GetRegisterSize(unsigned reg) {
+ assert(reg < m_reg_info.num_registers && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_size;
}
-const char *
-RegisterContextPOSIX_s390x::GetRegisterName(unsigned reg)
-{
- assert(reg < m_reg_info.num_registers && "Invalid register offset.");
- return GetRegisterInfo()[reg].name;
+const char *RegisterContextPOSIX_s390x::GetRegisterName(unsigned reg) {
+ assert(reg < m_reg_info.num_registers && "Invalid register offset.");
+ return GetRegisterInfo()[reg].name;
}
-bool
-RegisterContextPOSIX_s390x::IsRegisterSetAvailable(size_t set_index)
-{
- return set_index < k_num_register_sets;
+bool RegisterContextPOSIX_s390x::IsRegisterSetAvailable(size_t set_index) {
+ return set_index < k_num_register_sets;
}
-size_t
-RegisterContextPOSIX_s390x::GetRegisterSetCount()
-{
- size_t sets = 0;
- for (size_t set = 0; set < k_num_register_sets; ++set)
- {
- if (IsRegisterSetAvailable(set))
- ++sets;
- }
+size_t RegisterContextPOSIX_s390x::GetRegisterSetCount() {
+ size_t sets = 0;
+ for (size_t set = 0; set < k_num_register_sets; ++set) {
+ if (IsRegisterSetAvailable(set))
+ ++sets;
+ }
- return sets;
+ return sets;
}
-const RegisterSet *
-RegisterContextPOSIX_s390x::GetRegisterSet(size_t set)
-{
- if (IsRegisterSetAvailable(set))
- {
- switch (m_register_info_ap->m_target_arch.GetMachine())
- {
- case llvm::Triple::systemz:
- return &g_reg_sets_s390x[set];
- default:
- assert(false && "Unhandled target architecture.");
- return NULL;
- }
+const RegisterSet *RegisterContextPOSIX_s390x::GetRegisterSet(size_t set) {
+ if (IsRegisterSetAvailable(set)) {
+ switch (m_register_info_ap->m_target_arch.GetMachine()) {
+ case llvm::Triple::systemz:
+ return &g_reg_sets_s390x[set];
+ default:
+ assert(false && "Unhandled target architecture.");
+ return NULL;
}
- return NULL;
+ }
+ return NULL;
}
-lldb::ByteOrder
-RegisterContextPOSIX_s390x::GetByteOrder()
-{
- // Get the target process whose privileged thread was used for the register read.
- lldb::ByteOrder byte_order = eByteOrderInvalid;
- Process *process = CalculateProcess().get();
+lldb::ByteOrder RegisterContextPOSIX_s390x::GetByteOrder() {
+ // Get the target process whose privileged thread was used for the register
+ // read.
+ lldb::ByteOrder byte_order = eByteOrderInvalid;
+ Process *process = CalculateProcess().get();
- if (process)
- byte_order = process->GetByteOrder();
- return byte_order;
+ if (process)
+ byte_order = process->GetByteOrder();
+ return byte_order;
}
// Used when parsing DWARF and EH frame information and any other
// object file sections that contain register numbers in them.
-uint32_t
-RegisterContextPOSIX_s390x::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num)
-{
- const uint32_t num_regs = GetRegisterCount();
+uint32_t RegisterContextPOSIX_s390x::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t num) {
+ const uint32_t num_regs = GetRegisterCount();
- assert(kind < kNumRegisterKinds);
- for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
- {
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx);
+ assert(kind < kNumRegisterKinds);
+ for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx);
- if (reg_info->kinds[kind] == num)
- return reg_idx;
- }
+ if (reg_info->kinds[kind] == num)
+ return reg_idx;
+ }
- return LLDB_INVALID_REGNUM;
+ return LLDB_INVALID_REGNUM;
}
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h b/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h
index 4904b2857c43..1ffc45c2d4b1 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h
@@ -14,90 +14,71 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/Log.h"
-#include "lldb/Target/RegisterContext.h"
-#include "RegisterInfoInterface.h"
#include "RegisterContext_s390x.h"
+#include "RegisterInfoInterface.h"
#include "lldb-s390x-register-enums.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Target/RegisterContext.h"
class ProcessMonitor;
-class RegisterContextPOSIX_s390x : public lldb_private::RegisterContext
-{
+class RegisterContextPOSIX_s390x : public lldb_private::RegisterContext {
public:
- RegisterContextPOSIX_s390x(lldb_private::Thread &thread, uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info);
+ RegisterContextPOSIX_s390x(
+ lldb_private::Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info);
- ~RegisterContextPOSIX_s390x() override;
+ ~RegisterContextPOSIX_s390x() override;
- void
- Invalidate();
+ void Invalidate();
- void
- InvalidateAllRegisters() override;
+ void InvalidateAllRegisters() override;
- size_t
- GetRegisterCount() override;
+ size_t GetRegisterCount() override;
- virtual unsigned
- GetRegisterSize(unsigned reg);
+ virtual unsigned GetRegisterSize(unsigned reg);
- virtual unsigned
- GetRegisterOffset(unsigned reg);
+ virtual unsigned GetRegisterOffset(unsigned reg);
- const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex(size_t reg) override;
+ const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
- size_t
- GetRegisterSetCount() override;
+ size_t GetRegisterSetCount() override;
- const lldb_private::RegisterSet *
- GetRegisterSet(size_t set) override;
+ const lldb_private::RegisterSet *GetRegisterSet(size_t set) override;
- const char *
- GetRegisterName(unsigned reg);
+ const char *GetRegisterName(unsigned reg);
- uint32_t
- ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
protected:
- struct RegInfo
- {
- uint32_t num_registers;
- uint32_t num_gpr_registers;
- uint32_t num_fpr_registers;
-
- uint32_t last_gpr;
- uint32_t first_fpr;
- uint32_t last_fpr;
- };
-
- RegInfo m_reg_info;
- std::unique_ptr<lldb_private::RegisterInfoInterface> m_register_info_ap;
-
- virtual bool
- IsRegisterSetAvailable(size_t set_index);
-
- virtual const lldb_private::RegisterInfo *
- GetRegisterInfo();
-
- bool
- IsGPR(unsigned reg);
-
- bool
- IsFPR(unsigned reg);
-
- lldb::ByteOrder
- GetByteOrder();
-
- virtual bool
- ReadGPR() = 0;
- virtual bool
- ReadFPR() = 0;
- virtual bool
- WriteGPR() = 0;
- virtual bool
- WriteFPR() = 0;
+ struct RegInfo {
+ uint32_t num_registers;
+ uint32_t num_gpr_registers;
+ uint32_t num_fpr_registers;
+
+ uint32_t last_gpr;
+ uint32_t first_fpr;
+ uint32_t last_fpr;
+ };
+
+ RegInfo m_reg_info;
+ std::unique_ptr<lldb_private::RegisterInfoInterface> m_register_info_ap;
+
+ virtual bool IsRegisterSetAvailable(size_t set_index);
+
+ virtual const lldb_private::RegisterInfo *GetRegisterInfo();
+
+ bool IsGPR(unsigned reg);
+
+ bool IsFPR(unsigned reg);
+
+ lldb::ByteOrder GetByteOrder();
+
+ virtual bool ReadGPR() = 0;
+ virtual bool ReadFPR() = 0;
+ virtual bool WriteGPR() = 0;
+ virtual bool WriteFPR() = 0;
};
#endif // liblldb_RegisterContextPOSIX_s390x_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
index 77b6385da8bd..99525b6c2df2 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
@@ -15,187 +15,94 @@
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h"
+#include "lldb/Host/Endian.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-#include "lldb/Host/Endian.h"
+#include "lldb/Target/Process.h"
#include "llvm/Support/Compiler.h"
-#include "RegisterContext_x86.h"
#include "RegisterContextPOSIX_x86.h"
-#include "Plugins/Process/elf-core/ProcessElfCore.h"
+#include "RegisterContext_x86.h"
using namespace lldb_private;
using namespace lldb;
-const uint32_t
-g_gpr_regnums_i386[] =
-{
- lldb_eax_i386,
- lldb_ebx_i386,
- lldb_ecx_i386,
- lldb_edx_i386,
- lldb_edi_i386,
- lldb_esi_i386,
- lldb_ebp_i386,
- lldb_esp_i386,
- lldb_eip_i386,
- lldb_eflags_i386,
- lldb_cs_i386,
- lldb_fs_i386,
- lldb_gs_i386,
- lldb_ss_i386,
- lldb_ds_i386,
- lldb_es_i386,
- lldb_ax_i386,
- lldb_bx_i386,
- lldb_cx_i386,
- lldb_dx_i386,
- lldb_di_i386,
- lldb_si_i386,
- lldb_bp_i386,
- lldb_sp_i386,
- lldb_ah_i386,
- lldb_bh_i386,
- lldb_ch_i386,
- lldb_dh_i386,
- lldb_al_i386,
- lldb_bl_i386,
- lldb_cl_i386,
- lldb_dl_i386,
- LLDB_INVALID_REGNUM, // Register sets must be terminated with LLDB_INVALID_REGNUM.
+const uint32_t g_gpr_regnums_i386[] = {
+ lldb_eax_i386, lldb_ebx_i386, lldb_ecx_i386, lldb_edx_i386,
+ lldb_edi_i386, lldb_esi_i386, lldb_ebp_i386, lldb_esp_i386,
+ lldb_eip_i386, lldb_eflags_i386, lldb_cs_i386, lldb_fs_i386,
+ lldb_gs_i386, lldb_ss_i386, lldb_ds_i386, lldb_es_i386,
+ lldb_ax_i386, lldb_bx_i386, lldb_cx_i386, lldb_dx_i386,
+ lldb_di_i386, lldb_si_i386, lldb_bp_i386, lldb_sp_i386,
+ lldb_ah_i386, lldb_bh_i386, lldb_ch_i386, lldb_dh_i386,
+ lldb_al_i386, lldb_bl_i386, lldb_cl_i386, lldb_dl_i386,
+ LLDB_INVALID_REGNUM, // Register sets must be terminated with
+ // LLDB_INVALID_REGNUM.
};
-static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) - 1 == k_num_gpr_registers_i386,
- "g_gpr_regnums_i386 has wrong number of register infos");
-
-const uint32_t
-g_lldb_regnums_i386[] =
-{
- lldb_fctrl_i386,
- lldb_fstat_i386,
- lldb_ftag_i386,
- lldb_fop_i386,
- lldb_fiseg_i386,
- lldb_fioff_i386,
- lldb_foseg_i386,
- lldb_fooff_i386,
- lldb_mxcsr_i386,
- lldb_mxcsrmask_i386,
- lldb_st0_i386,
- lldb_st1_i386,
- lldb_st2_i386,
- lldb_st3_i386,
- lldb_st4_i386,
- lldb_st5_i386,
- lldb_st6_i386,
- lldb_st7_i386,
- lldb_mm0_i386,
- lldb_mm1_i386,
- lldb_mm2_i386,
- lldb_mm3_i386,
- lldb_mm4_i386,
- lldb_mm5_i386,
- lldb_mm6_i386,
- lldb_mm7_i386,
- lldb_xmm0_i386,
- lldb_xmm1_i386,
- lldb_xmm2_i386,
- lldb_xmm3_i386,
- lldb_xmm4_i386,
- lldb_xmm5_i386,
- lldb_xmm6_i386,
- lldb_xmm7_i386,
- LLDB_INVALID_REGNUM // Register sets must be terminated with LLDB_INVALID_REGNUM.
+static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) -
+ 1 ==
+ k_num_gpr_registers_i386,
+ "g_gpr_regnums_i386 has wrong number of register infos");
+
+const uint32_t g_lldb_regnums_i386[] = {
+ lldb_fctrl_i386, lldb_fstat_i386, lldb_ftag_i386, lldb_fop_i386,
+ lldb_fiseg_i386, lldb_fioff_i386, lldb_foseg_i386, lldb_fooff_i386,
+ lldb_mxcsr_i386, lldb_mxcsrmask_i386, lldb_st0_i386, lldb_st1_i386,
+ lldb_st2_i386, lldb_st3_i386, lldb_st4_i386, lldb_st5_i386,
+ lldb_st6_i386, lldb_st7_i386, lldb_mm0_i386, lldb_mm1_i386,
+ lldb_mm2_i386, lldb_mm3_i386, lldb_mm4_i386, lldb_mm5_i386,
+ lldb_mm6_i386, lldb_mm7_i386, lldb_xmm0_i386, lldb_xmm1_i386,
+ lldb_xmm2_i386, lldb_xmm3_i386, lldb_xmm4_i386, lldb_xmm5_i386,
+ lldb_xmm6_i386, lldb_xmm7_i386,
+ LLDB_INVALID_REGNUM // Register sets must be terminated with
+ // LLDB_INVALID_REGNUM.
};
-static_assert((sizeof(g_lldb_regnums_i386) / sizeof(g_lldb_regnums_i386[0])) - 1 == k_num_fpr_registers_i386,
- "g_lldb_regnums_i386 has wrong number of register infos");
-
-const uint32_t
-g_avx_regnums_i386[] =
-{
- lldb_ymm0_i386,
- lldb_ymm1_i386,
- lldb_ymm2_i386,
- lldb_ymm3_i386,
- lldb_ymm4_i386,
- lldb_ymm5_i386,
- lldb_ymm6_i386,
- lldb_ymm7_i386,
- LLDB_INVALID_REGNUM // Register sets must be terminated with LLDB_INVALID_REGNUM.
+static_assert((sizeof(g_lldb_regnums_i386) / sizeof(g_lldb_regnums_i386[0])) -
+ 1 ==
+ k_num_fpr_registers_i386,
+ "g_lldb_regnums_i386 has wrong number of register infos");
+
+const uint32_t g_avx_regnums_i386[] = {
+ lldb_ymm0_i386, lldb_ymm1_i386, lldb_ymm2_i386, lldb_ymm3_i386,
+ lldb_ymm4_i386, lldb_ymm5_i386, lldb_ymm6_i386, lldb_ymm7_i386,
+ LLDB_INVALID_REGNUM // Register sets must be terminated with
+ // LLDB_INVALID_REGNUM.
};
-static_assert((sizeof(g_avx_regnums_i386) / sizeof(g_avx_regnums_i386[0])) - 1 == k_num_avx_registers_i386,
- " g_avx_regnums_i386 has wrong number of register infos");
-
-static const
-uint32_t g_gpr_regnums_x86_64[] =
-{
- lldb_rax_x86_64,
- lldb_rbx_x86_64,
- lldb_rcx_x86_64,
- lldb_rdx_x86_64,
- lldb_rdi_x86_64,
- lldb_rsi_x86_64,
- lldb_rbp_x86_64,
- lldb_rsp_x86_64,
- lldb_r8_x86_64,
- lldb_r9_x86_64,
- lldb_r10_x86_64,
- lldb_r11_x86_64,
- lldb_r12_x86_64,
- lldb_r13_x86_64,
- lldb_r14_x86_64,
- lldb_r15_x86_64,
- lldb_rip_x86_64,
- lldb_rflags_x86_64,
- lldb_cs_x86_64,
- lldb_fs_x86_64,
- lldb_gs_x86_64,
- lldb_ss_x86_64,
- lldb_ds_x86_64,
- lldb_es_x86_64,
- lldb_eax_x86_64,
- lldb_ebx_x86_64,
- lldb_ecx_x86_64,
- lldb_edx_x86_64,
- lldb_edi_x86_64,
- lldb_esi_x86_64,
- lldb_ebp_x86_64,
- lldb_esp_x86_64,
- lldb_r8d_x86_64, // Low 32 bits or r8
- lldb_r9d_x86_64, // Low 32 bits or r9
- lldb_r10d_x86_64, // Low 32 bits or r10
- lldb_r11d_x86_64, // Low 32 bits or r11
- lldb_r12d_x86_64, // Low 32 bits or r12
- lldb_r13d_x86_64, // Low 32 bits or r13
- lldb_r14d_x86_64, // Low 32 bits or r14
- lldb_r15d_x86_64, // Low 32 bits or r15
- lldb_ax_x86_64,
- lldb_bx_x86_64,
- lldb_cx_x86_64,
- lldb_dx_x86_64,
- lldb_di_x86_64,
- lldb_si_x86_64,
- lldb_bp_x86_64,
- lldb_sp_x86_64,
- lldb_r8w_x86_64, // Low 16 bits or r8
- lldb_r9w_x86_64, // Low 16 bits or r9
- lldb_r10w_x86_64, // Low 16 bits or r10
- lldb_r11w_x86_64, // Low 16 bits or r11
- lldb_r12w_x86_64, // Low 16 bits or r12
- lldb_r13w_x86_64, // Low 16 bits or r13
- lldb_r14w_x86_64, // Low 16 bits or r14
- lldb_r15w_x86_64, // Low 16 bits or r15
- lldb_ah_x86_64,
- lldb_bh_x86_64,
- lldb_ch_x86_64,
- lldb_dh_x86_64,
- lldb_al_x86_64,
- lldb_bl_x86_64,
- lldb_cl_x86_64,
- lldb_dl_x86_64,
- lldb_dil_x86_64,
- lldb_sil_x86_64,
- lldb_bpl_x86_64,
- lldb_spl_x86_64,
+static_assert((sizeof(g_avx_regnums_i386) / sizeof(g_avx_regnums_i386[0])) -
+ 1 ==
+ k_num_avx_registers_i386,
+ " g_avx_regnums_i386 has wrong number of register infos");
+
+static const uint32_t g_gpr_regnums_x86_64[] = {
+ lldb_rax_x86_64, lldb_rbx_x86_64, lldb_rcx_x86_64, lldb_rdx_x86_64,
+ lldb_rdi_x86_64, lldb_rsi_x86_64, lldb_rbp_x86_64, lldb_rsp_x86_64,
+ lldb_r8_x86_64, lldb_r9_x86_64, lldb_r10_x86_64, lldb_r11_x86_64,
+ lldb_r12_x86_64, lldb_r13_x86_64, lldb_r14_x86_64, lldb_r15_x86_64,
+ lldb_rip_x86_64, lldb_rflags_x86_64, lldb_cs_x86_64, lldb_fs_x86_64,
+ lldb_gs_x86_64, lldb_ss_x86_64, lldb_ds_x86_64, lldb_es_x86_64,
+ lldb_eax_x86_64, lldb_ebx_x86_64, lldb_ecx_x86_64, lldb_edx_x86_64,
+ lldb_edi_x86_64, lldb_esi_x86_64, lldb_ebp_x86_64, lldb_esp_x86_64,
+ lldb_r8d_x86_64, // Low 32 bits or r8
+ lldb_r9d_x86_64, // Low 32 bits or r9
+ lldb_r10d_x86_64, // Low 32 bits or r10
+ lldb_r11d_x86_64, // Low 32 bits or r11
+ lldb_r12d_x86_64, // Low 32 bits or r12
+ lldb_r13d_x86_64, // Low 32 bits or r13
+ lldb_r14d_x86_64, // Low 32 bits or r14
+ lldb_r15d_x86_64, // Low 32 bits or r15
+ lldb_ax_x86_64, lldb_bx_x86_64, lldb_cx_x86_64, lldb_dx_x86_64,
+ lldb_di_x86_64, lldb_si_x86_64, lldb_bp_x86_64, lldb_sp_x86_64,
+ lldb_r8w_x86_64, // Low 16 bits or r8
+ lldb_r9w_x86_64, // Low 16 bits or r9
+ lldb_r10w_x86_64, // Low 16 bits or r10
+ lldb_r11w_x86_64, // Low 16 bits or r11
+ lldb_r12w_x86_64, // Low 16 bits or r12
+ lldb_r13w_x86_64, // Low 16 bits or r13
+ lldb_r14w_x86_64, // Low 16 bits or r14
+ lldb_r15w_x86_64, // Low 16 bits or r15
+ lldb_ah_x86_64, lldb_bh_x86_64, lldb_ch_x86_64, lldb_dh_x86_64,
+ lldb_al_x86_64, lldb_bl_x86_64, lldb_cl_x86_64, lldb_dl_x86_64,
+ lldb_dil_x86_64, lldb_sil_x86_64, lldb_bpl_x86_64, lldb_spl_x86_64,
lldb_r8l_x86_64, // Low 8 bits or r8
lldb_r9l_x86_64, // Low 8 bits or r9
lldb_r10l_x86_64, // Low 8 bits or r10
@@ -204,464 +111,445 @@ uint32_t g_gpr_regnums_x86_64[] =
lldb_r13l_x86_64, // Low 8 bits or r13
lldb_r14l_x86_64, // Low 8 bits or r14
lldb_r15l_x86_64, // Low 8 bits or r15
- LLDB_INVALID_REGNUM // Register sets must be terminated with LLDB_INVALID_REGNUM.
+ LLDB_INVALID_REGNUM // Register sets must be terminated with
+ // LLDB_INVALID_REGNUM.
};
-static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) - 1 == k_num_gpr_registers_x86_64,
- "g_gpr_regnums_x86_64 has wrong number of register infos");
-
-static const uint32_t
-g_lldb_regnums_x86_64[] =
-{
- lldb_fctrl_x86_64,
- lldb_fstat_x86_64,
- lldb_ftag_x86_64,
- lldb_fop_x86_64,
- lldb_fiseg_x86_64,
- lldb_fioff_x86_64,
- lldb_foseg_x86_64,
- lldb_fooff_x86_64,
- lldb_mxcsr_x86_64,
- lldb_mxcsrmask_x86_64,
- lldb_st0_x86_64,
- lldb_st1_x86_64,
- lldb_st2_x86_64,
- lldb_st3_x86_64,
- lldb_st4_x86_64,
- lldb_st5_x86_64,
- lldb_st6_x86_64,
- lldb_st7_x86_64,
- lldb_mm0_x86_64,
- lldb_mm1_x86_64,
- lldb_mm2_x86_64,
- lldb_mm3_x86_64,
- lldb_mm4_x86_64,
- lldb_mm5_x86_64,
- lldb_mm6_x86_64,
- lldb_mm7_x86_64,
- lldb_xmm0_x86_64,
- lldb_xmm1_x86_64,
- lldb_xmm2_x86_64,
- lldb_xmm3_x86_64,
- lldb_xmm4_x86_64,
- lldb_xmm5_x86_64,
- lldb_xmm6_x86_64,
- lldb_xmm7_x86_64,
- lldb_xmm8_x86_64,
- lldb_xmm9_x86_64,
- lldb_xmm10_x86_64,
- lldb_xmm11_x86_64,
- lldb_xmm12_x86_64,
- lldb_xmm13_x86_64,
- lldb_xmm14_x86_64,
- lldb_xmm15_x86_64,
- LLDB_INVALID_REGNUM // Register sets must be terminated with LLDB_INVALID_REGNUM.
+static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) -
+ 1 ==
+ k_num_gpr_registers_x86_64,
+ "g_gpr_regnums_x86_64 has wrong number of register infos");
+
+static const uint32_t g_lldb_regnums_x86_64[] = {
+ lldb_fctrl_x86_64, lldb_fstat_x86_64, lldb_ftag_x86_64,
+ lldb_fop_x86_64, lldb_fiseg_x86_64, lldb_fioff_x86_64,
+ lldb_foseg_x86_64, lldb_fooff_x86_64, lldb_mxcsr_x86_64,
+ lldb_mxcsrmask_x86_64, lldb_st0_x86_64, lldb_st1_x86_64,
+ lldb_st2_x86_64, lldb_st3_x86_64, lldb_st4_x86_64,
+ lldb_st5_x86_64, lldb_st6_x86_64, lldb_st7_x86_64,
+ lldb_mm0_x86_64, lldb_mm1_x86_64, lldb_mm2_x86_64,
+ lldb_mm3_x86_64, lldb_mm4_x86_64, lldb_mm5_x86_64,
+ lldb_mm6_x86_64, lldb_mm7_x86_64, lldb_xmm0_x86_64,
+ lldb_xmm1_x86_64, lldb_xmm2_x86_64, lldb_xmm3_x86_64,
+ lldb_xmm4_x86_64, lldb_xmm5_x86_64, lldb_xmm6_x86_64,
+ lldb_xmm7_x86_64, lldb_xmm8_x86_64, lldb_xmm9_x86_64,
+ lldb_xmm10_x86_64, lldb_xmm11_x86_64, lldb_xmm12_x86_64,
+ lldb_xmm13_x86_64, lldb_xmm14_x86_64, lldb_xmm15_x86_64,
+ LLDB_INVALID_REGNUM // Register sets must be terminated with
+ // LLDB_INVALID_REGNUM.
};
-static_assert((sizeof(g_lldb_regnums_x86_64) / sizeof(g_lldb_regnums_x86_64[0])) - 1 == k_num_fpr_registers_x86_64,
- "g_lldb_regnums_x86_64 has wrong number of register infos");
-
-static const uint32_t
-g_avx_regnums_x86_64[] =
-{
- lldb_ymm0_x86_64,
- lldb_ymm1_x86_64,
- lldb_ymm2_x86_64,
- lldb_ymm3_x86_64,
- lldb_ymm4_x86_64,
- lldb_ymm5_x86_64,
- lldb_ymm6_x86_64,
- lldb_ymm7_x86_64,
- lldb_ymm8_x86_64,
- lldb_ymm9_x86_64,
- lldb_ymm10_x86_64,
- lldb_ymm11_x86_64,
- lldb_ymm12_x86_64,
- lldb_ymm13_x86_64,
- lldb_ymm14_x86_64,
- lldb_ymm15_x86_64,
- LLDB_INVALID_REGNUM // Register sets must be terminated with LLDB_INVALID_REGNUM.
+static_assert((sizeof(g_lldb_regnums_x86_64) /
+ sizeof(g_lldb_regnums_x86_64[0])) -
+ 1 ==
+ k_num_fpr_registers_x86_64,
+ "g_lldb_regnums_x86_64 has wrong number of register infos");
+
+static const uint32_t g_avx_regnums_x86_64[] = {
+ lldb_ymm0_x86_64, lldb_ymm1_x86_64, lldb_ymm2_x86_64, lldb_ymm3_x86_64,
+ lldb_ymm4_x86_64, lldb_ymm5_x86_64, lldb_ymm6_x86_64, lldb_ymm7_x86_64,
+ lldb_ymm8_x86_64, lldb_ymm9_x86_64, lldb_ymm10_x86_64, lldb_ymm11_x86_64,
+ lldb_ymm12_x86_64, lldb_ymm13_x86_64, lldb_ymm14_x86_64, lldb_ymm15_x86_64,
+ LLDB_INVALID_REGNUM // Register sets must be terminated with
+ // LLDB_INVALID_REGNUM.
};
-static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) - 1 == k_num_avx_registers_x86_64,
- "g_avx_regnums_x86_64 has wrong number of register infos");
-
-uint32_t RegisterContextPOSIX_x86::g_contained_eax[] = { lldb_eax_i386, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_ebx[] = { lldb_ebx_i386, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_ecx[] = { lldb_ecx_i386, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_edx[] = { lldb_edx_i386, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_edi[] = { lldb_edi_i386, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_esi[] = { lldb_esi_i386, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_ebp[] = { lldb_ebp_i386, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_esp[] = { lldb_esp_i386, LLDB_INVALID_REGNUM };
-
-uint32_t RegisterContextPOSIX_x86::g_invalidate_eax[] = { lldb_eax_i386, lldb_ax_i386, lldb_ah_i386, lldb_al_i386, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_ebx[] = { lldb_ebx_i386, lldb_bx_i386, lldb_bh_i386, lldb_bl_i386, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_ecx[] = { lldb_ecx_i386, lldb_cx_i386, lldb_ch_i386, lldb_cl_i386, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_edx[] = { lldb_edx_i386, lldb_dx_i386, lldb_dh_i386, lldb_dl_i386, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_edi[] = { lldb_edi_i386, lldb_di_i386, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_esi[] = { lldb_esi_i386, lldb_si_i386, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_ebp[] = { lldb_ebp_i386, lldb_bp_i386, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_esp[] = { lldb_esp_i386, lldb_sp_i386, LLDB_INVALID_REGNUM };
-
-uint32_t RegisterContextPOSIX_x86::g_contained_rax[] = { lldb_rax_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_rbx[] = { lldb_rbx_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_rcx[] = { lldb_rcx_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_rdx[] = { lldb_rdx_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_rdi[] = { lldb_rdi_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_rsi[] = { lldb_rsi_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_rbp[] = { lldb_rbp_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_rsp[] = { lldb_rsp_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_r8[] = { lldb_r8_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_r9[] = { lldb_r9_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_r10[] = { lldb_r10_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_r11[] = { lldb_r11_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_r12[] = { lldb_r12_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_r13[] = { lldb_r13_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_r14[] = { lldb_r14_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_contained_r15[] = { lldb_r15_x86_64, LLDB_INVALID_REGNUM };
-
-uint32_t RegisterContextPOSIX_x86::g_invalidate_rax[] = { lldb_rax_x86_64, lldb_eax_x86_64, lldb_ax_x86_64, lldb_ah_x86_64, lldb_al_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_rbx[] = { lldb_rbx_x86_64, lldb_ebx_x86_64, lldb_bx_x86_64, lldb_bh_x86_64, lldb_bl_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_rcx[] = { lldb_rcx_x86_64, lldb_ecx_x86_64, lldb_cx_x86_64, lldb_ch_x86_64, lldb_cl_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_rdx[] = { lldb_rdx_x86_64, lldb_edx_x86_64, lldb_dx_x86_64, lldb_dh_x86_64, lldb_dl_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_rdi[] = { lldb_rdi_x86_64, lldb_edi_x86_64, lldb_di_x86_64, lldb_dil_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_rsi[] = { lldb_rsi_x86_64, lldb_esi_x86_64, lldb_si_x86_64, lldb_sil_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_rbp[] = { lldb_rbp_x86_64, lldb_ebp_x86_64, lldb_bp_x86_64, lldb_bpl_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_rsp[] = { lldb_rsp_x86_64, lldb_esp_x86_64, lldb_sp_x86_64, lldb_spl_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_r8[] = { lldb_r8_x86_64, lldb_r8d_x86_64, lldb_r8w_x86_64, lldb_r8l_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_r9[] = { lldb_r9_x86_64, lldb_r9d_x86_64, lldb_r9w_x86_64, lldb_r9l_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_r10[] = { lldb_r10_x86_64, lldb_r10d_x86_64, lldb_r10w_x86_64, lldb_r10l_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_r11[] = { lldb_r11_x86_64, lldb_r11d_x86_64, lldb_r11w_x86_64, lldb_r11l_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_r12[] = { lldb_r12_x86_64, lldb_r12d_x86_64, lldb_r12w_x86_64, lldb_r12l_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_r13[] = { lldb_r13_x86_64, lldb_r13d_x86_64, lldb_r13w_x86_64, lldb_r13l_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_r14[] = { lldb_r14_x86_64, lldb_r14d_x86_64, lldb_r14w_x86_64, lldb_r14l_x86_64, LLDB_INVALID_REGNUM };
-uint32_t RegisterContextPOSIX_x86::g_invalidate_r15[] = { lldb_r15_x86_64, lldb_r15d_x86_64, lldb_r15w_x86_64, lldb_r15l_x86_64, LLDB_INVALID_REGNUM };
+static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) -
+ 1 ==
+ k_num_avx_registers_x86_64,
+ "g_avx_regnums_x86_64 has wrong number of register infos");
+
+uint32_t RegisterContextPOSIX_x86::g_contained_eax[] = {lldb_eax_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_ebx[] = {lldb_ebx_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_ecx[] = {lldb_ecx_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_edx[] = {lldb_edx_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_edi[] = {lldb_edi_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_esi[] = {lldb_esi_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_ebp[] = {lldb_ebp_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_esp[] = {lldb_esp_i386,
+ LLDB_INVALID_REGNUM};
+
+uint32_t RegisterContextPOSIX_x86::g_invalidate_eax[] = {
+ lldb_eax_i386, lldb_ax_i386, lldb_ah_i386, lldb_al_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_ebx[] = {
+ lldb_ebx_i386, lldb_bx_i386, lldb_bh_i386, lldb_bl_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_ecx[] = {
+ lldb_ecx_i386, lldb_cx_i386, lldb_ch_i386, lldb_cl_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_edx[] = {
+ lldb_edx_i386, lldb_dx_i386, lldb_dh_i386, lldb_dl_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_edi[] = {
+ lldb_edi_i386, lldb_di_i386, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_esi[] = {
+ lldb_esi_i386, lldb_si_i386, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_ebp[] = {
+ lldb_ebp_i386, lldb_bp_i386, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_esp[] = {
+ lldb_esp_i386, lldb_sp_i386, LLDB_INVALID_REGNUM};
+
+uint32_t RegisterContextPOSIX_x86::g_contained_rax[] = {lldb_rax_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_rbx[] = {lldb_rbx_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_rcx[] = {lldb_rcx_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_rdx[] = {lldb_rdx_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_rdi[] = {lldb_rdi_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_rsi[] = {lldb_rsi_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_rbp[] = {lldb_rbp_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_rsp[] = {lldb_rsp_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_r8[] = {lldb_r8_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_r9[] = {lldb_r9_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_r10[] = {lldb_r10_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_r11[] = {lldb_r11_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_r12[] = {lldb_r12_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_r13[] = {lldb_r13_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_r14[] = {lldb_r14_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_r15[] = {lldb_r15_x86_64,
+ LLDB_INVALID_REGNUM};
+
+uint32_t RegisterContextPOSIX_x86::g_invalidate_rax[] = {
+ lldb_rax_x86_64, lldb_eax_x86_64, lldb_ax_x86_64,
+ lldb_ah_x86_64, lldb_al_x86_64, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_rbx[] = {
+ lldb_rbx_x86_64, lldb_ebx_x86_64, lldb_bx_x86_64,
+ lldb_bh_x86_64, lldb_bl_x86_64, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_rcx[] = {
+ lldb_rcx_x86_64, lldb_ecx_x86_64, lldb_cx_x86_64,
+ lldb_ch_x86_64, lldb_cl_x86_64, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_rdx[] = {
+ lldb_rdx_x86_64, lldb_edx_x86_64, lldb_dx_x86_64,
+ lldb_dh_x86_64, lldb_dl_x86_64, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_rdi[] = {
+ lldb_rdi_x86_64, lldb_edi_x86_64, lldb_di_x86_64, lldb_dil_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_rsi[] = {
+ lldb_rsi_x86_64, lldb_esi_x86_64, lldb_si_x86_64, lldb_sil_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_rbp[] = {
+ lldb_rbp_x86_64, lldb_ebp_x86_64, lldb_bp_x86_64, lldb_bpl_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_rsp[] = {
+ lldb_rsp_x86_64, lldb_esp_x86_64, lldb_sp_x86_64, lldb_spl_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_r8[] = {
+ lldb_r8_x86_64, lldb_r8d_x86_64, lldb_r8w_x86_64, lldb_r8l_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_r9[] = {
+ lldb_r9_x86_64, lldb_r9d_x86_64, lldb_r9w_x86_64, lldb_r9l_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_r10[] = {
+ lldb_r10_x86_64, lldb_r10d_x86_64, lldb_r10w_x86_64, lldb_r10l_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_r11[] = {
+ lldb_r11_x86_64, lldb_r11d_x86_64, lldb_r11w_x86_64, lldb_r11l_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_r12[] = {
+ lldb_r12_x86_64, lldb_r12d_x86_64, lldb_r12w_x86_64, lldb_r12l_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_r13[] = {
+ lldb_r13_x86_64, lldb_r13d_x86_64, lldb_r13w_x86_64, lldb_r13l_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_r14[] = {
+ lldb_r14_x86_64, lldb_r14d_x86_64, lldb_r14w_x86_64, lldb_r14l_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_r15[] = {
+ lldb_r15_x86_64, lldb_r15d_x86_64, lldb_r15w_x86_64, lldb_r15l_x86_64,
+ LLDB_INVALID_REGNUM};
// Number of register sets provided by this context.
-enum
-{
- k_num_extended_register_sets = 1,
- k_num_register_sets = 3
-};
-
-static const RegisterSet
-g_reg_sets_i386[k_num_register_sets] =
-{
- { "General Purpose Registers", "gpr", k_num_gpr_registers_i386, g_gpr_regnums_i386 },
- { "Floating Point Registers", "fpu", k_num_fpr_registers_i386, g_lldb_regnums_i386 },
- { "Advanced Vector Extensions", "avx", k_num_avx_registers_i386, g_avx_regnums_i386 }
-};
-
-static const RegisterSet
-g_reg_sets_x86_64[k_num_register_sets] =
-{
- { "General Purpose Registers", "gpr", k_num_gpr_registers_x86_64, g_gpr_regnums_x86_64 },
- { "Floating Point Registers", "fpu", k_num_fpr_registers_x86_64, g_lldb_regnums_x86_64 },
- { "Advanced Vector Extensions", "avx", k_num_avx_registers_x86_64, g_avx_regnums_x86_64 }
-};
-
-bool RegisterContextPOSIX_x86::IsGPR(unsigned reg)
-{
- return reg <= m_reg_info.last_gpr; // GPR's come first.
+enum { k_num_extended_register_sets = 1, k_num_register_sets = 3 };
+
+static const RegisterSet g_reg_sets_i386[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_i386,
+ g_gpr_regnums_i386},
+ {"Floating Point Registers", "fpu", k_num_fpr_registers_i386,
+ g_lldb_regnums_i386},
+ {"Advanced Vector Extensions", "avx", k_num_avx_registers_i386,
+ g_avx_regnums_i386}};
+
+static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_x86_64,
+ g_gpr_regnums_x86_64},
+ {"Floating Point Registers", "fpu", k_num_fpr_registers_x86_64,
+ g_lldb_regnums_x86_64},
+ {"Advanced Vector Extensions", "avx", k_num_avx_registers_x86_64,
+ g_avx_regnums_x86_64}};
+
+bool RegisterContextPOSIX_x86::IsGPR(unsigned reg) {
+ return reg <= m_reg_info.last_gpr; // GPR's come first.
}
-bool RegisterContextPOSIX_x86::IsFPR(unsigned reg)
-{
- return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
+bool RegisterContextPOSIX_x86::IsFPR(unsigned reg) {
+ return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
}
-bool RegisterContextPOSIX_x86::IsAVX(unsigned reg)
-{
- return (m_reg_info.first_ymm <= reg && reg <= m_reg_info.last_ymm);
+bool RegisterContextPOSIX_x86::IsAVX(unsigned reg) {
+ return (m_reg_info.first_ymm <= reg && reg <= m_reg_info.last_ymm);
}
-bool RegisterContextPOSIX_x86::IsFPR(unsigned reg, FPRType fpr_type)
-{
- bool generic_fpr = IsFPR(reg);
+bool RegisterContextPOSIX_x86::IsFPR(unsigned reg, FPRType fpr_type) {
+ bool generic_fpr = IsFPR(reg);
- if (fpr_type == eXSAVE)
- return generic_fpr || IsAVX(reg);
- return generic_fpr;
+ if (fpr_type == eXSAVE)
+ return generic_fpr || IsAVX(reg);
+ return generic_fpr;
}
-RegisterContextPOSIX_x86::RegisterContextPOSIX_x86(Thread &thread,
- uint32_t concrete_frame_idx,
- RegisterInfoInterface *register_info)
- : RegisterContext(thread, concrete_frame_idx)
-{
- m_register_info_ap.reset(register_info);
-
- switch (register_info->m_target_arch.GetMachine())
- {
- case llvm::Triple::x86:
- m_reg_info.num_registers = k_num_registers_i386;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_i386;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_i386;
- m_reg_info.num_avx_registers = k_num_avx_registers_i386;
- m_reg_info.last_gpr = k_last_gpr_i386;
- m_reg_info.first_fpr = k_first_fpr_i386;
- m_reg_info.last_fpr = k_last_fpr_i386;
- m_reg_info.first_st = lldb_st0_i386;
- m_reg_info.last_st = lldb_st7_i386;
- m_reg_info.first_mm = lldb_mm0_i386;
- m_reg_info.last_mm = lldb_mm7_i386;
- m_reg_info.first_xmm = lldb_xmm0_i386;
- m_reg_info.last_xmm = lldb_xmm7_i386;
- m_reg_info.first_ymm = lldb_ymm0_i386;
- m_reg_info.last_ymm = lldb_ymm7_i386;
- m_reg_info.first_dr = lldb_dr0_i386;
- m_reg_info.gpr_flags = lldb_eflags_i386;
- break;
- case llvm::Triple::x86_64:
- m_reg_info.num_registers = k_num_registers_x86_64;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_x86_64;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_x86_64;
- m_reg_info.num_avx_registers = k_num_avx_registers_x86_64;
- m_reg_info.last_gpr = k_last_gpr_x86_64;
- m_reg_info.first_fpr = k_first_fpr_x86_64;
- m_reg_info.last_fpr = k_last_fpr_x86_64;
- m_reg_info.first_st = lldb_st0_x86_64;
- m_reg_info.last_st = lldb_st7_x86_64;
- m_reg_info.first_mm = lldb_mm0_x86_64;
- m_reg_info.last_mm = lldb_mm7_x86_64;
- m_reg_info.first_xmm = lldb_xmm0_x86_64;
- m_reg_info.last_xmm = lldb_xmm15_x86_64;
- m_reg_info.first_ymm = lldb_ymm0_x86_64;
- m_reg_info.last_ymm = lldb_ymm15_x86_64;
- m_reg_info.first_dr = lldb_dr0_x86_64;
- m_reg_info.gpr_flags = lldb_rflags_x86_64;
- break;
- default:
- assert(false && "Unhandled target architecture.");
- break;
- }
-
- // Initialize m_iovec to point to the buffer and buffer size
- // using the conventions of Berkeley style UIO structures, as required
- // by PTRACE extensions.
- m_iovec.iov_base = &m_fpr.xstate.xsave;
- m_iovec.iov_len = sizeof(m_fpr.xstate.xsave);
+RegisterContextPOSIX_x86::RegisterContextPOSIX_x86(
+ Thread &thread, uint32_t concrete_frame_idx,
+ RegisterInfoInterface *register_info)
+ : RegisterContext(thread, concrete_frame_idx) {
+ m_register_info_ap.reset(register_info);
+
+ switch (register_info->m_target_arch.GetMachine()) {
+ case llvm::Triple::x86:
+ m_reg_info.num_registers = k_num_registers_i386;
+ m_reg_info.num_gpr_registers = k_num_gpr_registers_i386;
+ m_reg_info.num_fpr_registers = k_num_fpr_registers_i386;
+ m_reg_info.num_avx_registers = k_num_avx_registers_i386;
+ m_reg_info.last_gpr = k_last_gpr_i386;
+ m_reg_info.first_fpr = k_first_fpr_i386;
+ m_reg_info.last_fpr = k_last_fpr_i386;
+ m_reg_info.first_st = lldb_st0_i386;
+ m_reg_info.last_st = lldb_st7_i386;
+ m_reg_info.first_mm = lldb_mm0_i386;
+ m_reg_info.last_mm = lldb_mm7_i386;
+ m_reg_info.first_xmm = lldb_xmm0_i386;
+ m_reg_info.last_xmm = lldb_xmm7_i386;
+ m_reg_info.first_ymm = lldb_ymm0_i386;
+ m_reg_info.last_ymm = lldb_ymm7_i386;
+ m_reg_info.first_dr = lldb_dr0_i386;
+ m_reg_info.gpr_flags = lldb_eflags_i386;
+ break;
+ case llvm::Triple::x86_64:
+ m_reg_info.num_registers = k_num_registers_x86_64;
+ m_reg_info.num_gpr_registers = k_num_gpr_registers_x86_64;
+ m_reg_info.num_fpr_registers = k_num_fpr_registers_x86_64;
+ m_reg_info.num_avx_registers = k_num_avx_registers_x86_64;
+ m_reg_info.last_gpr = k_last_gpr_x86_64;
+ m_reg_info.first_fpr = k_first_fpr_x86_64;
+ m_reg_info.last_fpr = k_last_fpr_x86_64;
+ m_reg_info.first_st = lldb_st0_x86_64;
+ m_reg_info.last_st = lldb_st7_x86_64;
+ m_reg_info.first_mm = lldb_mm0_x86_64;
+ m_reg_info.last_mm = lldb_mm7_x86_64;
+ m_reg_info.first_xmm = lldb_xmm0_x86_64;
+ m_reg_info.last_xmm = lldb_xmm15_x86_64;
+ m_reg_info.first_ymm = lldb_ymm0_x86_64;
+ m_reg_info.last_ymm = lldb_ymm15_x86_64;
+ m_reg_info.first_dr = lldb_dr0_x86_64;
+ m_reg_info.gpr_flags = lldb_rflags_x86_64;
+ break;
+ default:
+ assert(false && "Unhandled target architecture.");
+ break;
+ }
+
+ // Initialize m_iovec to point to the buffer and buffer size
+ // using the conventions of Berkeley style UIO structures, as required
+ // by PTRACE extensions.
+ m_iovec.iov_base = &m_fpr.xstate.xsave;
+ m_iovec.iov_len = sizeof(m_fpr.xstate.xsave);
+
+ ::memset(&m_fpr, 0, sizeof(FPR));
+
+ m_fpr_type = eNotValid;
+}
- ::memset(&m_fpr, 0, sizeof(FPR));
+RegisterContextPOSIX_x86::~RegisterContextPOSIX_x86() {}
- // elf-core yet to support ReadFPR()
- ProcessSP base = CalculateProcess();
- if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic())
- return;
-
- m_fpr_type = eNotValid;
+RegisterContextPOSIX_x86::FPRType RegisterContextPOSIX_x86::GetFPRType() {
+ if (m_fpr_type == eNotValid) {
+ // TODO: Use assembly to call cpuid on the inferior and query ebx or ecx
+ m_fpr_type = eXSAVE; // extended floating-point registers, if available
+ if (false == ReadFPR())
+ m_fpr_type = eFXSAVE; // assume generic floating-point registers
+ }
+ return m_fpr_type;
}
-RegisterContextPOSIX_x86::~RegisterContextPOSIX_x86()
-{
-}
+void RegisterContextPOSIX_x86::Invalidate() {}
-RegisterContextPOSIX_x86::FPRType RegisterContextPOSIX_x86::GetFPRType()
-{
- if (m_fpr_type == eNotValid)
- {
- // TODO: Use assembly to call cpuid on the inferior and query ebx or ecx
- m_fpr_type = eXSAVE; // extended floating-point registers, if available
- if (false == ReadFPR())
- m_fpr_type = eFXSAVE; // assume generic floating-point registers
- }
- return m_fpr_type;
-}
+void RegisterContextPOSIX_x86::InvalidateAllRegisters() {}
-void
-RegisterContextPOSIX_x86::Invalidate()
-{
+unsigned RegisterContextPOSIX_x86::GetRegisterOffset(unsigned reg) {
+ assert(reg < m_reg_info.num_registers && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_offset;
}
-void
-RegisterContextPOSIX_x86::InvalidateAllRegisters()
-{
+unsigned RegisterContextPOSIX_x86::GetRegisterSize(unsigned reg) {
+ assert(reg < m_reg_info.num_registers && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_size;
}
-unsigned
-RegisterContextPOSIX_x86::GetRegisterOffset(unsigned reg)
-{
- assert(reg < m_reg_info.num_registers && "Invalid register number.");
- return GetRegisterInfo()[reg].byte_offset;
+size_t RegisterContextPOSIX_x86::GetRegisterCount() {
+ size_t num_registers =
+ m_reg_info.num_gpr_registers + m_reg_info.num_fpr_registers;
+ if (GetFPRType() == eXSAVE)
+ return num_registers + m_reg_info.num_avx_registers;
+ return num_registers;
}
-unsigned
-RegisterContextPOSIX_x86::GetRegisterSize(unsigned reg)
-{
- assert(reg < m_reg_info.num_registers && "Invalid register number.");
- return GetRegisterInfo()[reg].byte_size;
+size_t RegisterContextPOSIX_x86::GetGPRSize() {
+ return m_register_info_ap->GetGPRSize();
}
-size_t
-RegisterContextPOSIX_x86::GetRegisterCount()
-{
- size_t num_registers = m_reg_info.num_gpr_registers + m_reg_info.num_fpr_registers;
- if (GetFPRType() == eXSAVE)
- return num_registers + m_reg_info.num_avx_registers;
- return num_registers;
+size_t RegisterContextPOSIX_x86::GetFXSAVEOffset() {
+ return GetRegisterInfo()[m_reg_info.first_fpr].byte_offset;
}
-size_t
-RegisterContextPOSIX_x86::GetGPRSize()
-{
- return m_register_info_ap->GetGPRSize ();
+const RegisterInfo *RegisterContextPOSIX_x86::GetRegisterInfo() {
+ // Commonly, this method is overridden and g_register_infos is copied and
+ // specialized.
+ // So, use GetRegisterInfo() rather than g_register_infos in this scope.
+ return m_register_info_ap->GetRegisterInfo();
}
const RegisterInfo *
-RegisterContextPOSIX_x86::GetRegisterInfo()
-{
- // Commonly, this method is overridden and g_register_infos is copied and specialized.
- // So, use GetRegisterInfo() rather than g_register_infos in this scope.
- return m_register_info_ap->GetRegisterInfo ();
-}
-
-const RegisterInfo *
-RegisterContextPOSIX_x86::GetRegisterInfoAtIndex(size_t reg)
-{
- if (reg < m_reg_info.num_registers)
- return &GetRegisterInfo()[reg];
- else
- return NULL;
+RegisterContextPOSIX_x86::GetRegisterInfoAtIndex(size_t reg) {
+ if (reg < m_reg_info.num_registers)
+ return &GetRegisterInfo()[reg];
+ else
+ return NULL;
}
-size_t
-RegisterContextPOSIX_x86::GetRegisterSetCount()
-{
- size_t sets = 0;
- for (size_t set = 0; set < k_num_register_sets; ++set)
- {
- if (IsRegisterSetAvailable(set))
- ++sets;
- }
+size_t RegisterContextPOSIX_x86::GetRegisterSetCount() {
+ size_t sets = 0;
+ for (size_t set = 0; set < k_num_register_sets; ++set) {
+ if (IsRegisterSetAvailable(set))
+ ++sets;
+ }
- return sets;
+ return sets;
}
-const RegisterSet *
-RegisterContextPOSIX_x86::GetRegisterSet(size_t set)
-{
- if (IsRegisterSetAvailable(set))
- {
- switch (m_register_info_ap->m_target_arch.GetMachine())
- {
- case llvm::Triple::x86:
- return &g_reg_sets_i386[set];
- case llvm::Triple::x86_64:
- return &g_reg_sets_x86_64[set];
- default:
- assert(false && "Unhandled target architecture.");
- return NULL;
- }
+const RegisterSet *RegisterContextPOSIX_x86::GetRegisterSet(size_t set) {
+ if (IsRegisterSetAvailable(set)) {
+ switch (m_register_info_ap->m_target_arch.GetMachine()) {
+ case llvm::Triple::x86:
+ return &g_reg_sets_i386[set];
+ case llvm::Triple::x86_64:
+ return &g_reg_sets_x86_64[set];
+ default:
+ assert(false && "Unhandled target architecture.");
+ return NULL;
}
- return NULL;
+ }
+ return NULL;
}
-const char *
-RegisterContextPOSIX_x86::GetRegisterName(unsigned reg)
-{
- assert(reg < m_reg_info.num_registers && "Invalid register offset.");
- return GetRegisterInfo()[reg].name;
+const char *RegisterContextPOSIX_x86::GetRegisterName(unsigned reg) {
+ assert(reg < m_reg_info.num_registers && "Invalid register offset.");
+ return GetRegisterInfo()[reg].name;
}
-lldb::ByteOrder
-RegisterContextPOSIX_x86::GetByteOrder()
-{
- // Get the target process whose privileged thread was used for the register read.
- lldb::ByteOrder byte_order = eByteOrderInvalid;
- Process *process = CalculateProcess().get();
+lldb::ByteOrder RegisterContextPOSIX_x86::GetByteOrder() {
+ // Get the target process whose privileged thread was used for the register
+ // read.
+ lldb::ByteOrder byte_order = eByteOrderInvalid;
+ Process *process = CalculateProcess().get();
- if (process)
- byte_order = process->GetByteOrder();
- return byte_order;
+ if (process)
+ byte_order = process->GetByteOrder();
+ return byte_order;
}
// Parse ymm registers and into xmm.bytes and ymmh.bytes.
-bool RegisterContextPOSIX_x86::CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder byte_order)
-{
- if (!IsAVX(reg))
- return false;
-
- if (byte_order == eByteOrderLittle)
- {
- ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
- m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
- sizeof(XMMReg));
- ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
- m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
- sizeof(YMMHReg));
- return true;
- }
-
- if (byte_order == eByteOrderBig)
- {
- ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
- m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
- sizeof(XMMReg));
- ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
- m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
- sizeof(YMMHReg));
- return true;
- }
- return false; // unsupported or invalid byte order
+bool RegisterContextPOSIX_x86::CopyYMMtoXSTATE(uint32_t reg,
+ lldb::ByteOrder byte_order) {
+ if (!IsAVX(reg))
+ return false;
+
+ if (byte_order == eByteOrderLittle) {
+ ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
+ m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(XMMReg));
+ ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
+ m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
+ sizeof(YMMHReg));
+ return true;
+ }
+
+ if (byte_order == eByteOrderBig) {
+ ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
+ m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
+ sizeof(XMMReg));
+ ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
+ m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(YMMHReg));
+ return true;
+ }
+ return false; // unsupported or invalid byte order
}
// Concatenate xmm.bytes with ymmh.bytes
-bool RegisterContextPOSIX_x86::CopyXSTATEtoYMM(uint32_t reg, lldb::ByteOrder byte_order)
-{
- if (!IsAVX(reg))
- return false;
-
- if (byte_order == eByteOrderLittle)
- {
- ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
- m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
- sizeof(XMMReg));
- ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
- m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
- sizeof(YMMHReg));
- return true;
- }
-
- if (byte_order == eByteOrderBig)
- {
- ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
- m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
- sizeof(XMMReg));
- ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
- m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
- sizeof(YMMHReg));
- return true;
- }
- return false; // unsupported or invalid byte order
+bool RegisterContextPOSIX_x86::CopyXSTATEtoYMM(uint32_t reg,
+ lldb::ByteOrder byte_order) {
+ if (!IsAVX(reg))
+ return false;
+
+ if (byte_order == eByteOrderLittle) {
+ ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
+ m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
+ sizeof(XMMReg));
+ ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
+ m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
+ sizeof(YMMHReg));
+ return true;
+ }
+
+ if (byte_order == eByteOrderBig) {
+ ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
+ m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
+ sizeof(XMMReg));
+ ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
+ m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
+ sizeof(YMMHReg));
+ return true;
+ }
+ return false; // unsupported or invalid byte order
}
-bool
-RegisterContextPOSIX_x86::IsRegisterSetAvailable(size_t set_index)
-{
- // Note: Extended register sets are assumed to be at the end of g_reg_sets...
- size_t num_sets = k_num_register_sets - k_num_extended_register_sets;
+bool RegisterContextPOSIX_x86::IsRegisterSetAvailable(size_t set_index) {
+ // Note: Extended register sets are assumed to be at the end of g_reg_sets...
+ size_t num_sets = k_num_register_sets - k_num_extended_register_sets;
- if (GetFPRType() == eXSAVE) // ...and to start with AVX registers.
- ++num_sets;
- return (set_index < num_sets);
+ if (GetFPRType() == eXSAVE) // ...and to start with AVX registers.
+ ++num_sets;
+ return (set_index < num_sets);
}
-
// Used when parsing DWARF and EH frame information and any other
-// object file sections that contain register numbers in them.
-uint32_t
-RegisterContextPOSIX_x86::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
- uint32_t num)
-{
- const uint32_t num_regs = GetRegisterCount();
-
- assert (kind < kNumRegisterKinds);
- for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
- {
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg_idx);
-
- if (reg_info->kinds[kind] == num)
- return reg_idx;
- }
+// object file sections that contain register numbers in them.
+uint32_t RegisterContextPOSIX_x86::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t num) {
+ const uint32_t num_regs = GetRegisterCount();
- return LLDB_INVALID_REGNUM;
-}
+ assert(kind < kNumRegisterKinds);
+ for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx);
+ if (reg_info->kinds[kind] == num)
+ return reg_idx;
+ }
+
+ return LLDB_INVALID_REGNUM;
+}
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h b/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h
index b4708255a566..c5afe089e476 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h
@@ -14,181 +14,170 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/Log.h"
-#include "lldb/Target/RegisterContext.h"
-#include "RegisterInfoInterface.h"
#include "RegisterContext_x86.h"
+#include "RegisterInfoInterface.h"
#include "lldb-x86-register-enums.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Target/RegisterContext.h"
class ProcessMonitor;
-class RegisterContextPOSIX_x86
- : public lldb_private::RegisterContext
-{
+class RegisterContextPOSIX_x86 : public lldb_private::RegisterContext {
public:
- RegisterContextPOSIX_x86 (lldb_private::Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info);
-
- ~RegisterContextPOSIX_x86() override;
-
- void
- Invalidate();
-
- void
- InvalidateAllRegisters() override;
-
- size_t
- GetRegisterCount() override;
-
- virtual size_t
- GetGPRSize();
-
- virtual unsigned
- GetRegisterSize(unsigned reg);
-
- virtual unsigned
- GetRegisterOffset(unsigned reg);
-
- const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex(size_t reg) override;
-
- size_t
- GetRegisterSetCount() override;
-
- const lldb_private::RegisterSet *
- GetRegisterSet(size_t set) override;
-
- const char *
- GetRegisterName(unsigned reg);
-
- uint32_t
- ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
-
- //---------------------------------------------------------------------------
- // Note: prefer kernel definitions over user-land
- //---------------------------------------------------------------------------
- enum FPRType
- {
- eNotValid = 0,
- eFSAVE, // TODO
- eFXSAVE,
- eSOFT, // TODO
- eXSAVE
- };
-
- static uint32_t g_contained_eax[];
- static uint32_t g_contained_ebx[];
- static uint32_t g_contained_ecx[];
- static uint32_t g_contained_edx[];
- static uint32_t g_contained_edi[];
- static uint32_t g_contained_esi[];
- static uint32_t g_contained_ebp[];
- static uint32_t g_contained_esp[];
-
- static uint32_t g_invalidate_eax[];
- static uint32_t g_invalidate_ebx[];
- static uint32_t g_invalidate_ecx[];
- static uint32_t g_invalidate_edx[];
- static uint32_t g_invalidate_edi[];
- static uint32_t g_invalidate_esi[];
- static uint32_t g_invalidate_ebp[];
- static uint32_t g_invalidate_esp[];
-
- static uint32_t g_contained_rax[];
- static uint32_t g_contained_rbx[];
- static uint32_t g_contained_rcx[];
- static uint32_t g_contained_rdx[];
- static uint32_t g_contained_rdi[];
- static uint32_t g_contained_rsi[];
- static uint32_t g_contained_rbp[];
- static uint32_t g_contained_rsp[];
- static uint32_t g_contained_r8[];
- static uint32_t g_contained_r9[];
- static uint32_t g_contained_r10[];
- static uint32_t g_contained_r11[];
- static uint32_t g_contained_r12[];
- static uint32_t g_contained_r13[];
- static uint32_t g_contained_r14[];
- static uint32_t g_contained_r15[];
-
- static uint32_t g_invalidate_rax[];
- static uint32_t g_invalidate_rbx[];
- static uint32_t g_invalidate_rcx[];
- static uint32_t g_invalidate_rdx[];
- static uint32_t g_invalidate_rdi[];
- static uint32_t g_invalidate_rsi[];
- static uint32_t g_invalidate_rbp[];
- static uint32_t g_invalidate_rsp[];
- static uint32_t g_invalidate_r8[];
- static uint32_t g_invalidate_r9[];
- static uint32_t g_invalidate_r10[];
- static uint32_t g_invalidate_r11[];
- static uint32_t g_invalidate_r12[];
- static uint32_t g_invalidate_r13[];
- static uint32_t g_invalidate_r14[];
- static uint32_t g_invalidate_r15[];
+ RegisterContextPOSIX_x86(lldb_private::Thread &thread,
+ uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info);
+
+ ~RegisterContextPOSIX_x86() override;
+
+ void Invalidate();
+
+ void InvalidateAllRegisters() override;
+
+ size_t GetRegisterCount() override;
+
+ virtual size_t GetGPRSize();
+
+ virtual size_t GetFXSAVEOffset();
+
+ virtual unsigned GetRegisterSize(unsigned reg);
+
+ virtual unsigned GetRegisterOffset(unsigned reg);
+
+ const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
+
+ size_t GetRegisterSetCount() override;
+
+ const lldb_private::RegisterSet *GetRegisterSet(size_t set) override;
+
+ const char *GetRegisterName(unsigned reg);
+
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
+
+ //---------------------------------------------------------------------------
+ // Note: prefer kernel definitions over user-land
+ //---------------------------------------------------------------------------
+ enum FPRType {
+ eNotValid = 0,
+ eFSAVE, // TODO
+ eFXSAVE,
+ eSOFT, // TODO
+ eXSAVE
+ };
+
+ static uint32_t g_contained_eax[];
+ static uint32_t g_contained_ebx[];
+ static uint32_t g_contained_ecx[];
+ static uint32_t g_contained_edx[];
+ static uint32_t g_contained_edi[];
+ static uint32_t g_contained_esi[];
+ static uint32_t g_contained_ebp[];
+ static uint32_t g_contained_esp[];
+
+ static uint32_t g_invalidate_eax[];
+ static uint32_t g_invalidate_ebx[];
+ static uint32_t g_invalidate_ecx[];
+ static uint32_t g_invalidate_edx[];
+ static uint32_t g_invalidate_edi[];
+ static uint32_t g_invalidate_esi[];
+ static uint32_t g_invalidate_ebp[];
+ static uint32_t g_invalidate_esp[];
+
+ static uint32_t g_contained_rax[];
+ static uint32_t g_contained_rbx[];
+ static uint32_t g_contained_rcx[];
+ static uint32_t g_contained_rdx[];
+ static uint32_t g_contained_rdi[];
+ static uint32_t g_contained_rsi[];
+ static uint32_t g_contained_rbp[];
+ static uint32_t g_contained_rsp[];
+ static uint32_t g_contained_r8[];
+ static uint32_t g_contained_r9[];
+ static uint32_t g_contained_r10[];
+ static uint32_t g_contained_r11[];
+ static uint32_t g_contained_r12[];
+ static uint32_t g_contained_r13[];
+ static uint32_t g_contained_r14[];
+ static uint32_t g_contained_r15[];
+
+ static uint32_t g_invalidate_rax[];
+ static uint32_t g_invalidate_rbx[];
+ static uint32_t g_invalidate_rcx[];
+ static uint32_t g_invalidate_rdx[];
+ static uint32_t g_invalidate_rdi[];
+ static uint32_t g_invalidate_rsi[];
+ static uint32_t g_invalidate_rbp[];
+ static uint32_t g_invalidate_rsp[];
+ static uint32_t g_invalidate_r8[];
+ static uint32_t g_invalidate_r9[];
+ static uint32_t g_invalidate_r10[];
+ static uint32_t g_invalidate_r11[];
+ static uint32_t g_invalidate_r12[];
+ static uint32_t g_invalidate_r13[];
+ static uint32_t g_invalidate_r14[];
+ static uint32_t g_invalidate_r15[];
protected:
- struct RegInfo
- {
- uint32_t num_registers;
- uint32_t num_gpr_registers;
- uint32_t num_fpr_registers;
- uint32_t num_avx_registers;
-
- uint32_t last_gpr;
- uint32_t first_fpr;
- uint32_t last_fpr;
-
- uint32_t first_st;
- uint32_t last_st;
- uint32_t first_mm;
- uint32_t last_mm;
- uint32_t first_xmm;
- uint32_t last_xmm;
- uint32_t first_ymm;
- uint32_t last_ymm;
-
- uint32_t first_dr;
- uint32_t gpr_flags;
- };
-
- uint64_t m_gpr_x86_64[lldb_private::k_num_gpr_registers_x86_64]; // 64-bit general purpose registers.
- RegInfo m_reg_info;
- FPRType m_fpr_type; // determines the type of data stored by union FPR, if any.
- FPR m_fpr; // floating-point registers including extended register sets.
- IOVEC m_iovec; // wrapper for xsave.
- YMM m_ymm_set; // copy of ymmh and xmm register halves.
- std::unique_ptr<lldb_private::RegisterInfoInterface> m_register_info_ap; // Register Info Interface (FreeBSD or Linux)
-
- // Determines if an extended register set is supported on the processor running the inferior process.
- virtual bool
- IsRegisterSetAvailable(size_t set_index);
-
- virtual const lldb_private::RegisterInfo *
- GetRegisterInfo();
-
- bool
- IsGPR(unsigned reg);
-
- bool
- IsFPR(unsigned reg);
-
- bool
- IsAVX(unsigned reg);
-
- lldb::ByteOrder GetByteOrder();
-
- bool CopyXSTATEtoYMM(uint32_t reg, lldb::ByteOrder byte_order);
- bool CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder byte_order);
- bool IsFPR(unsigned reg, FPRType fpr_type);
- FPRType GetFPRType();
-
- virtual bool ReadGPR() = 0;
- virtual bool ReadFPR() = 0;
- virtual bool WriteGPR() = 0;
- virtual bool WriteFPR() = 0;
+ struct RegInfo {
+ uint32_t num_registers;
+ uint32_t num_gpr_registers;
+ uint32_t num_fpr_registers;
+ uint32_t num_avx_registers;
+
+ uint32_t last_gpr;
+ uint32_t first_fpr;
+ uint32_t last_fpr;
+
+ uint32_t first_st;
+ uint32_t last_st;
+ uint32_t first_mm;
+ uint32_t last_mm;
+ uint32_t first_xmm;
+ uint32_t last_xmm;
+ uint32_t first_ymm;
+ uint32_t last_ymm;
+
+ uint32_t first_dr;
+ uint32_t gpr_flags;
+ };
+
+ uint64_t m_gpr_x86_64[lldb_private::k_num_gpr_registers_x86_64]; // 64-bit
+ // general
+ // purpose
+ // registers.
+ RegInfo m_reg_info;
+ FPRType
+ m_fpr_type; // determines the type of data stored by union FPR, if any.
+ FPR m_fpr; // floating-point registers including extended register sets.
+ IOVEC m_iovec; // wrapper for xsave.
+ YMM m_ymm_set; // copy of ymmh and xmm register halves.
+ std::unique_ptr<lldb_private::RegisterInfoInterface>
+ m_register_info_ap; // Register Info Interface (FreeBSD or Linux)
+
+ // Determines if an extended register set is supported on the processor
+ // running the inferior process.
+ virtual bool IsRegisterSetAvailable(size_t set_index);
+
+ virtual const lldb_private::RegisterInfo *GetRegisterInfo();
+
+ bool IsGPR(unsigned reg);
+
+ bool IsFPR(unsigned reg);
+
+ bool IsAVX(unsigned reg);
+
+ lldb::ByteOrder GetByteOrder();
+
+ bool CopyXSTATEtoYMM(uint32_t reg, lldb::ByteOrder byte_order);
+ bool CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder byte_order);
+ bool IsFPR(unsigned reg, FPRType fpr_type);
+ FPRType GetFPRType();
+
+ virtual bool ReadGPR() = 0;
+ virtual bool ReadFPR() = 0;
+ virtual bool WriteGPR() = 0;
+ virtual bool WriteFPR() = 0;
};
#endif // liblldb_RegisterContextPOSIX_x86_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp b/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp
index 200ef4d3d651..2b5cb00fa96a 100644
--- a/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp
@@ -7,255 +7,213 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-private.h"
#include "lldb/Core/Error.h"
#include "lldb/Target/OperatingSystem.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"
+#include "lldb/lldb-private.h"
#include "RegisterContextThreadMemory.h"
using namespace lldb;
using namespace lldb_private;
-RegisterContextThreadMemory::RegisterContextThreadMemory (Thread &thread,
- lldb::addr_t register_data_addr) :
- RegisterContext (thread, 0),
- m_thread_wp (thread.shared_from_this()),
- m_reg_ctx_sp (),
- m_register_data_addr (register_data_addr),
- m_stop_id(0)
-{
-}
+RegisterContextThreadMemory::RegisterContextThreadMemory(
+ Thread &thread, lldb::addr_t register_data_addr)
+ : RegisterContext(thread, 0), m_thread_wp(thread.shared_from_this()),
+ m_reg_ctx_sp(), m_register_data_addr(register_data_addr), m_stop_id(0) {}
-RegisterContextThreadMemory::~RegisterContextThreadMemory()
-{
-}
+RegisterContextThreadMemory::~RegisterContextThreadMemory() {}
-void
-RegisterContextThreadMemory::UpdateRegisterContext ()
-{
- ThreadSP thread_sp (m_thread_wp.lock());
- if (thread_sp)
- {
- ProcessSP process_sp (thread_sp->GetProcess());
+void RegisterContextThreadMemory::UpdateRegisterContext() {
+ ThreadSP thread_sp(m_thread_wp.lock());
+ if (thread_sp) {
+ ProcessSP process_sp(thread_sp->GetProcess());
- if (process_sp)
- {
- const uint32_t stop_id = process_sp->GetModID().GetStopID();
- if (m_stop_id != stop_id)
- {
- m_stop_id = stop_id;
- m_reg_ctx_sp.reset();
- }
- if (!m_reg_ctx_sp)
- {
- ThreadSP backing_thread_sp (thread_sp->GetBackingThread());
- if (backing_thread_sp)
- {
- m_reg_ctx_sp = backing_thread_sp->GetRegisterContext();
- }
- else
- {
- OperatingSystem *os = process_sp->GetOperatingSystem ();
- if (os->IsOperatingSystemPluginThread (thread_sp))
- m_reg_ctx_sp = os->CreateRegisterContextForThread (thread_sp.get(), m_register_data_addr);
- }
- }
- }
- else
- {
- m_reg_ctx_sp.reset();
- }
- }
- else
- {
+ if (process_sp) {
+ const uint32_t stop_id = process_sp->GetModID().GetStopID();
+ if (m_stop_id != stop_id) {
+ m_stop_id = stop_id;
m_reg_ctx_sp.reset();
+ }
+ if (!m_reg_ctx_sp) {
+ ThreadSP backing_thread_sp(thread_sp->GetBackingThread());
+ if (backing_thread_sp) {
+ m_reg_ctx_sp = backing_thread_sp->GetRegisterContext();
+ } else {
+ OperatingSystem *os = process_sp->GetOperatingSystem();
+ if (os->IsOperatingSystemPluginThread(thread_sp))
+ m_reg_ctx_sp = os->CreateRegisterContextForThread(
+ thread_sp.get(), m_register_data_addr);
+ }
+ }
+ } else {
+ m_reg_ctx_sp.reset();
}
+ } else {
+ m_reg_ctx_sp.reset();
+ }
}
//------------------------------------------------------------------
// Subclasses must override these functions
//------------------------------------------------------------------
-void
-RegisterContextThreadMemory::InvalidateAllRegisters ()
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- m_reg_ctx_sp->InvalidateAllRegisters();
+void RegisterContextThreadMemory::InvalidateAllRegisters() {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ m_reg_ctx_sp->InvalidateAllRegisters();
}
-size_t
-RegisterContextThreadMemory::GetRegisterCount ()
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->GetRegisterCount();
- return 0;
+size_t RegisterContextThreadMemory::GetRegisterCount() {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->GetRegisterCount();
+ return 0;
}
const RegisterInfo *
-RegisterContextThreadMemory::GetRegisterInfoAtIndex (size_t reg)
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->GetRegisterInfoAtIndex(reg);
- return NULL;
-}
-
-size_t
-RegisterContextThreadMemory::GetRegisterSetCount ()
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->GetRegisterSetCount();
- return 0;
-}
-
-const RegisterSet *
-RegisterContextThreadMemory::GetRegisterSet (size_t reg_set)
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->GetRegisterSet(reg_set);
- return NULL;
-}
-
-bool
-RegisterContextThreadMemory::ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value)
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->ReadRegister(reg_info, reg_value);
- return false;
-}
-
-bool
-RegisterContextThreadMemory::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value)
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->WriteRegister (reg_info, reg_value);
- return false;
-}
-
-bool
-RegisterContextThreadMemory::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->ReadAllRegisterValues(data_sp);
- return false;
-}
-
-bool
-RegisterContextThreadMemory::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->WriteAllRegisterValues (data_sp);
- return false;
-}
-
-bool
-RegisterContextThreadMemory::CopyFromRegisterContext (lldb::RegisterContextSP reg_ctx_sp)
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->CopyFromRegisterContext(reg_ctx_sp);
- return false;
-}
-
-uint32_t
-RegisterContextThreadMemory::ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t num)
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->ConvertRegisterKindToRegisterNumber(kind, num);
- return false;
-}
-
-uint32_t
-RegisterContextThreadMemory::NumSupportedHardwareBreakpoints ()
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->NumSupportedHardwareBreakpoints();
- return false;
-}
-
-uint32_t
-RegisterContextThreadMemory::SetHardwareBreakpoint (lldb::addr_t addr, size_t size)
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->SetHardwareBreakpoint(addr, size);
- return 0;
-}
-
-bool
-RegisterContextThreadMemory::ClearHardwareBreakpoint (uint32_t hw_idx)
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->ClearHardwareBreakpoint (hw_idx);
- return false;
-}
-
-uint32_t
-RegisterContextThreadMemory::NumSupportedHardwareWatchpoints ()
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->NumSupportedHardwareWatchpoints();
- return 0;
+RegisterContextThreadMemory::GetRegisterInfoAtIndex(size_t reg) {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->GetRegisterInfoAtIndex(reg);
+ return NULL;
}
-uint32_t
-RegisterContextThreadMemory::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write)
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->SetHardwareWatchpoint(addr, size, read, write);
- return 0;
+size_t RegisterContextThreadMemory::GetRegisterSetCount() {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->GetRegisterSetCount();
+ return 0;
}
-bool
-RegisterContextThreadMemory::ClearHardwareWatchpoint (uint32_t hw_index)
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->ClearHardwareWatchpoint(hw_index);
- return false;
+const RegisterSet *RegisterContextThreadMemory::GetRegisterSet(size_t reg_set) {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->GetRegisterSet(reg_set);
+ return NULL;
}
-bool
-RegisterContextThreadMemory::HardwareSingleStep (bool enable)
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->HardwareSingleStep(enable);
- return false;
+bool RegisterContextThreadMemory::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->ReadRegister(reg_info, reg_value);
+ return false;
}
-Error
-RegisterContextThreadMemory::ReadRegisterValueFromMemory (const lldb_private::RegisterInfo *reg_info, lldb::addr_t src_addr, uint32_t src_len, RegisterValue &reg_value)
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->ReadRegisterValueFromMemory (reg_info, src_addr, src_len, reg_value);
- Error error;
- error.SetErrorString("invalid register context");
- return error;
+bool RegisterContextThreadMemory::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &reg_value) {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->WriteRegister(reg_info, reg_value);
+ return false;
}
-Error
-RegisterContextThreadMemory::WriteRegisterValueToMemory (const lldb_private::RegisterInfo *reg_info, lldb::addr_t dst_addr, uint32_t dst_len, const RegisterValue &reg_value)
-{
- UpdateRegisterContext ();
- if (m_reg_ctx_sp)
- return m_reg_ctx_sp->WriteRegisterValueToMemory (reg_info, dst_addr, dst_len, reg_value);
- Error error;
- error.SetErrorString("invalid register context");
- return error;
+bool RegisterContextThreadMemory::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->ReadAllRegisterValues(data_sp);
+ return false;
+}
+
+bool RegisterContextThreadMemory::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->WriteAllRegisterValues(data_sp);
+ return false;
+}
+
+bool RegisterContextThreadMemory::CopyFromRegisterContext(
+ lldb::RegisterContextSP reg_ctx_sp) {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->CopyFromRegisterContext(reg_ctx_sp);
+ return false;
+}
+
+uint32_t RegisterContextThreadMemory::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t num) {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->ConvertRegisterKindToRegisterNumber(kind, num);
+ return false;
+}
+
+uint32_t RegisterContextThreadMemory::NumSupportedHardwareBreakpoints() {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->NumSupportedHardwareBreakpoints();
+ return false;
+}
+
+uint32_t RegisterContextThreadMemory::SetHardwareBreakpoint(lldb::addr_t addr,
+ size_t size) {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->SetHardwareBreakpoint(addr, size);
+ return 0;
+}
+
+bool RegisterContextThreadMemory::ClearHardwareBreakpoint(uint32_t hw_idx) {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->ClearHardwareBreakpoint(hw_idx);
+ return false;
+}
+
+uint32_t RegisterContextThreadMemory::NumSupportedHardwareWatchpoints() {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->NumSupportedHardwareWatchpoints();
+ return 0;
+}
+
+uint32_t RegisterContextThreadMemory::SetHardwareWatchpoint(lldb::addr_t addr,
+ size_t size,
+ bool read,
+ bool write) {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->SetHardwareWatchpoint(addr, size, read, write);
+ return 0;
+}
+
+bool RegisterContextThreadMemory::ClearHardwareWatchpoint(uint32_t hw_index) {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->ClearHardwareWatchpoint(hw_index);
+ return false;
+}
+
+bool RegisterContextThreadMemory::HardwareSingleStep(bool enable) {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->HardwareSingleStep(enable);
+ return false;
+}
+
+Error RegisterContextThreadMemory::ReadRegisterValueFromMemory(
+ const lldb_private::RegisterInfo *reg_info, lldb::addr_t src_addr,
+ uint32_t src_len, RegisterValue &reg_value) {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->ReadRegisterValueFromMemory(reg_info, src_addr,
+ src_len, reg_value);
+ Error error;
+ error.SetErrorString("invalid register context");
+ return error;
+}
+
+Error RegisterContextThreadMemory::WriteRegisterValueToMemory(
+ const lldb_private::RegisterInfo *reg_info, lldb::addr_t dst_addr,
+ uint32_t dst_len, const RegisterValue &reg_value) {
+ UpdateRegisterContext();
+ if (m_reg_ctx_sp)
+ return m_reg_ctx_sp->WriteRegisterValueToMemory(reg_info, dst_addr, dst_len,
+ reg_value);
+ Error error;
+ error.SetErrorString("invalid register context");
+ return error;
}
diff --git a/source/Plugins/Process/Utility/RegisterContextThreadMemory.h b/source/Plugins/Process/Utility/RegisterContextThreadMemory.h
index b4680de79514..7e0a2a9f7f1e 100644
--- a/source/Plugins/Process/Utility/RegisterContextThreadMemory.h
+++ b/source/Plugins/Process/Utility/RegisterContextThreadMemory.h
@@ -16,103 +16,88 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
-#include "lldb/Target/RegisterContext.h"
#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/lldb-private.h"
namespace lldb_private {
-
-class RegisterContextThreadMemory : public lldb_private::RegisterContext
-{
+
+class RegisterContextThreadMemory : public lldb_private::RegisterContext {
public:
- RegisterContextThreadMemory (Thread &thread,
- lldb::addr_t register_data_addr);
-
- ~RegisterContextThreadMemory() override;
-
- void
- InvalidateAllRegisters() override;
-
- size_t
- GetRegisterCount() override;
-
- const RegisterInfo *
- GetRegisterInfoAtIndex(size_t reg) override;
-
- size_t
- GetRegisterSetCount() override;
-
- const RegisterSet *
- GetRegisterSet(size_t reg_set) override;
-
- bool
- ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value) override;
-
- bool
- WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value) override;
-
- // These two functions are used to implement "push" and "pop" of register states. They are used primarily
- // for expression evaluation, where we need to push a new state (storing the old one in data_sp) and then
- // restoring the original state by passing the data_sp we got from ReadAllRegisters to WriteAllRegisterValues.
- // ReadAllRegisters will do what is necessary to return a coherent set of register values for this thread, which
- // may mean e.g. interrupting a thread that is sitting in a kernel trap. That is a somewhat disruptive operation,
- // so these API's should only be used when this behavior is needed.
-
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
-
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
-
- bool
- CopyFromRegisterContext (lldb::RegisterContextSP context);
-
- uint32_t
- ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
-
- uint32_t
- NumSupportedHardwareBreakpoints() override;
-
- uint32_t
- SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override;
-
- bool
- ClearHardwareBreakpoint(uint32_t hw_idx) override;
-
- uint32_t
- NumSupportedHardwareWatchpoints() override;
-
- uint32_t
- SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write) override;
-
- bool
- ClearHardwareWatchpoint(uint32_t hw_index) override;
-
- bool
- HardwareSingleStep(bool enable) override;
-
- Error
- ReadRegisterValueFromMemory(const lldb_private::RegisterInfo *reg_info,
- lldb::addr_t src_addr,
- uint32_t src_len,
- RegisterValue &reg_value) override;
-
- Error
- WriteRegisterValueToMemory(const lldb_private::RegisterInfo *reg_info,
- lldb::addr_t dst_addr, uint32_t dst_len,
- const RegisterValue &reg_value) override;
+ RegisterContextThreadMemory(Thread &thread, lldb::addr_t register_data_addr);
+
+ ~RegisterContextThreadMemory() override;
+
+ void InvalidateAllRegisters() override;
+
+ size_t GetRegisterCount() override;
+
+ const RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
+
+ size_t GetRegisterSetCount() override;
+
+ const RegisterSet *GetRegisterSet(size_t reg_set) override;
+
+ bool ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) override;
+
+ bool WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) override;
+
+ // These two functions are used to implement "push" and "pop" of register
+ // states. They are used primarily
+ // for expression evaluation, where we need to push a new state (storing the
+ // old one in data_sp) and then
+ // restoring the original state by passing the data_sp we got from
+ // ReadAllRegisters to WriteAllRegisterValues.
+ // ReadAllRegisters will do what is necessary to return a coherent set of
+ // register values for this thread, which
+ // may mean e.g. interrupting a thread that is sitting in a kernel trap. That
+ // is a somewhat disruptive operation,
+ // so these API's should only be used when this behavior is needed.
+
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+
+ bool CopyFromRegisterContext(lldb::RegisterContextSP context);
+
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
+
+ uint32_t NumSupportedHardwareBreakpoints() override;
+
+ uint32_t SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override;
+
+ bool ClearHardwareBreakpoint(uint32_t hw_idx) override;
+
+ uint32_t NumSupportedHardwareWatchpoints() override;
+
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read,
+ bool write) override;
+
+ bool ClearHardwareWatchpoint(uint32_t hw_index) override;
+
+ bool HardwareSingleStep(bool enable) override;
+
+ Error ReadRegisterValueFromMemory(const lldb_private::RegisterInfo *reg_info,
+ lldb::addr_t src_addr, uint32_t src_len,
+ RegisterValue &reg_value) override;
+
+ Error WriteRegisterValueToMemory(const lldb_private::RegisterInfo *reg_info,
+ lldb::addr_t dst_addr, uint32_t dst_len,
+ const RegisterValue &reg_value) override;
protected:
- void
- UpdateRegisterContext ();
-
- lldb::ThreadWP m_thread_wp;
- lldb::RegisterContextSP m_reg_ctx_sp;
- lldb::addr_t m_register_data_addr;
- uint32_t m_stop_id;
+ void UpdateRegisterContext();
+
+ lldb::ThreadWP m_thread_wp;
+ lldb::RegisterContextSP m_reg_ctx_sp;
+ lldb::addr_t m_register_data_addr;
+ uint32_t m_stop_id;
private:
- DISALLOW_COPY_AND_ASSIGN (RegisterContextThreadMemory);
+ DISALLOW_COPY_AND_ASSIGN(RegisterContextThreadMemory);
};
} // namespace lldb_private
diff --git a/source/Plugins/Process/Utility/RegisterContext_mips.h b/source/Plugins/Process/Utility/RegisterContext_mips.h
index 3603227d5e73..565747cb4bd7 100644
--- a/source/Plugins/Process/Utility/RegisterContext_mips.h
+++ b/source/Plugins/Process/Utility/RegisterContext_mips.h
@@ -10,375 +10,371 @@
#ifndef liblldb_RegisterContext_mips64_H_
#define liblldb_RegisterContext_mips64_H_
-// eh_frame and DWARF Register numbers (eRegisterKindEHFrame & eRegisterKindDWARF)
+#include <cstddef>
+#include <cstdint>
-enum
-{
- // GP Registers
- dwarf_zero_mips = 0,
- dwarf_r1_mips,
- dwarf_r2_mips,
- dwarf_r3_mips,
- dwarf_r4_mips,
- dwarf_r5_mips,
- dwarf_r6_mips,
- dwarf_r7_mips,
- dwarf_r8_mips,
- dwarf_r9_mips,
- dwarf_r10_mips,
- dwarf_r11_mips,
- dwarf_r12_mips,
- dwarf_r13_mips,
- dwarf_r14_mips,
- dwarf_r15_mips,
- dwarf_r16_mips,
- dwarf_r17_mips,
- dwarf_r18_mips,
- dwarf_r19_mips,
- dwarf_r20_mips,
- dwarf_r21_mips,
- dwarf_r22_mips,
- dwarf_r23_mips,
- dwarf_r24_mips,
- dwarf_r25_mips,
- dwarf_r26_mips,
- dwarf_r27_mips,
- dwarf_gp_mips,
- dwarf_sp_mips,
- dwarf_r30_mips,
- dwarf_ra_mips,
- dwarf_sr_mips,
- dwarf_lo_mips,
- dwarf_hi_mips,
- dwarf_bad_mips,
- dwarf_cause_mips,
- dwarf_pc_mips,
- dwarf_f0_mips,
- dwarf_f1_mips,
- dwarf_f2_mips,
- dwarf_f3_mips,
- dwarf_f4_mips,
- dwarf_f5_mips,
- dwarf_f6_mips,
- dwarf_f7_mips,
- dwarf_f8_mips,
- dwarf_f9_mips,
- dwarf_f10_mips,
- dwarf_f11_mips,
- dwarf_f12_mips,
- dwarf_f13_mips,
- dwarf_f14_mips,
- dwarf_f15_mips,
- dwarf_f16_mips,
- dwarf_f17_mips,
- dwarf_f18_mips,
- dwarf_f19_mips,
- dwarf_f20_mips,
- dwarf_f21_mips,
- dwarf_f22_mips,
- dwarf_f23_mips,
- dwarf_f24_mips,
- dwarf_f25_mips,
- dwarf_f26_mips,
- dwarf_f27_mips,
- dwarf_f28_mips,
- dwarf_f29_mips,
- dwarf_f30_mips,
- dwarf_f31_mips,
- dwarf_fcsr_mips,
- dwarf_fir_mips,
- dwarf_w0_mips,
- dwarf_w1_mips,
- dwarf_w2_mips,
- dwarf_w3_mips,
- dwarf_w4_mips,
- dwarf_w5_mips,
- dwarf_w6_mips,
- dwarf_w7_mips,
- dwarf_w8_mips,
- dwarf_w9_mips,
- dwarf_w10_mips,
- dwarf_w11_mips,
- dwarf_w12_mips,
- dwarf_w13_mips,
- dwarf_w14_mips,
- dwarf_w15_mips,
- dwarf_w16_mips,
- dwarf_w17_mips,
- dwarf_w18_mips,
- dwarf_w19_mips,
- dwarf_w20_mips,
- dwarf_w21_mips,
- dwarf_w22_mips,
- dwarf_w23_mips,
- dwarf_w24_mips,
- dwarf_w25_mips,
- dwarf_w26_mips,
- dwarf_w27_mips,
- dwarf_w28_mips,
- dwarf_w29_mips,
- dwarf_w30_mips,
- dwarf_w31_mips,
- dwarf_mcsr_mips,
- dwarf_mir_mips,
- dwarf_config5_mips,
- dwarf_ic_mips,
- dwarf_dummy_mips
+// eh_frame and DWARF Register numbers (eRegisterKindEHFrame &
+// eRegisterKindDWARF)
+
+enum {
+ // GP Registers
+ dwarf_zero_mips = 0,
+ dwarf_r1_mips,
+ dwarf_r2_mips,
+ dwarf_r3_mips,
+ dwarf_r4_mips,
+ dwarf_r5_mips,
+ dwarf_r6_mips,
+ dwarf_r7_mips,
+ dwarf_r8_mips,
+ dwarf_r9_mips,
+ dwarf_r10_mips,
+ dwarf_r11_mips,
+ dwarf_r12_mips,
+ dwarf_r13_mips,
+ dwarf_r14_mips,
+ dwarf_r15_mips,
+ dwarf_r16_mips,
+ dwarf_r17_mips,
+ dwarf_r18_mips,
+ dwarf_r19_mips,
+ dwarf_r20_mips,
+ dwarf_r21_mips,
+ dwarf_r22_mips,
+ dwarf_r23_mips,
+ dwarf_r24_mips,
+ dwarf_r25_mips,
+ dwarf_r26_mips,
+ dwarf_r27_mips,
+ dwarf_gp_mips,
+ dwarf_sp_mips,
+ dwarf_r30_mips,
+ dwarf_ra_mips,
+ dwarf_sr_mips,
+ dwarf_lo_mips,
+ dwarf_hi_mips,
+ dwarf_bad_mips,
+ dwarf_cause_mips,
+ dwarf_pc_mips,
+ dwarf_f0_mips,
+ dwarf_f1_mips,
+ dwarf_f2_mips,
+ dwarf_f3_mips,
+ dwarf_f4_mips,
+ dwarf_f5_mips,
+ dwarf_f6_mips,
+ dwarf_f7_mips,
+ dwarf_f8_mips,
+ dwarf_f9_mips,
+ dwarf_f10_mips,
+ dwarf_f11_mips,
+ dwarf_f12_mips,
+ dwarf_f13_mips,
+ dwarf_f14_mips,
+ dwarf_f15_mips,
+ dwarf_f16_mips,
+ dwarf_f17_mips,
+ dwarf_f18_mips,
+ dwarf_f19_mips,
+ dwarf_f20_mips,
+ dwarf_f21_mips,
+ dwarf_f22_mips,
+ dwarf_f23_mips,
+ dwarf_f24_mips,
+ dwarf_f25_mips,
+ dwarf_f26_mips,
+ dwarf_f27_mips,
+ dwarf_f28_mips,
+ dwarf_f29_mips,
+ dwarf_f30_mips,
+ dwarf_f31_mips,
+ dwarf_fcsr_mips,
+ dwarf_fir_mips,
+ dwarf_w0_mips,
+ dwarf_w1_mips,
+ dwarf_w2_mips,
+ dwarf_w3_mips,
+ dwarf_w4_mips,
+ dwarf_w5_mips,
+ dwarf_w6_mips,
+ dwarf_w7_mips,
+ dwarf_w8_mips,
+ dwarf_w9_mips,
+ dwarf_w10_mips,
+ dwarf_w11_mips,
+ dwarf_w12_mips,
+ dwarf_w13_mips,
+ dwarf_w14_mips,
+ dwarf_w15_mips,
+ dwarf_w16_mips,
+ dwarf_w17_mips,
+ dwarf_w18_mips,
+ dwarf_w19_mips,
+ dwarf_w20_mips,
+ dwarf_w21_mips,
+ dwarf_w22_mips,
+ dwarf_w23_mips,
+ dwarf_w24_mips,
+ dwarf_w25_mips,
+ dwarf_w26_mips,
+ dwarf_w27_mips,
+ dwarf_w28_mips,
+ dwarf_w29_mips,
+ dwarf_w30_mips,
+ dwarf_w31_mips,
+ dwarf_mcsr_mips,
+ dwarf_mir_mips,
+ dwarf_config5_mips,
+ dwarf_ic_mips,
+ dwarf_dummy_mips
};
-enum
-{
- dwarf_zero_mips64 = 0,
- dwarf_r1_mips64,
- dwarf_r2_mips64,
- dwarf_r3_mips64,
- dwarf_r4_mips64,
- dwarf_r5_mips64,
- dwarf_r6_mips64,
- dwarf_r7_mips64,
- dwarf_r8_mips64,
- dwarf_r9_mips64,
- dwarf_r10_mips64,
- dwarf_r11_mips64,
- dwarf_r12_mips64,
- dwarf_r13_mips64,
- dwarf_r14_mips64,
- dwarf_r15_mips64,
- dwarf_r16_mips64,
- dwarf_r17_mips64,
- dwarf_r18_mips64,
- dwarf_r19_mips64,
- dwarf_r20_mips64,
- dwarf_r21_mips64,
- dwarf_r22_mips64,
- dwarf_r23_mips64,
- dwarf_r24_mips64,
- dwarf_r25_mips64,
- dwarf_r26_mips64,
- dwarf_r27_mips64,
- dwarf_gp_mips64,
- dwarf_sp_mips64,
- dwarf_r30_mips64,
- dwarf_ra_mips64,
- dwarf_sr_mips64,
- dwarf_lo_mips64,
- dwarf_hi_mips64,
- dwarf_bad_mips64,
- dwarf_cause_mips64,
- dwarf_pc_mips64,
- dwarf_f0_mips64,
- dwarf_f1_mips64,
- dwarf_f2_mips64,
- dwarf_f3_mips64,
- dwarf_f4_mips64,
- dwarf_f5_mips64,
- dwarf_f6_mips64,
- dwarf_f7_mips64,
- dwarf_f8_mips64,
- dwarf_f9_mips64,
- dwarf_f10_mips64,
- dwarf_f11_mips64,
- dwarf_f12_mips64,
- dwarf_f13_mips64,
- dwarf_f14_mips64,
- dwarf_f15_mips64,
- dwarf_f16_mips64,
- dwarf_f17_mips64,
- dwarf_f18_mips64,
- dwarf_f19_mips64,
- dwarf_f20_mips64,
- dwarf_f21_mips64,
- dwarf_f22_mips64,
- dwarf_f23_mips64,
- dwarf_f24_mips64,
- dwarf_f25_mips64,
- dwarf_f26_mips64,
- dwarf_f27_mips64,
- dwarf_f28_mips64,
- dwarf_f29_mips64,
- dwarf_f30_mips64,
- dwarf_f31_mips64,
- dwarf_fcsr_mips64,
- dwarf_fir_mips64,
- dwarf_ic_mips64,
- dwarf_dummy_mips64,
- dwarf_w0_mips64,
- dwarf_w1_mips64,
- dwarf_w2_mips64,
- dwarf_w3_mips64,
- dwarf_w4_mips64,
- dwarf_w5_mips64,
- dwarf_w6_mips64,
- dwarf_w7_mips64,
- dwarf_w8_mips64,
- dwarf_w9_mips64,
- dwarf_w10_mips64,
- dwarf_w11_mips64,
- dwarf_w12_mips64,
- dwarf_w13_mips64,
- dwarf_w14_mips64,
- dwarf_w15_mips64,
- dwarf_w16_mips64,
- dwarf_w17_mips64,
- dwarf_w18_mips64,
- dwarf_w19_mips64,
- dwarf_w20_mips64,
- dwarf_w21_mips64,
- dwarf_w22_mips64,
- dwarf_w23_mips64,
- dwarf_w24_mips64,
- dwarf_w25_mips64,
- dwarf_w26_mips64,
- dwarf_w27_mips64,
- dwarf_w28_mips64,
- dwarf_w29_mips64,
- dwarf_w30_mips64,
- dwarf_w31_mips64,
- dwarf_mcsr_mips64,
- dwarf_mir_mips64,
- dwarf_config5_mips64,
+enum {
+ dwarf_zero_mips64 = 0,
+ dwarf_r1_mips64,
+ dwarf_r2_mips64,
+ dwarf_r3_mips64,
+ dwarf_r4_mips64,
+ dwarf_r5_mips64,
+ dwarf_r6_mips64,
+ dwarf_r7_mips64,
+ dwarf_r8_mips64,
+ dwarf_r9_mips64,
+ dwarf_r10_mips64,
+ dwarf_r11_mips64,
+ dwarf_r12_mips64,
+ dwarf_r13_mips64,
+ dwarf_r14_mips64,
+ dwarf_r15_mips64,
+ dwarf_r16_mips64,
+ dwarf_r17_mips64,
+ dwarf_r18_mips64,
+ dwarf_r19_mips64,
+ dwarf_r20_mips64,
+ dwarf_r21_mips64,
+ dwarf_r22_mips64,
+ dwarf_r23_mips64,
+ dwarf_r24_mips64,
+ dwarf_r25_mips64,
+ dwarf_r26_mips64,
+ dwarf_r27_mips64,
+ dwarf_gp_mips64,
+ dwarf_sp_mips64,
+ dwarf_r30_mips64,
+ dwarf_ra_mips64,
+ dwarf_sr_mips64,
+ dwarf_lo_mips64,
+ dwarf_hi_mips64,
+ dwarf_bad_mips64,
+ dwarf_cause_mips64,
+ dwarf_pc_mips64,
+ dwarf_f0_mips64,
+ dwarf_f1_mips64,
+ dwarf_f2_mips64,
+ dwarf_f3_mips64,
+ dwarf_f4_mips64,
+ dwarf_f5_mips64,
+ dwarf_f6_mips64,
+ dwarf_f7_mips64,
+ dwarf_f8_mips64,
+ dwarf_f9_mips64,
+ dwarf_f10_mips64,
+ dwarf_f11_mips64,
+ dwarf_f12_mips64,
+ dwarf_f13_mips64,
+ dwarf_f14_mips64,
+ dwarf_f15_mips64,
+ dwarf_f16_mips64,
+ dwarf_f17_mips64,
+ dwarf_f18_mips64,
+ dwarf_f19_mips64,
+ dwarf_f20_mips64,
+ dwarf_f21_mips64,
+ dwarf_f22_mips64,
+ dwarf_f23_mips64,
+ dwarf_f24_mips64,
+ dwarf_f25_mips64,
+ dwarf_f26_mips64,
+ dwarf_f27_mips64,
+ dwarf_f28_mips64,
+ dwarf_f29_mips64,
+ dwarf_f30_mips64,
+ dwarf_f31_mips64,
+ dwarf_fcsr_mips64,
+ dwarf_fir_mips64,
+ dwarf_ic_mips64,
+ dwarf_dummy_mips64,
+ dwarf_w0_mips64,
+ dwarf_w1_mips64,
+ dwarf_w2_mips64,
+ dwarf_w3_mips64,
+ dwarf_w4_mips64,
+ dwarf_w5_mips64,
+ dwarf_w6_mips64,
+ dwarf_w7_mips64,
+ dwarf_w8_mips64,
+ dwarf_w9_mips64,
+ dwarf_w10_mips64,
+ dwarf_w11_mips64,
+ dwarf_w12_mips64,
+ dwarf_w13_mips64,
+ dwarf_w14_mips64,
+ dwarf_w15_mips64,
+ dwarf_w16_mips64,
+ dwarf_w17_mips64,
+ dwarf_w18_mips64,
+ dwarf_w19_mips64,
+ dwarf_w20_mips64,
+ dwarf_w21_mips64,
+ dwarf_w22_mips64,
+ dwarf_w23_mips64,
+ dwarf_w24_mips64,
+ dwarf_w25_mips64,
+ dwarf_w26_mips64,
+ dwarf_w27_mips64,
+ dwarf_w28_mips64,
+ dwarf_w29_mips64,
+ dwarf_w30_mips64,
+ dwarf_w31_mips64,
+ dwarf_mcsr_mips64,
+ dwarf_mir_mips64,
+ dwarf_config5_mips64,
};
-struct IOVEC_mips
-{
- void *iov_base;
- size_t iov_len;
+struct IOVEC_mips {
+ void *iov_base;
+ size_t iov_len;
};
// GP registers
-struct GPR_linux_mips
-{
- uint64_t zero;
- uint64_t r1;
- uint64_t r2;
- uint64_t r3;
- uint64_t r4;
- uint64_t r5;
- uint64_t r6;
- uint64_t r7;
- uint64_t r8;
- uint64_t r9;
- uint64_t r10;
- uint64_t r11;
- uint64_t r12;
- uint64_t r13;
- uint64_t r14;
- uint64_t r15;
- uint64_t r16;
- uint64_t r17;
- uint64_t r18;
- uint64_t r19;
- uint64_t r20;
- uint64_t r21;
- uint64_t r22;
- uint64_t r23;
- uint64_t r24;
- uint64_t r25;
- uint64_t r26;
- uint64_t r27;
- uint64_t gp;
- uint64_t sp;
- uint64_t r30;
- uint64_t ra;
- uint64_t mullo;
- uint64_t mulhi;
- uint64_t pc;
- uint64_t badvaddr;
- uint64_t sr;
- uint64_t cause;
- uint64_t config5;
+struct GPR_linux_mips {
+ uint64_t zero;
+ uint64_t r1;
+ uint64_t r2;
+ uint64_t r3;
+ uint64_t r4;
+ uint64_t r5;
+ uint64_t r6;
+ uint64_t r7;
+ uint64_t r8;
+ uint64_t r9;
+ uint64_t r10;
+ uint64_t r11;
+ uint64_t r12;
+ uint64_t r13;
+ uint64_t r14;
+ uint64_t r15;
+ uint64_t r16;
+ uint64_t r17;
+ uint64_t r18;
+ uint64_t r19;
+ uint64_t r20;
+ uint64_t r21;
+ uint64_t r22;
+ uint64_t r23;
+ uint64_t r24;
+ uint64_t r25;
+ uint64_t r26;
+ uint64_t r27;
+ uint64_t gp;
+ uint64_t sp;
+ uint64_t r30;
+ uint64_t ra;
+ uint64_t mullo;
+ uint64_t mulhi;
+ uint64_t pc;
+ uint64_t badvaddr;
+ uint64_t sr;
+ uint64_t cause;
+ uint64_t config5;
};
-struct FPR_linux_mips
-{
- uint64_t f0;
- uint64_t f1;
- uint64_t f2;
- uint64_t f3;
- uint64_t f4;
- uint64_t f5;
- uint64_t f6;
- uint64_t f7;
- uint64_t f8;
- uint64_t f9;
- uint64_t f10;
- uint64_t f11;
- uint64_t f12;
- uint64_t f13;
- uint64_t f14;
- uint64_t f15;
- uint64_t f16;
- uint64_t f17;
- uint64_t f18;
- uint64_t f19;
- uint64_t f20;
- uint64_t f21;
- uint64_t f22;
- uint64_t f23;
- uint64_t f24;
- uint64_t f25;
- uint64_t f26;
- uint64_t f27;
- uint64_t f28;
- uint64_t f29;
- uint64_t f30;
- uint64_t f31;
- uint32_t fcsr;
- uint32_t fir;
- uint32_t config5;
+struct FPR_linux_mips {
+ uint64_t f0;
+ uint64_t f1;
+ uint64_t f2;
+ uint64_t f3;
+ uint64_t f4;
+ uint64_t f5;
+ uint64_t f6;
+ uint64_t f7;
+ uint64_t f8;
+ uint64_t f9;
+ uint64_t f10;
+ uint64_t f11;
+ uint64_t f12;
+ uint64_t f13;
+ uint64_t f14;
+ uint64_t f15;
+ uint64_t f16;
+ uint64_t f17;
+ uint64_t f18;
+ uint64_t f19;
+ uint64_t f20;
+ uint64_t f21;
+ uint64_t f22;
+ uint64_t f23;
+ uint64_t f24;
+ uint64_t f25;
+ uint64_t f26;
+ uint64_t f27;
+ uint64_t f28;
+ uint64_t f29;
+ uint64_t f30;
+ uint64_t f31;
+ uint32_t fcsr;
+ uint32_t fir;
+ uint32_t config5;
};
-struct MSAReg
-{
- uint8_t byte[16];
+struct MSAReg {
+ uint8_t byte[16];
};
-struct MSA_linux_mips
-{
- MSAReg w0;
- MSAReg w1;
- MSAReg w2;
- MSAReg w3;
- MSAReg w4;
- MSAReg w5;
- MSAReg w6;
- MSAReg w7;
- MSAReg w8;
- MSAReg w9;
- MSAReg w10;
- MSAReg w11;
- MSAReg w12;
- MSAReg w13;
- MSAReg w14;
- MSAReg w15;
- MSAReg w16;
- MSAReg w17;
- MSAReg w18;
- MSAReg w19;
- MSAReg w20;
- MSAReg w21;
- MSAReg w22;
- MSAReg w23;
- MSAReg w24;
- MSAReg w25;
- MSAReg w26;
- MSAReg w27;
- MSAReg w28;
- MSAReg w29;
- MSAReg w30;
- MSAReg w31;
- uint32_t fcsr; /* FPU control status register */
- uint32_t fir; /* FPU implementaion revision */
- uint32_t mcsr; /* MSA control status register */
- uint32_t mir; /* MSA implementation revision */
- uint32_t config5; /* Config5 register */
+struct MSA_linux_mips {
+ MSAReg w0;
+ MSAReg w1;
+ MSAReg w2;
+ MSAReg w3;
+ MSAReg w4;
+ MSAReg w5;
+ MSAReg w6;
+ MSAReg w7;
+ MSAReg w8;
+ MSAReg w9;
+ MSAReg w10;
+ MSAReg w11;
+ MSAReg w12;
+ MSAReg w13;
+ MSAReg w14;
+ MSAReg w15;
+ MSAReg w16;
+ MSAReg w17;
+ MSAReg w18;
+ MSAReg w19;
+ MSAReg w20;
+ MSAReg w21;
+ MSAReg w22;
+ MSAReg w23;
+ MSAReg w24;
+ MSAReg w25;
+ MSAReg w26;
+ MSAReg w27;
+ MSAReg w28;
+ MSAReg w29;
+ MSAReg w30;
+ MSAReg w31;
+ uint32_t fcsr; /* FPU control status register */
+ uint32_t fir; /* FPU implementaion revision */
+ uint32_t mcsr; /* MSA control status register */
+ uint32_t mir; /* MSA implementation revision */
+ uint32_t config5; /* Config5 register */
};
-struct UserArea
-{
- GPR_linux_mips gpr; // General purpose registers.
- FPR_linux_mips fpr; // Floating point registers.
- MSA_linux_mips msa; // MSA registers.
+struct UserArea {
+ GPR_linux_mips gpr; // General purpose registers.
+ FPR_linux_mips fpr; // Floating point registers.
+ MSA_linux_mips msa; // MSA registers.
};
#endif // liblldb_RegisterContext_mips64_H_
diff --git a/source/Plugins/Process/Utility/RegisterContext_powerpc.h b/source/Plugins/Process/Utility/RegisterContext_powerpc.h
index 2e3053cf37bc..73242952c6d0 100644
--- a/source/Plugins/Process/Utility/RegisterContext_powerpc.h
+++ b/source/Plugins/Process/Utility/RegisterContext_powerpc.h
@@ -1,4 +1,5 @@
-//===-- RegisterContext_powerpc.h --------------------------------*- C++ -*-===//
+//===-- RegisterContext_powerpc.h --------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,114 +11,114 @@
#ifndef liblldb_RegisterContext_powerpc_H_
#define liblldb_RegisterContext_powerpc_H_
-// eh_frame and DWARF Register numbers (eRegisterKindEHFrame & eRegisterKindDWARF)
-enum
-{
- dwarf_r0_powerpc = 0,
- dwarf_r1_powerpc,
- dwarf_r2_powerpc,
- dwarf_r3_powerpc,
- dwarf_r4_powerpc,
- dwarf_r5_powerpc,
- dwarf_r6_powerpc,
- dwarf_r7_powerpc,
- dwarf_r8_powerpc,
- dwarf_r9_powerpc,
- dwarf_r10_powerpc,
- dwarf_r11_powerpc,
- dwarf_r12_powerpc,
- dwarf_r13_powerpc,
- dwarf_r14_powerpc,
- dwarf_r15_powerpc,
- dwarf_r16_powerpc,
- dwarf_r17_powerpc,
- dwarf_r18_powerpc,
- dwarf_r19_powerpc,
- dwarf_r20_powerpc,
- dwarf_r21_powerpc,
- dwarf_r22_powerpc,
- dwarf_r23_powerpc,
- dwarf_r24_powerpc,
- dwarf_r25_powerpc,
- dwarf_r26_powerpc,
- dwarf_r27_powerpc,
- dwarf_r28_powerpc,
- dwarf_r29_powerpc,
- dwarf_r30_powerpc,
- dwarf_r31_powerpc,
- dwarf_f0_powerpc,
- dwarf_f1_powerpc,
- dwarf_f2_powerpc,
- dwarf_f3_powerpc,
- dwarf_f4_powerpc,
- dwarf_f5_powerpc,
- dwarf_f6_powerpc,
- dwarf_f7_powerpc,
- dwarf_f8_powerpc,
- dwarf_f9_powerpc,
- dwarf_f10_powerpc,
- dwarf_f11_powerpc,
- dwarf_f12_powerpc,
- dwarf_f13_powerpc,
- dwarf_f14_powerpc,
- dwarf_f15_powerpc,
- dwarf_f16_powerpc,
- dwarf_f17_powerpc,
- dwarf_f18_powerpc,
- dwarf_f19_powerpc,
- dwarf_f20_powerpc,
- dwarf_f21_powerpc,
- dwarf_f22_powerpc,
- dwarf_f23_powerpc,
- dwarf_f24_powerpc,
- dwarf_f25_powerpc,
- dwarf_f26_powerpc,
- dwarf_f27_powerpc,
- dwarf_f28_powerpc,
- dwarf_f29_powerpc,
- dwarf_f30_powerpc,
- dwarf_f31_powerpc,
- dwarf_cr_powerpc,
- dwarf_fpscr_powerpc,
- dwarf_msr_powerpc,
- dwarf_vscr_powerpc,
- dwarf_xer_powerpc = 101,
- dwarf_lr_powerpc = 108,
- dwarf_ctr_powerpc,
- dwarf_pc_powerpc,
- dwarf_vrsave_powerpc = 356,
- dwarf_v0_powerpc = 1124,
- dwarf_v1_powerpc,
- dwarf_v2_powerpc,
- dwarf_v3_powerpc,
- dwarf_v4_powerpc,
- dwarf_v5_powerpc,
- dwarf_v6_powerpc,
- dwarf_v7_powerpc,
- dwarf_v8_powerpc,
- dwarf_v9_powerpc,
- dwarf_v10_powerpc,
- dwarf_v11_powerpc,
- dwarf_v12_powerpc,
- dwarf_v13_powerpc,
- dwarf_v14_powerpc,
- dwarf_v15_powerpc,
- dwarf_v16_powerpc,
- dwarf_v17_powerpc,
- dwarf_v18_powerpc,
- dwarf_v19_powerpc,
- dwarf_v20_powerpc,
- dwarf_v21_powerpc,
- dwarf_v22_powerpc,
- dwarf_v23_powerpc,
- dwarf_v24_powerpc,
- dwarf_v25_powerpc,
- dwarf_v26_powerpc,
- dwarf_v27_powerpc,
- dwarf_v28_powerpc,
- dwarf_v29_powerpc,
- dwarf_v30_powerpc,
- dwarf_v31_powerpc,
+// eh_frame and DWARF Register numbers (eRegisterKindEHFrame &
+// eRegisterKindDWARF)
+enum {
+ dwarf_r0_powerpc = 0,
+ dwarf_r1_powerpc,
+ dwarf_r2_powerpc,
+ dwarf_r3_powerpc,
+ dwarf_r4_powerpc,
+ dwarf_r5_powerpc,
+ dwarf_r6_powerpc,
+ dwarf_r7_powerpc,
+ dwarf_r8_powerpc,
+ dwarf_r9_powerpc,
+ dwarf_r10_powerpc,
+ dwarf_r11_powerpc,
+ dwarf_r12_powerpc,
+ dwarf_r13_powerpc,
+ dwarf_r14_powerpc,
+ dwarf_r15_powerpc,
+ dwarf_r16_powerpc,
+ dwarf_r17_powerpc,
+ dwarf_r18_powerpc,
+ dwarf_r19_powerpc,
+ dwarf_r20_powerpc,
+ dwarf_r21_powerpc,
+ dwarf_r22_powerpc,
+ dwarf_r23_powerpc,
+ dwarf_r24_powerpc,
+ dwarf_r25_powerpc,
+ dwarf_r26_powerpc,
+ dwarf_r27_powerpc,
+ dwarf_r28_powerpc,
+ dwarf_r29_powerpc,
+ dwarf_r30_powerpc,
+ dwarf_r31_powerpc,
+ dwarf_f0_powerpc,
+ dwarf_f1_powerpc,
+ dwarf_f2_powerpc,
+ dwarf_f3_powerpc,
+ dwarf_f4_powerpc,
+ dwarf_f5_powerpc,
+ dwarf_f6_powerpc,
+ dwarf_f7_powerpc,
+ dwarf_f8_powerpc,
+ dwarf_f9_powerpc,
+ dwarf_f10_powerpc,
+ dwarf_f11_powerpc,
+ dwarf_f12_powerpc,
+ dwarf_f13_powerpc,
+ dwarf_f14_powerpc,
+ dwarf_f15_powerpc,
+ dwarf_f16_powerpc,
+ dwarf_f17_powerpc,
+ dwarf_f18_powerpc,
+ dwarf_f19_powerpc,
+ dwarf_f20_powerpc,
+ dwarf_f21_powerpc,
+ dwarf_f22_powerpc,
+ dwarf_f23_powerpc,
+ dwarf_f24_powerpc,
+ dwarf_f25_powerpc,
+ dwarf_f26_powerpc,
+ dwarf_f27_powerpc,
+ dwarf_f28_powerpc,
+ dwarf_f29_powerpc,
+ dwarf_f30_powerpc,
+ dwarf_f31_powerpc,
+ dwarf_cr_powerpc,
+ dwarf_fpscr_powerpc,
+ dwarf_msr_powerpc,
+ dwarf_vscr_powerpc,
+ dwarf_xer_powerpc = 101,
+ dwarf_lr_powerpc = 108,
+ dwarf_ctr_powerpc,
+ dwarf_pc_powerpc,
+ dwarf_vrsave_powerpc = 356,
+ dwarf_v0_powerpc = 1124,
+ dwarf_v1_powerpc,
+ dwarf_v2_powerpc,
+ dwarf_v3_powerpc,
+ dwarf_v4_powerpc,
+ dwarf_v5_powerpc,
+ dwarf_v6_powerpc,
+ dwarf_v7_powerpc,
+ dwarf_v8_powerpc,
+ dwarf_v9_powerpc,
+ dwarf_v10_powerpc,
+ dwarf_v11_powerpc,
+ dwarf_v12_powerpc,
+ dwarf_v13_powerpc,
+ dwarf_v14_powerpc,
+ dwarf_v15_powerpc,
+ dwarf_v16_powerpc,
+ dwarf_v17_powerpc,
+ dwarf_v18_powerpc,
+ dwarf_v19_powerpc,
+ dwarf_v20_powerpc,
+ dwarf_v21_powerpc,
+ dwarf_v22_powerpc,
+ dwarf_v23_powerpc,
+ dwarf_v24_powerpc,
+ dwarf_v25_powerpc,
+ dwarf_v26_powerpc,
+ dwarf_v27_powerpc,
+ dwarf_v28_powerpc,
+ dwarf_v29_powerpc,
+ dwarf_v30_powerpc,
+ dwarf_v31_powerpc,
};
#endif // liblldb_RegisterContext_powerpc_H_
diff --git a/source/Plugins/Process/Utility/RegisterContext_s390x.h b/source/Plugins/Process/Utility/RegisterContext_s390x.h
index 9777c7744409..90803dc16785 100644
--- a/source/Plugins/Process/Utility/RegisterContext_s390x.h
+++ b/source/Plugins/Process/Utility/RegisterContext_s390x.h
@@ -14,80 +14,80 @@
// SystemZ ehframe, dwarf regnums
//---------------------------------------------------------------------------
-// EHFrame and DWARF Register numbers (eRegisterKindEHFrame & eRegisterKindDWARF)
-enum
-{
- // General Purpose Registers
- dwarf_r0_s390x = 0,
- dwarf_r1_s390x,
- dwarf_r2_s390x,
- dwarf_r3_s390x,
- dwarf_r4_s390x,
- dwarf_r5_s390x,
- dwarf_r6_s390x,
- dwarf_r7_s390x,
- dwarf_r8_s390x,
- dwarf_r9_s390x,
- dwarf_r10_s390x,
- dwarf_r11_s390x,
- dwarf_r12_s390x,
- dwarf_r13_s390x,
- dwarf_r14_s390x,
- dwarf_r15_s390x,
- // Floating Point Registers / Vector Registers 0-15
- dwarf_f0_s390x = 16,
- dwarf_f2_s390x,
- dwarf_f4_s390x,
- dwarf_f6_s390x,
- dwarf_f1_s390x,
- dwarf_f3_s390x,
- dwarf_f5_s390x,
- dwarf_f7_s390x,
- dwarf_f8_s390x,
- dwarf_f10_s390x,
- dwarf_f12_s390x,
- dwarf_f14_s390x,
- dwarf_f9_s390x,
- dwarf_f11_s390x,
- dwarf_f13_s390x,
- dwarf_f15_s390x,
- // Access Registers
- dwarf_acr0_s390x = 48,
- dwarf_acr1_s390x,
- dwarf_acr2_s390x,
- dwarf_acr3_s390x,
- dwarf_acr4_s390x,
- dwarf_acr5_s390x,
- dwarf_acr6_s390x,
- dwarf_acr7_s390x,
- dwarf_acr8_s390x,
- dwarf_acr9_s390x,
- dwarf_acr10_s390x,
- dwarf_acr11_s390x,
- dwarf_acr12_s390x,
- dwarf_acr13_s390x,
- dwarf_acr14_s390x,
- dwarf_acr15_s390x,
- // Program Status Word
- dwarf_pswm_s390x = 64,
- dwarf_pswa_s390x,
- // Vector Registers 16-31
- dwarf_v16_s390x = 68,
- dwarf_v18_s390x,
- dwarf_v20_s390x,
- dwarf_v22_s390x,
- dwarf_v17_s390x,
- dwarf_v19_s390x,
- dwarf_v21_s390x,
- dwarf_v23_s390x,
- dwarf_v24_s390x,
- dwarf_v26_s390x,
- dwarf_v28_s390x,
- dwarf_v30_s390x,
- dwarf_v25_s390x,
- dwarf_v27_s390x,
- dwarf_v29_s390x,
- dwarf_v31_s390x,
+// EHFrame and DWARF Register numbers (eRegisterKindEHFrame &
+// eRegisterKindDWARF)
+enum {
+ // General Purpose Registers
+ dwarf_r0_s390x = 0,
+ dwarf_r1_s390x,
+ dwarf_r2_s390x,
+ dwarf_r3_s390x,
+ dwarf_r4_s390x,
+ dwarf_r5_s390x,
+ dwarf_r6_s390x,
+ dwarf_r7_s390x,
+ dwarf_r8_s390x,
+ dwarf_r9_s390x,
+ dwarf_r10_s390x,
+ dwarf_r11_s390x,
+ dwarf_r12_s390x,
+ dwarf_r13_s390x,
+ dwarf_r14_s390x,
+ dwarf_r15_s390x,
+ // Floating Point Registers / Vector Registers 0-15
+ dwarf_f0_s390x = 16,
+ dwarf_f2_s390x,
+ dwarf_f4_s390x,
+ dwarf_f6_s390x,
+ dwarf_f1_s390x,
+ dwarf_f3_s390x,
+ dwarf_f5_s390x,
+ dwarf_f7_s390x,
+ dwarf_f8_s390x,
+ dwarf_f10_s390x,
+ dwarf_f12_s390x,
+ dwarf_f14_s390x,
+ dwarf_f9_s390x,
+ dwarf_f11_s390x,
+ dwarf_f13_s390x,
+ dwarf_f15_s390x,
+ // Access Registers
+ dwarf_acr0_s390x = 48,
+ dwarf_acr1_s390x,
+ dwarf_acr2_s390x,
+ dwarf_acr3_s390x,
+ dwarf_acr4_s390x,
+ dwarf_acr5_s390x,
+ dwarf_acr6_s390x,
+ dwarf_acr7_s390x,
+ dwarf_acr8_s390x,
+ dwarf_acr9_s390x,
+ dwarf_acr10_s390x,
+ dwarf_acr11_s390x,
+ dwarf_acr12_s390x,
+ dwarf_acr13_s390x,
+ dwarf_acr14_s390x,
+ dwarf_acr15_s390x,
+ // Program Status Word
+ dwarf_pswm_s390x = 64,
+ dwarf_pswa_s390x,
+ // Vector Registers 16-31
+ dwarf_v16_s390x = 68,
+ dwarf_v18_s390x,
+ dwarf_v20_s390x,
+ dwarf_v22_s390x,
+ dwarf_v17_s390x,
+ dwarf_v19_s390x,
+ dwarf_v21_s390x,
+ dwarf_v23_s390x,
+ dwarf_v24_s390x,
+ dwarf_v26_s390x,
+ dwarf_v28_s390x,
+ dwarf_v30_s390x,
+ dwarf_v25_s390x,
+ dwarf_v27_s390x,
+ dwarf_v29_s390x,
+ dwarf_v31_s390x,
};
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContext_x86.h b/source/Plugins/Process/Utility/RegisterContext_x86.h
index 252f1253a086..ab2ca2bb6c2c 100644
--- a/source/Plugins/Process/Utility/RegisterContext_x86.h
+++ b/source/Plugins/Process/Utility/RegisterContext_x86.h
@@ -10,319 +10,350 @@
#ifndef liblldb_RegisterContext_x86_H_
#define liblldb_RegisterContext_x86_H_
+#include <cstddef>
+#include <cstdint>
+
+#include "llvm/Support/Compiler.h"
+
//---------------------------------------------------------------------------
// i386 ehframe, dwarf regnums
//---------------------------------------------------------------------------
-// Register numbers seen in eh_frame (eRegisterKindEHFrame) on i386 systems (non-Darwin)
+// Register numbers seen in eh_frame (eRegisterKindEHFrame) on i386 systems
+// (non-Darwin)
//
-enum
-{
- ehframe_eax_i386 = 0,
- ehframe_ecx_i386,
- ehframe_edx_i386,
- ehframe_ebx_i386,
+enum {
+ ehframe_eax_i386 = 0,
+ ehframe_ecx_i386,
+ ehframe_edx_i386,
+ ehframe_ebx_i386,
- // on Darwin esp & ebp are reversed in the eh_frame section for i386 (versus dwarf's reg numbering).
- // To be specific:
- // i386+darwin eh_frame: 4 is ebp, 5 is esp
- // i386+everyone else eh_frame: 4 is esp, 5 is ebp
- // i386 dwarf: 4 is esp, 5 is ebp
- // lldb will get the darwin-specific eh_frame reg numberings from debugserver, or the ABI, so we
- // only encode the generally correct 4 == esp, 5 == ebp numbers in this generic header.
+ // on Darwin esp & ebp are reversed in the eh_frame section for i386 (versus
+ // dwarf's reg numbering).
+ // To be specific:
+ // i386+darwin eh_frame: 4 is ebp, 5 is esp
+ // i386+everyone else eh_frame: 4 is esp, 5 is ebp
+ // i386 dwarf: 4 is esp, 5 is ebp
+ // lldb will get the darwin-specific eh_frame reg numberings from debugserver,
+ // or the ABI, so we
+ // only encode the generally correct 4 == esp, 5 == ebp numbers in this
+ // generic header.
- ehframe_esp_i386,
- ehframe_ebp_i386,
- ehframe_esi_i386,
- ehframe_edi_i386,
- ehframe_eip_i386,
- ehframe_eflags_i386,
- ehframe_st0_i386 = 12,
- ehframe_st1_i386,
- ehframe_st2_i386,
- ehframe_st3_i386,
- ehframe_st4_i386,
- ehframe_st5_i386,
- ehframe_st6_i386,
- ehframe_st7_i386,
- ehframe_xmm0_i386 = 21,
- ehframe_xmm1_i386,
- ehframe_xmm2_i386,
- ehframe_xmm3_i386,
- ehframe_xmm4_i386,
- ehframe_xmm5_i386,
- ehframe_xmm6_i386,
- ehframe_xmm7_i386,
- ehframe_mm0_i386 = 29,
- ehframe_mm1_i386,
- ehframe_mm2_i386,
- ehframe_mm3_i386,
- ehframe_mm4_i386,
- ehframe_mm5_i386,
- ehframe_mm6_i386,
- ehframe_mm7_i386,
+ ehframe_esp_i386,
+ ehframe_ebp_i386,
+ ehframe_esi_i386,
+ ehframe_edi_i386,
+ ehframe_eip_i386,
+ ehframe_eflags_i386,
+ ehframe_st0_i386 = 12,
+ ehframe_st1_i386,
+ ehframe_st2_i386,
+ ehframe_st3_i386,
+ ehframe_st4_i386,
+ ehframe_st5_i386,
+ ehframe_st6_i386,
+ ehframe_st7_i386,
+ ehframe_xmm0_i386 = 21,
+ ehframe_xmm1_i386,
+ ehframe_xmm2_i386,
+ ehframe_xmm3_i386,
+ ehframe_xmm4_i386,
+ ehframe_xmm5_i386,
+ ehframe_xmm6_i386,
+ ehframe_xmm7_i386,
+ ehframe_mm0_i386 = 29,
+ ehframe_mm1_i386,
+ ehframe_mm2_i386,
+ ehframe_mm3_i386,
+ ehframe_mm4_i386,
+ ehframe_mm5_i386,
+ ehframe_mm6_i386,
+ ehframe_mm7_i386,
};
// DWARF register numbers (eRegisterKindDWARF)
// Intel's x86 or IA-32
-enum
-{
- // General Purpose Registers.
- dwarf_eax_i386 = 0,
- dwarf_ecx_i386,
- dwarf_edx_i386,
- dwarf_ebx_i386,
- dwarf_esp_i386,
- dwarf_ebp_i386,
- dwarf_esi_i386,
- dwarf_edi_i386,
- dwarf_eip_i386,
- dwarf_eflags_i386,
- // Floating Point Registers
- dwarf_st0_i386 = 11,
- dwarf_st1_i386,
- dwarf_st2_i386,
- dwarf_st3_i386,
- dwarf_st4_i386,
- dwarf_st5_i386,
- dwarf_st6_i386,
- dwarf_st7_i386,
- // SSE Registers
- dwarf_xmm0_i386 = 21,
- dwarf_xmm1_i386,
- dwarf_xmm2_i386,
- dwarf_xmm3_i386,
- dwarf_xmm4_i386,
- dwarf_xmm5_i386,
- dwarf_xmm6_i386,
- dwarf_xmm7_i386,
- // MMX Registers
- dwarf_mm0_i386 = 29,
- dwarf_mm1_i386,
- dwarf_mm2_i386,
- dwarf_mm3_i386,
- dwarf_mm4_i386,
- dwarf_mm5_i386,
- dwarf_mm6_i386,
- dwarf_mm7_i386,
- dwarf_fctrl_i386 = 37, // x87 control word
- dwarf_fstat_i386 = 38, // x87 status word
- dwarf_mxcsr_i386 = 39,
- dwarf_es_i386 = 40,
- dwarf_cs_i386 = 41,
- dwarf_ss_i386 = 42,
- dwarf_ds_i386 = 43,
- dwarf_fs_i386 = 44,
- dwarf_gs_i386 = 45
+enum {
+ // General Purpose Registers.
+ dwarf_eax_i386 = 0,
+ dwarf_ecx_i386,
+ dwarf_edx_i386,
+ dwarf_ebx_i386,
+ dwarf_esp_i386,
+ dwarf_ebp_i386,
+ dwarf_esi_i386,
+ dwarf_edi_i386,
+ dwarf_eip_i386,
+ dwarf_eflags_i386,
+ // Floating Point Registers
+ dwarf_st0_i386 = 11,
+ dwarf_st1_i386,
+ dwarf_st2_i386,
+ dwarf_st3_i386,
+ dwarf_st4_i386,
+ dwarf_st5_i386,
+ dwarf_st6_i386,
+ dwarf_st7_i386,
+ // SSE Registers
+ dwarf_xmm0_i386 = 21,
+ dwarf_xmm1_i386,
+ dwarf_xmm2_i386,
+ dwarf_xmm3_i386,
+ dwarf_xmm4_i386,
+ dwarf_xmm5_i386,
+ dwarf_xmm6_i386,
+ dwarf_xmm7_i386,
+ // MMX Registers
+ dwarf_mm0_i386 = 29,
+ dwarf_mm1_i386,
+ dwarf_mm2_i386,
+ dwarf_mm3_i386,
+ dwarf_mm4_i386,
+ dwarf_mm5_i386,
+ dwarf_mm6_i386,
+ dwarf_mm7_i386,
+ dwarf_fctrl_i386 = 37, // x87 control word
+ dwarf_fstat_i386 = 38, // x87 status word
+ dwarf_mxcsr_i386 = 39,
+ dwarf_es_i386 = 40,
+ dwarf_cs_i386 = 41,
+ dwarf_ss_i386 = 42,
+ dwarf_ds_i386 = 43,
+ dwarf_fs_i386 = 44,
+ dwarf_gs_i386 = 45,
- // I believe the ymm registers use the dwarf_xmm%_i386 register numbers and
- // then differentiate based on size of the register.
+ // I believe the ymm registers use the dwarf_xmm%_i386 register numbers and
+ // then differentiate based on size of the register.
+ dwarf_bnd0_i386 = 101,
+ dwarf_bnd1_i386,
+ dwarf_bnd2_i386,
+ dwarf_bnd3_i386,
};
//---------------------------------------------------------------------------
// AMD x86_64, AMD64, Intel EM64T, or Intel 64 ehframe, dwarf regnums
//---------------------------------------------------------------------------
-// EHFrame and DWARF Register numbers (eRegisterKindEHFrame & eRegisterKindDWARF)
+// EHFrame and DWARF Register numbers (eRegisterKindEHFrame &
+// eRegisterKindDWARF)
// This is the spec I used (as opposed to x86-64-abi-0.99.pdf):
// http://software.intel.com/sites/default/files/article/402129/mpx-linux64-abi.pdf
-enum
-{
- // GP Registers
- dwarf_rax_x86_64 = 0,
- dwarf_rdx_x86_64,
- dwarf_rcx_x86_64,
- dwarf_rbx_x86_64,
- dwarf_rsi_x86_64,
- dwarf_rdi_x86_64,
- dwarf_rbp_x86_64,
- dwarf_rsp_x86_64,
- // Extended GP Registers
- dwarf_r8_x86_64 = 8,
- dwarf_r9_x86_64,
- dwarf_r10_x86_64,
- dwarf_r11_x86_64,
- dwarf_r12_x86_64,
- dwarf_r13_x86_64,
- dwarf_r14_x86_64,
- dwarf_r15_x86_64,
- // Return Address (RA) mapped to RIP
- dwarf_rip_x86_64 = 16,
- // SSE Vector Registers
- dwarf_xmm0_x86_64 = 17,
- dwarf_xmm1_x86_64,
- dwarf_xmm2_x86_64,
- dwarf_xmm3_x86_64,
- dwarf_xmm4_x86_64,
- dwarf_xmm5_x86_64,
- dwarf_xmm6_x86_64,
- dwarf_xmm7_x86_64,
- dwarf_xmm8_x86_64,
- dwarf_xmm9_x86_64,
- dwarf_xmm10_x86_64,
- dwarf_xmm11_x86_64,
- dwarf_xmm12_x86_64,
- dwarf_xmm13_x86_64,
- dwarf_xmm14_x86_64,
- dwarf_xmm15_x86_64,
- // Floating Point Registers
- dwarf_st0_x86_64 = 33,
- dwarf_st1_x86_64,
- dwarf_st2_x86_64,
- dwarf_st3_x86_64,
- dwarf_st4_x86_64,
- dwarf_st5_x86_64,
- dwarf_st6_x86_64,
- dwarf_st7_x86_64,
- // MMX Registers
- dwarf_mm0_x86_64 = 41,
- dwarf_mm1_x86_64,
- dwarf_mm2_x86_64,
- dwarf_mm3_x86_64,
- dwarf_mm4_x86_64,
- dwarf_mm5_x86_64,
- dwarf_mm6_x86_64,
- dwarf_mm7_x86_64,
- // Control and Status Flags Register
- dwarf_rflags_x86_64 = 49,
- // selector registers
- dwarf_es_x86_64 = 50,
- dwarf_cs_x86_64,
- dwarf_ss_x86_64,
- dwarf_ds_x86_64,
- dwarf_fs_x86_64,
- dwarf_gs_x86_64,
- // Floating point control registers
- dwarf_mxcsr_x86_64 = 64, // Media Control and Status
- dwarf_fctrl_x86_64, // x87 control word
- dwarf_fstat_x86_64, // x87 status word
- // Upper Vector Registers
- dwarf_ymm0h_x86_64 = 67,
- dwarf_ymm1h_x86_64,
- dwarf_ymm2h_x86_64,
- dwarf_ymm3h_x86_64,
- dwarf_ymm4h_x86_64,
- dwarf_ymm5h_x86_64,
- dwarf_ymm6h_x86_64,
- dwarf_ymm7h_x86_64,
- dwarf_ymm8h_x86_64,
- dwarf_ymm9h_x86_64,
- dwarf_ymm10h_x86_64,
- dwarf_ymm11h_x86_64,
- dwarf_ymm12h_x86_64,
- dwarf_ymm13h_x86_64,
- dwarf_ymm14h_x86_64,
- dwarf_ymm15h_x86_64,
- // AVX2 Vector Mask Registers
- // dwarf_k0_x86_64 = 118,
- // dwarf_k1_x86_64,
- // dwarf_k2_x86_64,
- // dwarf_k3_x86_64,
- // dwarf_k4_x86_64,
- // dwarf_k5_x86_64,
- // dwarf_k6_x86_64,
- // dwarf_k7_x86_64,
+enum {
+ // GP Registers
+ dwarf_rax_x86_64 = 0,
+ dwarf_rdx_x86_64,
+ dwarf_rcx_x86_64,
+ dwarf_rbx_x86_64,
+ dwarf_rsi_x86_64,
+ dwarf_rdi_x86_64,
+ dwarf_rbp_x86_64,
+ dwarf_rsp_x86_64,
+ // Extended GP Registers
+ dwarf_r8_x86_64 = 8,
+ dwarf_r9_x86_64,
+ dwarf_r10_x86_64,
+ dwarf_r11_x86_64,
+ dwarf_r12_x86_64,
+ dwarf_r13_x86_64,
+ dwarf_r14_x86_64,
+ dwarf_r15_x86_64,
+ // Return Address (RA) mapped to RIP
+ dwarf_rip_x86_64 = 16,
+ // SSE Vector Registers
+ dwarf_xmm0_x86_64 = 17,
+ dwarf_xmm1_x86_64,
+ dwarf_xmm2_x86_64,
+ dwarf_xmm3_x86_64,
+ dwarf_xmm4_x86_64,
+ dwarf_xmm5_x86_64,
+ dwarf_xmm6_x86_64,
+ dwarf_xmm7_x86_64,
+ dwarf_xmm8_x86_64,
+ dwarf_xmm9_x86_64,
+ dwarf_xmm10_x86_64,
+ dwarf_xmm11_x86_64,
+ dwarf_xmm12_x86_64,
+ dwarf_xmm13_x86_64,
+ dwarf_xmm14_x86_64,
+ dwarf_xmm15_x86_64,
+ // Floating Point Registers
+ dwarf_st0_x86_64 = 33,
+ dwarf_st1_x86_64,
+ dwarf_st2_x86_64,
+ dwarf_st3_x86_64,
+ dwarf_st4_x86_64,
+ dwarf_st5_x86_64,
+ dwarf_st6_x86_64,
+ dwarf_st7_x86_64,
+ // MMX Registers
+ dwarf_mm0_x86_64 = 41,
+ dwarf_mm1_x86_64,
+ dwarf_mm2_x86_64,
+ dwarf_mm3_x86_64,
+ dwarf_mm4_x86_64,
+ dwarf_mm5_x86_64,
+ dwarf_mm6_x86_64,
+ dwarf_mm7_x86_64,
+ // Control and Status Flags Register
+ dwarf_rflags_x86_64 = 49,
+ // selector registers
+ dwarf_es_x86_64 = 50,
+ dwarf_cs_x86_64,
+ dwarf_ss_x86_64,
+ dwarf_ds_x86_64,
+ dwarf_fs_x86_64,
+ dwarf_gs_x86_64,
+ // Floating point control registers
+ dwarf_mxcsr_x86_64 = 64, // Media Control and Status
+ dwarf_fctrl_x86_64, // x87 control word
+ dwarf_fstat_x86_64, // x87 status word
+ // Upper Vector Registers
+ dwarf_ymm0h_x86_64 = 67,
+ dwarf_ymm1h_x86_64,
+ dwarf_ymm2h_x86_64,
+ dwarf_ymm3h_x86_64,
+ dwarf_ymm4h_x86_64,
+ dwarf_ymm5h_x86_64,
+ dwarf_ymm6h_x86_64,
+ dwarf_ymm7h_x86_64,
+ dwarf_ymm8h_x86_64,
+ dwarf_ymm9h_x86_64,
+ dwarf_ymm10h_x86_64,
+ dwarf_ymm11h_x86_64,
+ dwarf_ymm12h_x86_64,
+ dwarf_ymm13h_x86_64,
+ dwarf_ymm14h_x86_64,
+ dwarf_ymm15h_x86_64,
+ // MPX registers
+ dwarf_bnd0_x86_64 = 126,
+ dwarf_bnd1_x86_64,
+ dwarf_bnd2_x86_64,
+ dwarf_bnd3_x86_64,
+ // AVX2 Vector Mask Registers
+ // dwarf_k0_x86_64 = 118,
+ // dwarf_k1_x86_64,
+ // dwarf_k2_x86_64,
+ // dwarf_k3_x86_64,
+ // dwarf_k4_x86_64,
+ // dwarf_k5_x86_64,
+ // dwarf_k6_x86_64,
+ // dwarf_k7_x86_64,
};
//---------------------------------------------------------------------------
// Generic floating-point registers
//---------------------------------------------------------------------------
-struct MMSReg
-{
- uint8_t bytes[10];
- uint8_t pad[6];
+struct MMSReg {
+ uint8_t bytes[10];
+ uint8_t pad[6];
};
-struct XMMReg
-{
- uint8_t bytes[16]; // 128-bits for each XMM register
+struct XMMReg {
+ uint8_t bytes[16]; // 128-bits for each XMM register
};
// i387_fxsave_struct
-struct FXSAVE
-{
- uint16_t fctrl; // FPU Control Word (fcw)
- uint16_t fstat; // FPU Status Word (fsw)
- uint8_t ftag; // FPU Tag Word (ftw)
- uint8_t reserved_1; // Reserved
- uint16_t fop; // Last Instruction Opcode (fop)
- union
- {
- struct
- {
- uint64_t fip; // Instruction Pointer
- uint64_t fdp; // Data Pointer
- } x86_64;
- struct
- {
- uint32_t fioff; // FPU IP Offset (fip)
- uint32_t fiseg; // FPU IP Selector (fcs)
- uint32_t fooff; // FPU Operand Pointer Offset (foo)
- uint32_t foseg; // FPU Operand Pointer Selector (fos)
- } i386_;// Added _ in the end to avoid error with gcc defining i386 in some cases
- } ptr;
- uint32_t mxcsr; // MXCSR Register State
- uint32_t mxcsrmask; // MXCSR Mask
- MMSReg stmm[8]; // 8*16 bytes for each FP-reg = 128 bytes
- XMMReg xmm[16]; // 16*16 bytes for each XMM-reg = 256 bytes
- uint32_t padding[24];
+struct FXSAVE {
+ uint16_t fctrl; // FPU Control Word (fcw)
+ uint16_t fstat; // FPU Status Word (fsw)
+ uint8_t ftag; // FPU Tag Word (ftw)
+ uint8_t reserved_1; // Reserved
+ uint16_t fop; // Last Instruction Opcode (fop)
+ union {
+ struct {
+ uint64_t fip; // Instruction Pointer
+ uint64_t fdp; // Data Pointer
+ } x86_64;
+ struct {
+ uint32_t fioff; // FPU IP Offset (fip)
+ uint32_t fiseg; // FPU IP Selector (fcs)
+ uint32_t fooff; // FPU Operand Pointer Offset (foo)
+ uint32_t foseg; // FPU Operand Pointer Selector (fos)
+ } i386_; // Added _ in the end to avoid error with gcc defining i386 in some
+ // cases
+ } ptr;
+ uint32_t mxcsr; // MXCSR Register State
+ uint32_t mxcsrmask; // MXCSR Mask
+ MMSReg stmm[8]; // 8*16 bytes for each FP-reg = 128 bytes
+ XMMReg xmm[16]; // 16*16 bytes for each XMM-reg = 256 bytes
+ uint8_t padding1[48];
+ uint64_t xcr0;
+ uint8_t padding2[40];
};
//---------------------------------------------------------------------------
// Extended floating-point registers
//---------------------------------------------------------------------------
-struct YMMHReg
-{
- uint8_t bytes[16]; // 16 * 8 bits for the high bytes of each YMM register
+struct YMMHReg {
+ uint8_t bytes[16]; // 16 * 8 bits for the high bytes of each YMM register
+};
+
+struct YMMReg {
+ uint8_t bytes[32]; // 16 * 16 bits for each YMM register
+};
+
+struct YMM {
+ YMMReg ymm[16]; // assembled from ymmh and xmm registers
};
-struct YMMReg
-{
- uint8_t bytes[32]; // 16 * 16 bits for each YMM register
+struct MPXReg {
+ uint8_t bytes[16]; // MPX 128 bit bound registers
};
-struct YMM
-{
- YMMReg ymm[16]; // assembled from ymmh and xmm registers
+struct MPXCsr {
+ uint8_t bytes[8]; // MPX 64 bit bndcfgu and bndstatus registers (collectively
+ // BNDCSR state)
};
-struct XSAVE_HDR
-{
- uint64_t xstate_bv; // OS enabled xstate mask to determine the extended states supported by the processor
- uint64_t reserved1[2];
- uint64_t reserved2[5];
-} __attribute__((packed));
+struct MPX {
+ MPXReg mpxr[4];
+ MPXCsr mpxc[2];
+};
-// x86 extensions to FXSAVE (i.e. for AVX processors)
-struct XSAVE
-{
- FXSAVE i387; // floating point registers typical in i387_fxsave_struct
- XSAVE_HDR header; // The xsave_hdr_struct can be used to determine if the following extensions are usable
- YMMHReg ymmh[16]; // High 16 bytes of each of 16 YMM registers (the low bytes are in FXSAVE.xmm for compatibility with SSE)
- // Slot any extensions to the register file here
-} __attribute__((packed, aligned (64)));
+LLVM_PACKED_START
+struct XSAVE_HDR {
+ uint64_t xstate_bv; // OS enabled xstate mask to determine the extended states
+ // supported by the processor
+ uint64_t xcomp_bv; // Mask to indicate the format of the XSAVE area and of
+ // the XRSTOR instruction
+ uint64_t reserved1[1];
+ uint64_t reserved2[5];
+};
+LLVM_PACKED_END
+
+// x86 extensions to FXSAVE (i.e. for AVX and MPX processors)
+LLVM_PACKED_START
+struct LLVM_ALIGNAS(64) XSAVE {
+ FXSAVE i387; // floating point registers typical in i387_fxsave_struct
+ XSAVE_HDR header; // The xsave_hdr_struct can be used to determine if the
+ // following extensions are usable
+ YMMHReg ymmh[16]; // High 16 bytes of each of 16 YMM registers (the low bytes
+ // are in FXSAVE.xmm for compatibility with SSE)
+ uint64_t reserved3[16];
+ MPXReg mpxr[4]; // MPX BNDREG state, containing 128-bit bound registers
+ MPXCsr mpxc[2]; // MPX BNDCSR state, containing 64-bit BNDCFGU and
+ // BNDSTATUS registers
+};
+LLVM_PACKED_END
// Floating-point registers
-struct FPR
-{
- // Thread state for the floating-point unit of the processor read by ptrace.
- union XSTATE
- {
- FXSAVE fxsave; // Generic floating-point registers.
- XSAVE xsave; // x86 extended processor state.
- } xstate;
+struct FPR {
+ // Thread state for the floating-point unit of the processor read by ptrace.
+ union XSTATE {
+ FXSAVE fxsave; // Generic floating-point registers.
+ XSAVE xsave; // x86 extended processor state.
+ } xstate;
};
//---------------------------------------------------------------------------
// ptrace PTRACE_GETREGSET, PTRACE_SETREGSET structure
//---------------------------------------------------------------------------
-struct IOVEC
-{
- void *iov_base; // pointer to XSAVE
- size_t iov_len; // sizeof(XSAVE)
+struct IOVEC {
+ void *iov_base; // pointer to XSAVE
+ size_t iov_len; // sizeof(XSAVE)
};
#endif
diff --git a/source/Plugins/Process/Utility/RegisterInfoInterface.h b/source/Plugins/Process/Utility/RegisterInfoInterface.h
index 801885d5f4c5..12db366d7a57 100644
--- a/source/Plugins/Process/Utility/RegisterInfoInterface.h
+++ b/source/Plugins/Process/Utility/RegisterInfoInterface.h
@@ -14,69 +14,60 @@
#include "lldb/Core/ArchSpec.h"
-namespace lldb_private
-{
+namespace lldb_private {
- ///------------------------------------------------------------------------------
- /// @class RegisterInfoInterface
- ///
- /// @brief RegisterInfo interface to patch RegisterInfo structure for archs.
- ///------------------------------------------------------------------------------
- class RegisterInfoInterface
- {
- public:
- RegisterInfoInterface(const lldb_private::ArchSpec& target_arch) : m_target_arch(target_arch) {}
- virtual ~RegisterInfoInterface () {}
+///------------------------------------------------------------------------------
+/// @class RegisterInfoInterface
+///
+/// @brief RegisterInfo interface to patch RegisterInfo structure for archs.
+///------------------------------------------------------------------------------
+class RegisterInfoInterface {
+public:
+ RegisterInfoInterface(const lldb_private::ArchSpec &target_arch)
+ : m_target_arch(target_arch) {}
+ virtual ~RegisterInfoInterface() {}
- virtual size_t
- GetGPRSize () const = 0;
+ virtual size_t GetGPRSize() const = 0;
- virtual const lldb_private::RegisterInfo *
- GetRegisterInfo () const = 0;
+ virtual const lldb_private::RegisterInfo *GetRegisterInfo() const = 0;
- // Returns the number of registers including the user registers and the
- // lldb internal registers also
- virtual uint32_t
- GetRegisterCount () const = 0;
+ // Returns the number of registers including the user registers and the
+ // lldb internal registers also
+ virtual uint32_t GetRegisterCount() const = 0;
- // Returns the number of the user registers (excluding the registers
- // kept for lldb internal use only). Subclasses should override it if
- // they belongs to an architecture with lldb internal registers.
- virtual uint32_t
- GetUserRegisterCount () const
- {
- return GetRegisterCount();
- }
+ // Returns the number of the user registers (excluding the registers
+ // kept for lldb internal use only). Subclasses should override it if
+ // they belongs to an architecture with lldb internal registers.
+ virtual uint32_t GetUserRegisterCount() const { return GetRegisterCount(); }
- const lldb_private::ArchSpec&
- GetTargetArchitecture() const
- { return m_target_arch; }
+ const lldb_private::ArchSpec &GetTargetArchitecture() const {
+ return m_target_arch;
+ }
- virtual const lldb_private::RegisterInfo *
- GetDynamicRegisterInfo(const char *reg_name) const
- {
- const std::vector <lldb_private::RegisterInfo> * d_register_infos = GetDynamicRegisterInfoP();
- if(d_register_infos != nullptr)
- {
- std::vector <lldb_private::RegisterInfo> ::const_iterator pos = d_register_infos->begin();
- for(; pos < d_register_infos->end() ; pos++)
- {
- if(::strcmp(reg_name, pos->name) == 0)
- return(d_register_infos->data() + (pos - d_register_infos->begin()) );
- }
- }
- return nullptr;
- }
+ virtual const lldb_private::RegisterInfo *
+ GetDynamicRegisterInfo(const char *reg_name) const {
+ const std::vector<lldb_private::RegisterInfo> *d_register_infos =
+ GetDynamicRegisterInfoP();
+ if (d_register_infos != nullptr) {
+ std::vector<lldb_private::RegisterInfo>::const_iterator pos =
+ d_register_infos->begin();
+ for (; pos < d_register_infos->end(); pos++) {
+ if (::strcmp(reg_name, pos->name) == 0)
+ return (d_register_infos->data() + (pos - d_register_infos->begin()));
+ }
+ }
+ return nullptr;
+ }
- virtual const std::vector<lldb_private::RegisterInfo> *
- GetDynamicRegisterInfoP() const
- { return nullptr; }
-
- public:
- // FIXME make private.
- lldb_private::ArchSpec m_target_arch;
- };
+ virtual const std::vector<lldb_private::RegisterInfo> *
+ GetDynamicRegisterInfoP() const {
+ return nullptr;
+ }
+public:
+ // FIXME make private.
+ lldb_private::ArchSpec m_target_arch;
+};
}
#endif
diff --git a/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp b/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
new file mode 100644
index 000000000000..1b145e0a173b
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
@@ -0,0 +1,99 @@
+//===-- RegisterInfoPOSIX_arm64.cpp ----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===---------------------------------------------------------------------===//
+
+#include <cassert>
+#include <stddef.h>
+#include <vector>
+
+#include "lldb/lldb-defines.h"
+#include "llvm/Support/Compiler.h"
+
+#include "RegisterInfoPOSIX_arm64.h"
+
+// Based on RegisterContextDarwin_arm64.cpp
+#define GPR_OFFSET(idx) ((idx)*8)
+#define GPR_OFFSET_NAME(reg) \
+ (LLVM_EXTENSION offsetof(RegisterInfoPOSIX_arm64::GPR, reg))
+
+#define FPU_OFFSET(idx) ((idx)*16 + sizeof(RegisterInfoPOSIX_arm64::GPR))
+#define FPU_OFFSET_NAME(reg) \
+ (LLVM_EXTENSION offsetof(RegisterInfoPOSIX_arm64::FPU, reg) + \
+ sizeof(RegisterInfoPOSIX_arm64::GPR))
+
+#define EXC_OFFSET_NAME(reg) \
+ (LLVM_EXTENSION offsetof(RegisterInfoPOSIX_arm64::EXC, reg) + \
+ sizeof(RegisterInfoPOSIX_arm64::GPR) + \
+ sizeof(RegisterInfoPOSIX_arm64::FPU))
+#define DBG_OFFSET_NAME(reg) \
+ (LLVM_EXTENSION offsetof(RegisterInfoPOSIX_arm64::DBG, reg) + \
+ sizeof(RegisterInfoPOSIX_arm64::GPR) + \
+ sizeof(RegisterInfoPOSIX_arm64::FPU) + \
+ sizeof(RegisterInfoPOSIX_arm64::EXC))
+
+#define DEFINE_DBG(reg, i) \
+ #reg, NULL, \
+ sizeof(((RegisterInfoPOSIX_arm64::DBG *) NULL)->reg[i]), \
+ DBG_OFFSET_NAME(reg[i]), lldb::eEncodingUint, lldb::eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ dbg_##reg##i }, \
+ NULL, NULL, NULL, 0
+#define REG_CONTEXT_SIZE \
+ (sizeof(RegisterInfoPOSIX_arm64::GPR) + \
+ sizeof(RegisterInfoPOSIX_arm64::FPU) + \
+ sizeof(RegisterInfoPOSIX_arm64::EXC))
+
+//-----------------------------------------------------------------------------
+// Include RegisterInfos_arm64 to declare our g_register_infos_arm64 structure.
+//-----------------------------------------------------------------------------
+#define DECLARE_REGISTER_INFOS_ARM64_STRUCT
+#include "RegisterInfos_arm64.h"
+#undef DECLARE_REGISTER_INFOS_ARM64_STRUCT
+
+static const lldb_private::RegisterInfo *
+GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::aarch64:
+ return g_register_infos_arm64_le;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return NULL;
+ }
+}
+
+static uint32_t
+GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::aarch64:
+ return static_cast<uint32_t>(sizeof(g_register_infos_arm64_le) /
+ sizeof(g_register_infos_arm64_le[0]));
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
+}
+
+RegisterInfoPOSIX_arm64::RegisterInfoPOSIX_arm64(
+ const lldb_private::ArchSpec &target_arch)
+ : lldb_private::RegisterInfoInterface(target_arch),
+ m_register_info_p(GetRegisterInfoPtr(target_arch)),
+ m_register_info_count(GetRegisterInfoCount(target_arch)) {}
+
+size_t RegisterInfoPOSIX_arm64::GetGPRSize() const {
+ return sizeof(struct RegisterInfoPOSIX_arm64::GPR);
+}
+
+const lldb_private::RegisterInfo *
+RegisterInfoPOSIX_arm64::GetRegisterInfo() const {
+ return m_register_info_p;
+}
+
+uint32_t RegisterInfoPOSIX_arm64::GetRegisterCount() const {
+ return m_register_info_count;
+}
diff --git a/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h b/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
new file mode 100644
index 000000000000..af770760cbf4
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
@@ -0,0 +1,70 @@
+//===-- RegisterInfoPOSIX_arm64.h -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_RegisterContextLinux_arm64_H_
+#define liblldb_RegisterContextLinux_arm64_H_
+
+#include "RegisterInfoInterface.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/lldb-private.h"
+
+class RegisterInfoPOSIX_arm64 : public lldb_private::RegisterInfoInterface {
+public:
+ // based on RegisterContextDarwin_arm64.h
+ struct GPR {
+ uint64_t x[29]; // x0-x28
+ uint64_t fp; // x29
+ uint64_t lr; // x30
+ uint64_t sp; // x31
+ uint64_t pc; // pc
+ uint32_t cpsr; // cpsr
+ };
+
+ // based on RegisterContextDarwin_arm64.h
+ struct VReg {
+ uint8_t bytes[16];
+ };
+
+ // based on RegisterContextDarwin_arm64.h
+ struct FPU {
+ VReg v[32];
+ uint32_t fpsr;
+ uint32_t fpcr;
+ };
+
+ // based on RegisterContextDarwin_arm64.h
+ struct EXC {
+ uint64_t far; // Virtual Fault Address
+ uint32_t esr; // Exception syndrome
+ uint32_t exception; // number of arm exception token
+ };
+
+ // based on RegisterContextDarwin_arm64.h
+ struct DBG {
+ uint64_t bvr[16];
+ uint64_t bcr[16];
+ uint64_t wvr[16];
+ uint64_t wcr[16];
+ uint64_t mdscr_el1;
+ };
+
+ RegisterInfoPOSIX_arm64(const lldb_private::ArchSpec &target_arch);
+
+ size_t GetGPRSize() const override;
+
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
+
+ uint32_t GetRegisterCount() const override;
+
+private:
+ const lldb_private::RegisterInfo *m_register_info_p;
+ uint32_t m_register_info_count;
+};
+
+#endif
diff --git a/source/Plugins/Process/Utility/RegisterInfos_arm.h b/source/Plugins/Process/Utility/RegisterInfos_arm.h
index e3c7473bf712..74d3226c8a52 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_arm.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_arm.h
@@ -15,12 +15,12 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/lldb-defines.h"
#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-private.h"
-#include "Utility/ARM_ehframe_Registers.h"
#include "Utility/ARM_DWARF_Registers.h"
+#include "Utility/ARM_ehframe_Registers.h"
using namespace lldb;
using namespace lldb_private;
@@ -45,461 +45,1580 @@ using namespace lldb_private;
#error DEFINE_DBG must be defined before including this header file
#endif
-enum
-{
- gpr_r0 = 0,
- gpr_r1,
- gpr_r2,
- gpr_r3,
- gpr_r4,
- gpr_r5,
- gpr_r6,
- gpr_r7,
- gpr_r8,
- gpr_r9,
- gpr_r10,
- gpr_r11,
- gpr_r12,
- gpr_r13, gpr_sp = gpr_r13,
- gpr_r14, gpr_lr = gpr_r14,
- gpr_r15, gpr_pc = gpr_r15,
- gpr_cpsr,
-
- fpu_s0,
- fpu_s1,
- fpu_s2,
- fpu_s3,
- fpu_s4,
- fpu_s5,
- fpu_s6,
- fpu_s7,
- fpu_s8,
- fpu_s9,
- fpu_s10,
- fpu_s11,
- fpu_s12,
- fpu_s13,
- fpu_s14,
- fpu_s15,
- fpu_s16,
- fpu_s17,
- fpu_s18,
- fpu_s19,
- fpu_s20,
- fpu_s21,
- fpu_s22,
- fpu_s23,
- fpu_s24,
- fpu_s25,
- fpu_s26,
- fpu_s27,
- fpu_s28,
- fpu_s29,
- fpu_s30,
- fpu_s31,
- fpu_fpscr,
-
- fpu_d0,
- fpu_d1,
- fpu_d2,
- fpu_d3,
- fpu_d4,
- fpu_d5,
- fpu_d6,
- fpu_d7,
- fpu_d8,
- fpu_d9,
- fpu_d10,
- fpu_d11,
- fpu_d12,
- fpu_d13,
- fpu_d14,
- fpu_d15,
- fpu_d16,
- fpu_d17,
- fpu_d18,
- fpu_d19,
- fpu_d20,
- fpu_d21,
- fpu_d22,
- fpu_d23,
- fpu_d24,
- fpu_d25,
- fpu_d26,
- fpu_d27,
- fpu_d28,
- fpu_d29,
- fpu_d30,
- fpu_d31,
-
- fpu_q0,
- fpu_q1,
- fpu_q2,
- fpu_q3,
- fpu_q4,
- fpu_q5,
- fpu_q6,
- fpu_q7,
- fpu_q8,
- fpu_q9,
- fpu_q10,
- fpu_q11,
- fpu_q12,
- fpu_q13,
- fpu_q14,
- fpu_q15,
-
- exc_exception,
- exc_fsr,
- exc_far,
-
- dbg_bvr0,
- dbg_bvr1,
- dbg_bvr2,
- dbg_bvr3,
- dbg_bvr4,
- dbg_bvr5,
- dbg_bvr6,
- dbg_bvr7,
- dbg_bvr8,
- dbg_bvr9,
- dbg_bvr10,
- dbg_bvr11,
- dbg_bvr12,
- dbg_bvr13,
- dbg_bvr14,
- dbg_bvr15,
-
- dbg_bcr0,
- dbg_bcr1,
- dbg_bcr2,
- dbg_bcr3,
- dbg_bcr4,
- dbg_bcr5,
- dbg_bcr6,
- dbg_bcr7,
- dbg_bcr8,
- dbg_bcr9,
- dbg_bcr10,
- dbg_bcr11,
- dbg_bcr12,
- dbg_bcr13,
- dbg_bcr14,
- dbg_bcr15,
-
- dbg_wvr0,
- dbg_wvr1,
- dbg_wvr2,
- dbg_wvr3,
- dbg_wvr4,
- dbg_wvr5,
- dbg_wvr6,
- dbg_wvr7,
- dbg_wvr8,
- dbg_wvr9,
- dbg_wvr10,
- dbg_wvr11,
- dbg_wvr12,
- dbg_wvr13,
- dbg_wvr14,
- dbg_wvr15,
-
- dbg_wcr0,
- dbg_wcr1,
- dbg_wcr2,
- dbg_wcr3,
- dbg_wcr4,
- dbg_wcr5,
- dbg_wcr6,
- dbg_wcr7,
- dbg_wcr8,
- dbg_wcr9,
- dbg_wcr10,
- dbg_wcr11,
- dbg_wcr12,
- dbg_wcr13,
- dbg_wcr14,
- dbg_wcr15,
-
- k_num_registers
+enum {
+ gpr_r0 = 0,
+ gpr_r1,
+ gpr_r2,
+ gpr_r3,
+ gpr_r4,
+ gpr_r5,
+ gpr_r6,
+ gpr_r7,
+ gpr_r8,
+ gpr_r9,
+ gpr_r10,
+ gpr_r11,
+ gpr_r12,
+ gpr_r13,
+ gpr_sp = gpr_r13,
+ gpr_r14,
+ gpr_lr = gpr_r14,
+ gpr_r15,
+ gpr_pc = gpr_r15,
+ gpr_cpsr,
+
+ fpu_s0,
+ fpu_s1,
+ fpu_s2,
+ fpu_s3,
+ fpu_s4,
+ fpu_s5,
+ fpu_s6,
+ fpu_s7,
+ fpu_s8,
+ fpu_s9,
+ fpu_s10,
+ fpu_s11,
+ fpu_s12,
+ fpu_s13,
+ fpu_s14,
+ fpu_s15,
+ fpu_s16,
+ fpu_s17,
+ fpu_s18,
+ fpu_s19,
+ fpu_s20,
+ fpu_s21,
+ fpu_s22,
+ fpu_s23,
+ fpu_s24,
+ fpu_s25,
+ fpu_s26,
+ fpu_s27,
+ fpu_s28,
+ fpu_s29,
+ fpu_s30,
+ fpu_s31,
+ fpu_fpscr,
+
+ fpu_d0,
+ fpu_d1,
+ fpu_d2,
+ fpu_d3,
+ fpu_d4,
+ fpu_d5,
+ fpu_d6,
+ fpu_d7,
+ fpu_d8,
+ fpu_d9,
+ fpu_d10,
+ fpu_d11,
+ fpu_d12,
+ fpu_d13,
+ fpu_d14,
+ fpu_d15,
+ fpu_d16,
+ fpu_d17,
+ fpu_d18,
+ fpu_d19,
+ fpu_d20,
+ fpu_d21,
+ fpu_d22,
+ fpu_d23,
+ fpu_d24,
+ fpu_d25,
+ fpu_d26,
+ fpu_d27,
+ fpu_d28,
+ fpu_d29,
+ fpu_d30,
+ fpu_d31,
+
+ fpu_q0,
+ fpu_q1,
+ fpu_q2,
+ fpu_q3,
+ fpu_q4,
+ fpu_q5,
+ fpu_q6,
+ fpu_q7,
+ fpu_q8,
+ fpu_q9,
+ fpu_q10,
+ fpu_q11,
+ fpu_q12,
+ fpu_q13,
+ fpu_q14,
+ fpu_q15,
+
+ exc_exception,
+ exc_fsr,
+ exc_far,
+
+ dbg_bvr0,
+ dbg_bvr1,
+ dbg_bvr2,
+ dbg_bvr3,
+ dbg_bvr4,
+ dbg_bvr5,
+ dbg_bvr6,
+ dbg_bvr7,
+ dbg_bvr8,
+ dbg_bvr9,
+ dbg_bvr10,
+ dbg_bvr11,
+ dbg_bvr12,
+ dbg_bvr13,
+ dbg_bvr14,
+ dbg_bvr15,
+
+ dbg_bcr0,
+ dbg_bcr1,
+ dbg_bcr2,
+ dbg_bcr3,
+ dbg_bcr4,
+ dbg_bcr5,
+ dbg_bcr6,
+ dbg_bcr7,
+ dbg_bcr8,
+ dbg_bcr9,
+ dbg_bcr10,
+ dbg_bcr11,
+ dbg_bcr12,
+ dbg_bcr13,
+ dbg_bcr14,
+ dbg_bcr15,
+
+ dbg_wvr0,
+ dbg_wvr1,
+ dbg_wvr2,
+ dbg_wvr3,
+ dbg_wvr4,
+ dbg_wvr5,
+ dbg_wvr6,
+ dbg_wvr7,
+ dbg_wvr8,
+ dbg_wvr9,
+ dbg_wvr10,
+ dbg_wvr11,
+ dbg_wvr12,
+ dbg_wvr13,
+ dbg_wvr14,
+ dbg_wvr15,
+
+ dbg_wcr0,
+ dbg_wcr1,
+ dbg_wcr2,
+ dbg_wcr3,
+ dbg_wcr4,
+ dbg_wcr5,
+ dbg_wcr6,
+ dbg_wcr7,
+ dbg_wcr8,
+ dbg_wcr9,
+ dbg_wcr10,
+ dbg_wcr11,
+ dbg_wcr12,
+ dbg_wcr13,
+ dbg_wcr14,
+ dbg_wcr15,
+
+ k_num_registers
};
-static uint32_t g_s0_invalidates[] = { fpu_d0, fpu_q0, LLDB_INVALID_REGNUM };
-static uint32_t g_s1_invalidates[] = { fpu_d0, fpu_q0, LLDB_INVALID_REGNUM };
-static uint32_t g_s2_invalidates[] = { fpu_d1, fpu_q0, LLDB_INVALID_REGNUM };
-static uint32_t g_s3_invalidates[] = { fpu_d1, fpu_q0, LLDB_INVALID_REGNUM };
-static uint32_t g_s4_invalidates[] = { fpu_d2, fpu_q1, LLDB_INVALID_REGNUM };
-static uint32_t g_s5_invalidates[] = { fpu_d2, fpu_q1, LLDB_INVALID_REGNUM };
-static uint32_t g_s6_invalidates[] = { fpu_d3, fpu_q1, LLDB_INVALID_REGNUM };
-static uint32_t g_s7_invalidates[] = { fpu_d3, fpu_q1, LLDB_INVALID_REGNUM };
-static uint32_t g_s8_invalidates[] = { fpu_d4, fpu_q2, LLDB_INVALID_REGNUM };
-static uint32_t g_s9_invalidates[] = { fpu_d4, fpu_q2, LLDB_INVALID_REGNUM };
-static uint32_t g_s10_invalidates[] = { fpu_d5, fpu_q2, LLDB_INVALID_REGNUM };
-static uint32_t g_s11_invalidates[] = { fpu_d5, fpu_q2, LLDB_INVALID_REGNUM };
-static uint32_t g_s12_invalidates[] = { fpu_d6, fpu_q3, LLDB_INVALID_REGNUM };
-static uint32_t g_s13_invalidates[] = { fpu_d6, fpu_q3, LLDB_INVALID_REGNUM };
-static uint32_t g_s14_invalidates[] = { fpu_d7, fpu_q3, LLDB_INVALID_REGNUM };
-static uint32_t g_s15_invalidates[] = { fpu_d7, fpu_q3, LLDB_INVALID_REGNUM };
-static uint32_t g_s16_invalidates[] = { fpu_d8, fpu_q4, LLDB_INVALID_REGNUM };
-static uint32_t g_s17_invalidates[] = { fpu_d8, fpu_q4, LLDB_INVALID_REGNUM };
-static uint32_t g_s18_invalidates[] = { fpu_d9, fpu_q4, LLDB_INVALID_REGNUM };
-static uint32_t g_s19_invalidates[] = { fpu_d9, fpu_q4, LLDB_INVALID_REGNUM };
-static uint32_t g_s20_invalidates[] = { fpu_d10, fpu_q5, LLDB_INVALID_REGNUM };
-static uint32_t g_s21_invalidates[] = { fpu_d10, fpu_q5, LLDB_INVALID_REGNUM };
-static uint32_t g_s22_invalidates[] = { fpu_d11, fpu_q5, LLDB_INVALID_REGNUM };
-static uint32_t g_s23_invalidates[] = { fpu_d11, fpu_q5, LLDB_INVALID_REGNUM };
-static uint32_t g_s24_invalidates[] = { fpu_d12, fpu_q6, LLDB_INVALID_REGNUM };
-static uint32_t g_s25_invalidates[] = { fpu_d12, fpu_q6, LLDB_INVALID_REGNUM };
-static uint32_t g_s26_invalidates[] = { fpu_d13, fpu_q6, LLDB_INVALID_REGNUM };
-static uint32_t g_s27_invalidates[] = { fpu_d13, fpu_q6, LLDB_INVALID_REGNUM };
-static uint32_t g_s28_invalidates[] = { fpu_d14, fpu_q7, LLDB_INVALID_REGNUM };
-static uint32_t g_s29_invalidates[] = { fpu_d14, fpu_q7, LLDB_INVALID_REGNUM };
-static uint32_t g_s30_invalidates[] = { fpu_d15, fpu_q7, LLDB_INVALID_REGNUM };
-static uint32_t g_s31_invalidates[] = { fpu_d15, fpu_q7, LLDB_INVALID_REGNUM };
-
-static uint32_t g_d0_contains[] = { fpu_s0, fpu_s1, LLDB_INVALID_REGNUM };
-static uint32_t g_d1_contains[] = { fpu_s2, fpu_s3, LLDB_INVALID_REGNUM };
-static uint32_t g_d2_contains[] = { fpu_s4, fpu_s5, LLDB_INVALID_REGNUM };
-static uint32_t g_d3_contains[] = { fpu_s6, fpu_s7, LLDB_INVALID_REGNUM };
-static uint32_t g_d4_contains[] = { fpu_s8, fpu_s9, LLDB_INVALID_REGNUM };
-static uint32_t g_d5_contains[] = { fpu_s10, fpu_s11, LLDB_INVALID_REGNUM };
-static uint32_t g_d6_contains[] = { fpu_s12, fpu_s13, LLDB_INVALID_REGNUM };
-static uint32_t g_d7_contains[] = { fpu_s14, fpu_s15, LLDB_INVALID_REGNUM };
-static uint32_t g_d8_contains[] = { fpu_s16, fpu_s17, LLDB_INVALID_REGNUM };
-static uint32_t g_d9_contains[] = { fpu_s18, fpu_s19, LLDB_INVALID_REGNUM };
-static uint32_t g_d10_contains[] = { fpu_s20, fpu_s21, LLDB_INVALID_REGNUM };
-static uint32_t g_d11_contains[] = { fpu_s22, fpu_s23, LLDB_INVALID_REGNUM };
-static uint32_t g_d12_contains[] = { fpu_s24, fpu_s25, LLDB_INVALID_REGNUM };
-static uint32_t g_d13_contains[] = { fpu_s26, fpu_s27, LLDB_INVALID_REGNUM };
-static uint32_t g_d14_contains[] = { fpu_s28, fpu_s29, LLDB_INVALID_REGNUM };
-static uint32_t g_d15_contains[] = { fpu_s30, fpu_s31, LLDB_INVALID_REGNUM };
-
-static uint32_t g_d0_invalidates[] = { fpu_q0, LLDB_INVALID_REGNUM };
-static uint32_t g_d1_invalidates[] = { fpu_q0, LLDB_INVALID_REGNUM };
-static uint32_t g_d2_invalidates[] = { fpu_q1, LLDB_INVALID_REGNUM };
-static uint32_t g_d3_invalidates[] = { fpu_q1, LLDB_INVALID_REGNUM };
-static uint32_t g_d4_invalidates[] = { fpu_q2, LLDB_INVALID_REGNUM };
-static uint32_t g_d5_invalidates[] = { fpu_q2, LLDB_INVALID_REGNUM };
-static uint32_t g_d6_invalidates[] = { fpu_q3, LLDB_INVALID_REGNUM };
-static uint32_t g_d7_invalidates[] = { fpu_q3, LLDB_INVALID_REGNUM };
-static uint32_t g_d8_invalidates[] = { fpu_q4, LLDB_INVALID_REGNUM };
-static uint32_t g_d9_invalidates[] = { fpu_q4, LLDB_INVALID_REGNUM };
-static uint32_t g_d10_invalidates[] = { fpu_q5, LLDB_INVALID_REGNUM };
-static uint32_t g_d11_invalidates[] = { fpu_q5, LLDB_INVALID_REGNUM };
-static uint32_t g_d12_invalidates[] = { fpu_q6, LLDB_INVALID_REGNUM };
-static uint32_t g_d13_invalidates[] = { fpu_q6, LLDB_INVALID_REGNUM };
-static uint32_t g_d14_invalidates[] = { fpu_q7, LLDB_INVALID_REGNUM };
-static uint32_t g_d15_invalidates[] = { fpu_q7, LLDB_INVALID_REGNUM };
-static uint32_t g_d16_invalidates[] = { fpu_q8, LLDB_INVALID_REGNUM };
-static uint32_t g_d17_invalidates[] = { fpu_q8, LLDB_INVALID_REGNUM };
-static uint32_t g_d18_invalidates[] = { fpu_q9, LLDB_INVALID_REGNUM };
-static uint32_t g_d19_invalidates[] = { fpu_q9, LLDB_INVALID_REGNUM };
-static uint32_t g_d20_invalidates[] = { fpu_q10, LLDB_INVALID_REGNUM };
-static uint32_t g_d21_invalidates[] = { fpu_q10, LLDB_INVALID_REGNUM };
-static uint32_t g_d22_invalidates[] = { fpu_q11, LLDB_INVALID_REGNUM };
-static uint32_t g_d23_invalidates[] = { fpu_q11, LLDB_INVALID_REGNUM };
-static uint32_t g_d24_invalidates[] = { fpu_q12, LLDB_INVALID_REGNUM };
-static uint32_t g_d25_invalidates[] = { fpu_q12, LLDB_INVALID_REGNUM };
-static uint32_t g_d26_invalidates[] = { fpu_q13, LLDB_INVALID_REGNUM };
-static uint32_t g_d27_invalidates[] = { fpu_q13, LLDB_INVALID_REGNUM };
-static uint32_t g_d28_invalidates[] = { fpu_q14, LLDB_INVALID_REGNUM };
-static uint32_t g_d29_invalidates[] = { fpu_q14, LLDB_INVALID_REGNUM };
-static uint32_t g_d30_invalidates[] = { fpu_q15, LLDB_INVALID_REGNUM };
-static uint32_t g_d31_invalidates[] = { fpu_q15, LLDB_INVALID_REGNUM };
-
-static uint32_t g_q0_contains[] = { fpu_d0, fpu_d1, fpu_s0, fpu_s1, fpu_s2, fpu_s3, LLDB_INVALID_REGNUM };
-static uint32_t g_q1_contains[] = { fpu_d2, fpu_d3, fpu_s4, fpu_s5, fpu_s6, fpu_s7, LLDB_INVALID_REGNUM };
-static uint32_t g_q2_contains[] = { fpu_d4, fpu_d5, fpu_s8, fpu_s9, fpu_s10, fpu_s11, LLDB_INVALID_REGNUM };
-static uint32_t g_q3_contains[] = { fpu_d6, fpu_d7, fpu_s12, fpu_s13, fpu_s14, fpu_s15, LLDB_INVALID_REGNUM };
-static uint32_t g_q4_contains[] = { fpu_d8, fpu_d9, fpu_s16, fpu_s17, fpu_s18, fpu_s19, LLDB_INVALID_REGNUM };
-static uint32_t g_q5_contains[] = { fpu_d10, fpu_d11, fpu_s20, fpu_s21, fpu_s22, fpu_s23, LLDB_INVALID_REGNUM };
-static uint32_t g_q6_contains[] = { fpu_d12, fpu_d13, fpu_s24, fpu_s25, fpu_s26, fpu_s27, LLDB_INVALID_REGNUM };
-static uint32_t g_q7_contains[] = { fpu_d14, fpu_d15, fpu_s28, fpu_s29, fpu_s30, fpu_s31, LLDB_INVALID_REGNUM };
-static uint32_t g_q8_contains[] = { fpu_d16, fpu_d17, LLDB_INVALID_REGNUM };
-static uint32_t g_q9_contains[] = { fpu_d18, fpu_d19, LLDB_INVALID_REGNUM };
-static uint32_t g_q10_contains[] = { fpu_d20, fpu_d21, LLDB_INVALID_REGNUM };
-static uint32_t g_q11_contains[] = { fpu_d22, fpu_d23, LLDB_INVALID_REGNUM };
-static uint32_t g_q12_contains[] = { fpu_d24, fpu_d25, LLDB_INVALID_REGNUM };
-static uint32_t g_q13_contains[] = { fpu_d26, fpu_d27, LLDB_INVALID_REGNUM };
-static uint32_t g_q14_contains[] = { fpu_d28, fpu_d29, LLDB_INVALID_REGNUM };
-static uint32_t g_q15_contains[] = { fpu_d30, fpu_d31, LLDB_INVALID_REGNUM };
+static uint32_t g_s0_invalidates[] = {fpu_d0, fpu_q0, LLDB_INVALID_REGNUM};
+static uint32_t g_s1_invalidates[] = {fpu_d0, fpu_q0, LLDB_INVALID_REGNUM};
+static uint32_t g_s2_invalidates[] = {fpu_d1, fpu_q0, LLDB_INVALID_REGNUM};
+static uint32_t g_s3_invalidates[] = {fpu_d1, fpu_q0, LLDB_INVALID_REGNUM};
+static uint32_t g_s4_invalidates[] = {fpu_d2, fpu_q1, LLDB_INVALID_REGNUM};
+static uint32_t g_s5_invalidates[] = {fpu_d2, fpu_q1, LLDB_INVALID_REGNUM};
+static uint32_t g_s6_invalidates[] = {fpu_d3, fpu_q1, LLDB_INVALID_REGNUM};
+static uint32_t g_s7_invalidates[] = {fpu_d3, fpu_q1, LLDB_INVALID_REGNUM};
+static uint32_t g_s8_invalidates[] = {fpu_d4, fpu_q2, LLDB_INVALID_REGNUM};
+static uint32_t g_s9_invalidates[] = {fpu_d4, fpu_q2, LLDB_INVALID_REGNUM};
+static uint32_t g_s10_invalidates[] = {fpu_d5, fpu_q2, LLDB_INVALID_REGNUM};
+static uint32_t g_s11_invalidates[] = {fpu_d5, fpu_q2, LLDB_INVALID_REGNUM};
+static uint32_t g_s12_invalidates[] = {fpu_d6, fpu_q3, LLDB_INVALID_REGNUM};
+static uint32_t g_s13_invalidates[] = {fpu_d6, fpu_q3, LLDB_INVALID_REGNUM};
+static uint32_t g_s14_invalidates[] = {fpu_d7, fpu_q3, LLDB_INVALID_REGNUM};
+static uint32_t g_s15_invalidates[] = {fpu_d7, fpu_q3, LLDB_INVALID_REGNUM};
+static uint32_t g_s16_invalidates[] = {fpu_d8, fpu_q4, LLDB_INVALID_REGNUM};
+static uint32_t g_s17_invalidates[] = {fpu_d8, fpu_q4, LLDB_INVALID_REGNUM};
+static uint32_t g_s18_invalidates[] = {fpu_d9, fpu_q4, LLDB_INVALID_REGNUM};
+static uint32_t g_s19_invalidates[] = {fpu_d9, fpu_q4, LLDB_INVALID_REGNUM};
+static uint32_t g_s20_invalidates[] = {fpu_d10, fpu_q5, LLDB_INVALID_REGNUM};
+static uint32_t g_s21_invalidates[] = {fpu_d10, fpu_q5, LLDB_INVALID_REGNUM};
+static uint32_t g_s22_invalidates[] = {fpu_d11, fpu_q5, LLDB_INVALID_REGNUM};
+static uint32_t g_s23_invalidates[] = {fpu_d11, fpu_q5, LLDB_INVALID_REGNUM};
+static uint32_t g_s24_invalidates[] = {fpu_d12, fpu_q6, LLDB_INVALID_REGNUM};
+static uint32_t g_s25_invalidates[] = {fpu_d12, fpu_q6, LLDB_INVALID_REGNUM};
+static uint32_t g_s26_invalidates[] = {fpu_d13, fpu_q6, LLDB_INVALID_REGNUM};
+static uint32_t g_s27_invalidates[] = {fpu_d13, fpu_q6, LLDB_INVALID_REGNUM};
+static uint32_t g_s28_invalidates[] = {fpu_d14, fpu_q7, LLDB_INVALID_REGNUM};
+static uint32_t g_s29_invalidates[] = {fpu_d14, fpu_q7, LLDB_INVALID_REGNUM};
+static uint32_t g_s30_invalidates[] = {fpu_d15, fpu_q7, LLDB_INVALID_REGNUM};
+static uint32_t g_s31_invalidates[] = {fpu_d15, fpu_q7, LLDB_INVALID_REGNUM};
+
+static uint32_t g_d0_contains[] = {fpu_s0, fpu_s1, LLDB_INVALID_REGNUM};
+static uint32_t g_d1_contains[] = {fpu_s2, fpu_s3, LLDB_INVALID_REGNUM};
+static uint32_t g_d2_contains[] = {fpu_s4, fpu_s5, LLDB_INVALID_REGNUM};
+static uint32_t g_d3_contains[] = {fpu_s6, fpu_s7, LLDB_INVALID_REGNUM};
+static uint32_t g_d4_contains[] = {fpu_s8, fpu_s9, LLDB_INVALID_REGNUM};
+static uint32_t g_d5_contains[] = {fpu_s10, fpu_s11, LLDB_INVALID_REGNUM};
+static uint32_t g_d6_contains[] = {fpu_s12, fpu_s13, LLDB_INVALID_REGNUM};
+static uint32_t g_d7_contains[] = {fpu_s14, fpu_s15, LLDB_INVALID_REGNUM};
+static uint32_t g_d8_contains[] = {fpu_s16, fpu_s17, LLDB_INVALID_REGNUM};
+static uint32_t g_d9_contains[] = {fpu_s18, fpu_s19, LLDB_INVALID_REGNUM};
+static uint32_t g_d10_contains[] = {fpu_s20, fpu_s21, LLDB_INVALID_REGNUM};
+static uint32_t g_d11_contains[] = {fpu_s22, fpu_s23, LLDB_INVALID_REGNUM};
+static uint32_t g_d12_contains[] = {fpu_s24, fpu_s25, LLDB_INVALID_REGNUM};
+static uint32_t g_d13_contains[] = {fpu_s26, fpu_s27, LLDB_INVALID_REGNUM};
+static uint32_t g_d14_contains[] = {fpu_s28, fpu_s29, LLDB_INVALID_REGNUM};
+static uint32_t g_d15_contains[] = {fpu_s30, fpu_s31, LLDB_INVALID_REGNUM};
+
+static uint32_t g_d0_invalidates[] = {fpu_q0, LLDB_INVALID_REGNUM};
+static uint32_t g_d1_invalidates[] = {fpu_q0, LLDB_INVALID_REGNUM};
+static uint32_t g_d2_invalidates[] = {fpu_q1, LLDB_INVALID_REGNUM};
+static uint32_t g_d3_invalidates[] = {fpu_q1, LLDB_INVALID_REGNUM};
+static uint32_t g_d4_invalidates[] = {fpu_q2, LLDB_INVALID_REGNUM};
+static uint32_t g_d5_invalidates[] = {fpu_q2, LLDB_INVALID_REGNUM};
+static uint32_t g_d6_invalidates[] = {fpu_q3, LLDB_INVALID_REGNUM};
+static uint32_t g_d7_invalidates[] = {fpu_q3, LLDB_INVALID_REGNUM};
+static uint32_t g_d8_invalidates[] = {fpu_q4, LLDB_INVALID_REGNUM};
+static uint32_t g_d9_invalidates[] = {fpu_q4, LLDB_INVALID_REGNUM};
+static uint32_t g_d10_invalidates[] = {fpu_q5, LLDB_INVALID_REGNUM};
+static uint32_t g_d11_invalidates[] = {fpu_q5, LLDB_INVALID_REGNUM};
+static uint32_t g_d12_invalidates[] = {fpu_q6, LLDB_INVALID_REGNUM};
+static uint32_t g_d13_invalidates[] = {fpu_q6, LLDB_INVALID_REGNUM};
+static uint32_t g_d14_invalidates[] = {fpu_q7, LLDB_INVALID_REGNUM};
+static uint32_t g_d15_invalidates[] = {fpu_q7, LLDB_INVALID_REGNUM};
+static uint32_t g_d16_invalidates[] = {fpu_q8, LLDB_INVALID_REGNUM};
+static uint32_t g_d17_invalidates[] = {fpu_q8, LLDB_INVALID_REGNUM};
+static uint32_t g_d18_invalidates[] = {fpu_q9, LLDB_INVALID_REGNUM};
+static uint32_t g_d19_invalidates[] = {fpu_q9, LLDB_INVALID_REGNUM};
+static uint32_t g_d20_invalidates[] = {fpu_q10, LLDB_INVALID_REGNUM};
+static uint32_t g_d21_invalidates[] = {fpu_q10, LLDB_INVALID_REGNUM};
+static uint32_t g_d22_invalidates[] = {fpu_q11, LLDB_INVALID_REGNUM};
+static uint32_t g_d23_invalidates[] = {fpu_q11, LLDB_INVALID_REGNUM};
+static uint32_t g_d24_invalidates[] = {fpu_q12, LLDB_INVALID_REGNUM};
+static uint32_t g_d25_invalidates[] = {fpu_q12, LLDB_INVALID_REGNUM};
+static uint32_t g_d26_invalidates[] = {fpu_q13, LLDB_INVALID_REGNUM};
+static uint32_t g_d27_invalidates[] = {fpu_q13, LLDB_INVALID_REGNUM};
+static uint32_t g_d28_invalidates[] = {fpu_q14, LLDB_INVALID_REGNUM};
+static uint32_t g_d29_invalidates[] = {fpu_q14, LLDB_INVALID_REGNUM};
+static uint32_t g_d30_invalidates[] = {fpu_q15, LLDB_INVALID_REGNUM};
+static uint32_t g_d31_invalidates[] = {fpu_q15, LLDB_INVALID_REGNUM};
+
+static uint32_t g_q0_contains[] = {
+ fpu_d0, fpu_d1, fpu_s0, fpu_s1, fpu_s2, fpu_s3, LLDB_INVALID_REGNUM};
+static uint32_t g_q1_contains[] = {
+ fpu_d2, fpu_d3, fpu_s4, fpu_s5, fpu_s6, fpu_s7, LLDB_INVALID_REGNUM};
+static uint32_t g_q2_contains[] = {
+ fpu_d4, fpu_d5, fpu_s8, fpu_s9, fpu_s10, fpu_s11, LLDB_INVALID_REGNUM};
+static uint32_t g_q3_contains[] = {
+ fpu_d6, fpu_d7, fpu_s12, fpu_s13, fpu_s14, fpu_s15, LLDB_INVALID_REGNUM};
+static uint32_t g_q4_contains[] = {
+ fpu_d8, fpu_d9, fpu_s16, fpu_s17, fpu_s18, fpu_s19, LLDB_INVALID_REGNUM};
+static uint32_t g_q5_contains[] = {
+ fpu_d10, fpu_d11, fpu_s20, fpu_s21, fpu_s22, fpu_s23, LLDB_INVALID_REGNUM};
+static uint32_t g_q6_contains[] = {
+ fpu_d12, fpu_d13, fpu_s24, fpu_s25, fpu_s26, fpu_s27, LLDB_INVALID_REGNUM};
+static uint32_t g_q7_contains[] = {
+ fpu_d14, fpu_d15, fpu_s28, fpu_s29, fpu_s30, fpu_s31, LLDB_INVALID_REGNUM};
+static uint32_t g_q8_contains[] = {fpu_d16, fpu_d17, LLDB_INVALID_REGNUM};
+static uint32_t g_q9_contains[] = {fpu_d18, fpu_d19, LLDB_INVALID_REGNUM};
+static uint32_t g_q10_contains[] = {fpu_d20, fpu_d21, LLDB_INVALID_REGNUM};
+static uint32_t g_q11_contains[] = {fpu_d22, fpu_d23, LLDB_INVALID_REGNUM};
+static uint32_t g_q12_contains[] = {fpu_d24, fpu_d25, LLDB_INVALID_REGNUM};
+static uint32_t g_q13_contains[] = {fpu_d26, fpu_d27, LLDB_INVALID_REGNUM};
+static uint32_t g_q14_contains[] = {fpu_d28, fpu_d29, LLDB_INVALID_REGNUM};
+static uint32_t g_q15_contains[] = {fpu_d30, fpu_d31, LLDB_INVALID_REGNUM};
static RegisterInfo g_register_infos_arm[] = {
-// NAME ALT SZ OFFSET ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB NATIVE VALUE REGS INVALIDATE REGS
-// =========== ======= == ============== ================ ==================== =================== =================== ========================== =================== ============= ============== =================
-{ "r0", nullptr, 4, GPR_OFFSET(0), eEncodingUint, eFormatHex, { ehframe_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, gpr_r0 }, nullptr, nullptr, nullptr, 0},
-{ "r1", nullptr, 4, GPR_OFFSET(1), eEncodingUint, eFormatHex, { ehframe_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, gpr_r1 }, nullptr, nullptr, nullptr, 0},
-{ "r2", nullptr, 4, GPR_OFFSET(2), eEncodingUint, eFormatHex, { ehframe_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, gpr_r2 }, nullptr, nullptr, nullptr, 0},
-{ "r3", nullptr, 4, GPR_OFFSET(3), eEncodingUint, eFormatHex, { ehframe_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, gpr_r3 }, nullptr, nullptr, nullptr, 0},
-{ "r4", nullptr, 4, GPR_OFFSET(4), eEncodingUint, eFormatHex, { ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r4 }, nullptr, nullptr, nullptr, 0},
-{ "r5", nullptr, 4, GPR_OFFSET(5), eEncodingUint, eFormatHex, { ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r5 }, nullptr, nullptr, nullptr, 0},
-{ "r6", nullptr, 4, GPR_OFFSET(6), eEncodingUint, eFormatHex, { ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r6 }, nullptr, nullptr, nullptr, 0},
-{ "r7", nullptr, 4, GPR_OFFSET(7), eEncodingUint, eFormatHex, { ehframe_r7, dwarf_r7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r7 }, nullptr, nullptr, nullptr, 0},
-{ "r8", nullptr, 4, GPR_OFFSET(8), eEncodingUint, eFormatHex, { ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r8 }, nullptr, nullptr, nullptr, 0},
-{ "r9", nullptr, 4, GPR_OFFSET(9), eEncodingUint, eFormatHex, { ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r9 }, nullptr, nullptr, nullptr, 0},
-{ "r10", nullptr, 4, GPR_OFFSET(10), eEncodingUint, eFormatHex, { ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r10 }, nullptr, nullptr, nullptr, 0},
-{ "r11", nullptr, 4, GPR_OFFSET(11), eEncodingUint, eFormatHex, { ehframe_r11, dwarf_r11, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, gpr_r11 }, nullptr, nullptr, nullptr, 0},
-{ "r12", nullptr, 4, GPR_OFFSET(12), eEncodingUint, eFormatHex, { ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r12 }, nullptr, nullptr, nullptr, 0},
-{ "sp", "r13", 4, GPR_OFFSET(13), eEncodingUint, eFormatHex, { ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, gpr_sp }, nullptr, nullptr, nullptr, 0},
-{ "lr", "r14", 4, GPR_OFFSET(14), eEncodingUint, eFormatHex, { ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, gpr_lr }, nullptr, nullptr, nullptr, 0},
-{ "pc", "r15", 4, GPR_OFFSET(15), eEncodingUint, eFormatHex, { ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, gpr_pc }, nullptr, nullptr, nullptr, 0},
-{ "cpsr", "psr", 4, GPR_OFFSET(16), eEncodingUint, eFormatHex, { ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, gpr_cpsr }, nullptr, nullptr, nullptr, 0},
-
-{ "s0", nullptr, 4, FPU_OFFSET(0), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s0 }, nullptr, g_s0_invalidates, nullptr, 0},
-{ "s1", nullptr, 4, FPU_OFFSET(1), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s1 }, nullptr, g_s1_invalidates, nullptr, 0},
-{ "s2", nullptr, 4, FPU_OFFSET(2), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s2 }, nullptr, g_s2_invalidates, nullptr, 0},
-{ "s3", nullptr, 4, FPU_OFFSET(3), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s3 }, nullptr, g_s3_invalidates, nullptr, 0},
-{ "s4", nullptr, 4, FPU_OFFSET(4), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s4 }, nullptr, g_s4_invalidates, nullptr, 0},
-{ "s5", nullptr, 4, FPU_OFFSET(5), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s5 }, nullptr, g_s5_invalidates, nullptr, 0},
-{ "s6", nullptr, 4, FPU_OFFSET(6), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s6 }, nullptr, g_s6_invalidates, nullptr, 0},
-{ "s7", nullptr, 4, FPU_OFFSET(7), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s7 }, nullptr, g_s7_invalidates, nullptr, 0},
-{ "s8", nullptr, 4, FPU_OFFSET(8), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s8 }, nullptr, g_s8_invalidates, nullptr, 0},
-{ "s9", nullptr, 4, FPU_OFFSET(9), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s9 }, nullptr, g_s9_invalidates, nullptr, 0},
-{ "s10", nullptr, 4, FPU_OFFSET(10), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s10 }, nullptr, g_s10_invalidates, nullptr, 0},
-{ "s11", nullptr, 4, FPU_OFFSET(11), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s11 }, nullptr, g_s11_invalidates, nullptr, 0},
-{ "s12", nullptr, 4, FPU_OFFSET(12), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s12 }, nullptr, g_s12_invalidates, nullptr, 0},
-{ "s13", nullptr, 4, FPU_OFFSET(13), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s13 }, nullptr, g_s13_invalidates, nullptr, 0},
-{ "s14", nullptr, 4, FPU_OFFSET(14), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s14 }, nullptr, g_s14_invalidates, nullptr, 0},
-{ "s15", nullptr, 4, FPU_OFFSET(15), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s15 }, nullptr, g_s15_invalidates, nullptr, 0},
-{ "s16", nullptr, 4, FPU_OFFSET(16), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s16 }, nullptr, g_s16_invalidates, nullptr, 0},
-{ "s17", nullptr, 4, FPU_OFFSET(17), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s17 }, nullptr, g_s17_invalidates, nullptr, 0},
-{ "s18", nullptr, 4, FPU_OFFSET(18), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s18 }, nullptr, g_s18_invalidates, nullptr, 0},
-{ "s19", nullptr, 4, FPU_OFFSET(19), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s19 }, nullptr, g_s19_invalidates, nullptr, 0},
-{ "s20", nullptr, 4, FPU_OFFSET(20), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s20 }, nullptr, g_s20_invalidates, nullptr, 0},
-{ "s21", nullptr, 4, FPU_OFFSET(21), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s21 }, nullptr, g_s21_invalidates, nullptr, 0},
-{ "s22", nullptr, 4, FPU_OFFSET(22), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s22 }, nullptr, g_s22_invalidates, nullptr, 0},
-{ "s23", nullptr, 4, FPU_OFFSET(23), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s23 }, nullptr, g_s23_invalidates, nullptr, 0},
-{ "s24", nullptr, 4, FPU_OFFSET(24), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s24 }, nullptr, g_s24_invalidates, nullptr, 0},
-{ "s25", nullptr, 4, FPU_OFFSET(25), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s25 }, nullptr, g_s25_invalidates, nullptr, 0},
-{ "s26", nullptr, 4, FPU_OFFSET(26), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s26 }, nullptr, g_s26_invalidates, nullptr, 0},
-{ "s27", nullptr, 4, FPU_OFFSET(27), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s27 }, nullptr, g_s27_invalidates, nullptr, 0},
-{ "s28", nullptr, 4, FPU_OFFSET(28), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s28 }, nullptr, g_s28_invalidates, nullptr, 0},
-{ "s29", nullptr, 4, FPU_OFFSET(29), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s29 }, nullptr, g_s29_invalidates, nullptr, 0},
-{ "s30", nullptr, 4, FPU_OFFSET(30), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s30 }, nullptr, g_s30_invalidates, nullptr, 0},
-{ "s31", nullptr, 4, FPU_OFFSET(31), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s31 }, nullptr, g_s31_invalidates, nullptr, 0},
-{ "fpscr", nullptr, 4, FPSCR_OFFSET, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_fpscr }, nullptr, nullptr, nullptr, 0},
-
-{ "d0", nullptr, 8, FPU_OFFSET(0), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d0 }, g_d0_contains, g_d0_invalidates, nullptr, 0},
-{ "d1", nullptr, 8, FPU_OFFSET(2), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d1 }, g_d1_contains, g_d1_invalidates, nullptr, 0},
-{ "d2", nullptr, 8, FPU_OFFSET(4), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d2 }, g_d2_contains, g_d2_invalidates, nullptr, 0},
-{ "d3", nullptr, 8, FPU_OFFSET(6), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d3 }, g_d3_contains, g_d3_invalidates, nullptr, 0},
-{ "d4", nullptr, 8, FPU_OFFSET(8), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d4 }, g_d4_contains, g_d4_invalidates, nullptr, 0},
-{ "d5", nullptr, 8, FPU_OFFSET(10), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d5 }, g_d5_contains, g_d5_invalidates, nullptr, 0},
-{ "d6", nullptr, 8, FPU_OFFSET(12), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d6 }, g_d6_contains, g_d6_invalidates, nullptr, 0},
-{ "d7", nullptr, 8, FPU_OFFSET(14), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d7 }, g_d7_contains, g_d7_invalidates, nullptr, 0},
-{ "d8", nullptr, 8, FPU_OFFSET(16), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d8 }, g_d8_contains, g_d8_invalidates, nullptr, 0},
-{ "d9", nullptr, 8, FPU_OFFSET(18), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d9 }, g_d9_contains, g_d9_invalidates, nullptr, 0},
-{ "d10", nullptr, 8, FPU_OFFSET(20), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d10 }, g_d10_contains, g_d10_invalidates, nullptr, 0},
-{ "d11", nullptr, 8, FPU_OFFSET(22), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d11 }, g_d11_contains, g_d11_invalidates, nullptr, 0},
-{ "d12", nullptr, 8, FPU_OFFSET(24), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d12 }, g_d12_contains, g_d12_invalidates, nullptr, 0},
-{ "d13", nullptr, 8, FPU_OFFSET(26), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d13 }, g_d13_contains, g_d13_invalidates, nullptr, 0},
-{ "d14", nullptr, 8, FPU_OFFSET(28), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d14 }, g_d14_contains, g_d14_invalidates, nullptr, 0},
-{ "d15", nullptr, 8, FPU_OFFSET(30), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d15 }, g_d15_contains, g_d15_invalidates, nullptr, 0},
-{ "d16", nullptr, 8, FPU_OFFSET(32), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d16 }, nullptr, g_d16_invalidates, nullptr, 0 },
-{ "d17", nullptr, 8, FPU_OFFSET(34), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d17 }, nullptr, g_d17_invalidates, nullptr, 0},
-{ "d18", nullptr, 8, FPU_OFFSET(36), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d18 }, nullptr, g_d18_invalidates, nullptr, 0},
-{ "d19", nullptr, 8, FPU_OFFSET(38), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d19 }, nullptr, g_d19_invalidates, nullptr, 0},
-{ "d20", nullptr, 8, FPU_OFFSET(40), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d20 }, nullptr, g_d20_invalidates, nullptr, 0},
-{ "d21", nullptr, 8, FPU_OFFSET(42), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d21 }, nullptr, g_d21_invalidates, nullptr, 0},
-{ "d22", nullptr, 8, FPU_OFFSET(44), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d22 }, nullptr, g_d22_invalidates, nullptr, 0},
-{ "d23", nullptr, 8, FPU_OFFSET(46), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d23 }, nullptr, g_d23_invalidates, nullptr, 0},
-{ "d24", nullptr, 8, FPU_OFFSET(48), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d24 }, nullptr, g_d24_invalidates, nullptr, 0},
-{ "d25", nullptr, 8, FPU_OFFSET(50), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d25 }, nullptr, g_d25_invalidates, nullptr, 0},
-{ "d26", nullptr, 8, FPU_OFFSET(52), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d26 }, nullptr, g_d26_invalidates, nullptr, 0},
-{ "d27", nullptr, 8, FPU_OFFSET(54), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d27 }, nullptr, g_d27_invalidates, nullptr, 0},
-{ "d28", nullptr, 8, FPU_OFFSET(56), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d28 }, nullptr, g_d28_invalidates, nullptr, 0},
-{ "d29", nullptr, 8, FPU_OFFSET(58), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d29 }, nullptr, g_d29_invalidates, nullptr, 0},
-{ "d30", nullptr, 8, FPU_OFFSET(60), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d30 }, nullptr, g_d30_invalidates, nullptr, 0},
-{ "d31", nullptr, 8, FPU_OFFSET(62), eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d31 }, nullptr, g_d31_invalidates, nullptr, 0},
-
-{ "q0", nullptr, 16, FPU_OFFSET(0), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_q0 }, g_q0_contains, nullptr, nullptr, 0},
-{ "q1", nullptr, 16, FPU_OFFSET(4), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_q1 }, g_q1_contains, nullptr, nullptr, 0},
-{ "q2", nullptr, 16, FPU_OFFSET(8), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_q2 }, g_q2_contains, nullptr, nullptr, 0},
-{ "q3", nullptr, 16, FPU_OFFSET(12), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_q3 }, g_q3_contains, nullptr, nullptr, 0},
-{ "q4", nullptr, 16, FPU_OFFSET(16), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_q4 }, g_q4_contains, nullptr, nullptr, 0},
-{ "q5", nullptr, 16, FPU_OFFSET(20), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_q5 }, g_q5_contains, nullptr, nullptr, 0},
-{ "q6", nullptr, 16, FPU_OFFSET(24), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_q6 }, g_q6_contains, nullptr, nullptr, 0},
-{ "q7", nullptr, 16, FPU_OFFSET(28), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_q7 }, g_q7_contains, nullptr, nullptr, 0},
-{ "q8", nullptr, 16, FPU_OFFSET(32), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_q8 }, g_q8_contains, nullptr, nullptr, 0},
-{ "q9", nullptr, 16, FPU_OFFSET(36), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_q9 }, g_q9_contains, nullptr, nullptr, 0},
-{ "q10", nullptr, 16, FPU_OFFSET(40), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_q10 }, g_q10_contains, nullptr, nullptr, 0},
-{ "q11", nullptr, 16, FPU_OFFSET(44), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_q11 }, g_q11_contains, nullptr, nullptr, 0},
-{ "q12", nullptr, 16, FPU_OFFSET(48), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_q12 }, g_q12_contains, nullptr, nullptr, 0},
-{ "q13", nullptr, 16, FPU_OFFSET(52), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_q13 }, g_q13_contains, nullptr, nullptr, 0},
-{ "q14", nullptr, 16, FPU_OFFSET(56), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_q14 }, g_q14_contains, nullptr, nullptr, 0},
-{ "q15", nullptr, 16, FPU_OFFSET(60), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_q15 }, g_q15_contains, nullptr, nullptr, 0},
-
-{ "exception", nullptr, 4, EXC_OFFSET(0), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_exception }, nullptr, nullptr, nullptr, 0},
-{ "fsr", nullptr, 4, EXC_OFFSET(1), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_fsr }, nullptr, nullptr, nullptr, 0},
-{ "far", nullptr, 4, EXC_OFFSET(2), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_far }, nullptr, nullptr, nullptr, 0},
-
-{ DEFINE_DBG (bvr, 0) },
-{ DEFINE_DBG (bvr, 1) },
-{ DEFINE_DBG (bvr, 2) },
-{ DEFINE_DBG (bvr, 3) },
-{ DEFINE_DBG (bvr, 4) },
-{ DEFINE_DBG (bvr, 5) },
-{ DEFINE_DBG (bvr, 6) },
-{ DEFINE_DBG (bvr, 7) },
-{ DEFINE_DBG (bvr, 8) },
-{ DEFINE_DBG (bvr, 9) },
-{ DEFINE_DBG (bvr, 10) },
-{ DEFINE_DBG (bvr, 11) },
-{ DEFINE_DBG (bvr, 12) },
-{ DEFINE_DBG (bvr, 13) },
-{ DEFINE_DBG (bvr, 14) },
-{ DEFINE_DBG (bvr, 15) },
-
-{ DEFINE_DBG (bcr, 0) },
-{ DEFINE_DBG (bcr, 1) },
-{ DEFINE_DBG (bcr, 2) },
-{ DEFINE_DBG (bcr, 3) },
-{ DEFINE_DBG (bcr, 4) },
-{ DEFINE_DBG (bcr, 5) },
-{ DEFINE_DBG (bcr, 6) },
-{ DEFINE_DBG (bcr, 7) },
-{ DEFINE_DBG (bcr, 8) },
-{ DEFINE_DBG (bcr, 9) },
-{ DEFINE_DBG (bcr, 10) },
-{ DEFINE_DBG (bcr, 11) },
-{ DEFINE_DBG (bcr, 12) },
-{ DEFINE_DBG (bcr, 13) },
-{ DEFINE_DBG (bcr, 14) },
-{ DEFINE_DBG (bcr, 15) },
-
-{ DEFINE_DBG (wvr, 0) },
-{ DEFINE_DBG (wvr, 1) },
-{ DEFINE_DBG (wvr, 2) },
-{ DEFINE_DBG (wvr, 3) },
-{ DEFINE_DBG (wvr, 4) },
-{ DEFINE_DBG (wvr, 5) },
-{ DEFINE_DBG (wvr, 6) },
-{ DEFINE_DBG (wvr, 7) },
-{ DEFINE_DBG (wvr, 8) },
-{ DEFINE_DBG (wvr, 9) },
-{ DEFINE_DBG (wvr, 10) },
-{ DEFINE_DBG (wvr, 11) },
-{ DEFINE_DBG (wvr, 12) },
-{ DEFINE_DBG (wvr, 13) },
-{ DEFINE_DBG (wvr, 14) },
-{ DEFINE_DBG (wvr, 15) },
-
-{ DEFINE_DBG (wcr, 0) },
-{ DEFINE_DBG (wcr, 1) },
-{ DEFINE_DBG (wcr, 2) },
-{ DEFINE_DBG (wcr, 3) },
-{ DEFINE_DBG (wcr, 4) },
-{ DEFINE_DBG (wcr, 5) },
-{ DEFINE_DBG (wcr, 6) },
-{ DEFINE_DBG (wcr, 7) },
-{ DEFINE_DBG (wcr, 8) },
-{ DEFINE_DBG (wcr, 9) },
-{ DEFINE_DBG (wcr, 10) },
-{ DEFINE_DBG (wcr, 11) },
-{ DEFINE_DBG (wcr, 12) },
-{ DEFINE_DBG (wcr, 13) },
-{ DEFINE_DBG (wcr, 14) },
-{ DEFINE_DBG (wcr, 15) }
-};
+ // NAME ALT SZ OFFSET ENCODING FORMAT
+ // EH_FRAME DWARF GENERIC
+ // PROCESS PLUGIN LLDB NATIVE VALUE REGS INVALIDATE REGS
+ // =========== ======= == ============== ================
+ // ==================== =================== ===================
+ // ========================== =================== =============
+ // ============== =================
+ {"r0",
+ nullptr,
+ 4,
+ GPR_OFFSET(0),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM,
+ gpr_r0},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r1",
+ nullptr,
+ 4,
+ GPR_OFFSET(1),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM,
+ gpr_r1},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r2",
+ nullptr,
+ 4,
+ GPR_OFFSET(2),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM,
+ gpr_r2},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r3",
+ nullptr,
+ 4,
+ GPR_OFFSET(3),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM,
+ gpr_r3},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r4",
+ nullptr,
+ 4,
+ GPR_OFFSET(4),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r4},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r5",
+ nullptr,
+ 4,
+ GPR_OFFSET(5),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r5},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r6",
+ nullptr,
+ 4,
+ GPR_OFFSET(6),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r6},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r7",
+ nullptr,
+ 4,
+ GPR_OFFSET(7),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r7, dwarf_r7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r7},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r8",
+ nullptr,
+ 4,
+ GPR_OFFSET(8),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r8},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r9",
+ nullptr,
+ 4,
+ GPR_OFFSET(9),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r9},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r10",
+ nullptr,
+ 4,
+ GPR_OFFSET(10),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ gpr_r10},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r11",
+ nullptr,
+ 4,
+ GPR_OFFSET(11),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r11, dwarf_r11, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
+ gpr_r11},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"r12",
+ nullptr,
+ 4,
+ GPR_OFFSET(12),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ gpr_r12},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"sp",
+ "r13",
+ 4,
+ GPR_OFFSET(13),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
+ gpr_sp},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"lr",
+ "r14",
+ 4,
+ GPR_OFFSET(14),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM,
+ gpr_lr},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"pc",
+ "r15",
+ 4,
+ GPR_OFFSET(15),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
+ gpr_pc},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"cpsr",
+ "psr",
+ 4,
+ GPR_OFFSET(16),
+ eEncodingUint,
+ eFormatHex,
+ {ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM,
+ gpr_cpsr},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+
+ {"s0",
+ nullptr,
+ 4,
+ FPU_OFFSET(0),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s0},
+ nullptr,
+ g_s0_invalidates,
+ nullptr,
+ 0},
+ {"s1",
+ nullptr,
+ 4,
+ FPU_OFFSET(1),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s1},
+ nullptr,
+ g_s1_invalidates,
+ nullptr,
+ 0},
+ {"s2",
+ nullptr,
+ 4,
+ FPU_OFFSET(2),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s2},
+ nullptr,
+ g_s2_invalidates,
+ nullptr,
+ 0},
+ {"s3",
+ nullptr,
+ 4,
+ FPU_OFFSET(3),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s3},
+ nullptr,
+ g_s3_invalidates,
+ nullptr,
+ 0},
+ {"s4",
+ nullptr,
+ 4,
+ FPU_OFFSET(4),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s4},
+ nullptr,
+ g_s4_invalidates,
+ nullptr,
+ 0},
+ {"s5",
+ nullptr,
+ 4,
+ FPU_OFFSET(5),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s5},
+ nullptr,
+ g_s5_invalidates,
+ nullptr,
+ 0},
+ {"s6",
+ nullptr,
+ 4,
+ FPU_OFFSET(6),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s6},
+ nullptr,
+ g_s6_invalidates,
+ nullptr,
+ 0},
+ {"s7",
+ nullptr,
+ 4,
+ FPU_OFFSET(7),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s7},
+ nullptr,
+ g_s7_invalidates,
+ nullptr,
+ 0},
+ {"s8",
+ nullptr,
+ 4,
+ FPU_OFFSET(8),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s8},
+ nullptr,
+ g_s8_invalidates,
+ nullptr,
+ 0},
+ {"s9",
+ nullptr,
+ 4,
+ FPU_OFFSET(9),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s9},
+ nullptr,
+ g_s9_invalidates,
+ nullptr,
+ 0},
+ {"s10",
+ nullptr,
+ 4,
+ FPU_OFFSET(10),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s10},
+ nullptr,
+ g_s10_invalidates,
+ nullptr,
+ 0},
+ {"s11",
+ nullptr,
+ 4,
+ FPU_OFFSET(11),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s11},
+ nullptr,
+ g_s11_invalidates,
+ nullptr,
+ 0},
+ {"s12",
+ nullptr,
+ 4,
+ FPU_OFFSET(12),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s12},
+ nullptr,
+ g_s12_invalidates,
+ nullptr,
+ 0},
+ {"s13",
+ nullptr,
+ 4,
+ FPU_OFFSET(13),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s13},
+ nullptr,
+ g_s13_invalidates,
+ nullptr,
+ 0},
+ {"s14",
+ nullptr,
+ 4,
+ FPU_OFFSET(14),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s14},
+ nullptr,
+ g_s14_invalidates,
+ nullptr,
+ 0},
+ {"s15",
+ nullptr,
+ 4,
+ FPU_OFFSET(15),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s15},
+ nullptr,
+ g_s15_invalidates,
+ nullptr,
+ 0},
+ {"s16",
+ nullptr,
+ 4,
+ FPU_OFFSET(16),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s16},
+ nullptr,
+ g_s16_invalidates,
+ nullptr,
+ 0},
+ {"s17",
+ nullptr,
+ 4,
+ FPU_OFFSET(17),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s17},
+ nullptr,
+ g_s17_invalidates,
+ nullptr,
+ 0},
+ {"s18",
+ nullptr,
+ 4,
+ FPU_OFFSET(18),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s18},
+ nullptr,
+ g_s18_invalidates,
+ nullptr,
+ 0},
+ {"s19",
+ nullptr,
+ 4,
+ FPU_OFFSET(19),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s19},
+ nullptr,
+ g_s19_invalidates,
+ nullptr,
+ 0},
+ {"s20",
+ nullptr,
+ 4,
+ FPU_OFFSET(20),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s20},
+ nullptr,
+ g_s20_invalidates,
+ nullptr,
+ 0},
+ {"s21",
+ nullptr,
+ 4,
+ FPU_OFFSET(21),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s21},
+ nullptr,
+ g_s21_invalidates,
+ nullptr,
+ 0},
+ {"s22",
+ nullptr,
+ 4,
+ FPU_OFFSET(22),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s22},
+ nullptr,
+ g_s22_invalidates,
+ nullptr,
+ 0},
+ {"s23",
+ nullptr,
+ 4,
+ FPU_OFFSET(23),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s23},
+ nullptr,
+ g_s23_invalidates,
+ nullptr,
+ 0},
+ {"s24",
+ nullptr,
+ 4,
+ FPU_OFFSET(24),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s24},
+ nullptr,
+ g_s24_invalidates,
+ nullptr,
+ 0},
+ {"s25",
+ nullptr,
+ 4,
+ FPU_OFFSET(25),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s25},
+ nullptr,
+ g_s25_invalidates,
+ nullptr,
+ 0},
+ {"s26",
+ nullptr,
+ 4,
+ FPU_OFFSET(26),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s26},
+ nullptr,
+ g_s26_invalidates,
+ nullptr,
+ 0},
+ {"s27",
+ nullptr,
+ 4,
+ FPU_OFFSET(27),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s27},
+ nullptr,
+ g_s27_invalidates,
+ nullptr,
+ 0},
+ {"s28",
+ nullptr,
+ 4,
+ FPU_OFFSET(28),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s28},
+ nullptr,
+ g_s28_invalidates,
+ nullptr,
+ 0},
+ {"s29",
+ nullptr,
+ 4,
+ FPU_OFFSET(29),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s29},
+ nullptr,
+ g_s29_invalidates,
+ nullptr,
+ 0},
+ {"s30",
+ nullptr,
+ 4,
+ FPU_OFFSET(30),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s30},
+ nullptr,
+ g_s30_invalidates,
+ nullptr,
+ 0},
+ {"s31",
+ nullptr,
+ 4,
+ FPU_OFFSET(31),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_s31},
+ nullptr,
+ g_s31_invalidates,
+ nullptr,
+ 0},
+ {"fpscr",
+ nullptr,
+ 4,
+ FPSCR_OFFSET,
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, fpu_fpscr},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+
+ {"d0",
+ nullptr,
+ 8,
+ FPU_OFFSET(0),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d0},
+ g_d0_contains,
+ g_d0_invalidates,
+ nullptr,
+ 0},
+ {"d1",
+ nullptr,
+ 8,
+ FPU_OFFSET(2),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d1},
+ g_d1_contains,
+ g_d1_invalidates,
+ nullptr,
+ 0},
+ {"d2",
+ nullptr,
+ 8,
+ FPU_OFFSET(4),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d2},
+ g_d2_contains,
+ g_d2_invalidates,
+ nullptr,
+ 0},
+ {"d3",
+ nullptr,
+ 8,
+ FPU_OFFSET(6),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d3},
+ g_d3_contains,
+ g_d3_invalidates,
+ nullptr,
+ 0},
+ {"d4",
+ nullptr,
+ 8,
+ FPU_OFFSET(8),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d4},
+ g_d4_contains,
+ g_d4_invalidates,
+ nullptr,
+ 0},
+ {"d5",
+ nullptr,
+ 8,
+ FPU_OFFSET(10),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d5},
+ g_d5_contains,
+ g_d5_invalidates,
+ nullptr,
+ 0},
+ {"d6",
+ nullptr,
+ 8,
+ FPU_OFFSET(12),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d6},
+ g_d6_contains,
+ g_d6_invalidates,
+ nullptr,
+ 0},
+ {"d7",
+ nullptr,
+ 8,
+ FPU_OFFSET(14),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d7},
+ g_d7_contains,
+ g_d7_invalidates,
+ nullptr,
+ 0},
+ {"d8",
+ nullptr,
+ 8,
+ FPU_OFFSET(16),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d8},
+ g_d8_contains,
+ g_d8_invalidates,
+ nullptr,
+ 0},
+ {"d9",
+ nullptr,
+ 8,
+ FPU_OFFSET(18),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d9},
+ g_d9_contains,
+ g_d9_invalidates,
+ nullptr,
+ 0},
+ {"d10",
+ nullptr,
+ 8,
+ FPU_OFFSET(20),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d10},
+ g_d10_contains,
+ g_d10_invalidates,
+ nullptr,
+ 0},
+ {"d11",
+ nullptr,
+ 8,
+ FPU_OFFSET(22),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d11},
+ g_d11_contains,
+ g_d11_invalidates,
+ nullptr,
+ 0},
+ {"d12",
+ nullptr,
+ 8,
+ FPU_OFFSET(24),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d12},
+ g_d12_contains,
+ g_d12_invalidates,
+ nullptr,
+ 0},
+ {"d13",
+ nullptr,
+ 8,
+ FPU_OFFSET(26),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d13},
+ g_d13_contains,
+ g_d13_invalidates,
+ nullptr,
+ 0},
+ {"d14",
+ nullptr,
+ 8,
+ FPU_OFFSET(28),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d14},
+ g_d14_contains,
+ g_d14_invalidates,
+ nullptr,
+ 0},
+ {"d15",
+ nullptr,
+ 8,
+ FPU_OFFSET(30),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d15},
+ g_d15_contains,
+ g_d15_invalidates,
+ nullptr,
+ 0},
+ {"d16",
+ nullptr,
+ 8,
+ FPU_OFFSET(32),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d16},
+ nullptr,
+ g_d16_invalidates,
+ nullptr,
+ 0},
+ {"d17",
+ nullptr,
+ 8,
+ FPU_OFFSET(34),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d17},
+ nullptr,
+ g_d17_invalidates,
+ nullptr,
+ 0},
+ {"d18",
+ nullptr,
+ 8,
+ FPU_OFFSET(36),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d18},
+ nullptr,
+ g_d18_invalidates,
+ nullptr,
+ 0},
+ {"d19",
+ nullptr,
+ 8,
+ FPU_OFFSET(38),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d19},
+ nullptr,
+ g_d19_invalidates,
+ nullptr,
+ 0},
+ {"d20",
+ nullptr,
+ 8,
+ FPU_OFFSET(40),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d20},
+ nullptr,
+ g_d20_invalidates,
+ nullptr,
+ 0},
+ {"d21",
+ nullptr,
+ 8,
+ FPU_OFFSET(42),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d21},
+ nullptr,
+ g_d21_invalidates,
+ nullptr,
+ 0},
+ {"d22",
+ nullptr,
+ 8,
+ FPU_OFFSET(44),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d22},
+ nullptr,
+ g_d22_invalidates,
+ nullptr,
+ 0},
+ {"d23",
+ nullptr,
+ 8,
+ FPU_OFFSET(46),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d23},
+ nullptr,
+ g_d23_invalidates,
+ nullptr,
+ 0},
+ {"d24",
+ nullptr,
+ 8,
+ FPU_OFFSET(48),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d24},
+ nullptr,
+ g_d24_invalidates,
+ nullptr,
+ 0},
+ {"d25",
+ nullptr,
+ 8,
+ FPU_OFFSET(50),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d25},
+ nullptr,
+ g_d25_invalidates,
+ nullptr,
+ 0},
+ {"d26",
+ nullptr,
+ 8,
+ FPU_OFFSET(52),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d26},
+ nullptr,
+ g_d26_invalidates,
+ nullptr,
+ 0},
+ {"d27",
+ nullptr,
+ 8,
+ FPU_OFFSET(54),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d27},
+ nullptr,
+ g_d27_invalidates,
+ nullptr,
+ 0},
+ {"d28",
+ nullptr,
+ 8,
+ FPU_OFFSET(56),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d28},
+ nullptr,
+ g_d28_invalidates,
+ nullptr,
+ 0},
+ {"d29",
+ nullptr,
+ 8,
+ FPU_OFFSET(58),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d29},
+ nullptr,
+ g_d29_invalidates,
+ nullptr,
+ 0},
+ {"d30",
+ nullptr,
+ 8,
+ FPU_OFFSET(60),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d30},
+ nullptr,
+ g_d30_invalidates,
+ nullptr,
+ 0},
+ {"d31",
+ nullptr,
+ 8,
+ FPU_OFFSET(62),
+ eEncodingIEEE754,
+ eFormatFloat,
+ {LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_d31},
+ nullptr,
+ g_d31_invalidates,
+ nullptr,
+ 0},
+
+ {"q0",
+ nullptr,
+ 16,
+ FPU_OFFSET(0),
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_q0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_q0},
+ g_q0_contains,
+ nullptr,
+ nullptr,
+ 0},
+ {"q1",
+ nullptr,
+ 16,
+ FPU_OFFSET(4),
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_q1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_q1},
+ g_q1_contains,
+ nullptr,
+ nullptr,
+ 0},
+ {"q2",
+ nullptr,
+ 16,
+ FPU_OFFSET(8),
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_q2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_q2},
+ g_q2_contains,
+ nullptr,
+ nullptr,
+ 0},
+ {"q3",
+ nullptr,
+ 16,
+ FPU_OFFSET(12),
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_q3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_q3},
+ g_q3_contains,
+ nullptr,
+ nullptr,
+ 0},
+ {"q4",
+ nullptr,
+ 16,
+ FPU_OFFSET(16),
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_q4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_q4},
+ g_q4_contains,
+ nullptr,
+ nullptr,
+ 0},
+ {"q5",
+ nullptr,
+ 16,
+ FPU_OFFSET(20),
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_q5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_q5},
+ g_q5_contains,
+ nullptr,
+ nullptr,
+ 0},
+ {"q6",
+ nullptr,
+ 16,
+ FPU_OFFSET(24),
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_q6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_q6},
+ g_q6_contains,
+ nullptr,
+ nullptr,
+ 0},
+ {"q7",
+ nullptr,
+ 16,
+ FPU_OFFSET(28),
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_q7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_q7},
+ g_q7_contains,
+ nullptr,
+ nullptr,
+ 0},
+ {"q8",
+ nullptr,
+ 16,
+ FPU_OFFSET(32),
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_q8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_q8},
+ g_q8_contains,
+ nullptr,
+ nullptr,
+ 0},
+ {"q9",
+ nullptr,
+ 16,
+ FPU_OFFSET(36),
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_q9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_q9},
+ g_q9_contains,
+ nullptr,
+ nullptr,
+ 0},
+ {"q10",
+ nullptr,
+ 16,
+ FPU_OFFSET(40),
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_q10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_q10},
+ g_q10_contains,
+ nullptr,
+ nullptr,
+ 0},
+ {"q11",
+ nullptr,
+ 16,
+ FPU_OFFSET(44),
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_q11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_q11},
+ g_q11_contains,
+ nullptr,
+ nullptr,
+ 0},
+ {"q12",
+ nullptr,
+ 16,
+ FPU_OFFSET(48),
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_q12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_q12},
+ g_q12_contains,
+ nullptr,
+ nullptr,
+ 0},
+ {"q13",
+ nullptr,
+ 16,
+ FPU_OFFSET(52),
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_q13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_q13},
+ g_q13_contains,
+ nullptr,
+ nullptr,
+ 0},
+ {"q14",
+ nullptr,
+ 16,
+ FPU_OFFSET(56),
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_q14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_q14},
+ g_q14_contains,
+ nullptr,
+ nullptr,
+ 0},
+ {"q15",
+ nullptr,
+ 16,
+ FPU_OFFSET(60),
+ eEncodingVector,
+ eFormatVectorOfUInt8,
+ {LLDB_INVALID_REGNUM, dwarf_q15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ fpu_q15},
+ g_q15_contains,
+ nullptr,
+ nullptr,
+ 0},
+
+ {"exception",
+ nullptr,
+ 4,
+ EXC_OFFSET(0),
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, exc_exception},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fsr",
+ nullptr,
+ 4,
+ EXC_OFFSET(1),
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, exc_fsr},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"far",
+ nullptr,
+ 4,
+ EXC_OFFSET(2),
+ eEncodingUint,
+ eFormatHex,
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, exc_far},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+
+ {DEFINE_DBG(bvr, 0)},
+ {DEFINE_DBG(bvr, 1)},
+ {DEFINE_DBG(bvr, 2)},
+ {DEFINE_DBG(bvr, 3)},
+ {DEFINE_DBG(bvr, 4)},
+ {DEFINE_DBG(bvr, 5)},
+ {DEFINE_DBG(bvr, 6)},
+ {DEFINE_DBG(bvr, 7)},
+ {DEFINE_DBG(bvr, 8)},
+ {DEFINE_DBG(bvr, 9)},
+ {DEFINE_DBG(bvr, 10)},
+ {DEFINE_DBG(bvr, 11)},
+ {DEFINE_DBG(bvr, 12)},
+ {DEFINE_DBG(bvr, 13)},
+ {DEFINE_DBG(bvr, 14)},
+ {DEFINE_DBG(bvr, 15)},
+
+ {DEFINE_DBG(bcr, 0)},
+ {DEFINE_DBG(bcr, 1)},
+ {DEFINE_DBG(bcr, 2)},
+ {DEFINE_DBG(bcr, 3)},
+ {DEFINE_DBG(bcr, 4)},
+ {DEFINE_DBG(bcr, 5)},
+ {DEFINE_DBG(bcr, 6)},
+ {DEFINE_DBG(bcr, 7)},
+ {DEFINE_DBG(bcr, 8)},
+ {DEFINE_DBG(bcr, 9)},
+ {DEFINE_DBG(bcr, 10)},
+ {DEFINE_DBG(bcr, 11)},
+ {DEFINE_DBG(bcr, 12)},
+ {DEFINE_DBG(bcr, 13)},
+ {DEFINE_DBG(bcr, 14)},
+ {DEFINE_DBG(bcr, 15)},
+
+ {DEFINE_DBG(wvr, 0)},
+ {DEFINE_DBG(wvr, 1)},
+ {DEFINE_DBG(wvr, 2)},
+ {DEFINE_DBG(wvr, 3)},
+ {DEFINE_DBG(wvr, 4)},
+ {DEFINE_DBG(wvr, 5)},
+ {DEFINE_DBG(wvr, 6)},
+ {DEFINE_DBG(wvr, 7)},
+ {DEFINE_DBG(wvr, 8)},
+ {DEFINE_DBG(wvr, 9)},
+ {DEFINE_DBG(wvr, 10)},
+ {DEFINE_DBG(wvr, 11)},
+ {DEFINE_DBG(wvr, 12)},
+ {DEFINE_DBG(wvr, 13)},
+ {DEFINE_DBG(wvr, 14)},
+ {DEFINE_DBG(wvr, 15)},
+
+ {DEFINE_DBG(wcr, 0)},
+ {DEFINE_DBG(wcr, 1)},
+ {DEFINE_DBG(wcr, 2)},
+ {DEFINE_DBG(wcr, 3)},
+ {DEFINE_DBG(wcr, 4)},
+ {DEFINE_DBG(wcr, 5)},
+ {DEFINE_DBG(wcr, 6)},
+ {DEFINE_DBG(wcr, 7)},
+ {DEFINE_DBG(wcr, 8)},
+ {DEFINE_DBG(wcr, 9)},
+ {DEFINE_DBG(wcr, 10)},
+ {DEFINE_DBG(wcr, 11)},
+ {DEFINE_DBG(wcr, 12)},
+ {DEFINE_DBG(wcr, 13)},
+ {DEFINE_DBG(wcr, 14)},
+ {DEFINE_DBG(wcr, 15)}};
#endif // DECLARE_REGISTER_INFOS_ARM_STRUCT
diff --git a/source/Plugins/Process/Utility/RegisterInfos_arm64.h b/source/Plugins/Process/Utility/RegisterInfos_arm64.h
index f360f25501e7..b996533791ff 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_arm64.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_arm64.h
@@ -15,9 +15,9 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/lldb-defines.h"
#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-private.h"
#include "Utility/ARM64_DWARF_Registers.h"
#include "Utility/ARM64_ehframe_Registers.h"
@@ -50,302 +50,668 @@
#error DEFINE_DBG must be defined before including this header file
#endif
-enum
-{
- gpr_x0 = 0,
- gpr_x1,
- gpr_x2,
- gpr_x3,
- gpr_x4,
- gpr_x5,
- gpr_x6,
- gpr_x7,
- gpr_x8,
- gpr_x9,
- gpr_x10,
- gpr_x11,
- gpr_x12,
- gpr_x13,
- gpr_x14,
- gpr_x15,
- gpr_x16,
- gpr_x17,
- gpr_x18,
- gpr_x19,
- gpr_x20,
- gpr_x21,
- gpr_x22,
- gpr_x23,
- gpr_x24,
- gpr_x25,
- gpr_x26,
- gpr_x27,
- gpr_x28,
- gpr_x29 = 29, gpr_fp = gpr_x29,
- gpr_x30 = 30, gpr_lr = gpr_x30, gpr_ra = gpr_x30,
- gpr_x31 = 31, gpr_sp = gpr_x31,
- gpr_pc = 32,
- gpr_cpsr,
-
- fpu_v0,
- fpu_v1,
- fpu_v2,
- fpu_v3,
- fpu_v4,
- fpu_v5,
- fpu_v6,
- fpu_v7,
- fpu_v8,
- fpu_v9,
- fpu_v10,
- fpu_v11,
- fpu_v12,
- fpu_v13,
- fpu_v14,
- fpu_v15,
- fpu_v16,
- fpu_v17,
- fpu_v18,
- fpu_v19,
- fpu_v20,
- fpu_v21,
- fpu_v22,
- fpu_v23,
- fpu_v24,
- fpu_v25,
- fpu_v26,
- fpu_v27,
- fpu_v28,
- fpu_v29,
- fpu_v30,
- fpu_v31,
-
- fpu_fpsr,
- fpu_fpcr,
-
- exc_far,
- exc_esr,
- exc_exception,
-
- dbg_bvr0,
- dbg_bvr1,
- dbg_bvr2,
- dbg_bvr3,
- dbg_bvr4,
- dbg_bvr5,
- dbg_bvr6,
- dbg_bvr7,
- dbg_bvr8,
- dbg_bvr9,
- dbg_bvr10,
- dbg_bvr11,
- dbg_bvr12,
- dbg_bvr13,
- dbg_bvr14,
- dbg_bvr15,
-
- dbg_bcr0,
- dbg_bcr1,
- dbg_bcr2,
- dbg_bcr3,
- dbg_bcr4,
- dbg_bcr5,
- dbg_bcr6,
- dbg_bcr7,
- dbg_bcr8,
- dbg_bcr9,
- dbg_bcr10,
- dbg_bcr11,
- dbg_bcr12,
- dbg_bcr13,
- dbg_bcr14,
- dbg_bcr15,
-
- dbg_wvr0,
- dbg_wvr1,
- dbg_wvr2,
- dbg_wvr3,
- dbg_wvr4,
- dbg_wvr5,
- dbg_wvr6,
- dbg_wvr7,
- dbg_wvr8,
- dbg_wvr9,
- dbg_wvr10,
- dbg_wvr11,
- dbg_wvr12,
- dbg_wvr13,
- dbg_wvr14,
- dbg_wvr15,
-
- dbg_wcr0,
- dbg_wcr1,
- dbg_wcr2,
- dbg_wcr3,
- dbg_wcr4,
- dbg_wcr5,
- dbg_wcr6,
- dbg_wcr7,
- dbg_wcr8,
- dbg_wcr9,
- dbg_wcr10,
- dbg_wcr11,
- dbg_wcr12,
- dbg_wcr13,
- dbg_wcr14,
- dbg_wcr15,
-
- k_num_registers
+// Offsets for a little-endian layout of the register context
+#define GPR_W_PSEUDO_REG_ENDIAN_OFFSET 0
+#define FPU_S_PSEUDO_REG_ENDIAN_OFFSET 0
+#define FPU_D_PSEUDO_REG_ENDIAN_OFFSET 0
+
+enum {
+ gpr_x0 = 0,
+ gpr_x1,
+ gpr_x2,
+ gpr_x3,
+ gpr_x4,
+ gpr_x5,
+ gpr_x6,
+ gpr_x7,
+ gpr_x8,
+ gpr_x9,
+ gpr_x10,
+ gpr_x11,
+ gpr_x12,
+ gpr_x13,
+ gpr_x14,
+ gpr_x15,
+ gpr_x16,
+ gpr_x17,
+ gpr_x18,
+ gpr_x19,
+ gpr_x20,
+ gpr_x21,
+ gpr_x22,
+ gpr_x23,
+ gpr_x24,
+ gpr_x25,
+ gpr_x26,
+ gpr_x27,
+ gpr_x28,
+ gpr_x29 = 29,
+ gpr_fp = gpr_x29,
+ gpr_x30 = 30,
+ gpr_lr = gpr_x30,
+ gpr_ra = gpr_x30,
+ gpr_x31 = 31,
+ gpr_sp = gpr_x31,
+ gpr_pc = 32,
+ gpr_cpsr,
+
+ gpr_w0,
+ gpr_w1,
+ gpr_w2,
+ gpr_w3,
+ gpr_w4,
+ gpr_w5,
+ gpr_w6,
+ gpr_w7,
+ gpr_w8,
+ gpr_w9,
+ gpr_w10,
+ gpr_w11,
+ gpr_w12,
+ gpr_w13,
+ gpr_w14,
+ gpr_w15,
+ gpr_w16,
+ gpr_w17,
+ gpr_w18,
+ gpr_w19,
+ gpr_w20,
+ gpr_w21,
+ gpr_w22,
+ gpr_w23,
+ gpr_w24,
+ gpr_w25,
+ gpr_w26,
+ gpr_w27,
+ gpr_w28,
+
+ fpu_v0,
+ fpu_v1,
+ fpu_v2,
+ fpu_v3,
+ fpu_v4,
+ fpu_v5,
+ fpu_v6,
+ fpu_v7,
+ fpu_v8,
+ fpu_v9,
+ fpu_v10,
+ fpu_v11,
+ fpu_v12,
+ fpu_v13,
+ fpu_v14,
+ fpu_v15,
+ fpu_v16,
+ fpu_v17,
+ fpu_v18,
+ fpu_v19,
+ fpu_v20,
+ fpu_v21,
+ fpu_v22,
+ fpu_v23,
+ fpu_v24,
+ fpu_v25,
+ fpu_v26,
+ fpu_v27,
+ fpu_v28,
+ fpu_v29,
+ fpu_v30,
+ fpu_v31,
+
+ fpu_s0,
+ fpu_s1,
+ fpu_s2,
+ fpu_s3,
+ fpu_s4,
+ fpu_s5,
+ fpu_s6,
+ fpu_s7,
+ fpu_s8,
+ fpu_s9,
+ fpu_s10,
+ fpu_s11,
+ fpu_s12,
+ fpu_s13,
+ fpu_s14,
+ fpu_s15,
+ fpu_s16,
+ fpu_s17,
+ fpu_s18,
+ fpu_s19,
+ fpu_s20,
+ fpu_s21,
+ fpu_s22,
+ fpu_s23,
+ fpu_s24,
+ fpu_s25,
+ fpu_s26,
+ fpu_s27,
+ fpu_s28,
+ fpu_s29,
+ fpu_s30,
+ fpu_s31,
+
+ fpu_d0,
+ fpu_d1,
+ fpu_d2,
+ fpu_d3,
+ fpu_d4,
+ fpu_d5,
+ fpu_d6,
+ fpu_d7,
+ fpu_d8,
+ fpu_d9,
+ fpu_d10,
+ fpu_d11,
+ fpu_d12,
+ fpu_d13,
+ fpu_d14,
+ fpu_d15,
+ fpu_d16,
+ fpu_d17,
+ fpu_d18,
+ fpu_d19,
+ fpu_d20,
+ fpu_d21,
+ fpu_d22,
+ fpu_d23,
+ fpu_d24,
+ fpu_d25,
+ fpu_d26,
+ fpu_d27,
+ fpu_d28,
+ fpu_d29,
+ fpu_d30,
+ fpu_d31,
+
+ fpu_fpsr,
+ fpu_fpcr,
+
+ exc_far,
+ exc_esr,
+ exc_exception,
+
+ dbg_bvr0,
+ dbg_bvr1,
+ dbg_bvr2,
+ dbg_bvr3,
+ dbg_bvr4,
+ dbg_bvr5,
+ dbg_bvr6,
+ dbg_bvr7,
+ dbg_bvr8,
+ dbg_bvr9,
+ dbg_bvr10,
+ dbg_bvr11,
+ dbg_bvr12,
+ dbg_bvr13,
+ dbg_bvr14,
+ dbg_bvr15,
+
+ dbg_bcr0,
+ dbg_bcr1,
+ dbg_bcr2,
+ dbg_bcr3,
+ dbg_bcr4,
+ dbg_bcr5,
+ dbg_bcr6,
+ dbg_bcr7,
+ dbg_bcr8,
+ dbg_bcr9,
+ dbg_bcr10,
+ dbg_bcr11,
+ dbg_bcr12,
+ dbg_bcr13,
+ dbg_bcr14,
+ dbg_bcr15,
+
+ dbg_wvr0,
+ dbg_wvr1,
+ dbg_wvr2,
+ dbg_wvr3,
+ dbg_wvr4,
+ dbg_wvr5,
+ dbg_wvr6,
+ dbg_wvr7,
+ dbg_wvr8,
+ dbg_wvr9,
+ dbg_wvr10,
+ dbg_wvr11,
+ dbg_wvr12,
+ dbg_wvr13,
+ dbg_wvr14,
+ dbg_wvr15,
+
+ dbg_wcr0,
+ dbg_wcr1,
+ dbg_wcr2,
+ dbg_wcr3,
+ dbg_wcr4,
+ dbg_wcr5,
+ dbg_wcr6,
+ dbg_wcr7,
+ dbg_wcr8,
+ dbg_wcr9,
+ dbg_wcr10,
+ dbg_wcr11,
+ dbg_wcr12,
+ dbg_wcr13,
+ dbg_wcr14,
+ dbg_wcr15,
+
+ k_num_registers
};
-static lldb_private::RegisterInfo g_register_infos_arm64[] = {
-// General purpose registers
-// NAME ALT SZ OFFSET ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB NATIVE VALUE REGS INVALIDATE REGS
-// ====== ======= == ============= ============= ============ =============== =============== ========================= ===================== ============= ========== ===============
-{ "x0", nullptr, 8, GPR_OFFSET(0), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x0, arm64_dwarf::x0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, gpr_x0 }, nullptr, nullptr, nullptr, 0},
-{ "x1", nullptr, 8, GPR_OFFSET(1), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x1, arm64_dwarf::x1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, gpr_x1 }, nullptr, nullptr, nullptr, 0},
-{ "x2", nullptr, 8, GPR_OFFSET(2), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x2, arm64_dwarf::x2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, gpr_x2 }, nullptr, nullptr, nullptr, 0},
-{ "x3", nullptr, 8, GPR_OFFSET(3), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x3, arm64_dwarf::x3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, gpr_x3 }, nullptr, nullptr, nullptr, 0},
-{ "x4", nullptr, 8, GPR_OFFSET(4), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x4, arm64_dwarf::x4, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM, gpr_x4 }, nullptr, nullptr, nullptr, 0},
-{ "x5", nullptr, 8, GPR_OFFSET(5), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x5, arm64_dwarf::x5, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM, gpr_x5 }, nullptr, nullptr, nullptr, 0},
-{ "x6", nullptr, 8, GPR_OFFSET(6), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x6, arm64_dwarf::x6, LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM, gpr_x6 }, nullptr, nullptr, nullptr, 0},
-{ "x7", nullptr, 8, GPR_OFFSET(7), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x7, arm64_dwarf::x7, LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM, gpr_x7 }, nullptr, nullptr, nullptr, 0},
-{ "x8", nullptr, 8, GPR_OFFSET(8), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x8, arm64_dwarf::x8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x8 }, nullptr, nullptr, nullptr, 0},
-{ "x9", nullptr, 8, GPR_OFFSET(9), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x9, arm64_dwarf::x9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x9 }, nullptr, nullptr, nullptr, 0},
-{ "x10", nullptr, 8, GPR_OFFSET(10), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x10, arm64_dwarf::x10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x10 }, nullptr, nullptr, nullptr, 0},
-{ "x11", nullptr, 8, GPR_OFFSET(11), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x11, arm64_dwarf::x11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x11 }, nullptr, nullptr, nullptr, 0},
-{ "x12", nullptr, 8, GPR_OFFSET(12), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x12, arm64_dwarf::x12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x12 }, nullptr, nullptr, nullptr, 0},
-{ "x13", nullptr, 8, GPR_OFFSET(13), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x13, arm64_dwarf::x13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x13 }, nullptr, nullptr, nullptr, 0},
-{ "x14", nullptr, 8, GPR_OFFSET(14), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x14, arm64_dwarf::x14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x14 }, nullptr, nullptr, nullptr, 0},
-{ "x15", nullptr, 8, GPR_OFFSET(15), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x15, arm64_dwarf::x15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x15 }, nullptr, nullptr, nullptr, 0},
-{ "x16", nullptr, 8, GPR_OFFSET(16), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x16, arm64_dwarf::x16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x16 }, nullptr, nullptr, nullptr, 0},
-{ "x17", nullptr, 8, GPR_OFFSET(17), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x17, arm64_dwarf::x17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x17 }, nullptr, nullptr, nullptr, 0},
-{ "x18", nullptr, 8, GPR_OFFSET(18), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x18, arm64_dwarf::x18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x18 }, nullptr, nullptr, nullptr, 0},
-{ "x19", nullptr, 8, GPR_OFFSET(19), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x19, arm64_dwarf::x19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x19 }, nullptr, nullptr, nullptr, 0},
-{ "x20", nullptr, 8, GPR_OFFSET(20), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x20, arm64_dwarf::x20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x20 }, nullptr, nullptr, nullptr, 0},
-{ "x21", nullptr, 8, GPR_OFFSET(21), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x21, arm64_dwarf::x21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x21 }, nullptr, nullptr, nullptr, 0},
-{ "x22", nullptr, 8, GPR_OFFSET(22), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x22, arm64_dwarf::x22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x22 }, nullptr, nullptr, nullptr, 0},
-{ "x23", nullptr, 8, GPR_OFFSET(23), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x23, arm64_dwarf::x23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x23 }, nullptr, nullptr, nullptr, 0},
-{ "x24", nullptr, 8, GPR_OFFSET(24), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x24, arm64_dwarf::x24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x24 }, nullptr, nullptr, nullptr, 0},
-{ "x25", nullptr, 8, GPR_OFFSET(25), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x25, arm64_dwarf::x25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x25 }, nullptr, nullptr, nullptr, 0},
-{ "x26", nullptr, 8, GPR_OFFSET(26), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x26, arm64_dwarf::x26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x26 }, nullptr, nullptr, nullptr, 0},
-{ "x27", nullptr, 8, GPR_OFFSET(27), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x27, arm64_dwarf::x27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x27 }, nullptr, nullptr, nullptr, 0},
-{ "x28", nullptr, 8, GPR_OFFSET(28), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::x28, arm64_dwarf::x28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x28 }, nullptr, nullptr, nullptr, 0},
-
-{ "fp", "x29", 8, GPR_OFFSET(29), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::fp, arm64_dwarf::fp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, gpr_fp }, nullptr, nullptr, nullptr, 0},
-{ "lr", "x30", 8, GPR_OFFSET(30), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::lr, arm64_dwarf::lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, gpr_lr }, nullptr, nullptr, nullptr, 0},
-{ "sp", "x31", 8, GPR_OFFSET(31), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::sp, arm64_dwarf::sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, gpr_sp }, nullptr, nullptr, nullptr, 0},
-{ "pc", nullptr, 8, GPR_OFFSET(32), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::pc, arm64_dwarf::pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, gpr_pc }, nullptr, nullptr, nullptr, 0},
-
-{ "cpsr", nullptr, 4, GPR_OFFSET_NAME(cpsr), lldb::eEncodingUint, lldb::eFormatHex, { arm64_ehframe::cpsr, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, gpr_cpsr }, nullptr, nullptr, nullptr, 0},
-
-{ "v0", nullptr, 16, FPU_OFFSET(0), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v0 }, nullptr, nullptr, nullptr, 0},
-{ "v1", nullptr, 16, FPU_OFFSET(1), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v1 }, nullptr, nullptr, nullptr, 0},
-{ "v2", nullptr, 16, FPU_OFFSET(2), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v2 }, nullptr, nullptr, nullptr, 0},
-{ "v3", nullptr, 16, FPU_OFFSET(3), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v3 }, nullptr, nullptr, nullptr, 0},
-{ "v4", nullptr, 16, FPU_OFFSET(4), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v4 }, nullptr, nullptr, nullptr, 0},
-{ "v5", nullptr, 16, FPU_OFFSET(5), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v5 }, nullptr, nullptr, nullptr, 0},
-{ "v6", nullptr, 16, FPU_OFFSET(6), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v6 }, nullptr, nullptr, nullptr, 0},
-{ "v7", nullptr, 16, FPU_OFFSET(7), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v7 }, nullptr, nullptr, nullptr, 0},
-{ "v8", nullptr, 16, FPU_OFFSET(8), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v8 }, nullptr, nullptr, nullptr, 0},
-{ "v9", nullptr, 16, FPU_OFFSET(9), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v9 }, nullptr, nullptr, nullptr, 0},
-{ "v10", nullptr, 16, FPU_OFFSET(10), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v10 }, nullptr, nullptr, nullptr, 0},
-{ "v11", nullptr, 16, FPU_OFFSET(11), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v11 }, nullptr, nullptr, nullptr, 0},
-{ "v12", nullptr, 16, FPU_OFFSET(12), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v12 }, nullptr, nullptr, nullptr, 0},
-{ "v13", nullptr, 16, FPU_OFFSET(13), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v13 }, nullptr, nullptr, nullptr, 0},
-{ "v14", nullptr, 16, FPU_OFFSET(14), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v14 }, nullptr, nullptr, nullptr, 0},
-{ "v15", nullptr, 16, FPU_OFFSET(15), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v15 }, nullptr, nullptr, nullptr, 0},
-{ "v16", nullptr, 16, FPU_OFFSET(16), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v16 }, nullptr, nullptr, nullptr, 0},
-{ "v17", nullptr, 16, FPU_OFFSET(17), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v17 }, nullptr, nullptr, nullptr, 0},
-{ "v18", nullptr, 16, FPU_OFFSET(18), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v18 }, nullptr, nullptr, nullptr, 0},
-{ "v19", nullptr, 16, FPU_OFFSET(19), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v19 }, nullptr, nullptr, nullptr, 0},
-{ "v20", nullptr, 16, FPU_OFFSET(20), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v20 }, nullptr, nullptr, nullptr, 0},
-{ "v21", nullptr, 16, FPU_OFFSET(21), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v21 }, nullptr, nullptr, nullptr, 0},
-{ "v22", nullptr, 16, FPU_OFFSET(22), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v22 }, nullptr, nullptr, nullptr, 0},
-{ "v23", nullptr, 16, FPU_OFFSET(23), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v23 }, nullptr, nullptr, nullptr, 0},
-{ "v24", nullptr, 16, FPU_OFFSET(24), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v24 }, nullptr, nullptr, nullptr, 0},
-{ "v25", nullptr, 16, FPU_OFFSET(25), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v25 }, nullptr, nullptr, nullptr, 0},
-{ "v26", nullptr, 16, FPU_OFFSET(26), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v26 }, nullptr, nullptr, nullptr, 0},
-{ "v27", nullptr, 16, FPU_OFFSET(27), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v27 }, nullptr, nullptr, nullptr, 0},
-{ "v28", nullptr, 16, FPU_OFFSET(28), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v28 }, nullptr, nullptr, nullptr, 0},
-{ "v29", nullptr, 16, FPU_OFFSET(29), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v29 }, nullptr, nullptr, nullptr, 0},
-{ "v30", nullptr, 16, FPU_OFFSET(30), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v30 }, nullptr, nullptr, nullptr, 0},
-{ "v31", nullptr, 16, FPU_OFFSET(31), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v31 }, nullptr, nullptr, nullptr, 0},
-
-{ "fpsr", nullptr, 4, FPU_OFFSET_NAME(fpsr), lldb::eEncodingUint, lldb::eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_fpsr }, nullptr, nullptr, nullptr, 0},
-{ "fpcr", nullptr, 4, FPU_OFFSET_NAME(fpcr), lldb::eEncodingUint, lldb::eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_fpcr }, nullptr, nullptr, nullptr, 0},
-
-{ "far", nullptr, 8, EXC_OFFSET_NAME(far), lldb::eEncodingUint, lldb::eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_far }, nullptr, nullptr, nullptr, 0},
-{ "esr", nullptr, 4, EXC_OFFSET_NAME(esr), lldb::eEncodingUint, lldb::eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_esr }, nullptr, nullptr, nullptr, 0},
-{ "exception",nullptr, 4, EXC_OFFSET_NAME(exception), lldb::eEncodingUint, lldb::eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_exception }, nullptr, nullptr, nullptr, 0},
-
-{ DEFINE_DBG (bvr, 0) },
-{ DEFINE_DBG (bvr, 1) },
-{ DEFINE_DBG (bvr, 2) },
-{ DEFINE_DBG (bvr, 3) },
-{ DEFINE_DBG (bvr, 4) },
-{ DEFINE_DBG (bvr, 5) },
-{ DEFINE_DBG (bvr, 6) },
-{ DEFINE_DBG (bvr, 7) },
-{ DEFINE_DBG (bvr, 8) },
-{ DEFINE_DBG (bvr, 9) },
-{ DEFINE_DBG (bvr, 10) },
-{ DEFINE_DBG (bvr, 11) },
-{ DEFINE_DBG (bvr, 12) },
-{ DEFINE_DBG (bvr, 13) },
-{ DEFINE_DBG (bvr, 14) },
-{ DEFINE_DBG (bvr, 15) },
-
-{ DEFINE_DBG (bcr, 0) },
-{ DEFINE_DBG (bcr, 1) },
-{ DEFINE_DBG (bcr, 2) },
-{ DEFINE_DBG (bcr, 3) },
-{ DEFINE_DBG (bcr, 4) },
-{ DEFINE_DBG (bcr, 5) },
-{ DEFINE_DBG (bcr, 6) },
-{ DEFINE_DBG (bcr, 7) },
-{ DEFINE_DBG (bcr, 8) },
-{ DEFINE_DBG (bcr, 9) },
-{ DEFINE_DBG (bcr, 10) },
-{ DEFINE_DBG (bcr, 11) },
-{ DEFINE_DBG (bcr, 12) },
-{ DEFINE_DBG (bcr, 13) },
-{ DEFINE_DBG (bcr, 14) },
-{ DEFINE_DBG (bcr, 15) },
-
-{ DEFINE_DBG (wvr, 0) },
-{ DEFINE_DBG (wvr, 1) },
-{ DEFINE_DBG (wvr, 2) },
-{ DEFINE_DBG (wvr, 3) },
-{ DEFINE_DBG (wvr, 4) },
-{ DEFINE_DBG (wvr, 5) },
-{ DEFINE_DBG (wvr, 6) },
-{ DEFINE_DBG (wvr, 7) },
-{ DEFINE_DBG (wvr, 8) },
-{ DEFINE_DBG (wvr, 9) },
-{ DEFINE_DBG (wvr, 10) },
-{ DEFINE_DBG (wvr, 11) },
-{ DEFINE_DBG (wvr, 12) },
-{ DEFINE_DBG (wvr, 13) },
-{ DEFINE_DBG (wvr, 14) },
-{ DEFINE_DBG (wvr, 15) },
-
-{ DEFINE_DBG (wcr, 0) },
-{ DEFINE_DBG (wcr, 1) },
-{ DEFINE_DBG (wcr, 2) },
-{ DEFINE_DBG (wcr, 3) },
-{ DEFINE_DBG (wcr, 4) },
-{ DEFINE_DBG (wcr, 5) },
-{ DEFINE_DBG (wcr, 6) },
-{ DEFINE_DBG (wcr, 7) },
-{ DEFINE_DBG (wcr, 8) },
-{ DEFINE_DBG (wcr, 9) },
-{ DEFINE_DBG (wcr, 10) },
-{ DEFINE_DBG (wcr, 11) },
-{ DEFINE_DBG (wcr, 12) },
-{ DEFINE_DBG (wcr, 13) },
-{ DEFINE_DBG (wcr, 14) },
-{ DEFINE_DBG (wcr, 15) }
+static uint32_t g_contained_x0[] = {gpr_x0, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x1[] = {gpr_x1, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x2[] = {gpr_x2, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x3[] = {gpr_x3, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x4[] = {gpr_x4, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x5[] = {gpr_x5, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x6[] = {gpr_x6, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x7[] = {gpr_x7, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x8[] = {gpr_x8, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x9[] = {gpr_x9, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x10[] = {gpr_x10, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x11[] = {gpr_x11, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x12[] = {gpr_x12, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x13[] = {gpr_x13, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x14[] = {gpr_x14, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x15[] = {gpr_x15, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x16[] = {gpr_x16, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x17[] = {gpr_x17, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x18[] = {gpr_x18, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x19[] = {gpr_x19, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x20[] = {gpr_x20, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x21[] = {gpr_x21, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x22[] = {gpr_x22, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x23[] = {gpr_x23, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x24[] = {gpr_x24, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x25[] = {gpr_x25, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x26[] = {gpr_x26, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x27[] = {gpr_x27, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_x28[] = {gpr_x28, LLDB_INVALID_REGNUM};
+
+static uint32_t g_w0_invalidates[] = {gpr_x0, LLDB_INVALID_REGNUM};
+static uint32_t g_w1_invalidates[] = {gpr_x1, LLDB_INVALID_REGNUM};
+static uint32_t g_w2_invalidates[] = {gpr_x2, LLDB_INVALID_REGNUM};
+static uint32_t g_w3_invalidates[] = {gpr_x3, LLDB_INVALID_REGNUM};
+static uint32_t g_w4_invalidates[] = {gpr_x4, LLDB_INVALID_REGNUM};
+static uint32_t g_w5_invalidates[] = {gpr_x5, LLDB_INVALID_REGNUM};
+static uint32_t g_w6_invalidates[] = {gpr_x6, LLDB_INVALID_REGNUM};
+static uint32_t g_w7_invalidates[] = {gpr_x7, LLDB_INVALID_REGNUM};
+static uint32_t g_w8_invalidates[] = {gpr_x8, LLDB_INVALID_REGNUM};
+static uint32_t g_w9_invalidates[] = {gpr_x9, LLDB_INVALID_REGNUM};
+static uint32_t g_w10_invalidates[] = {gpr_x10, LLDB_INVALID_REGNUM};
+static uint32_t g_w11_invalidates[] = {gpr_x11, LLDB_INVALID_REGNUM};
+static uint32_t g_w12_invalidates[] = {gpr_x12, LLDB_INVALID_REGNUM};
+static uint32_t g_w13_invalidates[] = {gpr_x13, LLDB_INVALID_REGNUM};
+static uint32_t g_w14_invalidates[] = {gpr_x14, LLDB_INVALID_REGNUM};
+static uint32_t g_w15_invalidates[] = {gpr_x15, LLDB_INVALID_REGNUM};
+static uint32_t g_w16_invalidates[] = {gpr_x16, LLDB_INVALID_REGNUM};
+static uint32_t g_w17_invalidates[] = {gpr_x17, LLDB_INVALID_REGNUM};
+static uint32_t g_w18_invalidates[] = {gpr_x18, LLDB_INVALID_REGNUM};
+static uint32_t g_w19_invalidates[] = {gpr_x19, LLDB_INVALID_REGNUM};
+static uint32_t g_w20_invalidates[] = {gpr_x20, LLDB_INVALID_REGNUM};
+static uint32_t g_w21_invalidates[] = {gpr_x21, LLDB_INVALID_REGNUM};
+static uint32_t g_w22_invalidates[] = {gpr_x22, LLDB_INVALID_REGNUM};
+static uint32_t g_w23_invalidates[] = {gpr_x23, LLDB_INVALID_REGNUM};
+static uint32_t g_w24_invalidates[] = {gpr_x24, LLDB_INVALID_REGNUM};
+static uint32_t g_w25_invalidates[] = {gpr_x25, LLDB_INVALID_REGNUM};
+static uint32_t g_w26_invalidates[] = {gpr_x26, LLDB_INVALID_REGNUM};
+static uint32_t g_w27_invalidates[] = {gpr_x27, LLDB_INVALID_REGNUM};
+static uint32_t g_w28_invalidates[] = {gpr_x28, LLDB_INVALID_REGNUM};
+
+static uint32_t g_contained_v0[] = {fpu_v0, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v1[] = {fpu_v1, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v2[] = {fpu_v2, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v3[] = {fpu_v3, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v4[] = {fpu_v4, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v5[] = {fpu_v5, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v6[] = {fpu_v6, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v7[] = {fpu_v7, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v8[] = {fpu_v8, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v9[] = {fpu_v9, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v10[] = {fpu_v10, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v11[] = {fpu_v11, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v12[] = {fpu_v12, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v13[] = {fpu_v13, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v14[] = {fpu_v14, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v15[] = {fpu_v15, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v16[] = {fpu_v16, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v17[] = {fpu_v17, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v18[] = {fpu_v18, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v19[] = {fpu_v19, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v20[] = {fpu_v20, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v21[] = {fpu_v21, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v22[] = {fpu_v22, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v23[] = {fpu_v23, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v24[] = {fpu_v24, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v25[] = {fpu_v25, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v26[] = {fpu_v26, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v27[] = {fpu_v27, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v28[] = {fpu_v28, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v29[] = {fpu_v29, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v30[] = {fpu_v30, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_v31[] = {fpu_v31, LLDB_INVALID_REGNUM};
+
+static uint32_t g_s0_invalidates[] = {fpu_v0, fpu_d0, LLDB_INVALID_REGNUM};
+static uint32_t g_s1_invalidates[] = {fpu_v1, fpu_d1, LLDB_INVALID_REGNUM};
+static uint32_t g_s2_invalidates[] = {fpu_v2, fpu_d2, LLDB_INVALID_REGNUM};
+static uint32_t g_s3_invalidates[] = {fpu_v3, fpu_d3, LLDB_INVALID_REGNUM};
+static uint32_t g_s4_invalidates[] = {fpu_v4, fpu_d4, LLDB_INVALID_REGNUM};
+static uint32_t g_s5_invalidates[] = {fpu_v5, fpu_d5, LLDB_INVALID_REGNUM};
+static uint32_t g_s6_invalidates[] = {fpu_v6, fpu_d6, LLDB_INVALID_REGNUM};
+static uint32_t g_s7_invalidates[] = {fpu_v7, fpu_d7, LLDB_INVALID_REGNUM};
+static uint32_t g_s8_invalidates[] = {fpu_v8, fpu_d8, LLDB_INVALID_REGNUM};
+static uint32_t g_s9_invalidates[] = {fpu_v9, fpu_d9, LLDB_INVALID_REGNUM};
+static uint32_t g_s10_invalidates[] = {fpu_v10, fpu_d10, LLDB_INVALID_REGNUM};
+static uint32_t g_s11_invalidates[] = {fpu_v11, fpu_d11, LLDB_INVALID_REGNUM};
+static uint32_t g_s12_invalidates[] = {fpu_v12, fpu_d12, LLDB_INVALID_REGNUM};
+static uint32_t g_s13_invalidates[] = {fpu_v13, fpu_d13, LLDB_INVALID_REGNUM};
+static uint32_t g_s14_invalidates[] = {fpu_v14, fpu_d14, LLDB_INVALID_REGNUM};
+static uint32_t g_s15_invalidates[] = {fpu_v15, fpu_d15, LLDB_INVALID_REGNUM};
+static uint32_t g_s16_invalidates[] = {fpu_v16, fpu_d16, LLDB_INVALID_REGNUM};
+static uint32_t g_s17_invalidates[] = {fpu_v17, fpu_d17, LLDB_INVALID_REGNUM};
+static uint32_t g_s18_invalidates[] = {fpu_v18, fpu_d18, LLDB_INVALID_REGNUM};
+static uint32_t g_s19_invalidates[] = {fpu_v19, fpu_d19, LLDB_INVALID_REGNUM};
+static uint32_t g_s20_invalidates[] = {fpu_v20, fpu_d20, LLDB_INVALID_REGNUM};
+static uint32_t g_s21_invalidates[] = {fpu_v21, fpu_d21, LLDB_INVALID_REGNUM};
+static uint32_t g_s22_invalidates[] = {fpu_v22, fpu_d22, LLDB_INVALID_REGNUM};
+static uint32_t g_s23_invalidates[] = {fpu_v23, fpu_d23, LLDB_INVALID_REGNUM};
+static uint32_t g_s24_invalidates[] = {fpu_v24, fpu_d24, LLDB_INVALID_REGNUM};
+static uint32_t g_s25_invalidates[] = {fpu_v25, fpu_d25, LLDB_INVALID_REGNUM};
+static uint32_t g_s26_invalidates[] = {fpu_v26, fpu_d26, LLDB_INVALID_REGNUM};
+static uint32_t g_s27_invalidates[] = {fpu_v27, fpu_d27, LLDB_INVALID_REGNUM};
+static uint32_t g_s28_invalidates[] = {fpu_v28, fpu_d28, LLDB_INVALID_REGNUM};
+static uint32_t g_s29_invalidates[] = {fpu_v29, fpu_d29, LLDB_INVALID_REGNUM};
+static uint32_t g_s30_invalidates[] = {fpu_v30, fpu_d30, LLDB_INVALID_REGNUM};
+static uint32_t g_s31_invalidates[] = {fpu_v31, fpu_d31, LLDB_INVALID_REGNUM};
+
+static uint32_t g_d0_invalidates[] = {fpu_v0, fpu_s0, LLDB_INVALID_REGNUM};
+static uint32_t g_d1_invalidates[] = {fpu_v1, fpu_s1, LLDB_INVALID_REGNUM};
+static uint32_t g_d2_invalidates[] = {fpu_v2, fpu_s2, LLDB_INVALID_REGNUM};
+static uint32_t g_d3_invalidates[] = {fpu_v3, fpu_s3, LLDB_INVALID_REGNUM};
+static uint32_t g_d4_invalidates[] = {fpu_v4, fpu_s4, LLDB_INVALID_REGNUM};
+static uint32_t g_d5_invalidates[] = {fpu_v5, fpu_s5, LLDB_INVALID_REGNUM};
+static uint32_t g_d6_invalidates[] = {fpu_v6, fpu_s6, LLDB_INVALID_REGNUM};
+static uint32_t g_d7_invalidates[] = {fpu_v7, fpu_s7, LLDB_INVALID_REGNUM};
+static uint32_t g_d8_invalidates[] = {fpu_v8, fpu_s8, LLDB_INVALID_REGNUM};
+static uint32_t g_d9_invalidates[] = {fpu_v9, fpu_s9, LLDB_INVALID_REGNUM};
+static uint32_t g_d10_invalidates[] = {fpu_v10, fpu_s10, LLDB_INVALID_REGNUM};
+static uint32_t g_d11_invalidates[] = {fpu_v11, fpu_s11, LLDB_INVALID_REGNUM};
+static uint32_t g_d12_invalidates[] = {fpu_v12, fpu_s12, LLDB_INVALID_REGNUM};
+static uint32_t g_d13_invalidates[] = {fpu_v13, fpu_s13, LLDB_INVALID_REGNUM};
+static uint32_t g_d14_invalidates[] = {fpu_v14, fpu_s14, LLDB_INVALID_REGNUM};
+static uint32_t g_d15_invalidates[] = {fpu_v15, fpu_s15, LLDB_INVALID_REGNUM};
+static uint32_t g_d16_invalidates[] = {fpu_v16, fpu_s16, LLDB_INVALID_REGNUM};
+static uint32_t g_d17_invalidates[] = {fpu_v17, fpu_s17, LLDB_INVALID_REGNUM};
+static uint32_t g_d18_invalidates[] = {fpu_v18, fpu_s18, LLDB_INVALID_REGNUM};
+static uint32_t g_d19_invalidates[] = {fpu_v19, fpu_s19, LLDB_INVALID_REGNUM};
+static uint32_t g_d20_invalidates[] = {fpu_v20, fpu_s20, LLDB_INVALID_REGNUM};
+static uint32_t g_d21_invalidates[] = {fpu_v21, fpu_s21, LLDB_INVALID_REGNUM};
+static uint32_t g_d22_invalidates[] = {fpu_v22, fpu_s22, LLDB_INVALID_REGNUM};
+static uint32_t g_d23_invalidates[] = {fpu_v23, fpu_s23, LLDB_INVALID_REGNUM};
+static uint32_t g_d24_invalidates[] = {fpu_v24, fpu_s24, LLDB_INVALID_REGNUM};
+static uint32_t g_d25_invalidates[] = {fpu_v25, fpu_s25, LLDB_INVALID_REGNUM};
+static uint32_t g_d26_invalidates[] = {fpu_v26, fpu_s26, LLDB_INVALID_REGNUM};
+static uint32_t g_d27_invalidates[] = {fpu_v27, fpu_s27, LLDB_INVALID_REGNUM};
+static uint32_t g_d28_invalidates[] = {fpu_v28, fpu_s28, LLDB_INVALID_REGNUM};
+static uint32_t g_d29_invalidates[] = {fpu_v29, fpu_s29, LLDB_INVALID_REGNUM};
+static uint32_t g_d30_invalidates[] = {fpu_v30, fpu_s30, LLDB_INVALID_REGNUM};
+static uint32_t g_d31_invalidates[] = {fpu_v31, fpu_s31, LLDB_INVALID_REGNUM};
+
+static lldb_private::RegisterInfo g_register_infos_arm64_le[] = {
+ // clang-format off
+ // General purpose registers
+ // NAME ALT SZ OFFSET ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB VALUE REGS INVAL DYNEXPR SZ
+ // ===== ======= == ============= =================== ================ ================= =============== ======================== =================== ====== ============== ======= ======= ==
+ {"x0", nullptr, 8, GPR_OFFSET(0), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x0, arm64_dwarf::x0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, gpr_x0}, nullptr, nullptr, nullptr, 0},
+ {"x1", nullptr, 8, GPR_OFFSET(1), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x1, arm64_dwarf::x1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, gpr_x1}, nullptr, nullptr, nullptr, 0},
+ {"x2", nullptr, 8, GPR_OFFSET(2), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x2, arm64_dwarf::x2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, gpr_x2}, nullptr, nullptr, nullptr, 0},
+ {"x3", nullptr, 8, GPR_OFFSET(3), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x3, arm64_dwarf::x3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, gpr_x3}, nullptr, nullptr, nullptr, 0},
+ {"x4", nullptr, 8, GPR_OFFSET(4), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x4, arm64_dwarf::x4, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM, gpr_x4}, nullptr, nullptr, nullptr, 0},
+ {"x5", nullptr, 8, GPR_OFFSET(5), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x5, arm64_dwarf::x5, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM, gpr_x5}, nullptr, nullptr, nullptr, 0},
+ {"x6", nullptr, 8, GPR_OFFSET(6), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x6, arm64_dwarf::x6, LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM, gpr_x6}, nullptr, nullptr, nullptr, 0},
+ {"x7", nullptr, 8, GPR_OFFSET(7), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x7, arm64_dwarf::x7, LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM, gpr_x7}, nullptr, nullptr, nullptr, 0},
+ {"x8", nullptr, 8, GPR_OFFSET(8), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x8, arm64_dwarf::x8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x8}, nullptr, nullptr, nullptr, 0},
+ {"x9", nullptr, 8, GPR_OFFSET(9), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x9, arm64_dwarf::x9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x9}, nullptr, nullptr, nullptr, 0},
+ {"x10", nullptr, 8, GPR_OFFSET(10), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x10, arm64_dwarf::x10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x10}, nullptr, nullptr, nullptr, 0},
+ {"x11", nullptr, 8, GPR_OFFSET(11), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x11, arm64_dwarf::x11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x11}, nullptr, nullptr, nullptr, 0},
+ {"x12", nullptr, 8, GPR_OFFSET(12), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x12, arm64_dwarf::x12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x12}, nullptr, nullptr, nullptr, 0},
+ {"x13", nullptr, 8, GPR_OFFSET(13), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x13, arm64_dwarf::x13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x13}, nullptr, nullptr, nullptr, 0},
+ {"x14", nullptr, 8, GPR_OFFSET(14), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x14, arm64_dwarf::x14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x14}, nullptr, nullptr, nullptr, 0},
+ {"x15", nullptr, 8, GPR_OFFSET(15), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x15, arm64_dwarf::x15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x15}, nullptr, nullptr, nullptr, 0},
+ {"x16", nullptr, 8, GPR_OFFSET(16), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x16, arm64_dwarf::x16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x16}, nullptr, nullptr, nullptr, 0},
+ {"x17", nullptr, 8, GPR_OFFSET(17), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x17, arm64_dwarf::x17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x17}, nullptr, nullptr, nullptr, 0},
+ {"x18", nullptr, 8, GPR_OFFSET(18), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x18, arm64_dwarf::x18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x18}, nullptr, nullptr, nullptr, 0},
+ {"x19", nullptr, 8, GPR_OFFSET(19), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x19, arm64_dwarf::x19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x19}, nullptr, nullptr, nullptr, 0},
+ {"x20", nullptr, 8, GPR_OFFSET(20), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x20, arm64_dwarf::x20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x20}, nullptr, nullptr, nullptr, 0},
+ {"x21", nullptr, 8, GPR_OFFSET(21), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x21, arm64_dwarf::x21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x21}, nullptr, nullptr, nullptr, 0},
+ {"x22", nullptr, 8, GPR_OFFSET(22), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x22, arm64_dwarf::x22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x22}, nullptr, nullptr, nullptr, 0},
+ {"x23", nullptr, 8, GPR_OFFSET(23), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x23, arm64_dwarf::x23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x23}, nullptr, nullptr, nullptr, 0},
+ {"x24", nullptr, 8, GPR_OFFSET(24), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x24, arm64_dwarf::x24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x24}, nullptr, nullptr, nullptr, 0},
+ {"x25", nullptr, 8, GPR_OFFSET(25), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x25, arm64_dwarf::x25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x25}, nullptr, nullptr, nullptr, 0},
+ {"x26", nullptr, 8, GPR_OFFSET(26), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x26, arm64_dwarf::x26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x26}, nullptr, nullptr, nullptr, 0},
+ {"x27", nullptr, 8, GPR_OFFSET(27), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x27, arm64_dwarf::x27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x27}, nullptr, nullptr, nullptr, 0},
+ {"x28", nullptr, 8, GPR_OFFSET(28), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::x28, arm64_dwarf::x28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_x28}, nullptr, nullptr, nullptr, 0},
+ {"fp", "x29", 8, GPR_OFFSET(29), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::fp, arm64_dwarf::fp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, gpr_fp}, nullptr, nullptr, nullptr, 0},
+ {"lr", "x30", 8, GPR_OFFSET(30), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::lr, arm64_dwarf::lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, gpr_lr}, nullptr, nullptr, nullptr, 0},
+ {"sp", "x31", 8, GPR_OFFSET(31), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::sp, arm64_dwarf::sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, gpr_sp}, nullptr, nullptr, nullptr, 0},
+ {"pc", nullptr, 8, GPR_OFFSET(32), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::pc, arm64_dwarf::pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, gpr_pc}, nullptr, nullptr, nullptr, 0},
+
+ {"cpsr",nullptr, 4, GPR_OFFSET_NAME(cpsr), lldb::eEncodingUint, lldb::eFormatHex, {arm64_ehframe::cpsr, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, gpr_cpsr}, nullptr, nullptr, nullptr, 0},
+
+ // NAME ALT SZ OFFSET ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB VALUE INVALIDATES DYNEXPR SZ
+ // ===== ======= == ============================================== =================== ================ ================= =============== =================== =================== ====== =============== ================= ======= ==
+ {"w0", nullptr, 4, GPR_OFFSET(0) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w0}, g_contained_x0, g_w0_invalidates, nullptr, 0},
+ {"w1", nullptr, 4, GPR_OFFSET(1) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w1}, g_contained_x1, g_w1_invalidates, nullptr, 0},
+ {"w2", nullptr, 4, GPR_OFFSET(2) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w2}, g_contained_x2, g_w2_invalidates, nullptr, 0},
+ {"w3", nullptr, 4, GPR_OFFSET(3) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w3}, g_contained_x3, g_w3_invalidates, nullptr, 0},
+ {"w4", nullptr, 4, GPR_OFFSET(4) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w4}, g_contained_x4, g_w4_invalidates, nullptr, 0},
+ {"w5", nullptr, 4, GPR_OFFSET(5) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w5}, g_contained_x5, g_w5_invalidates, nullptr, 0},
+ {"w6", nullptr, 4, GPR_OFFSET(6) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w6}, g_contained_x6, g_w6_invalidates, nullptr, 0},
+ {"w7", nullptr, 4, GPR_OFFSET(7) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w7}, g_contained_x7, g_w7_invalidates, nullptr, 0},
+ {"w8", nullptr, 4, GPR_OFFSET(8) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w8}, g_contained_x8, g_w8_invalidates, nullptr, 0},
+ {"w9", nullptr, 4, GPR_OFFSET(9) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w9}, g_contained_x9, g_w9_invalidates, nullptr, 0},
+ {"w10", nullptr, 4, GPR_OFFSET(10) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w10}, g_contained_x10, g_w10_invalidates, nullptr, 0},
+ {"w11", nullptr, 4, GPR_OFFSET(11) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w11}, g_contained_x11, g_w11_invalidates, nullptr, 0},
+ {"w12", nullptr, 4, GPR_OFFSET(12) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w12}, g_contained_x12, g_w12_invalidates, nullptr, 0},
+ {"w13", nullptr, 4, GPR_OFFSET(13) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w13}, g_contained_x13, g_w13_invalidates, nullptr, 0},
+ {"w14", nullptr, 4, GPR_OFFSET(14) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w14}, g_contained_x14, g_w14_invalidates, nullptr, 0},
+ {"w15", nullptr, 4, GPR_OFFSET(15) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w15}, g_contained_x15, g_w15_invalidates, nullptr, 0},
+ {"w16", nullptr, 4, GPR_OFFSET(16) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w16}, g_contained_x16, g_w16_invalidates, nullptr, 0},
+ {"w17", nullptr, 4, GPR_OFFSET(17) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w17}, g_contained_x17, g_w17_invalidates, nullptr, 0},
+ {"w18", nullptr, 4, GPR_OFFSET(18) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w18}, g_contained_x18, g_w18_invalidates, nullptr, 0},
+ {"w19", nullptr, 4, GPR_OFFSET(19) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w19}, g_contained_x19, g_w19_invalidates, nullptr, 0},
+ {"w20", nullptr, 4, GPR_OFFSET(20) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w20}, g_contained_x20, g_w20_invalidates, nullptr, 0},
+ {"w21", nullptr, 4, GPR_OFFSET(21) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w21}, g_contained_x21, g_w21_invalidates, nullptr, 0},
+ {"w22", nullptr, 4, GPR_OFFSET(22) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w22}, g_contained_x22, g_w22_invalidates, nullptr, 0},
+ {"w23", nullptr, 4, GPR_OFFSET(23) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w23}, g_contained_x23, g_w23_invalidates, nullptr, 0},
+ {"w24", nullptr, 4, GPR_OFFSET(24) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w24}, g_contained_x24, g_w24_invalidates, nullptr, 0},
+ {"w25", nullptr, 4, GPR_OFFSET(25) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w25}, g_contained_x25, g_w25_invalidates, nullptr, 0},
+ {"w26", nullptr, 4, GPR_OFFSET(26) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w26}, g_contained_x26, g_w26_invalidates, nullptr, 0},
+ {"w27", nullptr, 4, GPR_OFFSET(27) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w27}, g_contained_x27, g_w27_invalidates, nullptr, 0},
+ {"w28", nullptr, 4, GPR_OFFSET(28) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_w28}, g_contained_x28, g_w28_invalidates, nullptr, 0},
+
+ // NAME ALT SZ OFFSET ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB VALUE REGS INVAL DYNEXPR SZ
+ // ===== ======= == ============= =================== ================ ================= =============== =================== =================== ====== ============== ======= ======= ==
+ {"v0", nullptr, 16, FPU_OFFSET(0), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v0}, nullptr, nullptr, nullptr, 0},
+ {"v1", nullptr, 16, FPU_OFFSET(1), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v1}, nullptr, nullptr, nullptr, 0},
+ {"v2", nullptr, 16, FPU_OFFSET(2), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v2}, nullptr, nullptr, nullptr, 0},
+ {"v3", nullptr, 16, FPU_OFFSET(3), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v3}, nullptr, nullptr, nullptr, 0},
+ {"v4", nullptr, 16, FPU_OFFSET(4), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v4}, nullptr, nullptr, nullptr, 0},
+ {"v5", nullptr, 16, FPU_OFFSET(5), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v5}, nullptr, nullptr, nullptr, 0},
+ {"v6", nullptr, 16, FPU_OFFSET(6), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v6}, nullptr, nullptr, nullptr, 0},
+ {"v7", nullptr, 16, FPU_OFFSET(7), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v7}, nullptr, nullptr, nullptr, 0},
+ {"v8", nullptr, 16, FPU_OFFSET(8), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v8}, nullptr, nullptr, nullptr, 0},
+ {"v9", nullptr, 16, FPU_OFFSET(9), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v9}, nullptr, nullptr, nullptr, 0},
+ {"v10", nullptr, 16, FPU_OFFSET(10), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v10}, nullptr, nullptr, nullptr, 0},
+ {"v11", nullptr, 16, FPU_OFFSET(11), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v11}, nullptr, nullptr, nullptr, 0},
+ {"v12", nullptr, 16, FPU_OFFSET(12), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v12}, nullptr, nullptr, nullptr, 0},
+ {"v13", nullptr, 16, FPU_OFFSET(13), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v13}, nullptr, nullptr, nullptr, 0},
+ {"v14", nullptr, 16, FPU_OFFSET(14), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v14}, nullptr, nullptr, nullptr, 0},
+ {"v15", nullptr, 16, FPU_OFFSET(15), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v15}, nullptr, nullptr, nullptr, 0},
+ {"v16", nullptr, 16, FPU_OFFSET(16), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v16}, nullptr, nullptr, nullptr, 0},
+ {"v17", nullptr, 16, FPU_OFFSET(17), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v17}, nullptr, nullptr, nullptr, 0},
+ {"v18", nullptr, 16, FPU_OFFSET(18), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v18}, nullptr, nullptr, nullptr, 0},
+ {"v19", nullptr, 16, FPU_OFFSET(19), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v19}, nullptr, nullptr, nullptr, 0},
+ {"v20", nullptr, 16, FPU_OFFSET(20), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v20}, nullptr, nullptr, nullptr, 0},
+ {"v21", nullptr, 16, FPU_OFFSET(21), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v21}, nullptr, nullptr, nullptr, 0},
+ {"v22", nullptr, 16, FPU_OFFSET(22), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v22}, nullptr, nullptr, nullptr, 0},
+ {"v23", nullptr, 16, FPU_OFFSET(23), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v23}, nullptr, nullptr, nullptr, 0},
+ {"v24", nullptr, 16, FPU_OFFSET(24), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v24}, nullptr, nullptr, nullptr, 0},
+ {"v25", nullptr, 16, FPU_OFFSET(25), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v25}, nullptr, nullptr, nullptr, 0},
+ {"v26", nullptr, 16, FPU_OFFSET(26), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v26}, nullptr, nullptr, nullptr, 0},
+ {"v27", nullptr, 16, FPU_OFFSET(27), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v27}, nullptr, nullptr, nullptr, 0},
+ {"v28", nullptr, 16, FPU_OFFSET(28), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v28}, nullptr, nullptr, nullptr, 0},
+ {"v29", nullptr, 16, FPU_OFFSET(29), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v29}, nullptr, nullptr, nullptr, 0},
+ {"v30", nullptr, 16, FPU_OFFSET(30), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v30}, nullptr, nullptr, nullptr, 0},
+ {"v31", nullptr, 16, FPU_OFFSET(31), lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, arm64_dwarf::v31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_v31}, nullptr, nullptr, nullptr, 0},
+
+ // NAME ALT SZ OFFSET ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB VALUE REGS INVALIDATES DYNEXPR SZ
+ // ===== ======= == ============================================== =================== ================ ================= =============== =================== =================== ====== =============== ================= ======= ==
+ {"s0", nullptr, 4, FPU_OFFSET(0) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s0}, g_contained_v0, g_s0_invalidates, nullptr, 0},
+ {"s1", nullptr, 4, FPU_OFFSET(1) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s1}, g_contained_v1, g_s1_invalidates, nullptr, 0},
+ {"s2", nullptr, 4, FPU_OFFSET(2) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s2}, g_contained_v2, g_s2_invalidates, nullptr, 0},
+ {"s3", nullptr, 4, FPU_OFFSET(3) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s3}, g_contained_v3, g_s3_invalidates, nullptr, 0},
+ {"s4", nullptr, 4, FPU_OFFSET(4) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s4}, g_contained_v4, g_s4_invalidates, nullptr, 0},
+ {"s5", nullptr, 4, FPU_OFFSET(5) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s5}, g_contained_v5, g_s5_invalidates, nullptr, 0},
+ {"s6", nullptr, 4, FPU_OFFSET(6) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s6}, g_contained_v6, g_s6_invalidates, nullptr, 0},
+ {"s7", nullptr, 4, FPU_OFFSET(7) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s7}, g_contained_v7, g_s7_invalidates, nullptr, 0},
+ {"s8", nullptr, 4, FPU_OFFSET(8) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s8}, g_contained_v8, g_s8_invalidates, nullptr, 0},
+ {"s9", nullptr, 4, FPU_OFFSET(9) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s9}, g_contained_v9, g_s9_invalidates, nullptr, 0},
+ {"s10", nullptr, 4, FPU_OFFSET(10) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s10}, g_contained_v10, g_s10_invalidates, nullptr, 0},
+ {"s11", nullptr, 4, FPU_OFFSET(11) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s11}, g_contained_v11, g_s11_invalidates, nullptr, 0},
+ {"s12", nullptr, 4, FPU_OFFSET(12) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s12}, g_contained_v12, g_s12_invalidates, nullptr, 0},
+ {"s13", nullptr, 4, FPU_OFFSET(13) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s13}, g_contained_v13, g_s13_invalidates, nullptr, 0},
+ {"s14", nullptr, 4, FPU_OFFSET(14) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s14}, g_contained_v14, g_s14_invalidates, nullptr, 0},
+ {"s15", nullptr, 4, FPU_OFFSET(15) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s15}, g_contained_v15, g_s15_invalidates, nullptr, 0},
+ {"s16", nullptr, 4, FPU_OFFSET(16) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s16}, g_contained_v16, g_s16_invalidates, nullptr, 0},
+ {"s17", nullptr, 4, FPU_OFFSET(17) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s17}, g_contained_v17, g_s17_invalidates, nullptr, 0},
+ {"s18", nullptr, 4, FPU_OFFSET(18) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s18}, g_contained_v18, g_s18_invalidates, nullptr, 0},
+ {"s19", nullptr, 4, FPU_OFFSET(19) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s19}, g_contained_v19, g_s19_invalidates, nullptr, 0},
+ {"s20", nullptr, 4, FPU_OFFSET(20) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s20}, g_contained_v20, g_s20_invalidates, nullptr, 0},
+ {"s21", nullptr, 4, FPU_OFFSET(21) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s21}, g_contained_v21, g_s21_invalidates, nullptr, 0},
+ {"s22", nullptr, 4, FPU_OFFSET(22) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s22}, g_contained_v22, g_s22_invalidates, nullptr, 0},
+ {"s23", nullptr, 4, FPU_OFFSET(23) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s23}, g_contained_v23, g_s23_invalidates, nullptr, 0},
+ {"s24", nullptr, 4, FPU_OFFSET(24) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s24}, g_contained_v24, g_s24_invalidates, nullptr, 0},
+ {"s25", nullptr, 4, FPU_OFFSET(25) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s25}, g_contained_v25, g_s25_invalidates, nullptr, 0},
+ {"s26", nullptr, 4, FPU_OFFSET(26) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s26}, g_contained_v26, g_s26_invalidates, nullptr, 0},
+ {"s27", nullptr, 4, FPU_OFFSET(27) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s27}, g_contained_v27, g_s27_invalidates, nullptr, 0},
+ {"s28", nullptr, 4, FPU_OFFSET(28) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s28}, g_contained_v28, g_s28_invalidates, nullptr, 0},
+ {"s29", nullptr, 4, FPU_OFFSET(29) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s29}, g_contained_v29, g_s29_invalidates, nullptr, 0},
+ {"s30", nullptr, 4, FPU_OFFSET(30) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s30}, g_contained_v30, g_s30_invalidates, nullptr, 0},
+ {"s31", nullptr, 4, FPU_OFFSET(31) + FPU_S_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s31}, g_contained_v31, g_s31_invalidates, nullptr, 0},
+
+ {"d0", nullptr, 8, FPU_OFFSET(0) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d0}, g_contained_v0, g_d0_invalidates, nullptr, 0},
+ {"d1", nullptr, 8, FPU_OFFSET(1) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d1}, g_contained_v1, g_d1_invalidates, nullptr, 0},
+ {"d2", nullptr, 8, FPU_OFFSET(2) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d2}, g_contained_v2, g_d2_invalidates, nullptr, 0},
+ {"d3", nullptr, 8, FPU_OFFSET(3) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d3}, g_contained_v3, g_d3_invalidates, nullptr, 0},
+ {"d4", nullptr, 8, FPU_OFFSET(4) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d4}, g_contained_v4, g_d4_invalidates, nullptr, 0},
+ {"d5", nullptr, 8, FPU_OFFSET(5) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d5}, g_contained_v5, g_d5_invalidates, nullptr, 0},
+ {"d6", nullptr, 8, FPU_OFFSET(6) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d6}, g_contained_v6, g_d6_invalidates, nullptr, 0},
+ {"d7", nullptr, 8, FPU_OFFSET(7) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d7}, g_contained_v7, g_d7_invalidates, nullptr, 0},
+ {"d8", nullptr, 8, FPU_OFFSET(8) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d8}, g_contained_v8, g_d8_invalidates, nullptr, 0},
+ {"d9", nullptr, 8, FPU_OFFSET(9) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d9}, g_contained_v9, g_d9_invalidates, nullptr, 0},
+ {"d10", nullptr, 8, FPU_OFFSET(10) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d10}, g_contained_v10, g_d10_invalidates, nullptr, 0},
+ {"d11", nullptr, 8, FPU_OFFSET(11) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d11}, g_contained_v11, g_d11_invalidates, nullptr, 0},
+ {"d12", nullptr, 8, FPU_OFFSET(12) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d12}, g_contained_v12, g_d12_invalidates, nullptr, 0},
+ {"d13", nullptr, 8, FPU_OFFSET(13) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d13}, g_contained_v13, g_d13_invalidates, nullptr, 0},
+ {"d14", nullptr, 8, FPU_OFFSET(14) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d14}, g_contained_v14, g_d14_invalidates, nullptr, 0},
+ {"d15", nullptr, 8, FPU_OFFSET(15) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d15}, g_contained_v15, g_d15_invalidates, nullptr, 0},
+ {"d16", nullptr, 8, FPU_OFFSET(16) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d16}, g_contained_v16, g_d16_invalidates, nullptr, 0},
+ {"d17", nullptr, 8, FPU_OFFSET(17) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d17}, g_contained_v17, g_d17_invalidates, nullptr, 0},
+ {"d18", nullptr, 8, FPU_OFFSET(18) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d18}, g_contained_v18, g_d18_invalidates, nullptr, 0},
+ {"d19", nullptr, 8, FPU_OFFSET(19) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d19}, g_contained_v19, g_d19_invalidates, nullptr, 0},
+ {"d20", nullptr, 8, FPU_OFFSET(20) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d20}, g_contained_v20, g_d20_invalidates, nullptr, 0},
+ {"d21", nullptr, 8, FPU_OFFSET(21) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d21}, g_contained_v21, g_d21_invalidates, nullptr, 0},
+ {"d22", nullptr, 8, FPU_OFFSET(22) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d22}, g_contained_v22, g_d22_invalidates, nullptr, 0},
+ {"d23", nullptr, 8, FPU_OFFSET(23) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d23}, g_contained_v23, g_d23_invalidates, nullptr, 0},
+ {"d24", nullptr, 8, FPU_OFFSET(24) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d24}, g_contained_v24, g_d24_invalidates, nullptr, 0},
+ {"d25", nullptr, 8, FPU_OFFSET(25) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d25}, g_contained_v25, g_d25_invalidates, nullptr, 0},
+ {"d26", nullptr, 8, FPU_OFFSET(26) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d26}, g_contained_v26, g_d26_invalidates, nullptr, 0},
+ {"d27", nullptr, 8, FPU_OFFSET(27) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d27}, g_contained_v27, g_d27_invalidates, nullptr, 0},
+ {"d28", nullptr, 8, FPU_OFFSET(28) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d28}, g_contained_v28, g_d28_invalidates, nullptr, 0},
+ {"d29", nullptr, 8, FPU_OFFSET(29) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d29}, g_contained_v29, g_d29_invalidates, nullptr, 0},
+ {"d30", nullptr, 8, FPU_OFFSET(30) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d30}, g_contained_v30, g_d30_invalidates, nullptr, 0},
+ {"d31", nullptr, 8, FPU_OFFSET(31) + FPU_D_PSEUDO_REG_ENDIAN_OFFSET, lldb::eEncodingIEEE754, lldb::eFormatFloat, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_d31}, g_contained_v31, g_d31_invalidates, nullptr, 0},
+
+ {"fpsr", nullptr, 4, FPU_OFFSET_NAME(fpsr), lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_fpsr}, nullptr, nullptr, nullptr, 0},
+ {"fpcr", nullptr, 4, FPU_OFFSET_NAME(fpcr), lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_fpcr}, nullptr, nullptr, nullptr, 0},
+
+ {"far", nullptr, 8, EXC_OFFSET_NAME(far), lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_far}, nullptr, nullptr, nullptr, 0},
+ {"esr", nullptr, 4, EXC_OFFSET_NAME(esr), lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_esr}, nullptr, nullptr, nullptr, 0},
+ {"exception", nullptr, 4, EXC_OFFSET_NAME(exception), lldb::eEncodingUint, lldb::eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_exception}, nullptr, nullptr, nullptr, 0},
+
+ {DEFINE_DBG(bvr, 0)},
+ {DEFINE_DBG(bvr, 1)},
+ {DEFINE_DBG(bvr, 2)},
+ {DEFINE_DBG(bvr, 3)},
+ {DEFINE_DBG(bvr, 4)},
+ {DEFINE_DBG(bvr, 5)},
+ {DEFINE_DBG(bvr, 6)},
+ {DEFINE_DBG(bvr, 7)},
+ {DEFINE_DBG(bvr, 8)},
+ {DEFINE_DBG(bvr, 9)},
+ {DEFINE_DBG(bvr, 10)},
+ {DEFINE_DBG(bvr, 11)},
+ {DEFINE_DBG(bvr, 12)},
+ {DEFINE_DBG(bvr, 13)},
+ {DEFINE_DBG(bvr, 14)},
+ {DEFINE_DBG(bvr, 15)},
+
+ {DEFINE_DBG(bcr, 0)},
+ {DEFINE_DBG(bcr, 1)},
+ {DEFINE_DBG(bcr, 2)},
+ {DEFINE_DBG(bcr, 3)},
+ {DEFINE_DBG(bcr, 4)},
+ {DEFINE_DBG(bcr, 5)},
+ {DEFINE_DBG(bcr, 6)},
+ {DEFINE_DBG(bcr, 7)},
+ {DEFINE_DBG(bcr, 8)},
+ {DEFINE_DBG(bcr, 9)},
+ {DEFINE_DBG(bcr, 10)},
+ {DEFINE_DBG(bcr, 11)},
+ {DEFINE_DBG(bcr, 12)},
+ {DEFINE_DBG(bcr, 13)},
+ {DEFINE_DBG(bcr, 14)},
+ {DEFINE_DBG(bcr, 15)},
+
+ {DEFINE_DBG(wvr, 0)},
+ {DEFINE_DBG(wvr, 1)},
+ {DEFINE_DBG(wvr, 2)},
+ {DEFINE_DBG(wvr, 3)},
+ {DEFINE_DBG(wvr, 4)},
+ {DEFINE_DBG(wvr, 5)},
+ {DEFINE_DBG(wvr, 6)},
+ {DEFINE_DBG(wvr, 7)},
+ {DEFINE_DBG(wvr, 8)},
+ {DEFINE_DBG(wvr, 9)},
+ {DEFINE_DBG(wvr, 10)},
+ {DEFINE_DBG(wvr, 11)},
+ {DEFINE_DBG(wvr, 12)},
+ {DEFINE_DBG(wvr, 13)},
+ {DEFINE_DBG(wvr, 14)},
+ {DEFINE_DBG(wvr, 15)},
+
+ {DEFINE_DBG(wcr, 0)},
+ {DEFINE_DBG(wcr, 1)},
+ {DEFINE_DBG(wcr, 2)},
+ {DEFINE_DBG(wcr, 3)},
+ {DEFINE_DBG(wcr, 4)},
+ {DEFINE_DBG(wcr, 5)},
+ {DEFINE_DBG(wcr, 6)},
+ {DEFINE_DBG(wcr, 7)},
+ {DEFINE_DBG(wcr, 8)},
+ {DEFINE_DBG(wcr, 9)},
+ {DEFINE_DBG(wcr, 10)},
+ {DEFINE_DBG(wcr, 11)},
+ {DEFINE_DBG(wcr, 12)},
+ {DEFINE_DBG(wcr, 13)},
+ {DEFINE_DBG(wcr, 14)},
+ {DEFINE_DBG(wcr, 15)}
+ // clang-format on
};
#endif // DECLARE_REGISTER_INFOS_ARM64_STRUCT
diff --git a/source/Plugins/Process/Utility/RegisterInfos_i386.h b/source/Plugins/Process/Utility/RegisterInfos_i386.h
index a94b790b680f..8597d0c39dc4 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_i386.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_i386.h
@@ -7,41 +7,47 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-#include <stddef.h>
-
-// C++ Includes
-// Other libraries and framework includes
#include "llvm/Support/Compiler.h"
+#include <cstddef>
+#include <cstdint>
// Project includes
#ifdef DECLARE_REGISTER_INFOS_I386_STRUCT
// Computes the offset of the given GPR in the user data area.
-#define GPR_OFFSET(regname) \
- (LLVM_EXTENSION offsetof(GPR, regname))
+#define GPR_OFFSET(regname) (LLVM_EXTENSION offsetof(GPR, regname))
// Computes the offset of the given FPR in the extended data area.
-#define FPR_OFFSET(regname) \
- (LLVM_EXTENSION offsetof(UserArea, i387) + \
- LLVM_EXTENSION offsetof(FPR_i386, regname))
+#define FPR_OFFSET(regname) \
+ (LLVM_EXTENSION offsetof(UserArea, i387) + \
+ LLVM_EXTENSION offsetof(FPR_i386, regname))
// Computes the offset of the YMM register assembled from register halves.
// Based on DNBArchImplI386.cpp from debugserver
-#define YMM_OFFSET(reg_index) \
+#define YMM_OFFSET(reg_index) \
+ (LLVM_EXTENSION offsetof(UserArea, i387) + \
+ LLVM_EXTENSION offsetof(FPR, xstate) + \
+ LLVM_EXTENSION offsetof(FXSAVE, xmm[7]) + sizeof(XMMReg) + \
+ (32 * reg_index))
+
+#define BNDR_OFFSET(reg_index) \
+ (LLVM_EXTENSION offsetof(UserArea, i387) + \
+ LLVM_EXTENSION offsetof(FPR, xstate) + \
+ LLVM_EXTENSION offsetof(XSAVE, mpxr[reg_index]))
+
+#define BNDC_OFFSET(reg_index) \
(LLVM_EXTENSION offsetof(UserArea, i387) + \
LLVM_EXTENSION offsetof(FPR, xstate) + \
- LLVM_EXTENSION offsetof(FXSAVE, xmm[7]) + \
- sizeof(XMMReg) + (32 * reg_index))
+ LLVM_EXTENSION offsetof(XSAVE, mpxc[reg_index]))
// Number of bytes needed to represent a FPR.
#if !defined(FPR_SIZE)
-#define FPR_SIZE(reg) sizeof(((FXSAVE*)NULL)->reg)
+#define FPR_SIZE(reg) sizeof(((FXSAVE *)nullptr)->reg)
#endif
// Number of bytes needed to represent the i'th FP register.
-#define FP_SIZE sizeof(((MMSReg*)NULL)->bytes)
+#define FP_SIZE sizeof(((MMSReg *)nullptr)->bytes)
// Number of bytes needed to represent an XMM register.
#define XMM_SIZE sizeof(XMMReg)
@@ -49,158 +55,235 @@
// Number of bytes needed to represent a YMM register.
#define YMM_SIZE sizeof(YMMReg)
+// Number of bytes needed to represent MPX registers.
+#define BNDR_SIZE sizeof(MPXReg)
+#define BNDC_SIZE sizeof(MPXCsr)
+
// Note that the size and offset will be updated by platform-specific classes.
-#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
- { #reg, alt, sizeof(((GPR*)NULL)->reg), GPR_OFFSET(reg), eEncodingUint, \
- eFormatHex, { kind1, kind2, kind3, kind4, lldb_##reg##_i386 }, NULL, NULL, NULL, 0}
+#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
+ { \
+ #reg, alt, sizeof(((GPR *)nullptr)->reg), \
+ GPR_OFFSET(reg), eEncodingUint, eFormatHex, \
+ {kind1, kind2, kind3, kind4, \
+ lldb_##reg##_i386 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
-#define DEFINE_FPR(name, reg, kind1, kind2, kind3, kind4) \
- { #name, NULL, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, \
- eFormatHex, { kind1, kind2, kind3, kind4, lldb_##name##_i386 }, NULL, NULL, NULL, 0}
+#define DEFINE_FPR(name, reg, kind1, kind2, kind3, kind4) \
+ { \
+ #name, nullptr, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, eFormatHex, \
+ {kind1, kind2, kind3, kind4, \
+ lldb_##name##_i386 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
// RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB
-#define DEFINE_FP_ST(reg, i) \
- { #reg#i, NULL, FP_SIZE, LLVM_EXTENSION FPR_OFFSET(stmm[i]), \
- eEncodingVector, eFormatVectorOfUInt8, \
- { ehframe_st##i##_i386, dwarf_st##i##_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_st##i##_i386 }, \
- NULL, NULL, NULL, 0}
-
-#define DEFINE_FP_MM(reg, i) \
- { #reg#i, NULL, sizeof(uint64_t), LLVM_EXTENSION FPR_OFFSET(stmm[i]), \
- eEncodingUint, eFormatHex, \
- { ehframe_mm##i##_i386, dwarf_mm##i##_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_mm##i##_i386 }, \
- NULL, NULL, NULL, 0}
-
-#define DEFINE_XMM(reg, i) \
- { #reg#i, NULL, XMM_SIZE, LLVM_EXTENSION FPR_OFFSET(reg[i]), \
- eEncodingVector, eFormatVectorOfUInt8, \
- { ehframe_##reg##i##_i386, dwarf_##reg##i##_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg##i##_i386}, \
- NULL, NULL, NULL, 0}
-
-// I believe the YMM registers use dwarf_xmm_%_i386 register numbers and then differentiate based on register size.
-#define DEFINE_YMM(reg, i) \
- { #reg#i, NULL, YMM_SIZE, LLVM_EXTENSION YMM_OFFSET(i), \
- eEncodingVector, eFormatVectorOfUInt8, \
- { LLDB_INVALID_REGNUM, dwarf_xmm##i##_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg##i##_i386 }, \
- NULL, NULL, NULL, 0}
-
-#define DEFINE_DR(reg, i) \
- { #reg#i, NULL, DR_SIZE, DR_OFFSET(i), eEncodingUint, eFormatHex, \
- { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL, NULL, 0}
-
-#define DEFINE_GPR_PSEUDO_16(reg16, reg32) \
- { #reg16, NULL, 2, GPR_OFFSET(reg32), eEncodingUint, \
- eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg16##_i386 }, RegisterContextPOSIX_x86::g_contained_##reg32, RegisterContextPOSIX_x86::g_invalidate_##reg32, NULL, 0}
-#define DEFINE_GPR_PSEUDO_8H(reg8, reg32) \
- { #reg8, NULL, 1, GPR_OFFSET(reg32)+1, eEncodingUint, \
- eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg8##_i386 }, RegisterContextPOSIX_x86::g_contained_##reg32, RegisterContextPOSIX_x86::g_invalidate_##reg32, NULL, 0}
-#define DEFINE_GPR_PSEUDO_8L(reg8, reg32) \
- { #reg8, NULL, 1, GPR_OFFSET(reg32), eEncodingUint, \
- eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg8##_i386 }, RegisterContextPOSIX_x86::g_contained_##reg32, RegisterContextPOSIX_x86::g_invalidate_##reg32, NULL, 0}
-
-static RegisterInfo
-g_register_infos_i386[] =
-{
+#define DEFINE_FP_ST(reg, i) \
+ { \
+ #reg #i, nullptr, FP_SIZE, \
+ LLVM_EXTENSION FPR_OFFSET( \
+ stmm[i]), eEncodingVector, eFormatVectorOfUInt8, \
+ {ehframe_st##i##_i386, dwarf_st##i##_i386, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, lldb_st##i##_i386 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_FP_MM(reg, i) \
+ { \
+ #reg #i, nullptr, sizeof(uint64_t), \
+ LLVM_EXTENSION FPR_OFFSET( \
+ stmm[i]), eEncodingUint, eFormatHex, \
+ {ehframe_mm##i##_i386, dwarf_mm##i##_i386, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_mm##i##_i386 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_XMM(reg, i) \
+ { \
+ #reg #i, nullptr, XMM_SIZE, \
+ LLVM_EXTENSION FPR_OFFSET( \
+ reg[i]), eEncodingVector, eFormatVectorOfUInt8, \
+ {ehframe_##reg##i##_i386, dwarf_##reg##i##_i386, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg##i##_i386 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+// I believe the YMM registers use dwarf_xmm_%_i386 register numbers and then
+// differentiate based on register size.
+#define DEFINE_YMM(reg, i) \
+ { \
+ #reg #i, nullptr, YMM_SIZE, \
+ LLVM_EXTENSION YMM_OFFSET(i), eEncodingVector, eFormatVectorOfUInt8, \
+ {LLDB_INVALID_REGNUM, dwarf_xmm##i##_i386, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg##i##_i386 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_BNDR(reg, i) \
+ { \
+ #reg #i, nullptr, BNDR_SIZE, \
+ LLVM_EXTENSION BNDR_OFFSET(i), eEncodingVector, eFormatVectorOfUInt64, \
+ {dwarf_##reg##i##_i386, dwarf_##reg##i##_i386, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, lldb_##reg##i##_i386 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_BNDC(name, i) \
+ { \
+ #name, nullptr, BNDC_SIZE, \
+ LLVM_EXTENSION BNDC_OFFSET(i), eEncodingVector, \
+ eFormatVectorOfUInt8, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, lldb_##name##_i386 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_DR(reg, i) \
+ { \
+ #reg #i, nullptr, DR_SIZE, \
+ DR_OFFSET(i), eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_GPR_PSEUDO_16(reg16, reg32) \
+ { \
+ #reg16, nullptr, 2, \
+ GPR_OFFSET(reg32), eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg16##_i386 }, \
+ RegisterContextPOSIX_x86::g_contained_##reg32, \
+ RegisterContextPOSIX_x86::g_invalidate_##reg32, nullptr, 0 \
+ }
+
+#define DEFINE_GPR_PSEUDO_8H(reg8, reg32) \
+ { \
+ #reg8, nullptr, 1, \
+ GPR_OFFSET(reg32) + 1, eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg8##_i386 }, \
+ RegisterContextPOSIX_x86::g_contained_##reg32, \
+ RegisterContextPOSIX_x86::g_invalidate_##reg32, nullptr, 0 \
+ }
+
+#define DEFINE_GPR_PSEUDO_8L(reg8, reg32) \
+ { \
+ #reg8, nullptr, 1, \
+ GPR_OFFSET(reg32), eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg8##_i386 }, \
+ RegisterContextPOSIX_x86::g_contained_##reg32, \
+ RegisterContextPOSIX_x86::g_invalidate_##reg32, nullptr, 0 \
+ }
+
+static RegisterInfo g_register_infos_i386[] = {
// General purpose registers.
- DEFINE_GPR(eax, nullptr, ehframe_eax_i386, dwarf_eax_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(ebx, nullptr, ehframe_ebx_i386, dwarf_ebx_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(ecx, nullptr, ehframe_ecx_i386, dwarf_ecx_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(edx, nullptr, ehframe_edx_i386, dwarf_edx_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(edi, nullptr, ehframe_edi_i386, dwarf_edi_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(esi, nullptr, ehframe_esi_i386, dwarf_esi_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(ebp, "fp", ehframe_ebp_i386, dwarf_ebp_i386, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM),
- DEFINE_GPR(esp, "sp", ehframe_esp_i386, dwarf_esp_i386, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM),
- DEFINE_GPR(eip, "pc", ehframe_eip_i386, dwarf_eip_i386, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM),
- DEFINE_GPR(eflags, "flags", ehframe_eflags_i386, dwarf_eflags_i386, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM),
- DEFINE_GPR(cs, nullptr, LLDB_INVALID_REGNUM, dwarf_cs_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(fs, nullptr, LLDB_INVALID_REGNUM, dwarf_fs_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(gs, nullptr, LLDB_INVALID_REGNUM, dwarf_gs_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(ss, nullptr, LLDB_INVALID_REGNUM, dwarf_ss_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(ds, nullptr, LLDB_INVALID_REGNUM, dwarf_ds_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(es, nullptr, LLDB_INVALID_REGNUM, dwarf_es_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-
- DEFINE_GPR_PSEUDO_16(ax, eax),
- DEFINE_GPR_PSEUDO_16(bx, ebx),
- DEFINE_GPR_PSEUDO_16(cx, ecx),
- DEFINE_GPR_PSEUDO_16(dx, edx),
- DEFINE_GPR_PSEUDO_16(di, edi),
- DEFINE_GPR_PSEUDO_16(si, esi),
- DEFINE_GPR_PSEUDO_16(bp, ebp),
- DEFINE_GPR_PSEUDO_16(sp, esp),
- DEFINE_GPR_PSEUDO_8H(ah, eax),
- DEFINE_GPR_PSEUDO_8H(bh, ebx),
- DEFINE_GPR_PSEUDO_8H(ch, ecx),
- DEFINE_GPR_PSEUDO_8H(dh, edx),
- DEFINE_GPR_PSEUDO_8L(al, eax),
- DEFINE_GPR_PSEUDO_8L(bl, ebx),
- DEFINE_GPR_PSEUDO_8L(cl, ecx),
- DEFINE_GPR_PSEUDO_8L(dl, edx),
+ DEFINE_GPR(eax, nullptr, ehframe_eax_i386, dwarf_eax_i386,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ebx, nullptr, ehframe_ebx_i386, dwarf_ebx_i386,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ecx, nullptr, ehframe_ecx_i386, dwarf_ecx_i386,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(edx, nullptr, ehframe_edx_i386, dwarf_edx_i386,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(edi, nullptr, ehframe_edi_i386, dwarf_edi_i386,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(esi, nullptr, ehframe_esi_i386, dwarf_esi_i386,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ebp, "fp", ehframe_ebp_i386, dwarf_ebp_i386,
+ LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(esp, "sp", ehframe_esp_i386, dwarf_esp_i386,
+ LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(eip, "pc", ehframe_eip_i386, dwarf_eip_i386,
+ LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(eflags, "flags", ehframe_eflags_i386, dwarf_eflags_i386,
+ LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(cs, nullptr, LLDB_INVALID_REGNUM, dwarf_cs_i386,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(fs, nullptr, LLDB_INVALID_REGNUM, dwarf_fs_i386,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(gs, nullptr, LLDB_INVALID_REGNUM, dwarf_gs_i386,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ss, nullptr, LLDB_INVALID_REGNUM, dwarf_ss_i386,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ds, nullptr, LLDB_INVALID_REGNUM, dwarf_ds_i386,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(es, nullptr, LLDB_INVALID_REGNUM, dwarf_es_i386,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+
+ DEFINE_GPR_PSEUDO_16(ax, eax), DEFINE_GPR_PSEUDO_16(bx, ebx),
+ DEFINE_GPR_PSEUDO_16(cx, ecx), DEFINE_GPR_PSEUDO_16(dx, edx),
+ DEFINE_GPR_PSEUDO_16(di, edi), DEFINE_GPR_PSEUDO_16(si, esi),
+ DEFINE_GPR_PSEUDO_16(bp, ebp), DEFINE_GPR_PSEUDO_16(sp, esp),
+ DEFINE_GPR_PSEUDO_8H(ah, eax), DEFINE_GPR_PSEUDO_8H(bh, ebx),
+ DEFINE_GPR_PSEUDO_8H(ch, ecx), DEFINE_GPR_PSEUDO_8H(dh, edx),
+ DEFINE_GPR_PSEUDO_8L(al, eax), DEFINE_GPR_PSEUDO_8L(bl, ebx),
+ DEFINE_GPR_PSEUDO_8L(cl, ecx), DEFINE_GPR_PSEUDO_8L(dl, edx),
// i387 Floating point registers.
- DEFINE_FPR(fctrl, fctrl, LLDB_INVALID_REGNUM, dwarf_fctrl_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(fstat, fstat, LLDB_INVALID_REGNUM, dwarf_fstat_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(ftag, ftag, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(fop, fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(fiseg, ptr.i386_.fiseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(fioff, ptr.i386_.fioff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(foseg, ptr.i386_.foseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(fooff, ptr.i386_.fooff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(mxcsr, mxcsr, LLDB_INVALID_REGNUM, dwarf_mxcsr_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(mxcsrmask, mxcsrmask, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fctrl, fctrl, LLDB_INVALID_REGNUM, dwarf_fctrl_i386,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fstat, fstat, LLDB_INVALID_REGNUM, dwarf_fstat_i386,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(ftag, ftag, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fop, fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fiseg, ptr.i386_.fiseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fioff, ptr.i386_.fioff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(foseg, ptr.i386_.foseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fooff, ptr.i386_.fooff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(mxcsr, mxcsr, LLDB_INVALID_REGNUM, dwarf_mxcsr_i386,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(mxcsrmask, mxcsrmask, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
// FP registers.
- DEFINE_FP_ST(st, 0),
- DEFINE_FP_ST(st, 1),
- DEFINE_FP_ST(st, 2),
- DEFINE_FP_ST(st, 3),
- DEFINE_FP_ST(st, 4),
- DEFINE_FP_ST(st, 5),
- DEFINE_FP_ST(st, 6),
- DEFINE_FP_ST(st, 7),
- DEFINE_FP_MM(mm, 0),
- DEFINE_FP_MM(mm, 1),
- DEFINE_FP_MM(mm, 2),
- DEFINE_FP_MM(mm, 3),
- DEFINE_FP_MM(mm, 4),
- DEFINE_FP_MM(mm, 5),
- DEFINE_FP_MM(mm, 6),
+ DEFINE_FP_ST(st, 0), DEFINE_FP_ST(st, 1), DEFINE_FP_ST(st, 2),
+ DEFINE_FP_ST(st, 3), DEFINE_FP_ST(st, 4), DEFINE_FP_ST(st, 5),
+ DEFINE_FP_ST(st, 6), DEFINE_FP_ST(st, 7), DEFINE_FP_MM(mm, 0),
+ DEFINE_FP_MM(mm, 1), DEFINE_FP_MM(mm, 2), DEFINE_FP_MM(mm, 3),
+ DEFINE_FP_MM(mm, 4), DEFINE_FP_MM(mm, 5), DEFINE_FP_MM(mm, 6),
DEFINE_FP_MM(mm, 7),
// XMM registers
- DEFINE_XMM(xmm, 0),
- DEFINE_XMM(xmm, 1),
- DEFINE_XMM(xmm, 2),
- DEFINE_XMM(xmm, 3),
- DEFINE_XMM(xmm, 4),
- DEFINE_XMM(xmm, 5),
- DEFINE_XMM(xmm, 6),
- DEFINE_XMM(xmm, 7),
+ DEFINE_XMM(xmm, 0), DEFINE_XMM(xmm, 1), DEFINE_XMM(xmm, 2),
+ DEFINE_XMM(xmm, 3), DEFINE_XMM(xmm, 4), DEFINE_XMM(xmm, 5),
+ DEFINE_XMM(xmm, 6), DEFINE_XMM(xmm, 7),
// Copy of YMM registers assembled from xmm and ymmh
- DEFINE_YMM(ymm, 0),
- DEFINE_YMM(ymm, 1),
- DEFINE_YMM(ymm, 2),
- DEFINE_YMM(ymm, 3),
- DEFINE_YMM(ymm, 4),
- DEFINE_YMM(ymm, 5),
- DEFINE_YMM(ymm, 6),
- DEFINE_YMM(ymm, 7),
+ DEFINE_YMM(ymm, 0), DEFINE_YMM(ymm, 1), DEFINE_YMM(ymm, 2),
+ DEFINE_YMM(ymm, 3), DEFINE_YMM(ymm, 4), DEFINE_YMM(ymm, 5),
+ DEFINE_YMM(ymm, 6), DEFINE_YMM(ymm, 7),
+
+ // MPX registers
+ DEFINE_BNDR(bnd, 0),
+ DEFINE_BNDR(bnd, 1),
+ DEFINE_BNDR(bnd, 2),
+ DEFINE_BNDR(bnd, 3),
+
+ DEFINE_BNDC(bndcfgu, 0),
+ DEFINE_BNDC(bndstatus, 1),
// Debug registers for lldb internal use
- DEFINE_DR(dr, 0),
- DEFINE_DR(dr, 1),
- DEFINE_DR(dr, 2),
- DEFINE_DR(dr, 3),
- DEFINE_DR(dr, 4),
- DEFINE_DR(dr, 5),
- DEFINE_DR(dr, 6),
- DEFINE_DR(dr, 7)
-};
-
-static_assert((sizeof(g_register_infos_i386) / sizeof(g_register_infos_i386[0])) == k_num_registers_i386,
- "g_register_infos_x86_64 has wrong number of register infos");
+ DEFINE_DR(dr, 0), DEFINE_DR(dr, 1), DEFINE_DR(dr, 2), DEFINE_DR(dr, 3),
+ DEFINE_DR(dr, 4), DEFINE_DR(dr, 5), DEFINE_DR(dr, 6), DEFINE_DR(dr, 7)};
+
+static_assert((sizeof(g_register_infos_i386) /
+ sizeof(g_register_infos_i386[0])) == k_num_registers_i386,
+ "g_register_infos_x86_64 has wrong number of register infos");
#undef GPR_OFFSET
#undef FPR_OFFSET
@@ -214,6 +297,8 @@ static_assert((sizeof(g_register_infos_i386) / sizeof(g_register_infos_i386[0]))
#undef DEFINE_FP
#undef DEFINE_XMM
#undef DEFINE_YMM
+#undef DEFINE_BNDR
+#undef DEFINE_BNDC
#undef DEFINE_DR
#undef DEFINE_GPR_PSEUDO_16
#undef DEFINE_GPR_PSEUDO_8H
diff --git a/source/Plugins/Process/Utility/RegisterInfos_mips.h b/source/Plugins/Process/Utility/RegisterInfos_mips.h
index 81294e7b0d97..b116b99b3f81 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_mips.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_mips.h
@@ -12,27 +12,27 @@
// C++ Includes
// Other libraries and framework includes
-#include "llvm/Support/Compiler.h"
#include "lldb/Core/dwarf.h"
+#include "llvm/Support/Compiler.h"
// Project includes
#ifdef DECLARE_REGISTER_INFOS_MIPS_STRUCT
// Computes the offset of the given GPR in the user data area.
-#define GPR_OFFSET(regname) \
- (LLVM_EXTENSION offsetof(UserArea, gpr) + \
- LLVM_EXTENSION offsetof(GPR_linux_mips, regname))
+#define GPR_OFFSET(regname) \
+ (LLVM_EXTENSION offsetof(UserArea, gpr) + \
+ LLVM_EXTENSION offsetof(GPR_linux_mips, regname))
// Computes the offset of the given FPR in the extended data area.
-#define FPR_OFFSET(regname) \
- (LLVM_EXTENSION offsetof(UserArea, fpr) + \
- LLVM_EXTENSION offsetof(FPR_linux_mips, regname))
+#define FPR_OFFSET(regname) \
+ (LLVM_EXTENSION offsetof(UserArea, fpr) + \
+ LLVM_EXTENSION offsetof(FPR_linux_mips, regname))
// Computes the offset of the given MSA in the extended data area.
-#define MSA_OFFSET(regname) \
- (LLVM_EXTENSION offsetof(UserArea, msa) + \
- LLVM_EXTENSION offsetof(MSA_linux_mips, regname))
+#define MSA_OFFSET(regname) \
+ (LLVM_EXTENSION offsetof(UserArea, msa) + \
+ LLVM_EXTENSION offsetof(MSA_linux_mips, regname))
// Note that the size and offset will be updated by platform-specific classes.
#define DEFINE_GPR(reg, alt, kind1, kind2, kind3) \
@@ -44,11 +44,10 @@
NULL, NULL, NULL, 0 \
}
-const uint8_t dwarf_opcode_mips [] = {
- llvm::dwarf::DW_OP_regx, dwarf_sr_mips, llvm::dwarf::DW_OP_lit1,
- llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shl, llvm::dwarf::DW_OP_and,
- llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shr
- };
+const uint8_t dwarf_opcode_mips[] = {
+ llvm::dwarf::DW_OP_regx, dwarf_sr_mips, llvm::dwarf::DW_OP_lit1,
+ llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shl, llvm::dwarf::DW_OP_and,
+ llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shr};
#define DEFINE_FPR(reg, alt, kind1, kind2, kind3) \
{ \
@@ -69,13 +68,23 @@ const uint8_t dwarf_opcode_mips [] = {
NULL, NULL, NULL, 0 \
}
-#define DEFINE_MSA(reg, alt, kind1, kind2, kind3, kind4) \
- { #reg, alt, sizeof(((MSA_linux_mips*)0)->reg), MSA_OFFSET(reg), eEncodingVector, \
- eFormatVectorOfUInt8, { kind1, kind2, kind3, kind4, msa_##reg##_mips }, NULL, NULL, NULL, 0}
+#define DEFINE_MSA(reg, alt, kind1, kind2, kind3, kind4) \
+ { \
+ #reg, alt, sizeof(((MSA_linux_mips *) 0)->reg), \
+ MSA_OFFSET(reg), eEncodingVector, eFormatVectorOfUInt8, \
+ {kind1, kind2, kind3, kind4, \
+ msa_##reg##_mips }, \
+ NULL, NULL, NULL, 0 \
+ }
-#define DEFINE_MSA_INFO(reg, alt, kind1, kind2, kind3, kind4) \
- { #reg, alt, sizeof(((MSA_linux_mips*)0)->reg), MSA_OFFSET(reg), eEncodingUint, \
- eFormatHex, { kind1, kind2, kind3, kind4, msa_##reg##_mips }, NULL, NULL, NULL, 0}
+#define DEFINE_MSA_INFO(reg, alt, kind1, kind2, kind3, kind4) \
+ { \
+ #reg, alt, sizeof(((MSA_linux_mips *) 0)->reg), \
+ MSA_OFFSET(reg), eEncodingUint, eFormatHex, \
+ {kind1, kind2, kind3, kind4, \
+ msa_##reg##_mips }, \
+ NULL, NULL, NULL, 0 \
+ }
// RegisterKind: EH_Frame, DWARF, Generic, Procss Plugin, LLDB
@@ -283,11 +292,11 @@ static RegisterInfo g_register_infos_mips[] = {
DEFINE_MSA_INFO(fir, nullptr, dwarf_fir_mips, dwarf_fir_mips,
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
DEFINE_MSA_INFO(config5, nullptr, dwarf_config5_mips, dwarf_config5_mips,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM)
-};
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM)};
-static_assert((sizeof(g_register_infos_mips) / sizeof(g_register_infos_mips[0])) == k_num_registers_mips,
- "g_register_infos_mips has wrong number of register infos");
+static_assert((sizeof(g_register_infos_mips) /
+ sizeof(g_register_infos_mips[0])) == k_num_registers_mips,
+ "g_register_infos_mips has wrong number of register infos");
#undef GPR_OFFSET
#undef FPR_OFFSET
diff --git a/source/Plugins/Process/Utility/RegisterInfos_mips64.h b/source/Plugins/Process/Utility/RegisterInfos_mips64.h
index 5e9c503ca880..3c3912fa6978 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_mips64.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_mips64.h
@@ -12,8 +12,8 @@
// C++ Includes
// Other libraries and framework includes
-#include "llvm/Support/Compiler.h"
#include "lldb/Core/dwarf.h"
+#include "llvm/Support/Compiler.h"
// Project includes
@@ -21,23 +21,22 @@
// Computes the offset of the given GPR in the user data area.
#ifdef LINUX_MIPS64
- #define GPR_OFFSET(regname) \
- (LLVM_EXTENSION offsetof(UserArea, gpr) + \
- LLVM_EXTENSION offsetof(GPR_linux_mips, regname))
+#define GPR_OFFSET(regname) \
+ (LLVM_EXTENSION offsetof(UserArea, gpr) + \
+ LLVM_EXTENSION offsetof(GPR_linux_mips, regname))
#else
- #define GPR_OFFSET(regname) \
- (LLVM_EXTENSION offsetof(GPR_freebsd_mips, regname))
+#define GPR_OFFSET(regname) (LLVM_EXTENSION offsetof(GPR_freebsd_mips, regname))
#endif
// Computes the offset of the given FPR in the extended data area.
-#define FPR_OFFSET(regname) \
- (LLVM_EXTENSION offsetof(UserArea, fpr) + \
- LLVM_EXTENSION offsetof(FPR_linux_mips, regname))
+#define FPR_OFFSET(regname) \
+ (LLVM_EXTENSION offsetof(UserArea, fpr) + \
+ LLVM_EXTENSION offsetof(FPR_linux_mips, regname))
// Computes the offset of the given MSA in the extended data area.
-#define MSA_OFFSET(regname) \
- (LLVM_EXTENSION offsetof(UserArea, msa) + \
- LLVM_EXTENSION offsetof(MSA_linux_mips, regname))
+#define MSA_OFFSET(regname) \
+ (LLVM_EXTENSION offsetof(UserArea, msa) + \
+ LLVM_EXTENSION offsetof(MSA_linux_mips, regname))
// RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB
@@ -52,9 +51,14 @@
NULL, NULL, NULL, 0 \
}
#else
- #define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
- { #reg, alt, sizeof(((GPR_freebsd_mips*)0)->reg), GPR_OFFSET(reg), eEncodingUint, \
- eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg##_mips64 }, NULL, NULL, NULL, 0}
+#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
+ { \
+ #reg, alt, sizeof(((GPR_freebsd_mips *) 0)->reg), \
+ GPR_OFFSET(reg), eEncodingUint, eFormatHex, \
+ {kind1, kind2, kind3, kind4, \
+ gpr_##reg##_mips64 }, \
+ NULL, NULL, NULL, 0 \
+ }
#endif
#define DEFINE_GPR_INFO(reg, alt, kind1, kind2, kind3) \
@@ -66,11 +70,10 @@
NULL, NULL, NULL, 0 \
}
-const uint8_t dwarf_opcode_mips64 [] = {
- llvm::dwarf::DW_OP_regx, dwarf_sr_mips64, llvm::dwarf::DW_OP_lit1,
- llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shl, llvm::dwarf::DW_OP_and,
- llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shr
- };
+const uint8_t dwarf_opcode_mips64[] = {
+ llvm::dwarf::DW_OP_regx, dwarf_sr_mips64, llvm::dwarf::DW_OP_lit1,
+ llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shl, llvm::dwarf::DW_OP_and,
+ llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shr};
#define DEFINE_FPR(reg, alt, kind1, kind2, kind3) \
{ \
@@ -91,60 +94,108 @@ const uint8_t dwarf_opcode_mips64 [] = {
NULL, NULL, NULL, 0 \
}
+#define DEFINE_MSA(reg, alt, kind1, kind2, kind3, kind4) \
+ { \
+ #reg, alt, sizeof(((MSA_linux_mips *) 0)->reg), \
+ MSA_OFFSET(reg), eEncodingVector, eFormatVectorOfUInt8, \
+ {kind1, kind2, kind3, kind4, \
+ msa_##reg##_mips64 }, \
+ NULL, NULL, NULL, 0 \
+ }
-#define DEFINE_MSA(reg, alt, kind1, kind2, kind3, kind4) \
- { #reg, alt, sizeof(((MSA_linux_mips*)0)->reg), MSA_OFFSET(reg), eEncodingVector, \
- eFormatVectorOfUInt8, { kind1, kind2, kind3, kind4, msa_##reg##_mips64 }, NULL, NULL, NULL, 0}
-
-#define DEFINE_MSA_INFO(reg, alt, kind1, kind2, kind3, kind4) \
- { #reg, alt, sizeof(((MSA_linux_mips*)0)->reg), MSA_OFFSET(reg), eEncodingUint, \
- eFormatHex, { kind1, kind2, kind3, kind4, msa_##reg##_mips64 }, NULL, NULL, NULL, 0}
+#define DEFINE_MSA_INFO(reg, alt, kind1, kind2, kind3, kind4) \
+ { \
+ #reg, alt, sizeof(((MSA_linux_mips *) 0)->reg), \
+ MSA_OFFSET(reg), eEncodingUint, eFormatHex, \
+ {kind1, kind2, kind3, kind4, \
+ msa_##reg##_mips64 }, \
+ NULL, NULL, NULL, 0 \
+ }
-static RegisterInfo
-g_register_infos_mips64[] =
-{
- // General purpose registers. EH_Frame, DWARF, Generic, Process Plugin
+static RegisterInfo g_register_infos_mips64[] = {
+// General purpose registers. EH_Frame, DWARF,
+// Generic, Process Plugin
#ifndef LINUX_MIPS64
- DEFINE_GPR(zero, "r0", dwarf_zero_mips64, dwarf_zero_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r1, nullptr, dwarf_r1_mips64, dwarf_r1_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r2, nullptr, dwarf_r2_mips64, dwarf_r2_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r3, nullptr, dwarf_r3_mips64, dwarf_r3_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r4, nullptr, dwarf_r4_mips64, dwarf_r4_mips64, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r5, nullptr, dwarf_r5_mips64, dwarf_r5_mips64, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r6, nullptr, dwarf_r6_mips64, dwarf_r6_mips64, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r7, nullptr, dwarf_r7_mips64, dwarf_r7_mips64, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r8, nullptr, dwarf_r8_mips64, dwarf_r8_mips64, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r9, nullptr, dwarf_r9_mips64, dwarf_r9_mips64, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r10, nullptr, dwarf_r10_mips64, dwarf_r10_mips64, LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r11, nullptr, dwarf_r11_mips64, dwarf_r11_mips64, LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r12, nullptr, dwarf_r12_mips64, dwarf_r12_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r13, nullptr, dwarf_r13_mips64, dwarf_r13_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r14, nullptr, dwarf_r14_mips64, dwarf_r14_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r15, nullptr, dwarf_r15_mips64, dwarf_r15_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r16, nullptr, dwarf_r16_mips64, dwarf_r16_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r17, nullptr, dwarf_r17_mips64, dwarf_r17_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r18, nullptr, dwarf_r18_mips64, dwarf_r18_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r19, nullptr, dwarf_r19_mips64, dwarf_r19_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r20, nullptr, dwarf_r20_mips64, dwarf_r20_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r21, nullptr, dwarf_r21_mips64, dwarf_r21_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r22, nullptr, dwarf_r22_mips64, dwarf_r22_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r23, nullptr, dwarf_r23_mips64, dwarf_r23_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r24, nullptr, dwarf_r24_mips64, dwarf_r24_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r25, nullptr, dwarf_r25_mips64, dwarf_r25_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r26, nullptr, dwarf_r26_mips64, dwarf_r26_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r27, nullptr, dwarf_r27_mips64, dwarf_r27_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(gp, "r28", dwarf_gp_mips64, dwarf_gp_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(sp, "r29", dwarf_sp_mips64, dwarf_sp_mips64, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r30, nullptr, dwarf_r30_mips64, dwarf_r30_mips64, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM),
- DEFINE_GPR(ra, "r31", dwarf_ra_mips64, dwarf_ra_mips64, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM),
- DEFINE_GPR(sr, nullptr, dwarf_sr_mips64, dwarf_sr_mips64, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM),
- DEFINE_GPR(mullo, nullptr, dwarf_lo_mips64, dwarf_lo_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(mulhi, nullptr, dwarf_hi_mips64, dwarf_hi_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(badvaddr, nullptr, dwarf_bad_mips64, dwarf_bad_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(cause, nullptr, dwarf_cause_mips64, dwarf_cause_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(pc, "pc", dwarf_pc_mips64, dwarf_pc_mips64, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM),
- DEFINE_GPR(ic, nullptr, dwarf_ic_mips64, dwarf_ic_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(dummy, nullptr, dwarf_dummy_mips64, dwarf_dummy_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(zero, "r0", dwarf_zero_mips64, dwarf_zero_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r1, nullptr, dwarf_r1_mips64, dwarf_r1_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r2, nullptr, dwarf_r2_mips64, dwarf_r2_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r3, nullptr, dwarf_r3_mips64, dwarf_r3_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r4, nullptr, dwarf_r4_mips64, dwarf_r4_mips64,
+ LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r5, nullptr, dwarf_r5_mips64, dwarf_r5_mips64,
+ LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r6, nullptr, dwarf_r6_mips64, dwarf_r6_mips64,
+ LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r7, nullptr, dwarf_r7_mips64, dwarf_r7_mips64,
+ LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r8, nullptr, dwarf_r8_mips64, dwarf_r8_mips64,
+ LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r9, nullptr, dwarf_r9_mips64, dwarf_r9_mips64,
+ LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r10, nullptr, dwarf_r10_mips64, dwarf_r10_mips64,
+ LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r11, nullptr, dwarf_r11_mips64, dwarf_r11_mips64,
+ LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r12, nullptr, dwarf_r12_mips64, dwarf_r12_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r13, nullptr, dwarf_r13_mips64, dwarf_r13_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r14, nullptr, dwarf_r14_mips64, dwarf_r14_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r15, nullptr, dwarf_r15_mips64, dwarf_r15_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r16, nullptr, dwarf_r16_mips64, dwarf_r16_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r17, nullptr, dwarf_r17_mips64, dwarf_r17_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r18, nullptr, dwarf_r18_mips64, dwarf_r18_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r19, nullptr, dwarf_r19_mips64, dwarf_r19_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r20, nullptr, dwarf_r20_mips64, dwarf_r20_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r21, nullptr, dwarf_r21_mips64, dwarf_r21_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r22, nullptr, dwarf_r22_mips64, dwarf_r22_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r23, nullptr, dwarf_r23_mips64, dwarf_r23_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r24, nullptr, dwarf_r24_mips64, dwarf_r24_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r25, nullptr, dwarf_r25_mips64, dwarf_r25_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r26, nullptr, dwarf_r26_mips64, dwarf_r26_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r27, nullptr, dwarf_r27_mips64, dwarf_r27_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(gp, "r28", dwarf_gp_mips64, dwarf_gp_mips64, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM),
+ DEFINE_GPR(sp, "r29", dwarf_sp_mips64, dwarf_sp_mips64,
+ LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r30, nullptr, dwarf_r30_mips64, dwarf_r30_mips64,
+ LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ra, "r31", dwarf_ra_mips64, dwarf_ra_mips64,
+ LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(sr, nullptr, dwarf_sr_mips64, dwarf_sr_mips64,
+ LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(mullo, nullptr, dwarf_lo_mips64, dwarf_lo_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(mulhi, nullptr, dwarf_hi_mips64, dwarf_hi_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(badvaddr, nullptr, dwarf_bad_mips64, dwarf_bad_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(cause, nullptr, dwarf_cause_mips64, dwarf_cause_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(pc, "pc", dwarf_pc_mips64, dwarf_pc_mips64,
+ LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ic, nullptr, dwarf_ic_mips64, dwarf_ic_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(dummy, nullptr, dwarf_dummy_mips64, dwarf_dummy_mips64,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
#else
DEFINE_GPR(zero, "r0", dwarf_zero_mips64, dwarf_zero_mips64,
LLDB_INVALID_REGNUM),
@@ -372,8 +423,9 @@ g_register_infos_mips64[] =
#endif
};
-static_assert((sizeof(g_register_infos_mips64) / sizeof(g_register_infos_mips64[0])) == k_num_registers_mips64,
- "g_register_infos_mips64 has wrong number of register infos");
+static_assert((sizeof(g_register_infos_mips64) /
+ sizeof(g_register_infos_mips64[0])) == k_num_registers_mips64,
+ "g_register_infos_mips64 has wrong number of register infos");
#undef DEFINE_GPR
#undef DEFINE_GPR_INFO
diff --git a/source/Plugins/Process/Utility/RegisterInfos_powerpc.h b/source/Plugins/Process/Utility/RegisterInfos_powerpc.h
index 927c73a5551d..c0d47f0d991f 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_powerpc.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_powerpc.h
@@ -10,170 +10,216 @@
#include <stddef.h>
// Computes the offset of the given GPR in the user data area.
-#define GPR_OFFSET(regname) \
- (offsetof(GPR, regname))
-#define FPR_OFFSET(regname) \
- (offsetof(FPR, regname))
-#define VMX_OFFSET(regname) \
- (offsetof(VMX, regname))
-#define GPR_SIZE(regname) \
- (sizeof(((GPR*)NULL)->regname))
+#define GPR_OFFSET(regname) (offsetof(GPR, regname))
+#define FPR_OFFSET(regname) (offsetof(FPR, regname))
+#define VMX_OFFSET(regname) (offsetof(VMX, regname))
+#define GPR_SIZE(regname) (sizeof(((GPR *)NULL)->regname))
#ifdef DECLARE_REGISTER_INFOS_POWERPC_STRUCT
// Note that the size and offset will be updated by platform-specific classes.
-#define DEFINE_GPR(reg, alt, lldb_kind) \
- { #reg, alt, GPR_SIZE(reg), GPR_OFFSET(reg), eEncodingUint, \
- eFormatHex, { dwarf_##reg##_powerpc, dwarf_##reg##_powerpc, lldb_kind, LLDB_INVALID_REGNUM, gpr_##reg##_powerpc }, NULL, NULL, NULL, 0}
-#define DEFINE_FPR(reg, lldb_kind) \
- { #reg, NULL, 8, FPR_OFFSET(reg), eEncodingIEEE754, \
- eFormatFloat, { dwarf_##reg##_powerpc, dwarf_##reg##_powerpc, lldb_kind, LLDB_INVALID_REGNUM, fpr_##reg##_powerpc }, NULL, NULL, NULL, 0}
-#define DEFINE_VMX(reg, lldb_kind) \
- { #reg, NULL, 16, VMX_OFFSET(reg), eEncodingVector, \
- eFormatVectorOfUInt32, { dwarf_##reg##_powerpc, dwarf_##reg##_powerpc, lldb_kind, LLDB_INVALID_REGNUM, vmx_##reg##_powerpc }, NULL, NULL, NULL, 0}
+#define DEFINE_GPR(reg, alt, lldb_kind) \
+ { \
+ #reg, alt, GPR_SIZE(reg), GPR_OFFSET(reg), eEncodingUint, eFormatHex, \
+ {dwarf_##reg##_powerpc, \
+ dwarf_##reg##_powerpc, lldb_kind, \
+ LLDB_INVALID_REGNUM, \
+ gpr_##reg##_powerpc }, \
+ NULL, NULL, NULL, 0 \
+ }
+#define DEFINE_FPR(reg, lldb_kind) \
+ { \
+ #reg, NULL, 8, FPR_OFFSET(reg), eEncodingIEEE754, eFormatFloat, \
+ {dwarf_##reg##_powerpc, dwarf_##reg##_powerpc, \
+ lldb_kind, LLDB_INVALID_REGNUM, \
+ fpr_##reg##_powerpc }, \
+ NULL, NULL, NULL, 0 \
+ }
+#define DEFINE_VMX(reg, lldb_kind) \
+ { \
+ #reg, NULL, 16, VMX_OFFSET(reg), eEncodingVector, eFormatVectorOfUInt32, \
+ {dwarf_##reg##_powerpc, dwarf_##reg##_powerpc, \
+ lldb_kind, LLDB_INVALID_REGNUM, \
+ vmx_##reg##_powerpc }, \
+ NULL, NULL, NULL, 0 \
+ }
- // General purpose registers. EH_Frame, DWARF, Generic, Process Plugin
-#define POWERPC_REGS \
- DEFINE_GPR(r0, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r1, "sp", LLDB_REGNUM_GENERIC_SP), \
- DEFINE_GPR(r2, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r3, "arg1",LLDB_REGNUM_GENERIC_ARG1), \
- DEFINE_GPR(r4, "arg2",LLDB_REGNUM_GENERIC_ARG2), \
- DEFINE_GPR(r5, "arg3",LLDB_REGNUM_GENERIC_ARG3), \
- DEFINE_GPR(r6, "arg4",LLDB_REGNUM_GENERIC_ARG4), \
- DEFINE_GPR(r7, "arg5",LLDB_REGNUM_GENERIC_ARG5), \
- DEFINE_GPR(r8, "arg6",LLDB_REGNUM_GENERIC_ARG6), \
- DEFINE_GPR(r9, "arg7",LLDB_REGNUM_GENERIC_ARG7), \
- DEFINE_GPR(r10, "arg8",LLDB_REGNUM_GENERIC_ARG8), \
- DEFINE_GPR(r11, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r12, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r13, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r14, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r15, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r16, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r17, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r18, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r19, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r20, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r21, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r22, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r23, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r24, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r25, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r26, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r27, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r28, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r29, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r30, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(r31, NULL, LLDB_INVALID_REGNUM), \
- DEFINE_GPR(lr, "lr", LLDB_REGNUM_GENERIC_RA), \
- DEFINE_GPR(cr, "cr", LLDB_REGNUM_GENERIC_FLAGS), \
- DEFINE_GPR(xer, "xer", LLDB_INVALID_REGNUM), \
- DEFINE_GPR(ctr, "ctr", LLDB_INVALID_REGNUM), \
- DEFINE_GPR(pc, "pc", LLDB_REGNUM_GENERIC_PC), \
- DEFINE_FPR(f0, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f1, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f2, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f3, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f4, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f5, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f6, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f7, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f8, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f9, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f10, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f11, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f12, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f13, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f14, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f15, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f16, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f17, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f18, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f19, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f20, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f21, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f22, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f23, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f24, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f25, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f26, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f27, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f28, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f29, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f30, LLDB_INVALID_REGNUM), \
- DEFINE_FPR(f31, LLDB_INVALID_REGNUM), \
- { "fpscr", NULL, 8, FPR_OFFSET(fpscr), eEncodingUint, eFormatHex, { dwarf_fpscr_powerpc, dwarf_fpscr_powerpc, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpr_fpscr_powerpc }, NULL, NULL }, \
- DEFINE_VMX(v0, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v1, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v2, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v3, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v4, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v5, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v6, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v7, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v8, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v9, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v10, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v11, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v12, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v13, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v14, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v15, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v16, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v17, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v18, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v19, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v20, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v21, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v22, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v23, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v24, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v25, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v26, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v27, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v28, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v29, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v30, LLDB_INVALID_REGNUM), \
- DEFINE_VMX(v31, LLDB_INVALID_REGNUM), \
- { "vrsave", NULL, 4, VMX_OFFSET(vrsave), eEncodingUint, eFormatHex, { dwarf_vrsave_powerpc, dwarf_vrsave_powerpc, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, vmx_vrsave_powerpc }, NULL, NULL, NULL, 0}, \
- { "vscr", NULL, 4, VMX_OFFSET(vscr), eEncodingUint, eFormatHex, { dwarf_vscr_powerpc, dwarf_vscr_powerpc, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, vmx_vscr_powerpc }, NULL, NULL, NULL, 0},
+// General purpose registers. EH_Frame, DWARF,
+// Generic, Process Plugin
+#define POWERPC_REGS \
+ DEFINE_GPR(r0, NULL, LLDB_INVALID_REGNUM) \
+ , DEFINE_GPR(r1, "sp", LLDB_REGNUM_GENERIC_SP), \
+ DEFINE_GPR(r2, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r3, "arg1", LLDB_REGNUM_GENERIC_ARG1), \
+ DEFINE_GPR(r4, "arg2", LLDB_REGNUM_GENERIC_ARG2), \
+ DEFINE_GPR(r5, "arg3", LLDB_REGNUM_GENERIC_ARG3), \
+ DEFINE_GPR(r6, "arg4", LLDB_REGNUM_GENERIC_ARG4), \
+ DEFINE_GPR(r7, "arg5", LLDB_REGNUM_GENERIC_ARG5), \
+ DEFINE_GPR(r8, "arg6", LLDB_REGNUM_GENERIC_ARG6), \
+ DEFINE_GPR(r9, "arg7", LLDB_REGNUM_GENERIC_ARG7), \
+ DEFINE_GPR(r10, "arg8", LLDB_REGNUM_GENERIC_ARG8), \
+ DEFINE_GPR(r11, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r12, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r13, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r14, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r15, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r16, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r17, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r18, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r19, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r20, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r21, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r22, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r23, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r24, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r25, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r26, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r27, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r28, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r29, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r30, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r31, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(lr, "lr", LLDB_REGNUM_GENERIC_RA), \
+ DEFINE_GPR(cr, "cr", LLDB_REGNUM_GENERIC_FLAGS), \
+ DEFINE_GPR(xer, "xer", LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(ctr, "ctr", LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(pc, "pc", LLDB_REGNUM_GENERIC_PC), \
+ DEFINE_FPR(f0, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f1, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f2, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f3, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f4, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f5, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f6, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f7, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f8, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f9, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f10, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f11, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f12, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f13, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f14, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f15, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f16, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f17, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f18, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f19, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f20, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f21, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f22, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f23, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f24, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f25, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f26, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f27, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f28, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f29, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f30, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f31, LLDB_INVALID_REGNUM), \
+ {"fpscr", \
+ NULL, \
+ 8, \
+ FPR_OFFSET(fpscr), \
+ eEncodingUint, \
+ eFormatHex, \
+ {dwarf_fpscr_powerpc, dwarf_fpscr_powerpc, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, fpr_fpscr_powerpc}, \
+ NULL, \
+ NULL, \
+ NULL, \
+ 0}, \
+ DEFINE_VMX(v0, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v1, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v2, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v3, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v4, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v5, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v6, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v7, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v8, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v9, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v10, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v11, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v12, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v13, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v14, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v15, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v16, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v17, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v18, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v19, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v20, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v21, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v22, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v23, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v24, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v25, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v26, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v27, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v28, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v29, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v30, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v31, LLDB_INVALID_REGNUM), \
+ {"vrsave", \
+ NULL, \
+ 4, \
+ VMX_OFFSET(vrsave), \
+ eEncodingUint, \
+ eFormatHex, \
+ {dwarf_vrsave_powerpc, dwarf_vrsave_powerpc, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, vmx_vrsave_powerpc}, \
+ NULL, \
+ NULL, \
+ NULL, \
+ 0}, \
+ {"vscr", \
+ NULL, \
+ 4, \
+ VMX_OFFSET(vscr), \
+ eEncodingUint, \
+ eFormatHex, \
+ {dwarf_vscr_powerpc, dwarf_vscr_powerpc, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, vmx_vscr_powerpc}, \
+ NULL, \
+ NULL, \
+ NULL, \
+ 0},
-static RegisterInfo
-g_register_infos_powerpc64[] =
-{
+static RegisterInfo g_register_infos_powerpc64[] = {
#define GPR GPR64
POWERPC_REGS
#undef GPR
};
-static RegisterInfo
-g_register_infos_powerpc32[] =
-{
+static RegisterInfo g_register_infos_powerpc32[] = {
#define GPR GPR32
POWERPC_REGS
#undef GPR
};
-static RegisterInfo
-g_register_infos_powerpc64_32[] =
-{
+static RegisterInfo g_register_infos_powerpc64_32[] = {
#define GPR GPR64
#undef GPR_SIZE
-#define GPR_SIZE(reg) (sizeof(uint32_t))
+#define GPR_SIZE(reg) (sizeof(uint32_t))
#undef GPR_OFFSET
-#define GPR_OFFSET(regname) \
- (offsetof(GPR, regname) + (sizeof(((GPR *)NULL)->regname) - GPR_SIZE(reg)))
+#define GPR_OFFSET(regname) \
+ (offsetof(GPR, regname) + (sizeof(((GPR *)NULL)->regname) - GPR_SIZE(reg)))
POWERPC_REGS
#undef GPR
};
-static_assert((sizeof(g_register_infos_powerpc32) / sizeof(g_register_infos_powerpc32[0])) == k_num_registers_powerpc,
- "g_register_infos_powerpc32 has wrong number of register infos");
-static_assert((sizeof(g_register_infos_powerpc64) / sizeof(g_register_infos_powerpc64[0])) == k_num_registers_powerpc,
- "g_register_infos_powerpc64 has wrong number of register infos");
-static_assert(sizeof(g_register_infos_powerpc64_32) == sizeof(g_register_infos_powerpc64),
- "g_register_infos_powerpc64_32 doesn't match size of g_register_infos_powerpc64");
+static_assert((sizeof(g_register_infos_powerpc32) /
+ sizeof(g_register_infos_powerpc32[0])) ==
+ k_num_registers_powerpc,
+ "g_register_infos_powerpc32 has wrong number of register infos");
+static_assert((sizeof(g_register_infos_powerpc64) /
+ sizeof(g_register_infos_powerpc64[0])) ==
+ k_num_registers_powerpc,
+ "g_register_infos_powerpc64 has wrong number of register infos");
+static_assert(sizeof(g_register_infos_powerpc64_32) ==
+ sizeof(g_register_infos_powerpc64),
+ "g_register_infos_powerpc64_32 doesn't match size of "
+ "g_register_infos_powerpc64");
#undef DEFINE_FPR
#undef DEFINE_GPR
@@ -181,4 +227,3 @@ static_assert(sizeof(g_register_infos_powerpc64_32) == sizeof(g_register_infos_p
#endif // DECLARE_REGISTER_INFOS_POWERPC_STRUCT
#undef GPR_OFFSET
-
diff --git a/source/Plugins/Process/Utility/RegisterInfos_s390x.h b/source/Plugins/Process/Utility/RegisterInfos_s390x.h
index 0710174c0a85..0bbf422405ee 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_s390x.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_s390x.h
@@ -27,36 +27,39 @@
// RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB
-#define DEFINE_GPR(name, size, offset, alt, generic) \
- { \
- #name, alt, size, offset, eEncodingUint, eFormatHex, \
- { dwarf_##name##_s390x, dwarf_##name##_s390x, generic, LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \
- NULL, NULL, NULL, 0 \
- }
-
-#define DEFINE_GPR_NODWARF(name, size, offset, alt, generic) \
- { \
- #name, alt, size, offset, eEncodingUint, eFormatHex, \
- { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, generic, LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \
- NULL, NULL, NULL, 0 \
- }
-
-#define DEFINE_FPR(name, size, offset) \
- { \
- #name, NULL, size, offset, eEncodingUint, eFormatHex, \
- { dwarf_##name##_s390x, dwarf_##name##_s390x, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \
- NULL, NULL, NULL, 0 \
- }
-
-#define DEFINE_FPR_NODWARF(name, size, offset) \
- { \
- #name, NULL, size, offset, eEncodingUint, eFormatHex, \
- { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \
- NULL, NULL, NULL, 0 \
- }
-
-static RegisterInfo g_register_infos_s390x[] =
-{
+#define DEFINE_GPR(name, size, offset, alt, generic) \
+ { \
+ #name, alt, size, offset, eEncodingUint, eFormatHex, \
+ {dwarf_##name##_s390x, dwarf_##name##_s390x, generic, \
+ LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \
+ NULL, NULL, NULL, 0 \
+ }
+
+#define DEFINE_GPR_NODWARF(name, size, offset, alt, generic) \
+ { \
+ #name, alt, size, offset, eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, generic, \
+ LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \
+ NULL, NULL, NULL, 0 \
+ }
+
+#define DEFINE_FPR(name, size, offset) \
+ { \
+ #name, NULL, size, offset, eEncodingUint, eFormatHex, \
+ {dwarf_##name##_s390x, dwarf_##name##_s390x, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \
+ NULL, NULL, NULL, 0 \
+ }
+
+#define DEFINE_FPR_NODWARF(name, size, offset) \
+ { \
+ #name, NULL, size, offset, eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \
+ NULL, NULL, NULL, 0 \
+ }
+
+static RegisterInfo g_register_infos_s390x[] = {
// General purpose registers.
DEFINE_GPR(r0, 8, GPR_OFFSET(0), nullptr, LLDB_INVALID_REGNUM),
DEFINE_GPR(r1, 8, GPR_OFFSET(1), nullptr, LLDB_INVALID_REGNUM),
@@ -94,31 +97,25 @@ static RegisterInfo g_register_infos_s390x[] =
DEFINE_GPR(pswa, 8, 8, "pc", LLDB_REGNUM_GENERIC_PC),
// Floating point registers.
- DEFINE_FPR(f0, 8, FPR_OFFSET(0)),
- DEFINE_FPR(f1, 8, FPR_OFFSET(1)),
- DEFINE_FPR(f2, 8, FPR_OFFSET(2)),
- DEFINE_FPR(f3, 8, FPR_OFFSET(3)),
- DEFINE_FPR(f4, 8, FPR_OFFSET(4)),
- DEFINE_FPR(f5, 8, FPR_OFFSET(5)),
- DEFINE_FPR(f6, 8, FPR_OFFSET(6)),
- DEFINE_FPR(f7, 8, FPR_OFFSET(7)),
- DEFINE_FPR(f8, 8, FPR_OFFSET(8)),
- DEFINE_FPR(f9, 8, FPR_OFFSET(9)),
- DEFINE_FPR(f10, 8, FPR_OFFSET(10)),
- DEFINE_FPR(f11, 8, FPR_OFFSET(11)),
- DEFINE_FPR(f12, 8, FPR_OFFSET(12)),
- DEFINE_FPR(f13, 8, FPR_OFFSET(13)),
- DEFINE_FPR(f14, 8, FPR_OFFSET(14)),
- DEFINE_FPR(f15, 8, FPR_OFFSET(15)),
+ DEFINE_FPR(f0, 8, FPR_OFFSET(0)), DEFINE_FPR(f1, 8, FPR_OFFSET(1)),
+ DEFINE_FPR(f2, 8, FPR_OFFSET(2)), DEFINE_FPR(f3, 8, FPR_OFFSET(3)),
+ DEFINE_FPR(f4, 8, FPR_OFFSET(4)), DEFINE_FPR(f5, 8, FPR_OFFSET(5)),
+ DEFINE_FPR(f6, 8, FPR_OFFSET(6)), DEFINE_FPR(f7, 8, FPR_OFFSET(7)),
+ DEFINE_FPR(f8, 8, FPR_OFFSET(8)), DEFINE_FPR(f9, 8, FPR_OFFSET(9)),
+ DEFINE_FPR(f10, 8, FPR_OFFSET(10)), DEFINE_FPR(f11, 8, FPR_OFFSET(11)),
+ DEFINE_FPR(f12, 8, FPR_OFFSET(12)), DEFINE_FPR(f13, 8, FPR_OFFSET(13)),
+ DEFINE_FPR(f14, 8, FPR_OFFSET(14)), DEFINE_FPR(f15, 8, FPR_OFFSET(15)),
DEFINE_FPR_NODWARF(fpc, 4, 0),
// Linux operating-specific info.
- DEFINE_GPR_NODWARF(orig_r2, 8, 16 + 16 * 8 + 16 * 4, nullptr, LLDB_INVALID_REGNUM),
+ DEFINE_GPR_NODWARF(orig_r2, 8, 16 + 16 * 8 + 16 * 4, nullptr,
+ LLDB_INVALID_REGNUM),
DEFINE_GPR_NODWARF(last_break, 8, 0, nullptr, LLDB_INVALID_REGNUM),
DEFINE_GPR_NODWARF(system_call, 4, 0, nullptr, LLDB_INVALID_REGNUM),
};
-static_assert((sizeof(g_register_infos_s390x) / sizeof(g_register_infos_s390x[0])) == k_num_registers_s390x,
+static_assert((sizeof(g_register_infos_s390x) /
+ sizeof(g_register_infos_s390x[0])) == k_num_registers_s390x,
"g_register_infos_s390x has wrong number of register infos");
#undef GPR_OFFSET
diff --git a/source/Plugins/Process/Utility/RegisterInfos_x86_64.h b/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
index aeb6672ec943..2ba8059911a0 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
@@ -7,40 +7,45 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-#include <stddef.h>
-
-// C++ Includes
-// Other libraries and framework includes
#include "llvm/Support/Compiler.h"
+#include <cstddef>
+#include <cstdint>
// Project includes
// Computes the offset of the given GPR in the user data area.
-#define GPR_OFFSET(regname) \
- (LLVM_EXTENSION offsetof(GPR, regname))
+#define GPR_OFFSET(regname) (LLVM_EXTENSION offsetof(GPR, regname))
// Computes the offset of the given FPR in the extended data area.
-#define FPR_OFFSET(regname) \
- (LLVM_EXTENSION offsetof(UserArea, fpr) + \
- LLVM_EXTENSION offsetof(FPR, xstate) + \
- LLVM_EXTENSION offsetof(FXSAVE, regname))
+#define FPR_OFFSET(regname) \
+ (LLVM_EXTENSION offsetof(UserArea, fpr) + \
+ LLVM_EXTENSION offsetof(FPR, xstate) + \
+ LLVM_EXTENSION offsetof(FXSAVE, regname))
// Computes the offset of the YMM register assembled from register halves.
// Based on DNBArchImplX86_64.cpp from debugserver
-#define YMM_OFFSET(reg_index) \
+#define YMM_OFFSET(reg_index) \
+ (LLVM_EXTENSION offsetof(UserArea, fpr) + \
+ LLVM_EXTENSION offsetof(FPR, xstate) + \
+ LLVM_EXTENSION offsetof(XSAVE, ymmh[0]) + (32 * reg_index))
+
+#define BNDR_OFFSET(reg_index) \
+ (LLVM_EXTENSION offsetof(UserArea, fpr) + \
+ LLVM_EXTENSION offsetof(FPR, xstate) + \
+ LLVM_EXTENSION offsetof(XSAVE, mpxr[reg_index]))
+
+#define BNDC_OFFSET(reg_index) \
(LLVM_EXTENSION offsetof(UserArea, fpr) + \
LLVM_EXTENSION offsetof(FPR, xstate) + \
- LLVM_EXTENSION offsetof(XSAVE, ymmh[0]) + \
- (32 * reg_index))
+ LLVM_EXTENSION offsetof(XSAVE, mpxc[reg_index]))
#ifdef DECLARE_REGISTER_INFOS_X86_64_STRUCT
// Number of bytes needed to represent a FPR.
-#define FPR_SIZE(reg) sizeof(((FXSAVE*)NULL)->reg)
+#define FPR_SIZE(reg) sizeof(((FXSAVE *)nullptr)->reg)
// Number of bytes needed to represent the i'th FP register.
-#define FP_SIZE sizeof(((MMSReg*)NULL)->bytes)
+#define FP_SIZE sizeof(((MMSReg *)nullptr)->bytes)
// Number of bytes needed to represent an XMM register.
#define XMM_SIZE sizeof(XMMReg)
@@ -48,222 +53,260 @@
// Number of bytes needed to represent a YMM register.
#define YMM_SIZE sizeof(YMMReg)
-#define DR_SIZE sizeof(((DBG*)NULL)->dr[0])
+// Number of bytes needed to represent MPX registers.
+#define BNDR_SIZE sizeof(MPXReg)
+#define BNDC_SIZE sizeof(MPXCsr)
+
+#define DR_SIZE sizeof(((DBG *)nullptr)->dr[0])
// RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB
// Note that the size and offset will be updated by platform-specific classes.
-#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
- { #reg, alt, sizeof(((GPR*)NULL)->reg), GPR_OFFSET(reg), eEncodingUint, \
- eFormatHex, { kind1, kind2, kind3, kind4, lldb_##reg##_x86_64 }, NULL, NULL, NULL, 0}
-
-#define DEFINE_FPR(name, reg, kind1, kind2, kind3, kind4) \
- { #name, NULL, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, \
- eFormatHex, { kind1, kind2, kind3, kind4, lldb_##name##_x86_64 }, NULL, NULL, NULL, 0}
-
-#define DEFINE_FP_ST(reg, i) \
- { #reg#i, NULL, FP_SIZE, LLVM_EXTENSION FPR_OFFSET(stmm[i]), \
- eEncodingVector, eFormatVectorOfUInt8, \
- { dwarf_st##i##_x86_64, dwarf_st##i##_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_st##i##_x86_64 }, \
- NULL, NULL, NULL, 0}
-
-#define DEFINE_FP_MM(reg, i) \
- { #reg#i, NULL, sizeof(uint64_t), LLVM_EXTENSION FPR_OFFSET(stmm[i]), \
- eEncodingUint, eFormatHex, \
- { dwarf_mm##i##_x86_64, dwarf_mm##i##_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_mm##i##_x86_64 }, \
- NULL, NULL, NULL, 0}
-
-#define DEFINE_XMM(reg, i) \
- { #reg#i, NULL, XMM_SIZE, LLVM_EXTENSION FPR_OFFSET(reg[i]), \
- eEncodingVector, eFormatVectorOfUInt8, \
- { dwarf_##reg##i##_x86_64, dwarf_##reg##i##_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg##i##_x86_64}, \
- NULL, NULL, NULL, 0}
-
-#define DEFINE_YMM(reg, i) \
- { #reg#i, NULL, YMM_SIZE, LLVM_EXTENSION YMM_OFFSET(i), \
- eEncodingVector, eFormatVectorOfUInt8, \
- { dwarf_##reg##i##h_x86_64, dwarf_##reg##i##h_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg##i##_x86_64 }, \
- NULL, NULL, NULL, 0}
-
-#define DEFINE_DR(reg, i) \
- { #reg#i, NULL, DR_SIZE, DR_OFFSET(i), eEncodingUint, eFormatHex, \
- { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL, NULL, 0}
-
-#define DEFINE_GPR_PSEUDO_32(reg32, reg64) \
- { #reg32, NULL, 4, GPR_OFFSET(reg64), eEncodingUint, \
- eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg32##_x86_64 }, RegisterContextPOSIX_x86::g_contained_##reg64, RegisterContextPOSIX_x86::g_invalidate_##reg64, NULL, 0}
-#define DEFINE_GPR_PSEUDO_16(reg16, reg64) \
- { #reg16, NULL, 2, GPR_OFFSET(reg64), eEncodingUint, \
- eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg16##_x86_64 }, RegisterContextPOSIX_x86::g_contained_##reg64, RegisterContextPOSIX_x86::g_invalidate_##reg64, NULL, 0}
-#define DEFINE_GPR_PSEUDO_8H(reg8, reg64) \
- { #reg8, NULL, 1, GPR_OFFSET(reg64)+1, eEncodingUint, \
- eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg8##_x86_64 }, RegisterContextPOSIX_x86::g_contained_##reg64, RegisterContextPOSIX_x86::g_invalidate_##reg64, NULL, 0}
-#define DEFINE_GPR_PSEUDO_8L(reg8, reg64) \
- { #reg8, NULL, 1, GPR_OFFSET(reg64), eEncodingUint, \
- eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg8##_x86_64 }, RegisterContextPOSIX_x86::g_contained_##reg64, RegisterContextPOSIX_x86::g_invalidate_##reg64, NULL, 0}
-
-static RegisterInfo
-g_register_infos_x86_64[] =
-{
- // General purpose registers. EH_Frame, DWARF, Generic, Process Plugin
- DEFINE_GPR(rax, nullptr, dwarf_rax_x86_64, dwarf_rax_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rbx, nullptr, dwarf_rbx_x86_64, dwarf_rbx_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rcx, "arg4", dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rdx, "arg3", dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rdi, "arg1", dwarf_rdi_x86_64, dwarf_rdi_x86_64, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rsi, "arg2", dwarf_rsi_x86_64, dwarf_rsi_x86_64, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rbp, "fp", dwarf_rbp_x86_64, dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rsp, "sp", dwarf_rsp_x86_64, dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r8, "arg5", dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r9, "arg6", dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r10, nullptr, dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r11, nullptr, dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r12, nullptr, dwarf_r12_x86_64, dwarf_r12_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r13, nullptr, dwarf_r13_x86_64, dwarf_r13_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r14, nullptr, dwarf_r14_x86_64, dwarf_r14_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(r15, nullptr, dwarf_r15_x86_64, dwarf_r15_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rip, "pc", dwarf_rip_x86_64, dwarf_rip_x86_64, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM),
- DEFINE_GPR(rflags, "flags", dwarf_rflags_x86_64, dwarf_rflags_x86_64, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM),
- DEFINE_GPR(cs, nullptr, dwarf_cs_x86_64, dwarf_cs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(fs, nullptr, dwarf_fs_x86_64, dwarf_fs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(gs, nullptr, dwarf_gs_x86_64, dwarf_gs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(ss, nullptr, dwarf_ss_x86_64, dwarf_ss_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(ds, nullptr, dwarf_ds_x86_64, dwarf_ds_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_GPR(es, nullptr, dwarf_es_x86_64, dwarf_es_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-
- DEFINE_GPR_PSEUDO_32(eax, rax),
- DEFINE_GPR_PSEUDO_32(ebx, rbx),
- DEFINE_GPR_PSEUDO_32(ecx, rcx),
- DEFINE_GPR_PSEUDO_32(edx, rdx),
- DEFINE_GPR_PSEUDO_32(edi, rdi),
- DEFINE_GPR_PSEUDO_32(esi, rsi),
- DEFINE_GPR_PSEUDO_32(ebp, rbp),
- DEFINE_GPR_PSEUDO_32(esp, rsp),
- DEFINE_GPR_PSEUDO_32(r8d, r8),
- DEFINE_GPR_PSEUDO_32(r9d, r9),
- DEFINE_GPR_PSEUDO_32(r10d, r10),
- DEFINE_GPR_PSEUDO_32(r11d, r11),
- DEFINE_GPR_PSEUDO_32(r12d, r12),
- DEFINE_GPR_PSEUDO_32(r13d, r13),
- DEFINE_GPR_PSEUDO_32(r14d, r14),
- DEFINE_GPR_PSEUDO_32(r15d, r15),
- DEFINE_GPR_PSEUDO_16(ax, rax),
- DEFINE_GPR_PSEUDO_16(bx, rbx),
- DEFINE_GPR_PSEUDO_16(cx, rcx),
- DEFINE_GPR_PSEUDO_16(dx, rdx),
- DEFINE_GPR_PSEUDO_16(di, rdi),
- DEFINE_GPR_PSEUDO_16(si, rsi),
- DEFINE_GPR_PSEUDO_16(bp, rbp),
- DEFINE_GPR_PSEUDO_16(sp, rsp),
- DEFINE_GPR_PSEUDO_16(r8w, r8),
- DEFINE_GPR_PSEUDO_16(r9w, r9),
- DEFINE_GPR_PSEUDO_16(r10w, r10),
- DEFINE_GPR_PSEUDO_16(r11w, r11),
- DEFINE_GPR_PSEUDO_16(r12w, r12),
- DEFINE_GPR_PSEUDO_16(r13w, r13),
- DEFINE_GPR_PSEUDO_16(r14w, r14),
- DEFINE_GPR_PSEUDO_16(r15w, r15),
- DEFINE_GPR_PSEUDO_8H(ah, rax),
- DEFINE_GPR_PSEUDO_8H(bh, rbx),
- DEFINE_GPR_PSEUDO_8H(ch, rcx),
- DEFINE_GPR_PSEUDO_8H(dh, rdx),
- DEFINE_GPR_PSEUDO_8L(al, rax),
- DEFINE_GPR_PSEUDO_8L(bl, rbx),
- DEFINE_GPR_PSEUDO_8L(cl, rcx),
- DEFINE_GPR_PSEUDO_8L(dl, rdx),
- DEFINE_GPR_PSEUDO_8L(dil, rdi),
- DEFINE_GPR_PSEUDO_8L(sil, rsi),
- DEFINE_GPR_PSEUDO_8L(bpl, rbp),
- DEFINE_GPR_PSEUDO_8L(spl, rsp),
- DEFINE_GPR_PSEUDO_8L(r8l, r8),
- DEFINE_GPR_PSEUDO_8L(r9l, r9),
- DEFINE_GPR_PSEUDO_8L(r10l, r10),
- DEFINE_GPR_PSEUDO_8L(r11l, r11),
- DEFINE_GPR_PSEUDO_8L(r12l, r12),
- DEFINE_GPR_PSEUDO_8L(r13l, r13),
- DEFINE_GPR_PSEUDO_8L(r14l, r14),
- DEFINE_GPR_PSEUDO_8L(r15l, r15),
-
- // i387 Floating point registers. EH_frame, DWARF, Generic, Process Plugin
- DEFINE_FPR(fctrl, fctrl, dwarf_fctrl_x86_64, dwarf_fctrl_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(fstat, fstat, dwarf_fstat_x86_64, dwarf_fstat_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(ftag, ftag, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(fop, fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(fiseg, ptr.i386_.fiseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(fioff, ptr.i386_.fioff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(foseg, ptr.i386_.foseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(fooff, ptr.i386_.fooff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(mxcsr, mxcsr, dwarf_mxcsr_x86_64, dwarf_mxcsr_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
- DEFINE_FPR(mxcsrmask, mxcsrmask, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
+ { \
+ #reg, alt, sizeof(((GPR *)nullptr)->reg), \
+ GPR_OFFSET(reg), eEncodingUint, eFormatHex, \
+ {kind1, kind2, kind3, kind4, \
+ lldb_##reg##_x86_64 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_FPR(name, reg, kind1, kind2, kind3, kind4) \
+ { \
+ #name, nullptr, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, eFormatHex, \
+ {kind1, kind2, kind3, kind4, \
+ lldb_##name##_x86_64 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_FP_ST(reg, i) \
+ { \
+ #reg #i, nullptr, FP_SIZE, \
+ LLVM_EXTENSION FPR_OFFSET( \
+ stmm[i]), eEncodingVector, eFormatVectorOfUInt8, \
+ {dwarf_st##i##_x86_64, dwarf_st##i##_x86_64, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, lldb_st##i##_x86_64 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_FP_MM(reg, i) \
+ { \
+ #reg #i, nullptr, sizeof(uint64_t), \
+ LLVM_EXTENSION FPR_OFFSET( \
+ stmm[i]), eEncodingUint, eFormatHex, \
+ {dwarf_mm##i##_x86_64, dwarf_mm##i##_x86_64, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_mm##i##_x86_64 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_XMM(reg, i) \
+ { \
+ #reg #i, nullptr, XMM_SIZE, \
+ LLVM_EXTENSION FPR_OFFSET( \
+ reg[i]), eEncodingVector, eFormatVectorOfUInt8, \
+ {dwarf_##reg##i##_x86_64, dwarf_##reg##i##_x86_64, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg##i##_x86_64 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_YMM(reg, i) \
+ { \
+ #reg #i, nullptr, YMM_SIZE, \
+ LLVM_EXTENSION YMM_OFFSET(i), eEncodingVector, eFormatVectorOfUInt8, \
+ {dwarf_##reg##i##h_x86_64, \
+ dwarf_##reg##i##h_x86_64, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg##i##_x86_64 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_BNDR(reg, i) \
+ { \
+ #reg #i, nullptr, BNDR_SIZE, \
+ LLVM_EXTENSION BNDR_OFFSET(i), eEncodingVector, eFormatVectorOfUInt64, \
+ {dwarf_##reg##i##_x86_64, \
+ dwarf_##reg##i##_x86_64, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg##i##_x86_64 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_BNDC(name, i) \
+ { \
+ #name, nullptr, BNDC_SIZE, \
+ LLVM_EXTENSION BNDC_OFFSET(i), eEncodingVector, eFormatVectorOfUInt8, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, lldb_##name##_x86_64 }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_DR(reg, i) \
+ { \
+ #reg #i, nullptr, DR_SIZE, \
+ DR_OFFSET(i), eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM }, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEFINE_GPR_PSEUDO_32(reg32, reg64) \
+ { \
+ #reg32, nullptr, 4, \
+ GPR_OFFSET(reg64), eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg32##_x86_64 }, \
+ RegisterContextPOSIX_x86::g_contained_##reg64, \
+ RegisterContextPOSIX_x86::g_invalidate_##reg64, nullptr, 0 \
+ }
+
+#define DEFINE_GPR_PSEUDO_16(reg16, reg64) \
+ { \
+ #reg16, nullptr, 2, \
+ GPR_OFFSET(reg64), eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg16##_x86_64 }, \
+ RegisterContextPOSIX_x86::g_contained_##reg64, \
+ RegisterContextPOSIX_x86::g_invalidate_##reg64, nullptr, 0 \
+ }
+
+#define DEFINE_GPR_PSEUDO_8H(reg8, reg64) \
+ { \
+ #reg8, nullptr, 1, \
+ GPR_OFFSET(reg64) + 1, eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg8##_x86_64 }, \
+ RegisterContextPOSIX_x86::g_contained_##reg64, \
+ RegisterContextPOSIX_x86::g_invalidate_##reg64, nullptr, 0 \
+ }
+
+#define DEFINE_GPR_PSEUDO_8L(reg8, reg64) \
+ { \
+ #reg8, nullptr, 1, \
+ GPR_OFFSET(reg64), eEncodingUint, eFormatHex, \
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ lldb_##reg8##_x86_64 }, \
+ RegisterContextPOSIX_x86::g_contained_##reg64, \
+ RegisterContextPOSIX_x86::g_invalidate_##reg64, nullptr, 0 \
+ }
+
+// clang-format off
+static RegisterInfo g_register_infos_x86_64[] = {
+// General purpose registers EH_Frame DWARF Generic Process Plugin
+// =========================== ================== ================ ========================= ====================
+ DEFINE_GPR(rax, nullptr, dwarf_rax_x86_64, dwarf_rax_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rbx, nullptr, dwarf_rbx_x86_64, dwarf_rbx_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rcx, "arg4", dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rdx, "arg3", dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rdi, "arg1", dwarf_rdi_x86_64, dwarf_rdi_x86_64, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rsi, "arg2", dwarf_rsi_x86_64, dwarf_rsi_x86_64, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rbp, "fp", dwarf_rbp_x86_64, dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rsp, "sp", dwarf_rsp_x86_64, dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r8, "arg5", dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r9, "arg6", dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r10, nullptr, dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r11, nullptr, dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r12, nullptr, dwarf_r12_x86_64, dwarf_r12_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r13, nullptr, dwarf_r13_x86_64, dwarf_r13_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r14, nullptr, dwarf_r14_x86_64, dwarf_r14_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(r15, nullptr, dwarf_r15_x86_64, dwarf_r15_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rip, "pc", dwarf_rip_x86_64, dwarf_rip_x86_64, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(rflags, "flags", dwarf_rflags_x86_64, dwarf_rflags_x86_64, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(cs, nullptr, dwarf_cs_x86_64, dwarf_cs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(fs, nullptr, dwarf_fs_x86_64, dwarf_fs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(gs, nullptr, dwarf_gs_x86_64, dwarf_gs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ss, nullptr, dwarf_ss_x86_64, dwarf_ss_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ds, nullptr, dwarf_ds_x86_64, dwarf_ds_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(es, nullptr, dwarf_es_x86_64, dwarf_es_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+
+ DEFINE_GPR_PSEUDO_32(eax, rax), DEFINE_GPR_PSEUDO_32(ebx, rbx),
+ DEFINE_GPR_PSEUDO_32(ecx, rcx), DEFINE_GPR_PSEUDO_32(edx, rdx),
+ DEFINE_GPR_PSEUDO_32(edi, rdi), DEFINE_GPR_PSEUDO_32(esi, rsi),
+ DEFINE_GPR_PSEUDO_32(ebp, rbp), DEFINE_GPR_PSEUDO_32(esp, rsp),
+ DEFINE_GPR_PSEUDO_32(r8d, r8), DEFINE_GPR_PSEUDO_32(r9d, r9),
+ DEFINE_GPR_PSEUDO_32(r10d, r10), DEFINE_GPR_PSEUDO_32(r11d, r11),
+ DEFINE_GPR_PSEUDO_32(r12d, r12), DEFINE_GPR_PSEUDO_32(r13d, r13),
+ DEFINE_GPR_PSEUDO_32(r14d, r14), DEFINE_GPR_PSEUDO_32(r15d, r15),
+ DEFINE_GPR_PSEUDO_16(ax, rax), DEFINE_GPR_PSEUDO_16(bx, rbx),
+ DEFINE_GPR_PSEUDO_16(cx, rcx), DEFINE_GPR_PSEUDO_16(dx, rdx),
+ DEFINE_GPR_PSEUDO_16(di, rdi), DEFINE_GPR_PSEUDO_16(si, rsi),
+ DEFINE_GPR_PSEUDO_16(bp, rbp), DEFINE_GPR_PSEUDO_16(sp, rsp),
+ DEFINE_GPR_PSEUDO_16(r8w, r8), DEFINE_GPR_PSEUDO_16(r9w, r9),
+ DEFINE_GPR_PSEUDO_16(r10w, r10), DEFINE_GPR_PSEUDO_16(r11w, r11),
+ DEFINE_GPR_PSEUDO_16(r12w, r12), DEFINE_GPR_PSEUDO_16(r13w, r13),
+ DEFINE_GPR_PSEUDO_16(r14w, r14), DEFINE_GPR_PSEUDO_16(r15w, r15),
+ DEFINE_GPR_PSEUDO_8H(ah, rax), DEFINE_GPR_PSEUDO_8H(bh, rbx),
+ DEFINE_GPR_PSEUDO_8H(ch, rcx), DEFINE_GPR_PSEUDO_8H(dh, rdx),
+ DEFINE_GPR_PSEUDO_8L(al, rax), DEFINE_GPR_PSEUDO_8L(bl, rbx),
+ DEFINE_GPR_PSEUDO_8L(cl, rcx), DEFINE_GPR_PSEUDO_8L(dl, rdx),
+ DEFINE_GPR_PSEUDO_8L(dil, rdi), DEFINE_GPR_PSEUDO_8L(sil, rsi),
+ DEFINE_GPR_PSEUDO_8L(bpl, rbp), DEFINE_GPR_PSEUDO_8L(spl, rsp),
+ DEFINE_GPR_PSEUDO_8L(r8l, r8), DEFINE_GPR_PSEUDO_8L(r9l, r9),
+ DEFINE_GPR_PSEUDO_8L(r10l, r10), DEFINE_GPR_PSEUDO_8L(r11l, r11),
+ DEFINE_GPR_PSEUDO_8L(r12l, r12), DEFINE_GPR_PSEUDO_8L(r13l, r13),
+ DEFINE_GPR_PSEUDO_8L(r14l, r14), DEFINE_GPR_PSEUDO_8L(r15l, r15),
+
+// i387 Floating point registers. EH_frame DWARF Generic Process Plugin
+// ====================================== =============== ================== =================== ====================
+ DEFINE_FPR(fctrl, fctrl, dwarf_fctrl_x86_64, dwarf_fctrl_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fstat, fstat, dwarf_fstat_x86_64, dwarf_fstat_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(ftag, ftag, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fop, fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fiseg, ptr.i386_.fiseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fioff, ptr.i386_.fioff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(foseg, ptr.i386_.foseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(fooff, ptr.i386_.fooff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(mxcsr, mxcsr, dwarf_mxcsr_x86_64, dwarf_mxcsr_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR(mxcsrmask, mxcsrmask, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
// FP registers.
- DEFINE_FP_ST(st, 0),
- DEFINE_FP_ST(st, 1),
- DEFINE_FP_ST(st, 2),
- DEFINE_FP_ST(st, 3),
- DEFINE_FP_ST(st, 4),
- DEFINE_FP_ST(st, 5),
- DEFINE_FP_ST(st, 6),
- DEFINE_FP_ST(st, 7),
- DEFINE_FP_MM(mm, 0),
- DEFINE_FP_MM(mm, 1),
- DEFINE_FP_MM(mm, 2),
- DEFINE_FP_MM(mm, 3),
- DEFINE_FP_MM(mm, 4),
- DEFINE_FP_MM(mm, 5),
- DEFINE_FP_MM(mm, 6),
+ DEFINE_FP_ST(st, 0), DEFINE_FP_ST(st, 1), DEFINE_FP_ST(st, 2),
+ DEFINE_FP_ST(st, 3), DEFINE_FP_ST(st, 4), DEFINE_FP_ST(st, 5),
+ DEFINE_FP_ST(st, 6), DEFINE_FP_ST(st, 7), DEFINE_FP_MM(mm, 0),
+ DEFINE_FP_MM(mm, 1), DEFINE_FP_MM(mm, 2), DEFINE_FP_MM(mm, 3),
+ DEFINE_FP_MM(mm, 4), DEFINE_FP_MM(mm, 5), DEFINE_FP_MM(mm, 6),
DEFINE_FP_MM(mm, 7),
// XMM registers
- DEFINE_XMM(xmm, 0),
- DEFINE_XMM(xmm, 1),
- DEFINE_XMM(xmm, 2),
- DEFINE_XMM(xmm, 3),
- DEFINE_XMM(xmm, 4),
- DEFINE_XMM(xmm, 5),
- DEFINE_XMM(xmm, 6),
- DEFINE_XMM(xmm, 7),
- DEFINE_XMM(xmm, 8),
- DEFINE_XMM(xmm, 9),
- DEFINE_XMM(xmm, 10),
- DEFINE_XMM(xmm, 11),
- DEFINE_XMM(xmm, 12),
- DEFINE_XMM(xmm, 13),
- DEFINE_XMM(xmm, 14),
+ DEFINE_XMM(xmm, 0), DEFINE_XMM(xmm, 1), DEFINE_XMM(xmm, 2),
+ DEFINE_XMM(xmm, 3), DEFINE_XMM(xmm, 4), DEFINE_XMM(xmm, 5),
+ DEFINE_XMM(xmm, 6), DEFINE_XMM(xmm, 7), DEFINE_XMM(xmm, 8),
+ DEFINE_XMM(xmm, 9), DEFINE_XMM(xmm, 10), DEFINE_XMM(xmm, 11),
+ DEFINE_XMM(xmm, 12), DEFINE_XMM(xmm, 13), DEFINE_XMM(xmm, 14),
DEFINE_XMM(xmm, 15),
// Copy of YMM registers assembled from xmm and ymmh
- DEFINE_YMM(ymm, 0),
- DEFINE_YMM(ymm, 1),
- DEFINE_YMM(ymm, 2),
- DEFINE_YMM(ymm, 3),
- DEFINE_YMM(ymm, 4),
- DEFINE_YMM(ymm, 5),
- DEFINE_YMM(ymm, 6),
- DEFINE_YMM(ymm, 7),
- DEFINE_YMM(ymm, 8),
- DEFINE_YMM(ymm, 9),
- DEFINE_YMM(ymm, 10),
- DEFINE_YMM(ymm, 11),
- DEFINE_YMM(ymm, 12),
- DEFINE_YMM(ymm, 13),
- DEFINE_YMM(ymm, 14),
+ DEFINE_YMM(ymm, 0), DEFINE_YMM(ymm, 1), DEFINE_YMM(ymm, 2),
+ DEFINE_YMM(ymm, 3), DEFINE_YMM(ymm, 4), DEFINE_YMM(ymm, 5),
+ DEFINE_YMM(ymm, 6), DEFINE_YMM(ymm, 7), DEFINE_YMM(ymm, 8),
+ DEFINE_YMM(ymm, 9), DEFINE_YMM(ymm, 10), DEFINE_YMM(ymm, 11),
+ DEFINE_YMM(ymm, 12), DEFINE_YMM(ymm, 13), DEFINE_YMM(ymm, 14),
DEFINE_YMM(ymm, 15),
+ // MPX registers
+ DEFINE_BNDR(bnd, 0),
+ DEFINE_BNDR(bnd, 1),
+ DEFINE_BNDR(bnd, 2),
+ DEFINE_BNDR(bnd, 3),
+
+ DEFINE_BNDC(bndcfgu, 0),
+ DEFINE_BNDC(bndstatus, 1),
+
// Debug registers for lldb internal use
- DEFINE_DR(dr, 0),
- DEFINE_DR(dr, 1),
- DEFINE_DR(dr, 2),
- DEFINE_DR(dr, 3),
- DEFINE_DR(dr, 4),
- DEFINE_DR(dr, 5),
- DEFINE_DR(dr, 6),
- DEFINE_DR(dr, 7)
-};
-
-static_assert((sizeof(g_register_infos_x86_64) / sizeof(g_register_infos_x86_64[0])) == k_num_registers_x86_64,
- "g_register_infos_x86_64 has wrong number of register infos");
+ DEFINE_DR(dr, 0), DEFINE_DR(dr, 1), DEFINE_DR(dr, 2), DEFINE_DR(dr, 3),
+ DEFINE_DR(dr, 4), DEFINE_DR(dr, 5), DEFINE_DR(dr, 6), DEFINE_DR(dr, 7)};
+
+// clang-format on
+
+static_assert((sizeof(g_register_infos_x86_64) /
+ sizeof(g_register_infos_x86_64[0])) == k_num_registers_x86_64,
+ "g_register_infos_x86_64 has wrong number of register infos");
#undef FPR_SIZE
#undef FP_SIZE
@@ -274,6 +317,8 @@ static_assert((sizeof(g_register_infos_x86_64) / sizeof(g_register_infos_x86_64[
#undef DEFINE_FP
#undef DEFINE_XMM
#undef DEFINE_YMM
+#undef DEFINE_BNDR
+#undef DEFINE_BNDC
#undef DEFINE_DR
#undef DEFINE_GPR_PSEUDO_32
#undef DEFINE_GPR_PSEUDO_16
@@ -284,130 +329,131 @@ static_assert((sizeof(g_register_infos_x86_64) / sizeof(g_register_infos_x86_64[
#ifdef UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
-#define UPDATE_GPR_INFO(reg, reg64) \
-do { \
- g_register_infos[lldb_##reg##_i386].byte_offset = GPR_OFFSET(reg64); \
-} while(false);
-
-#define UPDATE_GPR_INFO_8H(reg, reg64) \
-do { \
- g_register_infos[lldb_##reg##_i386].byte_offset = GPR_OFFSET(reg64) + 1; \
-} while(false);
-
-#define UPDATE_FPR_INFO(reg, reg64) \
-do { \
- g_register_infos[lldb_##reg##_i386].byte_offset = FPR_OFFSET(reg64); \
-} while(false);
-
-#define UPDATE_FP_INFO(reg, i) \
-do { \
- g_register_infos[lldb_##reg##i##_i386].byte_offset = FPR_OFFSET(stmm[i]); \
-} while(false);
-
-#define UPDATE_XMM_INFO(reg, i) \
-do { \
- g_register_infos[lldb_##reg##i##_i386].byte_offset = FPR_OFFSET(reg[i]); \
-} while(false);
-
-#define UPDATE_YMM_INFO(reg, i) \
-do { \
- g_register_infos[lldb_##reg##i##_i386].byte_offset = YMM_OFFSET(i); \
-} while(false);
-
-#define UPDATE_DR_INFO(reg_index) \
-do { \
- g_register_infos[lldb_dr##reg_index##_i386].byte_offset = DR_OFFSET(reg_index); \
-} while(false);
-
- // Update the register offsets
- UPDATE_GPR_INFO(eax, rax);
- UPDATE_GPR_INFO(ebx, rbx);
- UPDATE_GPR_INFO(ecx, rcx);
- UPDATE_GPR_INFO(edx, rdx);
- UPDATE_GPR_INFO(edi, rdi);
- UPDATE_GPR_INFO(esi, rsi);
- UPDATE_GPR_INFO(ebp, rbp);
- UPDATE_GPR_INFO(esp, rsp);
- UPDATE_GPR_INFO(eip, rip);
- UPDATE_GPR_INFO(eflags, rflags);
- UPDATE_GPR_INFO(cs, cs);
- UPDATE_GPR_INFO(fs, fs);
- UPDATE_GPR_INFO(gs, gs);
- UPDATE_GPR_INFO(ss, ss);
- UPDATE_GPR_INFO(ds, ds);
- UPDATE_GPR_INFO(es, es);
-
- UPDATE_GPR_INFO(ax, rax);
- UPDATE_GPR_INFO(bx, rbx);
- UPDATE_GPR_INFO(cx, rcx);
- UPDATE_GPR_INFO(dx, rdx);
- UPDATE_GPR_INFO(di, rdi);
- UPDATE_GPR_INFO(si, rsi);
- UPDATE_GPR_INFO(bp, rbp);
- UPDATE_GPR_INFO(sp, rsp);
- UPDATE_GPR_INFO_8H(ah, rax);
- UPDATE_GPR_INFO_8H(bh, rbx);
- UPDATE_GPR_INFO_8H(ch, rcx);
- UPDATE_GPR_INFO_8H(dh, rdx);
- UPDATE_GPR_INFO(al, rax);
- UPDATE_GPR_INFO(bl, rbx);
- UPDATE_GPR_INFO(cl, rcx);
- UPDATE_GPR_INFO(dl, rdx);
-
- UPDATE_FPR_INFO(fctrl, fctrl);
- UPDATE_FPR_INFO(fstat, fstat);
- UPDATE_FPR_INFO(ftag, ftag);
- UPDATE_FPR_INFO(fop, fop);
- UPDATE_FPR_INFO(fiseg, ptr.i386_.fiseg);
- UPDATE_FPR_INFO(fioff, ptr.i386_.fioff);
- UPDATE_FPR_INFO(fooff, ptr.i386_.fooff);
- UPDATE_FPR_INFO(foseg, ptr.i386_.foseg);
- UPDATE_FPR_INFO(mxcsr, mxcsr);
- UPDATE_FPR_INFO(mxcsrmask, mxcsrmask);
-
- UPDATE_FP_INFO(st, 0);
- UPDATE_FP_INFO(st, 1);
- UPDATE_FP_INFO(st, 2);
- UPDATE_FP_INFO(st, 3);
- UPDATE_FP_INFO(st, 4);
- UPDATE_FP_INFO(st, 5);
- UPDATE_FP_INFO(st, 6);
- UPDATE_FP_INFO(st, 7);
- UPDATE_FP_INFO(mm, 0);
- UPDATE_FP_INFO(mm, 1);
- UPDATE_FP_INFO(mm, 2);
- UPDATE_FP_INFO(mm, 3);
- UPDATE_FP_INFO(mm, 4);
- UPDATE_FP_INFO(mm, 5);
- UPDATE_FP_INFO(mm, 6);
- UPDATE_FP_INFO(mm, 7);
-
- UPDATE_XMM_INFO(xmm, 0);
- UPDATE_XMM_INFO(xmm, 1);
- UPDATE_XMM_INFO(xmm, 2);
- UPDATE_XMM_INFO(xmm, 3);
- UPDATE_XMM_INFO(xmm, 4);
- UPDATE_XMM_INFO(xmm, 5);
- UPDATE_XMM_INFO(xmm, 6);
- UPDATE_XMM_INFO(xmm, 7);
-
- UPDATE_YMM_INFO(ymm, 0);
- UPDATE_YMM_INFO(ymm, 1);
- UPDATE_YMM_INFO(ymm, 2);
- UPDATE_YMM_INFO(ymm, 3);
- UPDATE_YMM_INFO(ymm, 4);
- UPDATE_YMM_INFO(ymm, 5);
- UPDATE_YMM_INFO(ymm, 6);
- UPDATE_YMM_INFO(ymm, 7);
-
- UPDATE_DR_INFO(0);
- UPDATE_DR_INFO(1);
- UPDATE_DR_INFO(2);
- UPDATE_DR_INFO(3);
- UPDATE_DR_INFO(4);
- UPDATE_DR_INFO(5);
- UPDATE_DR_INFO(6);
- UPDATE_DR_INFO(7);
+#define UPDATE_GPR_INFO(reg, reg64) \
+ do { \
+ g_register_infos[lldb_##reg##_i386].byte_offset = GPR_OFFSET(reg64); \
+ } while (false);
+
+#define UPDATE_GPR_INFO_8H(reg, reg64) \
+ do { \
+ g_register_infos[lldb_##reg##_i386].byte_offset = GPR_OFFSET(reg64) + 1; \
+ } while (false);
+
+#define UPDATE_FPR_INFO(reg, reg64) \
+ do { \
+ g_register_infos[lldb_##reg##_i386].byte_offset = FPR_OFFSET(reg64); \
+ } while (false);
+
+#define UPDATE_FP_INFO(reg, i) \
+ do { \
+ g_register_infos[lldb_##reg##i##_i386].byte_offset = FPR_OFFSET(stmm[i]); \
+ } while (false);
+
+#define UPDATE_XMM_INFO(reg, i) \
+ do { \
+ g_register_infos[lldb_##reg##i##_i386].byte_offset = FPR_OFFSET(reg[i]); \
+ } while (false);
+
+#define UPDATE_YMM_INFO(reg, i) \
+ do { \
+ g_register_infos[lldb_##reg##i##_i386].byte_offset = YMM_OFFSET(i); \
+ } while (false);
+
+#define UPDATE_DR_INFO(reg_index) \
+ do { \
+ g_register_infos[lldb_dr##reg_index##_i386].byte_offset = \
+ DR_OFFSET(reg_index); \
+ } while (false);
+
+// Update the register offsets
+UPDATE_GPR_INFO(eax, rax);
+UPDATE_GPR_INFO(ebx, rbx);
+UPDATE_GPR_INFO(ecx, rcx);
+UPDATE_GPR_INFO(edx, rdx);
+UPDATE_GPR_INFO(edi, rdi);
+UPDATE_GPR_INFO(esi, rsi);
+UPDATE_GPR_INFO(ebp, rbp);
+UPDATE_GPR_INFO(esp, rsp);
+UPDATE_GPR_INFO(eip, rip);
+UPDATE_GPR_INFO(eflags, rflags);
+UPDATE_GPR_INFO(cs, cs);
+UPDATE_GPR_INFO(fs, fs);
+UPDATE_GPR_INFO(gs, gs);
+UPDATE_GPR_INFO(ss, ss);
+UPDATE_GPR_INFO(ds, ds);
+UPDATE_GPR_INFO(es, es);
+
+UPDATE_GPR_INFO(ax, rax);
+UPDATE_GPR_INFO(bx, rbx);
+UPDATE_GPR_INFO(cx, rcx);
+UPDATE_GPR_INFO(dx, rdx);
+UPDATE_GPR_INFO(di, rdi);
+UPDATE_GPR_INFO(si, rsi);
+UPDATE_GPR_INFO(bp, rbp);
+UPDATE_GPR_INFO(sp, rsp);
+UPDATE_GPR_INFO_8H(ah, rax);
+UPDATE_GPR_INFO_8H(bh, rbx);
+UPDATE_GPR_INFO_8H(ch, rcx);
+UPDATE_GPR_INFO_8H(dh, rdx);
+UPDATE_GPR_INFO(al, rax);
+UPDATE_GPR_INFO(bl, rbx);
+UPDATE_GPR_INFO(cl, rcx);
+UPDATE_GPR_INFO(dl, rdx);
+
+UPDATE_FPR_INFO(fctrl, fctrl);
+UPDATE_FPR_INFO(fstat, fstat);
+UPDATE_FPR_INFO(ftag, ftag);
+UPDATE_FPR_INFO(fop, fop);
+UPDATE_FPR_INFO(fiseg, ptr.i386_.fiseg);
+UPDATE_FPR_INFO(fioff, ptr.i386_.fioff);
+UPDATE_FPR_INFO(fooff, ptr.i386_.fooff);
+UPDATE_FPR_INFO(foseg, ptr.i386_.foseg);
+UPDATE_FPR_INFO(mxcsr, mxcsr);
+UPDATE_FPR_INFO(mxcsrmask, mxcsrmask);
+
+UPDATE_FP_INFO(st, 0);
+UPDATE_FP_INFO(st, 1);
+UPDATE_FP_INFO(st, 2);
+UPDATE_FP_INFO(st, 3);
+UPDATE_FP_INFO(st, 4);
+UPDATE_FP_INFO(st, 5);
+UPDATE_FP_INFO(st, 6);
+UPDATE_FP_INFO(st, 7);
+UPDATE_FP_INFO(mm, 0);
+UPDATE_FP_INFO(mm, 1);
+UPDATE_FP_INFO(mm, 2);
+UPDATE_FP_INFO(mm, 3);
+UPDATE_FP_INFO(mm, 4);
+UPDATE_FP_INFO(mm, 5);
+UPDATE_FP_INFO(mm, 6);
+UPDATE_FP_INFO(mm, 7);
+
+UPDATE_XMM_INFO(xmm, 0);
+UPDATE_XMM_INFO(xmm, 1);
+UPDATE_XMM_INFO(xmm, 2);
+UPDATE_XMM_INFO(xmm, 3);
+UPDATE_XMM_INFO(xmm, 4);
+UPDATE_XMM_INFO(xmm, 5);
+UPDATE_XMM_INFO(xmm, 6);
+UPDATE_XMM_INFO(xmm, 7);
+
+UPDATE_YMM_INFO(ymm, 0);
+UPDATE_YMM_INFO(ymm, 1);
+UPDATE_YMM_INFO(ymm, 2);
+UPDATE_YMM_INFO(ymm, 3);
+UPDATE_YMM_INFO(ymm, 4);
+UPDATE_YMM_INFO(ymm, 5);
+UPDATE_YMM_INFO(ymm, 6);
+UPDATE_YMM_INFO(ymm, 7);
+
+UPDATE_DR_INFO(0);
+UPDATE_DR_INFO(1);
+UPDATE_DR_INFO(2);
+UPDATE_DR_INFO(3);
+UPDATE_DR_INFO(4);
+UPDATE_DR_INFO(5);
+UPDATE_DR_INFO(6);
+UPDATE_DR_INFO(7);
#undef UPDATE_GPR_INFO
#undef UPDATE_GPR_INFO_8H
diff --git a/source/Plugins/Process/Utility/StopInfoMachException.cpp b/source/Plugins/Process/Utility/StopInfoMachException.cpp
index 7c0487b1d43b..3b29a18dbe20 100644
--- a/source/Plugins/Process/Utility/StopInfoMachException.cpp
+++ b/source/Plugins/Process/Utility/StopInfoMachException.cpp
@@ -28,508 +28,557 @@
using namespace lldb;
using namespace lldb_private;
-
-const char *
-StopInfoMachException::GetDescription ()
-{
- if (m_description.empty() && m_value != 0)
- {
- ExecutionContext exe_ctx (m_thread_wp.lock());
- Target *target = exe_ctx.GetTargetPtr();
- const llvm::Triple::ArchType cpu = target ? target->GetArchitecture().GetMachine() : llvm::Triple::UnknownArch;
-
- const char *exc_desc = NULL;
- const char *code_label = "code";
- const char *code_desc = NULL;
- const char *subcode_label = "subcode";
- const char *subcode_desc = NULL;
- switch (m_value)
- {
- case 1: // EXC_BAD_ACCESS
- exc_desc = "EXC_BAD_ACCESS";
- subcode_label = "address";
- switch (cpu)
- {
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- switch (m_exc_code)
- {
- case 0xd: code_desc = "EXC_I386_GPFLT"; m_exc_data_count = 1; break;
- }
- break;
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- switch (m_exc_code)
- {
- case 0x101: code_desc = "EXC_ARM_DA_ALIGN"; break;
- case 0x102: code_desc = "EXC_ARM_DA_DEBUG"; break;
- }
- break;
-
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- switch (m_exc_code)
- {
- case 0x101: code_desc = "EXC_PPC_VM_PROT_READ"; break;
- case 0x102: code_desc = "EXC_PPC_BADSPACE"; break;
- case 0x103: code_desc = "EXC_PPC_UNALIGNED"; break;
- }
- break;
-
- default:
- break;
- }
- break;
-
- case 2: // EXC_BAD_INSTRUCTION
- exc_desc = "EXC_BAD_INSTRUCTION";
- switch (cpu)
- {
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- if (m_exc_code == 1)
- code_desc = "EXC_I386_INVOP";
- break;
-
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- switch (m_exc_code)
- {
- case 1: code_desc = "EXC_PPC_INVALID_SYSCALL"; break;
- case 2: code_desc = "EXC_PPC_UNIPL_INST"; break;
- case 3: code_desc = "EXC_PPC_PRIVINST"; break;
- case 4: code_desc = "EXC_PPC_PRIVREG"; break;
- case 5: code_desc = "EXC_PPC_TRACE"; break;
- case 6: code_desc = "EXC_PPC_PERFMON"; break;
- }
- break;
-
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- if (m_exc_code == 1)
- code_desc = "EXC_ARM_UNDEFINED";
- break;
-
- default:
- break;
- }
- break;
-
- case 3: // EXC_ARITHMETIC
- exc_desc = "EXC_ARITHMETIC";
- switch (cpu)
- {
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- switch (m_exc_code)
- {
- case 1: code_desc = "EXC_I386_DIV"; break;
- case 2: code_desc = "EXC_I386_INTO"; break;
- case 3: code_desc = "EXC_I386_NOEXT"; break;
- case 4: code_desc = "EXC_I386_EXTOVR"; break;
- case 5: code_desc = "EXC_I386_EXTERR"; break;
- case 6: code_desc = "EXC_I386_EMERR"; break;
- case 7: code_desc = "EXC_I386_BOUND"; break;
- case 8: code_desc = "EXC_I386_SSEEXTERR"; break;
- }
- break;
-
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- switch (m_exc_code)
- {
- case 1: code_desc = "EXC_PPC_OVERFLOW"; break;
- case 2: code_desc = "EXC_PPC_ZERO_DIVIDE"; break;
- case 3: code_desc = "EXC_PPC_FLT_INEXACT"; break;
- case 4: code_desc = "EXC_PPC_FLT_ZERO_DIVIDE"; break;
- case 5: code_desc = "EXC_PPC_FLT_UNDERFLOW"; break;
- case 6: code_desc = "EXC_PPC_FLT_OVERFLOW"; break;
- case 7: code_desc = "EXC_PPC_FLT_NOT_A_NUMBER"; break;
- }
- break;
-
- default:
- break;
- }
- break;
-
- case 4: // EXC_EMULATION
- exc_desc = "EXC_EMULATION";
- break;
-
-
- case 5: // EXC_SOFTWARE
- exc_desc = "EXC_SOFTWARE";
- if (m_exc_code == 0x10003)
- {
- subcode_desc = "EXC_SOFT_SIGNAL";
- subcode_label = "signo";
- }
- break;
-
- case 6: // EXC_BREAKPOINT
- {
- exc_desc = "EXC_BREAKPOINT";
- switch (cpu)
- {
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- switch (m_exc_code)
- {
- case 1: code_desc = "EXC_I386_SGL"; break;
- case 2: code_desc = "EXC_I386_BPT"; break;
- }
- break;
-
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- switch (m_exc_code)
- {
- case 1: code_desc = "EXC_PPC_BREAKPOINT"; break;
- }
- break;
-
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- switch (m_exc_code)
- {
- case 0x101: code_desc = "EXC_ARM_DA_ALIGN"; break;
- case 0x102: code_desc = "EXC_ARM_DA_DEBUG"; break;
- case 1: code_desc = "EXC_ARM_BREAKPOINT"; break;
- // FIXME temporary workaround, exc_code 0 does not really mean EXC_ARM_BREAKPOINT
- case 0: code_desc = "EXC_ARM_BREAKPOINT"; break;
- }
- break;
-
- default:
- break;
- }
- }
- break;
+const char *StopInfoMachException::GetDescription() {
+ if (m_description.empty() && m_value != 0) {
+ ExecutionContext exe_ctx(m_thread_wp.lock());
+ Target *target = exe_ctx.GetTargetPtr();
+ const llvm::Triple::ArchType cpu =
+ target ? target->GetArchitecture().GetMachine()
+ : llvm::Triple::UnknownArch;
+
+ const char *exc_desc = NULL;
+ const char *code_label = "code";
+ const char *code_desc = NULL;
+ const char *subcode_label = "subcode";
+ const char *subcode_desc = NULL;
+ switch (m_value) {
+ case 1: // EXC_BAD_ACCESS
+ exc_desc = "EXC_BAD_ACCESS";
+ subcode_label = "address";
+ switch (cpu) {
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ switch (m_exc_code) {
+ case 0xd:
+ code_desc = "EXC_I386_GPFLT";
+ m_exc_data_count = 1;
+ break;
+ }
+ break;
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ switch (m_exc_code) {
+ case 0x101:
+ code_desc = "EXC_ARM_DA_ALIGN";
+ break;
+ case 0x102:
+ code_desc = "EXC_ARM_DA_DEBUG";
+ break;
+ }
+ break;
+
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
+ switch (m_exc_code) {
+ case 0x101:
+ code_desc = "EXC_PPC_VM_PROT_READ";
+ break;
+ case 0x102:
+ code_desc = "EXC_PPC_BADSPACE";
+ break;
+ case 0x103:
+ code_desc = "EXC_PPC_UNALIGNED";
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case 2: // EXC_BAD_INSTRUCTION
+ exc_desc = "EXC_BAD_INSTRUCTION";
+ switch (cpu) {
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ if (m_exc_code == 1)
+ code_desc = "EXC_I386_INVOP";
+ break;
+
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
+ switch (m_exc_code) {
+ case 1:
+ code_desc = "EXC_PPC_INVALID_SYSCALL";
+ break;
+ case 2:
+ code_desc = "EXC_PPC_UNIPL_INST";
+ break;
+ case 3:
+ code_desc = "EXC_PPC_PRIVINST";
+ break;
+ case 4:
+ code_desc = "EXC_PPC_PRIVREG";
+ break;
+ case 5:
+ code_desc = "EXC_PPC_TRACE";
+ break;
+ case 6:
+ code_desc = "EXC_PPC_PERFMON";
+ break;
+ }
+ break;
+
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ if (m_exc_code == 1)
+ code_desc = "EXC_ARM_UNDEFINED";
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case 3: // EXC_ARITHMETIC
+ exc_desc = "EXC_ARITHMETIC";
+ switch (cpu) {
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ switch (m_exc_code) {
+ case 1:
+ code_desc = "EXC_I386_DIV";
+ break;
+ case 2:
+ code_desc = "EXC_I386_INTO";
+ break;
+ case 3:
+ code_desc = "EXC_I386_NOEXT";
+ break;
+ case 4:
+ code_desc = "EXC_I386_EXTOVR";
+ break;
+ case 5:
+ code_desc = "EXC_I386_EXTERR";
+ break;
+ case 6:
+ code_desc = "EXC_I386_EMERR";
+ break;
case 7:
- exc_desc = "EXC_SYSCALL";
- break;
-
+ code_desc = "EXC_I386_BOUND";
+ break;
case 8:
- exc_desc = "EXC_MACH_SYSCALL";
- break;
-
- case 9:
- exc_desc = "EXC_RPC_ALERT";
- break;
-
- case 10:
- exc_desc = "EXC_CRASH";
- break;
- case 11:
- exc_desc = "EXC_RESOURCE";
- break;
- case 12:
- exc_desc = "EXC_GUARD";
- break;
+ code_desc = "EXC_I386_SSEEXTERR";
+ break;
+ }
+ break;
+
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
+ switch (m_exc_code) {
+ case 1:
+ code_desc = "EXC_PPC_OVERFLOW";
+ break;
+ case 2:
+ code_desc = "EXC_PPC_ZERO_DIVIDE";
+ break;
+ case 3:
+ code_desc = "EXC_PPC_FLT_INEXACT";
+ break;
+ case 4:
+ code_desc = "EXC_PPC_FLT_ZERO_DIVIDE";
+ break;
+ case 5:
+ code_desc = "EXC_PPC_FLT_UNDERFLOW";
+ break;
+ case 6:
+ code_desc = "EXC_PPC_FLT_OVERFLOW";
+ break;
+ case 7:
+ code_desc = "EXC_PPC_FLT_NOT_A_NUMBER";
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case 4: // EXC_EMULATION
+ exc_desc = "EXC_EMULATION";
+ break;
+
+ case 5: // EXC_SOFTWARE
+ exc_desc = "EXC_SOFTWARE";
+ if (m_exc_code == 0x10003) {
+ subcode_desc = "EXC_SOFT_SIGNAL";
+ subcode_label = "signo";
+ }
+ break;
+
+ case 6: // EXC_BREAKPOINT
+ {
+ exc_desc = "EXC_BREAKPOINT";
+ switch (cpu) {
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ switch (m_exc_code) {
+ case 1:
+ code_desc = "EXC_I386_SGL";
+ break;
+ case 2:
+ code_desc = "EXC_I386_BPT";
+ break;
+ }
+ break;
+
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
+ switch (m_exc_code) {
+ case 1:
+ code_desc = "EXC_PPC_BREAKPOINT";
+ break;
}
-
- StreamString strm;
+ break;
+
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ switch (m_exc_code) {
+ case 0x101:
+ code_desc = "EXC_ARM_DA_ALIGN";
+ break;
+ case 0x102:
+ code_desc = "EXC_ARM_DA_DEBUG";
+ break;
+ case 1:
+ code_desc = "EXC_ARM_BREAKPOINT";
+ break;
+ // FIXME temporary workaround, exc_code 0 does not really mean
+ // EXC_ARM_BREAKPOINT
+ case 0:
+ code_desc = "EXC_ARM_BREAKPOINT";
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ } break;
+
+ case 7:
+ exc_desc = "EXC_SYSCALL";
+ break;
+
+ case 8:
+ exc_desc = "EXC_MACH_SYSCALL";
+ break;
+
+ case 9:
+ exc_desc = "EXC_RPC_ALERT";
+ break;
+
+ case 10:
+ exc_desc = "EXC_CRASH";
+ break;
+ case 11:
+ exc_desc = "EXC_RESOURCE";
+ break;
+ case 12:
+ exc_desc = "EXC_GUARD";
+ break;
+ }
- if (exc_desc)
- strm.PutCString(exc_desc);
- else
- strm.Printf("EXC_??? (%" PRIu64 ")", m_value);
+ StreamString strm;
- if (m_exc_data_count >= 1)
- {
- if (code_desc)
- strm.Printf(" (%s=%s", code_label, code_desc);
- else
- strm.Printf(" (%s=%" PRIu64, code_label, m_exc_code);
- }
+ if (exc_desc)
+ strm.PutCString(exc_desc);
+ else
+ strm.Printf("EXC_??? (%" PRIu64 ")", m_value);
- if (m_exc_data_count >= 2)
- {
- if (subcode_desc)
- strm.Printf(", %s=%s", subcode_label, subcode_desc);
- else
- strm.Printf(", %s=0x%" PRIx64, subcode_label, m_exc_subcode);
- }
-
- if (m_exc_data_count > 0)
- strm.PutChar(')');
-
- m_description.swap (strm.GetString());
+ if (m_exc_data_count >= 1) {
+ if (code_desc)
+ strm.Printf(" (%s=%s", code_label, code_desc);
+ else
+ strm.Printf(" (%s=%" PRIu64, code_label, m_exc_code);
}
- return m_description.c_str();
-}
+ if (m_exc_data_count >= 2) {
+ if (subcode_desc)
+ strm.Printf(", %s=%s", subcode_label, subcode_desc);
+ else
+ strm.Printf(", %s=0x%" PRIx64, subcode_label, m_exc_subcode);
+ }
+ if (m_exc_data_count > 0)
+ strm.PutChar(')');
+ m_description = strm.GetString();
+ }
+ return m_description.c_str();
+}
+StopInfoSP StopInfoMachException::CreateStopReasonWithMachException(
+ Thread &thread, uint32_t exc_type, uint32_t exc_data_count,
+ uint64_t exc_code, uint64_t exc_sub_code, uint64_t exc_sub_sub_code,
+ bool pc_already_adjusted, bool adjust_pc_if_needed) {
+ if (exc_type != 0) {
+ uint32_t pc_decrement = 0;
+ ExecutionContext exe_ctx(thread.shared_from_this());
+ Target *target = exe_ctx.GetTargetPtr();
+ const llvm::Triple::ArchType cpu =
+ target ? target->GetArchitecture().GetMachine()
+ : llvm::Triple::UnknownArch;
+
+ switch (exc_type) {
+ case 1: // EXC_BAD_ACCESS
+ break;
+
+ case 2: // EXC_BAD_INSTRUCTION
+ switch (cpu) {
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
+ switch (exc_code) {
+ case 1: // EXC_PPC_INVALID_SYSCALL
+ case 2: // EXC_PPC_UNIPL_INST
+ case 3: // EXC_PPC_PRIVINST
+ case 4: // EXC_PPC_PRIVREG
+ break;
+ case 5: // EXC_PPC_TRACE
+ return StopInfo::CreateStopReasonToTrace(thread);
+ case 6: // EXC_PPC_PERFMON
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case 3: // EXC_ARITHMETIC
+ case 4: // EXC_EMULATION
+ break;
+
+ case 5: // EXC_SOFTWARE
+ if (exc_code == 0x10003) // EXC_SOFT_SIGNAL
+ {
+ if (exc_sub_code == 5) {
+ // On MacOSX, a SIGTRAP can signify that a process has called
+ // exec, so we should check with our dynamic loader to verify.
+ ProcessSP process_sp(thread.GetProcess());
+ if (process_sp) {
+ DynamicLoader *dynamic_loader = process_sp->GetDynamicLoader();
+ if (dynamic_loader && dynamic_loader->ProcessDidExec()) {
+ // The program was re-exec'ed
+ return StopInfo::CreateStopReasonWithExec(thread);
+ }
+ // if (!process_did_exec)
+ // {
+ // // We have a SIGTRAP, make sure we
+ // didn't exec by checking
+ // // for the PC being at
+ // "_dyld_start"...
+ // lldb::StackFrameSP frame_sp
+ // (thread.GetStackFrameAtIndex(0));
+ // if (frame_sp)
+ // {
+ // const Symbol *symbol =
+ // frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol;
+ // if (symbol)
+ // {
+ // if (symbol->GetName() ==
+ // ConstString("_dyld_start"))
+ // process_did_exec = true;
+ // }
+ // }
+ // }
+ }
+ }
+ return StopInfo::CreateStopReasonWithSignal(thread, exc_sub_code);
+ }
+ break;
-StopInfoSP
-StopInfoMachException::CreateStopReasonWithMachException
-(
- Thread &thread,
- uint32_t exc_type,
- uint32_t exc_data_count,
- uint64_t exc_code,
- uint64_t exc_sub_code,
- uint64_t exc_sub_sub_code,
- bool pc_already_adjusted,
- bool adjust_pc_if_needed
-)
-{
- if (exc_type != 0)
+ case 6: // EXC_BREAKPOINT
{
- uint32_t pc_decrement = 0;
- ExecutionContext exe_ctx (thread.shared_from_this());
- Target *target = exe_ctx.GetTargetPtr();
- const llvm::Triple::ArchType cpu = target ? target->GetArchitecture().GetMachine() : llvm::Triple::UnknownArch;
-
- switch (exc_type)
+ bool is_actual_breakpoint = false;
+ bool is_trace_if_actual_breakpoint_missing = false;
+ switch (cpu) {
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ if (exc_code == 1) // EXC_I386_SGL
{
- case 1: // EXC_BAD_ACCESS
- break;
-
- case 2: // EXC_BAD_INSTRUCTION
- switch (cpu)
- {
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- switch (exc_code)
- {
- case 1: // EXC_PPC_INVALID_SYSCALL
- case 2: // EXC_PPC_UNIPL_INST
- case 3: // EXC_PPC_PRIVINST
- case 4: // EXC_PPC_PRIVREG
- break;
- case 5: // EXC_PPC_TRACE
- return StopInfo::CreateStopReasonToTrace (thread);
- case 6: // EXC_PPC_PERFMON
- break;
- }
- break;
-
- default:
- break;
+ if (!exc_sub_code) {
+ // This looks like a plain trap.
+ // Have to check if there is a breakpoint here as well. When you
+ // single-step onto a trap,
+ // the single step stops you not to trap. Since we also do that
+ // check below, let's just use
+ // that logic.
+ is_actual_breakpoint = true;
+ is_trace_if_actual_breakpoint_missing = true;
+ } else {
+
+ // It's a watchpoint, then.
+ // The exc_sub_code indicates the data break address.
+ lldb::WatchpointSP wp_sp;
+ if (target)
+ wp_sp = target->GetWatchpointList().FindByAddress(
+ (lldb::addr_t)exc_sub_code);
+ if (wp_sp && wp_sp->IsEnabled()) {
+ // Debugserver may piggyback the hardware index of the fired
+ // watchpoint in the exception data.
+ // Set the hardware index if that's the case.
+ if (exc_data_count >= 3)
+ wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
+ return StopInfo::CreateStopReasonWithWatchpointID(thread,
+ wp_sp->GetID());
}
- break;
-
- case 3: // EXC_ARITHMETIC
- case 4: // EXC_EMULATION
- break;
-
- case 5: // EXC_SOFTWARE
- if (exc_code == 0x10003) // EXC_SOFT_SIGNAL
- {
- if (exc_sub_code == 5)
- {
- // On MacOSX, a SIGTRAP can signify that a process has called
- // exec, so we should check with our dynamic loader to verify.
- ProcessSP process_sp (thread.GetProcess());
- if (process_sp)
- {
- DynamicLoader *dynamic_loader = process_sp->GetDynamicLoader();
- if (dynamic_loader && dynamic_loader->ProcessDidExec())
- {
- // The program was re-exec'ed
- return StopInfo::CreateStopReasonWithExec (thread);
- }
-// if (!process_did_exec)
-// {
-// // We have a SIGTRAP, make sure we didn't exec by checking
-// // for the PC being at "_dyld_start"...
-// lldb::StackFrameSP frame_sp (thread.GetStackFrameAtIndex(0));
-// if (frame_sp)
-// {
-// const Symbol *symbol = frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol;
-// if (symbol)
-// {
-// if (symbol->GetName() == ConstString("_dyld_start"))
-// process_did_exec = true;
-// }
-// }
-// }
- }
- }
- return StopInfo::CreateStopReasonWithSignal (thread, exc_sub_code);
- }
- break;
-
- case 6: // EXC_BREAKPOINT
- {
- bool is_actual_breakpoint = false;
- bool is_trace_if_actual_breakpoint_missing = false;
- switch (cpu)
- {
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- if (exc_code == 1) // EXC_I386_SGL
- {
- if (!exc_sub_code)
- {
- // This looks like a plain trap.
- // Have to check if there is a breakpoint here as well. When you single-step onto a trap,
- // the single step stops you not to trap. Since we also do that check below, let's just use
- // that logic.
- is_actual_breakpoint = true;
- is_trace_if_actual_breakpoint_missing = true;
- }
- else
- {
-
- // It's a watchpoint, then.
- // The exc_sub_code indicates the data break address.
- lldb::WatchpointSP wp_sp;
- if (target)
- wp_sp = target->GetWatchpointList().FindByAddress((lldb::addr_t)exc_sub_code);
- if (wp_sp && wp_sp->IsEnabled())
- {
- // Debugserver may piggyback the hardware index of the fired watchpoint in the exception data.
- // Set the hardware index if that's the case.
- if (exc_data_count >=3)
- wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
- return StopInfo::CreateStopReasonWithWatchpointID(thread, wp_sp->GetID());
- }
- }
- }
- else if (exc_code == 2 || // EXC_I386_BPT
- exc_code == 3) // EXC_I386_BPTFLT
- {
- // KDP returns EXC_I386_BPTFLT for trace breakpoints
- if (exc_code == 3)
- is_trace_if_actual_breakpoint_missing = true;
-
- is_actual_breakpoint = true;
- if (!pc_already_adjusted)
- pc_decrement = 1;
- }
- break;
-
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- is_actual_breakpoint = exc_code == 1; // EXC_PPC_BREAKPOINT
- break;
-
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- if (exc_code == 0x102) // EXC_ARM_DA_DEBUG
- {
- // It's a watchpoint, then, if the exc_sub_code indicates a known/enabled
- // data break address from our watchpoint list.
- lldb::WatchpointSP wp_sp;
- if (target)
- wp_sp = target->GetWatchpointList().FindByAddress((lldb::addr_t)exc_sub_code);
- if (wp_sp && wp_sp->IsEnabled())
- {
- // Debugserver may piggyback the hardware index of the fired watchpoint in the exception data.
- // Set the hardware index if that's the case.
- if (exc_data_count >=3)
- wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
- return StopInfo::CreateStopReasonWithWatchpointID(thread, wp_sp->GetID());
- }
- else
- {
- is_actual_breakpoint = true;
- is_trace_if_actual_breakpoint_missing = true;
- }
- }
- else if (exc_code == 1) // EXC_ARM_BREAKPOINT
- {
- is_actual_breakpoint = true;
- is_trace_if_actual_breakpoint_missing = true;
- }
- else if (exc_code == 0) // FIXME not EXC_ARM_BREAKPOINT but a kernel is currently returning this so accept it as indicating a breakpoint until the kernel is fixed
- {
- is_actual_breakpoint = true;
- is_trace_if_actual_breakpoint_missing = true;
- }
- break;
-
- case llvm::Triple::aarch64:
- {
- if (exc_code == 1 && exc_sub_code == 0) // EXC_ARM_BREAKPOINT
- {
- // This is hit when we single instruction step aka MDSCR_EL1 SS bit 0 is set
- return StopInfo::CreateStopReasonToTrace(thread);
- }
- if (exc_code == 0x102) // EXC_ARM_DA_DEBUG
- {
- // It's a watchpoint, then, if the exc_sub_code indicates a known/enabled
- // data break address from our watchpoint list.
- lldb::WatchpointSP wp_sp;
- if (target)
- wp_sp = target->GetWatchpointList().FindByAddress((lldb::addr_t)exc_sub_code);
- if (wp_sp && wp_sp->IsEnabled())
- {
- // Debugserver may piggyback the hardware index of the fired watchpoint in the exception data.
- // Set the hardware index if that's the case.
- if (exc_data_count >= 3)
- wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
- return StopInfo::CreateStopReasonWithWatchpointID(thread, wp_sp->GetID());
- }
- // EXC_ARM_DA_DEBUG seems to be reused for EXC_BREAKPOINT as well as EXC_BAD_ACCESS
- if (thread.GetTemporaryResumeState() == eStateStepping)
- return StopInfo::CreateStopReasonToTrace(thread);
- }
- // It looks like exc_sub_code has the 4 bytes of the instruction that triggered the
- // exception, i.e. our breakpoint opcode
- is_actual_breakpoint = exc_code == 1;
- break;
- }
-
- default:
- break;
- }
-
- if (is_actual_breakpoint)
- {
- RegisterContextSP reg_ctx_sp (thread.GetRegisterContext());
- addr_t pc = reg_ctx_sp->GetPC() - pc_decrement;
-
- ProcessSP process_sp (thread.CalculateProcess());
-
- lldb::BreakpointSiteSP bp_site_sp;
- if (process_sp)
- bp_site_sp = process_sp->GetBreakpointSiteList().FindByAddress(pc);
- if (bp_site_sp && bp_site_sp->IsEnabled())
- {
- // Update the PC if we were asked to do so, but only do
- // so if we find a breakpoint that we know about cause
- // this could be a trap instruction in the code
- if (pc_decrement > 0 && adjust_pc_if_needed)
- reg_ctx_sp->SetPC (pc);
-
- // If the breakpoint is for this thread, then we'll report the hit, but if it is for another thread,
- // we can just report no 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 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_sp->ValidForThisThread (&thread) || thread.GetProcess()->GetOperatingSystem () != NULL)
- return StopInfo::CreateStopReasonWithBreakpointSiteID (thread, bp_site_sp->GetID());
- else if (is_trace_if_actual_breakpoint_missing)
- return StopInfo::CreateStopReasonToTrace (thread);
- else
- return StopInfoSP();
- }
-
- // Don't call this a trace if we weren't single stepping this thread.
- if (is_trace_if_actual_breakpoint_missing && thread.GetTemporaryResumeState() == eStateStepping)
- {
- return StopInfo::CreateStopReasonToTrace (thread);
- }
- }
- }
- break;
+ }
+ } else if (exc_code == 2 || // EXC_I386_BPT
+ exc_code == 3) // EXC_I386_BPTFLT
+ {
+ // KDP returns EXC_I386_BPTFLT for trace breakpoints
+ if (exc_code == 3)
+ is_trace_if_actual_breakpoint_missing = true;
- case 7: // EXC_SYSCALL
- case 8: // EXC_MACH_SYSCALL
- case 9: // EXC_RPC_ALERT
- case 10: // EXC_CRASH
- break;
+ is_actual_breakpoint = true;
+ if (!pc_already_adjusted)
+ pc_decrement = 1;
}
-
- return StopInfoSP(new StopInfoMachException (thread, exc_type, exc_data_count, exc_code, exc_sub_code));
+ break;
+
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
+ is_actual_breakpoint = exc_code == 1; // EXC_PPC_BREAKPOINT
+ break;
+
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ if (exc_code == 0x102) // EXC_ARM_DA_DEBUG
+ {
+ // It's a watchpoint, then, if the exc_sub_code indicates a
+ // known/enabled
+ // data break address from our watchpoint list.
+ lldb::WatchpointSP wp_sp;
+ if (target)
+ wp_sp = target->GetWatchpointList().FindByAddress(
+ (lldb::addr_t)exc_sub_code);
+ if (wp_sp && wp_sp->IsEnabled()) {
+ // Debugserver may piggyback the hardware index of the fired
+ // watchpoint in the exception data.
+ // Set the hardware index if that's the case.
+ if (exc_data_count >= 3)
+ wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
+ return StopInfo::CreateStopReasonWithWatchpointID(thread,
+ wp_sp->GetID());
+ } else {
+ is_actual_breakpoint = true;
+ is_trace_if_actual_breakpoint_missing = true;
+ }
+ } else if (exc_code == 1) // EXC_ARM_BREAKPOINT
+ {
+ is_actual_breakpoint = true;
+ is_trace_if_actual_breakpoint_missing = true;
+ } else if (exc_code == 0) // FIXME not EXC_ARM_BREAKPOINT but a kernel
+ // is currently returning this so accept it as
+ // indicating a breakpoint until the kernel is
+ // fixed
+ {
+ is_actual_breakpoint = true;
+ is_trace_if_actual_breakpoint_missing = true;
+ }
+ break;
+
+ case llvm::Triple::aarch64: {
+ if (exc_code == 1 && exc_sub_code == 0) // EXC_ARM_BREAKPOINT
+ {
+ // This is hit when we single instruction step aka MDSCR_EL1 SS bit 0
+ // is set
+ is_actual_breakpoint = false;
+ is_trace_if_actual_breakpoint_missing = true;
+ }
+ if (exc_code == 0x102) // EXC_ARM_DA_DEBUG
+ {
+ // It's a watchpoint, then, if the exc_sub_code indicates a
+ // known/enabled
+ // data break address from our watchpoint list.
+ lldb::WatchpointSP wp_sp;
+ if (target)
+ wp_sp = target->GetWatchpointList().FindByAddress(
+ (lldb::addr_t)exc_sub_code);
+ if (wp_sp && wp_sp->IsEnabled()) {
+ // Debugserver may piggyback the hardware index of the fired
+ // watchpoint in the exception data.
+ // Set the hardware index if that's the case.
+ if (exc_data_count >= 3)
+ wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
+ return StopInfo::CreateStopReasonWithWatchpointID(thread,
+ wp_sp->GetID());
+ }
+ // EXC_ARM_DA_DEBUG seems to be reused for EXC_BREAKPOINT as well as
+ // EXC_BAD_ACCESS
+ if (thread.GetTemporaryResumeState() == eStateStepping)
+ return StopInfo::CreateStopReasonToTrace(thread);
+ }
+ // It looks like exc_sub_code has the 4 bytes of the instruction that
+ // triggered the
+ // exception, i.e. our breakpoint opcode
+ is_actual_breakpoint = exc_code == 1;
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ if (is_actual_breakpoint) {
+ RegisterContextSP reg_ctx_sp(thread.GetRegisterContext());
+ addr_t pc = reg_ctx_sp->GetPC() - pc_decrement;
+
+ ProcessSP process_sp(thread.CalculateProcess());
+
+ lldb::BreakpointSiteSP bp_site_sp;
+ if (process_sp)
+ bp_site_sp = process_sp->GetBreakpointSiteList().FindByAddress(pc);
+ if (bp_site_sp && bp_site_sp->IsEnabled()) {
+ // Update the PC if we were asked to do so, but only do
+ // so if we find a breakpoint that we know about cause
+ // this could be a trap instruction in the code
+ if (pc_decrement > 0 && adjust_pc_if_needed)
+ reg_ctx_sp->SetPC(pc);
+
+ // If the breakpoint is for this thread, then we'll report the hit,
+ // but if it is for another thread,
+ // we can just report no 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 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_sp->ValidForThisThread(&thread) ||
+ thread.GetProcess()->GetOperatingSystem() != NULL)
+ return StopInfo::CreateStopReasonWithBreakpointSiteID(
+ thread, bp_site_sp->GetID());
+ else if (is_trace_if_actual_breakpoint_missing)
+ return StopInfo::CreateStopReasonToTrace(thread);
+ else
+ return StopInfoSP();
+ }
+
+ // Don't call this a trace if we weren't single stepping this thread.
+ if (is_trace_if_actual_breakpoint_missing &&
+ thread.GetTemporaryResumeState() == eStateStepping) {
+ return StopInfo::CreateStopReasonToTrace(thread);
+ }
+ }
+ } break;
+
+ case 7: // EXC_SYSCALL
+ case 8: // EXC_MACH_SYSCALL
+ case 9: // EXC_RPC_ALERT
+ case 10: // EXC_CRASH
+ break;
}
- return StopInfoSP();
+
+ return StopInfoSP(new StopInfoMachException(
+ thread, exc_type, exc_data_count, exc_code, exc_sub_code));
+ }
+ return StopInfoSP();
}
diff --git a/source/Plugins/Process/Utility/StopInfoMachException.h b/source/Plugins/Process/Utility/StopInfoMachException.h
index 25e05ecc1ec7..94516454105e 100644
--- a/source/Plugins/Process/Utility/StopInfoMachException.h
+++ b/source/Plugins/Process/Utility/StopInfoMachException.h
@@ -20,52 +20,37 @@
namespace lldb_private {
-class StopInfoMachException : public StopInfo
-{
+class StopInfoMachException : public StopInfo {
public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- StopInfoMachException (Thread &thread,
- uint32_t exc_type,
- uint32_t exc_data_count,
- uint64_t exc_code,
- uint64_t exc_subcode) :
- StopInfo (thread, exc_type),
- m_exc_data_count (exc_data_count),
- m_exc_code (exc_code),
- m_exc_subcode (exc_subcode)
- {
- }
-
- ~StopInfoMachException() override = default;
-
- lldb::StopReason
- GetStopReason() const override
- {
- return lldb::eStopReasonException;
- }
-
- const char *
- GetDescription() override;
-
- // Since some mach exceptions will be reported as breakpoints, signals,
- // or trace, we use this static accessor which will translate the mach
- // exception into the correct StopInfo.
- static lldb::StopInfoSP
- CreateStopReasonWithMachException (Thread &thread,
- uint32_t exc_type,
- uint32_t exc_data_count,
- uint64_t exc_code,
- uint64_t exc_sub_code,
- uint64_t exc_sub_sub_code,
- bool pc_already_adjusted = true,
- bool adjust_pc_if_needed = false);
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ StopInfoMachException(Thread &thread, uint32_t exc_type,
+ uint32_t exc_data_count, uint64_t exc_code,
+ uint64_t exc_subcode)
+ : StopInfo(thread, exc_type), m_exc_data_count(exc_data_count),
+ m_exc_code(exc_code), m_exc_subcode(exc_subcode) {}
+
+ ~StopInfoMachException() override = default;
+
+ lldb::StopReason GetStopReason() const override {
+ return lldb::eStopReasonException;
+ }
+
+ const char *GetDescription() override;
+
+ // Since some mach exceptions will be reported as breakpoints, signals,
+ // or trace, we use this static accessor which will translate the mach
+ // exception into the correct StopInfo.
+ static lldb::StopInfoSP CreateStopReasonWithMachException(
+ Thread &thread, uint32_t exc_type, uint32_t exc_data_count,
+ uint64_t exc_code, uint64_t exc_sub_code, uint64_t exc_sub_sub_code,
+ bool pc_already_adjusted = true, bool adjust_pc_if_needed = false);
protected:
- uint32_t m_exc_data_count;
- uint64_t m_exc_code;
- uint64_t m_exc_subcode;
+ uint32_t m_exc_data_count;
+ uint64_t m_exc_code;
+ uint64_t m_exc_subcode;
};
} // namespace lldb_private
diff --git a/source/Plugins/Process/Utility/ThreadMemory.cpp b/source/Plugins/Process/Utility/ThreadMemory.cpp
index 6a7aa626bafc..b3cac1c854d1 100644
--- a/source/Plugins/Process/Utility/ThreadMemory.cpp
+++ b/source/Plugins/Process/Utility/ThreadMemory.cpp
@@ -1,4 +1,5 @@
-//===-- ThreadMemory.cpp ----------------------------------------------*- C++ -*-===//
+//===-- ThreadMemory.cpp ----------------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -8,133 +9,97 @@
//===----------------------------------------------------------------------===//
#include "Plugins/Process/Utility/ThreadMemory.h"
+#include "Plugins/Process/Utility/RegisterContextThreadMemory.h"
#include "lldb/Target/OperatingSystem.h"
-#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Unwind.h"
-#include "Plugins/Process/Utility/RegisterContextThreadMemory.h"
using namespace lldb;
using namespace lldb_private;
-ThreadMemory::ThreadMemory (Process &process,
- tid_t tid,
- const ValueObjectSP &thread_info_valobj_sp) :
- Thread (process, tid),
- m_backing_thread_sp (),
- m_thread_info_valobj_sp (thread_info_valobj_sp),
- m_name(),
- m_queue()
-{
-}
-
+ThreadMemory::ThreadMemory(Process &process, tid_t tid,
+ const ValueObjectSP &thread_info_valobj_sp)
+ : Thread(process, tid), m_backing_thread_sp(),
+ m_thread_info_valobj_sp(thread_info_valobj_sp), m_name(), m_queue() {}
-ThreadMemory::ThreadMemory (Process &process,
- lldb::tid_t tid,
- const char *name,
- const char *queue,
- lldb::addr_t register_data_addr) :
- Thread (process, tid),
- m_backing_thread_sp (),
- m_thread_info_valobj_sp (),
- m_name(),
- m_queue(),
- m_register_data_addr (register_data_addr)
-{
- if (name)
- m_name = name;
- if (queue)
- m_queue = queue;
+ThreadMemory::ThreadMemory(Process &process, lldb::tid_t tid, const char *name,
+ const char *queue, lldb::addr_t register_data_addr)
+ : Thread(process, tid), m_backing_thread_sp(), m_thread_info_valobj_sp(),
+ m_name(), m_queue(), m_register_data_addr(register_data_addr) {
+ if (name)
+ m_name = name;
+ if (queue)
+ m_queue = queue;
}
+ThreadMemory::~ThreadMemory() { DestroyThread(); }
-ThreadMemory::~ThreadMemory()
-{
- DestroyThread();
+void ThreadMemory::WillResume(StateType resume_state) {
+ if (m_backing_thread_sp)
+ m_backing_thread_sp->WillResume(resume_state);
}
-void
-ThreadMemory::WillResume (StateType resume_state)
-{
- if (m_backing_thread_sp)
- m_backing_thread_sp->WillResume(resume_state);
+void ThreadMemory::ClearStackFrames() {
+ if (m_backing_thread_sp)
+ m_backing_thread_sp->ClearStackFrames();
+ Thread::ClearStackFrames();
}
-void
-ThreadMemory::ClearStackFrames ()
-{
- if (m_backing_thread_sp)
- m_backing_thread_sp->ClearStackFrames();
- Thread::ClearStackFrames();
+RegisterContextSP ThreadMemory::GetRegisterContext() {
+ if (!m_reg_context_sp)
+ m_reg_context_sp.reset(
+ new RegisterContextThreadMemory(*this, m_register_data_addr));
+ return m_reg_context_sp;
}
RegisterContextSP
-ThreadMemory::GetRegisterContext ()
-{
- if (!m_reg_context_sp)
- m_reg_context_sp.reset (new RegisterContextThreadMemory (*this, m_register_data_addr));
- return m_reg_context_sp;
-}
+ThreadMemory::CreateRegisterContextForFrame(StackFrame *frame) {
+ RegisterContextSP reg_ctx_sp;
+ uint32_t concrete_frame_idx = 0;
-RegisterContextSP
-ThreadMemory::CreateRegisterContextForFrame (StackFrame *frame)
-{
- RegisterContextSP reg_ctx_sp;
- uint32_t concrete_frame_idx = 0;
-
- if (frame)
- concrete_frame_idx = frame->GetConcreteFrameIndex ();
-
- if (concrete_frame_idx == 0)
- {
- reg_ctx_sp = GetRegisterContext ();
- }
- else
- {
- Unwind *unwinder = GetUnwinder ();
- if (unwinder)
- reg_ctx_sp = unwinder->CreateRegisterContextForFrame (frame);
- }
- return reg_ctx_sp;
+ if (frame)
+ concrete_frame_idx = frame->GetConcreteFrameIndex();
+
+ if (concrete_frame_idx == 0) {
+ reg_ctx_sp = GetRegisterContext();
+ } else {
+ Unwind *unwinder = GetUnwinder();
+ if (unwinder)
+ reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame);
+ }
+ return reg_ctx_sp;
}
-bool
-ThreadMemory::CalculateStopInfo ()
-{
- if (m_backing_thread_sp)
- {
- lldb::StopInfoSP backing_stop_info_sp (m_backing_thread_sp->GetPrivateStopInfo());
- if (backing_stop_info_sp && backing_stop_info_sp->IsValidForOperatingSystemThread(*this))
- {
- backing_stop_info_sp->SetThread (shared_from_this());
- SetStopInfo (backing_stop_info_sp);
- return true;
- }
+bool ThreadMemory::CalculateStopInfo() {
+ if (m_backing_thread_sp) {
+ lldb::StopInfoSP backing_stop_info_sp(
+ m_backing_thread_sp->GetPrivateStopInfo());
+ if (backing_stop_info_sp &&
+ backing_stop_info_sp->IsValidForOperatingSystemThread(*this)) {
+ backing_stop_info_sp->SetThread(shared_from_this());
+ SetStopInfo(backing_stop_info_sp);
+ return true;
}
- else
- {
- ProcessSP process_sp (GetProcess());
+ } else {
+ ProcessSP process_sp(GetProcess());
- if (process_sp)
- {
- OperatingSystem *os = process_sp->GetOperatingSystem ();
- if (os)
- {
- SetStopInfo (os->CreateThreadStopReason (this));
- return true;
- }
- }
+ if (process_sp) {
+ OperatingSystem *os = process_sp->GetOperatingSystem();
+ if (os) {
+ SetStopInfo(os->CreateThreadStopReason(this));
+ return true;
+ }
}
- return false;
+ }
+ return false;
}
-void
-ThreadMemory::RefreshStateAfterStop()
-{
- if (m_backing_thread_sp)
- return m_backing_thread_sp->RefreshStateAfterStop();
-
- if (m_reg_context_sp)
- m_reg_context_sp->InvalidateAllRegisters();
+void ThreadMemory::RefreshStateAfterStop() {
+ if (m_backing_thread_sp)
+ return m_backing_thread_sp->RefreshStateAfterStop();
+
+ if (m_reg_context_sp)
+ m_reg_context_sp->InvalidateAllRegisters();
}
diff --git a/source/Plugins/Process/Utility/ThreadMemory.h b/source/Plugins/Process/Utility/ThreadMemory.h
index 1e7cbfa44815..095544d244ba 100644
--- a/source/Plugins/Process/Utility/ThreadMemory.h
+++ b/source/Plugins/Process/Utility/ThreadMemory.h
@@ -18,129 +18,94 @@
// Project includes
#include "lldb/Target/Thread.h"
-class ThreadMemory :
- public lldb_private::Thread
-{
+class ThreadMemory : public lldb_private::Thread {
public:
- ThreadMemory (lldb_private::Process &process,
- lldb::tid_t tid,
- const lldb::ValueObjectSP &thread_info_valobj_sp);
-
- ThreadMemory (lldb_private::Process &process,
- lldb::tid_t tid,
- const char *name,
- const char *queue,
- lldb::addr_t register_data_addr);
-
- ~ThreadMemory() override;
-
- lldb::RegisterContextSP
- GetRegisterContext() override;
-
- lldb::RegisterContextSP
- CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
-
- bool
- CalculateStopInfo() override;
-
- const char *
- GetInfo() override
- {
- if (m_backing_thread_sp)
- m_backing_thread_sp->GetInfo();
- return nullptr;
- }
-
- const char *
- GetName() override
- {
- if (!m_name.empty())
- return m_name.c_str();
- if (m_backing_thread_sp)
- m_backing_thread_sp->GetName();
- return nullptr;
- }
-
- const char *
- GetQueueName() override
- {
- if (!m_queue.empty())
- return m_queue.c_str();
- if (m_backing_thread_sp)
- m_backing_thread_sp->GetQueueName();
- return nullptr;
- }
-
- void
- WillResume(lldb::StateType resume_state) override;
-
- void
- DidResume() override
- {
- if (m_backing_thread_sp)
- m_backing_thread_sp->DidResume();
- }
-
- lldb::user_id_t
- GetProtocolID() const override
- {
- if (m_backing_thread_sp)
- return m_backing_thread_sp->GetProtocolID();
- return Thread::GetProtocolID();
- }
-
- void
- RefreshStateAfterStop() override;
-
- lldb::ValueObjectSP &
- GetValueObject ()
- {
- return m_thread_info_valobj_sp;
- }
-
- void
- ClearStackFrames() override;
-
- void
- ClearBackingThread() override
- {
- m_backing_thread_sp.reset();
- }
-
- bool
- SetBackingThread(const lldb::ThreadSP &thread_sp) override
- {
- //printf ("Thread 0x%llx is being backed by thread 0x%llx\n", GetID(), thread_sp->GetID());
- m_backing_thread_sp = thread_sp;
- return (bool)thread_sp;
- }
-
- lldb::ThreadSP
- GetBackingThread() const override
- {
- return m_backing_thread_sp;
- }
+ ThreadMemory(lldb_private::Process &process, lldb::tid_t tid,
+ const lldb::ValueObjectSP &thread_info_valobj_sp);
+
+ ThreadMemory(lldb_private::Process &process, lldb::tid_t tid,
+ const char *name, const char *queue,
+ lldb::addr_t register_data_addr);
+
+ ~ThreadMemory() override;
+
+ lldb::RegisterContextSP GetRegisterContext() override;
+
+ lldb::RegisterContextSP
+ CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
+
+ bool CalculateStopInfo() override;
+
+ const char *GetInfo() override {
+ if (m_backing_thread_sp)
+ m_backing_thread_sp->GetInfo();
+ return nullptr;
+ }
+
+ const char *GetName() override {
+ if (!m_name.empty())
+ return m_name.c_str();
+ if (m_backing_thread_sp)
+ m_backing_thread_sp->GetName();
+ return nullptr;
+ }
+
+ const char *GetQueueName() override {
+ if (!m_queue.empty())
+ return m_queue.c_str();
+ if (m_backing_thread_sp)
+ m_backing_thread_sp->GetQueueName();
+ return nullptr;
+ }
+
+ void WillResume(lldb::StateType resume_state) override;
+
+ void DidResume() override {
+ if (m_backing_thread_sp)
+ m_backing_thread_sp->DidResume();
+ }
+
+ lldb::user_id_t GetProtocolID() const override {
+ if (m_backing_thread_sp)
+ return m_backing_thread_sp->GetProtocolID();
+ return Thread::GetProtocolID();
+ }
+
+ void RefreshStateAfterStop() override;
+
+ lldb::ValueObjectSP &GetValueObject() { return m_thread_info_valobj_sp; }
+
+ void ClearStackFrames() override;
+
+ void ClearBackingThread() override { m_backing_thread_sp.reset(); }
+
+ bool SetBackingThread(const lldb::ThreadSP &thread_sp) override {
+ // printf ("Thread 0x%llx is being backed by thread 0x%llx\n", GetID(),
+ // thread_sp->GetID());
+ m_backing_thread_sp = thread_sp;
+ return (bool)thread_sp;
+ }
+
+ lldb::ThreadSP GetBackingThread() const override {
+ return m_backing_thread_sp;
+ }
protected:
- bool
- IsOperatingSystemPluginThread() const override
- {
- return true;
- }
-
- // If this memory thread is actually represented by a thread from the
- // lldb_private::Process subclass, then fill in the thread here and
- // all APIs will be routed through this thread object. If m_backing_thread_sp
- // is empty, then this thread is simply in memory with no representation
- // through the process plug-in.
- lldb::ThreadSP m_backing_thread_sp;
- lldb::ValueObjectSP m_thread_info_valobj_sp;
- std::string m_name;
- std::string m_queue;
- lldb::addr_t m_register_data_addr;
+ bool IsOperatingSystemPluginThread() const override { return true; }
+
+ // If this memory thread is actually represented by a thread from the
+ // lldb_private::Process subclass, then fill in the thread here and
+ // all APIs will be routed through this thread object. If m_backing_thread_sp
+ // is empty, then this thread is simply in memory with no representation
+ // through the process plug-in.
+ lldb::ThreadSP m_backing_thread_sp;
+ lldb::ValueObjectSP m_thread_info_valobj_sp;
+ std::string m_name;
+ std::string m_queue;
+ lldb::addr_t m_register_data_addr;
private:
- DISALLOW_COPY_AND_ASSIGN (ThreadMemory);
+ DISALLOW_COPY_AND_ASSIGN(ThreadMemory);
};
#endif // liblldb_ThreadMemory_h_
diff --git a/source/Plugins/Process/Utility/UnwindLLDB.cpp b/source/Plugins/Process/Utility/UnwindLLDB.cpp
index 9be09c478a0e..6e2a9a9ee100 100644
--- a/source/Plugins/Process/Utility/UnwindLLDB.cpp
+++ b/source/Plugins/Process/Utility/UnwindLLDB.cpp
@@ -7,529 +7,532 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Core/Module.h"
#include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
#include "lldb/Symbol/FuncUnwinders.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/ABI.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Target/Target.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
-#include "UnwindLLDB.h"
#include "RegisterContextLLDB.h"
+#include "UnwindLLDB.h"
using namespace lldb;
using namespace lldb_private;
-UnwindLLDB::UnwindLLDB (Thread &thread) :
- Unwind (thread),
- m_frames(),
- m_unwind_complete(false),
- m_user_supplied_trap_handler_functions()
-{
- ProcessSP process_sp(thread.GetProcess());
- if (process_sp)
- {
- Args args;
- process_sp->GetTarget().GetUserSpecifiedTrapHandlerNames (args);
- size_t count = args.GetArgumentCount();
- for (size_t i = 0; i < count; i++)
- {
- const char *func_name = args.GetArgumentAtIndex(i);
- m_user_supplied_trap_handler_functions.push_back (ConstString (func_name));
- }
+UnwindLLDB::UnwindLLDB(Thread &thread)
+ : Unwind(thread), m_frames(), m_unwind_complete(false),
+ m_user_supplied_trap_handler_functions() {
+ ProcessSP process_sp(thread.GetProcess());
+ if (process_sp) {
+ Args args;
+ process_sp->GetTarget().GetUserSpecifiedTrapHandlerNames(args);
+ size_t count = args.GetArgumentCount();
+ for (size_t i = 0; i < count; i++) {
+ const char *func_name = args.GetArgumentAtIndex(i);
+ m_user_supplied_trap_handler_functions.push_back(ConstString(func_name));
}
+ }
}
-uint32_t
-UnwindLLDB::DoGetFrameCount()
-{
- if (!m_unwind_complete)
- {
+uint32_t UnwindLLDB::DoGetFrameCount() {
+ if (!m_unwind_complete) {
//#define DEBUG_FRAME_SPEED 1
#if DEBUG_FRAME_SPEED
#define FRAME_COUNT 10000
- TimeValue time_value (TimeValue::Now());
+ using namespace std::chrono;
+ auto time_value = steady_clock::now();
#endif
- if (!AddFirstFrame ())
- return 0;
+ if (!AddFirstFrame())
+ return 0;
- ProcessSP process_sp (m_thread.GetProcess());
- ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
+ ProcessSP process_sp(m_thread.GetProcess());
+ ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
- while (AddOneMoreFrame (abi))
- {
+ while (AddOneMoreFrame(abi)) {
#if DEBUG_FRAME_SPEED
- if ((m_frames.size() % FRAME_COUNT) == 0)
- {
- TimeValue now(TimeValue::Now());
- uint64_t delta_t = now - time_value;
- printf ("%u frames in %" PRIu64 ".%09llu ms (%g frames/sec)\n",
- FRAME_COUNT,
- delta_t / TimeValue::NanoSecPerSec,
- delta_t % TimeValue::NanoSecPerSec,
- (float)FRAME_COUNT / ((float)delta_t / (float)TimeValue::NanoSecPerSec));
- time_value = now;
- }
+ if ((m_frames.size() % FRAME_COUNT) == 0) {
+ const auto now = steady_clock::now();
+ const auto delta_t = now - time_value;
+ printf("%u frames in %.9f ms (%g frames/sec)\n", FRAME_COUNT,
+ duration<double, std::milli>(delta_t).count(),
+ (float)FRAME_COUNT / duration<double>(delta_t).count());
+ time_value = now;
+ }
#endif
- }
}
- return m_frames.size ();
+ }
+ return m_frames.size();
}
-bool
-UnwindLLDB::AddFirstFrame ()
-{
- if (m_frames.size() > 0)
- return true;
-
- ProcessSP process_sp (m_thread.GetProcess());
- ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
+bool UnwindLLDB::AddFirstFrame() {
+ if (m_frames.size() > 0)
+ return true;
- // First, set up the 0th (initial) frame
- CursorSP first_cursor_sp(new Cursor ());
- RegisterContextLLDBSP reg_ctx_sp (new RegisterContextLLDB (m_thread,
- RegisterContextLLDBSP(),
- first_cursor_sp->sctx,
- 0, *this));
- if (reg_ctx_sp.get() == NULL)
- goto unwind_done;
-
- if (!reg_ctx_sp->IsValid())
- goto unwind_done;
+ ProcessSP process_sp(m_thread.GetProcess());
+ ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
- if (!reg_ctx_sp->GetCFA (first_cursor_sp->cfa))
- goto unwind_done;
+ // First, set up the 0th (initial) frame
+ CursorSP first_cursor_sp(new Cursor());
+ RegisterContextLLDBSP reg_ctx_sp(new RegisterContextLLDB(
+ m_thread, RegisterContextLLDBSP(), first_cursor_sp->sctx, 0, *this));
+ if (reg_ctx_sp.get() == NULL)
+ goto unwind_done;
- if (!reg_ctx_sp->ReadPC (first_cursor_sp->start_pc))
- goto unwind_done;
+ if (!reg_ctx_sp->IsValid())
+ goto unwind_done;
- // Everything checks out, so release the auto pointer value and let the
- // cursor own it in its shared pointer
- first_cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp;
- m_frames.push_back (first_cursor_sp);
+ if (!reg_ctx_sp->GetCFA(first_cursor_sp->cfa))
+ goto unwind_done;
- // Update the Full Unwind Plan for this frame if not valid
- UpdateUnwindPlanForFirstFrameIfInvalid(abi);
+ if (!reg_ctx_sp->ReadPC(first_cursor_sp->start_pc))
+ goto unwind_done;
- return true;
+ // Everything checks out, so release the auto pointer value and let the
+ // cursor own it in its shared pointer
+ first_cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp;
+ m_frames.push_back(first_cursor_sp);
+
+ // Update the Full Unwind Plan for this frame if not valid
+ UpdateUnwindPlanForFirstFrameIfInvalid(abi);
+
+ return true;
unwind_done:
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
- if (log)
- {
- log->Printf ("th%d Unwind of this thread is complete.", m_thread.GetIndexID());
- }
- m_unwind_complete = true;
- return false;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
+ if (log) {
+ log->Printf("th%d Unwind of this thread is complete.",
+ m_thread.GetIndexID());
+ }
+ m_unwind_complete = true;
+ return false;
}
-UnwindLLDB::CursorSP
-UnwindLLDB::GetOneMoreFrame (ABI* abi)
-{
- assert (m_frames.size() != 0 && "Get one more frame called with empty frame list");
-
- // If we've already gotten to the end of the stack, don't bother to try again...
- if (m_unwind_complete)
- return nullptr;
-
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
-
- CursorSP prev_frame = m_frames.back();
- uint32_t cur_idx = m_frames.size();
-
- CursorSP cursor_sp(new Cursor ());
- RegisterContextLLDBSP reg_ctx_sp(new RegisterContextLLDB (m_thread,
- prev_frame->reg_ctx_lldb_sp,
- cursor_sp->sctx,
- cur_idx,
- *this));
-
- // We want to detect an unwind that cycles erroneously and stop backtracing.
- // Don't want this maximum unwind limit to be too low -- if you have a backtrace
- // with an "infinitely recursing" bug, it will crash when the stack blows out
- // and the first 35,000 frames are uninteresting - it's the top most 5 frames that
- // you actually care about. So you can't just cap the unwind at 10,000 or something.
- // Realistically anything over around 200,000 is going to blow out the stack space.
- // If we're still unwinding at that point, we're probably never going to finish.
- if (cur_idx > 300000)
- {
- if (log)
- log->Printf ("%*sFrame %d unwound too many frames, assuming unwind has gone astray, stopping.",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) {
+ assert(m_frames.size() != 0 &&
+ "Get one more frame called with empty frame list");
+
+ // If we've already gotten to the end of the stack, don't bother to try
+ // again...
+ if (m_unwind_complete)
+ return nullptr;
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
+
+ CursorSP prev_frame = m_frames.back();
+ uint32_t cur_idx = m_frames.size();
+
+ CursorSP cursor_sp(new Cursor());
+ RegisterContextLLDBSP reg_ctx_sp(new RegisterContextLLDB(
+ m_thread, prev_frame->reg_ctx_lldb_sp, cursor_sp->sctx, cur_idx, *this));
+
+ // We want to detect an unwind that cycles erroneously and stop backtracing.
+ // Don't want this maximum unwind limit to be too low -- if you have a
+ // backtrace
+ // with an "infinitely recursing" bug, it will crash when the stack blows out
+ // and the first 35,000 frames are uninteresting - it's the top most 5 frames
+ // that
+ // you actually care about. So you can't just cap the unwind at 10,000 or
+ // something.
+ // Realistically anything over around 200,000 is going to blow out the stack
+ // space.
+ // If we're still unwinding at that point, we're probably never going to
+ // finish.
+ if (cur_idx > 300000) {
+ if (log)
+ log->Printf("%*sFrame %d unwound too many frames, assuming unwind has "
+ "gone astray, stopping.",
+ cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ return nullptr;
+ }
+
+ if (reg_ctx_sp.get() == NULL) {
+ // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to
+ // that and return
+ // true. Subsequent calls to TryFallbackUnwindPlan() will return false.
+ if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
+ // TryFallbackUnwindPlan for prev_frame succeeded and updated
+ // reg_ctx_lldb_sp field of
+ // prev_frame. However, cfa field of prev_frame still needs to be updated.
+ // Hence updating it.
+ if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
return nullptr;
- }
-
- if (reg_ctx_sp.get() == NULL)
- {
- // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to that and return
- // true. Subsequent calls to TryFallbackUnwindPlan() will return false.
- if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan())
- {
- // TryFallbackUnwindPlan for prev_frame succeeded and updated reg_ctx_lldb_sp field of
- // prev_frame. However, cfa field of prev_frame still needs to be updated. Hence updating it.
- if ( !(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
- return nullptr;
-
- return GetOneMoreFrame (abi);
- }
- if (log)
- log->Printf ("%*sFrame %d did not get a RegisterContext, stopping.",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
- return nullptr;
+ return GetOneMoreFrame(abi);
}
- if (!reg_ctx_sp->IsValid())
- {
- // We failed to get a valid RegisterContext.
- // See if the regctx below this on the stack has a fallback unwind plan it can use.
- // Subsequent calls to TryFallbackUnwindPlan() will return false.
- if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan())
- {
- // TryFallbackUnwindPlan for prev_frame succeeded and updated reg_ctx_lldb_sp field of
- // prev_frame. However, cfa field of prev_frame still needs to be updated. Hence updating it.
- if ( !(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
- return nullptr;
-
- return GetOneMoreFrame (abi);
- }
-
- if (log)
- log->Printf("%*sFrame %d invalid RegisterContext for this frame, stopping stack walk",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ if (log)
+ log->Printf("%*sFrame %d did not get a RegisterContext, stopping.",
+ cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ return nullptr;
+ }
+
+ if (!reg_ctx_sp->IsValid()) {
+ // We failed to get a valid RegisterContext.
+ // See if the regctx below this on the stack has a fallback unwind plan it
+ // can use.
+ // Subsequent calls to TryFallbackUnwindPlan() will return false.
+ if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
+ // TryFallbackUnwindPlan for prev_frame succeeded and updated
+ // reg_ctx_lldb_sp field of
+ // prev_frame. However, cfa field of prev_frame still needs to be updated.
+ // Hence updating it.
+ if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
return nullptr;
+
+ return GetOneMoreFrame(abi);
}
- if (!reg_ctx_sp->GetCFA (cursor_sp->cfa))
- {
- // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to that and return
- // true. Subsequent calls to TryFallbackUnwindPlan() will return false.
- if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan())
- {
- // TryFallbackUnwindPlan for prev_frame succeeded and updated reg_ctx_lldb_sp field of
- // prev_frame. However, cfa field of prev_frame still needs to be updated. Hence updating it.
- if ( !(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
- return nullptr;
-
- return GetOneMoreFrame (abi);
- }
- if (log)
- log->Printf("%*sFrame %d did not get CFA for this frame, stopping stack walk",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ if (log)
+ log->Printf("%*sFrame %d invalid RegisterContext for this frame, "
+ "stopping stack walk",
+ cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ return nullptr;
+ }
+ if (!reg_ctx_sp->GetCFA(cursor_sp->cfa)) {
+ // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to
+ // that and return
+ // true. Subsequent calls to TryFallbackUnwindPlan() will return false.
+ if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
+ // TryFallbackUnwindPlan for prev_frame succeeded and updated
+ // reg_ctx_lldb_sp field of
+ // prev_frame. However, cfa field of prev_frame still needs to be updated.
+ // Hence updating it.
+ if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
return nullptr;
+
+ return GetOneMoreFrame(abi);
}
- if (abi && !abi->CallFrameAddressIsValid(cursor_sp->cfa))
- {
- // On Mac OS X, the _sigtramp asynchronous signal trampoline frame may not have
- // its (constructed) CFA aligned correctly -- don't do the abi alignment check for
- // these.
- if (reg_ctx_sp->IsTrapHandlerFrame() == false)
- {
- // See if we can find a fallback unwind plan for THIS frame. It may be
- // that the UnwindPlan we're using for THIS frame was bad and gave us a
- // bad CFA.
- // If that's not it, then see if we can change the UnwindPlan for the frame
- // below us ("NEXT") -- see if using that other UnwindPlan gets us a better
- // unwind state.
- if (reg_ctx_sp->TryFallbackUnwindPlan() == false
- || reg_ctx_sp->GetCFA (cursor_sp->cfa) == false
- || abi->CallFrameAddressIsValid(cursor_sp->cfa) == false)
- {
- if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan())
- {
- // TryFallbackUnwindPlan for prev_frame succeeded and updated reg_ctx_lldb_sp field of
- // prev_frame. However, cfa field of prev_frame still needs to be updated. Hence updating it.
- if ( !(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
- return nullptr;
-
- return GetOneMoreFrame (abi);
- }
-
- if (log)
- log->Printf("%*sFrame %d did not get a valid CFA for this frame, stopping stack walk",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
- return nullptr;
- }
- else
- {
- if (log)
- log->Printf("%*sFrame %d had a bad CFA value but we switched the UnwindPlan being used and got one that looks more realistic.",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
- }
- }
- }
- if (!reg_ctx_sp->ReadPC (cursor_sp->start_pc))
- {
- // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to that and return
- // true. Subsequent calls to TryFallbackUnwindPlan() will return false.
- if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan())
- {
- // TryFallbackUnwindPlan for prev_frame succeeded and updated reg_ctx_lldb_sp field of
- // prev_frame. However, cfa field of prev_frame still needs to be updated. Hence updating it.
- if ( !(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
- return nullptr;
-
- return GetOneMoreFrame (abi);
+
+ if (log)
+ log->Printf(
+ "%*sFrame %d did not get CFA for this frame, stopping stack walk",
+ cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ return nullptr;
+ }
+ if (abi && !abi->CallFrameAddressIsValid(cursor_sp->cfa)) {
+ // On Mac OS X, the _sigtramp asynchronous signal trampoline frame may not
+ // have
+ // its (constructed) CFA aligned correctly -- don't do the abi alignment
+ // check for
+ // these.
+ if (reg_ctx_sp->IsTrapHandlerFrame() == false) {
+ // See if we can find a fallback unwind plan for THIS frame. It may be
+ // that the UnwindPlan we're using for THIS frame was bad and gave us a
+ // bad CFA.
+ // If that's not it, then see if we can change the UnwindPlan for the
+ // frame
+ // below us ("NEXT") -- see if using that other UnwindPlan gets us a
+ // better
+ // unwind state.
+ if (reg_ctx_sp->TryFallbackUnwindPlan() == false ||
+ reg_ctx_sp->GetCFA(cursor_sp->cfa) == false ||
+ abi->CallFrameAddressIsValid(cursor_sp->cfa) == false) {
+ if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
+ // TryFallbackUnwindPlan for prev_frame succeeded and updated
+ // reg_ctx_lldb_sp field of
+ // prev_frame. However, cfa field of prev_frame still needs to be
+ // updated. Hence updating it.
+ if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
+ return nullptr;
+
+ return GetOneMoreFrame(abi);
}
if (log)
- log->Printf("%*sFrame %d did not get PC for this frame, stopping stack walk",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ log->Printf("%*sFrame %d did not get a valid CFA for this frame, "
+ "stopping stack walk",
+ cur_idx < 100 ? cur_idx : 100, "", cur_idx);
return nullptr;
- }
- if (abi && !abi->CodeAddressIsValid (cursor_sp->start_pc))
- {
- // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to that and return
- // true. Subsequent calls to TryFallbackUnwindPlan() will return false.
- if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan())
- {
- // TryFallbackUnwindPlan for prev_frame succeeded and updated reg_ctx_lldb_sp field of
- // prev_frame. However, cfa field of prev_frame still needs to be updated. Hence updating it.
- if ( !(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
- return nullptr;
-
- return GetOneMoreFrame (abi);
- }
-
+ } else {
if (log)
- log->Printf("%*sFrame %d did not get a valid PC, stopping stack walk",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ log->Printf("%*sFrame %d had a bad CFA value but we switched the "
+ "UnwindPlan being used and got one that looks more "
+ "realistic.",
+ cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ }
+ }
+ }
+ if (!reg_ctx_sp->ReadPC(cursor_sp->start_pc)) {
+ // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to
+ // that and return
+ // true. Subsequent calls to TryFallbackUnwindPlan() will return false.
+ if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
+ // TryFallbackUnwindPlan for prev_frame succeeded and updated
+ // reg_ctx_lldb_sp field of
+ // prev_frame. However, cfa field of prev_frame still needs to be updated.
+ // Hence updating it.
+ if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
return nullptr;
+
+ return GetOneMoreFrame(abi);
}
- // Infinite loop where the current cursor is the same as the previous one...
- if (prev_frame->start_pc == cursor_sp->start_pc && prev_frame->cfa == cursor_sp->cfa)
- {
- if (log)
- log->Printf ("th%d pc of this frame is the same as the previous frame and CFAs for both frames are identical -- stopping unwind", m_thread.GetIndexID());
+
+ if (log)
+ log->Printf(
+ "%*sFrame %d did not get PC for this frame, stopping stack walk",
+ cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ return nullptr;
+ }
+ if (abi && !abi->CodeAddressIsValid(cursor_sp->start_pc)) {
+ // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to
+ // that and return
+ // true. Subsequent calls to TryFallbackUnwindPlan() will return false.
+ if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
+ // TryFallbackUnwindPlan for prev_frame succeeded and updated
+ // reg_ctx_lldb_sp field of
+ // prev_frame. However, cfa field of prev_frame still needs to be updated.
+ // Hence updating it.
+ if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
return nullptr;
+
+ return GetOneMoreFrame(abi);
}
- cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp;
- return cursor_sp;
+ if (log)
+ log->Printf("%*sFrame %d did not get a valid PC, stopping stack walk",
+ cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ return nullptr;
+ }
+ // Infinite loop where the current cursor is the same as the previous one...
+ if (prev_frame->start_pc == cursor_sp->start_pc &&
+ prev_frame->cfa == cursor_sp->cfa) {
+ if (log)
+ log->Printf("th%d pc of this frame is the same as the previous frame and "
+ "CFAs for both frames are identical -- stopping unwind",
+ m_thread.GetIndexID());
+ return nullptr;
+ }
+
+ cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp;
+ return cursor_sp;
}
-void
-UnwindLLDB::UpdateUnwindPlanForFirstFrameIfInvalid (ABI *abi)
-{
- // This function is called for First Frame only.
- assert (m_frames.size() == 1 && "No. of cursor frames are not 1");
-
- bool old_m_unwind_complete = m_unwind_complete;
- CursorSP old_m_candidate_frame = m_candidate_frame;
-
- // Try to unwind 2 more frames using the Unwinder. It uses Full UnwindPlan
- // and if Full UnwindPlan fails, then uses FallBack UnwindPlan. Also
- // update the cfa of Frame 0 (if required).
- AddOneMoreFrame(abi);
-
- // Remove all the frames added by above function as the purpose of
- // using above function was just to check whether Unwinder of Frame 0
- // works or not.
- for(uint32_t i=1; i<m_frames.size(); i++)
- m_frames.pop_back();
-
- // Restore status after calling AddOneMoreFrame
- m_unwind_complete = old_m_unwind_complete;
- m_candidate_frame = old_m_candidate_frame;
- return;
-}
+void UnwindLLDB::UpdateUnwindPlanForFirstFrameIfInvalid(ABI *abi) {
+ // This function is called for First Frame only.
+ assert(m_frames.size() == 1 && "No. of cursor frames are not 1");
+ bool old_m_unwind_complete = m_unwind_complete;
+ CursorSP old_m_candidate_frame = m_candidate_frame;
-bool
-UnwindLLDB::AddOneMoreFrame (ABI *abi)
-{
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
+ // Try to unwind 2 more frames using the Unwinder. It uses Full UnwindPlan
+ // and if Full UnwindPlan fails, then uses FallBack UnwindPlan. Also
+ // update the cfa of Frame 0 (if required).
+ AddOneMoreFrame(abi);
- // Frame zero is a little different
- if (m_frames.empty())
- return false;
+ // Remove all the frames added by above function as the purpose of
+ // using above function was just to check whether Unwinder of Frame 0
+ // works or not.
+ for (uint32_t i = 1; i < m_frames.size(); i++)
+ m_frames.pop_back();
- // If we've already gotten to the end of the stack, don't bother to try again...
- if (m_unwind_complete)
- return false;
+ // Restore status after calling AddOneMoreFrame
+ m_unwind_complete = old_m_unwind_complete;
+ m_candidate_frame = old_m_candidate_frame;
+ return;
+}
- CursorSP new_frame = m_candidate_frame;
- if (new_frame == nullptr)
- new_frame = GetOneMoreFrame(abi);
+bool UnwindLLDB::AddOneMoreFrame(ABI *abi) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
- if (new_frame == nullptr)
- {
- if (log)
- log->Printf ("th%d Unwind of this thread is complete.", m_thread.GetIndexID());
- m_unwind_complete = true;
- return false;
- }
+ // Frame zero is a little different
+ if (m_frames.empty())
+ return false;
- m_frames.push_back(new_frame);
+ // If we've already gotten to the end of the stack, don't bother to try
+ // again...
+ if (m_unwind_complete)
+ return false;
- // If we can get one more frame further then accept that we get back a correct frame.
- m_candidate_frame = GetOneMoreFrame(abi);
- if (m_candidate_frame)
- return true;
-
- // We can't go further from the frame returned by GetOneMore frame. Lets try to get a
- // different frame with using the fallback unwind plan.
- if (!m_frames[m_frames.size() - 2]->reg_ctx_lldb_sp->TryFallbackUnwindPlan())
- {
- // We don't have a valid fallback unwind plan. Accept the frame as it is. This is a
- // valid situation when we are at the bottom of the stack.
- return true;
- }
+ CursorSP new_frame = m_candidate_frame;
+ if (new_frame == nullptr)
+ new_frame = GetOneMoreFrame(abi);
- // Remove the possibly incorrect frame from the frame list and try to add a different one with
- // the newly selected fallback unwind plan.
- m_frames.pop_back();
- CursorSP new_frame_v2 = GetOneMoreFrame(abi);
- if (new_frame_v2 == nullptr)
- {
- // We haven't got a new frame from the fallback unwind plan. Accept the frame from the
- // original unwind plan. This is a valid situation when we are at the bottom of the stack.
- m_frames.push_back(new_frame);
- return true;
- }
+ if (new_frame == nullptr) {
+ if (log)
+ log->Printf("th%d Unwind of this thread is complete.",
+ m_thread.GetIndexID());
+ m_unwind_complete = true;
+ return false;
+ }
- // Push the new frame to the list and try to continue from this frame. If we can get a new frame
- // then accept it as the correct one.
- m_frames.push_back(new_frame_v2);
- m_candidate_frame = GetOneMoreFrame(abi);
- if (m_candidate_frame)
- {
- // If control reached here then TryFallbackUnwindPlan had succeeded for Cursor::m_frames[m_frames.size() - 2].
- // It also succeeded to Unwind next 2 frames i.e. m_frames[m_frames.size() - 1] and a frame after that.
- // For Cursor::m_frames[m_frames.size() - 2], reg_ctx_lldb_sp field was already updated during TryFallbackUnwindPlan
- // call above. However, cfa field still needs to be updated. Hence updating it here and then returning.
- if ( !(m_frames[m_frames.size() - 2]->reg_ctx_lldb_sp->GetCFA(m_frames[m_frames.size() - 2]->cfa)))
- return false;
- return true;
- }
+ m_frames.push_back(new_frame);
- // The new frame hasn't helped in unwinding. Fall back to the original one as the default unwind
- // plan is usually more reliable then the fallback one.
- m_frames.pop_back();
+ // If we can get one more frame further then accept that we get back a correct
+ // frame.
+ m_candidate_frame = GetOneMoreFrame(abi);
+ if (m_candidate_frame)
+ return true;
+
+ // We can't go further from the frame returned by GetOneMore frame. Lets try
+ // to get a
+ // different frame with using the fallback unwind plan.
+ if (!m_frames[m_frames.size() - 2]
+ ->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
+ // We don't have a valid fallback unwind plan. Accept the frame as it is.
+ // This is a
+ // valid situation when we are at the bottom of the stack.
+ return true;
+ }
+
+ // Remove the possibly incorrect frame from the frame list and try to add a
+ // different one with
+ // the newly selected fallback unwind plan.
+ m_frames.pop_back();
+ CursorSP new_frame_v2 = GetOneMoreFrame(abi);
+ if (new_frame_v2 == nullptr) {
+ // We haven't got a new frame from the fallback unwind plan. Accept the
+ // frame from the
+ // original unwind plan. This is a valid situation when we are at the bottom
+ // of the stack.
m_frames.push_back(new_frame);
return true;
+ }
+
+ // Push the new frame to the list and try to continue from this frame. If we
+ // can get a new frame
+ // then accept it as the correct one.
+ m_frames.push_back(new_frame_v2);
+ m_candidate_frame = GetOneMoreFrame(abi);
+ if (m_candidate_frame) {
+ // If control reached here then TryFallbackUnwindPlan had succeeded for
+ // Cursor::m_frames[m_frames.size() - 2].
+ // It also succeeded to Unwind next 2 frames i.e. m_frames[m_frames.size() -
+ // 1] and a frame after that.
+ // For Cursor::m_frames[m_frames.size() - 2], reg_ctx_lldb_sp field was
+ // already updated during TryFallbackUnwindPlan
+ // call above. However, cfa field still needs to be updated. Hence updating
+ // it here and then returning.
+ if (!(m_frames[m_frames.size() - 2]->reg_ctx_lldb_sp->GetCFA(
+ m_frames[m_frames.size() - 2]->cfa)))
+ return false;
+ return true;
+ }
+
+ // The new frame hasn't helped in unwinding. Fall back to the original one as
+ // the default unwind
+ // plan is usually more reliable then the fallback one.
+ m_frames.pop_back();
+ m_frames.push_back(new_frame);
+ return true;
}
-bool
-UnwindLLDB::DoGetFrameInfoAtIndex (uint32_t idx, addr_t& cfa, addr_t& pc)
-{
- if (m_frames.size() == 0)
- {
- if (!AddFirstFrame())
- return false;
- }
+bool UnwindLLDB::DoGetFrameInfoAtIndex(uint32_t idx, addr_t &cfa, addr_t &pc) {
+ if (m_frames.size() == 0) {
+ if (!AddFirstFrame())
+ return false;
+ }
- ProcessSP process_sp (m_thread.GetProcess());
- ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
+ ProcessSP process_sp(m_thread.GetProcess());
+ ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
- while (idx >= m_frames.size() && AddOneMoreFrame (abi))
- ;
+ while (idx >= m_frames.size() && AddOneMoreFrame(abi))
+ ;
- if (idx < m_frames.size ())
- {
- cfa = m_frames[idx]->cfa;
- pc = m_frames[idx]->start_pc;
- return true;
- }
- return false;
+ if (idx < m_frames.size()) {
+ cfa = m_frames[idx]->cfa;
+ pc = m_frames[idx]->start_pc;
+ return true;
+ }
+ return false;
}
lldb::RegisterContextSP
-UnwindLLDB::DoCreateRegisterContextForFrame (StackFrame *frame)
-{
- lldb::RegisterContextSP reg_ctx_sp;
- uint32_t idx = frame->GetConcreteFrameIndex ();
-
- if (idx == 0)
- {
- return m_thread.GetRegisterContext();
- }
-
- if (m_frames.size() == 0)
- {
- if (!AddFirstFrame())
- return reg_ctx_sp;
- }
-
- ProcessSP process_sp (m_thread.GetProcess());
- ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
-
- while (idx >= m_frames.size())
- {
- if (!AddOneMoreFrame (abi))
- break;
- }
-
- const uint32_t num_frames = m_frames.size();
- if (idx < num_frames)
- {
- Cursor *frame_cursor = m_frames[idx].get();
- reg_ctx_sp = frame_cursor->reg_ctx_lldb_sp;
- }
- return reg_ctx_sp;
+UnwindLLDB::DoCreateRegisterContextForFrame(StackFrame *frame) {
+ lldb::RegisterContextSP reg_ctx_sp;
+ uint32_t idx = frame->GetConcreteFrameIndex();
+
+ if (idx == 0) {
+ return m_thread.GetRegisterContext();
+ }
+
+ if (m_frames.size() == 0) {
+ if (!AddFirstFrame())
+ return reg_ctx_sp;
+ }
+
+ ProcessSP process_sp(m_thread.GetProcess());
+ ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
+
+ while (idx >= m_frames.size()) {
+ if (!AddOneMoreFrame(abi))
+ break;
+ }
+
+ const uint32_t num_frames = m_frames.size();
+ if (idx < num_frames) {
+ Cursor *frame_cursor = m_frames[idx].get();
+ reg_ctx_sp = frame_cursor->reg_ctx_lldb_sp;
+ }
+ return reg_ctx_sp;
}
UnwindLLDB::RegisterContextLLDBSP
-UnwindLLDB::GetRegisterContextForFrameNum (uint32_t frame_num)
-{
- RegisterContextLLDBSP reg_ctx_sp;
- if (frame_num < m_frames.size())
- reg_ctx_sp = m_frames[frame_num]->reg_ctx_lldb_sp;
- return reg_ctx_sp;
+UnwindLLDB::GetRegisterContextForFrameNum(uint32_t frame_num) {
+ RegisterContextLLDBSP reg_ctx_sp;
+ if (frame_num < m_frames.size())
+ reg_ctx_sp = m_frames[frame_num]->reg_ctx_lldb_sp;
+ return reg_ctx_sp;
}
-bool
-UnwindLLDB::SearchForSavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc, uint32_t starting_frame_num, bool pc_reg)
-{
- int64_t frame_num = starting_frame_num;
- if (static_cast<size_t>(frame_num) >= m_frames.size())
- return false;
-
- // Never interrogate more than one level while looking for the saved pc value. If the value
- // isn't saved by frame_num, none of the frames lower on the stack will have a useful value.
- if (pc_reg)
- {
- UnwindLLDB::RegisterSearchResult result;
- result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister (lldb_regnum, regloc);
- if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound)
- return true;
- else
- return false;
- }
- while (frame_num >= 0)
- {
- UnwindLLDB::RegisterSearchResult result;
- result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister (lldb_regnum, regloc);
-
- // We descended down to the live register context aka stack frame 0 and are reading the value
- // out of a live register.
- if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound
- && regloc.type == UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext)
- {
- return true;
- }
+bool UnwindLLDB::SearchForSavedLocationForRegister(
+ uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc,
+ uint32_t starting_frame_num, bool pc_reg) {
+ int64_t frame_num = starting_frame_num;
+ if (static_cast<size_t>(frame_num) >= m_frames.size())
+ return false;
- // If we have unwind instructions saying that register N is saved in register M in the middle of
- // the stack (and N can equal M here, meaning the register was not used in this function), then
- // change the register number we're looking for to M and keep looking for a concrete location
- // down the stack, or an actual value from a live RegisterContext at frame 0.
- if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound
- && regloc.type == UnwindLLDB::RegisterLocation::eRegisterInRegister
- && frame_num > 0)
- {
- result = UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
- lldb_regnum = regloc.location.register_number;
- }
+ // Never interrogate more than one level while looking for the saved pc value.
+ // If the value
+ // isn't saved by frame_num, none of the frames lower on the stack will have a
+ // useful value.
+ if (pc_reg) {
+ UnwindLLDB::RegisterSearchResult result;
+ result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister(
+ lldb_regnum, regloc);
+ if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound)
+ return true;
+ else
+ return false;
+ }
+ while (frame_num >= 0) {
+ UnwindLLDB::RegisterSearchResult result;
+ result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister(
+ lldb_regnum, regloc);
+
+ // We descended down to the live register context aka stack frame 0 and are
+ // reading the value
+ // out of a live register.
+ if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound &&
+ regloc.type ==
+ UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext) {
+ return true;
+ }
- if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound)
- return true;
- if (result == UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile)
- return false;
- frame_num--;
+ // If we have unwind instructions saying that register N is saved in
+ // register M in the middle of
+ // the stack (and N can equal M here, meaning the register was not used in
+ // this function), then
+ // change the register number we're looking for to M and keep looking for a
+ // concrete location
+ // down the stack, or an actual value from a live RegisterContext at frame
+ // 0.
+ if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound &&
+ regloc.type == UnwindLLDB::RegisterLocation::eRegisterInRegister &&
+ frame_num > 0) {
+ result = UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
+ lldb_regnum = regloc.location.register_number;
}
- return false;
+
+ if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound)
+ return true;
+ if (result == UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile)
+ return false;
+ frame_num--;
+ }
+ return false;
}
diff --git a/source/Plugins/Process/Utility/UnwindLLDB.h b/source/Plugins/Process/Utility/UnwindLLDB.h
index d3c07078759b..b9323032180d 100644
--- a/source/Plugins/Process/Utility/UnwindLLDB.h
+++ b/source/Plugins/Process/Utility/UnwindLLDB.h
@@ -16,148 +16,150 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-public.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Symbol/FuncUnwinders.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Unwind.h"
+#include "lldb/lldb-public.h"
namespace lldb_private {
class RegisterContextLLDB;
-class UnwindLLDB : public lldb_private::Unwind
-{
-public:
- UnwindLLDB (lldb_private::Thread &thread);
+class UnwindLLDB : public lldb_private::Unwind {
+public:
+ UnwindLLDB(lldb_private::Thread &thread);
- ~UnwindLLDB() override = default;
+ ~UnwindLLDB() override = default;
- enum RegisterSearchResult
- {
- eRegisterFound = 0,
- eRegisterNotFound,
- eRegisterIsVolatile
- };
+ enum RegisterSearchResult {
+ eRegisterFound = 0,
+ eRegisterNotFound,
+ eRegisterIsVolatile
+ };
protected:
- friend class lldb_private::RegisterContextLLDB;
-
- struct RegisterLocation {
- enum RegisterLocationTypes
- {
- eRegisterNotSaved = 0, // register was not preserved by callee. If volatile reg, is unavailable
- eRegisterSavedAtMemoryLocation, // register is saved at a specific word of target mem (target_memory_location)
- eRegisterInRegister, // register is available in a (possible other) register (register_number)
- eRegisterSavedAtHostMemoryLocation, // register is saved at a word in lldb's address space
- eRegisterValueInferred, // register val was computed (and is in inferred_value)
- eRegisterInLiveRegisterContext // register value is in a live (stack frame #0) register
- };
- int type;
- union
- {
- lldb::addr_t target_memory_location;
- uint32_t register_number; // in eRegisterKindLLDB register numbering system
- void* host_memory_location;
- uint64_t inferred_value; // eRegisterValueInferred - e.g. stack pointer == cfa + offset
- } location;
+ friend class lldb_private::RegisterContextLLDB;
+
+ struct RegisterLocation {
+ enum RegisterLocationTypes {
+ eRegisterNotSaved = 0, // register was not preserved by callee. If
+ // volatile reg, is unavailable
+ eRegisterSavedAtMemoryLocation, // register is saved at a specific word of
+ // target mem (target_memory_location)
+ eRegisterInRegister, // register is available in a (possible other)
+ // register (register_number)
+ eRegisterSavedAtHostMemoryLocation, // register is saved at a word in
+ // lldb's address space
+ eRegisterValueInferred, // register val was computed (and is in
+ // inferred_value)
+ eRegisterInLiveRegisterContext // register value is in a live (stack frame
+ // #0) register
};
+ int type;
+ union {
+ lldb::addr_t target_memory_location;
+ uint32_t
+ register_number; // in eRegisterKindLLDB register numbering system
+ void *host_memory_location;
+ uint64_t inferred_value; // eRegisterValueInferred - e.g. stack pointer ==
+ // cfa + offset
+ } location;
+ };
+
+ void DoClear() override {
+ m_frames.clear();
+ m_candidate_frame.reset();
+ m_unwind_complete = false;
+ }
+
+ uint32_t DoGetFrameCount() override;
+
+ bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
+ lldb::addr_t &start_pc) override;
+
+ lldb::RegisterContextSP
+ DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
+
+ typedef std::shared_ptr<RegisterContextLLDB> RegisterContextLLDBSP;
+
+ // Needed to retrieve the "next" frame (e.g. frame 2 needs to retrieve frame
+ // 1's RegisterContextLLDB)
+ // The RegisterContext for frame_num must already exist or this returns an
+ // empty shared pointer.
+ RegisterContextLLDBSP GetRegisterContextForFrameNum(uint32_t frame_num);
+
+ // Iterate over the RegisterContextLLDB's in our m_frames vector, look for the
+ // first one that
+ // has a saved location for this reg.
+ bool SearchForSavedLocationForRegister(
+ uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc,
+ uint32_t starting_frame_num, bool pc_register);
+
+ //------------------------------------------------------------------
+ /// Provide the list of user-specified trap handler functions
+ ///
+ /// The Platform is one source of trap handler function names; that
+ /// may be augmented via a setting. The setting needs to be converted
+ /// into an array of ConstStrings before it can be used - we only want
+ /// to do that once per thread so it's here in the UnwindLLDB object.
+ ///
+ /// @return
+ /// Vector of ConstStrings of trap handler function names. May be
+ /// empty.
+ //------------------------------------------------------------------
+ const std::vector<ConstString> &GetUserSpecifiedTrapHandlerFunctionNames() {
+ return m_user_supplied_trap_handler_functions;
+ }
- void
- DoClear() override
- {
- m_frames.clear();
- m_candidate_frame.reset();
- m_unwind_complete = false;
- }
-
- uint32_t
- DoGetFrameCount() override;
-
- bool
- DoGetFrameInfoAtIndex(uint32_t frame_idx,
- lldb::addr_t& cfa,
- lldb::addr_t& start_pc) override;
-
- lldb::RegisterContextSP
- DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
-
- typedef std::shared_ptr<RegisterContextLLDB> RegisterContextLLDBSP;
-
- // Needed to retrieve the "next" frame (e.g. frame 2 needs to retrieve frame 1's RegisterContextLLDB)
- // The RegisterContext for frame_num must already exist or this returns an empty shared pointer.
+private:
+ struct Cursor {
+ lldb::addr_t start_pc; // The start address of the function/symbol for this
+ // frame - current pc if unknown
+ lldb::addr_t cfa; // The canonical frame address for this stack frame
+ lldb_private::SymbolContext sctx; // A symbol context we'll contribute to &
+ // provide to the StackFrame creation
RegisterContextLLDBSP
- GetRegisterContextForFrameNum (uint32_t frame_num);
-
- // Iterate over the RegisterContextLLDB's in our m_frames vector, look for the first one that
- // has a saved location for this reg.
- bool
- SearchForSavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc, uint32_t starting_frame_num, bool pc_register);
-
-
- //------------------------------------------------------------------
- /// Provide the list of user-specified trap handler functions
- ///
- /// The Platform is one source of trap handler function names; that
- /// may be augmented via a setting. The setting needs to be converted
- /// into an array of ConstStrings before it can be used - we only want
- /// to do that once per thread so it's here in the UnwindLLDB object.
- ///
- /// @return
- /// Vector of ConstStrings of trap handler function names. May be
- /// empty.
- //------------------------------------------------------------------
- const std::vector<ConstString> &
- GetUserSpecifiedTrapHandlerFunctionNames ()
- {
- return m_user_supplied_trap_handler_functions;
- }
+ reg_ctx_lldb_sp; // These are all RegisterContextLLDB's
-private:
- struct Cursor
- {
- lldb::addr_t start_pc; // The start address of the function/symbol for this frame - current pc if unknown
- lldb::addr_t cfa; // The canonical frame address for this stack frame
- lldb_private::SymbolContext sctx; // A symbol context we'll contribute to & provide to the StackFrame creation
- RegisterContextLLDBSP reg_ctx_lldb_sp; // These are all RegisterContextLLDB's
-
- Cursor () : start_pc (LLDB_INVALID_ADDRESS), cfa (LLDB_INVALID_ADDRESS), sctx(), reg_ctx_lldb_sp() { }
- private:
- DISALLOW_COPY_AND_ASSIGN (Cursor);
- };
+ Cursor()
+ : start_pc(LLDB_INVALID_ADDRESS), cfa(LLDB_INVALID_ADDRESS), sctx(),
+ reg_ctx_lldb_sp() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Cursor);
+ };
+
+ typedef std::shared_ptr<Cursor> CursorSP;
+ std::vector<CursorSP> m_frames;
+ CursorSP m_candidate_frame;
+ bool m_unwind_complete; // If this is true, we've enumerated all the frames in
+ // the stack, and m_frames.size() is the
+ // number of frames, etc. Otherwise we've only gone as far as directly asked,
+ // and m_frames.size()
+ // is how far we've currently gone.
+
+ std::vector<ConstString> m_user_supplied_trap_handler_functions;
+
+ //-----------------------------------------------------------------
+ // Check if Full UnwindPlan of First frame is valid or not.
+ // If not then try Fallback UnwindPlan of the frame. If Fallback
+ // UnwindPlan succeeds then update the Full UnwindPlan with the
+ // Fallback UnwindPlan.
+ //-----------------------------------------------------------------
+ void UpdateUnwindPlanForFirstFrameIfInvalid(ABI *abi);
+
+ CursorSP GetOneMoreFrame(ABI *abi);
+
+ bool AddOneMoreFrame(ABI *abi);
+
+ bool AddFirstFrame();
- typedef std::shared_ptr<Cursor> CursorSP;
- std::vector<CursorSP> m_frames;
- CursorSP m_candidate_frame;
- bool m_unwind_complete; // If this is true, we've enumerated all the frames in the stack, and m_frames.size() is the
- // number of frames, etc. Otherwise we've only gone as far as directly asked, and m_frames.size()
- // is how far we've currently gone.
-
- std::vector<ConstString> m_user_supplied_trap_handler_functions;
-
- //-----------------------------------------------------------------
- // Check if Full UnwindPlan of First frame is valid or not.
- // If not then try Fallback UnwindPlan of the frame. If Fallback
- // UnwindPlan succeeds then update the Full UnwindPlan with the
- // Fallback UnwindPlan.
- //-----------------------------------------------------------------
- void
- UpdateUnwindPlanForFirstFrameIfInvalid (ABI* abi);
-
- CursorSP
- GetOneMoreFrame (ABI* abi);
-
- bool
- AddOneMoreFrame (ABI *abi);
-
- bool
- AddFirstFrame ();
-
- //------------------------------------------------------------------
- // For UnwindLLDB only
- //------------------------------------------------------------------
- DISALLOW_COPY_AND_ASSIGN (UnwindLLDB);
+ //------------------------------------------------------------------
+ // For UnwindLLDB only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN(UnwindLLDB);
};
} // namespace lldb_private
diff --git a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp
index d011314b0963..e2691be603ec 100644
--- a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp
+++ b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp
@@ -13,8 +13,8 @@
// Project includes
#include "lldb/Core/ArchSpec.h"
#include "lldb/Symbol/Function.h"
-#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
@@ -25,251 +25,230 @@
using namespace lldb;
using namespace lldb_private;
-UnwindMacOSXFrameBackchain::UnwindMacOSXFrameBackchain (Thread &thread) :
- Unwind (thread),
- m_cursors()
-{
-}
-
-uint32_t
-UnwindMacOSXFrameBackchain::DoGetFrameCount()
-{
- if (m_cursors.empty())
- {
- ExecutionContext exe_ctx (m_thread.shared_from_this());
- Target *target = exe_ctx.GetTargetPtr();
- if (target)
- {
- const ArchSpec& target_arch = target->GetArchitecture ();
- // Frame zero should always be supplied by the thread...
- exe_ctx.SetFrameSP (m_thread.GetStackFrameAtIndex (0));
-
- if (target_arch.GetAddressByteSize() == 8)
- GetStackFrameData_x86_64 (exe_ctx);
- else
- GetStackFrameData_i386 (exe_ctx);
- }
+UnwindMacOSXFrameBackchain::UnwindMacOSXFrameBackchain(Thread &thread)
+ : Unwind(thread), m_cursors() {}
+
+uint32_t UnwindMacOSXFrameBackchain::DoGetFrameCount() {
+ if (m_cursors.empty()) {
+ ExecutionContext exe_ctx(m_thread.shared_from_this());
+ Target *target = exe_ctx.GetTargetPtr();
+ if (target) {
+ const ArchSpec &target_arch = target->GetArchitecture();
+ // Frame zero should always be supplied by the thread...
+ exe_ctx.SetFrameSP(m_thread.GetStackFrameAtIndex(0));
+
+ if (target_arch.GetAddressByteSize() == 8)
+ GetStackFrameData_x86_64(exe_ctx);
+ else
+ GetStackFrameData_i386(exe_ctx);
}
- return m_cursors.size();
+ }
+ return m_cursors.size();
}
-bool
-UnwindMacOSXFrameBackchain::DoGetFrameInfoAtIndex (uint32_t idx, addr_t& cfa, addr_t& pc)
-{
- const uint32_t frame_count = GetFrameCount();
- if (idx < frame_count)
- {
- if (m_cursors[idx].pc == LLDB_INVALID_ADDRESS)
- return false;
- if (m_cursors[idx].fp == LLDB_INVALID_ADDRESS)
- return false;
-
- pc = m_cursors[idx].pc;
- cfa = m_cursors[idx].fp;
-
- return true;
- }
- return false;
+bool UnwindMacOSXFrameBackchain::DoGetFrameInfoAtIndex(uint32_t idx,
+ addr_t &cfa,
+ addr_t &pc) {
+ const uint32_t frame_count = GetFrameCount();
+ if (idx < frame_count) {
+ if (m_cursors[idx].pc == LLDB_INVALID_ADDRESS)
+ return false;
+ if (m_cursors[idx].fp == LLDB_INVALID_ADDRESS)
+ return false;
+
+ pc = m_cursors[idx].pc;
+ cfa = m_cursors[idx].fp;
+
+ return true;
+ }
+ return false;
}
-
+
lldb::RegisterContextSP
-UnwindMacOSXFrameBackchain::DoCreateRegisterContextForFrame (StackFrame *frame)
-{
- lldb::RegisterContextSP reg_ctx_sp;
- uint32_t concrete_idx = frame->GetConcreteFrameIndex ();
- const uint32_t frame_count = GetFrameCount();
- if (concrete_idx < frame_count)
- reg_ctx_sp.reset (new RegisterContextMacOSXFrameBackchain (m_thread, concrete_idx, m_cursors[concrete_idx]));
- return reg_ctx_sp;
+UnwindMacOSXFrameBackchain::DoCreateRegisterContextForFrame(StackFrame *frame) {
+ lldb::RegisterContextSP reg_ctx_sp;
+ uint32_t concrete_idx = frame->GetConcreteFrameIndex();
+ const uint32_t frame_count = GetFrameCount();
+ if (concrete_idx < frame_count)
+ reg_ctx_sp.reset(new RegisterContextMacOSXFrameBackchain(
+ m_thread, concrete_idx, m_cursors[concrete_idx]));
+ return reg_ctx_sp;
}
-size_t
-UnwindMacOSXFrameBackchain::GetStackFrameData_i386 (const ExecutionContext &exe_ctx)
-{
- m_cursors.clear();
-
- StackFrame *first_frame = exe_ctx.GetFramePtr();
-
- Process *process = exe_ctx.GetProcessPtr();
- if (process == NULL)
- return 0;
-
- std::pair<lldb::addr_t, lldb::addr_t> fp_pc_pair;
-
- struct Frame_i386
- {
- uint32_t fp;
- uint32_t pc;
- };
-
- RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
- assert (reg_ctx);
-
- Cursor cursor;
- cursor.pc = reg_ctx->GetPC (LLDB_INVALID_ADDRESS);
- cursor.fp = reg_ctx->GetFP (0);
-
- Frame_i386 frame = { static_cast<uint32_t>(cursor.fp), static_cast<uint32_t>(cursor.pc) };
-
- m_cursors.push_back(cursor);
-
- const size_t k_frame_size = sizeof(frame);
- Error error;
- while (frame.fp != 0 && frame.pc != 0 && ((frame.fp & 7) == 0))
- {
- // Read both the FP and PC (8 bytes)
- if (process->ReadMemory (frame.fp, &frame.fp, k_frame_size, error) != k_frame_size)
- break;
- if (frame.pc >= 0x1000)
- {
- cursor.pc = frame.pc;
- cursor.fp = frame.fp;
- m_cursors.push_back (cursor);
- }
+size_t UnwindMacOSXFrameBackchain::GetStackFrameData_i386(
+ const ExecutionContext &exe_ctx) {
+ m_cursors.clear();
+
+ StackFrame *first_frame = exe_ctx.GetFramePtr();
+
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process == NULL)
+ return 0;
+
+ std::pair<lldb::addr_t, lldb::addr_t> fp_pc_pair;
+
+ struct Frame_i386 {
+ uint32_t fp;
+ uint32_t pc;
+ };
+
+ RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
+ assert(reg_ctx);
+
+ Cursor cursor;
+ cursor.pc = reg_ctx->GetPC(LLDB_INVALID_ADDRESS);
+ cursor.fp = reg_ctx->GetFP(0);
+
+ Frame_i386 frame = {static_cast<uint32_t>(cursor.fp),
+ static_cast<uint32_t>(cursor.pc)};
+
+ m_cursors.push_back(cursor);
+
+ const size_t k_frame_size = sizeof(frame);
+ Error error;
+ while (frame.fp != 0 && frame.pc != 0 && ((frame.fp & 7) == 0)) {
+ // Read both the FP and PC (8 bytes)
+ if (process->ReadMemory(frame.fp, &frame.fp, k_frame_size, error) !=
+ k_frame_size)
+ break;
+ if (frame.pc >= 0x1000) {
+ cursor.pc = frame.pc;
+ cursor.fp = frame.fp;
+ m_cursors.push_back(cursor);
}
- if (!m_cursors.empty())
- {
- lldb::addr_t first_frame_pc = m_cursors.front().pc;
- if (first_frame_pc != LLDB_INVALID_ADDRESS)
- {
- const uint32_t resolve_scope = eSymbolContextModule |
- eSymbolContextCompUnit |
- eSymbolContextFunction |
- eSymbolContextSymbol;
-
- SymbolContext first_frame_sc (first_frame->GetSymbolContext(resolve_scope));
- const AddressRange *addr_range_ptr = NULL;
- AddressRange range;
- if (first_frame_sc.function)
- addr_range_ptr = &first_frame_sc.function->GetAddressRange();
- else if (first_frame_sc.symbol)
- {
- range.GetBaseAddress() = first_frame_sc.symbol->GetAddress();
- range.SetByteSize (first_frame_sc.symbol->GetByteSize());
- addr_range_ptr = &range;
- }
-
- if (addr_range_ptr)
- {
- if (first_frame->GetFrameCodeAddress() == addr_range_ptr->GetBaseAddress())
- {
- // We are at the first instruction, so we can recover the
- // previous PC by dereferencing the SP
- lldb::addr_t first_frame_sp = reg_ctx->GetSP (0);
- // Read the real second frame return address into frame.pc
- if (first_frame_sp && process->ReadMemory (first_frame_sp, &frame.pc, sizeof(frame.pc), error) == sizeof(frame.pc))
- {
- cursor.fp = m_cursors.front().fp;
- cursor.pc = frame.pc; // Set the new second frame PC
-
- // Insert the second frame
- m_cursors.insert(m_cursors.begin()+1, cursor);
-
- m_cursors.front().fp = first_frame_sp;
- }
- }
- }
+ }
+ if (!m_cursors.empty()) {
+ lldb::addr_t first_frame_pc = m_cursors.front().pc;
+ if (first_frame_pc != LLDB_INVALID_ADDRESS) {
+ const uint32_t resolve_scope =
+ eSymbolContextModule | eSymbolContextCompUnit |
+ eSymbolContextFunction | eSymbolContextSymbol;
+
+ SymbolContext first_frame_sc(
+ first_frame->GetSymbolContext(resolve_scope));
+ const AddressRange *addr_range_ptr = NULL;
+ AddressRange range;
+ if (first_frame_sc.function)
+ addr_range_ptr = &first_frame_sc.function->GetAddressRange();
+ else if (first_frame_sc.symbol) {
+ range.GetBaseAddress() = first_frame_sc.symbol->GetAddress();
+ range.SetByteSize(first_frame_sc.symbol->GetByteSize());
+ addr_range_ptr = &range;
+ }
+
+ if (addr_range_ptr) {
+ if (first_frame->GetFrameCodeAddress() ==
+ addr_range_ptr->GetBaseAddress()) {
+ // We are at the first instruction, so we can recover the
+ // previous PC by dereferencing the SP
+ lldb::addr_t first_frame_sp = reg_ctx->GetSP(0);
+ // Read the real second frame return address into frame.pc
+ if (first_frame_sp &&
+ process->ReadMemory(first_frame_sp, &frame.pc, sizeof(frame.pc),
+ error) == sizeof(frame.pc)) {
+ cursor.fp = m_cursors.front().fp;
+ cursor.pc = frame.pc; // Set the new second frame PC
+
+ // Insert the second frame
+ m_cursors.insert(m_cursors.begin() + 1, cursor);
+
+ m_cursors.front().fp = first_frame_sp;
+ }
}
+ }
}
-// uint32_t i=0;
-// printf(" PC FP\n");
-// printf(" ------------------ ------------------ \n");
-// for (i=0; i<m_cursors.size(); ++i)
-// {
-// printf("[%3u] 0x%16.16" PRIx64 " 0x%16.16" PRIx64 "\n", i, m_cursors[i].pc, m_cursors[i].fp);
-// }
- return m_cursors.size();
+ }
+ // uint32_t i=0;
+ // printf(" PC FP\n");
+ // printf(" ------------------ ------------------ \n");
+ // for (i=0; i<m_cursors.size(); ++i)
+ // {
+ // printf("[%3u] 0x%16.16" PRIx64 " 0x%16.16" PRIx64 "\n", i,
+ // m_cursors[i].pc, m_cursors[i].fp);
+ // }
+ return m_cursors.size();
}
+size_t UnwindMacOSXFrameBackchain::GetStackFrameData_x86_64(
+ const ExecutionContext &exe_ctx) {
+ m_cursors.clear();
-size_t
-UnwindMacOSXFrameBackchain::GetStackFrameData_x86_64 (const ExecutionContext &exe_ctx)
-{
- m_cursors.clear();
-
- Process *process = exe_ctx.GetProcessPtr();
- if (process == NULL)
- return 0;
-
- StackFrame *first_frame = exe_ctx.GetFramePtr();
-
- std::pair<lldb::addr_t, lldb::addr_t> fp_pc_pair;
-
- struct Frame_x86_64
- {
- uint64_t fp;
- uint64_t pc;
- };
-
- RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
- assert (reg_ctx);
-
- Cursor cursor;
- cursor.pc = reg_ctx->GetPC (LLDB_INVALID_ADDRESS);
- cursor.fp = reg_ctx->GetFP (0);
-
- Frame_x86_64 frame = { cursor.fp, cursor.pc };
-
- m_cursors.push_back(cursor);
- Error error;
- const size_t k_frame_size = sizeof(frame);
- while (frame.fp != 0 && frame.pc != 0 && ((frame.fp & 7) == 0))
- {
- // Read both the FP and PC (16 bytes)
- if (process->ReadMemory (frame.fp, &frame.fp, k_frame_size, error) != k_frame_size)
- break;
-
- if (frame.pc >= 0x1000)
- {
- cursor.pc = frame.pc;
- cursor.fp = frame.fp;
- m_cursors.push_back (cursor);
- }
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process == NULL)
+ return 0;
+
+ StackFrame *first_frame = exe_ctx.GetFramePtr();
+
+ std::pair<lldb::addr_t, lldb::addr_t> fp_pc_pair;
+
+ struct Frame_x86_64 {
+ uint64_t fp;
+ uint64_t pc;
+ };
+
+ RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
+ assert(reg_ctx);
+
+ Cursor cursor;
+ cursor.pc = reg_ctx->GetPC(LLDB_INVALID_ADDRESS);
+ cursor.fp = reg_ctx->GetFP(0);
+
+ Frame_x86_64 frame = {cursor.fp, cursor.pc};
+
+ m_cursors.push_back(cursor);
+ Error error;
+ const size_t k_frame_size = sizeof(frame);
+ while (frame.fp != 0 && frame.pc != 0 && ((frame.fp & 7) == 0)) {
+ // Read both the FP and PC (16 bytes)
+ if (process->ReadMemory(frame.fp, &frame.fp, k_frame_size, error) !=
+ k_frame_size)
+ break;
+
+ if (frame.pc >= 0x1000) {
+ cursor.pc = frame.pc;
+ cursor.fp = frame.fp;
+ m_cursors.push_back(cursor);
}
- if (!m_cursors.empty())
- {
- lldb::addr_t first_frame_pc = m_cursors.front().pc;
- if (first_frame_pc != LLDB_INVALID_ADDRESS)
- {
- const uint32_t resolve_scope = eSymbolContextModule |
- eSymbolContextCompUnit |
- eSymbolContextFunction |
- eSymbolContextSymbol;
-
- SymbolContext first_frame_sc(first_frame->GetSymbolContext(resolve_scope));
- const AddressRange *addr_range_ptr = NULL;
- AddressRange range;
- if (first_frame_sc.function)
- addr_range_ptr = &first_frame_sc.function->GetAddressRange();
- else if (first_frame_sc.symbol)
- {
- range.GetBaseAddress() = first_frame_sc.symbol->GetAddress();
- range.SetByteSize (first_frame_sc.symbol->GetByteSize());
- addr_range_ptr = &range;
- }
-
- if (addr_range_ptr)
- {
- if (first_frame->GetFrameCodeAddress() == addr_range_ptr->GetBaseAddress())
- {
- // We are at the first instruction, so we can recover the
- // previous PC by dereferencing the SP
- lldb::addr_t first_frame_sp = reg_ctx->GetSP (0);
- // Read the real second frame return address into frame.pc
- if (process->ReadMemory (first_frame_sp, &frame.pc, sizeof(frame.pc), error) == sizeof(frame.pc))
- {
- cursor.fp = m_cursors.front().fp;
- cursor.pc = frame.pc; // Set the new second frame PC
-
- // Insert the second frame
- m_cursors.insert(m_cursors.begin()+1, cursor);
-
- m_cursors.front().fp = first_frame_sp;
- }
- }
- }
+ }
+ if (!m_cursors.empty()) {
+ lldb::addr_t first_frame_pc = m_cursors.front().pc;
+ if (first_frame_pc != LLDB_INVALID_ADDRESS) {
+ const uint32_t resolve_scope =
+ eSymbolContextModule | eSymbolContextCompUnit |
+ eSymbolContextFunction | eSymbolContextSymbol;
+
+ SymbolContext first_frame_sc(
+ first_frame->GetSymbolContext(resolve_scope));
+ const AddressRange *addr_range_ptr = NULL;
+ AddressRange range;
+ if (first_frame_sc.function)
+ addr_range_ptr = &first_frame_sc.function->GetAddressRange();
+ else if (first_frame_sc.symbol) {
+ range.GetBaseAddress() = first_frame_sc.symbol->GetAddress();
+ range.SetByteSize(first_frame_sc.symbol->GetByteSize());
+ addr_range_ptr = &range;
+ }
+
+ if (addr_range_ptr) {
+ if (first_frame->GetFrameCodeAddress() ==
+ addr_range_ptr->GetBaseAddress()) {
+ // We are at the first instruction, so we can recover the
+ // previous PC by dereferencing the SP
+ lldb::addr_t first_frame_sp = reg_ctx->GetSP(0);
+ // Read the real second frame return address into frame.pc
+ if (process->ReadMemory(first_frame_sp, &frame.pc, sizeof(frame.pc),
+ error) == sizeof(frame.pc)) {
+ cursor.fp = m_cursors.front().fp;
+ cursor.pc = frame.pc; // Set the new second frame PC
+
+ // Insert the second frame
+ m_cursors.insert(m_cursors.begin() + 1, cursor);
+
+ m_cursors.front().fp = first_frame_sp;
+ }
}
+ }
}
- return m_cursors.size();
+ }
+ return m_cursors.size();
}
-
diff --git a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h
index f195514ed1ba..328117a306ef 100644
--- a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h
+++ b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h
@@ -16,55 +16,45 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Target/Unwind.h"
+#include "lldb/lldb-private.h"
-class UnwindMacOSXFrameBackchain : public lldb_private::Unwind
-{
-public:
- UnwindMacOSXFrameBackchain (lldb_private::Thread &thread);
+class UnwindMacOSXFrameBackchain : public lldb_private::Unwind {
+public:
+ UnwindMacOSXFrameBackchain(lldb_private::Thread &thread);
- ~UnwindMacOSXFrameBackchain() override = default;
+ ~UnwindMacOSXFrameBackchain() override = default;
protected:
- void
- DoClear() override
- {
- m_cursors.clear();
- }
-
- uint32_t
- DoGetFrameCount() override;
-
- bool
- DoGetFrameInfoAtIndex(uint32_t frame_idx,
- lldb::addr_t& cfa,
- lldb::addr_t& pc) override;
-
- lldb::RegisterContextSP
- DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
-
- friend class RegisterContextMacOSXFrameBackchain;
-
- struct Cursor
- {
- lldb::addr_t pc; // Program counter
- lldb::addr_t fp; // Frame pointer for us with backchain
- };
+ void DoClear() override { m_cursors.clear(); }
+
+ uint32_t DoGetFrameCount() override;
+
+ bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
+ lldb::addr_t &pc) override;
+
+ lldb::RegisterContextSP
+ DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
+
+ friend class RegisterContextMacOSXFrameBackchain;
+
+ struct Cursor {
+ lldb::addr_t pc; // Program counter
+ lldb::addr_t fp; // Frame pointer for us with backchain
+ };
private:
- std::vector<Cursor> m_cursors;
+ std::vector<Cursor> m_cursors;
- size_t
- GetStackFrameData_i386 (const lldb_private::ExecutionContext &exe_ctx);
+ size_t GetStackFrameData_i386(const lldb_private::ExecutionContext &exe_ctx);
- size_t
- GetStackFrameData_x86_64 (const lldb_private::ExecutionContext &exe_ctx);
+ size_t
+ GetStackFrameData_x86_64(const lldb_private::ExecutionContext &exe_ctx);
- //------------------------------------------------------------------
- // For UnwindMacOSXFrameBackchain only
- //------------------------------------------------------------------
- DISALLOW_COPY_AND_ASSIGN (UnwindMacOSXFrameBackchain);
+ //------------------------------------------------------------------
+ // For UnwindMacOSXFrameBackchain only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN(UnwindMacOSXFrameBackchain);
};
#endif // lldb_UnwindMacOSXFrameBackchain_h_
diff --git a/source/Plugins/Process/Utility/lldb-arm-register-enums.h b/source/Plugins/Process/Utility/lldb-arm-register-enums.h
index 4d82c10a78ea..49473bb885f2 100644
--- a/source/Plugins/Process/Utility/lldb-arm-register-enums.h
+++ b/source/Plugins/Process/Utility/lldb-arm-register-enums.h
@@ -10,192 +10,193 @@
#ifndef lldb_arm_register_enums_h
#define lldb_arm_register_enums_h
-namespace lldb_private
-{
- // LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
+namespace lldb_private {
+// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
- //---------------------------------------------------------------------------
- // Internal codes for all ARM registers.
- //---------------------------------------------------------------------------
- enum
- {
- k_first_gpr_arm = 0,
- gpr_r0_arm = k_first_gpr_arm,
- gpr_r1_arm,
- gpr_r2_arm,
- gpr_r3_arm,
- gpr_r4_arm,
- gpr_r5_arm,
- gpr_r6_arm,
- gpr_r7_arm,
- gpr_r8_arm,
- gpr_r9_arm,
- gpr_r10_arm,
- gpr_r11_arm,
- gpr_r12_arm,
- gpr_r13_arm, gpr_sp_arm = gpr_r13_arm,
- gpr_r14_arm, gpr_lr_arm = gpr_r14_arm,
- gpr_r15_arm, gpr_pc_arm = gpr_r15_arm,
- gpr_cpsr_arm,
+//---------------------------------------------------------------------------
+// Internal codes for all ARM registers.
+//---------------------------------------------------------------------------
+enum {
+ k_first_gpr_arm = 0,
+ gpr_r0_arm = k_first_gpr_arm,
+ gpr_r1_arm,
+ gpr_r2_arm,
+ gpr_r3_arm,
+ gpr_r4_arm,
+ gpr_r5_arm,
+ gpr_r6_arm,
+ gpr_r7_arm,
+ gpr_r8_arm,
+ gpr_r9_arm,
+ gpr_r10_arm,
+ gpr_r11_arm,
+ gpr_r12_arm,
+ gpr_r13_arm,
+ gpr_sp_arm = gpr_r13_arm,
+ gpr_r14_arm,
+ gpr_lr_arm = gpr_r14_arm,
+ gpr_r15_arm,
+ gpr_pc_arm = gpr_r15_arm,
+ gpr_cpsr_arm,
- k_last_gpr_arm = gpr_cpsr_arm,
+ k_last_gpr_arm = gpr_cpsr_arm,
- k_first_fpr_arm,
- fpu_s0_arm = k_first_fpr_arm,
- fpu_s1_arm,
- fpu_s2_arm,
- fpu_s3_arm,
- fpu_s4_arm,
- fpu_s5_arm,
- fpu_s6_arm,
- fpu_s7_arm,
- fpu_s8_arm,
- fpu_s9_arm,
- fpu_s10_arm,
- fpu_s11_arm,
- fpu_s12_arm,
- fpu_s13_arm,
- fpu_s14_arm,
- fpu_s15_arm,
- fpu_s16_arm,
- fpu_s17_arm,
- fpu_s18_arm,
- fpu_s19_arm,
- fpu_s20_arm,
- fpu_s21_arm,
- fpu_s22_arm,
- fpu_s23_arm,
- fpu_s24_arm,
- fpu_s25_arm,
- fpu_s26_arm,
- fpu_s27_arm,
- fpu_s28_arm,
- fpu_s29_arm,
- fpu_s30_arm,
- fpu_s31_arm,
- fpu_fpscr_arm,
- fpu_d0_arm,
- fpu_d1_arm,
- fpu_d2_arm,
- fpu_d3_arm,
- fpu_d4_arm,
- fpu_d5_arm,
- fpu_d6_arm,
- fpu_d7_arm,
- fpu_d8_arm,
- fpu_d9_arm,
- fpu_d10_arm,
- fpu_d11_arm,
- fpu_d12_arm,
- fpu_d13_arm,
- fpu_d14_arm,
- fpu_d15_arm,
- fpu_d16_arm,
- fpu_d17_arm,
- fpu_d18_arm,
- fpu_d19_arm,
- fpu_d20_arm,
- fpu_d21_arm,
- fpu_d22_arm,
- fpu_d23_arm,
- fpu_d24_arm,
- fpu_d25_arm,
- fpu_d26_arm,
- fpu_d27_arm,
- fpu_d28_arm,
- fpu_d29_arm,
- fpu_d30_arm,
- fpu_d31_arm,
- fpu_q0_arm,
- fpu_q1_arm,
- fpu_q2_arm,
- fpu_q3_arm,
- fpu_q4_arm,
- fpu_q5_arm,
- fpu_q6_arm,
- fpu_q7_arm,
- fpu_q8_arm,
- fpu_q9_arm,
- fpu_q10_arm,
- fpu_q11_arm,
- fpu_q12_arm,
- fpu_q13_arm,
- fpu_q14_arm,
- fpu_q15_arm,
- k_last_fpr_arm = fpu_q15_arm,
- exc_exception_arm,
- exc_fsr_arm,
- exc_far_arm,
+ k_first_fpr_arm,
+ fpu_s0_arm = k_first_fpr_arm,
+ fpu_s1_arm,
+ fpu_s2_arm,
+ fpu_s3_arm,
+ fpu_s4_arm,
+ fpu_s5_arm,
+ fpu_s6_arm,
+ fpu_s7_arm,
+ fpu_s8_arm,
+ fpu_s9_arm,
+ fpu_s10_arm,
+ fpu_s11_arm,
+ fpu_s12_arm,
+ fpu_s13_arm,
+ fpu_s14_arm,
+ fpu_s15_arm,
+ fpu_s16_arm,
+ fpu_s17_arm,
+ fpu_s18_arm,
+ fpu_s19_arm,
+ fpu_s20_arm,
+ fpu_s21_arm,
+ fpu_s22_arm,
+ fpu_s23_arm,
+ fpu_s24_arm,
+ fpu_s25_arm,
+ fpu_s26_arm,
+ fpu_s27_arm,
+ fpu_s28_arm,
+ fpu_s29_arm,
+ fpu_s30_arm,
+ fpu_s31_arm,
+ fpu_fpscr_arm,
+ fpu_d0_arm,
+ fpu_d1_arm,
+ fpu_d2_arm,
+ fpu_d3_arm,
+ fpu_d4_arm,
+ fpu_d5_arm,
+ fpu_d6_arm,
+ fpu_d7_arm,
+ fpu_d8_arm,
+ fpu_d9_arm,
+ fpu_d10_arm,
+ fpu_d11_arm,
+ fpu_d12_arm,
+ fpu_d13_arm,
+ fpu_d14_arm,
+ fpu_d15_arm,
+ fpu_d16_arm,
+ fpu_d17_arm,
+ fpu_d18_arm,
+ fpu_d19_arm,
+ fpu_d20_arm,
+ fpu_d21_arm,
+ fpu_d22_arm,
+ fpu_d23_arm,
+ fpu_d24_arm,
+ fpu_d25_arm,
+ fpu_d26_arm,
+ fpu_d27_arm,
+ fpu_d28_arm,
+ fpu_d29_arm,
+ fpu_d30_arm,
+ fpu_d31_arm,
+ fpu_q0_arm,
+ fpu_q1_arm,
+ fpu_q2_arm,
+ fpu_q3_arm,
+ fpu_q4_arm,
+ fpu_q5_arm,
+ fpu_q6_arm,
+ fpu_q7_arm,
+ fpu_q8_arm,
+ fpu_q9_arm,
+ fpu_q10_arm,
+ fpu_q11_arm,
+ fpu_q12_arm,
+ fpu_q13_arm,
+ fpu_q14_arm,
+ fpu_q15_arm,
+ k_last_fpr_arm = fpu_q15_arm,
+ exc_exception_arm,
+ exc_fsr_arm,
+ exc_far_arm,
- dbg_bvr0_arm,
- dbg_bvr1_arm,
- dbg_bvr2_arm,
- dbg_bvr3_arm,
- dbg_bvr4_arm,
- dbg_bvr5_arm,
- dbg_bvr6_arm,
- dbg_bvr7_arm,
- dbg_bvr8_arm,
- dbg_bvr9_arm,
- dbg_bvr10_arm,
- dbg_bvr11_arm,
- dbg_bvr12_arm,
- dbg_bvr13_arm,
- dbg_bvr14_arm,
- dbg_bvr15_arm,
- dbg_bcr0_arm,
- dbg_bcr1_arm,
- dbg_bcr2_arm,
- dbg_bcr3_arm,
- dbg_bcr4_arm,
- dbg_bcr5_arm,
- dbg_bcr6_arm,
- dbg_bcr7_arm,
- dbg_bcr8_arm,
- dbg_bcr9_arm,
- dbg_bcr10_arm,
- dbg_bcr11_arm,
- dbg_bcr12_arm,
- dbg_bcr13_arm,
- dbg_bcr14_arm,
- dbg_bcr15_arm,
- dbg_wvr0_arm,
- dbg_wvr1_arm,
- dbg_wvr2_arm,
- dbg_wvr3_arm,
- dbg_wvr4_arm,
- dbg_wvr5_arm,
- dbg_wvr6_arm,
- dbg_wvr7_arm,
- dbg_wvr8_arm,
- dbg_wvr9_arm,
- dbg_wvr10_arm,
- dbg_wvr11_arm,
- dbg_wvr12_arm,
- dbg_wvr13_arm,
- dbg_wvr14_arm,
- dbg_wvr15_arm,
- dbg_wcr0_arm,
- dbg_wcr1_arm,
- dbg_wcr2_arm,
- dbg_wcr3_arm,
- dbg_wcr4_arm,
- dbg_wcr5_arm,
- dbg_wcr6_arm,
- dbg_wcr7_arm,
- dbg_wcr8_arm,
- dbg_wcr9_arm,
- dbg_wcr10_arm,
- dbg_wcr11_arm,
- dbg_wcr12_arm,
- dbg_wcr13_arm,
- dbg_wcr14_arm,
- dbg_wcr15_arm,
+ dbg_bvr0_arm,
+ dbg_bvr1_arm,
+ dbg_bvr2_arm,
+ dbg_bvr3_arm,
+ dbg_bvr4_arm,
+ dbg_bvr5_arm,
+ dbg_bvr6_arm,
+ dbg_bvr7_arm,
+ dbg_bvr8_arm,
+ dbg_bvr9_arm,
+ dbg_bvr10_arm,
+ dbg_bvr11_arm,
+ dbg_bvr12_arm,
+ dbg_bvr13_arm,
+ dbg_bvr14_arm,
+ dbg_bvr15_arm,
+ dbg_bcr0_arm,
+ dbg_bcr1_arm,
+ dbg_bcr2_arm,
+ dbg_bcr3_arm,
+ dbg_bcr4_arm,
+ dbg_bcr5_arm,
+ dbg_bcr6_arm,
+ dbg_bcr7_arm,
+ dbg_bcr8_arm,
+ dbg_bcr9_arm,
+ dbg_bcr10_arm,
+ dbg_bcr11_arm,
+ dbg_bcr12_arm,
+ dbg_bcr13_arm,
+ dbg_bcr14_arm,
+ dbg_bcr15_arm,
+ dbg_wvr0_arm,
+ dbg_wvr1_arm,
+ dbg_wvr2_arm,
+ dbg_wvr3_arm,
+ dbg_wvr4_arm,
+ dbg_wvr5_arm,
+ dbg_wvr6_arm,
+ dbg_wvr7_arm,
+ dbg_wvr8_arm,
+ dbg_wvr9_arm,
+ dbg_wvr10_arm,
+ dbg_wvr11_arm,
+ dbg_wvr12_arm,
+ dbg_wvr13_arm,
+ dbg_wvr14_arm,
+ dbg_wvr15_arm,
+ dbg_wcr0_arm,
+ dbg_wcr1_arm,
+ dbg_wcr2_arm,
+ dbg_wcr3_arm,
+ dbg_wcr4_arm,
+ dbg_wcr5_arm,
+ dbg_wcr6_arm,
+ dbg_wcr7_arm,
+ dbg_wcr8_arm,
+ dbg_wcr9_arm,
+ dbg_wcr10_arm,
+ dbg_wcr11_arm,
+ dbg_wcr12_arm,
+ dbg_wcr13_arm,
+ dbg_wcr14_arm,
+ dbg_wcr15_arm,
- k_num_registers_arm,
- k_num_gpr_registers_arm = k_last_gpr_arm - k_first_gpr_arm + 1,
- k_num_fpr_registers_arm = k_last_fpr_arm - k_first_fpr_arm + 1
- };
+ k_num_registers_arm,
+ k_num_gpr_registers_arm = k_last_gpr_arm - k_first_gpr_arm + 1,
+ k_num_fpr_registers_arm = k_last_fpr_arm - k_first_fpr_arm + 1
+};
}
#endif // #ifndef lldb_arm64_register_enums_h
diff --git a/source/Plugins/Process/Utility/lldb-arm64-register-enums.h b/source/Plugins/Process/Utility/lldb-arm64-register-enums.h
index a0c0db0f2786..7181ce448195 100644
--- a/source/Plugins/Process/Utility/lldb-arm64-register-enums.h
+++ b/source/Plugins/Process/Utility/lldb-arm64-register-enums.h
@@ -10,163 +10,258 @@
#ifndef lldb_arm64_register_enums_h
#define lldb_arm64_register_enums_h
-namespace lldb_private
-{
- // LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
+namespace lldb_private {
+// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
- //---------------------------------------------------------------------------
- // Internal codes for all ARM64 registers.
- //---------------------------------------------------------------------------
- enum
- {
- k_first_gpr_arm64,
- gpr_x0_arm64 = k_first_gpr_arm64,
- gpr_x1_arm64,
- gpr_x2_arm64,
- gpr_x3_arm64,
- gpr_x4_arm64,
- gpr_x5_arm64,
- gpr_x6_arm64,
- gpr_x7_arm64,
- gpr_x8_arm64,
- gpr_x9_arm64,
- gpr_x10_arm64,
- gpr_x11_arm64,
- gpr_x12_arm64,
- gpr_x13_arm64,
- gpr_x14_arm64,
- gpr_x15_arm64,
- gpr_x16_arm64,
- gpr_x17_arm64,
- gpr_x18_arm64,
- gpr_x19_arm64,
- gpr_x20_arm64,
- gpr_x21_arm64,
- gpr_x22_arm64,
- gpr_x23_arm64,
- gpr_x24_arm64,
- gpr_x25_arm64,
- gpr_x26_arm64,
- gpr_x27_arm64,
- gpr_x28_arm64,
- gpr_fp_arm64,
- gpr_lr_arm64,
- gpr_sp_arm64,
- gpr_pc_arm64,
- gpr_cpsr_arm64,
+//---------------------------------------------------------------------------
+// Internal codes for all ARM64 registers.
+//---------------------------------------------------------------------------
+enum {
+ k_first_gpr_arm64,
+ gpr_x0_arm64 = k_first_gpr_arm64,
+ gpr_x1_arm64,
+ gpr_x2_arm64,
+ gpr_x3_arm64,
+ gpr_x4_arm64,
+ gpr_x5_arm64,
+ gpr_x6_arm64,
+ gpr_x7_arm64,
+ gpr_x8_arm64,
+ gpr_x9_arm64,
+ gpr_x10_arm64,
+ gpr_x11_arm64,
+ gpr_x12_arm64,
+ gpr_x13_arm64,
+ gpr_x14_arm64,
+ gpr_x15_arm64,
+ gpr_x16_arm64,
+ gpr_x17_arm64,
+ gpr_x18_arm64,
+ gpr_x19_arm64,
+ gpr_x20_arm64,
+ gpr_x21_arm64,
+ gpr_x22_arm64,
+ gpr_x23_arm64,
+ gpr_x24_arm64,
+ gpr_x25_arm64,
+ gpr_x26_arm64,
+ gpr_x27_arm64,
+ gpr_x28_arm64,
+ gpr_fp_arm64,
+ gpr_lr_arm64,
+ gpr_sp_arm64,
+ gpr_pc_arm64,
+ gpr_cpsr_arm64,
- k_last_gpr_arm64 = gpr_cpsr_arm64,
+ gpr_w0_arm64,
+ gpr_w1_arm64,
+ gpr_w2_arm64,
+ gpr_w3_arm64,
+ gpr_w4_arm64,
+ gpr_w5_arm64,
+ gpr_w6_arm64,
+ gpr_w7_arm64,
+ gpr_w8_arm64,
+ gpr_w9_arm64,
+ gpr_w10_arm64,
+ gpr_w11_arm64,
+ gpr_w12_arm64,
+ gpr_w13_arm64,
+ gpr_w14_arm64,
+ gpr_w15_arm64,
+ gpr_w16_arm64,
+ gpr_w17_arm64,
+ gpr_w18_arm64,
+ gpr_w19_arm64,
+ gpr_w20_arm64,
+ gpr_w21_arm64,
+ gpr_w22_arm64,
+ gpr_w23_arm64,
+ gpr_w24_arm64,
+ gpr_w25_arm64,
+ gpr_w26_arm64,
+ gpr_w27_arm64,
+ gpr_w28_arm64,
- k_first_fpr_arm64,
- fpu_v0_arm64 = k_first_fpr_arm64,
- fpu_v1_arm64,
- fpu_v2_arm64,
- fpu_v3_arm64,
- fpu_v4_arm64,
- fpu_v5_arm64,
- fpu_v6_arm64,
- fpu_v7_arm64,
- fpu_v8_arm64,
- fpu_v9_arm64,
- fpu_v10_arm64,
- fpu_v11_arm64,
- fpu_v12_arm64,
- fpu_v13_arm64,
- fpu_v14_arm64,
- fpu_v15_arm64,
- fpu_v16_arm64,
- fpu_v17_arm64,
- fpu_v18_arm64,
- fpu_v19_arm64,
- fpu_v20_arm64,
- fpu_v21_arm64,
- fpu_v22_arm64,
- fpu_v23_arm64,
- fpu_v24_arm64,
- fpu_v25_arm64,
- fpu_v26_arm64,
- fpu_v27_arm64,
- fpu_v28_arm64,
- fpu_v29_arm64,
- fpu_v30_arm64,
- fpu_v31_arm64,
- fpu_fpsr_arm64,
- fpu_fpcr_arm64,
- k_last_fpr_arm64 = fpu_fpcr_arm64,
+ k_last_gpr_arm64 = gpr_w28_arm64,
- exc_far_arm64,
- exc_esr_arm64,
- exc_exception_arm64,
+ k_first_fpr_arm64,
+ fpu_v0_arm64 = k_first_fpr_arm64,
+ fpu_v1_arm64,
+ fpu_v2_arm64,
+ fpu_v3_arm64,
+ fpu_v4_arm64,
+ fpu_v5_arm64,
+ fpu_v6_arm64,
+ fpu_v7_arm64,
+ fpu_v8_arm64,
+ fpu_v9_arm64,
+ fpu_v10_arm64,
+ fpu_v11_arm64,
+ fpu_v12_arm64,
+ fpu_v13_arm64,
+ fpu_v14_arm64,
+ fpu_v15_arm64,
+ fpu_v16_arm64,
+ fpu_v17_arm64,
+ fpu_v18_arm64,
+ fpu_v19_arm64,
+ fpu_v20_arm64,
+ fpu_v21_arm64,
+ fpu_v22_arm64,
+ fpu_v23_arm64,
+ fpu_v24_arm64,
+ fpu_v25_arm64,
+ fpu_v26_arm64,
+ fpu_v27_arm64,
+ fpu_v28_arm64,
+ fpu_v29_arm64,
+ fpu_v30_arm64,
+ fpu_v31_arm64,
- dbg_bvr0_arm64,
- dbg_bvr1_arm64,
- dbg_bvr2_arm64,
- dbg_bvr3_arm64,
- dbg_bvr4_arm64,
- dbg_bvr5_arm64,
- dbg_bvr6_arm64,
- dbg_bvr7_arm64,
- dbg_bvr8_arm64,
- dbg_bvr9_arm64,
- dbg_bvr10_arm64,
- dbg_bvr11_arm64,
- dbg_bvr12_arm64,
- dbg_bvr13_arm64,
- dbg_bvr14_arm64,
- dbg_bvr15_arm64,
- dbg_bcr0_arm64,
- dbg_bcr1_arm64,
- dbg_bcr2_arm64,
- dbg_bcr3_arm64,
- dbg_bcr4_arm64,
- dbg_bcr5_arm64,
- dbg_bcr6_arm64,
- dbg_bcr7_arm64,
- dbg_bcr8_arm64,
- dbg_bcr9_arm64,
- dbg_bcr10_arm64,
- dbg_bcr11_arm64,
- dbg_bcr12_arm64,
- dbg_bcr13_arm64,
- dbg_bcr14_arm64,
- dbg_bcr15_arm64,
- dbg_wvr0_arm64,
- dbg_wvr1_arm64,
- dbg_wvr2_arm64,
- dbg_wvr3_arm64,
- dbg_wvr4_arm64,
- dbg_wvr5_arm64,
- dbg_wvr6_arm64,
- dbg_wvr7_arm64,
- dbg_wvr8_arm64,
- dbg_wvr9_arm64,
- dbg_wvr10_arm64,
- dbg_wvr11_arm64,
- dbg_wvr12_arm64,
- dbg_wvr13_arm64,
- dbg_wvr14_arm64,
- dbg_wvr15_arm64,
- dbg_wcr0_arm64,
- dbg_wcr1_arm64,
- dbg_wcr2_arm64,
- dbg_wcr3_arm64,
- dbg_wcr4_arm64,
- dbg_wcr5_arm64,
- dbg_wcr6_arm64,
- dbg_wcr7_arm64,
- dbg_wcr8_arm64,
- dbg_wcr9_arm64,
- dbg_wcr10_arm64,
- dbg_wcr11_arm64,
- dbg_wcr12_arm64,
- dbg_wcr13_arm64,
- dbg_wcr14_arm64,
- dbg_wcr15_arm64,
+ fpu_s0_arm64,
+ fpu_s1_arm64,
+ fpu_s2_arm64,
+ fpu_s3_arm64,
+ fpu_s4_arm64,
+ fpu_s5_arm64,
+ fpu_s6_arm64,
+ fpu_s7_arm64,
+ fpu_s8_arm64,
+ fpu_s9_arm64,
+ fpu_s10_arm64,
+ fpu_s11_arm64,
+ fpu_s12_arm64,
+ fpu_s13_arm64,
+ fpu_s14_arm64,
+ fpu_s15_arm64,
+ fpu_s16_arm64,
+ fpu_s17_arm64,
+ fpu_s18_arm64,
+ fpu_s19_arm64,
+ fpu_s20_arm64,
+ fpu_s21_arm64,
+ fpu_s22_arm64,
+ fpu_s23_arm64,
+ fpu_s24_arm64,
+ fpu_s25_arm64,
+ fpu_s26_arm64,
+ fpu_s27_arm64,
+ fpu_s28_arm64,
+ fpu_s29_arm64,
+ fpu_s30_arm64,
+ fpu_s31_arm64,
- k_num_registers_arm64,
- k_num_gpr_registers_arm64 = k_last_gpr_arm64 - k_first_gpr_arm64 + 1,
- k_num_fpr_registers_arm64 = k_last_fpr_arm64 - k_first_fpr_arm64 + 1
- };
+ fpu_d0_arm64,
+ fpu_d1_arm64,
+ fpu_d2_arm64,
+ fpu_d3_arm64,
+ fpu_d4_arm64,
+ fpu_d5_arm64,
+ fpu_d6_arm64,
+ fpu_d7_arm64,
+ fpu_d8_arm64,
+ fpu_d9_arm64,
+ fpu_d10_arm64,
+ fpu_d11_arm64,
+ fpu_d12_arm64,
+ fpu_d13_arm64,
+ fpu_d14_arm64,
+ fpu_d15_arm64,
+ fpu_d16_arm64,
+ fpu_d17_arm64,
+ fpu_d18_arm64,
+ fpu_d19_arm64,
+ fpu_d20_arm64,
+ fpu_d21_arm64,
+ fpu_d22_arm64,
+ fpu_d23_arm64,
+ fpu_d24_arm64,
+ fpu_d25_arm64,
+ fpu_d26_arm64,
+ fpu_d27_arm64,
+ fpu_d28_arm64,
+ fpu_d29_arm64,
+ fpu_d30_arm64,
+ fpu_d31_arm64,
+
+ fpu_fpsr_arm64,
+ fpu_fpcr_arm64,
+ k_last_fpr_arm64 = fpu_fpcr_arm64,
+
+ exc_far_arm64,
+ exc_esr_arm64,
+ exc_exception_arm64,
+
+ dbg_bvr0_arm64,
+ dbg_bvr1_arm64,
+ dbg_bvr2_arm64,
+ dbg_bvr3_arm64,
+ dbg_bvr4_arm64,
+ dbg_bvr5_arm64,
+ dbg_bvr6_arm64,
+ dbg_bvr7_arm64,
+ dbg_bvr8_arm64,
+ dbg_bvr9_arm64,
+ dbg_bvr10_arm64,
+ dbg_bvr11_arm64,
+ dbg_bvr12_arm64,
+ dbg_bvr13_arm64,
+ dbg_bvr14_arm64,
+ dbg_bvr15_arm64,
+ dbg_bcr0_arm64,
+ dbg_bcr1_arm64,
+ dbg_bcr2_arm64,
+ dbg_bcr3_arm64,
+ dbg_bcr4_arm64,
+ dbg_bcr5_arm64,
+ dbg_bcr6_arm64,
+ dbg_bcr7_arm64,
+ dbg_bcr8_arm64,
+ dbg_bcr9_arm64,
+ dbg_bcr10_arm64,
+ dbg_bcr11_arm64,
+ dbg_bcr12_arm64,
+ dbg_bcr13_arm64,
+ dbg_bcr14_arm64,
+ dbg_bcr15_arm64,
+ dbg_wvr0_arm64,
+ dbg_wvr1_arm64,
+ dbg_wvr2_arm64,
+ dbg_wvr3_arm64,
+ dbg_wvr4_arm64,
+ dbg_wvr5_arm64,
+ dbg_wvr6_arm64,
+ dbg_wvr7_arm64,
+ dbg_wvr8_arm64,
+ dbg_wvr9_arm64,
+ dbg_wvr10_arm64,
+ dbg_wvr11_arm64,
+ dbg_wvr12_arm64,
+ dbg_wvr13_arm64,
+ dbg_wvr14_arm64,
+ dbg_wvr15_arm64,
+ dbg_wcr0_arm64,
+ dbg_wcr1_arm64,
+ dbg_wcr2_arm64,
+ dbg_wcr3_arm64,
+ dbg_wcr4_arm64,
+ dbg_wcr5_arm64,
+ dbg_wcr6_arm64,
+ dbg_wcr7_arm64,
+ dbg_wcr8_arm64,
+ dbg_wcr9_arm64,
+ dbg_wcr10_arm64,
+ dbg_wcr11_arm64,
+ dbg_wcr12_arm64,
+ dbg_wcr13_arm64,
+ dbg_wcr14_arm64,
+ dbg_wcr15_arm64,
+
+ k_num_registers_arm64,
+ k_num_gpr_registers_arm64 = k_last_gpr_arm64 - k_first_gpr_arm64 + 1,
+ k_num_fpr_registers_arm64 = k_last_fpr_arm64 - k_first_fpr_arm64 + 1
+};
}
#endif // #ifndef lldb_arm64_register_enums_h
diff --git a/source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h b/source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h
index 69dc9efac32b..61929365b736 100644
--- a/source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h
+++ b/source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h
@@ -1,4 +1,4 @@
-//===-- lldb-mips-frebsd-register-enums.h -------------------------------*- C++ -*-===//
+//===-- lldb-mips-freebsd-register-enums.h ----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,61 +10,59 @@
#ifndef lldb_mips_freebsd_register_enums_h
#define lldb_mips_freebsd_register_enums_h
-namespace lldb_private
-{
- // LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
+namespace lldb_private {
+// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
- //---------------------------------------------------------------------------
- // Internal codes for all mips registers.
- //---------------------------------------------------------------------------
- enum
- {
- k_first_gpr_mips64,
- gpr_zero_mips64 = k_first_gpr_mips64,
- gpr_r1_mips64,
- gpr_r2_mips64,
- gpr_r3_mips64,
- gpr_r4_mips64,
- gpr_r5_mips64,
- gpr_r6_mips64,
- gpr_r7_mips64,
- gpr_r8_mips64,
- gpr_r9_mips64,
- gpr_r10_mips64,
- gpr_r11_mips64,
- gpr_r12_mips64,
- gpr_r13_mips64,
- gpr_r14_mips64,
- gpr_r15_mips64,
- gpr_r16_mips64,
- gpr_r17_mips64,
- gpr_r18_mips64,
- gpr_r19_mips64,
- gpr_r20_mips64,
- gpr_r21_mips64,
- gpr_r22_mips64,
- gpr_r23_mips64,
- gpr_r24_mips64,
- gpr_r25_mips64,
- gpr_r26_mips64,
- gpr_r27_mips64,
- gpr_gp_mips64,
- gpr_sp_mips64,
- gpr_r30_mips64,
- gpr_ra_mips64,
- gpr_sr_mips64,
- gpr_mullo_mips64,
- gpr_mulhi_mips64,
- gpr_badvaddr_mips64,
- gpr_cause_mips64,
- gpr_pc_mips64,
- gpr_ic_mips64,
- gpr_dummy_mips64,
- k_last_gpr_mips64 = gpr_dummy_mips64,
+//---------------------------------------------------------------------------
+// Internal codes for all mips registers.
+//---------------------------------------------------------------------------
+enum {
+ k_first_gpr_mips64,
+ gpr_zero_mips64 = k_first_gpr_mips64,
+ gpr_r1_mips64,
+ gpr_r2_mips64,
+ gpr_r3_mips64,
+ gpr_r4_mips64,
+ gpr_r5_mips64,
+ gpr_r6_mips64,
+ gpr_r7_mips64,
+ gpr_r8_mips64,
+ gpr_r9_mips64,
+ gpr_r10_mips64,
+ gpr_r11_mips64,
+ gpr_r12_mips64,
+ gpr_r13_mips64,
+ gpr_r14_mips64,
+ gpr_r15_mips64,
+ gpr_r16_mips64,
+ gpr_r17_mips64,
+ gpr_r18_mips64,
+ gpr_r19_mips64,
+ gpr_r20_mips64,
+ gpr_r21_mips64,
+ gpr_r22_mips64,
+ gpr_r23_mips64,
+ gpr_r24_mips64,
+ gpr_r25_mips64,
+ gpr_r26_mips64,
+ gpr_r27_mips64,
+ gpr_gp_mips64,
+ gpr_sp_mips64,
+ gpr_r30_mips64,
+ gpr_ra_mips64,
+ gpr_sr_mips64,
+ gpr_mullo_mips64,
+ gpr_mulhi_mips64,
+ gpr_badvaddr_mips64,
+ gpr_cause_mips64,
+ gpr_pc_mips64,
+ gpr_ic_mips64,
+ gpr_dummy_mips64,
+ k_last_gpr_mips64 = gpr_dummy_mips64,
- k_num_registers_mips64,
+ k_num_registers_mips64,
- k_num_gpr_registers_mips64 = k_last_gpr_mips64 - k_first_gpr_mips64 + 1
- };
+ k_num_gpr_registers_mips64 = k_last_gpr_mips64 - k_first_gpr_mips64 + 1
+};
}
#endif // #ifndef lldb_mips_freebsd_register_enums_h
diff --git a/source/Plugins/Process/Utility/lldb-mips-linux-register-enums.h b/source/Plugins/Process/Utility/lldb-mips-linux-register-enums.h
index 46ebf4ba06e3..0ecf3e366db0 100644
--- a/source/Plugins/Process/Utility/lldb-mips-linux-register-enums.h
+++ b/source/Plugins/Process/Utility/lldb-mips-linux-register-enums.h
@@ -1,4 +1,5 @@
-//===-- lldb-mips-linux-register-enums.h -------------------------------*- C++ -*-===//
+//===-- lldb-mips-linux-register-enums.h -------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,276 +11,277 @@
#ifndef lldb_mips_linux_register_enums_h
#define lldb_mips_linux_register_enums_h
-namespace lldb_private
-{
- // LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
+namespace lldb_private {
+// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
- //---------------------------------------------------------------------------
- // Internal codes for all mips registers.
- //---------------------------------------------------------------------------
- enum
- {
- k_first_gpr_mips,
- gpr_zero_mips = k_first_gpr_mips,
- gpr_r1_mips,
- gpr_r2_mips,
- gpr_r3_mips,
- gpr_r4_mips,
- gpr_r5_mips,
- gpr_r6_mips,
- gpr_r7_mips,
- gpr_r8_mips,
- gpr_r9_mips,
- gpr_r10_mips,
- gpr_r11_mips,
- gpr_r12_mips,
- gpr_r13_mips,
- gpr_r14_mips,
- gpr_r15_mips,
- gpr_r16_mips,
- gpr_r17_mips,
- gpr_r18_mips,
- gpr_r19_mips,
- gpr_r20_mips,
- gpr_r21_mips,
- gpr_r22_mips,
- gpr_r23_mips,
- gpr_r24_mips,
- gpr_r25_mips,
- gpr_r26_mips,
- gpr_r27_mips,
- gpr_gp_mips,
- gpr_sp_mips,
- gpr_r30_mips,
- gpr_ra_mips,
- gpr_sr_mips,
- gpr_mullo_mips,
- gpr_mulhi_mips,
- gpr_badvaddr_mips,
- gpr_cause_mips,
- gpr_pc_mips,
- gpr_config5_mips,
+//---------------------------------------------------------------------------
+// Internal codes for all mips registers.
+//---------------------------------------------------------------------------
+enum {
+ k_first_gpr_mips,
+ gpr_zero_mips = k_first_gpr_mips,
+ gpr_r1_mips,
+ gpr_r2_mips,
+ gpr_r3_mips,
+ gpr_r4_mips,
+ gpr_r5_mips,
+ gpr_r6_mips,
+ gpr_r7_mips,
+ gpr_r8_mips,
+ gpr_r9_mips,
+ gpr_r10_mips,
+ gpr_r11_mips,
+ gpr_r12_mips,
+ gpr_r13_mips,
+ gpr_r14_mips,
+ gpr_r15_mips,
+ gpr_r16_mips,
+ gpr_r17_mips,
+ gpr_r18_mips,
+ gpr_r19_mips,
+ gpr_r20_mips,
+ gpr_r21_mips,
+ gpr_r22_mips,
+ gpr_r23_mips,
+ gpr_r24_mips,
+ gpr_r25_mips,
+ gpr_r26_mips,
+ gpr_r27_mips,
+ gpr_gp_mips,
+ gpr_sp_mips,
+ gpr_r30_mips,
+ gpr_ra_mips,
+ gpr_sr_mips,
+ gpr_mullo_mips,
+ gpr_mulhi_mips,
+ gpr_badvaddr_mips,
+ gpr_cause_mips,
+ gpr_pc_mips,
+ gpr_config5_mips,
- k_last_gpr_mips = gpr_config5_mips,
+ k_last_gpr_mips = gpr_config5_mips,
- k_first_fpr_mips,
- fpr_f0_mips = k_first_fpr_mips,
- fpr_f1_mips,
- fpr_f2_mips,
- fpr_f3_mips,
- fpr_f4_mips,
- fpr_f5_mips,
- fpr_f6_mips,
- fpr_f7_mips,
- fpr_f8_mips,
- fpr_f9_mips,
- fpr_f10_mips,
- fpr_f11_mips,
- fpr_f12_mips,
- fpr_f13_mips,
- fpr_f14_mips,
- fpr_f15_mips,
- fpr_f16_mips,
- fpr_f17_mips,
- fpr_f18_mips,
- fpr_f19_mips,
- fpr_f20_mips,
- fpr_f21_mips,
- fpr_f22_mips,
- fpr_f23_mips,
- fpr_f24_mips,
- fpr_f25_mips,
- fpr_f26_mips,
- fpr_f27_mips,
- fpr_f28_mips,
- fpr_f29_mips,
- fpr_f30_mips,
- fpr_f31_mips,
- fpr_fcsr_mips,
- fpr_fir_mips,
- fpr_config5_mips,
- k_last_fpr_mips = fpr_config5_mips,
+ k_first_fpr_mips,
+ fpr_f0_mips = k_first_fpr_mips,
+ fpr_f1_mips,
+ fpr_f2_mips,
+ fpr_f3_mips,
+ fpr_f4_mips,
+ fpr_f5_mips,
+ fpr_f6_mips,
+ fpr_f7_mips,
+ fpr_f8_mips,
+ fpr_f9_mips,
+ fpr_f10_mips,
+ fpr_f11_mips,
+ fpr_f12_mips,
+ fpr_f13_mips,
+ fpr_f14_mips,
+ fpr_f15_mips,
+ fpr_f16_mips,
+ fpr_f17_mips,
+ fpr_f18_mips,
+ fpr_f19_mips,
+ fpr_f20_mips,
+ fpr_f21_mips,
+ fpr_f22_mips,
+ fpr_f23_mips,
+ fpr_f24_mips,
+ fpr_f25_mips,
+ fpr_f26_mips,
+ fpr_f27_mips,
+ fpr_f28_mips,
+ fpr_f29_mips,
+ fpr_f30_mips,
+ fpr_f31_mips,
+ fpr_fcsr_mips,
+ fpr_fir_mips,
+ fpr_config5_mips,
+ k_last_fpr_mips = fpr_config5_mips,
- k_first_msa_mips,
- msa_w0_mips = k_first_msa_mips,
- msa_w1_mips,
- msa_w2_mips,
- msa_w3_mips,
- msa_w4_mips,
- msa_w5_mips,
- msa_w6_mips,
- msa_w7_mips,
- msa_w8_mips,
- msa_w9_mips,
- msa_w10_mips,
- msa_w11_mips,
- msa_w12_mips,
- msa_w13_mips,
- msa_w14_mips,
- msa_w15_mips,
- msa_w16_mips,
- msa_w17_mips,
- msa_w18_mips,
- msa_w19_mips,
- msa_w20_mips,
- msa_w21_mips,
- msa_w22_mips,
- msa_w23_mips,
- msa_w24_mips,
- msa_w25_mips,
- msa_w26_mips,
- msa_w27_mips,
- msa_w28_mips,
- msa_w29_mips,
- msa_w30_mips,
- msa_w31_mips,
- msa_fcsr_mips,
- msa_fir_mips,
- msa_mcsr_mips,
- msa_mir_mips,
- msa_config5_mips,
- k_last_msa_mips = msa_config5_mips,
+ k_first_msa_mips,
+ msa_w0_mips = k_first_msa_mips,
+ msa_w1_mips,
+ msa_w2_mips,
+ msa_w3_mips,
+ msa_w4_mips,
+ msa_w5_mips,
+ msa_w6_mips,
+ msa_w7_mips,
+ msa_w8_mips,
+ msa_w9_mips,
+ msa_w10_mips,
+ msa_w11_mips,
+ msa_w12_mips,
+ msa_w13_mips,
+ msa_w14_mips,
+ msa_w15_mips,
+ msa_w16_mips,
+ msa_w17_mips,
+ msa_w18_mips,
+ msa_w19_mips,
+ msa_w20_mips,
+ msa_w21_mips,
+ msa_w22_mips,
+ msa_w23_mips,
+ msa_w24_mips,
+ msa_w25_mips,
+ msa_w26_mips,
+ msa_w27_mips,
+ msa_w28_mips,
+ msa_w29_mips,
+ msa_w30_mips,
+ msa_w31_mips,
+ msa_fcsr_mips,
+ msa_fir_mips,
+ msa_mcsr_mips,
+ msa_mir_mips,
+ msa_config5_mips,
+ k_last_msa_mips = msa_config5_mips,
- k_num_registers_mips,
+ k_num_registers_mips,
- k_num_gpr_registers_mips = k_last_gpr_mips - k_first_gpr_mips + 1,
- k_num_fpr_registers_mips = k_last_fpr_mips - k_first_fpr_mips + 1,
- k_num_msa_registers_mips = k_last_msa_mips - k_first_msa_mips + 1,
- k_num_user_registers_mips = k_num_gpr_registers_mips + k_num_fpr_registers_mips + k_num_msa_registers_mips
- };
+ k_num_gpr_registers_mips = k_last_gpr_mips - k_first_gpr_mips + 1,
+ k_num_fpr_registers_mips = k_last_fpr_mips - k_first_fpr_mips + 1,
+ k_num_msa_registers_mips = k_last_msa_mips - k_first_msa_mips + 1,
+ k_num_user_registers_mips = k_num_gpr_registers_mips +
+ k_num_fpr_registers_mips +
+ k_num_msa_registers_mips
+};
- //---------------------------------------------------------------------------
- // Internal codes for all mips64 registers.
- //---------------------------------------------------------------------------
- enum
- {
- k_first_gpr_mips64,
- gpr_zero_mips64 = k_first_gpr_mips64,
- gpr_r1_mips64,
- gpr_r2_mips64,
- gpr_r3_mips64,
- gpr_r4_mips64,
- gpr_r5_mips64,
- gpr_r6_mips64,
- gpr_r7_mips64,
- gpr_r8_mips64,
- gpr_r9_mips64,
- gpr_r10_mips64,
- gpr_r11_mips64,
- gpr_r12_mips64,
- gpr_r13_mips64,
- gpr_r14_mips64,
- gpr_r15_mips64,
- gpr_r16_mips64,
- gpr_r17_mips64,
- gpr_r18_mips64,
- gpr_r19_mips64,
- gpr_r20_mips64,
- gpr_r21_mips64,
- gpr_r22_mips64,
- gpr_r23_mips64,
- gpr_r24_mips64,
- gpr_r25_mips64,
- gpr_r26_mips64,
- gpr_r27_mips64,
- gpr_gp_mips64,
- gpr_sp_mips64,
- gpr_r30_mips64,
- gpr_ra_mips64,
- gpr_sr_mips64,
- gpr_mullo_mips64,
- gpr_mulhi_mips64,
- gpr_badvaddr_mips64,
- gpr_cause_mips64,
- gpr_pc_mips64,
- gpr_config5_mips64,
- k_last_gpr_mips64 = gpr_config5_mips64,
+//---------------------------------------------------------------------------
+// Internal codes for all mips64 registers.
+//---------------------------------------------------------------------------
+enum {
+ k_first_gpr_mips64,
+ gpr_zero_mips64 = k_first_gpr_mips64,
+ gpr_r1_mips64,
+ gpr_r2_mips64,
+ gpr_r3_mips64,
+ gpr_r4_mips64,
+ gpr_r5_mips64,
+ gpr_r6_mips64,
+ gpr_r7_mips64,
+ gpr_r8_mips64,
+ gpr_r9_mips64,
+ gpr_r10_mips64,
+ gpr_r11_mips64,
+ gpr_r12_mips64,
+ gpr_r13_mips64,
+ gpr_r14_mips64,
+ gpr_r15_mips64,
+ gpr_r16_mips64,
+ gpr_r17_mips64,
+ gpr_r18_mips64,
+ gpr_r19_mips64,
+ gpr_r20_mips64,
+ gpr_r21_mips64,
+ gpr_r22_mips64,
+ gpr_r23_mips64,
+ gpr_r24_mips64,
+ gpr_r25_mips64,
+ gpr_r26_mips64,
+ gpr_r27_mips64,
+ gpr_gp_mips64,
+ gpr_sp_mips64,
+ gpr_r30_mips64,
+ gpr_ra_mips64,
+ gpr_sr_mips64,
+ gpr_mullo_mips64,
+ gpr_mulhi_mips64,
+ gpr_badvaddr_mips64,
+ gpr_cause_mips64,
+ gpr_pc_mips64,
+ gpr_config5_mips64,
+ k_last_gpr_mips64 = gpr_config5_mips64,
- k_first_fpr_mips64,
- fpr_f0_mips64 = k_first_fpr_mips64,
- fpr_f1_mips64,
- fpr_f2_mips64,
- fpr_f3_mips64,
- fpr_f4_mips64,
- fpr_f5_mips64,
- fpr_f6_mips64,
- fpr_f7_mips64,
- fpr_f8_mips64,
- fpr_f9_mips64,
- fpr_f10_mips64,
- fpr_f11_mips64,
- fpr_f12_mips64,
- fpr_f13_mips64,
- fpr_f14_mips64,
- fpr_f15_mips64,
- fpr_f16_mips64,
- fpr_f17_mips64,
- fpr_f18_mips64,
- fpr_f19_mips64,
- fpr_f20_mips64,
- fpr_f21_mips64,
- fpr_f22_mips64,
- fpr_f23_mips64,
- fpr_f24_mips64,
- fpr_f25_mips64,
- fpr_f26_mips64,
- fpr_f27_mips64,
- fpr_f28_mips64,
- fpr_f29_mips64,
- fpr_f30_mips64,
- fpr_f31_mips64,
- fpr_fcsr_mips64,
- fpr_fir_mips64,
- fpr_config5_mips64,
- k_last_fpr_mips64 = fpr_config5_mips64,
+ k_first_fpr_mips64,
+ fpr_f0_mips64 = k_first_fpr_mips64,
+ fpr_f1_mips64,
+ fpr_f2_mips64,
+ fpr_f3_mips64,
+ fpr_f4_mips64,
+ fpr_f5_mips64,
+ fpr_f6_mips64,
+ fpr_f7_mips64,
+ fpr_f8_mips64,
+ fpr_f9_mips64,
+ fpr_f10_mips64,
+ fpr_f11_mips64,
+ fpr_f12_mips64,
+ fpr_f13_mips64,
+ fpr_f14_mips64,
+ fpr_f15_mips64,
+ fpr_f16_mips64,
+ fpr_f17_mips64,
+ fpr_f18_mips64,
+ fpr_f19_mips64,
+ fpr_f20_mips64,
+ fpr_f21_mips64,
+ fpr_f22_mips64,
+ fpr_f23_mips64,
+ fpr_f24_mips64,
+ fpr_f25_mips64,
+ fpr_f26_mips64,
+ fpr_f27_mips64,
+ fpr_f28_mips64,
+ fpr_f29_mips64,
+ fpr_f30_mips64,
+ fpr_f31_mips64,
+ fpr_fcsr_mips64,
+ fpr_fir_mips64,
+ fpr_config5_mips64,
+ k_last_fpr_mips64 = fpr_config5_mips64,
- k_first_msa_mips64,
- msa_w0_mips64 = k_first_msa_mips64,
- msa_w1_mips64,
- msa_w2_mips64,
- msa_w3_mips64,
- msa_w4_mips64,
- msa_w5_mips64,
- msa_w6_mips64,
- msa_w7_mips64,
- msa_w8_mips64,
- msa_w9_mips64,
- msa_w10_mips64,
- msa_w11_mips64,
- msa_w12_mips64,
- msa_w13_mips64,
- msa_w14_mips64,
- msa_w15_mips64,
- msa_w16_mips64,
- msa_w17_mips64,
- msa_w18_mips64,
- msa_w19_mips64,
- msa_w20_mips64,
- msa_w21_mips64,
- msa_w22_mips64,
- msa_w23_mips64,
- msa_w24_mips64,
- msa_w25_mips64,
- msa_w26_mips64,
- msa_w27_mips64,
- msa_w28_mips64,
- msa_w29_mips64,
- msa_w30_mips64,
- msa_w31_mips64,
- msa_fcsr_mips64,
- msa_fir_mips64,
- msa_mcsr_mips64,
- msa_mir_mips64,
- msa_config5_mips64,
- k_last_msa_mips64 = msa_config5_mips64,
+ k_first_msa_mips64,
+ msa_w0_mips64 = k_first_msa_mips64,
+ msa_w1_mips64,
+ msa_w2_mips64,
+ msa_w3_mips64,
+ msa_w4_mips64,
+ msa_w5_mips64,
+ msa_w6_mips64,
+ msa_w7_mips64,
+ msa_w8_mips64,
+ msa_w9_mips64,
+ msa_w10_mips64,
+ msa_w11_mips64,
+ msa_w12_mips64,
+ msa_w13_mips64,
+ msa_w14_mips64,
+ msa_w15_mips64,
+ msa_w16_mips64,
+ msa_w17_mips64,
+ msa_w18_mips64,
+ msa_w19_mips64,
+ msa_w20_mips64,
+ msa_w21_mips64,
+ msa_w22_mips64,
+ msa_w23_mips64,
+ msa_w24_mips64,
+ msa_w25_mips64,
+ msa_w26_mips64,
+ msa_w27_mips64,
+ msa_w28_mips64,
+ msa_w29_mips64,
+ msa_w30_mips64,
+ msa_w31_mips64,
+ msa_fcsr_mips64,
+ msa_fir_mips64,
+ msa_mcsr_mips64,
+ msa_mir_mips64,
+ msa_config5_mips64,
+ k_last_msa_mips64 = msa_config5_mips64,
- k_num_registers_mips64,
+ k_num_registers_mips64,
- k_num_gpr_registers_mips64 = k_last_gpr_mips64 - k_first_gpr_mips64 + 1,
- k_num_fpr_registers_mips64 = k_last_fpr_mips64 - k_first_fpr_mips64 + 1,
- k_num_msa_registers_mips64 = k_last_msa_mips64 - k_first_msa_mips64 + 1,
- k_num_user_registers_mips64 = k_num_gpr_registers_mips64 + k_num_fpr_registers_mips64 + k_num_msa_registers_mips64
- };
+ k_num_gpr_registers_mips64 = k_last_gpr_mips64 - k_first_gpr_mips64 + 1,
+ k_num_fpr_registers_mips64 = k_last_fpr_mips64 - k_first_fpr_mips64 + 1,
+ k_num_msa_registers_mips64 = k_last_msa_mips64 - k_first_msa_mips64 + 1,
+ k_num_user_registers_mips64 = k_num_gpr_registers_mips64 +
+ k_num_fpr_registers_mips64 +
+ k_num_msa_registers_mips64
+};
// Register no. for RegisterKind = eRegisterKindProcessPlugin
// The ptrace request PTRACE_PEEKUSER/PTRACE_POKEUSER used this number
diff --git a/source/Plugins/Process/Utility/lldb-s390x-register-enums.h b/source/Plugins/Process/Utility/lldb-s390x-register-enums.h
index 174daa25e21b..65ff92f39bca 100644
--- a/source/Plugins/Process/Utility/lldb-s390x-register-enums.h
+++ b/source/Plugins/Process/Utility/lldb-s390x-register-enums.h
@@ -10,84 +10,83 @@
#ifndef lldb_s390x_register_enums_h
#define lldb_s390x_register_enums_h
-namespace lldb_private
-{
+namespace lldb_private {
// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
//---------------------------------------------------------------------------
// Internal codes for all s390x registers.
//---------------------------------------------------------------------------
-enum
-{
- k_first_gpr_s390x,
- lldb_r0_s390x = k_first_gpr_s390x,
- lldb_r1_s390x,
- lldb_r2_s390x,
- lldb_r3_s390x,
- lldb_r4_s390x,
- lldb_r5_s390x,
- lldb_r6_s390x,
- lldb_r7_s390x,
- lldb_r8_s390x,
- lldb_r9_s390x,
- lldb_r10_s390x,
- lldb_r11_s390x,
- lldb_r12_s390x,
- lldb_r13_s390x,
- lldb_r14_s390x,
- lldb_r15_s390x,
- lldb_acr0_s390x,
- lldb_acr1_s390x,
- lldb_acr2_s390x,
- lldb_acr3_s390x,
- lldb_acr4_s390x,
- lldb_acr5_s390x,
- lldb_acr6_s390x,
- lldb_acr7_s390x,
- lldb_acr8_s390x,
- lldb_acr9_s390x,
- lldb_acr10_s390x,
- lldb_acr11_s390x,
- lldb_acr12_s390x,
- lldb_acr13_s390x,
- lldb_acr14_s390x,
- lldb_acr15_s390x,
- lldb_pswm_s390x,
- lldb_pswa_s390x,
- k_last_gpr_s390x = lldb_pswa_s390x,
+enum {
+ k_first_gpr_s390x,
+ lldb_r0_s390x = k_first_gpr_s390x,
+ lldb_r1_s390x,
+ lldb_r2_s390x,
+ lldb_r3_s390x,
+ lldb_r4_s390x,
+ lldb_r5_s390x,
+ lldb_r6_s390x,
+ lldb_r7_s390x,
+ lldb_r8_s390x,
+ lldb_r9_s390x,
+ lldb_r10_s390x,
+ lldb_r11_s390x,
+ lldb_r12_s390x,
+ lldb_r13_s390x,
+ lldb_r14_s390x,
+ lldb_r15_s390x,
+ lldb_acr0_s390x,
+ lldb_acr1_s390x,
+ lldb_acr2_s390x,
+ lldb_acr3_s390x,
+ lldb_acr4_s390x,
+ lldb_acr5_s390x,
+ lldb_acr6_s390x,
+ lldb_acr7_s390x,
+ lldb_acr8_s390x,
+ lldb_acr9_s390x,
+ lldb_acr10_s390x,
+ lldb_acr11_s390x,
+ lldb_acr12_s390x,
+ lldb_acr13_s390x,
+ lldb_acr14_s390x,
+ lldb_acr15_s390x,
+ lldb_pswm_s390x,
+ lldb_pswa_s390x,
+ k_last_gpr_s390x = lldb_pswa_s390x,
- k_first_fpr_s390x,
- lldb_f0_s390x = k_first_fpr_s390x,
- lldb_f1_s390x,
- lldb_f2_s390x,
- lldb_f3_s390x,
- lldb_f4_s390x,
- lldb_f5_s390x,
- lldb_f6_s390x,
- lldb_f7_s390x,
- lldb_f8_s390x,
- lldb_f9_s390x,
- lldb_f10_s390x,
- lldb_f11_s390x,
- lldb_f12_s390x,
- lldb_f13_s390x,
- lldb_f14_s390x,
- lldb_f15_s390x,
- lldb_fpc_s390x,
- k_last_fpr_s390x = lldb_fpc_s390x,
+ k_first_fpr_s390x,
+ lldb_f0_s390x = k_first_fpr_s390x,
+ lldb_f1_s390x,
+ lldb_f2_s390x,
+ lldb_f3_s390x,
+ lldb_f4_s390x,
+ lldb_f5_s390x,
+ lldb_f6_s390x,
+ lldb_f7_s390x,
+ lldb_f8_s390x,
+ lldb_f9_s390x,
+ lldb_f10_s390x,
+ lldb_f11_s390x,
+ lldb_f12_s390x,
+ lldb_f13_s390x,
+ lldb_f14_s390x,
+ lldb_f15_s390x,
+ lldb_fpc_s390x,
+ k_last_fpr_s390x = lldb_fpc_s390x,
- // These are only available on Linux.
- k_first_linux_s390x,
- lldb_orig_r2_s390x = k_first_linux_s390x,
- lldb_last_break_s390x,
- lldb_system_call_s390x,
- k_last_linux_s390x = lldb_system_call_s390x,
+ // These are only available on Linux.
+ k_first_linux_s390x,
+ lldb_orig_r2_s390x = k_first_linux_s390x,
+ lldb_last_break_s390x,
+ lldb_system_call_s390x,
+ k_last_linux_s390x = lldb_system_call_s390x,
- k_num_registers_s390x,
- k_num_gpr_registers_s390x = k_last_gpr_s390x - k_first_gpr_s390x + 1,
- k_num_fpr_registers_s390x = k_last_fpr_s390x - k_first_fpr_s390x + 1,
- k_num_linux_registers_s390x = k_last_linux_s390x - k_first_linux_s390x + 1,
- k_num_user_registers_s390x = k_num_gpr_registers_s390x + k_num_fpr_registers_s390x,
+ k_num_registers_s390x,
+ k_num_gpr_registers_s390x = k_last_gpr_s390x - k_first_gpr_s390x + 1,
+ k_num_fpr_registers_s390x = k_last_fpr_s390x - k_first_fpr_s390x + 1,
+ k_num_linux_registers_s390x = k_last_linux_s390x - k_first_linux_s390x + 1,
+ k_num_user_registers_s390x =
+ k_num_gpr_registers_s390x + k_num_fpr_registers_s390x,
};
}
diff --git a/source/Plugins/Process/Utility/lldb-x86-register-enums.h b/source/Plugins/Process/Utility/lldb-x86-register-enums.h
index 63027b4451b8..770ec5a5f3ef 100644
--- a/source/Plugins/Process/Utility/lldb-x86-register-enums.h
+++ b/source/Plugins/Process/Utility/lldb-x86-register-enums.h
@@ -10,286 +10,314 @@
#ifndef lldb_x86_register_enums_h
#define lldb_x86_register_enums_h
-namespace lldb_private
-{
- // LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
+namespace lldb_private {
+// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
- //---------------------------------------------------------------------------
- // Internal codes for all i386 registers.
- //---------------------------------------------------------------------------
- enum
- {
- k_first_gpr_i386,
- lldb_eax_i386 = k_first_gpr_i386,
- lldb_ebx_i386,
- lldb_ecx_i386,
- lldb_edx_i386,
- lldb_edi_i386,
- lldb_esi_i386,
- lldb_ebp_i386,
- lldb_esp_i386,
- lldb_eip_i386,
- lldb_eflags_i386,
- lldb_cs_i386,
- lldb_fs_i386,
- lldb_gs_i386,
- lldb_ss_i386,
- lldb_ds_i386,
- lldb_es_i386,
+//---------------------------------------------------------------------------
+// Internal codes for all i386 registers.
+//---------------------------------------------------------------------------
+enum {
+ k_first_gpr_i386,
+ lldb_eax_i386 = k_first_gpr_i386,
+ lldb_ebx_i386,
+ lldb_ecx_i386,
+ lldb_edx_i386,
+ lldb_edi_i386,
+ lldb_esi_i386,
+ lldb_ebp_i386,
+ lldb_esp_i386,
+ lldb_eip_i386,
+ lldb_eflags_i386,
+ lldb_cs_i386,
+ lldb_fs_i386,
+ lldb_gs_i386,
+ lldb_ss_i386,
+ lldb_ds_i386,
+ lldb_es_i386,
- k_first_alias_i386,
- lldb_ax_i386 = k_first_alias_i386,
- lldb_bx_i386,
- lldb_cx_i386,
- lldb_dx_i386,
- lldb_di_i386,
- lldb_si_i386,
- lldb_bp_i386,
- lldb_sp_i386,
- lldb_ah_i386,
- lldb_bh_i386,
- lldb_ch_i386,
- lldb_dh_i386,
- lldb_al_i386,
- lldb_bl_i386,
- lldb_cl_i386,
- lldb_dl_i386,
- k_last_alias_i386 = lldb_dl_i386,
+ k_first_alias_i386,
+ lldb_ax_i386 = k_first_alias_i386,
+ lldb_bx_i386,
+ lldb_cx_i386,
+ lldb_dx_i386,
+ lldb_di_i386,
+ lldb_si_i386,
+ lldb_bp_i386,
+ lldb_sp_i386,
+ lldb_ah_i386,
+ lldb_bh_i386,
+ lldb_ch_i386,
+ lldb_dh_i386,
+ lldb_al_i386,
+ lldb_bl_i386,
+ lldb_cl_i386,
+ lldb_dl_i386,
+ k_last_alias_i386 = lldb_dl_i386,
- k_last_gpr_i386 = k_last_alias_i386,
+ k_last_gpr_i386 = k_last_alias_i386,
- k_first_fpr_i386,
- lldb_fctrl_i386 = k_first_fpr_i386,
- lldb_fstat_i386,
- lldb_ftag_i386,
- lldb_fop_i386,
- lldb_fiseg_i386,
- lldb_fioff_i386,
- lldb_foseg_i386,
- lldb_fooff_i386,
- lldb_mxcsr_i386,
- lldb_mxcsrmask_i386,
- lldb_st0_i386,
- lldb_st1_i386,
- lldb_st2_i386,
- lldb_st3_i386,
- lldb_st4_i386,
- lldb_st5_i386,
- lldb_st6_i386,
- lldb_st7_i386,
- lldb_mm0_i386,
- lldb_mm1_i386,
- lldb_mm2_i386,
- lldb_mm3_i386,
- lldb_mm4_i386,
- lldb_mm5_i386,
- lldb_mm6_i386,
- lldb_mm7_i386,
- lldb_xmm0_i386,
- lldb_xmm1_i386,
- lldb_xmm2_i386,
- lldb_xmm3_i386,
- lldb_xmm4_i386,
- lldb_xmm5_i386,
- lldb_xmm6_i386,
- lldb_xmm7_i386,
- k_last_fpr_i386 = lldb_xmm7_i386,
+ k_first_fpr_i386,
+ lldb_fctrl_i386 = k_first_fpr_i386,
+ lldb_fstat_i386,
+ lldb_ftag_i386,
+ lldb_fop_i386,
+ lldb_fiseg_i386,
+ lldb_fioff_i386,
+ lldb_foseg_i386,
+ lldb_fooff_i386,
+ lldb_mxcsr_i386,
+ lldb_mxcsrmask_i386,
+ lldb_st0_i386,
+ lldb_st1_i386,
+ lldb_st2_i386,
+ lldb_st3_i386,
+ lldb_st4_i386,
+ lldb_st5_i386,
+ lldb_st6_i386,
+ lldb_st7_i386,
+ lldb_mm0_i386,
+ lldb_mm1_i386,
+ lldb_mm2_i386,
+ lldb_mm3_i386,
+ lldb_mm4_i386,
+ lldb_mm5_i386,
+ lldb_mm6_i386,
+ lldb_mm7_i386,
+ lldb_xmm0_i386,
+ lldb_xmm1_i386,
+ lldb_xmm2_i386,
+ lldb_xmm3_i386,
+ lldb_xmm4_i386,
+ lldb_xmm5_i386,
+ lldb_xmm6_i386,
+ lldb_xmm7_i386,
+ k_last_fpr_i386 = lldb_xmm7_i386,
- k_first_avx_i386,
- lldb_ymm0_i386 = k_first_avx_i386,
- lldb_ymm1_i386,
- lldb_ymm2_i386,
- lldb_ymm3_i386,
- lldb_ymm4_i386,
- lldb_ymm5_i386,
- lldb_ymm6_i386,
- lldb_ymm7_i386,
- k_last_avx_i386 = lldb_ymm7_i386,
+ k_first_avx_i386,
+ lldb_ymm0_i386 = k_first_avx_i386,
+ lldb_ymm1_i386,
+ lldb_ymm2_i386,
+ lldb_ymm3_i386,
+ lldb_ymm4_i386,
+ lldb_ymm5_i386,
+ lldb_ymm6_i386,
+ lldb_ymm7_i386,
+ k_last_avx_i386 = lldb_ymm7_i386,
- lldb_dr0_i386,
- lldb_dr1_i386,
- lldb_dr2_i386,
- lldb_dr3_i386,
- lldb_dr4_i386,
- lldb_dr5_i386,
- lldb_dr6_i386,
- lldb_dr7_i386,
+ k_first_mpxr_i386,
+ lldb_bnd0_i386 = k_first_mpxr_i386,
+ lldb_bnd1_i386,
+ lldb_bnd2_i386,
+ lldb_bnd3_i386,
+ k_last_mpxr = lldb_bnd3_i386,
- k_num_registers_i386,
- k_num_gpr_registers_i386 = k_last_gpr_i386 - k_first_gpr_i386 + 1,
- k_num_fpr_registers_i386 = k_last_fpr_i386 - k_first_fpr_i386 + 1,
- k_num_avx_registers_i386 = k_last_avx_i386 - k_first_avx_i386 + 1,
- k_num_user_registers_i386 = k_num_gpr_registers_i386 + k_num_fpr_registers_i386 + k_num_avx_registers_i386,
- };
+ k_first_mpxc_i386,
+ lldb_bndcfgu_i386 = k_first_mpxc_i386,
+ lldb_bndstatus_i386,
+ k_last_mpxc_i386 = lldb_bndstatus_i386,
- //---------------------------------------------------------------------------
- // Internal codes for all x86_64 registers.
- //---------------------------------------------------------------------------
- enum
- {
- k_first_gpr_x86_64,
- lldb_rax_x86_64 = k_first_gpr_x86_64,
- lldb_rbx_x86_64,
- lldb_rcx_x86_64,
- lldb_rdx_x86_64,
- lldb_rdi_x86_64,
- lldb_rsi_x86_64,
- lldb_rbp_x86_64,
- lldb_rsp_x86_64,
- lldb_r8_x86_64,
- lldb_r9_x86_64,
- lldb_r10_x86_64,
- lldb_r11_x86_64,
- lldb_r12_x86_64,
- lldb_r13_x86_64,
- lldb_r14_x86_64,
- lldb_r15_x86_64,
- lldb_rip_x86_64,
- lldb_rflags_x86_64,
- lldb_cs_x86_64,
- lldb_fs_x86_64,
- lldb_gs_x86_64,
- lldb_ss_x86_64,
- lldb_ds_x86_64,
- lldb_es_x86_64,
+ lldb_dr0_i386,
+ lldb_dr1_i386,
+ lldb_dr2_i386,
+ lldb_dr3_i386,
+ lldb_dr4_i386,
+ lldb_dr5_i386,
+ lldb_dr6_i386,
+ lldb_dr7_i386,
- k_first_alias_x86_64,
- lldb_eax_x86_64 = k_first_alias_x86_64,
- lldb_ebx_x86_64,
- lldb_ecx_x86_64,
- lldb_edx_x86_64,
- lldb_edi_x86_64,
- lldb_esi_x86_64,
- lldb_ebp_x86_64,
- lldb_esp_x86_64,
- lldb_r8d_x86_64, // Low 32 bits of r8
- lldb_r9d_x86_64, // Low 32 bits of r9
- lldb_r10d_x86_64, // Low 32 bits of r10
- lldb_r11d_x86_64, // Low 32 bits of r11
- lldb_r12d_x86_64, // Low 32 bits of r12
- lldb_r13d_x86_64, // Low 32 bits of r13
- lldb_r14d_x86_64, // Low 32 bits of r14
- lldb_r15d_x86_64, // Low 32 bits of r15
- lldb_ax_x86_64,
- lldb_bx_x86_64,
- lldb_cx_x86_64,
- lldb_dx_x86_64,
- lldb_di_x86_64,
- lldb_si_x86_64,
- lldb_bp_x86_64,
- lldb_sp_x86_64,
- lldb_r8w_x86_64, // Low 16 bits of r8
- lldb_r9w_x86_64, // Low 16 bits of r9
- lldb_r10w_x86_64, // Low 16 bits of r10
- lldb_r11w_x86_64, // Low 16 bits of r11
- lldb_r12w_x86_64, // Low 16 bits of r12
- lldb_r13w_x86_64, // Low 16 bits of r13
- lldb_r14w_x86_64, // Low 16 bits of r14
- lldb_r15w_x86_64, // Low 16 bits of r15
- lldb_ah_x86_64,
- lldb_bh_x86_64,
- lldb_ch_x86_64,
- lldb_dh_x86_64,
- lldb_al_x86_64,
- lldb_bl_x86_64,
- lldb_cl_x86_64,
- lldb_dl_x86_64,
- lldb_dil_x86_64,
- lldb_sil_x86_64,
- lldb_bpl_x86_64,
- lldb_spl_x86_64,
- lldb_r8l_x86_64, // Low 8 bits of r8
- lldb_r9l_x86_64, // Low 8 bits of r9
- lldb_r10l_x86_64, // Low 8 bits of r10
- lldb_r11l_x86_64, // Low 8 bits of r11
- lldb_r12l_x86_64, // Low 8 bits of r12
- lldb_r13l_x86_64, // Low 8 bits of r13
- lldb_r14l_x86_64, // Low 8 bits of r14
- lldb_r15l_x86_64, // Low 8 bits of r15
- k_last_alias_x86_64 = lldb_r15l_x86_64,
+ k_num_registers_i386,
+ k_num_gpr_registers_i386 = k_last_gpr_i386 - k_first_gpr_i386 + 1,
+ k_num_fpr_registers_i386 = k_last_fpr_i386 - k_first_fpr_i386 + 1,
+ k_num_avx_registers_i386 = k_last_avx_i386 - k_first_avx_i386 + 1,
+ k_num_mpx_registers_i386 = k_last_mpxc_i386 - k_first_mpxr_i386 + 1,
+ k_num_user_registers_i386 = k_num_gpr_registers_i386 +
+ k_num_fpr_registers_i386 +
+ k_num_avx_registers_i386 +
+ k_num_mpx_registers_i386,
+};
- k_last_gpr_x86_64 = k_last_alias_x86_64,
+//---------------------------------------------------------------------------
+// Internal codes for all x86_64 registers.
+//---------------------------------------------------------------------------
+enum {
+ k_first_gpr_x86_64,
+ lldb_rax_x86_64 = k_first_gpr_x86_64,
+ lldb_rbx_x86_64,
+ lldb_rcx_x86_64,
+ lldb_rdx_x86_64,
+ lldb_rdi_x86_64,
+ lldb_rsi_x86_64,
+ lldb_rbp_x86_64,
+ lldb_rsp_x86_64,
+ lldb_r8_x86_64,
+ lldb_r9_x86_64,
+ lldb_r10_x86_64,
+ lldb_r11_x86_64,
+ lldb_r12_x86_64,
+ lldb_r13_x86_64,
+ lldb_r14_x86_64,
+ lldb_r15_x86_64,
+ lldb_rip_x86_64,
+ lldb_rflags_x86_64,
+ lldb_cs_x86_64,
+ lldb_fs_x86_64,
+ lldb_gs_x86_64,
+ lldb_ss_x86_64,
+ lldb_ds_x86_64,
+ lldb_es_x86_64,
- k_first_fpr_x86_64,
- lldb_fctrl_x86_64 = k_first_fpr_x86_64,
- lldb_fstat_x86_64,
- lldb_ftag_x86_64,
- lldb_fop_x86_64,
- lldb_fiseg_x86_64,
- lldb_fioff_x86_64,
- lldb_foseg_x86_64,
- lldb_fooff_x86_64,
- lldb_mxcsr_x86_64,
- lldb_mxcsrmask_x86_64,
- lldb_st0_x86_64,
- lldb_st1_x86_64,
- lldb_st2_x86_64,
- lldb_st3_x86_64,
- lldb_st4_x86_64,
- lldb_st5_x86_64,
- lldb_st6_x86_64,
- lldb_st7_x86_64,
- lldb_mm0_x86_64,
- lldb_mm1_x86_64,
- lldb_mm2_x86_64,
- lldb_mm3_x86_64,
- lldb_mm4_x86_64,
- lldb_mm5_x86_64,
- lldb_mm6_x86_64,
- lldb_mm7_x86_64,
- lldb_xmm0_x86_64,
- lldb_xmm1_x86_64,
- lldb_xmm2_x86_64,
- lldb_xmm3_x86_64,
- lldb_xmm4_x86_64,
- lldb_xmm5_x86_64,
- lldb_xmm6_x86_64,
- lldb_xmm7_x86_64,
- lldb_xmm8_x86_64,
- lldb_xmm9_x86_64,
- lldb_xmm10_x86_64,
- lldb_xmm11_x86_64,
- lldb_xmm12_x86_64,
- lldb_xmm13_x86_64,
- lldb_xmm14_x86_64,
- lldb_xmm15_x86_64,
- k_last_fpr_x86_64 = lldb_xmm15_x86_64,
+ k_first_alias_x86_64,
+ lldb_eax_x86_64 = k_first_alias_x86_64,
+ lldb_ebx_x86_64,
+ lldb_ecx_x86_64,
+ lldb_edx_x86_64,
+ lldb_edi_x86_64,
+ lldb_esi_x86_64,
+ lldb_ebp_x86_64,
+ lldb_esp_x86_64,
+ lldb_r8d_x86_64, // Low 32 bits of r8
+ lldb_r9d_x86_64, // Low 32 bits of r9
+ lldb_r10d_x86_64, // Low 32 bits of r10
+ lldb_r11d_x86_64, // Low 32 bits of r11
+ lldb_r12d_x86_64, // Low 32 bits of r12
+ lldb_r13d_x86_64, // Low 32 bits of r13
+ lldb_r14d_x86_64, // Low 32 bits of r14
+ lldb_r15d_x86_64, // Low 32 bits of r15
+ lldb_ax_x86_64,
+ lldb_bx_x86_64,
+ lldb_cx_x86_64,
+ lldb_dx_x86_64,
+ lldb_di_x86_64,
+ lldb_si_x86_64,
+ lldb_bp_x86_64,
+ lldb_sp_x86_64,
+ lldb_r8w_x86_64, // Low 16 bits of r8
+ lldb_r9w_x86_64, // Low 16 bits of r9
+ lldb_r10w_x86_64, // Low 16 bits of r10
+ lldb_r11w_x86_64, // Low 16 bits of r11
+ lldb_r12w_x86_64, // Low 16 bits of r12
+ lldb_r13w_x86_64, // Low 16 bits of r13
+ lldb_r14w_x86_64, // Low 16 bits of r14
+ lldb_r15w_x86_64, // Low 16 bits of r15
+ lldb_ah_x86_64,
+ lldb_bh_x86_64,
+ lldb_ch_x86_64,
+ lldb_dh_x86_64,
+ lldb_al_x86_64,
+ lldb_bl_x86_64,
+ lldb_cl_x86_64,
+ lldb_dl_x86_64,
+ lldb_dil_x86_64,
+ lldb_sil_x86_64,
+ lldb_bpl_x86_64,
+ lldb_spl_x86_64,
+ lldb_r8l_x86_64, // Low 8 bits of r8
+ lldb_r9l_x86_64, // Low 8 bits of r9
+ lldb_r10l_x86_64, // Low 8 bits of r10
+ lldb_r11l_x86_64, // Low 8 bits of r11
+ lldb_r12l_x86_64, // Low 8 bits of r12
+ lldb_r13l_x86_64, // Low 8 bits of r13
+ lldb_r14l_x86_64, // Low 8 bits of r14
+ lldb_r15l_x86_64, // Low 8 bits of r15
+ k_last_alias_x86_64 = lldb_r15l_x86_64,
- k_first_avx_x86_64,
- lldb_ymm0_x86_64 = k_first_avx_x86_64,
- lldb_ymm1_x86_64,
- lldb_ymm2_x86_64,
- lldb_ymm3_x86_64,
- lldb_ymm4_x86_64,
- lldb_ymm5_x86_64,
- lldb_ymm6_x86_64,
- lldb_ymm7_x86_64,
- lldb_ymm8_x86_64,
- lldb_ymm9_x86_64,
- lldb_ymm10_x86_64,
- lldb_ymm11_x86_64,
- lldb_ymm12_x86_64,
- lldb_ymm13_x86_64,
- lldb_ymm14_x86_64,
- lldb_ymm15_x86_64,
- k_last_avx_x86_64 = lldb_ymm15_x86_64,
+ k_last_gpr_x86_64 = k_last_alias_x86_64,
- lldb_dr0_x86_64,
- lldb_dr1_x86_64,
- lldb_dr2_x86_64,
- lldb_dr3_x86_64,
- lldb_dr4_x86_64,
- lldb_dr5_x86_64,
- lldb_dr6_x86_64,
- lldb_dr7_x86_64,
+ k_first_fpr_x86_64,
+ lldb_fctrl_x86_64 = k_first_fpr_x86_64,
+ lldb_fstat_x86_64,
+ lldb_ftag_x86_64,
+ lldb_fop_x86_64,
+ lldb_fiseg_x86_64,
+ lldb_fioff_x86_64,
+ lldb_foseg_x86_64,
+ lldb_fooff_x86_64,
+ lldb_mxcsr_x86_64,
+ lldb_mxcsrmask_x86_64,
+ lldb_st0_x86_64,
+ lldb_st1_x86_64,
+ lldb_st2_x86_64,
+ lldb_st3_x86_64,
+ lldb_st4_x86_64,
+ lldb_st5_x86_64,
+ lldb_st6_x86_64,
+ lldb_st7_x86_64,
+ lldb_mm0_x86_64,
+ lldb_mm1_x86_64,
+ lldb_mm2_x86_64,
+ lldb_mm3_x86_64,
+ lldb_mm4_x86_64,
+ lldb_mm5_x86_64,
+ lldb_mm6_x86_64,
+ lldb_mm7_x86_64,
+ lldb_xmm0_x86_64,
+ lldb_xmm1_x86_64,
+ lldb_xmm2_x86_64,
+ lldb_xmm3_x86_64,
+ lldb_xmm4_x86_64,
+ lldb_xmm5_x86_64,
+ lldb_xmm6_x86_64,
+ lldb_xmm7_x86_64,
+ lldb_xmm8_x86_64,
+ lldb_xmm9_x86_64,
+ lldb_xmm10_x86_64,
+ lldb_xmm11_x86_64,
+ lldb_xmm12_x86_64,
+ lldb_xmm13_x86_64,
+ lldb_xmm14_x86_64,
+ lldb_xmm15_x86_64,
+ k_last_fpr_x86_64 = lldb_xmm15_x86_64,
- k_num_registers_x86_64,
- k_num_gpr_registers_x86_64 = k_last_gpr_x86_64 - k_first_gpr_x86_64 + 1,
- k_num_fpr_registers_x86_64 = k_last_fpr_x86_64 - k_first_fpr_x86_64 + 1,
- k_num_avx_registers_x86_64 = k_last_avx_x86_64 - k_first_avx_x86_64 + 1,
- k_num_user_registers_x86_64 = k_num_gpr_registers_x86_64 + k_num_fpr_registers_x86_64 + k_num_avx_registers_x86_64,
- };
+ k_first_avx_x86_64,
+ lldb_ymm0_x86_64 = k_first_avx_x86_64,
+ lldb_ymm1_x86_64,
+ lldb_ymm2_x86_64,
+ lldb_ymm3_x86_64,
+ lldb_ymm4_x86_64,
+ lldb_ymm5_x86_64,
+ lldb_ymm6_x86_64,
+ lldb_ymm7_x86_64,
+ lldb_ymm8_x86_64,
+ lldb_ymm9_x86_64,
+ lldb_ymm10_x86_64,
+ lldb_ymm11_x86_64,
+ lldb_ymm12_x86_64,
+ lldb_ymm13_x86_64,
+ lldb_ymm14_x86_64,
+ lldb_ymm15_x86_64,
+ k_last_avx_x86_64 = lldb_ymm15_x86_64,
+ k_first_mpxr_x86_64,
+ lldb_bnd0_x86_64 = k_first_mpxr_x86_64,
+ lldb_bnd1_x86_64,
+ lldb_bnd2_x86_64,
+ lldb_bnd3_x86_64,
+ k_last_mpxr_x86_64 = lldb_bnd3_x86_64,
+
+ k_first_mpxc_x86_64,
+ lldb_bndcfgu_x86_64 = k_first_mpxc_x86_64,
+ lldb_bndstatus_x86_64,
+ k_last_mpxc_x86_64 = lldb_bndstatus_x86_64,
+
+ lldb_dr0_x86_64,
+ lldb_dr1_x86_64,
+ lldb_dr2_x86_64,
+ lldb_dr3_x86_64,
+ lldb_dr4_x86_64,
+ lldb_dr5_x86_64,
+ lldb_dr6_x86_64,
+ lldb_dr7_x86_64,
+
+ k_num_registers_x86_64,
+ k_num_gpr_registers_x86_64 = k_last_gpr_x86_64 - k_first_gpr_x86_64 + 1,
+ k_num_fpr_registers_x86_64 = k_last_fpr_x86_64 - k_first_fpr_x86_64 + 1,
+ k_num_avx_registers_x86_64 = k_last_avx_x86_64 - k_first_avx_x86_64 + 1,
+ k_num_mpx_registers_x86_64 = k_last_mpxc_x86_64 - k_first_mpxr_x86_64 + 1,
+ k_num_user_registers_x86_64 = k_num_gpr_registers_x86_64 +
+ k_num_fpr_registers_x86_64 +
+ k_num_avx_registers_x86_64 +
+ k_num_mpx_registers_x86_64,
+};
}
#endif // #ifndef lldb_x86_register_enums_h
diff --git a/source/Plugins/Process/Windows/Common/CMakeLists.txt b/source/Plugins/Process/Windows/Common/CMakeLists.txt
index 5a53c3c3300c..9386ed8a0e4c 100644
--- a/source/Plugins/Process/Windows/Common/CMakeLists.txt
+++ b/source/Plugins/Process/Windows/Common/CMakeLists.txt
@@ -2,9 +2,11 @@ include_directories(.)
include_directories(../../Utility)
set(PROC_WINDOWS_COMMON_SOURCES
- RegisterContextWindows.cpp
+ DebuggerThread.cpp
+ LocalDebugDelegate.cpp
ProcessWindows.cpp
ProcessWindowsLog.cpp
+ RegisterContextWindows.cpp
TargetThreadWindows.cpp
)
diff --git a/source/Plugins/Process/Windows/Common/DebuggerThread.cpp b/source/Plugins/Process/Windows/Common/DebuggerThread.cpp
new file mode 100644
index 000000000000..be1462aa6602
--- /dev/null
+++ b/source/Plugins/Process/Windows/Common/DebuggerThread.cpp
@@ -0,0 +1,549 @@
+//===-- DebuggerThread.cpp --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DebuggerThread.h"
+#include "ExceptionRecord.h"
+#include "IDebugDelegate.h"
+
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Host/Predicate.h"
+#include "lldb/Host/ThisThread.h"
+#include "lldb/Host/ThreadLauncher.h"
+#include "lldb/Host/windows/HostProcessWindows.h"
+#include "lldb/Host/windows/HostThreadWindows.h"
+#include "lldb/Host/windows/ProcessLauncherWindows.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/ProcessLaunchInfo.h"
+
+#include "Plugins/Process/Windows/Common/ProcessWindowsLog.h"
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+namespace {
+struct DebugLaunchContext {
+ DebugLaunchContext(DebuggerThread *thread,
+ const ProcessLaunchInfo &launch_info)
+ : m_thread(thread), m_launch_info(launch_info) {}
+ DebuggerThread *m_thread;
+ ProcessLaunchInfo m_launch_info;
+};
+
+struct DebugAttachContext {
+ DebugAttachContext(DebuggerThread *thread, lldb::pid_t pid,
+ const ProcessAttachInfo &attach_info)
+ : m_thread(thread), m_pid(pid), m_attach_info(attach_info) {}
+ DebuggerThread *m_thread;
+ lldb::pid_t m_pid;
+ ProcessAttachInfo m_attach_info;
+};
+}
+
+DebuggerThread::DebuggerThread(DebugDelegateSP debug_delegate)
+ : m_debug_delegate(debug_delegate), m_pid_to_detach(0),
+ m_is_shutting_down(false) {
+ m_debugging_ended_event = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
+}
+
+DebuggerThread::~DebuggerThread() { ::CloseHandle(m_debugging_ended_event); }
+
+Error DebuggerThread::DebugLaunch(const ProcessLaunchInfo &launch_info) {
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS,
+ "DebuggerThread::DebugLaunch launching '%s'",
+ launch_info.GetExecutableFile().GetPath().c_str());
+
+ Error error;
+ DebugLaunchContext *context = new DebugLaunchContext(this, launch_info);
+ HostThread slave_thread(ThreadLauncher::LaunchThread(
+ "lldb.plugin.process-windows.slave[?]", DebuggerThreadLaunchRoutine,
+ context, &error));
+
+ if (!error.Success()) {
+ WINERR_IFALL(WINDOWS_LOG_PROCESS,
+ "DebugLaunch couldn't launch debugger thread. %s",
+ error.AsCString());
+ }
+
+ return error;
+}
+
+Error DebuggerThread::DebugAttach(lldb::pid_t pid,
+ const ProcessAttachInfo &attach_info) {
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS,
+ "DebuggerThread::DebugAttach attaching to '%llu'", pid);
+
+ Error error;
+ DebugAttachContext *context = new DebugAttachContext(this, pid, attach_info);
+ HostThread slave_thread(ThreadLauncher::LaunchThread(
+ "lldb.plugin.process-windows.slave[?]", DebuggerThreadAttachRoutine,
+ context, &error));
+
+ if (!error.Success()) {
+ WINERR_IFALL(WINDOWS_LOG_PROCESS,
+ "DebugAttach couldn't attach to process '%llu'. %s", pid,
+ error.AsCString());
+ }
+
+ return error;
+}
+
+lldb::thread_result_t DebuggerThread::DebuggerThreadLaunchRoutine(void *data) {
+ DebugLaunchContext *context = static_cast<DebugLaunchContext *>(data);
+ lldb::thread_result_t result =
+ context->m_thread->DebuggerThreadLaunchRoutine(context->m_launch_info);
+ delete context;
+ return result;
+}
+
+lldb::thread_result_t DebuggerThread::DebuggerThreadAttachRoutine(void *data) {
+ DebugAttachContext *context = static_cast<DebugAttachContext *>(data);
+ lldb::thread_result_t result = context->m_thread->DebuggerThreadAttachRoutine(
+ context->m_pid, context->m_attach_info);
+ delete context;
+ return result;
+}
+
+lldb::thread_result_t DebuggerThread::DebuggerThreadLaunchRoutine(
+ const ProcessLaunchInfo &launch_info) {
+ // Grab a shared_ptr reference to this so that we know it won't get deleted
+ // until after the
+ // thread routine has exited.
+ std::shared_ptr<DebuggerThread> this_ref(shared_from_this());
+
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS,
+ "DebuggerThread preparing to launch '%s' on background thread.",
+ launch_info.GetExecutableFile().GetPath().c_str());
+
+ Error error;
+ ProcessLauncherWindows launcher;
+ HostProcess process(launcher.LaunchProcess(launch_info, error));
+ // If we couldn't create the process, notify waiters immediately. Otherwise
+ // enter the debug
+ // loop and wait until we get the create process debug notification. Note
+ // that if the process
+ // was created successfully, we can throw away the process handle we got from
+ // CreateProcess
+ // because Windows will give us another (potentially more useful?) handle when
+ // it sends us the
+ // CREATE_PROCESS_DEBUG_EVENT.
+ if (error.Success())
+ DebugLoop();
+ else
+ m_debug_delegate->OnDebuggerError(error, 0);
+
+ return 0;
+}
+
+lldb::thread_result_t DebuggerThread::DebuggerThreadAttachRoutine(
+ lldb::pid_t pid, const ProcessAttachInfo &attach_info) {
+ // Grab a shared_ptr reference to this so that we know it won't get deleted
+ // until after the
+ // thread routine has exited.
+ std::shared_ptr<DebuggerThread> this_ref(shared_from_this());
+
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DebuggerThread preparing to attach to "
+ "process '%llu' on background thread.",
+ pid);
+
+ if (!DebugActiveProcess((DWORD)pid)) {
+ Error error(::GetLastError(), eErrorTypeWin32);
+ m_debug_delegate->OnDebuggerError(error, 0);
+ return 0;
+ }
+
+ // The attach was successful, enter the debug loop. From here on out, this is
+ // no different than
+ // a create process operation, so all the same comments in DebugLaunch should
+ // apply from this
+ // point out.
+ DebugLoop();
+
+ return 0;
+}
+
+Error DebuggerThread::StopDebugging(bool terminate) {
+ Error error;
+
+ lldb::pid_t pid = m_process.GetProcessId();
+
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS,
+ "StopDebugging('%s') called (inferior=%I64u).",
+ (terminate ? "true" : "false"), pid);
+
+ // Set m_is_shutting_down to true if it was false. Return if it was already
+ // true.
+ bool expected = false;
+ if (!m_is_shutting_down.compare_exchange_strong(expected, true))
+ return error;
+
+ // Make a copy of the process, since the termination sequence will reset
+ // DebuggerThread's internal copy and it needs to remain open for the Wait
+ // operation.
+ HostProcess process_copy = m_process;
+ lldb::process_t handle = m_process.GetNativeProcess().GetSystemHandle();
+
+ if (terminate) {
+ // Initiate the termination before continuing the exception, so that the
+ // next debug
+ // event we get is the exit process event, and not some other event.
+ BOOL terminate_suceeded = TerminateProcess(handle, 0);
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS, "StopDebugging called "
+ "TerminateProcess(0x%p, 0) "
+ "(inferior=%I64u), success='%s'",
+ handle, pid, (terminate_suceeded ? "true" : "false"));
+ }
+
+ // If we're stuck waiting for an exception to continue (e.g. the user is at a
+ // breakpoint
+ // messing around in the debugger), continue it now. But only AFTER calling
+ // TerminateProcess
+ // to make sure that the very next call to WaitForDebugEvent is an exit
+ // process event.
+ if (m_active_exception.get()) {
+ WINLOG_IFANY(WINDOWS_LOG_PROCESS | WINDOWS_LOG_EXCEPTION,
+ "StopDebugging masking active exception");
+
+ ContinueAsyncException(ExceptionResult::MaskException);
+ }
+
+ if (!terminate) {
+ // Indicate that we want to detach.
+ m_pid_to_detach = GetProcess().GetProcessId();
+
+ // Force a fresh break so that the detach can happen from the debugger
+ // thread.
+ if (!::DebugBreakProcess(
+ GetProcess().GetNativeProcess().GetSystemHandle())) {
+ error.SetError(::GetLastError(), eErrorTypeWin32);
+ }
+ }
+
+ WINLOG_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "StopDebugging waiting for detach from process %llu to complete.", pid);
+
+ DWORD wait_result = WaitForSingleObject(m_debugging_ended_event, 5000);
+ if (wait_result != WAIT_OBJECT_0) {
+ error.SetError(GetLastError(), eErrorTypeWin32);
+ WINERR_IFALL(WINDOWS_LOG_PROCESS,
+ "StopDebugging WaitForSingleObject(0x%p, 5000) returned %lu",
+ m_debugging_ended_event, wait_result);
+ } else {
+ WINLOG_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "StopDebugging detach from process %llu completed successfully.", pid);
+ }
+
+ if (!error.Success()) {
+ WINERR_IFALL(WINDOWS_LOG_PROCESS, "StopDebugging encountered an error "
+ "while trying to stop process %llu. %s",
+ pid, error.AsCString());
+ }
+ return error;
+}
+
+void DebuggerThread::ContinueAsyncException(ExceptionResult result) {
+ if (!m_active_exception.get())
+ return;
+
+ WINLOG_IFANY(
+ WINDOWS_LOG_PROCESS | WINDOWS_LOG_EXCEPTION,
+ "ContinueAsyncException called for inferior process %I64u, broadcasting.",
+ m_process.GetProcessId());
+
+ m_active_exception.reset();
+ m_exception_pred.SetValue(result, eBroadcastAlways);
+}
+
+void DebuggerThread::FreeProcessHandles() {
+ m_process = HostProcess();
+ m_main_thread = HostThread();
+ if (m_image_file) {
+ ::CloseHandle(m_image_file);
+ m_image_file = nullptr;
+ }
+}
+
+void DebuggerThread::DebugLoop() {
+ DEBUG_EVENT dbe = {};
+ bool should_debug = true;
+ WINLOG_IFALL(WINDOWS_LOG_EVENT, "Entering WaitForDebugEvent loop");
+ while (should_debug) {
+ WINLOGD_IFALL(WINDOWS_LOG_EVENT, "Calling WaitForDebugEvent");
+ BOOL wait_result = WaitForDebugEvent(&dbe, INFINITE);
+ if (wait_result) {
+ DWORD continue_status = DBG_CONTINUE;
+ switch (dbe.dwDebugEventCode) {
+ case EXCEPTION_DEBUG_EVENT: {
+ ExceptionResult status =
+ HandleExceptionEvent(dbe.u.Exception, dbe.dwThreadId);
+
+ if (status == ExceptionResult::MaskException)
+ continue_status = DBG_CONTINUE;
+ else if (status == ExceptionResult::SendToApplication)
+ continue_status = DBG_EXCEPTION_NOT_HANDLED;
+
+ break;
+ }
+ case CREATE_THREAD_DEBUG_EVENT:
+ continue_status =
+ HandleCreateThreadEvent(dbe.u.CreateThread, dbe.dwThreadId);
+ break;
+ case CREATE_PROCESS_DEBUG_EVENT:
+ continue_status =
+ HandleCreateProcessEvent(dbe.u.CreateProcessInfo, dbe.dwThreadId);
+ break;
+ case EXIT_THREAD_DEBUG_EVENT:
+ continue_status =
+ HandleExitThreadEvent(dbe.u.ExitThread, dbe.dwThreadId);
+ break;
+ case EXIT_PROCESS_DEBUG_EVENT:
+ continue_status =
+ HandleExitProcessEvent(dbe.u.ExitProcess, dbe.dwThreadId);
+ should_debug = false;
+ break;
+ case LOAD_DLL_DEBUG_EVENT:
+ continue_status = HandleLoadDllEvent(dbe.u.LoadDll, dbe.dwThreadId);
+ break;
+ case UNLOAD_DLL_DEBUG_EVENT:
+ continue_status = HandleUnloadDllEvent(dbe.u.UnloadDll, dbe.dwThreadId);
+ break;
+ case OUTPUT_DEBUG_STRING_EVENT:
+ continue_status = HandleODSEvent(dbe.u.DebugString, dbe.dwThreadId);
+ break;
+ case RIP_EVENT:
+ continue_status = HandleRipEvent(dbe.u.RipInfo, dbe.dwThreadId);
+ if (dbe.u.RipInfo.dwType == SLE_ERROR)
+ should_debug = false;
+ break;
+ }
+
+ WINLOGD_IFALL(
+ WINDOWS_LOG_EVENT,
+ "DebugLoop calling ContinueDebugEvent(%lu, %lu, %lu) on thread %lu.",
+ dbe.dwProcessId, dbe.dwThreadId, continue_status,
+ ::GetCurrentThreadId());
+
+ ::ContinueDebugEvent(dbe.dwProcessId, dbe.dwThreadId, continue_status);
+
+ if (m_detached) {
+ should_debug = false;
+ }
+ } else {
+ WINERR_IFALL(
+ WINDOWS_LOG_EVENT,
+ "DebugLoop returned FALSE from WaitForDebugEvent. Error = %lu",
+ ::GetLastError());
+
+ should_debug = false;
+ }
+ }
+ FreeProcessHandles();
+
+ WINLOG_IFALL(WINDOWS_LOG_EVENT, "WaitForDebugEvent loop completed, exiting.");
+ SetEvent(m_debugging_ended_event);
+}
+
+ExceptionResult
+DebuggerThread::HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info,
+ DWORD thread_id) {
+ if (m_is_shutting_down) {
+ // A breakpoint that occurs while `m_pid_to_detach` is non-zero is a magic
+ // exception that
+ // we use simply to wake up the DebuggerThread so that we can close out the
+ // debug loop.
+ if (m_pid_to_detach != 0 &&
+ info.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT) {
+ WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_EXCEPTION |
+ WINDOWS_LOG_PROCESS,
+ "Breakpoint exception is cue to detach from process 0x%lx",
+ m_pid_to_detach.load());
+ ::DebugActiveProcessStop(m_pid_to_detach);
+ m_detached = true;
+ }
+
+ // Don't perform any blocking operations while we're shutting down. That
+ // will
+ // cause TerminateProcess -> WaitForSingleObject to time out.
+ return ExceptionResult::SendToApplication;
+ }
+
+ bool first_chance = (info.dwFirstChance != 0);
+
+ m_active_exception.reset(
+ new ExceptionRecord(info.ExceptionRecord, thread_id));
+ WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_EXCEPTION,
+ "HandleExceptionEvent encountered %s chance exception 0x%lx on "
+ "thread 0x%lx",
+ first_chance ? "first" : "second",
+ info.ExceptionRecord.ExceptionCode, thread_id);
+
+ ExceptionResult result =
+ m_debug_delegate->OnDebugException(first_chance, *m_active_exception);
+ m_exception_pred.SetValue(result, eBroadcastNever);
+
+ WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_EXCEPTION,
+ "DebuggerThread::HandleExceptionEvent waiting for ExceptionPred "
+ "!= BreakInDebugger");
+
+ m_exception_pred.WaitForValueNotEqualTo(ExceptionResult::BreakInDebugger,
+ result);
+
+ WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_EXCEPTION,
+ "DebuggerThread::HandleExceptionEvent got ExceptionPred = %u",
+ m_exception_pred.GetValue());
+
+ return result;
+}
+
+DWORD
+DebuggerThread::HandleCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO &info,
+ DWORD thread_id) {
+ WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_THREAD,
+ "HandleCreateThreadEvent Thread 0x%lx spawned in process %llu",
+ thread_id, m_process.GetProcessId());
+ HostThread thread(info.hThread);
+ thread.GetNativeThread().SetOwnsHandle(false);
+ m_debug_delegate->OnCreateThread(thread);
+ return DBG_CONTINUE;
+}
+
+DWORD
+DebuggerThread::HandleCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO &info,
+ DWORD thread_id) {
+ uint32_t process_id = ::GetProcessId(info.hProcess);
+
+ WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_PROCESS,
+ "HandleCreateProcessEvent process %u spawned", process_id);
+
+ std::string thread_name;
+ llvm::raw_string_ostream name_stream(thread_name);
+ name_stream << "lldb.plugin.process-windows.slave[" << process_id << "]";
+ name_stream.flush();
+ ThisThread::SetName(thread_name.c_str());
+
+ // info.hProcess and info.hThread are closed automatically by Windows when
+ // EXIT_PROCESS_DEBUG_EVENT is received.
+ m_process = HostProcess(info.hProcess);
+ ((HostProcessWindows &)m_process.GetNativeProcess()).SetOwnsHandle(false);
+ m_main_thread = HostThread(info.hThread);
+ m_main_thread.GetNativeThread().SetOwnsHandle(false);
+ m_image_file = info.hFile;
+
+ lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfImage);
+ m_debug_delegate->OnDebuggerConnected(load_addr);
+
+ return DBG_CONTINUE;
+}
+
+DWORD
+DebuggerThread::HandleExitThreadEvent(const EXIT_THREAD_DEBUG_INFO &info,
+ DWORD thread_id) {
+ WINLOG_IFANY(
+ WINDOWS_LOG_EVENT | WINDOWS_LOG_THREAD,
+ "HandleExitThreadEvent Thread %lu exited with code %lu in process %llu",
+ thread_id, info.dwExitCode, m_process.GetProcessId());
+ m_debug_delegate->OnExitThread(thread_id, info.dwExitCode);
+ return DBG_CONTINUE;
+}
+
+DWORD
+DebuggerThread::HandleExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO &info,
+ DWORD thread_id) {
+ WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_THREAD,
+ "HandleExitProcessEvent process %llu exited with code %lu",
+ m_process.GetProcessId(), info.dwExitCode);
+
+ m_debug_delegate->OnExitProcess(info.dwExitCode);
+
+ FreeProcessHandles();
+ return DBG_CONTINUE;
+}
+
+DWORD
+DebuggerThread::HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info,
+ DWORD thread_id) {
+ if (info.hFile == nullptr) {
+ // Not sure what this is, so just ignore it.
+ WINWARN_IFALL(WINDOWS_LOG_EVENT, "Inferior %llu - HandleLoadDllEvent has "
+ "a NULL file handle, returning...",
+ m_process.GetProcessId());
+ return DBG_CONTINUE;
+ }
+
+ std::vector<wchar_t> buffer(1);
+ DWORD required_size =
+ GetFinalPathNameByHandleW(info.hFile, &buffer[0], 0, VOLUME_NAME_DOS);
+ if (required_size > 0) {
+ buffer.resize(required_size + 1);
+ required_size = GetFinalPathNameByHandleW(info.hFile, &buffer[0],
+ required_size, VOLUME_NAME_DOS);
+ std::string path_str_utf8;
+ llvm::convertWideToUTF8(buffer.data(), path_str_utf8);
+ llvm::StringRef path_str = path_str_utf8;
+ const char *path = path_str.data();
+ if (path_str.startswith("\\\\?\\"))
+ path += 4;
+
+ FileSpec file_spec(path, false);
+ ModuleSpec module_spec(file_spec);
+ lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll);
+
+ WINLOG_IFALL(WINDOWS_LOG_EVENT, "Inferior %I64u - HandleLoadDllEvent DLL "
+ "'%s' loaded at address 0x%p...",
+ m_process.GetProcessId(), path, info.lpBaseOfDll);
+
+ m_debug_delegate->OnLoadDll(module_spec, load_addr);
+ } else {
+ WINERR_IFALL(WINDOWS_LOG_EVENT, "Inferior %llu - HandleLoadDllEvent Error "
+ "%lu occurred calling "
+ "GetFinalPathNameByHandle",
+ m_process.GetProcessId(), ::GetLastError());
+ }
+ // Windows does not automatically close info.hFile, so we need to do it.
+ ::CloseHandle(info.hFile);
+ return DBG_CONTINUE;
+}
+
+DWORD
+DebuggerThread::HandleUnloadDllEvent(const UNLOAD_DLL_DEBUG_INFO &info,
+ DWORD thread_id) {
+ WINLOG_IFALL(WINDOWS_LOG_EVENT,
+ "HandleUnloadDllEvent process %llu unloading DLL at addr 0x%p.",
+ m_process.GetProcessId(), info.lpBaseOfDll);
+
+ m_debug_delegate->OnUnloadDll(
+ reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll));
+ return DBG_CONTINUE;
+}
+
+DWORD
+DebuggerThread::HandleODSEvent(const OUTPUT_DEBUG_STRING_INFO &info,
+ DWORD thread_id) {
+ return DBG_CONTINUE;
+}
+
+DWORD
+DebuggerThread::HandleRipEvent(const RIP_INFO &info, DWORD thread_id) {
+ WINERR_IFALL(WINDOWS_LOG_EVENT, "HandleRipEvent encountered error %lu "
+ "(type=%lu) in process %llu thread %lu",
+ info.dwError, info.dwType, m_process.GetProcessId(), thread_id);
+
+ Error error(info.dwError, eErrorTypeWin32);
+ m_debug_delegate->OnDebuggerError(error, info.dwType);
+
+ return DBG_CONTINUE;
+}
diff --git a/source/Plugins/Process/Windows/Common/DebuggerThread.h b/source/Plugins/Process/Windows/Common/DebuggerThread.h
new file mode 100644
index 000000000000..ef4b47bab8c7
--- /dev/null
+++ b/source/Plugins/Process/Windows/Common/DebuggerThread.h
@@ -0,0 +1,106 @@
+//===-- DebuggerThread.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Plugins_Process_Windows_DebuggerThread_H_
+#define liblldb_Plugins_Process_Windows_DebuggerThread_H_
+
+#include <atomic>
+#include <memory>
+
+#include "ForwardDecl.h"
+#include "lldb/Host/HostProcess.h"
+#include "lldb/Host/HostThread.h"
+#include "lldb/Host/Predicate.h"
+#include "lldb/Host/windows/windows.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+// DebuggerThread
+//
+// Debugs a single process, notifying listeners as appropriate when interesting
+// things occur.
+//----------------------------------------------------------------------
+class DebuggerThread : public std::enable_shared_from_this<DebuggerThread> {
+public:
+ DebuggerThread(DebugDelegateSP debug_delegate);
+ virtual ~DebuggerThread();
+
+ Error DebugLaunch(const ProcessLaunchInfo &launch_info);
+ Error DebugAttach(lldb::pid_t pid, const ProcessAttachInfo &attach_info);
+
+ HostProcess GetProcess() const { return m_process; }
+ HostThread GetMainThread() const { return m_main_thread; }
+ std::weak_ptr<ExceptionRecord> GetActiveException() {
+ return m_active_exception;
+ }
+
+ Error StopDebugging(bool terminate);
+
+ void ContinueAsyncException(ExceptionResult result);
+
+private:
+ void FreeProcessHandles();
+ void DebugLoop();
+ ExceptionResult HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info,
+ DWORD thread_id);
+ DWORD HandleCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO &info,
+ DWORD thread_id);
+ DWORD HandleCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO &info,
+ DWORD thread_id);
+ DWORD HandleExitThreadEvent(const EXIT_THREAD_DEBUG_INFO &info,
+ DWORD thread_id);
+ DWORD HandleExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO &info,
+ DWORD thread_id);
+ DWORD HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info, DWORD thread_id);
+ DWORD HandleUnloadDllEvent(const UNLOAD_DLL_DEBUG_INFO &info,
+ DWORD thread_id);
+ DWORD HandleODSEvent(const OUTPUT_DEBUG_STRING_INFO &info, DWORD thread_id);
+ DWORD HandleRipEvent(const RIP_INFO &info, DWORD thread_id);
+
+ DebugDelegateSP m_debug_delegate;
+
+ HostProcess m_process; // The process being debugged.
+ HostThread m_main_thread; // The main thread of the inferior.
+
+ // The image file of the process being debugged.
+ HANDLE m_image_file = nullptr;
+
+ // The current exception waiting to be handled
+ ExceptionRecordSP m_active_exception;
+
+ // A predicate which gets signalled when an exception is finished processing
+ // and the debug loop can be continued.
+ Predicate<ExceptionResult> m_exception_pred;
+
+ // An event which gets signalled by the debugger thread when it exits the
+ // debugger loop and is detached from the inferior.
+ HANDLE m_debugging_ended_event = nullptr;
+
+ // Signals the loop to detach from the process (specified by pid).
+ std::atomic<DWORD> m_pid_to_detach;
+
+ // Signals the debug loop to stop processing certain types of events that
+ // block shutdown.
+ std::atomic<bool> m_is_shutting_down;
+
+ // Indicates we've detached from the inferior process and the debug loop can
+ // exit.
+ bool m_detached = false;
+
+ static lldb::thread_result_t DebuggerThreadLaunchRoutine(void *data);
+ lldb::thread_result_t
+ DebuggerThreadLaunchRoutine(const ProcessLaunchInfo &launch_info);
+ static lldb::thread_result_t DebuggerThreadAttachRoutine(void *data);
+ lldb::thread_result_t
+ DebuggerThreadAttachRoutine(lldb::pid_t pid,
+ const ProcessAttachInfo &launch_info);
+};
+}
+#endif
diff --git a/source/Plugins/Process/Windows/Common/ExceptionRecord.h b/source/Plugins/Process/Windows/Common/ExceptionRecord.h
index 79dae3fca4e8..1eec85d52c26 100644
--- a/source/Plugins/Process/Windows/Common/ExceptionRecord.h
+++ b/source/Plugins/Process/Windows/Common/ExceptionRecord.h
@@ -10,15 +10,14 @@
#ifndef liblldb_Plugins_Process_Windows_ExceptionRecord_H_
#define liblldb_Plugins_Process_Windows_ExceptionRecord_H_
-#include "lldb/lldb-forward.h"
#include "lldb/Host/windows/windows.h"
-#include <DbgHelp.h>
+#include "lldb/lldb-forward.h"
+#include <dbghelp.h>
#include <memory>
#include <vector>
-namespace lldb_private
-{
+namespace lldb_private {
//----------------------------------------------------------------------
// ExceptionRecord
@@ -26,73 +25,55 @@ namespace lldb_private
// ExceptionRecord defines an interface which allows implementors to receive
// notification of events that happen in a debugged process.
//----------------------------------------------------------------------
-class ExceptionRecord
-{
- public:
- ExceptionRecord(const EXCEPTION_RECORD &record, lldb::tid_t thread_id)
- {
- m_code = record.ExceptionCode;
- m_continuable = (record.ExceptionFlags == 0);
- if (record.ExceptionRecord)
- m_next_exception.reset(new ExceptionRecord(*record.ExceptionRecord, thread_id));
- m_exception_addr = reinterpret_cast<lldb::addr_t>(record.ExceptionAddress);
- m_thread_id = thread_id;
- m_arguments.assign(record.ExceptionInformation, record.ExceptionInformation + record.NumberParameters);
- }
+class ExceptionRecord {
+public:
+ ExceptionRecord(const EXCEPTION_RECORD &record, lldb::tid_t thread_id) {
+ m_code = record.ExceptionCode;
+ m_continuable = (record.ExceptionFlags == 0);
+ if (record.ExceptionRecord)
+ m_next_exception.reset(
+ new ExceptionRecord(*record.ExceptionRecord, thread_id));
+ m_exception_addr = reinterpret_cast<lldb::addr_t>(record.ExceptionAddress);
+ m_thread_id = thread_id;
+ m_arguments.assign(record.ExceptionInformation,
+ record.ExceptionInformation + record.NumberParameters);
+ }
- // MINIDUMP_EXCEPTIONs are almost identical to EXCEPTION_RECORDs.
- ExceptionRecord(const MINIDUMP_EXCEPTION &record, lldb::tid_t thread_id) :
- m_code(record.ExceptionCode),
- m_continuable(record.ExceptionFlags == 0),
+ // MINIDUMP_EXCEPTIONs are almost identical to EXCEPTION_RECORDs.
+ ExceptionRecord(const MINIDUMP_EXCEPTION &record, lldb::tid_t thread_id)
+ : m_code(record.ExceptionCode), m_continuable(record.ExceptionFlags == 0),
m_next_exception(nullptr),
m_exception_addr(static_cast<lldb::addr_t>(record.ExceptionAddress)),
m_thread_id(thread_id),
- m_arguments(record.ExceptionInformation, record.ExceptionInformation + record.NumberParameters)
- {
- // Set up link to nested exception.
- if (record.ExceptionRecord)
- {
- m_next_exception.reset(new ExceptionRecord(*reinterpret_cast<const MINIDUMP_EXCEPTION *>(record.ExceptionRecord),
- thread_id));
- }
+ m_arguments(record.ExceptionInformation,
+ record.ExceptionInformation + record.NumberParameters) {
+ // Set up link to nested exception.
+ if (record.ExceptionRecord) {
+ m_next_exception.reset(new ExceptionRecord(
+ *reinterpret_cast<const MINIDUMP_EXCEPTION *>(record.ExceptionRecord),
+ thread_id));
}
+ }
- virtual ~ExceptionRecord() {}
+ virtual ~ExceptionRecord() {}
- DWORD
- GetExceptionCode() const
- {
- return m_code;
- }
- bool
- IsContinuable() const
- {
- return m_continuable;
- }
- const ExceptionRecord *
- GetNextException() const
- {
- return m_next_exception.get();
- }
- lldb::addr_t
- GetExceptionAddress() const
- {
- return m_exception_addr;
- }
+ DWORD
+ GetExceptionCode() const { return m_code; }
+ bool IsContinuable() const { return m_continuable; }
+ const ExceptionRecord *GetNextException() const {
+ return m_next_exception.get();
+ }
+ lldb::addr_t GetExceptionAddress() const { return m_exception_addr; }
- lldb::tid_t
- GetThreadID() const
- {
- return m_thread_id;
- }
+ lldb::tid_t GetThreadID() const { return m_thread_id; }
- private:
- DWORD m_code;
- bool m_continuable;
- std::shared_ptr<ExceptionRecord> m_next_exception;
- lldb::addr_t m_exception_addr;
- lldb::tid_t m_thread_id;
- std::vector<ULONG_PTR> m_arguments;
+private:
+ DWORD m_code;
+ bool m_continuable;
+ std::shared_ptr<ExceptionRecord> m_next_exception;
+ lldb::addr_t m_exception_addr;
+ lldb::tid_t m_thread_id;
+ std::vector<ULONG_PTR> m_arguments;
};
}
diff --git a/source/Plugins/Process/Windows/Live/ForwardDecl.h b/source/Plugins/Process/Windows/Common/ForwardDecl.h
index a782597555e1..cfe1b79cee11 100644
--- a/source/Plugins/Process/Windows/Live/ForwardDecl.h
+++ b/source/Plugins/Process/Windows/Common/ForwardDecl.h
@@ -14,17 +14,18 @@
// ExceptionResult is returned by the debug delegate to specify how it processed
// the exception.
-enum class ExceptionResult
-{
- BreakInDebugger, // Break in the debugger and give the user a chance to interact with
- // the program before continuing.
- MaskException, // Eat the exception and don't let the application know it occurred.
- SendToApplication // Send the exception to the application to be handled as if there were
- // no debugger attached.
+enum class ExceptionResult {
+ BreakInDebugger, // Break in the debugger and give the user a chance to
+ // interact with
+ // the program before continuing.
+ MaskException, // Eat the exception and don't let the application know it
+ // occurred.
+ SendToApplication // Send the exception to the application to be handled as if
+ // there were
+ // no debugger attached.
};
-namespace lldb_private
-{
+namespace lldb_private {
class ProcessWindows;
diff --git a/source/Plugins/Process/Windows/Live/IDebugDelegate.h b/source/Plugins/Process/Windows/Common/IDebugDelegate.h
index 6d864de7ed42..e88e0ada053b 100644
--- a/source/Plugins/Process/Windows/Live/IDebugDelegate.h
+++ b/source/Plugins/Process/Windows/Common/IDebugDelegate.h
@@ -15,8 +15,7 @@
#include "lldb/lldb-types.h"
#include <string>
-namespace lldb_private
-{
+namespace lldb_private {
class Error;
class HostThread;
@@ -26,20 +25,21 @@ class HostThread;
// IDebugDelegate defines an interface which allows implementors to receive
// notification of events that happen in a debugged process.
//----------------------------------------------------------------------
-class IDebugDelegate
-{
- public:
- virtual ~IDebugDelegate() {}
+class IDebugDelegate {
+public:
+ virtual ~IDebugDelegate() {}
- virtual void OnExitProcess(uint32_t exit_code) = 0;
- virtual void OnDebuggerConnected(lldb::addr_t image_base) = 0;
- virtual ExceptionResult OnDebugException(bool first_chance, const ExceptionRecord &record) = 0;
- virtual void OnCreateThread(const HostThread &thread) = 0;
- virtual void OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) = 0;
- virtual void OnLoadDll(const ModuleSpec &module_spec, lldb::addr_t module_addr) = 0;
- virtual void OnUnloadDll(lldb::addr_t module_addr) = 0;
- virtual void OnDebugString(const std::string &string) = 0;
- virtual void OnDebuggerError(const Error &error, uint32_t type) = 0;
+ virtual void OnExitProcess(uint32_t exit_code) = 0;
+ virtual void OnDebuggerConnected(lldb::addr_t image_base) = 0;
+ virtual ExceptionResult OnDebugException(bool first_chance,
+ const ExceptionRecord &record) = 0;
+ virtual void OnCreateThread(const HostThread &thread) = 0;
+ virtual void OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) = 0;
+ virtual void OnLoadDll(const ModuleSpec &module_spec,
+ lldb::addr_t module_addr) = 0;
+ virtual void OnUnloadDll(lldb::addr_t module_addr) = 0;
+ virtual void OnDebugString(const std::string &string) = 0;
+ virtual void OnDebuggerError(const Error &error, uint32_t type) = 0;
};
}
diff --git a/source/Plugins/Process/Windows/Common/LocalDebugDelegate.cpp b/source/Plugins/Process/Windows/Common/LocalDebugDelegate.cpp
new file mode 100644
index 000000000000..600aef372505
--- /dev/null
+++ b/source/Plugins/Process/Windows/Common/LocalDebugDelegate.cpp
@@ -0,0 +1,73 @@
+//===-- LocalDebugDelegate.cpp ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LocalDebugDelegate.h"
+#include "ProcessWindows.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+LocalDebugDelegate::LocalDebugDelegate(ProcessWP process)
+ : m_process(process) {}
+
+void LocalDebugDelegate::OnExitProcess(uint32_t exit_code) {
+ if (ProcessWindowsSP process = GetProcessPointer())
+ process->OnExitProcess(exit_code);
+}
+
+void LocalDebugDelegate::OnDebuggerConnected(lldb::addr_t image_base) {
+ if (ProcessWindowsSP process = GetProcessPointer())
+ process->OnDebuggerConnected(image_base);
+}
+
+ExceptionResult
+LocalDebugDelegate::OnDebugException(bool first_chance,
+ const ExceptionRecord &record) {
+ if (ProcessWindowsSP process = GetProcessPointer())
+ return process->OnDebugException(first_chance, record);
+ else
+ return ExceptionResult::MaskException;
+}
+
+void LocalDebugDelegate::OnCreateThread(const HostThread &thread) {
+ if (ProcessWindowsSP process = GetProcessPointer())
+ process->OnCreateThread(thread);
+}
+
+void LocalDebugDelegate::OnExitThread(lldb::tid_t thread_id,
+ uint32_t exit_code) {
+ if (ProcessWindowsSP process = GetProcessPointer())
+ process->OnExitThread(thread_id, exit_code);
+}
+
+void LocalDebugDelegate::OnLoadDll(const lldb_private::ModuleSpec &module_spec,
+ lldb::addr_t module_addr) {
+ if (ProcessWindowsSP process = GetProcessPointer())
+ process->OnLoadDll(module_spec, module_addr);
+}
+
+void LocalDebugDelegate::OnUnloadDll(lldb::addr_t module_addr) {
+ if (ProcessWindowsSP process = GetProcessPointer())
+ process->OnUnloadDll(module_addr);
+}
+
+void LocalDebugDelegate::OnDebugString(const std::string &string) {
+ if (ProcessWindowsSP process = GetProcessPointer())
+ process->OnDebugString(string);
+}
+
+void LocalDebugDelegate::OnDebuggerError(const Error &error, uint32_t type) {
+ if (ProcessWindowsSP process = GetProcessPointer())
+ process->OnDebuggerError(error, type);
+}
+
+ProcessWindowsSP LocalDebugDelegate::GetProcessPointer() {
+ ProcessSP process = m_process.lock();
+ return std::static_pointer_cast<ProcessWindows>(process);
+}
diff --git a/source/Plugins/Process/Windows/Live/LocalDebugDelegate.h b/source/Plugins/Process/Windows/Common/LocalDebugDelegate.h
index ec2f9418142f..819854a1e631 100644
--- a/source/Plugins/Process/Windows/Live/LocalDebugDelegate.h
+++ b/source/Plugins/Process/Windows/Common/LocalDebugDelegate.h
@@ -16,20 +16,19 @@
#include "lldb/lldb-forward.h"
-namespace lldb_private
-{
+namespace lldb_private {
-class ProcessWindowsLive;
-typedef std::shared_ptr<ProcessWindowsLive> ProcessWindowsLiveSP;
+class ProcessWindows;
+typedef std::shared_ptr<ProcessWindows> ProcessWindowsSP;
//----------------------------------------------------------------------
// LocalDebugDelegate
//
-// LocalDebugDelegate creates a connection between a ProcessWindowsLive and the
-// debug driver. This serves to decouple ProcessWindowsLive from the debug driver.
-// It would be possible to get a similar decoupling by just having
-// ProcessWindowsLive implement this interface directly. There are two reasons why
-// we don't do this:
+// LocalDebugDelegate creates a connection between a ProcessWindows and the
+// debug driver. This serves to decouple ProcessWindows from the debug
+// driver. It would be possible to get a similar decoupling by just having
+// ProcessWindows implement this interface directly. There are two reasons
+// why we don't do this:
//
// 1) In the future when we add support for local debugging through LLGS, and we
// go through the Native*Protocol interface, it is likely we will need the
@@ -42,26 +41,26 @@ typedef std::shared_ptr<ProcessWindowsLive> ProcessWindowsLiveSP;
// driver), so this adapter serves as a way to transparently hold the
// ProcessSP while still keeping it decoupled from the driver.
//----------------------------------------------------------------------
-class LocalDebugDelegate : public IDebugDelegate
-{
- public:
- explicit LocalDebugDelegate(lldb::ProcessWP process);
+class LocalDebugDelegate : public IDebugDelegate {
+public:
+ explicit LocalDebugDelegate(lldb::ProcessWP process);
- void OnExitProcess(uint32_t exit_code) override;
- void OnDebuggerConnected(lldb::addr_t image_base) override;
- ExceptionResult OnDebugException(bool first_chance, const ExceptionRecord &record) override;
- void OnCreateThread(const HostThread &thread) override;
- void OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) override;
- void OnLoadDll(const lldb_private::ModuleSpec &module_spec, lldb::addr_t module_addr) override;
- void OnUnloadDll(lldb::addr_t module_addr) override;
- void OnDebugString(const std::string &message) override;
- void OnDebuggerError(const Error &error, uint32_t type) override;
+ void OnExitProcess(uint32_t exit_code) override;
+ void OnDebuggerConnected(lldb::addr_t image_base) override;
+ ExceptionResult OnDebugException(bool first_chance,
+ const ExceptionRecord &record) override;
+ void OnCreateThread(const HostThread &thread) override;
+ void OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) override;
+ void OnLoadDll(const lldb_private::ModuleSpec &module_spec,
+ lldb::addr_t module_addr) override;
+ void OnUnloadDll(lldb::addr_t module_addr) override;
+ void OnDebugString(const std::string &message) override;
+ void OnDebuggerError(const Error &error, uint32_t type) override;
- private:
- ProcessWindowsLiveSP
- GetProcessPointer();
+private:
+ ProcessWindowsSP GetProcessPointer();
- lldb::ProcessWP m_process;
+ lldb::ProcessWP m_process;
};
}
diff --git a/source/Plugins/Process/Windows/Common/NtStructures.h b/source/Plugins/Process/Windows/Common/NtStructures.h
index 6c688d9068d5..6826b98c769e 100644
--- a/source/Plugins/Process/Windows/Common/NtStructures.h
+++ b/source/Plugins/Process/Windows/Common/NtStructures.h
@@ -15,18 +15,17 @@
// This describes the layout of a TEB (Thread Environment Block) for a 64-bit
// process. It's adapted from the 32-bit TEB in winternl.h. Currently, we care
// only about the position of the TlsSlots.
-struct TEB64
-{
- ULONG64 Reserved1[12];
- ULONG64 ProcessEnvironmentBlock;
- ULONG64 Reserved2[399];
- BYTE Reserved3[1952];
- ULONG64 TlsSlots[64];
- BYTE Reserved4[8];
- ULONG64 Reserved5[26];
- ULONG64 ReservedForOle; // Windows 2000 only
- ULONG64 Reserved6[4];
- ULONG64 TlsExpansionSlots;
+struct TEB64 {
+ ULONG64 Reserved1[12];
+ ULONG64 ProcessEnvironmentBlock;
+ ULONG64 Reserved2[399];
+ BYTE Reserved3[1952];
+ ULONG64 TlsSlots[64];
+ BYTE Reserved4[8];
+ ULONG64 Reserved5[26];
+ ULONG64 ReservedForOle; // Windows 2000 only
+ ULONG64 Reserved6[4];
+ ULONG64 TlsExpansionSlots;
};
#endif
diff --git a/source/Plugins/Process/Windows/Common/ProcessWindows.cpp b/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
index 2c3f9fbecf92..50f787f78495 100644
--- a/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
+++ b/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
@@ -9,92 +9,1065 @@
#include "ProcessWindows.h"
+// Windows includes
+#include "lldb/Host/windows/windows.h"
+#include <psapi.h>
+
// Other libraries and framework includes
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/State.h"
+#include "lldb/Host/HostNativeProcessBase.h"
+#include "lldb/Host/HostProcess.h"
+#include "lldb/Host/windows/HostThreadWindows.h"
#include "lldb/Host/windows/windows.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
+#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include "DebuggerThread.h"
+#include "ExceptionRecord.h"
+#include "ForwardDecl.h"
+#include "LocalDebugDelegate.h"
+#include "ProcessWindowsLog.h"
+#include "TargetThreadWindows.h"
+
using namespace lldb;
using namespace lldb_private;
-namespace lldb_private
-{
+namespace {
+std::string GetProcessExecutableName(HANDLE process_handle) {
+ std::vector<wchar_t> file_name;
+ DWORD file_name_size = MAX_PATH; // first guess, not an absolute limit
+ DWORD copied = 0;
+ do {
+ file_name_size *= 2;
+ file_name.resize(file_name_size);
+ copied = ::GetModuleFileNameExW(process_handle, NULL, file_name.data(),
+ file_name_size);
+ } while (copied >= file_name_size);
+ file_name.resize(copied);
+ std::string result;
+ llvm::convertWideToUTF8(file_name.data(), result);
+ return result;
+}
+
+std::string GetProcessExecutableName(DWORD pid) {
+ std::string file_name;
+ HANDLE process_handle =
+ ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
+ if (process_handle != NULL) {
+ file_name = GetProcessExecutableName(process_handle);
+ ::CloseHandle(process_handle);
+ }
+ return file_name;
+}
+
+} // anonymous namespace
+
+namespace lldb_private {
+
+// We store a pointer to this class in the ProcessWindows, so that we don't
+// expose Windows-specific types and implementation details from a public header
+// file.
+class ProcessWindowsData {
+public:
+ ProcessWindowsData(bool stop_at_entry) : m_stop_at_entry(stop_at_entry) {
+ m_initial_stop_event = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
+ }
+
+ ~ProcessWindowsData() { ::CloseHandle(m_initial_stop_event); }
+
+ Error m_launch_error;
+ DebuggerThreadSP m_debugger;
+ StopInfoSP m_pending_stop_info;
+ HANDLE m_initial_stop_event = nullptr;
+ bool m_initial_stop_received = false;
+ bool m_stop_at_entry;
+ std::map<lldb::tid_t, HostThread> m_new_threads;
+ std::set<lldb::tid_t> m_exited_threads;
+};
+
+ProcessSP ProcessWindows::CreateInstance(lldb::TargetSP target_sp,
+ lldb::ListenerSP listener_sp,
+ const FileSpec *) {
+ return ProcessSP(new ProcessWindows(target_sp, listener_sp));
+}
+
+void ProcessWindows::Initialize() {
+ static std::once_flag g_once_flag;
+
+ std::call_once(g_once_flag, []() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
+ });
+}
+
+void ProcessWindows::Terminate() {}
+
+lldb_private::ConstString ProcessWindows::GetPluginNameStatic() {
+ static ConstString g_name("windows");
+ return g_name;
+}
+
+const char *ProcessWindows::GetPluginDescriptionStatic() {
+ return "Process plugin for Windows";
+}
//------------------------------------------------------------------------------
// Constructors and destructors.
-ProcessWindows::ProcessWindows(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)
- : lldb_private::Process(target_sp, listener_sp)
-{
+ProcessWindows::ProcessWindows(lldb::TargetSP target_sp,
+ lldb::ListenerSP listener_sp)
+ : lldb_private::Process(target_sp, listener_sp) {}
+
+ProcessWindows::~ProcessWindows() {}
+
+size_t ProcessWindows::GetSTDOUT(char *buf, size_t buf_size, Error &error) {
+ error.SetErrorString("GetSTDOUT unsupported on Windows");
+ return 0;
}
-ProcessWindows::~ProcessWindows()
-{
+size_t ProcessWindows::GetSTDERR(char *buf, size_t buf_size, Error &error) {
+ error.SetErrorString("GetSTDERR unsupported on Windows");
+ return 0;
}
-size_t
-ProcessWindows::GetSTDOUT(char *buf, size_t buf_size, Error &error)
-{
- error.SetErrorString("GetSTDOUT unsupported on Windows");
- return 0;
+size_t ProcessWindows::PutSTDIN(const char *buf, size_t buf_size,
+ Error &error) {
+ error.SetErrorString("PutSTDIN unsupported on Windows");
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+// ProcessInterface protocol.
+
+lldb_private::ConstString ProcessWindows::GetPluginName() {
+ return GetPluginNameStatic();
+}
+
+uint32_t ProcessWindows::GetPluginVersion() { return 1; }
+
+Error ProcessWindows::EnableBreakpointSite(BreakpointSite *bp_site) {
+ WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS,
+ "EnableBreakpointSite called with bp_site 0x%p "
+ "(id=%d, addr=0x%llx)",
+ bp_site, bp_site->GetID(), bp_site->GetLoadAddress());
+
+ Error error = EnableSoftwareBreakpoint(bp_site);
+ if (!error.Success()) {
+ WINERR_IFALL(WINDOWS_LOG_BREAKPOINTS, "EnableBreakpointSite failed. %s",
+ error.AsCString());
+ }
+ return error;
+}
+
+Error ProcessWindows::DisableBreakpointSite(BreakpointSite *bp_site) {
+ WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS,
+ "DisableBreakpointSite called with bp_site 0x%p "
+ "(id=%d, addr=0x%llx)",
+ bp_site, bp_site->GetID(), bp_site->GetLoadAddress());
+
+ Error error = DisableSoftwareBreakpoint(bp_site);
+
+ if (!error.Success()) {
+ WINERR_IFALL(WINDOWS_LOG_BREAKPOINTS, "DisableBreakpointSite failed. %s",
+ error.AsCString());
+ }
+ return error;
+}
+
+Error ProcessWindows::DoDetach(bool keep_stopped) {
+ DebuggerThreadSP debugger_thread;
+ StateType private_state;
+ {
+ // Acquire the lock only long enough to get the DebuggerThread.
+ // StopDebugging() will trigger a call back into ProcessWindows which
+ // will also acquire the lock. Thus we have to release the lock before
+ // calling StopDebugging().
+ llvm::sys::ScopedLock lock(m_mutex);
+
+ private_state = GetPrivateState();
+
+ if (!m_session_data) {
+ WINWARN_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "DoDetach called while state = %u, but there is no active session.",
+ private_state);
+ return Error();
+ }
+
+ debugger_thread = m_session_data->m_debugger;
+ }
+
+ Error error;
+ if (private_state != eStateExited && private_state != eStateDetached) {
+ WINLOG_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "DoDetach called for process %p while state = %d. Detaching...",
+ debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(),
+ private_state);
+ error = debugger_thread->StopDebugging(false);
+ if (error.Success()) {
+ SetPrivateState(eStateDetached);
+ }
+
+ // By the time StopDebugging returns, there is no more debugger thread, so
+ // we can be assured that no other thread will race for the session data.
+ m_session_data.reset();
+ } else {
+ WINERR_IFALL(
+ WINDOWS_LOG_PROCESS, "DoDetach called for process %p while state = "
+ "%d, but cannot destroy in this state.",
+ debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(),
+ private_state);
+ }
+
+ return error;
+}
+
+Error ProcessWindows::DoLaunch(Module *exe_module,
+ ProcessLaunchInfo &launch_info) {
+ // Even though m_session_data is accessed here, it is before a debugger thread
+ // has been
+ // kicked off. So there's no race conditions, and it shouldn't be necessary
+ // to acquire
+ // the mutex.
+
+ Error result;
+ if (!launch_info.GetFlags().Test(eLaunchFlagDebug)) {
+ StreamString stream;
+ stream.Printf("ProcessWindows unable to launch '%s'. ProcessWindows can "
+ "only be used for debug launches.",
+ launch_info.GetExecutableFile().GetPath().c_str());
+ std::string message = stream.GetString();
+ result.SetErrorString(message.c_str());
+
+ WINERR_IFALL(WINDOWS_LOG_PROCESS, "%s", message.c_str());
+ return result;
+ }
+
+ bool stop_at_entry = launch_info.GetFlags().Test(eLaunchFlagStopAtEntry);
+ m_session_data.reset(new ProcessWindowsData(stop_at_entry));
+
+ SetPrivateState(eStateLaunching);
+ DebugDelegateSP delegate(new LocalDebugDelegate(shared_from_this()));
+ m_session_data->m_debugger.reset(new DebuggerThread(delegate));
+ DebuggerThreadSP debugger = m_session_data->m_debugger;
+
+ // Kick off the DebugLaunch asynchronously and wait for it to complete.
+ result = debugger->DebugLaunch(launch_info);
+ if (result.Fail()) {
+ WINERR_IFALL(WINDOWS_LOG_PROCESS, "DoLaunch failed launching '%s'. %s",
+ launch_info.GetExecutableFile().GetPath().c_str(),
+ result.AsCString());
+ return result;
+ }
+
+ HostProcess process;
+ Error error = WaitForDebuggerConnection(debugger, process);
+ if (error.Fail()) {
+ WINERR_IFALL(WINDOWS_LOG_PROCESS, "DoLaunch failed launching '%s'. %s",
+ launch_info.GetExecutableFile().GetPath().c_str(),
+ error.AsCString());
+ return error;
+ }
+
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DoLaunch successfully launched '%s'",
+ launch_info.GetExecutableFile().GetPath().c_str());
+
+ // We've hit the initial stop. If eLaunchFlagsStopAtEntry was specified, the
+ // private state
+ // should already be set to eStateStopped as a result of hitting the initial
+ // breakpoint. If
+ // it was not set, the breakpoint should have already been resumed from and
+ // the private state
+ // should already be eStateRunning.
+ launch_info.SetProcessID(process.GetProcessId());
+ SetID(process.GetProcessId());
+
+ return result;
+}
+
+Error ProcessWindows::DoAttachToProcessWithID(
+ lldb::pid_t pid, const ProcessAttachInfo &attach_info) {
+ m_session_data.reset(
+ new ProcessWindowsData(!attach_info.GetContinueOnceAttached()));
+
+ DebugDelegateSP delegate(new LocalDebugDelegate(shared_from_this()));
+ DebuggerThreadSP debugger(new DebuggerThread(delegate));
+
+ m_session_data->m_debugger = debugger;
+
+ DWORD process_id = static_cast<DWORD>(pid);
+ Error error = debugger->DebugAttach(process_id, attach_info);
+ if (error.Fail()) {
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DoAttachToProcessWithID encountered an "
+ "error occurred initiating the "
+ "asynchronous attach. %s",
+ error.AsCString());
+ return error;
+ }
+
+ HostProcess process;
+ error = WaitForDebuggerConnection(debugger, process);
+ if (error.Fail()) {
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DoAttachToProcessWithID encountered an "
+ "error waiting for the debugger to "
+ "connect. %s",
+ error.AsCString());
+ return error;
+ }
+
+ WINLOG_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "DoAttachToProcessWithID successfully attached to process with pid=%lu",
+ process_id);
+
+ // We've hit the initial stop. If eLaunchFlagsStopAtEntry was specified, the
+ // private state
+ // should already be set to eStateStopped as a result of hitting the initial
+ // breakpoint. If
+ // it was not set, the breakpoint should have already been resumed from and
+ // the private state
+ // should already be eStateRunning.
+ SetID(process.GetProcessId());
+ return error;
+}
+
+Error ProcessWindows::DoResume() {
+ llvm::sys::ScopedLock lock(m_mutex);
+ Error error;
+
+ StateType private_state = GetPrivateState();
+ if (private_state == eStateStopped || private_state == eStateCrashed) {
+ WINLOG_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "DoResume called for process %I64u while state is %u. Resuming...",
+ m_session_data->m_debugger->GetProcess().GetProcessId(),
+ GetPrivateState());
+
+ ExceptionRecordSP active_exception =
+ m_session_data->m_debugger->GetActiveException().lock();
+ if (active_exception) {
+ // Resume the process and continue processing debug events. Mask
+ // the exception so that from the process's view, there is no
+ // indication that anything happened.
+ m_session_data->m_debugger->ContinueAsyncException(
+ ExceptionResult::MaskException);
+ }
+
+ WINLOG_IFANY(WINDOWS_LOG_PROCESS | WINDOWS_LOG_THREAD,
+ "DoResume resuming %u threads.", m_thread_list.GetSize());
+
+ for (uint32_t i = 0; i < m_thread_list.GetSize(); ++i) {
+ auto thread = std::static_pointer_cast<TargetThreadWindows>(
+ m_thread_list.GetThreadAtIndex(i));
+ thread->DoResume();
+ }
+
+ SetPrivateState(eStateRunning);
+ } else {
+ WINERR_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "DoResume called for process %I64u but state is %u. Returning...",
+ m_session_data->m_debugger->GetProcess().GetProcessId(),
+ GetPrivateState());
+ }
+ return error;
+}
+
+Error ProcessWindows::DoDestroy() {
+ DebuggerThreadSP debugger_thread;
+ StateType private_state;
+ {
+ // Acquire this lock inside an inner scope, only long enough to get the
+ // DebuggerThread.
+ // StopDebugging() will trigger a call back into ProcessWindows which will
+ // acquire the lock
+ // again, so we need to not deadlock.
+ llvm::sys::ScopedLock lock(m_mutex);
+
+ private_state = GetPrivateState();
+
+ if (!m_session_data) {
+ WINWARN_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "DoDestroy called while state = %u, but there is no active session.",
+ private_state);
+ return Error();
+ }
+
+ debugger_thread = m_session_data->m_debugger;
+ }
+
+ Error error;
+ if (private_state != eStateExited && private_state != eStateDetached) {
+ WINLOG_IFALL(
+ WINDOWS_LOG_PROCESS, "DoDestroy called for process %p while state = "
+ "%u. Shutting down...",
+ debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(),
+ private_state);
+ error = debugger_thread->StopDebugging(true);
+
+ // By the time StopDebugging returns, there is no more debugger thread, so
+ // we can be assured that no other thread will race for the session data.
+ m_session_data.reset();
+ } else {
+ WINERR_IFALL(
+ WINDOWS_LOG_PROCESS, "DoDestroy called for process %p while state = "
+ "%d, but cannot destroy in this state.",
+ debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(),
+ private_state);
+ }
+
+ return error;
+}
+
+Error ProcessWindows::DoHalt(bool &caused_stop) {
+ Error error;
+ StateType state = GetPrivateState();
+ if (state == eStateStopped)
+ caused_stop = false;
+ else {
+ llvm::sys::ScopedLock lock(m_mutex);
+ caused_stop = ::DebugBreakProcess(m_session_data->m_debugger->GetProcess()
+ .GetNativeProcess()
+ .GetSystemHandle());
+ if (!caused_stop) {
+ error.SetError(::GetLastError(), eErrorTypeWin32);
+ WINERR_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "DoHalt called DebugBreakProcess, but it failed with error %u",
+ error.GetError());
+ }
+ }
+ return error;
}
-size_t
-ProcessWindows::GetSTDERR(char *buf, size_t buf_size, Error &error)
-{
- error.SetErrorString("GetSTDERR unsupported on Windows");
+void ProcessWindows::DidLaunch() {
+ ArchSpec arch_spec;
+ DidAttach(arch_spec);
+}
+
+void ProcessWindows::DidAttach(ArchSpec &arch_spec) {
+ llvm::sys::ScopedLock lock(m_mutex);
+
+ // The initial stop won't broadcast the state change event, so account for
+ // that here.
+ if (m_session_data && GetPrivateState() == eStateStopped &&
+ m_session_data->m_stop_at_entry)
+ RefreshStateAfterStop();
+}
+
+void ProcessWindows::RefreshStateAfterStop() {
+ llvm::sys::ScopedLock lock(m_mutex);
+
+ if (!m_session_data) {
+ WINWARN_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "RefreshStateAfterStop called with no active session. Returning...");
+ return;
+ }
+
+ m_thread_list.RefreshStateAfterStop();
+
+ std::weak_ptr<ExceptionRecord> exception_record =
+ m_session_data->m_debugger->GetActiveException();
+ ExceptionRecordSP active_exception = exception_record.lock();
+ if (!active_exception) {
+ WINERR_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "RefreshStateAfterStop called for process %I64u but there is no "
+ "active exception. Why is the process stopped?",
+ m_session_data->m_debugger->GetProcess().GetProcessId());
+ return;
+ }
+
+ StopInfoSP stop_info;
+ m_thread_list.SetSelectedThreadByID(active_exception->GetThreadID());
+ ThreadSP stop_thread = m_thread_list.GetSelectedThread();
+ if (!stop_thread)
+ return;
+
+ switch (active_exception->GetExceptionCode()) {
+ case EXCEPTION_SINGLE_STEP: {
+ RegisterContextSP register_context = stop_thread->GetRegisterContext();
+ const uint64_t pc = register_context->GetPC();
+ BreakpointSiteSP site(GetBreakpointSiteList().FindByAddress(pc));
+ if (site && site->ValidForThisThread(stop_thread.get())) {
+ WINLOG_IFANY(WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION |
+ WINDOWS_LOG_STEP,
+ "Single-stepped onto a breakpoint in process %I64u at "
+ "address 0x%I64x with breakpoint site %d",
+ m_session_data->m_debugger->GetProcess().GetProcessId(), pc,
+ site->GetID());
+ stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(*stop_thread,
+ site->GetID());
+ stop_thread->SetStopInfo(stop_info);
+ } else {
+ WINLOG_IFANY(WINDOWS_LOG_EXCEPTION | WINDOWS_LOG_STEP,
+ "RefreshStateAfterStop single stepping thread %llu",
+ stop_thread->GetID());
+ stop_info = StopInfo::CreateStopReasonToTrace(*stop_thread);
+ stop_thread->SetStopInfo(stop_info);
+ }
+ return;
+ }
+
+ case EXCEPTION_BREAKPOINT: {
+ RegisterContextSP register_context = stop_thread->GetRegisterContext();
+
+ // The current EIP is AFTER the BP opcode, which is one byte.
+ uint64_t pc = register_context->GetPC() - 1;
+
+ BreakpointSiteSP site(GetBreakpointSiteList().FindByAddress(pc));
+ if (site) {
+ WINLOG_IFANY(
+ WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION,
+ "RefreshStateAfterStop detected breakpoint in process %I64u at "
+ "address 0x%I64x with breakpoint site %d",
+ m_session_data->m_debugger->GetProcess().GetProcessId(), pc,
+ site->GetID());
+
+ if (site->ValidForThisThread(stop_thread.get())) {
+ WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION,
+ "Breakpoint site %d is valid for this thread (0x%I64x), "
+ "creating stop info.",
+ site->GetID(), stop_thread->GetID());
+
+ stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(
+ *stop_thread, site->GetID());
+ register_context->SetPC(pc);
+ } else {
+ WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION,
+ "Breakpoint site %d is not valid for this thread, "
+ "creating empty stop info.",
+ site->GetID());
+ }
+ stop_thread->SetStopInfo(stop_info);
+ return;
+ } else {
+ // The thread hit a hard-coded breakpoint like an `int 3` or
+ // `__debugbreak()`.
+ WINLOG_IFALL(
+ WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION,
+ "No breakpoint site matches for this thread. __debugbreak()? "
+ "Creating stop info with the exception.");
+ // FALLTHROUGH: We'll treat this as a generic exception record in the
+ // default case.
+ }
+ }
+
+ default: {
+ std::string desc;
+ llvm::raw_string_ostream desc_stream(desc);
+ desc_stream << "Exception "
+ << llvm::format_hex(active_exception->GetExceptionCode(), 8)
+ << " encountered at address "
+ << llvm::format_hex(active_exception->GetExceptionAddress(), 8);
+ stop_info = StopInfo::CreateStopReasonWithException(
+ *stop_thread, desc_stream.str().c_str());
+ stop_thread->SetStopInfo(stop_info);
+ WINLOG_IFALL(WINDOWS_LOG_EXCEPTION, "%s", desc_stream.str().c_str());
+ return;
+ }
+ }
+}
+
+bool ProcessWindows::CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) {
+ if (plugin_specified_by_name)
+ return true;
+
+ // 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();
+ // However, if there is no executable module, we return true since we might be
+ // preparing to attach.
+ return true;
+}
+
+bool ProcessWindows::UpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) {
+ // Add all the threads that were previously running and for which we did not
+ // detect a thread exited event.
+ int new_size = 0;
+ int continued_threads = 0;
+ int exited_threads = 0;
+ int new_threads = 0;
+
+ for (ThreadSP old_thread : old_thread_list.Threads()) {
+ lldb::tid_t old_thread_id = old_thread->GetID();
+ auto exited_thread_iter =
+ m_session_data->m_exited_threads.find(old_thread_id);
+ if (exited_thread_iter == m_session_data->m_exited_threads.end()) {
+ new_thread_list.AddThread(old_thread);
+ ++new_size;
+ ++continued_threads;
+ WINLOGV_IFALL(
+ WINDOWS_LOG_THREAD,
+ "UpdateThreadList - Thread %llu was running and is still running.",
+ old_thread_id);
+ } else {
+ WINLOGV_IFALL(
+ WINDOWS_LOG_THREAD,
+ "UpdateThreadList - Thread %llu was running and has exited.",
+ old_thread_id);
+ ++exited_threads;
+ }
+ }
+
+ // Also add all the threads that are new since the last time we broke into the
+ // debugger.
+ for (const auto &thread_info : m_session_data->m_new_threads) {
+ ThreadSP thread(new TargetThreadWindows(*this, thread_info.second));
+ thread->SetID(thread_info.first);
+ new_thread_list.AddThread(thread);
+ ++new_size;
+ ++new_threads;
+ WINLOGV_IFALL(WINDOWS_LOG_THREAD,
+ "UpdateThreadList - Thread %llu is new since last update.",
+ thread_info.first);
+ }
+
+ WINLOG_IFALL(
+ WINDOWS_LOG_THREAD,
+ "UpdateThreadList - %d new threads, %d old threads, %d exited threads.",
+ new_threads, continued_threads, exited_threads);
+
+ m_session_data->m_new_threads.clear();
+ m_session_data->m_exited_threads.clear();
+
+ return new_size > 0;
+}
+
+bool ProcessWindows::IsAlive() {
+ StateType state = GetPrivateState();
+ switch (state) {
+ case eStateCrashed:
+ case eStateDetached:
+ case eStateUnloaded:
+ case eStateExited:
+ case eStateInvalid:
+ return false;
+ default:
+ return true;
+ }
+}
+
+size_t ProcessWindows::DoReadMemory(lldb::addr_t vm_addr, void *buf,
+ size_t size, Error &error) {
+ llvm::sys::ScopedLock lock(m_mutex);
+
+ if (!m_session_data)
return 0;
+
+ WINLOG_IFALL(WINDOWS_LOG_MEMORY,
+ "DoReadMemory attempting to read %u bytes from address 0x%I64x",
+ size, vm_addr);
+
+ HostProcess process = m_session_data->m_debugger->GetProcess();
+ void *addr = reinterpret_cast<void *>(vm_addr);
+ SIZE_T bytes_read = 0;
+ if (!ReadProcessMemory(process.GetNativeProcess().GetSystemHandle(), addr,
+ buf, size, &bytes_read)) {
+ error.SetError(GetLastError(), eErrorTypeWin32);
+ WINERR_IFALL(WINDOWS_LOG_MEMORY, "DoReadMemory failed with error code %u",
+ error.GetError());
+ }
+ return bytes_read;
}
-size_t
-ProcessWindows::PutSTDIN(const char *buf, size_t buf_size, Error &error)
-{
- error.SetErrorString("PutSTDIN unsupported on Windows");
+size_t ProcessWindows::DoWriteMemory(lldb::addr_t vm_addr, const void *buf,
+ size_t size, Error &error) {
+ llvm::sys::ScopedLock lock(m_mutex);
+ WINLOG_IFALL(
+ WINDOWS_LOG_MEMORY,
+ "DoWriteMemory attempting to write %u bytes into address 0x%I64x", size,
+ vm_addr);
+
+ if (!m_session_data) {
+ WINERR_IFANY(
+ WINDOWS_LOG_MEMORY,
+ "DoWriteMemory cannot write, there is no active debugger connection.");
return 0;
+ }
+
+ HostProcess process = m_session_data->m_debugger->GetProcess();
+ void *addr = reinterpret_cast<void *>(vm_addr);
+ SIZE_T bytes_written = 0;
+ lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
+ if (WriteProcessMemory(handle, addr, buf, size, &bytes_written))
+ FlushInstructionCache(handle, addr, bytes_written);
+ else {
+ error.SetError(GetLastError(), eErrorTypeWin32);
+ WINLOG_IFALL(WINDOWS_LOG_MEMORY, "DoWriteMemory failed with error code %u",
+ error.GetError());
+ }
+ return bytes_written;
}
-//------------------------------------------------------------------------------
-// ProcessInterface protocol.
+#define BOOL_STR(b) ((b) ? "true" : "false")
+
+Error ProcessWindows::GetMemoryRegionInfo(lldb::addr_t vm_addr,
+ MemoryRegionInfo &info) {
+ Error error;
+ llvm::sys::ScopedLock lock(m_mutex);
+ info.Clear();
+
+ if (!m_session_data) {
+ error.SetErrorString(
+ "GetMemoryRegionInfo called with no debugging session.");
+ WINERR_IFALL(WINDOWS_LOG_MEMORY, "%s", error.AsCString());
+ return error;
+ }
+ HostProcess process = m_session_data->m_debugger->GetProcess();
+ lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
+ if (handle == nullptr || handle == LLDB_INVALID_PROCESS) {
+ error.SetErrorString(
+ "GetMemoryRegionInfo called with an invalid target process.");
+ WINERR_IFALL(WINDOWS_LOG_MEMORY, "%s", error.AsCString());
+ return error;
+ }
+
+ WINLOG_IFALL(WINDOWS_LOG_MEMORY,
+ "GetMemoryRegionInfo getting info for address 0x%I64x", vm_addr);
+
+ void *addr = reinterpret_cast<void *>(vm_addr);
+ MEMORY_BASIC_INFORMATION mem_info = {};
+ SIZE_T result = ::VirtualQueryEx(handle, addr, &mem_info, sizeof(mem_info));
+ if (result == 0) {
+ if (::GetLastError() == ERROR_INVALID_PARAMETER) {
+ // ERROR_INVALID_PARAMETER is returned if VirtualQueryEx is called with an
+ // address
+ // past the highest accessible address. We should return a range from the
+ // vm_addr
+ // to LLDB_INVALID_ADDRESS
+ info.GetRange().SetRangeBase(vm_addr);
+ info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
+ info.SetReadable(MemoryRegionInfo::eNo);
+ info.SetExecutable(MemoryRegionInfo::eNo);
+ info.SetWritable(MemoryRegionInfo::eNo);
+ info.SetMapped(MemoryRegionInfo::eNo);
+ return error;
+ } else {
+ error.SetError(::GetLastError(), eErrorTypeWin32);
+ WINERR_IFALL(WINDOWS_LOG_MEMORY, "VirtualQueryEx returned error %u while "
+ "getting memory region info for address "
+ "0x%I64x",
+ error.GetError(), vm_addr);
+ return error;
+ }
+ }
+ // Protect bits are only valid for MEM_COMMIT regions.
+ if (mem_info.State == MEM_COMMIT) {
+ const bool readable = IsPageReadable(mem_info.Protect);
+ const bool executable = IsPageExecutable(mem_info.Protect);
+ const bool writable = IsPageWritable(mem_info.Protect);
+ info.SetReadable(readable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
+ info.SetExecutable(executable ? MemoryRegionInfo::eYes
+ : MemoryRegionInfo::eNo);
+ info.SetWritable(writable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
+ } else {
+ info.SetReadable(MemoryRegionInfo::eNo);
+ info.SetExecutable(MemoryRegionInfo::eNo);
+ info.SetWritable(MemoryRegionInfo::eNo);
+ }
-lldb::addr_t
-ProcessWindows::GetImageInfoAddress()
-{
- Target &target = GetTarget();
- ObjectFile *obj_file = target.GetExecutableModule()->GetObjectFile();
- Address addr = obj_file->GetImageInfoAddress(&target);
- if (addr.IsValid())
- return addr.GetLoadAddress(&target);
+ // AllocationBase is defined for MEM_COMMIT and MEM_RESERVE but not MEM_FREE.
+ if (mem_info.State != MEM_FREE) {
+ info.GetRange().SetRangeBase(
+ reinterpret_cast<addr_t>(mem_info.AllocationBase));
+ info.GetRange().SetRangeEnd(reinterpret_cast<addr_t>(mem_info.BaseAddress) +
+ mem_info.RegionSize);
+ info.SetMapped(MemoryRegionInfo::eYes);
+ } else {
+ // In the unmapped case we need to return the distance to the next block of
+ // memory.
+ // VirtualQueryEx nearly does that except that it gives the distance from
+ // the start
+ // of the page containing vm_addr.
+ SYSTEM_INFO data;
+ GetSystemInfo(&data);
+ DWORD page_offset = vm_addr % data.dwPageSize;
+ info.GetRange().SetRangeBase(vm_addr);
+ info.GetRange().SetByteSize(mem_info.RegionSize - page_offset);
+ info.SetMapped(MemoryRegionInfo::eNo);
+ }
+
+ error.SetError(::GetLastError(), eErrorTypeWin32);
+ WINLOGV_IFALL(WINDOWS_LOG_MEMORY, "Memory region info for address %llu: "
+ "readable=%s, executable=%s, writable=%s",
+ vm_addr, BOOL_STR(info.GetReadable()),
+ BOOL_STR(info.GetExecutable()), BOOL_STR(info.GetWritable()));
+ return error;
+}
+
+lldb::addr_t ProcessWindows::GetImageInfoAddress() {
+ Target &target = GetTarget();
+ ObjectFile *obj_file = target.GetExecutableModule()->GetObjectFile();
+ Address addr = obj_file->GetImageInfoAddress(&target);
+ if (addr.IsValid())
+ return addr.GetLoadAddress(&target);
+ else
+ return LLDB_INVALID_ADDRESS;
+}
+
+void ProcessWindows::OnExitProcess(uint32_t exit_code) {
+ // No need to acquire the lock since m_session_data isn't accessed.
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS, "Process %llu exited with code %u", GetID(),
+ exit_code);
+
+ TargetSP target = m_target_sp.lock();
+ if (target) {
+ ModuleSP executable_module = target->GetExecutableModule();
+ ModuleList unloaded_modules;
+ unloaded_modules.Append(executable_module);
+ target->ModulesDidUnload(unloaded_modules, true);
+ }
+
+ SetProcessExitStatus(GetID(), true, 0, exit_code);
+ SetPrivateState(eStateExited);
+}
+
+void ProcessWindows::OnDebuggerConnected(lldb::addr_t image_base) {
+ DebuggerThreadSP debugger = m_session_data->m_debugger;
+
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS,
+ "Debugger connected to process %I64u. Image base = 0x%I64x",
+ debugger->GetProcess().GetProcessId(), image_base);
+
+ ModuleSP module = GetTarget().GetExecutableModule();
+ if (!module) {
+ // During attach, we won't have the executable module, so find it now.
+ const DWORD pid = debugger->GetProcess().GetProcessId();
+ const std::string file_name = GetProcessExecutableName(pid);
+ if (file_name.empty()) {
+ return;
+ }
+
+ FileSpec executable_file(file_name, true);
+ ModuleSpec module_spec(executable_file);
+ Error error;
+ module = GetTarget().GetSharedModule(module_spec, &error);
+ if (!module) {
+ return;
+ }
+
+ GetTarget().SetExecutableModule(module, false);
+ }
+
+ bool load_addr_changed;
+ module->SetLoadAddress(GetTarget(), image_base, false, load_addr_changed);
+
+ ModuleList loaded_modules;
+ loaded_modules.Append(module);
+ GetTarget().ModulesDidLoad(loaded_modules);
+
+ // Add the main executable module to the list of pending module loads. We
+ // can't call
+ // GetTarget().ModulesDidLoad() here because we still haven't returned from
+ // DoLaunch() / DoAttach() yet
+ // so the target may not have set the process instance to `this` yet.
+ llvm::sys::ScopedLock lock(m_mutex);
+ const HostThreadWindows &wmain_thread =
+ debugger->GetMainThread().GetNativeThread();
+ m_session_data->m_new_threads[wmain_thread.GetThreadId()] =
+ debugger->GetMainThread();
+}
+
+ExceptionResult
+ProcessWindows::OnDebugException(bool first_chance,
+ const ExceptionRecord &record) {
+ llvm::sys::ScopedLock lock(m_mutex);
+
+ // FIXME: Without this check, occasionally when running the test suite there
+ // is
+ // an issue where m_session_data can be null. It's not clear how this could
+ // happen
+ // but it only surfaces while running the test suite. In order to properly
+ // diagnose
+ // this, we probably need to first figure allow the test suite to print out
+ // full
+ // lldb logs, and then add logging to the process plugin.
+ if (!m_session_data) {
+ WINERR_IFANY(WINDOWS_LOG_EXCEPTION, "Debugger thread reported exception "
+ "0x%lx at address 0x%llu, but there is "
+ "no session.",
+ record.GetExceptionCode(), record.GetExceptionAddress());
+ return ExceptionResult::SendToApplication;
+ }
+
+ if (!first_chance) {
+ // Any second chance exception is an application crash by definition.
+ SetPrivateState(eStateCrashed);
+ }
+
+ ExceptionResult result = ExceptionResult::SendToApplication;
+ switch (record.GetExceptionCode()) {
+ case EXCEPTION_BREAKPOINT:
+ // Handle breakpoints at the first chance.
+ result = ExceptionResult::BreakInDebugger;
+
+ if (!m_session_data->m_initial_stop_received) {
+ WINLOG_IFANY(WINDOWS_LOG_BREAKPOINTS, "Hit loader breakpoint at address "
+ "0x%I64x, setting initial stop "
+ "event.",
+ record.GetExceptionAddress());
+ m_session_data->m_initial_stop_received = true;
+ ::SetEvent(m_session_data->m_initial_stop_event);
+ } else {
+ WINLOG_IFANY(WINDOWS_LOG_BREAKPOINTS,
+ "Hit non-loader breakpoint at address 0x%I64x.",
+ record.GetExceptionAddress());
+ }
+ SetPrivateState(eStateStopped);
+ break;
+ case EXCEPTION_SINGLE_STEP:
+ result = ExceptionResult::BreakInDebugger;
+ SetPrivateState(eStateStopped);
+ break;
+ default:
+ WINLOG_IFANY(WINDOWS_LOG_EXCEPTION, "Debugger thread reported exception "
+ "0x%lx at address 0x%llx "
+ "(first_chance=%s)",
+ record.GetExceptionCode(), record.GetExceptionAddress(),
+ BOOL_STR(first_chance));
+ // For non-breakpoints, give the application a chance to handle the
+ // exception first.
+ if (first_chance)
+ result = ExceptionResult::SendToApplication;
else
- return LLDB_INVALID_ADDRESS;
+ result = ExceptionResult::BreakInDebugger;
+ }
+
+ return result;
+}
+
+void ProcessWindows::OnCreateThread(const HostThread &new_thread) {
+ llvm::sys::ScopedLock lock(m_mutex);
+ const HostThreadWindows &wnew_thread = new_thread.GetNativeThread();
+ m_session_data->m_new_threads[wnew_thread.GetThreadId()] = new_thread;
+}
+
+void ProcessWindows::OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) {
+ llvm::sys::ScopedLock lock(m_mutex);
+
+ // On a forced termination, we may get exit thread events after the session
+ // data has been cleaned up.
+ if (!m_session_data)
+ return;
+
+ // A thread may have started and exited before the debugger stopped allowing a
+ // refresh.
+ // Just remove it from the new threads list in that case.
+ auto iter = m_session_data->m_new_threads.find(thread_id);
+ if (iter != m_session_data->m_new_threads.end())
+ m_session_data->m_new_threads.erase(iter);
+ else
+ m_session_data->m_exited_threads.insert(thread_id);
+}
+
+void ProcessWindows::OnLoadDll(const ModuleSpec &module_spec,
+ lldb::addr_t module_addr) {
+ // Confusingly, there is no Target::AddSharedModule. Instead, calling
+ // GetSharedModule() with
+ // a new module will add it to the module list and return a corresponding
+ // ModuleSP.
+ Error error;
+ ModuleSP module = GetTarget().GetSharedModule(module_spec, &error);
+ bool load_addr_changed = false;
+ module->SetLoadAddress(GetTarget(), module_addr, false, load_addr_changed);
+
+ ModuleList loaded_modules;
+ loaded_modules.Append(module);
+ GetTarget().ModulesDidLoad(loaded_modules);
+}
+
+void ProcessWindows::OnUnloadDll(lldb::addr_t module_addr) {
+ Address resolved_addr;
+ if (GetTarget().ResolveLoadAddress(module_addr, resolved_addr)) {
+ ModuleSP module = resolved_addr.GetModule();
+ if (module) {
+ ModuleList unloaded_modules;
+ unloaded_modules.Append(module);
+ GetTarget().ModulesDidUnload(unloaded_modules, false);
+ }
+ }
+}
+
+void ProcessWindows::OnDebugString(const std::string &string) {}
+
+void ProcessWindows::OnDebuggerError(const Error &error, uint32_t type) {
+ llvm::sys::ScopedLock lock(m_mutex);
+
+ if (m_session_data->m_initial_stop_received) {
+ // This happened while debugging. Do we shutdown the debugging session, try
+ // to continue,
+ // or do something else?
+ WINERR_IFALL(WINDOWS_LOG_PROCESS, "Error %u occurred during debugging. "
+ "Unexpected behavior may result. %s",
+ error.GetError(), error.AsCString());
+ } else {
+ // If we haven't actually launched the process yet, this was an error
+ // launching the
+ // process. Set the internal error and signal the initial stop event so
+ // that the DoLaunch
+ // method wakes up and returns a failure.
+ m_session_data->m_launch_error = error;
+ ::SetEvent(m_session_data->m_initial_stop_event);
+ WINERR_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "Error %u occurred launching the process before the initial stop. %s",
+ error.GetError(), error.AsCString());
+ return;
+ }
}
-// The Windows page protection bits are NOT independent masks that can be bitwise-ORed
-// together. For example, PAGE_EXECUTE_READ is not (PAGE_EXECUTE | PAGE_READ).
-// To test for an access type, it's necessary to test for any of the bits that provide
-// that access type.
-bool
-ProcessWindows::IsPageReadable(uint32_t protect)
-{
- return (protect & PAGE_NOACCESS) == 0;
+Error ProcessWindows::WaitForDebuggerConnection(DebuggerThreadSP debugger,
+ HostProcess &process) {
+ Error result;
+ WINLOG_IFANY(WINDOWS_LOG_PROCESS | WINDOWS_LOG_BREAKPOINTS,
+ "WaitForDebuggerConnection Waiting for loader breakpoint.");
+
+ // Block this function until we receive the initial stop from the process.
+ if (::WaitForSingleObject(m_session_data->m_initial_stop_event, INFINITE) ==
+ WAIT_OBJECT_0) {
+ WINLOG_IFANY(WINDOWS_LOG_PROCESS | WINDOWS_LOG_BREAKPOINTS,
+ "WaitForDebuggerConnection hit loader breakpoint, returning.");
+
+ process = debugger->GetProcess();
+ return m_session_data->m_launch_error;
+ } else
+ return Error(::GetLastError(), eErrorTypeWin32);
}
-bool
-ProcessWindows::IsPageWritable(uint32_t protect)
-{
- return (protect & (PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY | PAGE_READWRITE | PAGE_WRITECOPY)) != 0;
+// The Windows page protection bits are NOT independent masks that can be
+// bitwise-ORed together. For example, PAGE_EXECUTE_READ is not
+// (PAGE_EXECUTE | PAGE_READ). To test for an access type, it's necessary to
+// test for any of the bits that provide that access type.
+bool ProcessWindows::IsPageReadable(uint32_t protect) {
+ return (protect & PAGE_NOACCESS) == 0;
}
-bool
-ProcessWindows::IsPageExecutable(uint32_t protect)
-{
- return (protect & (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)) != 0;
+bool ProcessWindows::IsPageWritable(uint32_t protect) {
+ return (protect & (PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY |
+ PAGE_READWRITE | PAGE_WRITECOPY)) != 0;
}
+bool ProcessWindows::IsPageExecutable(uint32_t protect) {
+ return (protect & (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE |
+ PAGE_EXECUTE_WRITECOPY)) != 0;
}
+
+} // namespace lldb_private
diff --git a/source/Plugins/Process/Windows/Common/ProcessWindows.h b/source/Plugins/Process/Windows/Common/ProcessWindows.h
index 0ee42e2ae1f1..fac06c46b2ba 100644
--- a/source/Plugins/Process/Windows/Common/ProcessWindows.h
+++ b/source/Plugins/Process/Windows/Common/ProcessWindows.h
@@ -11,42 +11,109 @@
#define liblldb_Plugins_Process_Windows_Common_ProcessWindows_H_
// Other libraries and framework includes
-#include "lldb/lldb-forward.h"
#include "lldb/Core/Error.h"
#include "lldb/Target/Process.h"
+#include "lldb/lldb-forward.h"
+
+#include "llvm/Support/Mutex.h"
+
+#include "IDebugDelegate.h"
+
+namespace lldb_private {
-namespace lldb_private
-{
+class HostProcess;
+class ProcessWindowsData;
-class ProcessWindows : public lldb_private::Process
-{
+class ProcessWindows : public Process, public IDebugDelegate {
public:
- //------------------------------------------------------------------
- // Constructors and destructors
- //------------------------------------------------------------------
- ProcessWindows(lldb::TargetSP target_sp,
- lldb::ListenerSP listener_sp);
+ //------------------------------------------------------------------
+ // Static functions.
+ //------------------------------------------------------------------
+ static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp,
+ lldb::ListenerSP listener_sp,
+ const FileSpec *);
- ~ProcessWindows();
+ static void Initialize();
- size_t GetSTDOUT(char *buf, size_t buf_size, lldb_private::Error &error) override;
- size_t GetSTDERR(char *buf, size_t buf_size, lldb_private::Error &error) override;
- size_t PutSTDIN(const char *buf, size_t buf_size, lldb_private::Error &error) override;
+ static void Terminate();
- lldb::addr_t GetImageInfoAddress() override;
+ static lldb_private::ConstString GetPluginNameStatic();
-protected:
- // These decode the page protection bits.
- static bool
- IsPageReadable(uint32_t protect);
+ static const char *GetPluginDescriptionStatic();
- static bool
- IsPageWritable(uint32_t protect);
+ //------------------------------------------------------------------
+ // Constructors and destructors
+ //------------------------------------------------------------------
+ ProcessWindows(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp);
- static bool
- IsPageExecutable(uint32_t protect);
-};
+ ~ProcessWindows();
+
+ size_t GetSTDOUT(char *buf, size_t buf_size, Error &error) override;
+ size_t GetSTDERR(char *buf, size_t buf_size, Error &error) override;
+ size_t PutSTDIN(const char *buf, size_t buf_size, Error &error) override;
+
+ // lldb_private::Process overrides
+ ConstString GetPluginName() override;
+ uint32_t GetPluginVersion() override;
+
+ Error EnableBreakpointSite(BreakpointSite *bp_site) override;
+ Error DisableBreakpointSite(BreakpointSite *bp_site) override;
+
+ Error DoDetach(bool keep_stopped) override;
+ Error DoLaunch(Module *exe_module, ProcessLaunchInfo &launch_info) override;
+ Error DoAttachToProcessWithID(
+ lldb::pid_t pid,
+ const lldb_private::ProcessAttachInfo &attach_info) override;
+ Error DoResume() override;
+ Error DoDestroy() override;
+ Error DoHalt(bool &caused_stop) override;
+ void DidLaunch() override;
+ void DidAttach(lldb_private::ArchSpec &arch_spec) override;
+
+ void RefreshStateAfterStop() override;
+
+ bool CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) override;
+ bool DestroyRequiresHalt() override { return false; }
+ bool UpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) override;
+ bool IsAlive() override;
+
+ size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
+ Error &error) override;
+ size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size,
+ Error &error) override;
+ Error GetMemoryRegionInfo(lldb::addr_t vm_addr,
+ MemoryRegionInfo &info) override;
+
+ lldb::addr_t GetImageInfoAddress() override;
+
+ // IDebugDelegate overrides.
+ void OnExitProcess(uint32_t exit_code) override;
+ void OnDebuggerConnected(lldb::addr_t image_base) override;
+ ExceptionResult OnDebugException(bool first_chance,
+ const ExceptionRecord &record) override;
+ void OnCreateThread(const HostThread &thread) override;
+ void OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) override;
+ void OnLoadDll(const ModuleSpec &module_spec,
+ lldb::addr_t module_addr) override;
+ void OnUnloadDll(lldb::addr_t module_addr) override;
+ void OnDebugString(const std::string &string) override;
+ void OnDebuggerError(const Error &error, uint32_t type) override;
+
+private:
+ Error WaitForDebuggerConnection(DebuggerThreadSP debugger,
+ HostProcess &process);
+
+ // These decode the page protection bits.
+ static bool IsPageReadable(uint32_t protect);
+ static bool IsPageWritable(uint32_t protect);
+ static bool IsPageExecutable(uint32_t protect);
+
+ llvm::sys::Mutex m_mutex;
+ std::unique_ptr<ProcessWindowsData> m_session_data;
+};
}
-#endif // liblldb_Plugins_Process_Windows_Common_ProcessWindows_H_
+#endif // liblldb_Plugins_Process_Windows_Common_ProcessWindows_H_
diff --git a/source/Plugins/Process/Windows/Common/ProcessWindowsLog.cpp b/source/Plugins/Process/Windows/Common/ProcessWindowsLog.cpp
index 47722c5146b2..242c1996bdd4 100644
--- a/source/Plugins/Process/Windows/Common/ProcessWindowsLog.cpp
+++ b/source/Plugins/Process/Windows/Common/ProcessWindowsLog.cpp
@@ -18,177 +18,151 @@
using namespace lldb;
using namespace lldb_private;
-
// We want to avoid global constructors where code needs to be run so here we
// control access to our static g_log_sp by hiding it in a singleton function
// that will construct the static g_log_sp the first time this function is
// called.
static bool g_log_enabled = false;
-static Log * g_log = nullptr;
+static Log *g_log = nullptr;
static llvm::ManagedStatic<std::once_flag> g_once_flag;
-void
-ProcessWindowsLog::Initialize()
-{
- static ConstString g_name("windows");
-
- std::call_once(*g_once_flag, [](){
- Log::Callbacks log_callbacks = {
- DisableLog,
- EnableLog,
- ListLogCategories
- };
-
- Log::RegisterLogChannel(g_name, log_callbacks);
- RegisterPluginName(g_name);
- });
-}
+void ProcessWindowsLog::Initialize() {
+ static ConstString g_name("windows");
-void
-ProcessWindowsLog::Terminate()
-{
-}
+ std::call_once(*g_once_flag, []() {
+ Log::Callbacks log_callbacks = {DisableLog, EnableLog, ListLogCategories};
-Log *
-ProcessWindowsLog::GetLog()
-{
- return (g_log_enabled) ? g_log : nullptr;
+ Log::RegisterLogChannel(g_name, log_callbacks);
+ RegisterPluginName(g_name);
+ });
}
-bool
-ProcessWindowsLog::TestLogFlags(uint32_t mask, LogMaskReq req)
-{
- Log *log = GetLog();
- if (!log)
- return false;
+void ProcessWindowsLog::Terminate() {}
- uint32_t log_mask = log->GetMask().Get();
- if (req == LogMaskReq::All)
- return ((log_mask & mask) == mask);
- else
- return (log_mask & mask);
+Log *ProcessWindowsLog::GetLog() { return (g_log_enabled) ? g_log : nullptr; }
+
+bool ProcessWindowsLog::TestLogFlags(uint32_t mask, LogMaskReq req) {
+ Log *log = GetLog();
+ if (!log)
+ return false;
+
+ uint32_t log_mask = log->GetMask().Get();
+ if (req == LogMaskReq::All)
+ return ((log_mask & mask) == mask);
+ else
+ return (log_mask & mask);
}
-static uint32_t
-GetFlagBits(const char *arg)
-{
- if (::strcasecmp(arg, "all") == 0 ) return WINDOWS_LOG_ALL;
- else if (::strcasecmp(arg, "break") == 0 ) return WINDOWS_LOG_BREAKPOINTS;
- else if (::strcasecmp(arg, "event") == 0 ) return WINDOWS_LOG_EVENT;
- else if (::strcasecmp(arg, "exception") == 0 ) return WINDOWS_LOG_EXCEPTION;
- else if (::strcasecmp(arg, "memory") == 0 ) return WINDOWS_LOG_MEMORY;
- else if (::strcasecmp(arg, "process") == 0 ) return WINDOWS_LOG_PROCESS;
- else if (::strcasecmp(arg, "registers") == 0 ) return WINDOWS_LOG_REGISTERS;
- else if (::strcasecmp(arg, "step") == 0 ) return WINDOWS_LOG_STEP;
- else if (::strcasecmp(arg, "thread") == 0 ) return WINDOWS_LOG_THREAD;
- else if (::strcasecmp(arg, "verbose") == 0 ) return WINDOWS_LOG_VERBOSE;
- return 0;
+static uint32_t GetFlagBits(const char *arg) {
+ if (::strcasecmp(arg, "all") == 0)
+ return WINDOWS_LOG_ALL;
+ else if (::strcasecmp(arg, "break") == 0)
+ return WINDOWS_LOG_BREAKPOINTS;
+ else if (::strcasecmp(arg, "event") == 0)
+ return WINDOWS_LOG_EVENT;
+ else if (::strcasecmp(arg, "exception") == 0)
+ return WINDOWS_LOG_EXCEPTION;
+ else if (::strcasecmp(arg, "memory") == 0)
+ return WINDOWS_LOG_MEMORY;
+ else if (::strcasecmp(arg, "process") == 0)
+ return WINDOWS_LOG_PROCESS;
+ else if (::strcasecmp(arg, "registers") == 0)
+ return WINDOWS_LOG_REGISTERS;
+ else if (::strcasecmp(arg, "step") == 0)
+ return WINDOWS_LOG_STEP;
+ else if (::strcasecmp(arg, "thread") == 0)
+ return WINDOWS_LOG_THREAD;
+ else if (::strcasecmp(arg, "verbose") == 0)
+ return WINDOWS_LOG_VERBOSE;
+ return 0;
}
-void
-ProcessWindowsLog::DisableLog(const char **args, Stream *feedback_strm)
-{
- Log *log (GetLog());
- if (log)
- {
- uint32_t flag_bits = 0;
-
- if (args[0] != nullptr)
- {
- flag_bits = log->GetMask().Get();
- for (; args[0]; args++)
- {
- const char *arg = args[0];
- uint32_t bits = GetFlagBits(arg);
-
- if (bits)
- {
- flag_bits &= ~bits;
- }
- else
- {
- feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
- ListLogCategories(feedback_strm);
- }
- }
- }
+void ProcessWindowsLog::DisableLog(const char **args, Stream *feedback_strm) {
+ Log *log(GetLog());
+ if (log) {
+ uint32_t flag_bits = 0;
- log->GetMask().Reset(flag_bits);
- if (flag_bits == 0)
- {
- g_log_enabled = false;
- log->SetStream(lldb::StreamSP());
+ if (args[0] != nullptr) {
+ flag_bits = log->GetMask().Get();
+ for (; args[0]; args++) {
+ const char *arg = args[0];
+ uint32_t bits = GetFlagBits(arg);
+
+ if (bits) {
+ flag_bits &= ~bits;
+ } else {
+ feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
+ ListLogCategories(feedback_strm);
}
+ }
}
- return;
-}
-
-Log *
-ProcessWindowsLog::EnableLog(StreamSP &log_stream_sp, uint32_t log_options, const char **args, Stream *feedback_strm)
-{
- // Try see if there already is a log - that way we can reuse its settings.
- // We could reuse the log in toto, but we don't know that the stream is the same.
- uint32_t flag_bits = 0;
- if (g_log)
- flag_bits = g_log->GetMask().Get();
-
- // Now make a new log with this stream if one was provided
- if (log_stream_sp)
- {
- if (g_log)
- g_log->SetStream(log_stream_sp);
- else
- g_log = new Log(log_stream_sp);
+ log->GetMask().Reset(flag_bits);
+ if (flag_bits == 0) {
+ g_log_enabled = false;
+ log->SetStream(lldb::StreamSP());
}
+ }
+ return;
+}
+
+Log *ProcessWindowsLog::EnableLog(StreamSP &log_stream_sp, uint32_t log_options,
+ const char **args, Stream *feedback_strm) {
+ // Try see if there already is a log - that way we can reuse its settings.
+ // We could reuse the log in toto, but we don't know that the stream is the
+ // same.
+ uint32_t flag_bits = 0;
+ if (g_log)
+ flag_bits = g_log->GetMask().Get();
+
+ // Now make a new log with this stream if one was provided
+ if (log_stream_sp) {
if (g_log)
- {
- bool got_unknown_category = false;
- for (; args[0]; args++)
- {
- const char *arg = args[0];
- uint32_t bits = GetFlagBits(arg);
-
- if (bits)
- {
- flag_bits |= bits;
- }
- else
- {
- feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
- if (got_unknown_category == false)
- {
- got_unknown_category = true;
- ListLogCategories (feedback_strm);
- }
- }
+ g_log->SetStream(log_stream_sp);
+ else
+ g_log = new Log(log_stream_sp);
+ }
+
+ if (g_log) {
+ bool got_unknown_category = false;
+ for (; args[0]; args++) {
+ const char *arg = args[0];
+ uint32_t bits = GetFlagBits(arg);
+
+ if (bits) {
+ flag_bits |= bits;
+ } else {
+ feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
+ if (got_unknown_category == false) {
+ got_unknown_category = true;
+ ListLogCategories(feedback_strm);
}
- if (flag_bits == 0)
- flag_bits = WINDOWS_LOG_ALL;
- g_log->GetMask().Reset(flag_bits);
- g_log->GetOptions().Reset(log_options);
- g_log_enabled = true;
+ }
}
- return g_log;
+ if (flag_bits == 0)
+ flag_bits = WINDOWS_LOG_ALL;
+ g_log->GetMask().Reset(flag_bits);
+ g_log->GetOptions().Reset(log_options);
+ g_log_enabled = true;
+ }
+ return g_log;
}
-void
-ProcessWindowsLog::ListLogCategories(Stream *strm)
-{
- strm->Printf("Logging categories for '%s':\n"
- " all - turn on all available logging categories\n"
- " break - log breakpoints\n"
- " event - log low level debugger events\n"
- " exception - log exception information\n"
- " memory - log memory reads and writes\n"
- " process - log process events and activities\n"
- " registers - log register read/writes\n"
- " thread - log thread events and activities\n"
- " step - log step related activities\n"
- " verbose - enable verbose logging\n",
- ProcessWindowsLog::m_pluginname);
+void ProcessWindowsLog::ListLogCategories(Stream *strm) {
+ strm->Printf("Logging categories for '%s':\n"
+ " all - turn on all available logging categories\n"
+ " break - log breakpoints\n"
+ " event - log low level debugger events\n"
+ " exception - log exception information\n"
+ " memory - log memory reads and writes\n"
+ " process - log process events and activities\n"
+ " registers - log register read/writes\n"
+ " thread - log thread events and activities\n"
+ " step - log step related activities\n"
+ " verbose - enable verbose logging\n",
+ ProcessWindowsLog::m_pluginname);
}
const char *ProcessWindowsLog::m_pluginname = "";
diff --git a/source/Plugins/Process/Windows/Common/ProcessWindowsLog.h b/source/Plugins/Process/Windows/Common/ProcessWindowsLog.h
index d798d131faeb..cbb99e8d907e 100644
--- a/source/Plugins/Process/Windows/Common/ProcessWindowsLog.h
+++ b/source/Plugins/Process/Windows/Common/ProcessWindowsLog.h
@@ -12,85 +12,80 @@
#include "lldb/Core/Log.h"
-#define WINDOWS_LOG_VERBOSE (1u << 0)
-#define WINDOWS_LOG_PROCESS (1u << 1) // Log process operations
-#define WINDOWS_LOG_EXCEPTION (1u << 1) // Log exceptions
-#define WINDOWS_LOG_THREAD (1u << 2) // Log thread operations
-#define WINDOWS_LOG_MEMORY (1u << 3) // Log memory reads/writes calls
-#define WINDOWS_LOG_BREAKPOINTS (1u << 4) // Log breakpoint operations
-#define WINDOWS_LOG_STEP (1u << 5) // Log step operations
-#define WINDOWS_LOG_REGISTERS (1u << 6) // Log register operations
-#define WINDOWS_LOG_EVENT (1u << 7) // Low level debug events
-#define WINDOWS_LOG_ALL (UINT32_MAX)
-
-enum class LogMaskReq
-{
- All,
- Any
-};
-
-class ProcessWindowsLog
-{
- static const char *m_pluginname;
+#define WINDOWS_LOG_VERBOSE (1u << 0)
+#define WINDOWS_LOG_PROCESS (1u << 1) // Log process operations
+#define WINDOWS_LOG_EXCEPTION (1u << 1) // Log exceptions
+#define WINDOWS_LOG_THREAD (1u << 2) // Log thread operations
+#define WINDOWS_LOG_MEMORY (1u << 3) // Log memory reads/writes calls
+#define WINDOWS_LOG_BREAKPOINTS (1u << 4) // Log breakpoint operations
+#define WINDOWS_LOG_STEP (1u << 5) // Log step operations
+#define WINDOWS_LOG_REGISTERS (1u << 6) // Log register operations
+#define WINDOWS_LOG_EVENT (1u << 7) // Low level debug events
+#define WINDOWS_LOG_ALL (UINT32_MAX)
+
+enum class LogMaskReq { All, Any };
+
+class ProcessWindowsLog {
+ static const char *m_pluginname;
public:
- // ---------------------------------------------------------------------
- // Public Static Methods
- // ---------------------------------------------------------------------
- static void
- Initialize();
-
- static void
- Terminate();
-
- static void
- RegisterPluginName(const char *pluginName)
- {
- m_pluginname = pluginName;
- }
-
- static void
- RegisterPluginName(lldb_private::ConstString pluginName)
- {
- m_pluginname = pluginName.GetCString();
- }
-
- static bool
- TestLogFlags(uint32_t mask, LogMaskReq req);
-
- static lldb_private::Log *
- GetLog();
-
- static void
- DisableLog(const char **args, lldb_private::Stream *feedback_strm);
-
- static lldb_private::Log *
- EnableLog(lldb::StreamSP &log_stream_sp, uint32_t log_options,
- const char **args, lldb_private::Stream *feedback_strm);
-
- static void
- ListLogCategories(lldb_private::Stream *strm);
+ // ---------------------------------------------------------------------
+ // Public Static Methods
+ // ---------------------------------------------------------------------
+ static void Initialize();
+
+ static void Terminate();
+
+ static void RegisterPluginName(const char *pluginName) {
+ m_pluginname = pluginName;
+ }
+
+ static void RegisterPluginName(lldb_private::ConstString pluginName) {
+ m_pluginname = pluginName.GetCString();
+ }
+
+ static bool TestLogFlags(uint32_t mask, LogMaskReq req);
+
+ static lldb_private::Log *GetLog();
+
+ static void DisableLog(const char **args,
+ lldb_private::Stream *feedback_strm);
+
+ static lldb_private::Log *EnableLog(lldb::StreamSP &log_stream_sp,
+ uint32_t log_options, const char **args,
+ lldb_private::Stream *feedback_strm);
+
+ static void ListLogCategories(lldb_private::Stream *strm);
};
-#define WINLOGF_IF(Flags, Req, Method, ...) \
- { \
- if (ProcessWindowsLog::TestLogFlags(Flags, Req)) \
- { \
- Log *log = ProcessWindowsLog::GetLog(); \
- if (log) \
- log->Method(__VA_ARGS__); \
- } \
- }
-
-#define WINLOG_IFANY(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::Any, Printf, __VA_ARGS__)
-#define WINLOG_IFALL(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::All, Printf, __VA_ARGS__)
-#define WINLOGV_IFANY(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::Any, Verbose, __VA_ARGS__)
-#define WINLOGV_IFALL(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::All, Verbose, __VA_ARGS__)
-#define WINLOGD_IFANY(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::Any, Debug, __VA_ARGS__)
-#define WINLOGD_IFALL(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::All, Debug, __VA_ARGS__)
-#define WINERR_IFANY(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::Any, Error, __VA_ARGS__)
-#define WINERR_IFALL(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::All, Error, __VA_ARGS__)
-#define WINWARN_IFANY(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::Any, Warning, __VA_ARGS__)
-#define WINWARN_IFALL(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::All, Warning, __VA_ARGS__)
-
-#endif // liblldb_ProcessWindowsLog_h_
+#define WINLOGF_IF(Flags, Req, Method, ...) \
+ { \
+ if (ProcessWindowsLog::TestLogFlags(Flags, Req)) { \
+ Log *log = ProcessWindowsLog::GetLog(); \
+ if (log) \
+ log->Method(__VA_ARGS__); \
+ } \
+ }
+
+#define WINLOG_IFANY(Flags, ...) \
+ WINLOGF_IF(Flags, LogMaskReq::Any, Printf, __VA_ARGS__)
+#define WINLOG_IFALL(Flags, ...) \
+ WINLOGF_IF(Flags, LogMaskReq::All, Printf, __VA_ARGS__)
+#define WINLOGV_IFANY(Flags, ...) \
+ WINLOGF_IF(Flags, LogMaskReq::Any, Verbose, __VA_ARGS__)
+#define WINLOGV_IFALL(Flags, ...) \
+ WINLOGF_IF(Flags, LogMaskReq::All, Verbose, __VA_ARGS__)
+#define WINLOGD_IFANY(Flags, ...) \
+ WINLOGF_IF(Flags, LogMaskReq::Any, Debug, __VA_ARGS__)
+#define WINLOGD_IFALL(Flags, ...) \
+ WINLOGF_IF(Flags, LogMaskReq::All, Debug, __VA_ARGS__)
+#define WINERR_IFANY(Flags, ...) \
+ WINLOGF_IF(Flags, LogMaskReq::Any, Error, __VA_ARGS__)
+#define WINERR_IFALL(Flags, ...) \
+ WINLOGF_IF(Flags, LogMaskReq::All, Error, __VA_ARGS__)
+#define WINWARN_IFANY(Flags, ...) \
+ WINLOGF_IF(Flags, LogMaskReq::Any, Warning, __VA_ARGS__)
+#define WINWARN_IFALL(Flags, ...) \
+ WINLOGF_IF(Flags, LogMaskReq::All, Warning, __VA_ARGS__)
+
+#endif // liblldb_ProcessWindowsLog_h_
diff --git a/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp b/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp
index d61675f09b1b..0ef3c77e47c1 100644
--- a/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp
+++ b/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp
@@ -7,11 +7,11 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-private-types.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Error.h"
#include "lldb/Host/windows/HostThreadWindows.h"
#include "lldb/Host/windows/windows.h"
+#include "lldb/lldb-private-types.h"
#include "ProcessWindowsLog.h"
#include "RegisterContextWindows.h"
@@ -27,129 +27,109 @@ const DWORD kWinContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
-RegisterContextWindows::RegisterContextWindows(Thread &thread, uint32_t concrete_frame_idx)
- : RegisterContext(thread, concrete_frame_idx)
- , m_context()
- , m_context_stale(true)
-{
-}
+RegisterContextWindows::RegisterContextWindows(Thread &thread,
+ uint32_t concrete_frame_idx)
+ : RegisterContext(thread, concrete_frame_idx), m_context(),
+ m_context_stale(true) {}
-RegisterContextWindows::~RegisterContextWindows()
-{
-}
+RegisterContextWindows::~RegisterContextWindows() {}
-void
-RegisterContextWindows::InvalidateAllRegisters()
-{
- m_context_stale = true;
+void RegisterContextWindows::InvalidateAllRegisters() {
+ m_context_stale = true;
}
-bool
-RegisterContextWindows::ReadAllRegisterValues(lldb::DataBufferSP &data_sp)
-{
- if (!CacheAllRegisterValues())
- return false;
- if (data_sp->GetByteSize() < sizeof(m_context))
- {
- data_sp.reset(new DataBufferHeap(sizeof(CONTEXT), 0));
- }
- memcpy(data_sp->GetBytes(), &m_context, sizeof(m_context));
- return true;
+bool RegisterContextWindows::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ if (!CacheAllRegisterValues())
+ return false;
+ if (data_sp->GetByteSize() < sizeof(m_context)) {
+ data_sp.reset(new DataBufferHeap(sizeof(CONTEXT), 0));
+ }
+ memcpy(data_sp->GetBytes(), &m_context, sizeof(m_context));
+ return true;
}
-bool
-RegisterContextWindows::WriteAllRegisterValues(const lldb::DataBufferSP &data_sp)
-{
- assert(data_sp->GetByteSize() >= sizeof(m_context));
- memcpy(&m_context, data_sp->GetBytes(), sizeof(m_context));
+bool RegisterContextWindows::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ assert(data_sp->GetByteSize() >= sizeof(m_context));
+ memcpy(&m_context, data_sp->GetBytes(), sizeof(m_context));
- TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
- if (!::SetThreadContext(wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context))
- return false;
+ TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
+ if (!::SetThreadContext(
+ wthread.GetHostThread().GetNativeThread().GetSystemHandle(),
+ &m_context))
+ return false;
- return true;
+ return true;
}
-uint32_t
-RegisterContextWindows::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num)
-{
- const uint32_t num_regs = GetRegisterCount();
+uint32_t RegisterContextWindows::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t num) {
+ const uint32_t num_regs = GetRegisterCount();
- assert(kind < kNumRegisterKinds);
- for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
- {
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx);
+ assert(kind < kNumRegisterKinds);
+ for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx);
- if (reg_info->kinds[kind] == num)
- return reg_idx;
- }
+ if (reg_info->kinds[kind] == num)
+ return reg_idx;
+ }
- return LLDB_INVALID_REGNUM;
+ return LLDB_INVALID_REGNUM;
}
//------------------------------------------------------------------
// Subclasses can these functions if desired
//------------------------------------------------------------------
-uint32_t
-RegisterContextWindows::NumSupportedHardwareBreakpoints()
-{
- // Support for hardware breakpoints not yet implemented.
- return 0;
+uint32_t RegisterContextWindows::NumSupportedHardwareBreakpoints() {
+ // Support for hardware breakpoints not yet implemented.
+ return 0;
}
-uint32_t
-RegisterContextWindows::SetHardwareBreakpoint(lldb::addr_t addr, size_t size)
-{
- return 0;
+uint32_t RegisterContextWindows::SetHardwareBreakpoint(lldb::addr_t addr,
+ size_t size) {
+ return 0;
}
-bool
-RegisterContextWindows::ClearHardwareBreakpoint(uint32_t hw_idx)
-{
- return false;
+bool RegisterContextWindows::ClearHardwareBreakpoint(uint32_t hw_idx) {
+ return false;
}
-uint32_t
-RegisterContextWindows::NumSupportedHardwareWatchpoints()
-{
- // Support for hardware watchpoints not yet implemented.
- return 0;
+uint32_t RegisterContextWindows::NumSupportedHardwareWatchpoints() {
+ // Support for hardware watchpoints not yet implemented.
+ return 0;
}
-uint32_t
-RegisterContextWindows::SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write)
-{
- return 0;
+uint32_t RegisterContextWindows::SetHardwareWatchpoint(lldb::addr_t addr,
+ size_t size, bool read,
+ bool write) {
+ return 0;
}
-bool
-RegisterContextWindows::ClearHardwareWatchpoint(uint32_t hw_index)
-{
- return false;
+bool RegisterContextWindows::ClearHardwareWatchpoint(uint32_t hw_index) {
+ return false;
}
-bool
-RegisterContextWindows::HardwareSingleStep(bool enable)
-{
- return false;
-}
+bool RegisterContextWindows::HardwareSingleStep(bool enable) { return false; }
-bool
-RegisterContextWindows::CacheAllRegisterValues()
-{
- if (!m_context_stale)
- return true;
-
- TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
- memset(&m_context, 0, sizeof(m_context));
- m_context.ContextFlags = kWinContextFlags;
- if (!::GetThreadContext(wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context))
- {
- WINERR_IFALL(WINDOWS_LOG_REGISTERS, "GetThreadContext failed with error %u while caching register values.",
- ::GetLastError());
- return false;
- }
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "GetThreadContext successfully updated the register values.", ::GetLastError());
- m_context_stale = false;
+bool RegisterContextWindows::CacheAllRegisterValues() {
+ if (!m_context_stale)
return true;
+
+ TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
+ memset(&m_context, 0, sizeof(m_context));
+ m_context.ContextFlags = kWinContextFlags;
+ if (!::GetThreadContext(
+ wthread.GetHostThread().GetNativeThread().GetSystemHandle(),
+ &m_context)) {
+ WINERR_IFALL(
+ WINDOWS_LOG_REGISTERS,
+ "GetThreadContext failed with error %lu while caching register values.",
+ ::GetLastError());
+ return false;
+ }
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS,
+ "GetThreadContext successfully updated the register values.");
+ m_context_stale = false;
+ return true;
}
diff --git a/source/Plugins/Process/Windows/Common/RegisterContextWindows.h b/source/Plugins/Process/Windows/Common/RegisterContextWindows.h
index 66b7a9004ead..bd09295c2f23 100644
--- a/source/Plugins/Process/Windows/Common/RegisterContextWindows.h
+++ b/source/Plugins/Process/Windows/Common/RegisterContextWindows.h
@@ -10,57 +10,57 @@
#ifndef liblldb_RegisterContextWindows_H_
#define liblldb_RegisterContextWindows_H_
-#include "lldb/lldb-forward.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/lldb-forward.h"
-namespace lldb_private
-{
+namespace lldb_private {
class Thread;
-class RegisterContextWindows : public lldb_private::RegisterContext
-{
- public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- RegisterContextWindows(Thread &thread, uint32_t concrete_frame_idx);
+class RegisterContextWindows : public lldb_private::RegisterContext {
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ RegisterContextWindows(Thread &thread, uint32_t concrete_frame_idx);
- virtual ~RegisterContextWindows();
+ virtual ~RegisterContextWindows();
- //------------------------------------------------------------------
- // Subclasses must override these functions
- //------------------------------------------------------------------
- void InvalidateAllRegisters() override;
+ //------------------------------------------------------------------
+ // Subclasses must override these functions
+ //------------------------------------------------------------------
+ void InvalidateAllRegisters() override;
- bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
- bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override;
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
- //------------------------------------------------------------------
- // Subclasses can override these functions if desired
- //------------------------------------------------------------------
- uint32_t NumSupportedHardwareBreakpoints() override;
+ //------------------------------------------------------------------
+ // Subclasses can override these functions if desired
+ //------------------------------------------------------------------
+ uint32_t NumSupportedHardwareBreakpoints() override;
- uint32_t SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override;
+ uint32_t SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override;
- bool ClearHardwareBreakpoint(uint32_t hw_idx) override;
+ bool ClearHardwareBreakpoint(uint32_t hw_idx) override;
- uint32_t NumSupportedHardwareWatchpoints() override;
+ uint32_t NumSupportedHardwareWatchpoints() override;
- uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write) override;
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read,
+ bool write) override;
- bool ClearHardwareWatchpoint(uint32_t hw_index) override;
+ bool ClearHardwareWatchpoint(uint32_t hw_index) override;
- bool HardwareSingleStep(bool enable) override;
+ bool HardwareSingleStep(bool enable) override;
- protected:
- virtual bool CacheAllRegisterValues();
+protected:
+ virtual bool CacheAllRegisterValues();
- CONTEXT m_context;
- bool m_context_stale;
+ CONTEXT m_context;
+ bool m_context_stale;
};
}
diff --git a/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp b/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp
index dcb6f0c72435..8f2603c3365b 100644
--- a/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp
+++ b/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp
@@ -16,83 +16,110 @@
#include "lldb/Host/windows/windows.h"
#include "lldb/Target/RegisterContext.h"
-#include "TargetThreadWindows.h"
#include "ProcessWindows.h"
#include "ProcessWindowsLog.h"
+#include "TargetThreadWindows.h"
#include "UnwindLLDB.h"
+#if defined(_WIN64)
+#include "x64/RegisterContextWindows_x64.h"
+#else
+#include "x86/RegisterContextWindows_x86.h"
+#endif
+
using namespace lldb;
using namespace lldb_private;
-TargetThreadWindows::TargetThreadWindows(ProcessWindows &process, const HostThread &thread)
- : Thread(process, thread.GetNativeThread().GetThreadId())
- , m_host_thread(thread)
-{
-}
+TargetThreadWindows::TargetThreadWindows(ProcessWindows &process,
+ const HostThread &thread)
+ : Thread(process, thread.GetNativeThread().GetThreadId()),
+ m_host_thread(thread) {}
-TargetThreadWindows::~TargetThreadWindows()
-{
- DestroyThread();
-}
+TargetThreadWindows::~TargetThreadWindows() { DestroyThread(); }
-void
-TargetThreadWindows::RefreshStateAfterStop()
-{
- ::SuspendThread(m_host_thread.GetNativeThread().GetSystemHandle());
- SetState(eStateStopped);
- GetRegisterContext()->InvalidateIfNeeded(false);
+void TargetThreadWindows::RefreshStateAfterStop() {
+ ::SuspendThread(m_host_thread.GetNativeThread().GetSystemHandle());
+ SetState(eStateStopped);
+ GetRegisterContext()->InvalidateIfNeeded(false);
}
-void
-TargetThreadWindows::WillResume(lldb::StateType resume_state)
-{
+void TargetThreadWindows::WillResume(lldb::StateType resume_state) {}
+
+void TargetThreadWindows::DidStop() {}
+
+RegisterContextSP TargetThreadWindows::GetRegisterContext() {
+ if (!m_reg_context_sp)
+ m_reg_context_sp = CreateRegisterContextForFrameIndex(0);
+
+ return m_reg_context_sp;
}
-void
-TargetThreadWindows::DidStop()
-{
+RegisterContextSP
+TargetThreadWindows::CreateRegisterContextForFrame(StackFrame *frame) {
+ return CreateRegisterContextForFrameIndex(frame->GetConcreteFrameIndex());
}
-bool
-TargetThreadWindows::CalculateStopInfo()
-{
- SetStopInfo(m_stop_info_sp);
- return true;
+RegisterContextSP
+TargetThreadWindows::CreateRegisterContextForFrameIndex(uint32_t idx) {
+ if (!m_reg_context_sp) {
+ ArchSpec arch = HostInfo::GetArchitecture();
+ switch (arch.GetMachine()) {
+ case llvm::Triple::x86:
+#if defined(_WIN64)
+// FIXME: This is a Wow64 process, create a RegisterContextWindows_Wow64
+#else
+ m_reg_context_sp.reset(new RegisterContextWindows_x86(*this, idx));
+#endif
+ break;
+ case llvm::Triple::x86_64:
+#if defined(_WIN64)
+ m_reg_context_sp.reset(new RegisterContextWindows_x64(*this, idx));
+#else
+// LLDB is 32-bit, but the target process is 64-bit. We probably can't debug
+// this.
+#endif
+ default:
+ break;
+ }
+ }
+ return m_reg_context_sp;
}
-Unwind *
-TargetThreadWindows::GetUnwinder()
-{
- // FIXME: Implement an unwinder based on the Windows unwinder exposed through DIA SDK.
- if (m_unwinder_ap.get() == NULL)
- m_unwinder_ap.reset(new UnwindLLDB(*this));
- return m_unwinder_ap.get();
+bool TargetThreadWindows::CalculateStopInfo() {
+ SetStopInfo(m_stop_info_sp);
+ return true;
}
-bool
-TargetThreadWindows::DoResume()
-{
- StateType resume_state = GetTemporaryResumeState();
- StateType current_state = GetState();
- if (resume_state == current_state)
- return true;
-
- if (resume_state == eStateStepping)
- {
- uint32_t flags_index = GetRegisterContext()->ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
- uint64_t flags_value = GetRegisterContext()->ReadRegisterAsUnsigned(flags_index, 0);
- flags_value |= 0x100; // Set the trap flag on the CPU
- GetRegisterContext()->WriteRegisterFromUnsigned(flags_index, flags_value);
- }
+Unwind *TargetThreadWindows::GetUnwinder() {
+ // FIXME: Implement an unwinder based on the Windows unwinder exposed through
+ // DIA SDK.
+ if (m_unwinder_ap.get() == NULL)
+ m_unwinder_ap.reset(new UnwindLLDB(*this));
+ return m_unwinder_ap.get();
+}
- if (resume_state == eStateStepping || resume_state == eStateRunning)
- {
- DWORD previous_suspend_count = 0;
- HANDLE thread_handle = m_host_thread.GetNativeThread().GetSystemHandle();
- do
- {
- previous_suspend_count = ::ResumeThread(thread_handle);
- } while (previous_suspend_count > 0);
- }
+bool TargetThreadWindows::DoResume() {
+ StateType resume_state = GetTemporaryResumeState();
+ StateType current_state = GetState();
+ if (resume_state == current_state)
return true;
+
+ if (resume_state == eStateStepping) {
+ uint32_t flags_index =
+ GetRegisterContext()->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
+ uint64_t flags_value =
+ GetRegisterContext()->ReadRegisterAsUnsigned(flags_index, 0);
+ flags_value |= 0x100; // Set the trap flag on the CPU
+ GetRegisterContext()->WriteRegisterFromUnsigned(flags_index, flags_value);
+ }
+
+ if (resume_state == eStateStepping || resume_state == eStateRunning) {
+ DWORD previous_suspend_count = 0;
+ HANDLE thread_handle = m_host_thread.GetNativeThread().GetSystemHandle();
+ do {
+ previous_suspend_count = ::ResumeThread(thread_handle);
+ } while (previous_suspend_count > 0);
+ }
+ return true;
}
diff --git a/source/Plugins/Process/Windows/Common/TargetThreadWindows.h b/source/Plugins/Process/Windows/Common/TargetThreadWindows.h
index 701b56b6d26a..8b4e3dfdda4a 100644
--- a/source/Plugins/Process/Windows/Common/TargetThreadWindows.h
+++ b/source/Plugins/Process/Windows/Common/TargetThreadWindows.h
@@ -11,39 +11,40 @@
#define liblldb_Plugins_Process_Windows_TargetThreadWindows_H_
//#include "ForwardDecl.h"
-#include "lldb/lldb-forward.h"
#include "lldb/Host/HostThread.h"
#include "lldb/Target/Thread.h"
+#include "lldb/lldb-forward.h"
-namespace lldb_private
-{
+#include "RegisterContextWindows.h"
+
+namespace lldb_private {
class ProcessWindows;
class HostThread;
class StackFrame;
-class TargetThreadWindows : public lldb_private::Thread
-{
- public:
- TargetThreadWindows(ProcessWindows &process, const HostThread &thread);
- virtual ~TargetThreadWindows();
-
- // lldb_private::Thread overrides
- void RefreshStateAfterStop() override;
- void WillResume(lldb::StateType resume_state) override;
- void DidStop() override;
- bool CalculateStopInfo() override;
- Unwind *GetUnwinder() override;
-
- bool DoResume();
-
- HostThread
- GetHostThread() const
- {
- return m_host_thread;
- }
-
- private:
- HostThread m_host_thread;
+class TargetThreadWindows : public lldb_private::Thread {
+public:
+ TargetThreadWindows(ProcessWindows &process, const HostThread &thread);
+ virtual ~TargetThreadWindows();
+
+ // lldb_private::Thread overrides
+ void RefreshStateAfterStop() override;
+ void WillResume(lldb::StateType resume_state) override;
+ void DidStop() override;
+ lldb::RegisterContextSP GetRegisterContext() override;
+ lldb::RegisterContextSP
+ CreateRegisterContextForFrame(StackFrame *frame) override;
+ bool CalculateStopInfo() override;
+ Unwind *GetUnwinder() override;
+
+ bool DoResume();
+
+ HostThread GetHostThread() const { return m_host_thread; }
+
+private:
+ lldb::RegisterContextSP CreateRegisterContextForFrameIndex(uint32_t idx);
+
+ HostThread m_host_thread;
};
}
diff --git a/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp b/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp
index 3a9c31a0b776..942b4e97c40d 100644
--- a/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp
+++ b/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp
@@ -7,16 +7,16 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-private-types.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Host/windows/HostThreadWindows.h"
#include "lldb/Host/windows/windows.h"
+#include "lldb/lldb-private-types.h"
-#include "lldb-x86-register-enums.h"
-#include "RegisterContext_x86.h"
#include "RegisterContextWindows_x64.h"
+#include "RegisterContext_x86.h"
#include "TargetThreadWindows.h"
+#include "lldb-x86-register-enums.h"
#include "llvm/ADT/STLExtras.h"
@@ -26,302 +26,317 @@ using namespace lldb_private;
#define DEFINE_GPR(reg, alt) #reg, alt, 8, 0, eEncodingUint, eFormatHexUppercase
#define DEFINE_GPR_BIN(reg, alt) #reg, alt, 8, 0, eEncodingUint, eFormatBinary
-namespace
-{
+namespace {
-// This enum defines the layout of the global RegisterInfo array. This is necessary because
-// lldb register sets are defined in terms of indices into the register array. As such, the
-// order of RegisterInfos defined in global registers array must match the order defined here.
-// When defining the register set layouts, these values can appear in an arbitrary order, and that
+// This enum defines the layout of the global RegisterInfo array. This is
+// necessary because
+// lldb register sets are defined in terms of indices into the register array.
+// As such, the
+// order of RegisterInfos defined in global registers array must match the order
+// defined here.
+// When defining the register set layouts, these values can appear in an
+// arbitrary order, and that
// determines the order that register values are displayed in a dump.
-enum RegisterIndex
-{
- eRegisterIndexRax,
- eRegisterIndexRbx,
- eRegisterIndexRcx,
- eRegisterIndexRdx,
- eRegisterIndexRdi,
- eRegisterIndexRsi,
- eRegisterIndexR8,
- eRegisterIndexR9,
- eRegisterIndexR10,
- eRegisterIndexR11,
- eRegisterIndexR12,
- eRegisterIndexR13,
- eRegisterIndexR14,
- eRegisterIndexR15,
- eRegisterIndexRbp,
- eRegisterIndexRsp,
- eRegisterIndexRip,
- eRegisterIndexRflags
+enum RegisterIndex {
+ eRegisterIndexRax,
+ eRegisterIndexRbx,
+ eRegisterIndexRcx,
+ eRegisterIndexRdx,
+ eRegisterIndexRdi,
+ eRegisterIndexRsi,
+ eRegisterIndexR8,
+ eRegisterIndexR9,
+ eRegisterIndexR10,
+ eRegisterIndexR11,
+ eRegisterIndexR12,
+ eRegisterIndexR13,
+ eRegisterIndexR14,
+ eRegisterIndexR15,
+ eRegisterIndexRbp,
+ eRegisterIndexRsp,
+ eRegisterIndexRip,
+ eRegisterIndexRflags
};
// Array of all register information supported by Windows x86
RegisterInfo g_register_infos[] = {
- // Macro auto defines most stuff eh_frame DWARF GENERIC
+ // Macro auto defines most stuff eh_frame DWARF
+ // GENERIC
// GDB LLDB VALUE REGS INVALIDATE REGS
- // ================================ ========================= ====================== =========================
+ // ================================ =========================
+ // ====================== =========================
// =================== ================= ========== ===============
{DEFINE_GPR(rax, nullptr),
- {dwarf_rax_x86_64, dwarf_rax_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_rax_x86_64},
+ {dwarf_rax_x86_64, dwarf_rax_x86_64, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_rax_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(rbx, nullptr),
- {dwarf_rbx_x86_64, dwarf_rbx_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_rbx_x86_64},
+ {dwarf_rbx_x86_64, dwarf_rbx_x86_64, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_rbx_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(rcx, nullptr),
- {dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_rcx_x86_64},
+ {dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_rcx_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(rdx, nullptr),
- {dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_rdx_x86_64},
+ {dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_rdx_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(rdi, nullptr),
- {dwarf_rdi_x86_64, dwarf_rdi_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_rdi_x86_64},
+ {dwarf_rdi_x86_64, dwarf_rdi_x86_64, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_rdi_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(rsi, nullptr),
- {dwarf_rsi_x86_64, dwarf_rsi_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_rsi_x86_64},
+ {dwarf_rsi_x86_64, dwarf_rsi_x86_64, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_rsi_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(r8, nullptr),
- {dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_r8_x86_64},
+ {dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_r8_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(r9, nullptr),
- {dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_r9_x86_64},
+ {dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_r9_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(r10, nullptr),
- {dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_r10_x86_64},
+ {dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_r10_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(r11, nullptr),
- {dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_r11_x86_64},
+ {dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_r11_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(r12, nullptr),
- {dwarf_r12_x86_64, dwarf_r12_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_r12_x86_64},
+ {dwarf_r12_x86_64, dwarf_r12_x86_64, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_r12_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(r13, nullptr),
- {dwarf_r13_x86_64, dwarf_r13_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_r13_x86_64},
+ {dwarf_r13_x86_64, dwarf_r13_x86_64, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_r13_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(r14, nullptr),
- {dwarf_r14_x86_64, dwarf_r14_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_r14_x86_64},
+ {dwarf_r14_x86_64, dwarf_r14_x86_64, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_r14_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(r15, nullptr),
- {dwarf_r15_x86_64, dwarf_r15_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_r15_x86_64},
+ {dwarf_r15_x86_64, dwarf_r15_x86_64, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_r15_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(rbp, "fp"),
- {dwarf_rbp_x86_64, dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, lldb_rbp_x86_64},
+ {dwarf_rbp_x86_64, dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP,
+ LLDB_INVALID_REGNUM, lldb_rbp_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(rsp, "sp"),
- {dwarf_rsp_x86_64, dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, lldb_rsp_x86_64},
+ {dwarf_rsp_x86_64, dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP,
+ LLDB_INVALID_REGNUM, lldb_rsp_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(rip, "pc"),
- {dwarf_rip_x86_64, dwarf_rip_x86_64, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, lldb_rip_x86_64},
+ {dwarf_rip_x86_64, dwarf_rip_x86_64, LLDB_REGNUM_GENERIC_PC,
+ LLDB_INVALID_REGNUM, lldb_rip_x86_64},
nullptr,
nullptr},
{DEFINE_GPR_BIN(eflags, "flags"),
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, lldb_rflags_x86_64},
+ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS,
+ LLDB_INVALID_REGNUM, lldb_rflags_x86_64},
nullptr,
nullptr},
};
static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
-// Array of lldb register numbers used to define the set of all General Purpose Registers
-uint32_t g_gpr_reg_indices[] = {eRegisterIndexRax, eRegisterIndexRbx, eRegisterIndexRcx, eRegisterIndexRdx,
- eRegisterIndexRdi, eRegisterIndexRsi, eRegisterIndexR8, eRegisterIndexR9,
- eRegisterIndexR10, eRegisterIndexR11, eRegisterIndexR12, eRegisterIndexR13,
- eRegisterIndexR14, eRegisterIndexR15, eRegisterIndexRbp, eRegisterIndexRsp,
- eRegisterIndexRip, eRegisterIndexRflags};
+// Array of lldb register numbers used to define the set of all General Purpose
+// Registers
+uint32_t g_gpr_reg_indices[] = {
+ eRegisterIndexRax, eRegisterIndexRbx, eRegisterIndexRcx,
+ eRegisterIndexRdx, eRegisterIndexRdi, eRegisterIndexRsi,
+ eRegisterIndexR8, eRegisterIndexR9, eRegisterIndexR10,
+ eRegisterIndexR11, eRegisterIndexR12, eRegisterIndexR13,
+ eRegisterIndexR14, eRegisterIndexR15, eRegisterIndexRbp,
+ eRegisterIndexRsp, eRegisterIndexRip, eRegisterIndexRflags};
RegisterSet g_register_sets[] = {
- {"General Purpose Registers", "gpr", llvm::array_lengthof(g_gpr_reg_indices), g_gpr_reg_indices},
+ {"General Purpose Registers", "gpr",
+ llvm::array_lengthof(g_gpr_reg_indices), g_gpr_reg_indices},
};
}
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
-RegisterContextWindows_x64::RegisterContextWindows_x64(Thread &thread, uint32_t concrete_frame_idx)
- : RegisterContextWindows(thread, concrete_frame_idx)
-{
-}
+RegisterContextWindows_x64::RegisterContextWindows_x64(
+ Thread &thread, uint32_t concrete_frame_idx)
+ : RegisterContextWindows(thread, concrete_frame_idx) {}
-RegisterContextWindows_x64::~RegisterContextWindows_x64()
-{
-}
+RegisterContextWindows_x64::~RegisterContextWindows_x64() {}
-size_t
-RegisterContextWindows_x64::GetRegisterCount()
-{
- return llvm::array_lengthof(g_register_infos);
+size_t RegisterContextWindows_x64::GetRegisterCount() {
+ return llvm::array_lengthof(g_register_infos);
}
const RegisterInfo *
-RegisterContextWindows_x64::GetRegisterInfoAtIndex(size_t reg)
-{
- if (reg < k_num_register_infos)
- return &g_register_infos[reg];
- return NULL;
+RegisterContextWindows_x64::GetRegisterInfoAtIndex(size_t reg) {
+ if (reg < k_num_register_infos)
+ return &g_register_infos[reg];
+ return NULL;
}
-size_t
-RegisterContextWindows_x64::GetRegisterSetCount()
-{
- return llvm::array_lengthof(g_register_sets);
+size_t RegisterContextWindows_x64::GetRegisterSetCount() {
+ return llvm::array_lengthof(g_register_sets);
}
-const RegisterSet *
-RegisterContextWindows_x64::GetRegisterSet(size_t reg_set)
-{
- return &g_register_sets[reg_set];
+const RegisterSet *RegisterContextWindows_x64::GetRegisterSet(size_t reg_set) {
+ return &g_register_sets[reg_set];
}
-bool
-RegisterContextWindows_x64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value)
-{
- if (!CacheAllRegisterValues())
- return false;
+bool RegisterContextWindows_x64::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) {
+ if (!CacheAllRegisterValues())
+ return false;
- switch (reg_info->kinds[eRegisterKindLLDB])
- {
- case lldb_rax_x86_64:
- reg_value.SetUInt64(m_context.Rax);
- break;
- case lldb_rbx_x86_64:
- reg_value.SetUInt64(m_context.Rbx);
- break;
- case lldb_rcx_x86_64:
- reg_value.SetUInt64(m_context.Rcx);
- break;
- case lldb_rdx_x86_64:
- reg_value.SetUInt64(m_context.Rdx);
- break;
- case lldb_rdi_x86_64:
- reg_value.SetUInt64(m_context.Rdi);
- break;
- case lldb_rsi_x86_64:
- reg_value.SetUInt64(m_context.Rsi);
- break;
- case lldb_r8_x86_64:
- reg_value.SetUInt64(m_context.R8);
- break;
- case lldb_r9_x86_64:
- reg_value.SetUInt64(m_context.R9);
- break;
- case lldb_r10_x86_64:
- reg_value.SetUInt64(m_context.R10);
- break;
- case lldb_r11_x86_64:
- reg_value.SetUInt64(m_context.R11);
- break;
- case lldb_r12_x86_64:
- reg_value.SetUInt64(m_context.R12);
- break;
- case lldb_r13_x86_64:
- reg_value.SetUInt64(m_context.R13);
- break;
- case lldb_r14_x86_64:
- reg_value.SetUInt64(m_context.R14);
- break;
- case lldb_r15_x86_64:
- reg_value.SetUInt64(m_context.R15);
- break;
- case lldb_rbp_x86_64:
- reg_value.SetUInt64(m_context.Rbp);
- break;
- case lldb_rsp_x86_64:
- reg_value.SetUInt64(m_context.Rsp);
- break;
- case lldb_rip_x86_64:
- reg_value.SetUInt64(m_context.Rip);
- break;
- case lldb_rflags_x86_64:
- reg_value.SetUInt64(m_context.EFlags);
- break;
- }
- return true;
+ switch (reg_info->kinds[eRegisterKindLLDB]) {
+ case lldb_rax_x86_64:
+ reg_value.SetUInt64(m_context.Rax);
+ break;
+ case lldb_rbx_x86_64:
+ reg_value.SetUInt64(m_context.Rbx);
+ break;
+ case lldb_rcx_x86_64:
+ reg_value.SetUInt64(m_context.Rcx);
+ break;
+ case lldb_rdx_x86_64:
+ reg_value.SetUInt64(m_context.Rdx);
+ break;
+ case lldb_rdi_x86_64:
+ reg_value.SetUInt64(m_context.Rdi);
+ break;
+ case lldb_rsi_x86_64:
+ reg_value.SetUInt64(m_context.Rsi);
+ break;
+ case lldb_r8_x86_64:
+ reg_value.SetUInt64(m_context.R8);
+ break;
+ case lldb_r9_x86_64:
+ reg_value.SetUInt64(m_context.R9);
+ break;
+ case lldb_r10_x86_64:
+ reg_value.SetUInt64(m_context.R10);
+ break;
+ case lldb_r11_x86_64:
+ reg_value.SetUInt64(m_context.R11);
+ break;
+ case lldb_r12_x86_64:
+ reg_value.SetUInt64(m_context.R12);
+ break;
+ case lldb_r13_x86_64:
+ reg_value.SetUInt64(m_context.R13);
+ break;
+ case lldb_r14_x86_64:
+ reg_value.SetUInt64(m_context.R14);
+ break;
+ case lldb_r15_x86_64:
+ reg_value.SetUInt64(m_context.R15);
+ break;
+ case lldb_rbp_x86_64:
+ reg_value.SetUInt64(m_context.Rbp);
+ break;
+ case lldb_rsp_x86_64:
+ reg_value.SetUInt64(m_context.Rsp);
+ break;
+ case lldb_rip_x86_64:
+ reg_value.SetUInt64(m_context.Rip);
+ break;
+ case lldb_rflags_x86_64:
+ reg_value.SetUInt64(m_context.EFlags);
+ break;
+ }
+ return true;
}
-bool
-RegisterContextWindows_x64::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value)
-{
- // Since we cannot only write a single register value to the inferior, we need to make sure
- // our cached copy of the register values are fresh. Otherwise when writing EAX, for example,
- // we may also overwrite some other register with a stale value.
- if (!CacheAllRegisterValues())
- return false;
+bool RegisterContextWindows_x64::WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) {
+ // Since we cannot only write a single register value to the inferior, we need
+ // to make sure
+ // our cached copy of the register values are fresh. Otherwise when writing
+ // EAX, for example,
+ // we may also overwrite some other register with a stale value.
+ if (!CacheAllRegisterValues())
+ return false;
- switch (reg_info->kinds[eRegisterKindLLDB])
- {
- case lldb_rax_x86_64:
- m_context.Rax = reg_value.GetAsUInt64();
- break;
- case lldb_rbx_x86_64:
- m_context.Rbx = reg_value.GetAsUInt64();
- break;
- case lldb_rcx_x86_64:
- m_context.Rcx = reg_value.GetAsUInt64();
- break;
- case lldb_rdx_x86_64:
- m_context.Rdx = reg_value.GetAsUInt64();
- break;
- case lldb_rdi_x86_64:
- m_context.Rdi = reg_value.GetAsUInt64();
- break;
- case lldb_rsi_x86_64:
- m_context.Rsi = reg_value.GetAsUInt64();
- break;
- case lldb_r8_x86_64:
- m_context.R8 = reg_value.GetAsUInt64();
- break;
- case lldb_r9_x86_64:
- m_context.R9 = reg_value.GetAsUInt64();
- break;
- case lldb_r10_x86_64:
- m_context.R10 = reg_value.GetAsUInt64();
- break;
- case lldb_r11_x86_64:
- m_context.R11 = reg_value.GetAsUInt64();
- break;
- case lldb_r12_x86_64:
- m_context.R12 = reg_value.GetAsUInt64();
- break;
- case lldb_r13_x86_64:
- m_context.R13 = reg_value.GetAsUInt64();
- break;
- case lldb_r14_x86_64:
- m_context.R14 = reg_value.GetAsUInt64();
- break;
- case lldb_r15_x86_64:
- m_context.R15 = reg_value.GetAsUInt64();
- break;
- case lldb_rbp_x86_64:
- m_context.Rbp = reg_value.GetAsUInt64();
- break;
- case lldb_rsp_x86_64:
- m_context.Rsp = reg_value.GetAsUInt64();
- break;
- case lldb_rip_x86_64:
- m_context.Rip = reg_value.GetAsUInt64();
- break;
- case lldb_rflags_x86_64:
- m_context.EFlags = reg_value.GetAsUInt64();
- break;
- }
+ switch (reg_info->kinds[eRegisterKindLLDB]) {
+ case lldb_rax_x86_64:
+ m_context.Rax = reg_value.GetAsUInt64();
+ break;
+ case lldb_rbx_x86_64:
+ m_context.Rbx = reg_value.GetAsUInt64();
+ break;
+ case lldb_rcx_x86_64:
+ m_context.Rcx = reg_value.GetAsUInt64();
+ break;
+ case lldb_rdx_x86_64:
+ m_context.Rdx = reg_value.GetAsUInt64();
+ break;
+ case lldb_rdi_x86_64:
+ m_context.Rdi = reg_value.GetAsUInt64();
+ break;
+ case lldb_rsi_x86_64:
+ m_context.Rsi = reg_value.GetAsUInt64();
+ break;
+ case lldb_r8_x86_64:
+ m_context.R8 = reg_value.GetAsUInt64();
+ break;
+ case lldb_r9_x86_64:
+ m_context.R9 = reg_value.GetAsUInt64();
+ break;
+ case lldb_r10_x86_64:
+ m_context.R10 = reg_value.GetAsUInt64();
+ break;
+ case lldb_r11_x86_64:
+ m_context.R11 = reg_value.GetAsUInt64();
+ break;
+ case lldb_r12_x86_64:
+ m_context.R12 = reg_value.GetAsUInt64();
+ break;
+ case lldb_r13_x86_64:
+ m_context.R13 = reg_value.GetAsUInt64();
+ break;
+ case lldb_r14_x86_64:
+ m_context.R14 = reg_value.GetAsUInt64();
+ break;
+ case lldb_r15_x86_64:
+ m_context.R15 = reg_value.GetAsUInt64();
+ break;
+ case lldb_rbp_x86_64:
+ m_context.Rbp = reg_value.GetAsUInt64();
+ break;
+ case lldb_rsp_x86_64:
+ m_context.Rsp = reg_value.GetAsUInt64();
+ break;
+ case lldb_rip_x86_64:
+ m_context.Rip = reg_value.GetAsUInt64();
+ break;
+ case lldb_rflags_x86_64:
+ m_context.EFlags = reg_value.GetAsUInt64();
+ break;
+ }
- // Physically update the registers in the target process.
- TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
- return ::SetThreadContext(wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context);
+ // Physically update the registers in the target process.
+ TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
+ return ::SetThreadContext(
+ wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context);
}
diff --git a/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.h b/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.h
index e69179d99c6c..62cedc8fbab0 100644
--- a/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.h
+++ b/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.h
@@ -10,38 +10,38 @@
#ifndef liblldb_RegisterContextWindows_x64_H_
#define liblldb_RegisterContextWindows_x64_H_
-#include "lldb/lldb-forward.h"
#include "RegisterContextWindows.h"
+#include "lldb/lldb-forward.h"
-namespace lldb_private
-{
+namespace lldb_private {
class Thread;
-class RegisterContextWindows_x64 : public RegisterContextWindows
-{
- public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- RegisterContextWindows_x64(Thread &thread, uint32_t concrete_frame_idx);
+class RegisterContextWindows_x64 : public RegisterContextWindows {
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ RegisterContextWindows_x64(Thread &thread, uint32_t concrete_frame_idx);
- virtual ~RegisterContextWindows_x64();
+ virtual ~RegisterContextWindows_x64();
- //------------------------------------------------------------------
- // Subclasses must override these functions
- //------------------------------------------------------------------
- size_t GetRegisterCount() override;
+ //------------------------------------------------------------------
+ // Subclasses must override these functions
+ //------------------------------------------------------------------
+ size_t GetRegisterCount() override;
- const RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
+ const RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
- size_t GetRegisterSetCount() override;
+ size_t GetRegisterSetCount() override;
- const RegisterSet *GetRegisterSet(size_t reg_set) override;
+ const RegisterSet *GetRegisterSet(size_t reg_set) override;
- bool ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value) override;
+ bool ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) override;
- bool WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value) override;
+ bool WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) override;
};
}
diff --git a/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp b/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp
index 11733eee7cb4..2938f77f3c2a 100644
--- a/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp
+++ b/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp
@@ -7,16 +7,17 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-private-types.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Host/windows/HostThreadWindows.h"
#include "lldb/Host/windows/windows.h"
+#include "lldb/lldb-private-types.h"
-#include "lldb-x86-register-enums.h"
#include "ProcessWindowsLog.h"
-#include "RegisterContext_x86.h"
#include "RegisterContextWindows_x86.h"
+#include "RegisterContext_x86.h"
+#include "TargetThreadWindows.h"
+#include "lldb-x86-register-enums.h"
#include "llvm/ADT/STLExtras.h"
@@ -26,150 +27,272 @@ using namespace lldb_private;
#define DEFINE_GPR(reg, alt) #reg, alt, 4, 0, eEncodingUint, eFormatHexUppercase
#define DEFINE_GPR_BIN(reg, alt) #reg, alt, 4, 0, eEncodingUint, eFormatBinary
-namespace
-{
+namespace {
-// This enum defines the layout of the global RegisterInfo array. This is necessary because
-// lldb register sets are defined in terms of indices into the register array. As such, the
-// order of RegisterInfos defined in global registers array must match the order defined here.
-// When defining the register set layouts, these values can appear in an arbitrary order, and that
+// This enum defines the layout of the global RegisterInfo array. This is
+// necessary because
+// lldb register sets are defined in terms of indices into the register array.
+// As such, the
+// order of RegisterInfos defined in global registers array must match the order
+// defined here.
+// When defining the register set layouts, these values can appear in an
+// arbitrary order, and that
// determines the order that register values are displayed in a dump.
-enum RegisterIndex
-{
- eRegisterIndexEax,
- eRegisterIndexEbx,
- eRegisterIndexEcx,
- eRegisterIndexEdx,
- eRegisterIndexEdi,
- eRegisterIndexEsi,
- eRegisterIndexEbp,
- eRegisterIndexEsp,
- eRegisterIndexEip,
- eRegisterIndexEflags
+enum RegisterIndex {
+ eRegisterIndexEax,
+ eRegisterIndexEbx,
+ eRegisterIndexEcx,
+ eRegisterIndexEdx,
+ eRegisterIndexEdi,
+ eRegisterIndexEsi,
+ eRegisterIndexEbp,
+ eRegisterIndexEsp,
+ eRegisterIndexEip,
+ eRegisterIndexEflags
};
// Array of all register information supported by Windows x86
-RegisterInfo g_register_infos[] =
-{
-// Macro auto defines most stuff eh_frame DWARF GENERIC GDB LLDB VALUE REGS INVALIDATE REGS
-// ============================== ======================= =================== ========================= =================== ================= ========== ===============
- { DEFINE_GPR(eax, nullptr), { ehframe_eax_i386, dwarf_eax_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_eax_i386 }, nullptr, nullptr},
- { DEFINE_GPR(ebx, nullptr), { ehframe_ebx_i386, dwarf_ebx_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_ebx_i386 }, nullptr, nullptr},
- { DEFINE_GPR(ecx, nullptr), { ehframe_ecx_i386, dwarf_ecx_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_ecx_i386 }, nullptr, nullptr},
- { DEFINE_GPR(edx, nullptr), { ehframe_edx_i386, dwarf_edx_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_edx_i386 }, nullptr, nullptr},
- { DEFINE_GPR(edi, nullptr), { ehframe_edi_i386, dwarf_edi_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_edi_i386 }, nullptr, nullptr},
- { DEFINE_GPR(esi, nullptr), { ehframe_esi_i386, dwarf_esi_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_esi_i386 }, nullptr, nullptr},
- { DEFINE_GPR(ebp, "fp"), { ehframe_ebp_i386, dwarf_ebp_i386, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, lldb_ebp_i386 }, nullptr, nullptr},
- { DEFINE_GPR(esp, "sp"), { ehframe_esp_i386, dwarf_esp_i386, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, lldb_esp_i386 }, nullptr, nullptr},
- { DEFINE_GPR(eip, "pc"), { ehframe_eip_i386, dwarf_eip_i386, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, lldb_eip_i386 }, nullptr, nullptr},
- { DEFINE_GPR_BIN(eflags, "flags"), { ehframe_eflags_i386, dwarf_eflags_i386, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, lldb_eflags_i386}, nullptr, nullptr},
+RegisterInfo g_register_infos[] = {
+ // Macro auto defines most stuff eh_frame DWARF
+ // GENERIC GDB LLDB
+ // VALUE REGS INVALIDATE REGS
+ // ============================== =======================
+ // =================== ========================= ===================
+ // ================= ========== ===============
+ {DEFINE_GPR(eax, nullptr),
+ {ehframe_eax_i386, dwarf_eax_i386, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_eax_i386},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0u},
+ {DEFINE_GPR(ebx, nullptr),
+ {ehframe_ebx_i386, dwarf_ebx_i386, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_ebx_i386},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0u},
+ {DEFINE_GPR(ecx, nullptr),
+ {ehframe_ecx_i386, dwarf_ecx_i386, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_ecx_i386},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0u},
+ {DEFINE_GPR(edx, nullptr),
+ {ehframe_edx_i386, dwarf_edx_i386, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_edx_i386},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0u},
+ {DEFINE_GPR(edi, nullptr),
+ {ehframe_edi_i386, dwarf_edi_i386, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_edi_i386},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0u},
+ {DEFINE_GPR(esi, nullptr),
+ {ehframe_esi_i386, dwarf_esi_i386, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, lldb_esi_i386},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0u},
+ {DEFINE_GPR(ebp, "fp"),
+ {ehframe_ebp_i386, dwarf_ebp_i386, LLDB_REGNUM_GENERIC_FP,
+ LLDB_INVALID_REGNUM, lldb_ebp_i386},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0u},
+ {DEFINE_GPR(esp, "sp"),
+ {ehframe_esp_i386, dwarf_esp_i386, LLDB_REGNUM_GENERIC_SP,
+ LLDB_INVALID_REGNUM, lldb_esp_i386},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0u},
+ {DEFINE_GPR(eip, "pc"),
+ {ehframe_eip_i386, dwarf_eip_i386, LLDB_REGNUM_GENERIC_PC,
+ LLDB_INVALID_REGNUM, lldb_eip_i386},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0u},
+ {DEFINE_GPR_BIN(eflags, "flags"),
+ {ehframe_eflags_i386, dwarf_eflags_i386, LLDB_REGNUM_GENERIC_FLAGS,
+ LLDB_INVALID_REGNUM, lldb_eflags_i386},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0u},
};
static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
-// Array of lldb register numbers used to define the set of all General Purpose Registers
-uint32_t g_gpr_reg_indices[] =
-{
- eRegisterIndexEax,
- eRegisterIndexEbx,
- eRegisterIndexEcx,
- eRegisterIndexEdx,
- eRegisterIndexEdi,
- eRegisterIndexEsi,
- eRegisterIndexEbp,
- eRegisterIndexEsp,
- eRegisterIndexEip,
- eRegisterIndexEflags
-};
+// Array of lldb register numbers used to define the set of all General Purpose
+// Registers
+uint32_t g_gpr_reg_indices[] = {eRegisterIndexEax, eRegisterIndexEbx,
+ eRegisterIndexEcx, eRegisterIndexEdx,
+ eRegisterIndexEdi, eRegisterIndexEsi,
+ eRegisterIndexEbp, eRegisterIndexEsp,
+ eRegisterIndexEip, eRegisterIndexEflags};
RegisterSet g_register_sets[] = {
- {"General Purpose Registers", "gpr", llvm::array_lengthof(g_gpr_reg_indices), g_gpr_reg_indices},
+ {"General Purpose Registers", "gpr",
+ llvm::array_lengthof(g_gpr_reg_indices), g_gpr_reg_indices},
};
}
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
-RegisterContextWindows_x86::RegisterContextWindows_x86(Thread &thread, uint32_t concrete_frame_idx)
- : RegisterContextWindows(thread, concrete_frame_idx)
-{
-}
+RegisterContextWindows_x86::RegisterContextWindows_x86(
+ Thread &thread, uint32_t concrete_frame_idx)
+ : RegisterContextWindows(thread, concrete_frame_idx) {}
-RegisterContextWindows_x86::~RegisterContextWindows_x86()
-{
-}
+RegisterContextWindows_x86::~RegisterContextWindows_x86() {}
-size_t
-RegisterContextWindows_x86::GetRegisterCount()
-{
- return llvm::array_lengthof(g_register_infos);
+size_t RegisterContextWindows_x86::GetRegisterCount() {
+ return llvm::array_lengthof(g_register_infos);
}
const RegisterInfo *
-RegisterContextWindows_x86::GetRegisterInfoAtIndex(size_t reg)
-{
- if (reg < k_num_register_infos)
- return &g_register_infos[reg];
- return NULL;
+RegisterContextWindows_x86::GetRegisterInfoAtIndex(size_t reg) {
+ if (reg < k_num_register_infos)
+ return &g_register_infos[reg];
+ return NULL;
+}
+
+size_t RegisterContextWindows_x86::GetRegisterSetCount() {
+ return llvm::array_lengthof(g_register_sets);
}
-size_t
-RegisterContextWindows_x86::GetRegisterSetCount()
-{
- return llvm::array_lengthof(g_register_sets);
+const RegisterSet *RegisterContextWindows_x86::GetRegisterSet(size_t reg_set) {
+ return &g_register_sets[reg_set];
}
-const RegisterSet *
-RegisterContextWindows_x86::GetRegisterSet(size_t reg_set)
-{
- return &g_register_sets[reg_set];
+bool RegisterContextWindows_x86::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) {
+ if (!CacheAllRegisterValues())
+ return false;
+
+ uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+ switch (reg) {
+ case lldb_eax_i386:
+ return ReadRegisterHelper(CONTEXT_INTEGER, "EAX", m_context.Eax, reg_value);
+ case lldb_ebx_i386:
+ return ReadRegisterHelper(CONTEXT_INTEGER, "EBX", m_context.Ebx, reg_value);
+ case lldb_ecx_i386:
+ return ReadRegisterHelper(CONTEXT_INTEGER, "ECX", m_context.Ecx, reg_value);
+ case lldb_edx_i386:
+ return ReadRegisterHelper(CONTEXT_INTEGER, "EDX", m_context.Edx, reg_value);
+ case lldb_edi_i386:
+ return ReadRegisterHelper(CONTEXT_INTEGER, "EDI", m_context.Edi, reg_value);
+ case lldb_esi_i386:
+ return ReadRegisterHelper(CONTEXT_INTEGER, "ESI", m_context.Esi, reg_value);
+ case lldb_ebp_i386:
+ return ReadRegisterHelper(CONTEXT_CONTROL, "EBP", m_context.Ebp, reg_value);
+ case lldb_esp_i386:
+ return ReadRegisterHelper(CONTEXT_CONTROL, "ESP", m_context.Esp, reg_value);
+ case lldb_eip_i386:
+ return ReadRegisterHelper(CONTEXT_CONTROL, "EIP", m_context.Eip, reg_value);
+ case lldb_eflags_i386:
+ return ReadRegisterHelper(CONTEXT_CONTROL, "EFLAGS", m_context.EFlags,
+ reg_value);
+ default:
+ WINWARN_IFALL(WINDOWS_LOG_REGISTERS, "Requested unknown register %u", reg);
+ break;
+ }
+ return false;
}
-bool
-RegisterContextWindows_x86::ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value)
-{
- if (!CacheAllRegisterValues())
- return false;
-
- uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- switch (reg)
- {
- case lldb_eax_i386:
- return ReadRegisterHelper(CONTEXT_INTEGER, "EAX", m_context.Eax, reg_value);
- case lldb_ebx_i386:
- return ReadRegisterHelper(CONTEXT_INTEGER, "EBX", m_context.Ebx, reg_value);
- case lldb_ecx_i386:
- return ReadRegisterHelper(CONTEXT_INTEGER, "ECX", m_context.Ecx, reg_value);
- case lldb_edx_i386:
- return ReadRegisterHelper(CONTEXT_INTEGER, "EDX", m_context.Edx, reg_value);
- case lldb_edi_i386:
- return ReadRegisterHelper(CONTEXT_INTEGER, "EDI", m_context.Edi, reg_value);
- case lldb_esi_i386:
- return ReadRegisterHelper(CONTEXT_INTEGER, "ESI", m_context.Esi, reg_value);
- case lldb_ebp_i386:
- return ReadRegisterHelper(CONTEXT_CONTROL, "EBP", m_context.Ebp, reg_value);
- case lldb_esp_i386:
- return ReadRegisterHelper(CONTEXT_CONTROL, "ESP", m_context.Esp, reg_value);
- case lldb_eip_i386:
- return ReadRegisterHelper(CONTEXT_CONTROL, "EIP", m_context.Eip, reg_value);
- case lldb_eflags_i386:
- return ReadRegisterHelper(CONTEXT_CONTROL, "EFLAGS", m_context.EFlags, reg_value);
- default:
- WINWARN_IFALL(WINDOWS_LOG_REGISTERS, "Requested unknown register %u", reg);
- break;
- }
+bool RegisterContextWindows_x86::WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) {
+ // Since we cannot only write a single register value to the inferior, we need
+ // to make sure
+ // our cached copy of the register values are fresh. Otherwise when writing
+ // EAX, for example,
+ // we may also overwrite some other register with a stale value.
+ if (!CacheAllRegisterValues())
return false;
+
+ uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+ switch (reg) {
+ case lldb_eax_i386:
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EAX",
+ reg_value.GetAsUInt32());
+ m_context.Eax = reg_value.GetAsUInt32();
+ break;
+ case lldb_ebx_i386:
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EBX",
+ reg_value.GetAsUInt32());
+ m_context.Ebx = reg_value.GetAsUInt32();
+ break;
+ case lldb_ecx_i386:
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to ECX",
+ reg_value.GetAsUInt32());
+ m_context.Ecx = reg_value.GetAsUInt32();
+ break;
+ case lldb_edx_i386:
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EDX",
+ reg_value.GetAsUInt32());
+ m_context.Edx = reg_value.GetAsUInt32();
+ break;
+ case lldb_edi_i386:
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EDI",
+ reg_value.GetAsUInt32());
+ m_context.Edi = reg_value.GetAsUInt32();
+ break;
+ case lldb_esi_i386:
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to ESI",
+ reg_value.GetAsUInt32());
+ m_context.Esi = reg_value.GetAsUInt32();
+ break;
+ case lldb_ebp_i386:
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EBP",
+ reg_value.GetAsUInt32());
+ m_context.Ebp = reg_value.GetAsUInt32();
+ break;
+ case lldb_esp_i386:
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to ESP",
+ reg_value.GetAsUInt32());
+ m_context.Esp = reg_value.GetAsUInt32();
+ break;
+ case lldb_eip_i386:
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EIP",
+ reg_value.GetAsUInt32());
+ m_context.Eip = reg_value.GetAsUInt32();
+ break;
+ case lldb_eflags_i386:
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EFLAGS",
+ reg_value.GetAsUInt32());
+ m_context.EFlags = reg_value.GetAsUInt32();
+ break;
+ default:
+ WINWARN_IFALL(WINDOWS_LOG_REGISTERS,
+ "Write value 0x%x to unknown register %u",
+ reg_value.GetAsUInt32(), reg);
+ }
+
+ // Physically update the registers in the target process.
+ TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
+ return ::SetThreadContext(
+ wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context);
}
-bool
-RegisterContextWindows_x86::ReadRegisterHelper(DWORD flags_required, const char *reg_name, DWORD value,
- RegisterValue &reg_value) const
-{
- if ((m_context.ContextFlags & flags_required) != flags_required)
- {
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Thread context doesn't have %s", reg_name);
- return false;
- }
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from %s", value, reg_name);
- reg_value.SetUInt32(value);
- return true;
+bool RegisterContextWindows_x86::ReadRegisterHelper(
+ DWORD flags_required, const char *reg_name, DWORD value,
+ RegisterValue &reg_value) const {
+ if ((m_context.ContextFlags & flags_required) != flags_required) {
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Thread context doesn't have %s",
+ reg_name);
+ return false;
+ }
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%lx from %s", value,
+ reg_name);
+ reg_value.SetUInt32(value);
+ return true;
}
diff --git a/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.h b/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.h
index 6c29d54dcae2..aae645fdb5a3 100644
--- a/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.h
+++ b/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.h
@@ -10,42 +10,43 @@
#ifndef liblldb_RegisterContextWindows_x86_H_
#define liblldb_RegisterContextWindows_x86_H_
-#include "lldb/lldb-forward.h"
#include "RegisterContextWindows.h"
+#include "lldb/lldb-forward.h"
-namespace lldb_private
-{
+namespace lldb_private {
class Thread;
-class RegisterContextWindows_x86 : public RegisterContextWindows
-{
- public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- RegisterContextWindows_x86(Thread &thread, uint32_t concrete_frame_idx);
+class RegisterContextWindows_x86 : public RegisterContextWindows {
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ RegisterContextWindows_x86(Thread &thread, uint32_t concrete_frame_idx);
- virtual ~RegisterContextWindows_x86();
+ virtual ~RegisterContextWindows_x86();
- //------------------------------------------------------------------
- // Subclasses must override these functions
- //------------------------------------------------------------------
- size_t GetRegisterCount() override;
+ //------------------------------------------------------------------
+ // Subclasses must override these functions
+ //------------------------------------------------------------------
+ size_t GetRegisterCount() override;
- const RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
+ const RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
- size_t GetRegisterSetCount() override;
+ size_t GetRegisterSetCount() override;
- const RegisterSet *GetRegisterSet(size_t reg_set) override;
+ const RegisterSet *GetRegisterSet(size_t reg_set) override;
- bool ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value) override;
+ bool ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) override;
+
+ bool WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) override;
private:
- bool
- ReadRegisterHelper(DWORD flags_required, const char *reg_name, DWORD value, RegisterValue &reg_value) const;
+ bool ReadRegisterHelper(DWORD flags_required, const char *reg_name,
+ DWORD value, RegisterValue &reg_value) const;
};
-
}
#endif // #ifndef liblldb_RegisterContextWindows_x86_H_
diff --git a/source/Plugins/Process/Windows/Live/CMakeLists.txt b/source/Plugins/Process/Windows/Live/CMakeLists.txt
deleted file mode 100644
index bdb680ad0bee..000000000000
--- a/source/Plugins/Process/Windows/Live/CMakeLists.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-include_directories(.)
-include_directories(../../Utility)
-include_directories(../Common)
-
-set(PROC_WINDOWS_SOURCES
- DebuggerThread.cpp
- LocalDebugDelegate.cpp
- ProcessWindowsLive.cpp
- TargetThreadWindowsLive.cpp
- )
-
-if (CMAKE_SIZEOF_VOID_P EQUAL 4)
- set(PROC_WINDOWS_SOURCES ${PROC_WINDOWS_SOURCES}
- x86/RegisterContextWindowsLive_x86.cpp
- )
-elseif (CMAKE_SIZEOF_VOID_P EQUAL 8)
- set(PROC_WINDOWS_SOURCES ${PROC_WINDOWS_SOURCES}
- x64/RegisterContextWindowsLive_x64.cpp
- )
-endif()
-
-add_lldb_library(lldbPluginProcessWindows
- ${PROC_WINDOWS_SOURCES}
- )
diff --git a/source/Plugins/Process/Windows/Live/DebuggerThread.cpp b/source/Plugins/Process/Windows/Live/DebuggerThread.cpp
deleted file mode 100644
index 2823474cbd5e..000000000000
--- a/source/Plugins/Process/Windows/Live/DebuggerThread.cpp
+++ /dev/null
@@ -1,549 +0,0 @@
-//===-- DebuggerThread.DebuggerThread --------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "DebuggerThread.h"
-#include "ExceptionRecord.h"
-#include "IDebugDelegate.h"
-
-#include "lldb/Core/Error.h"
-#include "lldb/Core/Log.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Host/FileSpec.h"
-#include "lldb/Host/Predicate.h"
-#include "lldb/Host/ThisThread.h"
-#include "lldb/Host/ThreadLauncher.h"
-#include "lldb/Host/windows/HostProcessWindows.h"
-#include "lldb/Host/windows/HostThreadWindows.h"
-#include "lldb/Host/windows/ProcessLauncherWindows.h"
-#include "lldb/Target/ProcessLaunchInfo.h"
-#include "lldb/Target/Process.h"
-
-#include "Plugins/Process/Windows/Common/ProcessWindowsLog.h"
-
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Support/ConvertUTF.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-namespace
-{
-struct DebugLaunchContext
-{
- DebugLaunchContext(DebuggerThread *thread, const ProcessLaunchInfo &launch_info)
- : m_thread(thread)
- , m_launch_info(launch_info)
- {
- }
- DebuggerThread *m_thread;
- ProcessLaunchInfo m_launch_info;
-};
-
-struct DebugAttachContext
-{
- DebugAttachContext(DebuggerThread *thread, lldb::pid_t pid, const ProcessAttachInfo &attach_info)
- : m_thread(thread)
- , m_pid(pid)
- , m_attach_info(attach_info)
- {
- }
- DebuggerThread *m_thread;
- lldb::pid_t m_pid;
- ProcessAttachInfo m_attach_info;
-};
-}
-
-DebuggerThread::DebuggerThread(DebugDelegateSP debug_delegate)
- : m_debug_delegate(debug_delegate)
- , m_image_file(nullptr)
- , m_debugging_ended_event(nullptr)
- , m_is_shutting_down(false)
- , m_pid_to_detach(0)
- , m_detached(false)
-{
- m_debugging_ended_event = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
-}
-
-DebuggerThread::~DebuggerThread()
-{
- ::CloseHandle(m_debugging_ended_event);
-}
-
-Error
-DebuggerThread::DebugLaunch(const ProcessLaunchInfo &launch_info)
-{
- WINLOG_IFALL(WINDOWS_LOG_PROCESS,
- "DebuggerThread::DebugLaunch launching '%s'", launch_info.GetExecutableFile().GetPath().c_str());
-
- Error error;
- DebugLaunchContext *context = new DebugLaunchContext(this, launch_info);
- HostThread slave_thread(ThreadLauncher::LaunchThread("lldb.plugin.process-windows.slave[?]",
- DebuggerThreadLaunchRoutine, context, &error));
-
- if (!error.Success())
- {
- WINERR_IFALL(WINDOWS_LOG_PROCESS,
- "DebugLaunch couldn't launch debugger thread. %s", error.AsCString());
- }
-
- return error;
-}
-
-Error
-DebuggerThread::DebugAttach(lldb::pid_t pid, const ProcessAttachInfo &attach_info)
-{
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DebuggerThread::DebugAttach attaching to '%u'", (DWORD)pid);
-
- Error error;
- DebugAttachContext *context = new DebugAttachContext(this, pid, attach_info);
- HostThread slave_thread(ThreadLauncher::LaunchThread("lldb.plugin.process-windows.slave[?]",
- DebuggerThreadAttachRoutine, context, &error));
-
- if (!error.Success())
- {
- WINERR_IFALL(WINDOWS_LOG_PROCESS, "DebugAttach couldn't attach to process '%u'. %s", (DWORD)pid,
- error.AsCString());
- }
-
- return error;
-}
-
-lldb::thread_result_t
-DebuggerThread::DebuggerThreadLaunchRoutine(void *data)
-{
- DebugLaunchContext *context = static_cast<DebugLaunchContext *>(data);
- lldb::thread_result_t result = context->m_thread->DebuggerThreadLaunchRoutine(context->m_launch_info);
- delete context;
- return result;
-}
-
-lldb::thread_result_t
-DebuggerThread::DebuggerThreadAttachRoutine(void *data)
-{
- DebugAttachContext *context = static_cast<DebugAttachContext *>(data);
- lldb::thread_result_t result =
- context->m_thread->DebuggerThreadAttachRoutine(context->m_pid, context->m_attach_info);
- delete context;
- return result;
-}
-
-lldb::thread_result_t
-DebuggerThread::DebuggerThreadLaunchRoutine(const ProcessLaunchInfo &launch_info)
-{
- // Grab a shared_ptr reference to this so that we know it won't get deleted until after the
- // thread routine has exited.
- std::shared_ptr<DebuggerThread> this_ref(shared_from_this());
-
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DebuggerThread preparing to launch '%s' on background thread.",
- launch_info.GetExecutableFile().GetPath().c_str());
-
- Error error;
- ProcessLauncherWindows launcher;
- HostProcess process(launcher.LaunchProcess(launch_info, error));
- // If we couldn't create the process, notify waiters immediately. Otherwise enter the debug
- // loop and wait until we get the create process debug notification. Note that if the process
- // was created successfully, we can throw away the process handle we got from CreateProcess
- // because Windows will give us another (potentially more useful?) handle when it sends us the
- // CREATE_PROCESS_DEBUG_EVENT.
- if (error.Success())
- DebugLoop();
- else
- m_debug_delegate->OnDebuggerError(error, 0);
-
- return 0;
-}
-
-lldb::thread_result_t
-DebuggerThread::DebuggerThreadAttachRoutine(lldb::pid_t pid, const ProcessAttachInfo &attach_info)
-{
- // Grab a shared_ptr reference to this so that we know it won't get deleted until after the
- // thread routine has exited.
- std::shared_ptr<DebuggerThread> this_ref(shared_from_this());
-
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DebuggerThread preparing to attach to process '%u' on background thread.",
- (DWORD)pid);
-
- if (!DebugActiveProcess((DWORD)pid))
- {
- Error error(::GetLastError(), eErrorTypeWin32);
- m_debug_delegate->OnDebuggerError(error, 0);
- return 0;
- }
-
- // The attach was successful, enter the debug loop. From here on out, this is no different than
- // a create process operation, so all the same comments in DebugLaunch should apply from this
- // point out.
- DebugLoop();
-
- return 0;
-}
-
-Error
-DebuggerThread::StopDebugging(bool terminate)
-{
- Error error;
-
- lldb::pid_t pid = m_process.GetProcessId();
-
- WINLOG_IFALL(WINDOWS_LOG_PROCESS,
- "StopDebugging('%s') called (inferior=%I64u).",
- (terminate ? "true" : "false"), pid);
-
- // Set m_is_shutting_down to true if it was false. Return if it was already true.
- bool expected = false;
- if (!m_is_shutting_down.compare_exchange_strong(expected, true))
- return error;
-
- // Make a copy of the process, since the termination sequence will reset
- // DebuggerThread's internal copy and it needs to remain open for the Wait operation.
- HostProcess process_copy = m_process;
- lldb::process_t handle = m_process.GetNativeProcess().GetSystemHandle();
-
- if (terminate)
- {
- // Initiate the termination before continuing the exception, so that the next debug
- // event we get is the exit process event, and not some other event.
- BOOL terminate_suceeded = TerminateProcess(handle, 0);
- WINLOG_IFALL(WINDOWS_LOG_PROCESS,
- "StopDebugging called TerminateProcess(0x%p, 0) (inferior=%I64u), success='%s'",
- handle, pid, (terminate_suceeded ? "true" : "false"));
- }
-
- // If we're stuck waiting for an exception to continue (e.g. the user is at a breakpoint
- // messing around in the debugger), continue it now. But only AFTER calling TerminateProcess
- // to make sure that the very next call to WaitForDebugEvent is an exit process event.
- if (m_active_exception.get())
- {
- WINLOG_IFANY(WINDOWS_LOG_PROCESS|WINDOWS_LOG_EXCEPTION,
- "StopDebugging masking active exception");
-
- ContinueAsyncException(ExceptionResult::MaskException);
- }
-
- if (!terminate)
- {
- // Indicate that we want to detach.
- m_pid_to_detach = GetProcess().GetProcessId();
-
- // Force a fresh break so that the detach can happen from the debugger thread.
- if (!::DebugBreakProcess(GetProcess().GetNativeProcess().GetSystemHandle()))
- {
- error.SetError(::GetLastError(), eErrorTypeWin32);
- }
- }
-
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "StopDebugging waiting for detach from process %u to complete.", pid);
-
- DWORD wait_result = WaitForSingleObject(m_debugging_ended_event, 5000);
- if (wait_result != WAIT_OBJECT_0)
- {
- error.SetError(GetLastError(), eErrorTypeWin32);
- WINERR_IFALL(WINDOWS_LOG_PROCESS, "StopDebugging WaitForSingleObject(0x%p, 5000) returned %u",
- m_debugging_ended_event, wait_result);
- }
- else
- {
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "StopDebugging detach from process %u completed successfully.", pid);
- }
-
- if (!error.Success())
- {
- WINERR_IFALL(WINDOWS_LOG_PROCESS,
- "StopDebugging encountered an error while trying to stop process %u. %s",
- pid, error.AsCString());
- }
- return error;
-}
-
-void
-DebuggerThread::ContinueAsyncException(ExceptionResult result)
-{
- if (!m_active_exception.get())
- return;
-
- WINLOG_IFANY(WINDOWS_LOG_PROCESS|WINDOWS_LOG_EXCEPTION,
- "ContinueAsyncException called for inferior process %I64u, broadcasting.",
- m_process.GetProcessId());
-
- m_active_exception.reset();
- m_exception_pred.SetValue(result, eBroadcastAlways);
-}
-
-void
-DebuggerThread::FreeProcessHandles()
-{
- m_process = HostProcess();
- m_main_thread = HostThread();
- if (m_image_file)
- {
- ::CloseHandle(m_image_file);
- m_image_file = nullptr;
- }
-}
-
-void
-DebuggerThread::DebugLoop()
-{
- DEBUG_EVENT dbe = {0};
- bool should_debug = true;
- WINLOG_IFALL(WINDOWS_LOG_EVENT, "Entering WaitForDebugEvent loop");
- while (should_debug)
- {
- WINLOGD_IFALL(WINDOWS_LOG_EVENT, "Calling WaitForDebugEvent");
- BOOL wait_result = WaitForDebugEvent(&dbe, INFINITE);
- if (wait_result)
- {
- DWORD continue_status = DBG_CONTINUE;
- switch (dbe.dwDebugEventCode)
- {
- case EXCEPTION_DEBUG_EVENT:
- {
- ExceptionResult status = HandleExceptionEvent(dbe.u.Exception, dbe.dwThreadId);
-
- if (status == ExceptionResult::MaskException)
- continue_status = DBG_CONTINUE;
- else if (status == ExceptionResult::SendToApplication)
- continue_status = DBG_EXCEPTION_NOT_HANDLED;
-
- break;
- }
- case CREATE_THREAD_DEBUG_EVENT:
- continue_status = HandleCreateThreadEvent(dbe.u.CreateThread, dbe.dwThreadId);
- break;
- case CREATE_PROCESS_DEBUG_EVENT:
- continue_status = HandleCreateProcessEvent(dbe.u.CreateProcessInfo, dbe.dwThreadId);
- break;
- case EXIT_THREAD_DEBUG_EVENT:
- continue_status = HandleExitThreadEvent(dbe.u.ExitThread, dbe.dwThreadId);
- break;
- case EXIT_PROCESS_DEBUG_EVENT:
- continue_status = HandleExitProcessEvent(dbe.u.ExitProcess, dbe.dwThreadId);
- should_debug = false;
- break;
- case LOAD_DLL_DEBUG_EVENT:
- continue_status = HandleLoadDllEvent(dbe.u.LoadDll, dbe.dwThreadId);
- break;
- case UNLOAD_DLL_DEBUG_EVENT:
- continue_status = HandleUnloadDllEvent(dbe.u.UnloadDll, dbe.dwThreadId);
- break;
- case OUTPUT_DEBUG_STRING_EVENT:
- continue_status = HandleODSEvent(dbe.u.DebugString, dbe.dwThreadId);
- break;
- case RIP_EVENT:
- continue_status = HandleRipEvent(dbe.u.RipInfo, dbe.dwThreadId);
- if (dbe.u.RipInfo.dwType == SLE_ERROR)
- should_debug = false;
- break;
- }
-
- WINLOGD_IFALL(WINDOWS_LOG_EVENT, "DebugLoop calling ContinueDebugEvent(%u, %u, %u) on thread %u.",
- dbe.dwProcessId, dbe.dwThreadId, continue_status, ::GetCurrentThreadId());
-
- ::ContinueDebugEvent(dbe.dwProcessId, dbe.dwThreadId, continue_status);
-
- if (m_detached)
- {
- should_debug = false;
- }
- }
- else
- {
- WINERR_IFALL(WINDOWS_LOG_EVENT,
- "DebugLoop returned FALSE from WaitForDebugEvent. Error = %u",
- ::GetCurrentThreadId(), ::GetLastError());
-
- should_debug = false;
- }
- }
- FreeProcessHandles();
-
- WINLOG_IFALL(WINDOWS_LOG_EVENT, "WaitForDebugEvent loop completed, exiting.");
- SetEvent(m_debugging_ended_event);
-}
-
-ExceptionResult
-DebuggerThread::HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info, DWORD thread_id)
-{
- if (m_is_shutting_down)
- {
- // A breakpoint that occurs while `m_pid_to_detach` is non-zero is a magic exception that
- // we use simply to wake up the DebuggerThread so that we can close out the debug loop.
- if (m_pid_to_detach != 0 && info.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT)
- {
- WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_EXCEPTION | WINDOWS_LOG_PROCESS,
- "Breakpoint exception is cue to detach from process 0x%x",
- m_pid_to_detach.load());
- ::DebugActiveProcessStop(m_pid_to_detach);
- m_detached = true;
- }
-
- // Don't perform any blocking operations while we're shutting down. That will
- // cause TerminateProcess -> WaitForSingleObject to time out.
- return ExceptionResult::SendToApplication;
- }
-
- bool first_chance = (info.dwFirstChance != 0);
-
- m_active_exception.reset(new ExceptionRecord(info.ExceptionRecord, thread_id));
- WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_EXCEPTION,
- "HandleExceptionEvent encountered %s chance exception 0x%x on thread 0x%x",
- first_chance ? "first" : "second", info.ExceptionRecord.ExceptionCode, thread_id);
-
- ExceptionResult result = m_debug_delegate->OnDebugException(first_chance,
- *m_active_exception);
- m_exception_pred.SetValue(result, eBroadcastNever);
-
- WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_EXCEPTION,
- "DebuggerThread::HandleExceptionEvent waiting for ExceptionPred != BreakInDebugger");
-
- m_exception_pred.WaitForValueNotEqualTo(ExceptionResult::BreakInDebugger, result);
-
- WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_EXCEPTION,
- "DebuggerThread::HandleExceptionEvent got ExceptionPred = %u",
- m_exception_pred.GetValue());
-
- return result;
-}
-
-DWORD
-DebuggerThread::HandleCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO &info, DWORD thread_id)
-{
- WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_THREAD,
- "HandleCreateThreadEvent Thread 0x%x spawned in process %I64u",
- thread_id, m_process.GetProcessId());
- HostThread thread(info.hThread);
- thread.GetNativeThread().SetOwnsHandle(false);
- m_debug_delegate->OnCreateThread(thread);
- return DBG_CONTINUE;
-}
-
-DWORD
-DebuggerThread::HandleCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO &info, DWORD thread_id)
-{
- uint32_t process_id = ::GetProcessId(info.hProcess);
-
- WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_PROCESS, "HandleCreateProcessEvent process %u spawned", process_id);
-
- std::string thread_name;
- llvm::raw_string_ostream name_stream(thread_name);
- name_stream << "lldb.plugin.process-windows.slave[" << process_id << "]";
- name_stream.flush();
- ThisThread::SetName(thread_name.c_str());
-
- // info.hProcess and info.hThread are closed automatically by Windows when
- // EXIT_PROCESS_DEBUG_EVENT is received.
- m_process = HostProcess(info.hProcess);
- ((HostProcessWindows &)m_process.GetNativeProcess()).SetOwnsHandle(false);
- m_main_thread = HostThread(info.hThread);
- m_main_thread.GetNativeThread().SetOwnsHandle(false);
- m_image_file = info.hFile;
-
- lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfImage);
- m_debug_delegate->OnDebuggerConnected(load_addr);
-
- return DBG_CONTINUE;
-}
-
-DWORD
-DebuggerThread::HandleExitThreadEvent(const EXIT_THREAD_DEBUG_INFO &info, DWORD thread_id)
-{
- WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_THREAD,
- "HandleExitThreadEvent Thread %u exited with code %u in process %I64u",
- thread_id, info.dwExitCode, m_process.GetProcessId());
- m_debug_delegate->OnExitThread(thread_id, info.dwExitCode);
- return DBG_CONTINUE;
-}
-
-DWORD
-DebuggerThread::HandleExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO &info, DWORD thread_id)
-{
- WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_THREAD,
- "HandleExitProcessEvent process %I64u exited with code %u",
- m_process.GetProcessId(), info.dwExitCode);
-
- m_debug_delegate->OnExitProcess(info.dwExitCode);
-
- FreeProcessHandles();
- return DBG_CONTINUE;
-}
-
-DWORD
-DebuggerThread::HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info, DWORD thread_id)
-{
- if (info.hFile == nullptr)
- {
- // Not sure what this is, so just ignore it.
- WINWARN_IFALL(WINDOWS_LOG_EVENT, "Inferior %I64u - HandleLoadDllEvent has a NULL file handle, returning...",
- m_process.GetProcessId());
- return DBG_CONTINUE;
- }
-
- std::vector<wchar_t> buffer(1);
- DWORD required_size = GetFinalPathNameByHandleW(info.hFile, &buffer[0], 0, VOLUME_NAME_DOS);
- if (required_size > 0)
- {
- buffer.resize(required_size + 1);
- required_size = GetFinalPathNameByHandleW(info.hFile, &buffer[0], required_size, VOLUME_NAME_DOS);
- std::string path_str_utf8;
- llvm::convertWideToUTF8(buffer.data(), path_str_utf8);
- llvm::StringRef path_str = path_str_utf8;
- const char *path = path_str.data();
- if (path_str.startswith("\\\\?\\"))
- path += 4;
-
- FileSpec file_spec(path, false);
- ModuleSpec module_spec(file_spec);
- lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll);
-
- WINLOG_IFALL(WINDOWS_LOG_EVENT, "Inferior %I64u - HandleLoadDllEvent DLL '%s' loaded at address 0x%p...",
- m_process.GetProcessId(), path, info.lpBaseOfDll);
-
- m_debug_delegate->OnLoadDll(module_spec, load_addr);
- }
- else
- {
- WINERR_IFALL(WINDOWS_LOG_EVENT,
- "Inferior %I64u - HandleLoadDllEvent Error %u occurred calling GetFinalPathNameByHandle",
- m_process.GetProcessId(), ::GetLastError());
- }
- // Windows does not automatically close info.hFile, so we need to do it.
- ::CloseHandle(info.hFile);
- return DBG_CONTINUE;
-}
-
-DWORD
-DebuggerThread::HandleUnloadDllEvent(const UNLOAD_DLL_DEBUG_INFO &info, DWORD thread_id)
-{
- WINLOG_IFALL(WINDOWS_LOG_EVENT,
- "HandleUnloadDllEvent process %I64u unloading DLL at addr 0x%p.",
- m_process.GetProcessId(), info.lpBaseOfDll);
-
- m_debug_delegate->OnUnloadDll(reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll));
- return DBG_CONTINUE;
-}
-
-DWORD
-DebuggerThread::HandleODSEvent(const OUTPUT_DEBUG_STRING_INFO &info, DWORD thread_id)
-{
- return DBG_CONTINUE;
-}
-
-DWORD
-DebuggerThread::HandleRipEvent(const RIP_INFO &info, DWORD thread_id)
-{
- WINERR_IFALL(WINDOWS_LOG_EVENT,
- "HandleRipEvent encountered error %u (type=%u) in process %I64u thread %u",
- info.dwError, info.dwType, m_process.GetProcessId(), thread_id);
-
- Error error(info.dwError, eErrorTypeWin32);
- m_debug_delegate->OnDebuggerError(error, info.dwType);
-
- return DBG_CONTINUE;
-}
diff --git a/source/Plugins/Process/Windows/Live/DebuggerThread.h b/source/Plugins/Process/Windows/Live/DebuggerThread.h
deleted file mode 100644
index 6a2619413950..000000000000
--- a/source/Plugins/Process/Windows/Live/DebuggerThread.h
+++ /dev/null
@@ -1,100 +0,0 @@
-//===-- DebuggerThread.h ----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_Plugins_Process_Windows_DebuggerThread_H_
-#define liblldb_Plugins_Process_Windows_DebuggerThread_H_
-
-#include <atomic>
-#include <memory>
-
-#include "ForwardDecl.h"
-#include "lldb/Host/HostProcess.h"
-#include "lldb/Host/HostThread.h"
-#include "lldb/Host/Predicate.h"
-#include "lldb/Host/windows/windows.h"
-
-namespace lldb_private
-{
-
-//----------------------------------------------------------------------
-// DebuggerThread
-//
-// Debugs a single process, notifying listeners as appropriate when interesting
-// things occur.
-//----------------------------------------------------------------------
-class DebuggerThread : public std::enable_shared_from_this<DebuggerThread>
-{
- public:
- DebuggerThread(DebugDelegateSP debug_delegate);
- virtual ~DebuggerThread();
-
- Error DebugLaunch(const ProcessLaunchInfo &launch_info);
- Error DebugAttach(lldb::pid_t pid, const ProcessAttachInfo &attach_info);
-
- HostProcess
- GetProcess() const
- {
- return m_process;
- }
- HostThread
- GetMainThread() const
- {
- return m_main_thread;
- }
- std::weak_ptr<ExceptionRecord>
- GetActiveException()
- {
- return m_active_exception;
- }
-
- Error StopDebugging(bool terminate);
-
- void ContinueAsyncException(ExceptionResult result);
-
- private:
- void FreeProcessHandles();
- void DebugLoop();
- ExceptionResult HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info, DWORD thread_id);
- DWORD HandleCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO &info, DWORD thread_id);
- DWORD HandleCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO &info, DWORD thread_id);
- DWORD HandleExitThreadEvent(const EXIT_THREAD_DEBUG_INFO &info, DWORD thread_id);
- DWORD HandleExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO &info, DWORD thread_id);
- DWORD HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info, DWORD thread_id);
- DWORD HandleUnloadDllEvent(const UNLOAD_DLL_DEBUG_INFO &info, DWORD thread_id);
- DWORD HandleODSEvent(const OUTPUT_DEBUG_STRING_INFO &info, DWORD thread_id);
- DWORD HandleRipEvent(const RIP_INFO &info, DWORD thread_id);
-
- DebugDelegateSP m_debug_delegate;
-
- HostProcess m_process; // The process being debugged.
- HostThread m_main_thread; // The main thread of the inferior.
- HANDLE m_image_file; // The image file of the process being debugged.
-
- ExceptionRecordSP m_active_exception; // The current exception waiting to be handled
-
- Predicate<ExceptionResult> m_exception_pred; // A predicate which gets signalled when an exception
- // is finished processing and the debug loop can be
- // continued.
-
- HANDLE m_debugging_ended_event; // An event which gets signalled by the debugger thread when it
- // exits the debugger loop and is detached from the inferior.
-
- std::atomic<DWORD> m_pid_to_detach; // Signals the loop to detach from the process (specified by pid).
- std::atomic<bool> m_is_shutting_down; // Signals the debug loop to stop processing certain types of
- // events that block shutdown.
- bool m_detached; // Indicates we've detached from the inferior process and the debug loop can exit.
-
- static lldb::thread_result_t DebuggerThreadLaunchRoutine(void *data);
- lldb::thread_result_t DebuggerThreadLaunchRoutine(const ProcessLaunchInfo &launch_info);
- static lldb::thread_result_t DebuggerThreadAttachRoutine(void *data);
- lldb::thread_result_t DebuggerThreadAttachRoutine(lldb::pid_t pid, const ProcessAttachInfo &launch_info);
-};
-}
-
-#endif
diff --git a/source/Plugins/Process/Windows/Live/LocalDebugDelegate.cpp b/source/Plugins/Process/Windows/Live/LocalDebugDelegate.cpp
deleted file mode 100644
index a0ac9725c756..000000000000
--- a/source/Plugins/Process/Windows/Live/LocalDebugDelegate.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-//===-- LocalDebugDelegate.cpp ----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "LocalDebugDelegate.h"
-#include "ProcessWindowsLive.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-LocalDebugDelegate::LocalDebugDelegate(ProcessWP process)
- : m_process(process)
-{
-}
-
-void
-LocalDebugDelegate::OnExitProcess(uint32_t exit_code)
-{
- if (ProcessWindowsLiveSP process = GetProcessPointer())
- process->OnExitProcess(exit_code);
-}
-
-void
-LocalDebugDelegate::OnDebuggerConnected(lldb::addr_t image_base)
-{
- if (ProcessWindowsLiveSP process = GetProcessPointer())
- process->OnDebuggerConnected(image_base);
-}
-
-ExceptionResult
-LocalDebugDelegate::OnDebugException(bool first_chance, const ExceptionRecord &record)
-{
- if (ProcessWindowsLiveSP process = GetProcessPointer())
- return process->OnDebugException(first_chance, record);
- else
- return ExceptionResult::MaskException;
-}
-
-void
-LocalDebugDelegate::OnCreateThread(const HostThread &thread)
-{
- if (ProcessWindowsLiveSP process = GetProcessPointer())
- process->OnCreateThread(thread);
-}
-
-void
-LocalDebugDelegate::OnExitThread(lldb::tid_t thread_id, uint32_t exit_code)
-{
- if (ProcessWindowsLiveSP process = GetProcessPointer())
- process->OnExitThread(thread_id, exit_code);
-}
-
-void
-LocalDebugDelegate::OnLoadDll(const lldb_private::ModuleSpec &module_spec, lldb::addr_t module_addr)
-{
- if (ProcessWindowsLiveSP process = GetProcessPointer())
- process->OnLoadDll(module_spec, module_addr);
-}
-
-void
-LocalDebugDelegate::OnUnloadDll(lldb::addr_t module_addr)
-{
- if (ProcessWindowsLiveSP process = GetProcessPointer())
- process->OnUnloadDll(module_addr);
-}
-
-void
-LocalDebugDelegate::OnDebugString(const std::string &string)
-{
- if (ProcessWindowsLiveSP process = GetProcessPointer())
- process->OnDebugString(string);
-}
-
-void
-LocalDebugDelegate::OnDebuggerError(const Error &error, uint32_t type)
-{
- if (ProcessWindowsLiveSP process = GetProcessPointer())
- process->OnDebuggerError(error, type);
-}
-
-ProcessWindowsLiveSP
-LocalDebugDelegate::GetProcessPointer()
-{
- ProcessSP process = m_process.lock();
- return std::static_pointer_cast<ProcessWindowsLive>(process);
-}
diff --git a/source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp b/source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp
deleted file mode 100644
index 300e0caa4378..000000000000
--- a/source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp
+++ /dev/null
@@ -1,1069 +0,0 @@
-//===-- ProcessWindowsLive.cpp ----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// Windows includes
-#include "lldb/Host/windows/windows.h"
-#include <psapi.h>
-
-// C++ Includes
-#include <list>
-#include <mutex>
-#include <set>
-#include <vector>
-
-// Other libraries and framework includes
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/Section.h"
-#include "lldb/Core/State.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Host/HostProcess.h"
-#include "lldb/Host/HostNativeProcessBase.h"
-#include "lldb/Host/HostNativeThreadBase.h"
-#include "lldb/Host/MonitoringProcessLauncher.h"
-#include "lldb/Host/ThreadLauncher.h"
-#include "lldb/Host/windows/HostThreadWindows.h"
-#include "lldb/Host/windows/ProcessLauncherWindows.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Target/DynamicLoader.h"
-#include "lldb/Target/FileAction.h"
-#include "lldb/Target/MemoryRegionInfo.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Target/StopInfo.h"
-#include "lldb/Target/Target.h"
-
-#include "Plugins/Process/Windows/Common/ProcessWindowsLog.h"
-
-#include "DebuggerThread.h"
-#include "ExceptionRecord.h"
-#include "LocalDebugDelegate.h"
-#include "ProcessWindowsLive.h"
-#include "TargetThreadWindowsLive.h"
-
-#include "llvm/Support/ConvertUTF.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-#define BOOL_STR(b) ((b) ? "true" : "false")
-
-namespace
-{
-
-std::string
-GetProcessExecutableName(HANDLE process_handle)
-{
- std::vector<wchar_t> file_name;
- DWORD file_name_size = MAX_PATH; // first guess, not an absolute limit
- DWORD copied = 0;
- do
- {
- file_name_size *= 2;
- file_name.resize(file_name_size);
- copied = ::GetModuleFileNameExW(process_handle, NULL, file_name.data(), file_name_size);
- } while (copied >= file_name_size);
- file_name.resize(copied);
- std::string result;
- llvm::convertWideToUTF8(file_name.data(), result);
- return result;
-}
-
-std::string
-GetProcessExecutableName(DWORD pid)
-{
- std::string file_name;
- HANDLE process_handle = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
- if (process_handle != NULL)
- {
- file_name = GetProcessExecutableName(process_handle);
- ::CloseHandle(process_handle);
- }
- return file_name;
-}
-
-} // anonymous namespace
-
-namespace lldb_private
-{
-
-// We store a pointer to this class in the ProcessWindows, so that we don't expose Windows
-// OS specific types and implementation details from a public header file.
-class ProcessWindowsData
-{
- public:
- ProcessWindowsData(bool stop_at_entry)
- : m_stop_at_entry(stop_at_entry)
- , m_initial_stop_event(nullptr)
- , m_initial_stop_received(false)
- {
- m_initial_stop_event = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
- }
-
- ~ProcessWindowsData() { ::CloseHandle(m_initial_stop_event); }
-
- lldb_private::Error m_launch_error;
- lldb_private::DebuggerThreadSP m_debugger;
- StopInfoSP m_pending_stop_info;
- HANDLE m_initial_stop_event;
- bool m_stop_at_entry;
- bool m_initial_stop_received;
- std::map<lldb::tid_t, HostThread> m_new_threads;
- std::set<lldb::tid_t> m_exited_threads;
-};
-}
-//------------------------------------------------------------------------------
-// Static functions.
-
-ProcessSP
-ProcessWindowsLive::CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec *)
-{
- return ProcessSP(new ProcessWindowsLive(target_sp, listener_sp));
-}
-
-void
-ProcessWindowsLive::Initialize()
-{
- static std::once_flag g_once_flag;
-
- std::call_once(g_once_flag, []()
- {
- PluginManager::RegisterPlugin(GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
- });
-}
-
-//------------------------------------------------------------------------------
-// Constructors and destructors.
-
-ProcessWindowsLive::ProcessWindowsLive(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)
- : lldb_private::ProcessWindows(target_sp, listener_sp)
-{
-}
-
-ProcessWindowsLive::~ProcessWindowsLive()
-{
-}
-
-void
-ProcessWindowsLive::Terminate()
-{
-}
-
-lldb_private::ConstString
-ProcessWindowsLive::GetPluginNameStatic()
-{
- static ConstString g_name("windows");
- return g_name;
-}
-
-const char *
-ProcessWindowsLive::GetPluginDescriptionStatic()
-{
- return "Process plugin for Windows";
-}
-
-Error
-ProcessWindowsLive::EnableBreakpointSite(BreakpointSite *bp_site)
-{
- WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS, "EnableBreakpointSite called with bp_site 0x%p "
- "(id=%d, addr=0x%x)",
- bp_site->GetID(), bp_site->GetLoadAddress());
-
- Error error = EnableSoftwareBreakpoint(bp_site);
- if (!error.Success())
- {
- WINERR_IFALL(WINDOWS_LOG_BREAKPOINTS, "EnableBreakpointSite failed. %s", error.AsCString());
- }
- return error;
-}
-
-Error
-ProcessWindowsLive::DisableBreakpointSite(BreakpointSite *bp_site)
-{
- WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS, "DisableBreakpointSite called with bp_site 0x%p "
- "(id=%d, addr=0x%x)",
- bp_site, bp_site->GetID(), bp_site->GetLoadAddress());
-
- Error error = DisableSoftwareBreakpoint(bp_site);
-
- if (!error.Success())
- {
- WINERR_IFALL(WINDOWS_LOG_BREAKPOINTS, "DisableBreakpointSite failed. %s", error.AsCString());
- }
- return error;
-}
-
-bool
-ProcessWindowsLive::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
-{
- // Add all the threads that were previously running and for which we did not detect a thread
- // exited event.
- int new_size = 0;
- int continued_threads = 0;
- int exited_threads = 0;
- int new_threads = 0;
-
- for (ThreadSP old_thread : old_thread_list.Threads())
- {
- lldb::tid_t old_thread_id = old_thread->GetID();
- auto exited_thread_iter = m_session_data->m_exited_threads.find(old_thread_id);
- if (exited_thread_iter == m_session_data->m_exited_threads.end())
- {
- new_thread_list.AddThread(old_thread);
- ++new_size;
- ++continued_threads;
- WINLOGV_IFALL(WINDOWS_LOG_THREAD, "UpdateThreadList - Thread %u was running and is still running.",
- old_thread_id);
- }
- else
- {
- WINLOGV_IFALL(WINDOWS_LOG_THREAD, "UpdateThreadList - Thread %u was running and has exited.",
- old_thread_id);
- ++exited_threads;
- }
- }
-
- // Also add all the threads that are new since the last time we broke into the debugger.
- for (const auto &thread_info : m_session_data->m_new_threads)
- {
- ThreadSP thread(new TargetThreadWindowsLive(*this, thread_info.second));
- thread->SetID(thread_info.first);
- new_thread_list.AddThread(thread);
- ++new_size;
- ++new_threads;
- WINLOGV_IFALL(WINDOWS_LOG_THREAD, "UpdateThreadList - Thread %u is new since last update.", thread_info.first);
- }
-
- WINLOG_IFALL(WINDOWS_LOG_THREAD, "UpdateThreadList - %d new threads, %d old threads, %d exited threads.",
- new_threads, continued_threads, exited_threads);
-
- m_session_data->m_new_threads.clear();
- m_session_data->m_exited_threads.clear();
-
- return new_size > 0;
-}
-
-Error
-ProcessWindowsLive::DoLaunch(Module *exe_module,
- ProcessLaunchInfo &launch_info)
-{
- // Even though m_session_data is accessed here, it is before a debugger thread has been
- // kicked off. So there's no race conditions, and it shouldn't be necessary to acquire
- // the mutex.
-
- Error result;
- if (!launch_info.GetFlags().Test(eLaunchFlagDebug))
- {
- StreamString stream;
- stream.Printf("ProcessWindows unable to launch '%s'. ProcessWindows can only be used for debug launches.",
- launch_info.GetExecutableFile().GetPath().c_str());
- std::string message = stream.GetString();
- result.SetErrorString(message.c_str());
-
- WINERR_IFALL(WINDOWS_LOG_PROCESS, message.c_str());
- return result;
- }
-
- bool stop_at_entry = launch_info.GetFlags().Test(eLaunchFlagStopAtEntry);
- m_session_data.reset(new ProcessWindowsData(stop_at_entry));
-
- SetPrivateState(eStateLaunching);
- DebugDelegateSP delegate(new LocalDebugDelegate(shared_from_this()));
- m_session_data->m_debugger.reset(new DebuggerThread(delegate));
- DebuggerThreadSP debugger = m_session_data->m_debugger;
-
- // Kick off the DebugLaunch asynchronously and wait for it to complete.
- result = debugger->DebugLaunch(launch_info);
- if (result.Fail())
- {
- WINERR_IFALL(WINDOWS_LOG_PROCESS, "DoLaunch failed launching '%s'. %s",
- launch_info.GetExecutableFile().GetPath().c_str(), result.AsCString());
- return result;
- }
-
- HostProcess process;
- Error error = WaitForDebuggerConnection(debugger, process);
- if (error.Fail())
- {
- WINERR_IFALL(WINDOWS_LOG_PROCESS, "DoLaunch failed launching '%s'. %s",
- launch_info.GetExecutableFile().GetPath().c_str(), error.AsCString());
- return error;
- }
-
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DoLaunch successfully launched '%s'",
- launch_info.GetExecutableFile().GetPath().c_str());
-
- // We've hit the initial stop. If eLaunchFlagsStopAtEntry was specified, the private state
- // should already be set to eStateStopped as a result of hitting the initial breakpoint. If
- // it was not set, the breakpoint should have already been resumed from and the private state
- // should already be eStateRunning.
- launch_info.SetProcessID(process.GetProcessId());
- SetID(process.GetProcessId());
-
- return result;
-}
-
-Error
-ProcessWindowsLive::DoAttachToProcessWithID(lldb::pid_t pid, const ProcessAttachInfo &attach_info)
-{
- m_session_data.reset(new ProcessWindowsData(!attach_info.GetContinueOnceAttached()));
-
- DebugDelegateSP delegate(new LocalDebugDelegate(shared_from_this()));
- DebuggerThreadSP debugger(new DebuggerThread(delegate));
-
- m_session_data->m_debugger = debugger;
-
- DWORD process_id = static_cast<DWORD>(pid);
- Error error = debugger->DebugAttach(process_id, attach_info);
- if (error.Fail())
- {
- WINLOG_IFALL(WINDOWS_LOG_PROCESS,
- "DoAttachToProcessWithID encountered an error occurred initiating the asynchronous attach. %s",
- error.AsCString());
- return error;
- }
-
- HostProcess process;
- error = WaitForDebuggerConnection(debugger, process);
- if (error.Fail())
- {
- WINLOG_IFALL(WINDOWS_LOG_PROCESS,
- "DoAttachToProcessWithID encountered an error waiting for the debugger to connect. %s",
- error.AsCString());
- return error;
- }
-
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DoAttachToProcessWithID successfully attached to process with pid=%u",
- process_id);
-
- // We've hit the initial stop. If eLaunchFlagsStopAtEntry was specified, the private state
- // should already be set to eStateStopped as a result of hitting the initial breakpoint. If
- // it was not set, the breakpoint should have already been resumed from and the private state
- // should already be eStateRunning.
- SetID(process.GetProcessId());
- return error;
-}
-
-Error
-ProcessWindowsLive::WaitForDebuggerConnection(DebuggerThreadSP debugger, HostProcess &process)
-{
- Error result;
- WINLOG_IFANY(WINDOWS_LOG_PROCESS|WINDOWS_LOG_BREAKPOINTS, "WaitForDebuggerConnection Waiting for loader breakpoint.");
-
- // Block this function until we receive the initial stop from the process.
- if (::WaitForSingleObject(m_session_data->m_initial_stop_event, INFINITE) == WAIT_OBJECT_0)
- {
- WINLOG_IFANY(WINDOWS_LOG_PROCESS|WINDOWS_LOG_BREAKPOINTS, "WaitForDebuggerConnection hit loader breakpoint, returning.");
-
- process = debugger->GetProcess();
- return m_session_data->m_launch_error;
- }
- else
- return Error(::GetLastError(), eErrorTypeWin32);
-}
-
-Error
-ProcessWindowsLive::DoResume()
-{
- llvm::sys::ScopedLock lock(m_mutex);
- Error error;
-
- StateType private_state = GetPrivateState();
- if (private_state == eStateStopped || private_state == eStateCrashed)
- {
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DoResume called for process %I64u while state is %u. Resuming...",
- m_session_data->m_debugger->GetProcess().GetProcessId(), GetPrivateState());
-
- ExceptionRecordSP active_exception =
- m_session_data->m_debugger->GetActiveException().lock();
- if (active_exception)
- {
- // Resume the process and continue processing debug events. Mask
- // the exception so that from the process's view, there is no
- // indication that anything happened.
- m_session_data->m_debugger->ContinueAsyncException(
- ExceptionResult::MaskException);
- }
-
- WINLOG_IFANY(WINDOWS_LOG_PROCESS | WINDOWS_LOG_THREAD, "DoResume resuming %u threads.",
- m_thread_list.GetSize());
-
- for (int i = 0; i < m_thread_list.GetSize(); ++i)
- {
- auto thread = std::static_pointer_cast<TargetThreadWindowsLive>(
- m_thread_list.GetThreadAtIndex(i));
- thread->DoResume();
- }
-
- SetPrivateState(eStateRunning);
- }
- else
- {
- WINERR_IFALL(WINDOWS_LOG_PROCESS, "DoResume called for process %I64u but state is %u. Returning...",
- m_session_data->m_debugger->GetProcess().GetProcessId(), GetPrivateState());
- }
- return error;
-}
-
-
-//------------------------------------------------------------------------------
-// ProcessInterface protocol.
-
-lldb_private::ConstString
-ProcessWindowsLive::GetPluginName()
-{
- return GetPluginNameStatic();
-}
-
-uint32_t
-ProcessWindowsLive::GetPluginVersion()
-{
- return 1;
-}
-
-Error
-ProcessWindowsLive::DoDetach(bool keep_stopped)
-{
- DebuggerThreadSP debugger_thread;
- StateType private_state;
- {
- // Acquire the lock only long enough to get the DebuggerThread.
- // StopDebugging() will trigger a call back into ProcessWindows which
- // will also acquire the lock. Thus we have to release the lock before
- // calling StopDebugging().
- llvm::sys::ScopedLock lock(m_mutex);
-
- private_state = GetPrivateState();
-
- if (!m_session_data)
- {
- WINWARN_IFALL(WINDOWS_LOG_PROCESS, "DoDetach called while state = %u, but there is no active session.",
- private_state);
- return Error();
- }
-
- debugger_thread = m_session_data->m_debugger;
- }
-
- Error error;
- if (private_state != eStateExited && private_state != eStateDetached)
- {
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DoDetach called for process %I64u while state = %u. Detaching...",
- debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(), private_state);
- error = debugger_thread->StopDebugging(false);
- if (error.Success())
- {
- SetPrivateState(eStateDetached);
- }
-
- // By the time StopDebugging returns, there is no more debugger thread, so
- // we can be assured that no other thread will race for the session data.
- m_session_data.reset();
- }
- else
- {
- WINERR_IFALL(WINDOWS_LOG_PROCESS,
- "DoDetach called for process %I64u while state = %u, but cannot destroy in this state.",
- debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(), private_state);
- }
-
- return error;
-}
-
-Error
-ProcessWindowsLive::DoDestroy()
-{
- DebuggerThreadSP debugger_thread;
- StateType private_state;
- {
- // Acquire this lock inside an inner scope, only long enough to get the DebuggerThread.
- // StopDebugging() will trigger a call back into ProcessWindows which will acquire the lock
- // again, so we need to not deadlock.
- llvm::sys::ScopedLock lock(m_mutex);
-
- private_state = GetPrivateState();
-
- if (!m_session_data)
- {
- WINWARN_IFALL(WINDOWS_LOG_PROCESS, "DoDestroy called while state = %u, but there is no active session.",
- private_state);
- return Error();
- }
-
- debugger_thread = m_session_data->m_debugger;
- }
-
- Error error;
- if (private_state != eStateExited && private_state != eStateDetached)
- {
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DoDestroy called for process %I64u while state = %u. Shutting down...",
- debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(), private_state);
- error = debugger_thread->StopDebugging(true);
-
- // By the time StopDebugging returns, there is no more debugger thread, so
- // we can be assured that no other thread will race for the session data.
- m_session_data.reset();
- }
- else
- {
- WINERR_IFALL(WINDOWS_LOG_PROCESS,
- "DoDestroy called for process %I64u while state = %u, but cannot destroy in this state.",
- debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(), private_state);
- }
-
- return error;
-}
-
-void
-ProcessWindowsLive::RefreshStateAfterStop()
-{
- llvm::sys::ScopedLock lock(m_mutex);
-
- if (!m_session_data)
- {
- WINWARN_IFALL(WINDOWS_LOG_PROCESS, "RefreshStateAfterStop called with no active session. Returning...");
- return;
- }
-
- m_thread_list.RefreshStateAfterStop();
-
- std::weak_ptr<ExceptionRecord> exception_record = m_session_data->m_debugger->GetActiveException();
- ExceptionRecordSP active_exception = exception_record.lock();
- if (!active_exception)
- {
- WINERR_IFALL(WINDOWS_LOG_PROCESS, "RefreshStateAfterStop called for process %I64u but there is no "
- "active exception. Why is the process stopped?",
- m_session_data->m_debugger->GetProcess().GetProcessId());
- return;
- }
-
- StopInfoSP stop_info;
- m_thread_list.SetSelectedThreadByID(active_exception->GetThreadID());
- ThreadSP stop_thread = m_thread_list.GetSelectedThread();
- if (!stop_thread)
- return;
-
- switch (active_exception->GetExceptionCode())
- {
- case EXCEPTION_SINGLE_STEP:
- {
- RegisterContextSP register_context = stop_thread->GetRegisterContext();
- const uint64_t pc = register_context->GetPC();
- BreakpointSiteSP site(GetBreakpointSiteList().FindByAddress(pc));
- if (site && site->ValidForThisThread(stop_thread.get()))
- {
- WINLOG_IFANY(WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION | WINDOWS_LOG_STEP,
- "Single-stepped onto a breakpoint in process %I64u at "
- "address 0x%I64x with breakpoint site %d",
- m_session_data->m_debugger->GetProcess().GetProcessId(), pc, site->GetID());
- stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(*stop_thread, site->GetID());
- stop_thread->SetStopInfo(stop_info);
- }
- else
- {
- WINLOG_IFANY(WINDOWS_LOG_EXCEPTION | WINDOWS_LOG_STEP,
- "RefreshStateAfterStop single stepping thread %u", stop_thread->GetID());
- stop_info = StopInfo::CreateStopReasonToTrace(*stop_thread);
- stop_thread->SetStopInfo(stop_info);
- }
- return;
- }
-
- case EXCEPTION_BREAKPOINT:
- {
- RegisterContextSP register_context = stop_thread->GetRegisterContext();
-
- // The current EIP is AFTER the BP opcode, which is one byte.
- uint64_t pc = register_context->GetPC() - 1;
-
- BreakpointSiteSP site(GetBreakpointSiteList().FindByAddress(pc));
- if (site)
- {
- WINLOG_IFANY(WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION,
- "RefreshStateAfterStop detected breakpoint in process %I64u at "
- "address 0x%I64x with breakpoint site %d",
- m_session_data->m_debugger->GetProcess().GetProcessId(), pc, site->GetID());
-
- if (site->ValidForThisThread(stop_thread.get()))
- {
- WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION,
- "Breakpoint site %d is valid for this thread (0x%I64x), creating stop info.",
- site->GetID(), stop_thread->GetID());
-
- stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(
- *stop_thread, site->GetID());
- register_context->SetPC(pc);
- }
- else
- {
- WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION,
- "Breakpoint site %d is not valid for this thread, creating empty stop info.",
- site->GetID());
- }
- stop_thread->SetStopInfo(stop_info);
- return;
- }
- else
- {
- // The thread hit a hard-coded breakpoint like an `int 3` or `__debugbreak()`.
- WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION,
- "No breakpoint site matches for this thread. __debugbreak()? "
- "Creating stop info with the exception.");
- // FALLTHROUGH: We'll treat this as a generic exception record in the default case.
- }
- }
-
- default:
- {
- std::string desc;
- llvm::raw_string_ostream desc_stream(desc);
- desc_stream << "Exception " << llvm::format_hex(active_exception->GetExceptionCode(), 8)
- << " encountered at address "
- << llvm::format_hex(active_exception->GetExceptionAddress(), 8);
- stop_info = StopInfo::CreateStopReasonWithException(*stop_thread, desc_stream.str().c_str());
- stop_thread->SetStopInfo(stop_info);
- WINLOG_IFALL(WINDOWS_LOG_EXCEPTION, desc_stream.str().c_str());
- return;
- }
- }
-}
-
-bool
-ProcessWindowsLive::IsAlive()
-{
- StateType state = GetPrivateState();
- switch (state)
- {
- case eStateCrashed:
- case eStateDetached:
- case eStateUnloaded:
- case eStateExited:
- case eStateInvalid:
- return false;
- default:
- return true;
- }
-}
-
-Error
-ProcessWindowsLive::DoHalt(bool &caused_stop)
-{
- Error error;
- StateType state = GetPrivateState();
- if (state == eStateStopped)
- caused_stop = false;
- else
- {
- llvm::sys::ScopedLock lock(m_mutex);
- caused_stop = ::DebugBreakProcess(m_session_data->m_debugger->GetProcess().GetNativeProcess().GetSystemHandle());
- if (!caused_stop)
- {
- error.SetError(::GetLastError(), eErrorTypeWin32);
- WINERR_IFALL(WINDOWS_LOG_PROCESS, "DoHalt called DebugBreakProcess, but it failed with error %u",
- error.GetError());
- }
- }
- return error;
-}
-
-void
-ProcessWindowsLive::DidLaunch()
-{
- ArchSpec arch_spec;
- DidAttach(arch_spec);
-}
-
-void
-ProcessWindowsLive::DidAttach(ArchSpec &arch_spec)
-{
- llvm::sys::ScopedLock lock(m_mutex);
-
- // The initial stop won't broadcast the state change event, so account for that here.
- if (m_session_data && GetPrivateState() == eStateStopped && m_session_data->m_stop_at_entry)
- RefreshStateAfterStop();
-}
-
-size_t
-ProcessWindowsLive::DoReadMemory(lldb::addr_t vm_addr,
- void *buf,
- size_t size,
- Error &error)
-{
- llvm::sys::ScopedLock lock(m_mutex);
-
- if (!m_session_data)
- return 0;
-
- WINLOG_IFALL(WINDOWS_LOG_MEMORY, "DoReadMemory attempting to read %u bytes from address 0x%I64x", size, vm_addr);
-
- HostProcess process = m_session_data->m_debugger->GetProcess();
- void *addr = reinterpret_cast<void *>(vm_addr);
- SIZE_T bytes_read = 0;
- if (!ReadProcessMemory(process.GetNativeProcess().GetSystemHandle(), addr, buf, size, &bytes_read))
- {
- error.SetError(GetLastError(), eErrorTypeWin32);
- WINERR_IFALL(WINDOWS_LOG_MEMORY, "DoReadMemory failed with error code %u", error.GetError());
- }
- return bytes_read;
-}
-
-size_t
-ProcessWindowsLive::DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, Error &error)
-{
- llvm::sys::ScopedLock lock(m_mutex);
- WINLOG_IFALL(WINDOWS_LOG_MEMORY, "DoWriteMemory attempting to write %u bytes into address 0x%I64x", size, vm_addr);
-
- if (!m_session_data)
- {
- WINERR_IFANY(WINDOWS_LOG_MEMORY, "DoWriteMemory cannot write, there is no active debugger connection.");
- return 0;
- }
-
- HostProcess process = m_session_data->m_debugger->GetProcess();
- void *addr = reinterpret_cast<void *>(vm_addr);
- SIZE_T bytes_written = 0;
- lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
- if (WriteProcessMemory(handle, addr, buf, size, &bytes_written))
- FlushInstructionCache(handle, addr, bytes_written);
- else
- {
- error.SetError(GetLastError(), eErrorTypeWin32);
- WINLOG_IFALL(WINDOWS_LOG_MEMORY, "DoWriteMemory failed with error code %u", error.GetError());
- }
- return bytes_written;
-}
-
-Error
-ProcessWindowsLive::GetMemoryRegionInfo(lldb::addr_t vm_addr, MemoryRegionInfo &info)
-{
- Error error;
- llvm::sys::ScopedLock lock(m_mutex);
- info.Clear();
-
- if (!m_session_data)
- {
- error.SetErrorString("GetMemoryRegionInfo called with no debugging session.");
- WINERR_IFALL(WINDOWS_LOG_MEMORY, error.AsCString());
- return error;
- }
- HostProcess process = m_session_data->m_debugger->GetProcess();
- lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
- if (handle == nullptr || handle == LLDB_INVALID_PROCESS)
- {
- error.SetErrorString("GetMemoryRegionInfo called with an invalid target process.");
- WINERR_IFALL(WINDOWS_LOG_MEMORY, error.AsCString());
- return error;
- }
-
- WINLOG_IFALL(WINDOWS_LOG_MEMORY, "GetMemoryRegionInfo getting info for address 0x%I64x", vm_addr);
-
- void *addr = reinterpret_cast<void *>(vm_addr);
- MEMORY_BASIC_INFORMATION mem_info = {0};
- SIZE_T result = ::VirtualQueryEx(handle, addr, &mem_info, sizeof(mem_info));
- if (result == 0)
- {
- if (::GetLastError() == ERROR_INVALID_PARAMETER)
- {
- // ERROR_INVALID_PARAMETER is returned if VirtualQueryEx is called with an address
- // past the highest accessible address. We should return a range from the vm_addr
- // to LLDB_INVALID_ADDRESS
- info.GetRange().SetRangeBase(vm_addr);
- info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
- info.SetReadable(MemoryRegionInfo::eNo);
- info.SetExecutable(MemoryRegionInfo::eNo);
- info.SetWritable(MemoryRegionInfo::eNo);
- info.SetMapped(MemoryRegionInfo::eNo);
- return error;
- }
- else
- {
- error.SetError(::GetLastError(), eErrorTypeWin32);
- WINERR_IFALL(WINDOWS_LOG_MEMORY,
- "VirtualQueryEx returned error %u while getting memory region info for address 0x%I64x",
- error.GetError(), vm_addr);
- return error;
- }
- }
-
- // Protect bits are only valid for MEM_COMMIT regions.
- if (mem_info.State == MEM_COMMIT) {
- const bool readable = IsPageReadable(mem_info.Protect);
- const bool executable = IsPageExecutable(mem_info.Protect);
- const bool writable = IsPageWritable(mem_info.Protect);
- info.SetReadable(readable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
- info.SetExecutable(executable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
- info.SetWritable(writable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
- }
- else
- {
- info.SetReadable(MemoryRegionInfo::eNo);
- info.SetExecutable(MemoryRegionInfo::eNo);
- info.SetWritable(MemoryRegionInfo::eNo);
- }
-
- // AllocationBase is defined for MEM_COMMIT and MEM_RESERVE but not MEM_FREE.
- if (mem_info.State != MEM_FREE) {
- info.GetRange().SetRangeBase(reinterpret_cast<addr_t>(mem_info.AllocationBase));
- info.GetRange().SetRangeEnd(reinterpret_cast<addr_t>(mem_info.BaseAddress) + mem_info.RegionSize);
- info.SetMapped(MemoryRegionInfo::eYes);
- }
- else
- {
- // In the unmapped case we need to return the distance to the next block of memory.
- // VirtualQueryEx nearly does that except that it gives the distance from the start
- // of the page containing vm_addr.
- SYSTEM_INFO data;
- GetSystemInfo(&data);
- DWORD page_offset = vm_addr % data.dwPageSize;
- info.GetRange().SetRangeBase(vm_addr);
- info.GetRange().SetByteSize(mem_info.RegionSize - page_offset);
- info.SetMapped(MemoryRegionInfo::eNo);
- }
-
- error.SetError(::GetLastError(), eErrorTypeWin32);
- WINLOGV_IFALL(WINDOWS_LOG_MEMORY, "Memory region info for address 0x%I64u: readable=%s, executable=%s, writable=%s",
- BOOL_STR(info.GetReadable()), BOOL_STR(info.GetExecutable()), BOOL_STR(info.GetWritable()));
- return error;
-}
-
-bool
-ProcessWindowsLive::CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name)
-{
- if (plugin_specified_by_name)
- return true;
-
- // 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();
- // However, if there is no executable module, we return true since we might be preparing to attach.
- return true;
-}
-
-void
-ProcessWindowsLive::OnExitProcess(uint32_t exit_code)
-{
- // No need to acquire the lock since m_session_data isn't accessed.
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "Process %u exited with code %u", GetID(), exit_code);
-
- TargetSP target = m_target_sp.lock();
- if (target)
- {
- ModuleSP executable_module = target->GetExecutableModule();
- ModuleList unloaded_modules;
- unloaded_modules.Append(executable_module);
- target->ModulesDidUnload(unloaded_modules, true);
- }
-
- SetProcessExitStatus(GetID(), true, 0, exit_code);
- SetPrivateState(eStateExited);
-}
-
-void
-ProcessWindowsLive::OnDebuggerConnected(lldb::addr_t image_base)
-{
- DebuggerThreadSP debugger = m_session_data->m_debugger;
-
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "Debugger connected to process %I64u. Image base = 0x%I64x",
- debugger->GetProcess().GetProcessId(), image_base);
-
- ModuleSP module = GetTarget().GetExecutableModule();
- if (!module)
- {
- // During attach, we won't have the executable module, so find it now.
- const DWORD pid = debugger->GetProcess().GetProcessId();
- const std::string file_name = GetProcessExecutableName(pid);
- if (file_name.empty())
- {
- return;
- }
-
- FileSpec executable_file(file_name, true);
- ModuleSpec module_spec(executable_file);
- Error error;
- module = GetTarget().GetSharedModule(module_spec, &error);
- if (!module)
- {
- return;
- }
-
- GetTarget().SetExecutableModule(module, false);
- }
-
- bool load_addr_changed;
- module->SetLoadAddress(GetTarget(), image_base, false, load_addr_changed);
-
- ModuleList loaded_modules;
- loaded_modules.Append(module);
- GetTarget().ModulesDidLoad(loaded_modules);
-
- // Add the main executable module to the list of pending module loads. We can't call
- // GetTarget().ModulesDidLoad() here because we still haven't returned from DoLaunch() / DoAttach() yet
- // so the target may not have set the process instance to `this` yet.
- llvm::sys::ScopedLock lock(m_mutex);
- const HostThreadWindows &wmain_thread = debugger->GetMainThread().GetNativeThread();
- m_session_data->m_new_threads[wmain_thread.GetThreadId()] = debugger->GetMainThread();
-}
-
-ExceptionResult
-ProcessWindowsLive::OnDebugException(bool first_chance, const ExceptionRecord &record)
-{
- llvm::sys::ScopedLock lock(m_mutex);
-
- // FIXME: Without this check, occasionally when running the test suite there is
- // an issue where m_session_data can be null. It's not clear how this could happen
- // but it only surfaces while running the test suite. In order to properly diagnose
- // this, we probably need to first figure allow the test suite to print out full
- // lldb logs, and then add logging to the process plugin.
- if (!m_session_data)
- {
- WINERR_IFANY(WINDOWS_LOG_EXCEPTION,
- "Debugger thread reported exception 0x%x at address 0x%I64x, but there is no session.",
- record.GetExceptionCode(), record.GetExceptionAddress());
- return ExceptionResult::SendToApplication;
- }
-
- if (!first_chance)
- {
- // Any second chance exception is an application crash by definition.
- SetPrivateState(eStateCrashed);
- }
-
- ExceptionResult result = ExceptionResult::SendToApplication;
- switch (record.GetExceptionCode())
- {
- case EXCEPTION_BREAKPOINT:
- // Handle breakpoints at the first chance.
- result = ExceptionResult::BreakInDebugger;
-
- if (!m_session_data->m_initial_stop_received)
- {
- WINLOG_IFANY(WINDOWS_LOG_BREAKPOINTS,
- "Hit loader breakpoint at address 0x%I64x, setting initial stop event.",
- record.GetExceptionAddress());
- m_session_data->m_initial_stop_received = true;
- ::SetEvent(m_session_data->m_initial_stop_event);
- }
- else
- {
- WINLOG_IFANY(WINDOWS_LOG_BREAKPOINTS,
- "Hit non-loader breakpoint at address 0x%I64x.",
- record.GetExceptionAddress());
- }
- SetPrivateState(eStateStopped);
- break;
- case EXCEPTION_SINGLE_STEP:
- result = ExceptionResult::BreakInDebugger;
- SetPrivateState(eStateStopped);
- break;
- default:
- WINLOG_IFANY(WINDOWS_LOG_EXCEPTION,
- "Debugger thread reported exception 0x%x at address 0x%I64x (first_chance=%s)",
- record.GetExceptionCode(), record.GetExceptionAddress(), BOOL_STR(first_chance));
- // For non-breakpoints, give the application a chance to handle the exception first.
- if (first_chance)
- result = ExceptionResult::SendToApplication;
- else
- result = ExceptionResult::BreakInDebugger;
- }
-
- return result;
-}
-
-void
-ProcessWindowsLive::OnCreateThread(const HostThread &new_thread)
-{
- llvm::sys::ScopedLock lock(m_mutex);
- const HostThreadWindows &wnew_thread = new_thread.GetNativeThread();
- m_session_data->m_new_threads[wnew_thread.GetThreadId()] = new_thread;
-}
-
-void
-ProcessWindowsLive::OnExitThread(lldb::tid_t thread_id, uint32_t exit_code)
-{
- llvm::sys::ScopedLock lock(m_mutex);
-
- // On a forced termination, we may get exit thread events after the session
- // data has been cleaned up.
- if (!m_session_data)
- return;
-
- // A thread may have started and exited before the debugger stopped allowing a refresh.
- // Just remove it from the new threads list in that case.
- auto iter = m_session_data->m_new_threads.find(thread_id);
- if (iter != m_session_data->m_new_threads.end())
- m_session_data->m_new_threads.erase(iter);
- else
- m_session_data->m_exited_threads.insert(thread_id);
-}
-
-void
-ProcessWindowsLive::OnLoadDll(const ModuleSpec &module_spec, lldb::addr_t module_addr)
-{
- // Confusingly, there is no Target::AddSharedModule. Instead, calling GetSharedModule() with
- // a new module will add it to the module list and return a corresponding ModuleSP.
- Error error;
- ModuleSP module = GetTarget().GetSharedModule(module_spec, &error);
- bool load_addr_changed = false;
- module->SetLoadAddress(GetTarget(), module_addr, false, load_addr_changed);
-
- ModuleList loaded_modules;
- loaded_modules.Append(module);
- GetTarget().ModulesDidLoad(loaded_modules);
-}
-
-void
-ProcessWindowsLive::OnUnloadDll(lldb::addr_t module_addr)
-{
- Address resolved_addr;
- if (GetTarget().ResolveLoadAddress(module_addr, resolved_addr))
- {
- ModuleSP module = resolved_addr.GetModule();
- if (module)
- {
- ModuleList unloaded_modules;
- unloaded_modules.Append(module);
- GetTarget().ModulesDidUnload(unloaded_modules, false);
- }
- }
-}
-
-void
-ProcessWindowsLive::OnDebugString(const std::string &string)
-{
-}
-
-void
-ProcessWindowsLive::OnDebuggerError(const Error &error, uint32_t type)
-{
- llvm::sys::ScopedLock lock(m_mutex);
-
- if (m_session_data->m_initial_stop_received)
- {
- // This happened while debugging. Do we shutdown the debugging session, try to continue,
- // or do something else?
- WINERR_IFALL(WINDOWS_LOG_PROCESS, "Error %u occurred during debugging. Unexpected behavior may result. %s",
- error.GetError(), error.AsCString());
- }
- else
- {
- // If we haven't actually launched the process yet, this was an error launching the
- // process. Set the internal error and signal the initial stop event so that the DoLaunch
- // method wakes up and returns a failure.
- m_session_data->m_launch_error = error;
- ::SetEvent(m_session_data->m_initial_stop_event);
- WINERR_IFALL(WINDOWS_LOG_PROCESS, "Error %u occurred launching the process before the initial stop. %s",
- error.GetError(), error.AsCString());
- return;
- }
-}
diff --git a/source/Plugins/Process/Windows/Live/ProcessWindowsLive.h b/source/Plugins/Process/Windows/Live/ProcessWindowsLive.h
deleted file mode 100644
index 657877f529b2..000000000000
--- a/source/Plugins/Process/Windows/Live/ProcessWindowsLive.h
+++ /dev/null
@@ -1,125 +0,0 @@
-//===-- ProcessWindowsLive.h ------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_Plugins_Process_Windows_Live_ProcessWindowsLive_H_
-#define liblldb_Plugins_Process_Windows_Live_ProcessWindowsLive_H_
-
-// C Includes
-
-// C++ Includes
-#include <memory>
-#include <queue>
-
-// Other libraries and framework includes
-#include "ForwardDecl.h"
-#include "IDebugDelegate.h"
-#include "lldb/lldb-forward.h"
-#include "lldb/Core/Error.h"
-#include "lldb/Host/HostThread.h"
-#include "lldb/Target/Process.h"
-
-#include "llvm/Support/Mutex.h"
-
-#include "plugins/Process/Windows/Common/ProcessWindows.h"
-
-class ProcessMonitor;
-
-namespace lldb_private
-{
-class HostProcess;
-class ProcessWindowsData;
-
-class ProcessWindowsLive : public lldb_private::ProcessWindows, public lldb_private::IDebugDelegate
-{
-public:
- //------------------------------------------------------------------
- // Static functions.
- //------------------------------------------------------------------
- static lldb::ProcessSP
- CreateInstance(lldb::TargetSP target_sp,
- lldb::ListenerSP listener_sp,
- const lldb_private::FileSpec *);
-
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- static const char *
- GetPluginDescriptionStatic();
-
- //------------------------------------------------------------------
- // Constructors and destructors
- //------------------------------------------------------------------
- ProcessWindowsLive(lldb::TargetSP target_sp,
- lldb::ListenerSP listener_sp);
-
- ~ProcessWindowsLive();
-
- // lldb_private::Process overrides
- lldb_private::ConstString GetPluginName() override;
- uint32_t GetPluginVersion() override;
-
- lldb_private::Error EnableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
- lldb_private::Error DisableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
-
- lldb_private::Error DoDetach(bool keep_stopped) override;
- lldb_private::Error DoLaunch(lldb_private::Module *exe_module, lldb_private::ProcessLaunchInfo &launch_info) override;
- lldb_private::Error DoAttachToProcessWithID(lldb::pid_t pid,
- const lldb_private::ProcessAttachInfo &attach_info) override;
- lldb_private::Error DoResume() override;
- lldb_private::Error DoDestroy() override;
- lldb_private::Error DoHalt(bool &caused_stop) override;
-
- void DidLaunch() override;
- void DidAttach(lldb_private::ArchSpec &arch_spec) override;
-
- void RefreshStateAfterStop() override;
-
- bool CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) override;
- bool
- DestroyRequiresHalt() override
- {
- return false;
- }
- bool UpdateThreadList(lldb_private::ThreadList &old_thread_list, lldb_private::ThreadList &new_thread_list) override;
- bool IsAlive() 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;
- lldb_private::Error GetMemoryRegionInfo(lldb::addr_t vm_addr, lldb_private::MemoryRegionInfo &info) override;
-
- // IDebugDelegate overrides.
- void OnExitProcess(uint32_t exit_code) override;
- void OnDebuggerConnected(lldb::addr_t image_base) override;
- ExceptionResult OnDebugException(bool first_chance, const lldb_private::ExceptionRecord &record) override;
- void OnCreateThread(const lldb_private::HostThread &thread) override;
- void OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) override;
- void OnLoadDll(const lldb_private::ModuleSpec &module_spec, lldb::addr_t module_addr) override;
- void OnUnloadDll(lldb::addr_t module_addr) override;
- void OnDebugString(const std::string &string) override;
- void OnDebuggerError(const lldb_private::Error &error, uint32_t type) override;
-
- private:
- lldb_private::Error WaitForDebuggerConnection(lldb_private::DebuggerThreadSP debugger,
- lldb_private::HostProcess &process);
-
- llvm::sys::Mutex m_mutex;
-
- // Data for the active debugging session.
- std::unique_ptr<lldb_private::ProcessWindowsData> m_session_data;
-};
-
-}
-
-#endif // liblldb_Plugins_Process_Windows_Live_ProcessWindowsLive_H_
diff --git a/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.cpp b/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.cpp
deleted file mode 100644
index 52b32716e674..000000000000
--- a/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-//===-- TargetThreadWindowsLive.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/Log.h"
-#include "lldb/Core/Logging.h"
-#include "lldb/Core/State.h"
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Host/HostNativeThreadBase.h"
-#include "lldb/Host/windows/HostThreadWindows.h"
-#include "lldb/Host/windows/windows.h"
-#include "lldb/Target/RegisterContext.h"
-
-#include "TargetThreadWindowsLive.h"
-#include "ProcessWindows.h"
-#include "ProcessWindowsLog.h"
-#include "UnwindLLDB.h"
-
-#if defined(_WIN64)
-#include "x64/RegisterContextWindowsLive_x64.h"
-#else
-#include "x86/RegisterContextWindowsLive_x86.h"
-#endif
-
-using namespace lldb;
-using namespace lldb_private;
-
-TargetThreadWindowsLive::TargetThreadWindowsLive(ProcessWindows &process, const HostThread &thread)
- : TargetThreadWindows(process, thread)
- , m_host_thread(thread)
-{
-}
-
-TargetThreadWindowsLive::~TargetThreadWindowsLive()
-{
- DestroyThread();
-}
-
-void
-TargetThreadWindowsLive::RefreshStateAfterStop()
-{
- ::SuspendThread(m_host_thread.GetNativeThread().GetSystemHandle());
- SetState(eStateStopped);
- GetRegisterContext()->InvalidateIfNeeded(false);
-}
-
-void
-TargetThreadWindowsLive::WillResume(lldb::StateType resume_state)
-{
-}
-
-void
-TargetThreadWindowsLive::DidStop()
-{
-}
-
-RegisterContextSP
-TargetThreadWindowsLive::GetRegisterContext()
-{
- if (!m_reg_context_sp)
- m_reg_context_sp = CreateRegisterContextForFrameIndex(0);
-
- return m_reg_context_sp;
-}
-
-RegisterContextSP
-TargetThreadWindowsLive::CreateRegisterContextForFrame(StackFrame *frame)
-{
- return CreateRegisterContextForFrameIndex(frame->GetConcreteFrameIndex());
-}
-
-RegisterContextSP
-TargetThreadWindowsLive::CreateRegisterContextForFrameIndex(uint32_t idx)
-{
- if (!m_reg_context_sp)
- {
- ArchSpec arch = HostInfo::GetArchitecture();
- switch (arch.GetMachine())
- {
- case llvm::Triple::x86:
-#if defined(_WIN64)
- // FIXME: This is a Wow64 process, create a RegisterContextWindows_Wow64
-#else
- m_reg_context_sp.reset(new RegisterContextWindowsLive_x86(*this, idx));
-#endif
- break;
- case llvm::Triple::x86_64:
-#if defined(_WIN64)
- m_reg_context_sp.reset(new RegisterContextWindowsLive_x64(*this, idx));
-#else
- // LLDB is 32-bit, but the target process is 64-bit. We probably can't debug this.
-#endif
- default:
- break;
- }
- }
- return m_reg_context_sp;
-}
-
-bool
-TargetThreadWindowsLive::CalculateStopInfo()
-{
- SetStopInfo(m_stop_info_sp);
- return true;
-}
-
-Unwind *
-TargetThreadWindowsLive::GetUnwinder()
-{
- // FIXME: Implement an unwinder based on the Windows unwinder exposed through DIA SDK.
- if (m_unwinder_ap.get() == NULL)
- m_unwinder_ap.reset(new UnwindLLDB(*this));
- return m_unwinder_ap.get();
-}
-
-bool
-TargetThreadWindowsLive::DoResume()
-{
- StateType resume_state = GetTemporaryResumeState();
- StateType current_state = GetState();
- if (resume_state == current_state)
- return true;
-
- if (resume_state == eStateStepping)
- {
- uint32_t flags_index = GetRegisterContext()->ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
- uint64_t flags_value = GetRegisterContext()->ReadRegisterAsUnsigned(flags_index, 0);
- flags_value |= 0x100; // Set the trap flag on the CPU
- GetRegisterContext()->WriteRegisterFromUnsigned(flags_index, flags_value);
- }
-
- if (resume_state == eStateStepping || resume_state == eStateRunning)
- {
- DWORD previous_suspend_count = 0;
- HANDLE thread_handle = m_host_thread.GetNativeThread().GetSystemHandle();
- do
- {
- previous_suspend_count = ::ResumeThread(thread_handle);
- } while (previous_suspend_count > 0);
- }
- return true;
-}
diff --git a/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.h b/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.h
deleted file mode 100644
index 15262b9e9423..000000000000
--- a/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.h
+++ /dev/null
@@ -1,55 +0,0 @@
-//===-- TargetThreadWindowsLive.h -------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_Plugins_Process_Windows_TargetThreadWindowsLive_H_
-#define liblldb_Plugins_Process_Windows_TargetThreadWindowsLive_H_
-
-#include "lldb/lldb-forward.h"
-#include "lldb/Host/HostThread.h"
-#include "lldb/Target/Thread.h"
-
-#include "Plugins/Process/Windows/Common/TargetThreadWindows.h"
-
-namespace lldb_private
-{
-class ProcessWindows;
-class HostThread;
-class StackFrame;
-
-class TargetThreadWindowsLive : public lldb_private::TargetThreadWindows
-{
- public:
- TargetThreadWindowsLive(ProcessWindows &process, const HostThread &thread);
- virtual ~TargetThreadWindowsLive();
-
- // lldb_private::Thread overrides
- void RefreshStateAfterStop() override;
- void WillResume(lldb::StateType resume_state) override;
- void DidStop() override;
- lldb::RegisterContextSP GetRegisterContext() override;
- lldb::RegisterContextSP CreateRegisterContextForFrame(StackFrame *frame) override;
- bool CalculateStopInfo() override;
- Unwind *GetUnwinder() override;
-
- bool DoResume();
-
- HostThread
- GetHostThread() const
- {
- return m_host_thread;
- }
-
- private:
- lldb::RegisterContextSP CreateRegisterContextForFrameIndex(uint32_t idx);
-
- HostThread m_host_thread;
-};
-}
-
-#endif
diff --git a/source/Plugins/Process/Windows/Live/x64/RegisterContextWindowsLive_x64.cpp b/source/Plugins/Process/Windows/Live/x64/RegisterContextWindowsLive_x64.cpp
deleted file mode 100644
index e74647ab68fb..000000000000
--- a/source/Plugins/Process/Windows/Live/x64/RegisterContextWindowsLive_x64.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-//===-- RegisterContextWindowsLive_x64.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/lldb-private-types.h"
-#include "lldb/Core/Error.h"
-#include "lldb/Core/RegisterValue.h"
-#include "lldb/Host/windows/HostThreadWindows.h"
-#include "lldb/Host/windows/windows.h"
-
-#include "lldb-x86-register-enums.h"
-#include "RegisterContextWindowsLive_x64.h"
-#include "TargetThreadWindows.h"
-
-#include "llvm/ADT/STLExtras.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-RegisterContextWindowsLive_x64::RegisterContextWindowsLive_x64(Thread &thread, uint32_t concrete_frame_idx)
- : RegisterContextWindows_x64(thread, concrete_frame_idx)
-{
-}
-
-RegisterContextWindowsLive_x64::~RegisterContextWindowsLive_x64()
-{
-}
-
-
-bool
-RegisterContextWindowsLive_x64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value)
-{
- if (!CacheAllRegisterValues())
- return false;
-
- switch (reg_info->kinds[eRegisterKindLLDB])
- {
- case lldb_rax_x86_64:
- reg_value.SetUInt64(m_context.Rax);
- break;
- case lldb_rbx_x86_64:
- reg_value.SetUInt64(m_context.Rbx);
- break;
- case lldb_rcx_x86_64:
- reg_value.SetUInt64(m_context.Rcx);
- break;
- case lldb_rdx_x86_64:
- reg_value.SetUInt64(m_context.Rdx);
- break;
- case lldb_rdi_x86_64:
- reg_value.SetUInt64(m_context.Rdi);
- break;
- case lldb_rsi_x86_64:
- reg_value.SetUInt64(m_context.Rsi);
- break;
- case lldb_r8_x86_64:
- reg_value.SetUInt64(m_context.R8);
- break;
- case lldb_r9_x86_64:
- reg_value.SetUInt64(m_context.R9);
- break;
- case lldb_r10_x86_64:
- reg_value.SetUInt64(m_context.R10);
- break;
- case lldb_r11_x86_64:
- reg_value.SetUInt64(m_context.R11);
- break;
- case lldb_r12_x86_64:
- reg_value.SetUInt64(m_context.R12);
- break;
- case lldb_r13_x86_64:
- reg_value.SetUInt64(m_context.R13);
- break;
- case lldb_r14_x86_64:
- reg_value.SetUInt64(m_context.R14);
- break;
- case lldb_r15_x86_64:
- reg_value.SetUInt64(m_context.R15);
- break;
- case lldb_rbp_x86_64:
- reg_value.SetUInt64(m_context.Rbp);
- break;
- case lldb_rsp_x86_64:
- reg_value.SetUInt64(m_context.Rsp);
- break;
- case lldb_rip_x86_64:
- reg_value.SetUInt64(m_context.Rip);
- break;
- case lldb_rflags_x86_64:
- reg_value.SetUInt64(m_context.EFlags);
- break;
- }
- return true;
-}
-
-bool
-RegisterContextWindowsLive_x64::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value)
-{
- // Since we cannot only write a single register value to the inferior, we need to make sure
- // our cached copy of the register values are fresh. Otherwise when writing EAX, for example,
- // we may also overwrite some other register with a stale value.
- if (!CacheAllRegisterValues())
- return false;
-
- switch (reg_info->kinds[eRegisterKindLLDB])
- {
- case lldb_rax_x86_64:
- m_context.Rax = reg_value.GetAsUInt64();
- break;
- case lldb_rbx_x86_64:
- m_context.Rbx = reg_value.GetAsUInt64();
- break;
- case lldb_rcx_x86_64:
- m_context.Rcx = reg_value.GetAsUInt64();
- break;
- case lldb_rdx_x86_64:
- m_context.Rdx = reg_value.GetAsUInt64();
- break;
- case lldb_rdi_x86_64:
- m_context.Rdi = reg_value.GetAsUInt64();
- break;
- case lldb_rsi_x86_64:
- m_context.Rsi = reg_value.GetAsUInt64();
- break;
- case lldb_r8_x86_64:
- m_context.R8 = reg_value.GetAsUInt64();
- break;
- case lldb_r9_x86_64:
- m_context.R9 = reg_value.GetAsUInt64();
- break;
- case lldb_r10_x86_64:
- m_context.R10 = reg_value.GetAsUInt64();
- break;
- case lldb_r11_x86_64:
- m_context.R11 = reg_value.GetAsUInt64();
- break;
- case lldb_r12_x86_64:
- m_context.R12 = reg_value.GetAsUInt64();
- break;
- case lldb_r13_x86_64:
- m_context.R13 = reg_value.GetAsUInt64();
- break;
- case lldb_r14_x86_64:
- m_context.R14 = reg_value.GetAsUInt64();
- break;
- case lldb_r15_x86_64:
- m_context.R15 = reg_value.GetAsUInt64();
- break;
- case lldb_rbp_x86_64:
- m_context.Rbp = reg_value.GetAsUInt64();
- break;
- case lldb_rsp_x86_64:
- m_context.Rsp = reg_value.GetAsUInt64();
- break;
- case lldb_rip_x86_64:
- m_context.Rip = reg_value.GetAsUInt64();
- break;
- case lldb_rflags_x86_64:
- m_context.EFlags = reg_value.GetAsUInt64();
- break;
- }
-
- // Physically update the registers in the target process.
- TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
- return ::SetThreadContext(wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context);
-}
diff --git a/source/Plugins/Process/Windows/Live/x64/RegisterContextWindowsLive_x64.h b/source/Plugins/Process/Windows/Live/x64/RegisterContextWindowsLive_x64.h
deleted file mode 100644
index bd250a994d3a..000000000000
--- a/source/Plugins/Process/Windows/Live/x64/RegisterContextWindowsLive_x64.h
+++ /dev/null
@@ -1,40 +0,0 @@
-//===-- RegisterContextWindowsLive_x64.h ------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_RegisterContextWindowsLive_x64_H_
-#define liblldb_RegisterContextWindowsLive_x64_H_
-
-#include "lldb/lldb-forward.h"
-#include "../../Common/x64/RegisterContextWindows_x64.h"
-
-namespace lldb_private
-{
-
-class Thread;
-
-class RegisterContextWindowsLive_x64 : public RegisterContextWindows_x64
-{
- public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- RegisterContextWindowsLive_x64(Thread &thread, uint32_t concrete_frame_idx);
-
- virtual ~RegisterContextWindowsLive_x64();
-
- //------------------------------------------------------------------
- // Subclasses must override these functions
- //------------------------------------------------------------------
- bool ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value) override;
-
- bool WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value) override;
-};
-}
-
-#endif // #ifndef liblldb_RegisterContextWindowsLive_x64_H_
diff --git a/source/Plugins/Process/Windows/Live/x86/RegisterContextWindowsLive_x86.cpp b/source/Plugins/Process/Windows/Live/x86/RegisterContextWindowsLive_x86.cpp
deleted file mode 100644
index f2decc72d16d..000000000000
--- a/source/Plugins/Process/Windows/Live/x86/RegisterContextWindowsLive_x86.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-//===-- RegisterContextWindowsLive_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/lldb-private-types.h"
-#include "lldb/Core/Error.h"
-#include "lldb/Core/RegisterValue.h"
-#include "lldb/Host/windows/HostThreadWindows.h"
-#include "lldb/Host/windows/windows.h"
-
-#include "lldb-x86-register-enums.h"
-#include "ProcessWindowsLog.h"
-#include "RegisterContextWindowsLive_x86.h"
-#include "TargetThreadWindows.h"
-
-#include "llvm/ADT/STLExtras.h"
-
-using namespace lldb;
-
-namespace lldb_private
-{
-
-RegisterContextWindowsLive_x86::RegisterContextWindowsLive_x86(Thread &thread, uint32_t concrete_frame_idx)
- : RegisterContextWindows_x86(thread, concrete_frame_idx)
-{
-}
-
-RegisterContextWindowsLive_x86::~RegisterContextWindowsLive_x86()
-{
-}
-
-
-bool
-RegisterContextWindowsLive_x86::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value)
-{
- // Since we cannot only write a single register value to the inferior, we need to make sure
- // our cached copy of the register values are fresh. Otherwise when writing EAX, for example,
- // we may also overwrite some other register with a stale value.
- if (!CacheAllRegisterValues())
- return false;
-
- uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- switch (reg)
- {
- case lldb_eax_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EAX", reg_value.GetAsUInt32());
- m_context.Eax = reg_value.GetAsUInt32();
- break;
- case lldb_ebx_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EBX", reg_value.GetAsUInt32());
- m_context.Ebx = reg_value.GetAsUInt32();
- break;
- case lldb_ecx_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to ECX", reg_value.GetAsUInt32());
- m_context.Ecx = reg_value.GetAsUInt32();
- break;
- case lldb_edx_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EDX", reg_value.GetAsUInt32());
- m_context.Edx = reg_value.GetAsUInt32();
- break;
- case lldb_edi_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EDI", reg_value.GetAsUInt32());
- m_context.Edi = reg_value.GetAsUInt32();
- break;
- case lldb_esi_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to ESI", reg_value.GetAsUInt32());
- m_context.Esi = reg_value.GetAsUInt32();
- break;
- case lldb_ebp_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EBP", reg_value.GetAsUInt32());
- m_context.Ebp = reg_value.GetAsUInt32();
- break;
- case lldb_esp_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to ESP", reg_value.GetAsUInt32());
- m_context.Esp = reg_value.GetAsUInt32();
- break;
- case lldb_eip_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EIP", reg_value.GetAsUInt32());
- m_context.Eip = reg_value.GetAsUInt32();
- break;
- case lldb_eflags_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EFLAGS", reg_value.GetAsUInt32());
- m_context.EFlags = reg_value.GetAsUInt32();
- break;
- default:
- WINWARN_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to unknown register %u", reg_value.GetAsUInt32(),
- reg);
- }
-
- // Physically update the registers in the target process.
- TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
- return ::SetThreadContext(wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context);
-}
-
-} // namespace lldb_private
diff --git a/source/Plugins/Process/Windows/Live/x86/RegisterContextWindowsLive_x86.h b/source/Plugins/Process/Windows/Live/x86/RegisterContextWindowsLive_x86.h
deleted file mode 100644
index 9554f017408a..000000000000
--- a/source/Plugins/Process/Windows/Live/x86/RegisterContextWindowsLive_x86.h
+++ /dev/null
@@ -1,36 +0,0 @@
-//===-- RegisterContextWindowsLive_x86.h ------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_RegisterContextWindowsLive_x86_H_
-#define liblldb_RegisterContextWindowsLive_x86_H_
-
-#include "lldb/lldb-forward.h"
-#include "../../Common/x86/RegisterContextWindows_x86.h"
-
-namespace lldb_private
-{
-
-class Thread;
-
-class RegisterContextWindowsLive_x86 : public RegisterContextWindows_x86
-{
- public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- RegisterContextWindowsLive_x86(Thread &thread, uint32_t concrete_frame_idx);
-
- virtual ~RegisterContextWindowsLive_x86();
-
- bool WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value) override;
-};
-
-}
-
-#endif // #ifndef liblldb_RegisterContextWindowsLive_x86_H_
diff --git a/source/Plugins/Process/Windows/MiniDump/CMakeLists.txt b/source/Plugins/Process/Windows/MiniDump/CMakeLists.txt
deleted file mode 100644
index b43246b00351..000000000000
--- a/source/Plugins/Process/Windows/MiniDump/CMakeLists.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-include_directories(../../Utility)
-include_directories(../Common)
-
-set(PROC_WINDOWS_MINIDUMP_SOURCES
- ProcessWinMiniDump.cpp
- ThreadWinMiniDump.cpp
- )
-
-if (CMAKE_SIZEOF_VOID_P EQUAL 4)
- set(PROC_WINDOWS_MINIDUMP_SOURCES ${PROC_WINDOWS_MINIDUMP_SOURCES}
- x86/RegisterContextWindowsMiniDump_x86.cpp
- )
-elseif (CMAKE_SIZEOF_VOID_P EQUAL 8)
- set(PROC_WINDOWS_MINIDUMP_SOURCES ${PROC_WINDOWS_MINIDUMP_SOURCES}
- x64/RegisterContextWindowsMiniDump_x64.cpp
- )
-endif()
-
-add_lldb_library(lldbPluginProcessWinMiniDump
- ${PROC_WINDOWS_MINIDUMP_SOURCES}
- )
diff --git a/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp b/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp
deleted file mode 100644
index 05839667688f..000000000000
--- a/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp
+++ /dev/null
@@ -1,710 +0,0 @@
-//===-- ProcessWinMiniDump.cpp ----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ProcessWinMiniDump.h"
-
-#include "lldb/Host/windows/windows.h"
-#include <DbgHelp.h>
-
-#include <assert.h>
-#include <stdlib.h>
-#include <memory>
-#include <mutex>
-
-#include "Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h"
-#include "lldb/Core/DataBufferHeap.h"
-#include "lldb/Core/Log.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/Section.h"
-#include "lldb/Core/State.h"
-#include "lldb/Target/DynamicLoader.h"
-#include "lldb/Target/MemoryRegionInfo.h"
-#include "lldb/Target/StopInfo.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/UnixSignals.h"
-#include "lldb/Utility/LLDBAssert.h"
-#include "llvm/Support/ConvertUTF.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/raw_ostream.h"
-
-#include "Plugins/Process/Windows/Common/NtStructures.h"
-#include "Plugins/Process/Windows/Common/ProcessWindowsLog.h"
-
-#include "ExceptionRecord.h"
-#include "ThreadWinMiniDump.h"
-
-using namespace lldb_private;
-
-// Implementation class for ProcessWinMiniDump encapsulates the Windows-specific
-// code, keeping non-portable types out of the header files.
-// TODO(amccarth): Determine if we need a mutex for access. Given that this is
-// postmortem debugging, I don't think so.
-class ProcessWinMiniDump::Impl
-{
-public:
- Impl(const FileSpec &core_file, ProcessWinMiniDump *self);
- ~Impl();
-
- Error
- DoLoadCore();
-
- bool
- UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list);
-
- void
- RefreshStateAfterStop();
-
- size_t
- DoReadMemory(lldb::addr_t addr, void *buf, size_t size, Error &error);
-
- Error
- GetMemoryRegionInfo(lldb::addr_t load_addr, lldb_private::MemoryRegionInfo &info);
-
-private:
- // Describes a range of memory captured in the mini dump.
- struct Range
- {
- lldb::addr_t start; // virtual address of the beginning of the range
- size_t size; // size of the range in bytes
- const uint8_t *ptr; // absolute pointer to the first byte of the range
- };
-
- // If the mini dump has a memory range that contains the desired address, it
- // returns true with the details of the range in *range_out. Otherwise, it
- // returns false.
- bool
- FindMemoryRange(lldb::addr_t addr, Range *range_out) const;
-
- lldb_private::Error
- MapMiniDumpIntoMemory();
-
- lldb_private::ArchSpec
- DetermineArchitecture();
-
- void
- ReadExceptionRecord();
-
- void
- ReadMiscInfo();
-
- void
- ReadModuleList();
-
- // A thin wrapper around WinAPI's MiniDumpReadDumpStream to avoid redundant
- // checks. If there's a failure (e.g., if the requested stream doesn't exist),
- // the function returns nullptr and sets *size_out to 0.
- void *
- FindDumpStream(unsigned stream_number, size_t *size_out) const;
-
- // Getting a string out of a mini dump is a chore. You're usually given a
- // relative virtual address (RVA), which points to a counted string that's in
- // Windows Unicode (UTF-16). This wrapper handles all the redirection and
- // returns a UTF-8 copy of the string.
- std::string
- GetMiniDumpString(RVA rva) const;
-
- ProcessWinMiniDump *m_self; // non-owning back pointer
- FileSpec m_core_file;
- HANDLE m_dump_file; // handle to the open minidump file
- HANDLE m_mapping; // handle to the file mapping for the minidump file
- void * m_base_addr; // base memory address of the minidump
- std::shared_ptr<ExceptionRecord> m_exception_sp;
- bool m_is_wow64; // minidump is of a 32-bit process captured with a 64-bit debugger
-};
-
-ProcessWinMiniDump::Impl::Impl(const FileSpec &core_file, ProcessWinMiniDump *self)
- : m_self(self),
- m_core_file(core_file),
- m_dump_file(INVALID_HANDLE_VALUE),
- m_mapping(NULL),
- m_base_addr(nullptr),
- m_exception_sp(),
- m_is_wow64(false)
-{
-}
-
-ProcessWinMiniDump::Impl::~Impl()
-{
- if (m_base_addr)
- {
- ::UnmapViewOfFile(m_base_addr);
- m_base_addr = nullptr;
- }
- if (m_mapping)
- {
- ::CloseHandle(m_mapping);
- m_mapping = NULL;
- }
- if (m_dump_file != INVALID_HANDLE_VALUE)
- {
- ::CloseHandle(m_dump_file);
- m_dump_file = INVALID_HANDLE_VALUE;
- }
-}
-
-Error
-ProcessWinMiniDump::Impl::DoLoadCore()
-{
- Error error = MapMiniDumpIntoMemory();
- if (error.Fail())
- {
- return error;
- }
-
- m_self->GetTarget().SetArchitecture(DetermineArchitecture());
- ReadMiscInfo(); // notably for process ID
- ReadModuleList();
- ReadExceptionRecord();
-
- return error;
-
-}
-
-bool
-ProcessWinMiniDump::Impl::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
-{
- size_t size = 0;
- auto thread_list_ptr = static_cast<const MINIDUMP_THREAD_LIST *>(FindDumpStream(ThreadListStream, &size));
- if (thread_list_ptr)
- {
- const ULONG32 thread_count = thread_list_ptr->NumberOfThreads;
- for (ULONG32 i = 0; i < thread_count; ++i) {
- const auto &mini_dump_thread = thread_list_ptr->Threads[i];
- auto thread_sp = std::make_shared<ThreadWinMiniDump>(*m_self, mini_dump_thread.ThreadId);
- if (mini_dump_thread.ThreadContext.DataSize >= sizeof(CONTEXT))
- {
- const CONTEXT *context = reinterpret_cast<const CONTEXT *>(static_cast<const char *>(m_base_addr) +
- mini_dump_thread.ThreadContext.Rva);
-
- if (m_is_wow64)
- {
- // On Windows, a 32-bit process can run on a 64-bit machine under WOW64.
- // If the minidump was captured with a 64-bit debugger, then the CONTEXT
- // we just grabbed from the mini_dump_thread is the one for the 64-bit
- // "native" process rather than the 32-bit "guest" process we care about.
- // In this case, we can get the 32-bit CONTEXT from the TEB (Thread
- // Environment Block) of the 64-bit process.
- Error error;
- TEB64 wow64teb = {0};
- m_self->ReadMemory(mini_dump_thread.Teb, &wow64teb, sizeof(wow64teb), error);
- if (error.Success())
- {
- // Slot 1 of the thread-local storage in the 64-bit TEB points to a structure
- // that includes the 32-bit CONTEXT (after a ULONG).
- // See: https://msdn.microsoft.com/en-us/library/ms681670.aspx
- const size_t addr = wow64teb.TlsSlots[1];
- Range range = {0};
- if (FindMemoryRange(addr, &range))
- {
- lldbassert(range.start <= addr);
- const size_t offset = addr - range.start + sizeof(ULONG);
- if (offset < range.size)
- {
- const size_t overlap = range.size - offset;
- if (overlap >= sizeof(CONTEXT))
- {
- context = reinterpret_cast<const CONTEXT *>(range.ptr + offset);
- }
- }
- }
- }
-
- // NOTE: We don't currently use the TEB for anything else. If we need it in
- // the future, the 32-bit TEB is located according to the address stored in the
- // first slot of the 64-bit TEB (wow64teb.Reserved1[0]).
- }
-
- thread_sp->SetContext(context);
- }
- new_thread_list.AddThread(thread_sp);
- }
- }
-
- return new_thread_list.GetSize(false) > 0;
-}
-
-void
-ProcessWinMiniDump::Impl::RefreshStateAfterStop()
-{
- if (!m_exception_sp)
- return;
-
- auto active_exception = m_exception_sp;
- std::string desc;
- llvm::raw_string_ostream desc_stream(desc);
- desc_stream << "Exception " << llvm::format_hex(active_exception->GetExceptionCode(), 8)
- << " encountered at address " << llvm::format_hex(active_exception->GetExceptionAddress(), 8);
- m_self->m_thread_list.SetSelectedThreadByID(active_exception->GetThreadID());
- auto stop_thread = m_self->m_thread_list.GetSelectedThread();
- auto stop_info = StopInfo::CreateStopReasonWithException(*stop_thread, desc_stream.str().c_str());
- stop_thread->SetStopInfo(stop_info);
-}
-
-size_t
-ProcessWinMiniDump::Impl::DoReadMemory(lldb::addr_t addr, void *buf, size_t size, Error &error)
-{
- // I don't have a sense of how frequently this is called or how many memory
- // ranges a mini dump typically has, so I'm not sure if searching for the
- // appropriate range linearly each time is stupid. Perhaps we should build
- // an index for faster lookups.
- Range range = {0};
- if (!FindMemoryRange(addr, &range))
- {
- return 0;
- }
-
- // There's at least some overlap between the beginning of the desired range
- // (addr) and the current range. Figure out where the overlap begins and
- // how much overlap there is, then copy it to the destination buffer.
- lldbassert(range.start <= addr);
- const size_t offset = addr - range.start;
- lldbassert(offset < range.size);
- const size_t overlap = std::min(size, range.size - offset);
- std::memcpy(buf, range.ptr + offset, overlap);
- return overlap;
-}
-
-Error
-ProcessWinMiniDump::Impl::GetMemoryRegionInfo(lldb::addr_t load_addr, lldb_private::MemoryRegionInfo &info)
-{
- Error error;
- size_t size;
- info.Clear();
- const auto list = reinterpret_cast<const MINIDUMP_MEMORY_INFO_LIST *>(FindDumpStream(MemoryInfoListStream, &size));
- if (list == nullptr || size < sizeof(MINIDUMP_MEMORY_INFO_LIST))
- {
- error.SetErrorString("the mini dump contains no memory range information");
- return error;
- }
-
- if (list->SizeOfEntry < sizeof(MINIDUMP_MEMORY_INFO))
- {
- error.SetErrorString("the entries in the mini dump memory info list are smaller than expected");
- return error;
- }
-
- if (size < list->SizeOfHeader + list->SizeOfEntry * list->NumberOfEntries)
- {
- error.SetErrorString("the mini dump memory info list is incomplete");
- return error;
- }
-
- const MINIDUMP_MEMORY_INFO *next_entry = nullptr;
-
- for (int i = 0; i < list->NumberOfEntries; ++i)
- {
- const auto entry = reinterpret_cast<const MINIDUMP_MEMORY_INFO *>(reinterpret_cast<const char *>(list) +
- list->SizeOfHeader + i * list->SizeOfEntry);
- const auto head = entry->BaseAddress;
- const auto tail = head + entry->RegionSize;
- if (head <= load_addr && load_addr < tail)
- {
- info.GetRange().SetRangeBase((entry->State != MEM_FREE) ? head : load_addr);
- info.GetRange().SetRangeEnd(tail);
- info.SetReadable(IsPageReadable(entry->Protect) ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
- info.SetWritable(IsPageWritable(entry->Protect) ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
- info.SetExecutable(IsPageExecutable(entry->Protect) ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
- info.SetMapped((entry->State != MEM_FREE) ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
- return error;
- }
- else if (head > load_addr && (next_entry == nullptr || head < next_entry->BaseAddress) )
- {
- // In case there is no region containing load_addr keep track of the nearest region
- // after load_addr so we can return the distance to it.
- next_entry = entry;
- }
- }
-
- // No containing region found. Create an unmapped region that extends to the next region
- // or LLDB_INVALID_ADDRESS
- info.GetRange().SetRangeBase(load_addr);
- info.GetRange().SetRangeEnd((next_entry != nullptr)?next_entry->BaseAddress:LLDB_INVALID_ADDRESS);
- info.SetReadable(MemoryRegionInfo::eNo);
- info.SetWritable(MemoryRegionInfo::eNo);
- info.SetExecutable(MemoryRegionInfo::eNo);
- info.SetMapped(MemoryRegionInfo::eNo);
-
- // Note that the memory info list doesn't seem to contain ranges in kernel space,
- // so if you're walking a stack that has kernel frames, the stack may appear
- // truncated.
- return error;
-}
-
-bool
-ProcessWinMiniDump::Impl::FindMemoryRange(lldb::addr_t addr, Range *range_out) const
-{
- size_t stream_size = 0;
- auto mem_list_stream = static_cast<const MINIDUMP_MEMORY_LIST *>(FindDumpStream(MemoryListStream, &stream_size));
- if (mem_list_stream)
- {
- for (ULONG32 i = 0; i < mem_list_stream->NumberOfMemoryRanges; ++i)
- {
- const MINIDUMP_MEMORY_DESCRIPTOR &mem_desc = mem_list_stream->MemoryRanges[i];
- const MINIDUMP_LOCATION_DESCRIPTOR &loc_desc = mem_desc.Memory;
- const lldb::addr_t range_start = mem_desc.StartOfMemoryRange;
- const size_t range_size = loc_desc.DataSize;
- if (range_start <= addr && addr < range_start + range_size)
- {
- range_out->start = range_start;
- range_out->size = range_size;
- range_out->ptr = reinterpret_cast<const uint8_t *>(m_base_addr) + loc_desc.Rva;
- return true;
- }
- }
- }
-
- // Some mini dumps have a Memory64ListStream that captures all the heap
- // memory. We can't exactly use the same loop as above, because the mini
- // dump uses slightly different data structures to describe those.
- auto mem_list64_stream = static_cast<const MINIDUMP_MEMORY64_LIST *>(FindDumpStream(Memory64ListStream, &stream_size));
- if (mem_list64_stream)
- {
- size_t base_rva = mem_list64_stream->BaseRva;
- for (ULONG32 i = 0; i < mem_list64_stream->NumberOfMemoryRanges; ++i) {
- const MINIDUMP_MEMORY_DESCRIPTOR64 &mem_desc = mem_list64_stream->MemoryRanges[i];
- const lldb::addr_t range_start = mem_desc.StartOfMemoryRange;
- const size_t range_size = mem_desc.DataSize;
- if (range_start <= addr && addr < range_start + range_size)
- {
- range_out->start = range_start;
- range_out->size = range_size;
- range_out->ptr = reinterpret_cast<const uint8_t *>(m_base_addr) + base_rva;
- return true;
- }
- base_rva += range_size;
- }
- }
-
- return false;
-}
-
-Error
-ProcessWinMiniDump::Impl::MapMiniDumpIntoMemory()
-{
- Error error;
- const char *file = m_core_file.GetCString();
- std::wstring wfile;
- if (!llvm::ConvertUTF8toWide(file, wfile))
- {
- error.SetErrorString("Error converting path to UTF-16");
- return error;
- }
- m_dump_file =
- ::CreateFileW(wfile.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if (m_dump_file == INVALID_HANDLE_VALUE)
- {
- error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
- return error;
- }
-
- m_mapping = ::CreateFileMappingW(m_dump_file, NULL, PAGE_READONLY, 0, 0, NULL);
- if (m_mapping == NULL)
- {
- error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
- return error;
- }
-
- m_base_addr = ::MapViewOfFile(m_mapping, FILE_MAP_READ, 0, 0, 0);
- if (m_base_addr == nullptr)
- {
- error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
- return error;
- }
-
- return error;
-}
-
-ArchSpec
-ProcessWinMiniDump::Impl::DetermineArchitecture()
-{
- size_t size = 0;
- auto system_info_ptr = static_cast<const MINIDUMP_SYSTEM_INFO *>(FindDumpStream(SystemInfoStream, &size));
- if (system_info_ptr)
- {
- switch (system_info_ptr->ProcessorArchitecture)
- {
- case PROCESSOR_ARCHITECTURE_INTEL:
- if (system_info_ptr->ProcessorLevel == 6)
- {
- return ArchSpec("i686-pc-windows");
- }
- else
- {
- return ArchSpec("i386-pc-windows");
- }
- break;
- case PROCESSOR_ARCHITECTURE_AMD64:
- return ArchSpec("x86_64-pc-windows");
- default:
- break;
- }
- }
-
- return ArchSpec(); // invalid or unknown
-}
-
-void
-ProcessWinMiniDump::Impl::ReadExceptionRecord()
-{
- size_t size = 0;
- auto exception_stream_ptr = static_cast<MINIDUMP_EXCEPTION_STREAM*>(FindDumpStream(ExceptionStream, &size));
- if (exception_stream_ptr)
- {
- m_exception_sp.reset(
- new ExceptionRecord(exception_stream_ptr->ExceptionRecord, exception_stream_ptr->ThreadId));
- }
- else
- {
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "Minidump has no exception record.");
- // TODO: See if we can recover the exception from the TEB.
- }
-}
-
-void
-ProcessWinMiniDump::Impl::ReadMiscInfo()
-{
- size_t size = 0;
- const auto misc_info_ptr = static_cast<MINIDUMP_MISC_INFO*>(FindDumpStream(MiscInfoStream, &size));
- if (!misc_info_ptr || size < sizeof(MINIDUMP_MISC_INFO)) {
- return;
- }
-
- if ((misc_info_ptr->Flags1 & MINIDUMP_MISC1_PROCESS_ID) != 0) {
- // This misc info record has the process ID.
- m_self->SetID(misc_info_ptr->ProcessId);
- }
-}
-
-void
-ProcessWinMiniDump::Impl::ReadModuleList()
-{
- size_t size = 0;
- auto module_list_ptr = static_cast<MINIDUMP_MODULE_LIST*>(FindDumpStream(ModuleListStream, &size));
- if (!module_list_ptr || module_list_ptr->NumberOfModules == 0)
- {
- return;
- }
-
- for (ULONG32 i = 0; i < module_list_ptr->NumberOfModules; ++i)
- {
- const auto &module = module_list_ptr->Modules[i];
- const auto file_name = GetMiniDumpString(module.ModuleNameRva);
- const auto file_spec = FileSpec(file_name, true);
- if (FileSpec::Compare(file_spec, FileSpec("wow64.dll", false), false) == 0)
- {
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "Minidump is for a WOW64 process.");
- m_is_wow64 = true;
- }
- ModuleSpec module_spec = file_spec;
-
- lldb::ModuleSP module_sp = m_self->GetTarget().GetSharedModule(module_spec);
- if (!module_sp)
- {
- continue;
- }
- bool load_addr_changed = false;
- module_sp->SetLoadAddress(m_self->GetTarget(), module.BaseOfImage, false, load_addr_changed);
- }
-}
-
-void *
-ProcessWinMiniDump::Impl::FindDumpStream(unsigned stream_number, size_t *size_out) const
-{
- void *stream = nullptr;
- *size_out = 0;
-
- MINIDUMP_DIRECTORY *dir = nullptr;
- if (::MiniDumpReadDumpStream(m_base_addr, stream_number, &dir, nullptr, nullptr) && dir != nullptr &&
- dir->Location.DataSize > 0)
- {
- assert(dir->StreamType == stream_number);
- *size_out = dir->Location.DataSize;
- stream = static_cast<void *>(static_cast<char *>(m_base_addr) + dir->Location.Rva);
- }
-
- return stream;
-}
-
-std::string
-ProcessWinMiniDump::Impl::GetMiniDumpString(RVA rva) const
-{
- std::string result;
- if (!m_base_addr)
- {
- return result;
- }
- auto md_string = reinterpret_cast<const MINIDUMP_STRING *>(static_cast<const char *>(m_base_addr) + rva);
- auto source_start = reinterpret_cast<const UTF16 *>(md_string->Buffer);
- const auto source_length = ::wcslen(md_string->Buffer);
- const auto source_end = source_start + source_length;
- result.resize(UNI_MAX_UTF8_BYTES_PER_CODE_POINT * source_length); // worst case length
- auto result_start = reinterpret_cast<UTF8 *>(&result[0]);
- const auto result_end = result_start + result.size();
- ConvertUTF16toUTF8(&source_start, source_end, &result_start, result_end, strictConversion);
- const auto result_size = std::distance(reinterpret_cast<UTF8 *>(&result[0]), result_start);
- result.resize(result_size); // shrink to actual length
- return result;
-}
-
-ConstString
-ProcessWinMiniDump::GetPluginNameStatic()
-{
- static ConstString g_name("win-minidump");
- return g_name;
-}
-
-const char *
-ProcessWinMiniDump::GetPluginDescriptionStatic()
-{
- return "Windows minidump plug-in.";
-}
-
-void
-ProcessWinMiniDump::Terminate()
-{
- PluginManager::UnregisterPlugin(ProcessWinMiniDump::CreateInstance);
-}
-
-lldb::ProcessSP
-ProcessWinMiniDump::CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec *crash_file)
-{
- lldb::ProcessSP process_sp;
- if (crash_file)
- {
- process_sp.reset(new ProcessWinMiniDump(target_sp, listener_sp, *crash_file));
- }
- return process_sp;
-}
-
-bool
-ProcessWinMiniDump::CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name)
-{
- // TODO(amccarth): Eventually, this needs some actual logic.
- return true;
-}
-
-ProcessWinMiniDump::ProcessWinMiniDump(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec &core_file)
- : ProcessWindows(target_sp, listener_sp), m_impl_up(new Impl(core_file, this))
-{
-}
-
-ProcessWinMiniDump::~ProcessWinMiniDump()
-{
- Clear();
- // We need to call finalize on the process before destroying ourselves
- // to make sure all of the broadcaster cleanup goes as planned. If we
- // destruct this class, then Process::~Process() might have problems
- // trying to fully destroy the broadcaster.
- Finalize();
-}
-
-ConstString
-ProcessWinMiniDump::GetPluginName()
-{
- return GetPluginNameStatic();
-}
-
-uint32_t
-ProcessWinMiniDump::GetPluginVersion()
-{
- return 1;
-}
-
-Error
-ProcessWinMiniDump::DoLoadCore()
-{
- return m_impl_up->DoLoadCore();
-}
-
-DynamicLoader *
-ProcessWinMiniDump::GetDynamicLoader()
-{
- if (m_dyld_ap.get() == NULL)
- m_dyld_ap.reset(DynamicLoader::FindPlugin(this, DynamicLoaderWindowsDYLD::GetPluginNameStatic().GetCString()));
- return m_dyld_ap.get();
-}
-
-bool
-ProcessWinMiniDump::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
-{
- return m_impl_up->UpdateThreadList(old_thread_list, new_thread_list);
-}
-
-void
-ProcessWinMiniDump::RefreshStateAfterStop()
-{
- if (!m_impl_up)
- return;
- return m_impl_up->RefreshStateAfterStop();
-}
-
-Error
-ProcessWinMiniDump::DoDestroy()
-{
- return Error();
-}
-
-bool
-ProcessWinMiniDump::IsAlive()
-{
- return true;
-}
-
-bool
-ProcessWinMiniDump::WarnBeforeDetach() const
-{
- // Since this is post-mortem debugging, there's no need to warn the user
- // that quitting the debugger will terminate the process.
- return false;
-}
-
-size_t
-ProcessWinMiniDump::ReadMemory(lldb::addr_t addr, void *buf, size_t size, Error &error)
-{
- // Don't allow the caching that lldb_private::Process::ReadMemory does
- // since we have it all cached our our dump file anyway.
- return DoReadMemory(addr, buf, size, error);
-}
-
-size_t
-ProcessWinMiniDump::DoReadMemory(lldb::addr_t addr, void *buf, size_t size, Error &error)
-{
- return m_impl_up->DoReadMemory(addr, buf, size, error);
-}
-
-Error
-ProcessWinMiniDump::GetMemoryRegionInfo(lldb::addr_t load_addr, lldb_private::MemoryRegionInfo &info)
-{
- return m_impl_up->GetMemoryRegionInfo(load_addr, info);
-}
-
-void
-ProcessWinMiniDump::Clear()
-{
- m_thread_list.Clear();
-}
-
-void
-ProcessWinMiniDump::Initialize()
-{
- static std::once_flag g_once_flag;
-
- std::call_once(g_once_flag, []() {
- PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance);
- });
-}
-
-ArchSpec
-ProcessWinMiniDump::GetArchitecture()
-{
- // TODO
- return ArchSpec();
-}
diff --git a/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h b/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h
deleted file mode 100644
index 3e1ac4bffbe3..000000000000
--- a/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h
+++ /dev/null
@@ -1,104 +0,0 @@
-//===-- ProcessWinMiniDump.h ------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_ProcessWinMiniDump_h_
-#define liblldb_ProcessWinMiniDump_h_
-
-#include <list>
-#include <vector>
-
-#include "lldb/Core/ConstString.h"
-#include "lldb/Core/Error.h"
-#include "lldb/Target/Process.h"
-
-#include "Plugins/Process/Windows/Common/ProcessWindows.h"
-
-struct ThreadData;
-
-class ProcessWinMiniDump : public lldb_private::ProcessWindows
-{
- public:
- static lldb::ProcessSP
- CreateInstance (lldb::TargetSP target_sp,
- lldb::ListenerSP listener_sp,
- const lldb_private::FileSpec *crash_file_path);
-
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- static const char *
- GetPluginDescriptionStatic();
-
- ProcessWinMiniDump(lldb::TargetSP target_sp,
- lldb::ListenerSP listener_sp,
- const lldb_private::FileSpec &core_file);
-
- virtual
- ~ProcessWinMiniDump();
-
- bool
- CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) override;
-
- lldb_private::Error
- DoLoadCore() override;
-
- lldb_private::DynamicLoader *
- GetDynamicLoader() override;
-
- lldb_private::ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override;
-
- lldb_private::Error
- DoDestroy() override;
-
- void
- RefreshStateAfterStop() override;
-
- bool
- IsAlive() override;
-
- bool
- WarnBeforeDetach () const override;
-
- size_t
- ReadMemory(lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error) override;
-
- size_t
- DoReadMemory(lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error) override;
-
- lldb_private::ArchSpec
- GetArchitecture();
-
- lldb_private::Error
- GetMemoryRegionInfo(lldb::addr_t load_addr, lldb_private::MemoryRegionInfo &range_info) override;
-
- protected:
- void
- Clear();
-
- bool
- UpdateThreadList(lldb_private::ThreadList &old_thread_list,
- lldb_private::ThreadList &new_thread_list) override;
-
- private:
- // Keep Windows-specific types out of this header.
- class Impl;
- std::unique_ptr<Impl> m_impl_up;
-};
-
-#endif // liblldb_ProcessWinMiniDump_h_
diff --git a/source/Plugins/Process/Windows/MiniDump/ThreadWinMiniDump.cpp b/source/Plugins/Process/Windows/MiniDump/ThreadWinMiniDump.cpp
deleted file mode 100644
index ddcd15b1ae12..000000000000
--- a/source/Plugins/Process/Windows/MiniDump/ThreadWinMiniDump.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-//===-- ThreadWinMiniDump.cpp -----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ThreadWinMiniDump.h"
-
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Host/windows/windows.h"
-#include <DbgHelp.h>
-
-#include "ProcessWinMiniDump.h"
-#if defined(_WIN64)
-#include "x64/RegisterContextWindowsMiniDump_x64.h"
-#else
-#include "x86/RegisterContextWindowsMiniDump_x86.h"
-#endif
-
-using namespace lldb;
-using namespace lldb_private;
-
-// This is a minimal implementation in order to get something running. It will
-// be fleshed out as more mini-dump functionality is added.
-
-class ThreadWinMiniDump::Data {
- public:
- Data() : m_context(nullptr) {}
- const CONTEXT *m_context;
-};
-
-ThreadWinMiniDump::ThreadWinMiniDump(lldb_private::Process &process, lldb::tid_t tid) :
- Thread(process, tid),
- m_data(new Data)
-{
-}
-
-ThreadWinMiniDump::~ThreadWinMiniDump()
-{
-}
-
-void
-ThreadWinMiniDump::RefreshStateAfterStop()
-{
-}
-
-lldb::RegisterContextSP
-ThreadWinMiniDump::GetRegisterContext()
-{
- if (m_reg_context_sp.get() == NULL) {
- m_reg_context_sp = CreateRegisterContextForFrame (NULL);
- }
- return m_reg_context_sp;
-}
-
-lldb::RegisterContextSP
-ThreadWinMiniDump::CreateRegisterContextForFrame(lldb_private::StackFrame *frame)
-{
- const uint32_t concrete_frame_idx = (frame) ? frame->GetConcreteFrameIndex() : 0;
- RegisterContextSP reg_ctx_sp;
- ArchSpec arch = HostInfo::GetArchitecture();
- switch (arch.GetMachine())
- {
- case llvm::Triple::x86:
-#if defined(_WIN64)
- // FIXME: This is a Wow64 process, create a RegisterContextWindows_Wow64
-#else
- reg_ctx_sp.reset(new RegisterContextWindowsMiniDump_x86(*this, concrete_frame_idx, m_data->m_context));
-#endif
- break;
- case llvm::Triple::x86_64:
-#if defined(_WIN64)
- reg_ctx_sp.reset(new RegisterContextWindowsMiniDump_x64(*this, concrete_frame_idx, m_data->m_context));
-#else
- // LLDB is 32-bit, but the target process is 64-bit. We probably can't debug this.
-#endif
- default:
- break;
- }
- return reg_ctx_sp;
-}
-
-void
-ThreadWinMiniDump::ClearStackFrames()
-{
-}
-
-void
-ThreadWinMiniDump::SetContext(const void *context)
-{
- if (m_data)
- {
- m_data->m_context = static_cast<const CONTEXT *>(context);
- }
-}
-
-bool
-ThreadWinMiniDump::CalculateStopInfo()
-{
- return false;
-}
diff --git a/source/Plugins/Process/Windows/MiniDump/ThreadWinMiniDump.h b/source/Plugins/Process/Windows/MiniDump/ThreadWinMiniDump.h
deleted file mode 100644
index c78925422102..000000000000
--- a/source/Plugins/Process/Windows/MiniDump/ThreadWinMiniDump.h
+++ /dev/null
@@ -1,49 +0,0 @@
-//===-- ThreadWinMiniDump.h -------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_ThreadWinMiniDump_h_
-#define liblldb_ThreadWinMiniDump_h_
-
-#include <string>
-
-#include "lldb/Core/DataExtractor.h"
-#include "lldb/Target/Thread.h"
-
-class ThreadWinMiniDump : public lldb_private::Thread
-{
-public:
- ThreadWinMiniDump(lldb_private::Process &process, lldb::tid_t tid);
-
- virtual
- ~ThreadWinMiniDump();
-
- void
- RefreshStateAfterStop() override;
-
- lldb::RegisterContextSP
- GetRegisterContext() override;
-
- lldb::RegisterContextSP
- CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
-
- void
- ClearStackFrames() override;
-
- void
- SetContext(const void *context);
-
-protected:
- lldb::RegisterContextSP m_reg_context_sp;
- class Data;
- std::unique_ptr<Data> m_data; // for WinAPI-specific data
-
- bool CalculateStopInfo() override;
-};
-
-#endif
diff --git a/source/Plugins/Process/Windows/MiniDump/x64/RegisterContextWindowsMiniDump_x64.cpp b/source/Plugins/Process/Windows/MiniDump/x64/RegisterContextWindowsMiniDump_x64.cpp
deleted file mode 100644
index 41d9195f1eed..000000000000
--- a/source/Plugins/Process/Windows/MiniDump/x64/RegisterContextWindowsMiniDump_x64.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-//===-- RegisterContextWindowsMiniDump_x64.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/lldb-private-types.h"
-#include "lldb/Host/windows/windows.h"
-
-#include "RegisterContextWindowsMiniDump_x64.h"
-
-using namespace lldb;
-
-namespace lldb_private
-{
-
-RegisterContextWindowsMiniDump_x64::RegisterContextWindowsMiniDump_x64(Thread &thread, uint32_t concrete_frame_idx, const CONTEXT *context)
- : RegisterContextWindows_x64(thread, concrete_frame_idx)
-{
- if (context)
- {
- m_context = *context;
- m_context_stale = false;
- }
-}
-
-RegisterContextWindowsMiniDump_x64::~RegisterContextWindowsMiniDump_x64()
-{
-}
-
-bool
-RegisterContextWindowsMiniDump_x64::WriteRegister(const RegisterInfo * /* reg_info */, const RegisterValue & /* reg_value */)
-{
- return false;
-}
-
-bool
-RegisterContextWindowsMiniDump_x64::CacheAllRegisterValues()
-{
- // Since this is post-mortem debugging, we either have the context or we don't.
- return !m_context_stale;
-}
-
-} // namespace lldb_private
diff --git a/source/Plugins/Process/Windows/MiniDump/x64/RegisterContextWindowsMiniDump_x64.h b/source/Plugins/Process/Windows/MiniDump/x64/RegisterContextWindowsMiniDump_x64.h
deleted file mode 100644
index 86d58046113f..000000000000
--- a/source/Plugins/Process/Windows/MiniDump/x64/RegisterContextWindowsMiniDump_x64.h
+++ /dev/null
@@ -1,36 +0,0 @@
-//===-- RegisterContextWindowsMiniDump_x64.h --------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_RegisterContextWindowsMiniDump_x64_H_
-#define liblldb_RegisterContextWindowsMiniDump_x64_H_
-
-#include "lldb/lldb-forward.h"
-#include "Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.h"
-
-namespace lldb_private
-{
-
-class Thread;
-
-class RegisterContextWindowsMiniDump_x64 : public RegisterContextWindows_x64
-{
- public:
- RegisterContextWindowsMiniDump_x64(Thread &thread, uint32_t concrete_frame_idx, const CONTEXT *context);
-
- virtual ~RegisterContextWindowsMiniDump_x64();
-
- bool WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value) override;
-
- protected:
- bool CacheAllRegisterValues() override;
-};
-
-}
-
-#endif // #ifndef liblldb_RegisterContextWindowsMiniDump_x64_H_
diff --git a/source/Plugins/Process/Windows/MiniDump/x86/RegisterContextWindowsMiniDump_x86.cpp b/source/Plugins/Process/Windows/MiniDump/x86/RegisterContextWindowsMiniDump_x86.cpp
deleted file mode 100644
index 2c8a069c5376..000000000000
--- a/source/Plugins/Process/Windows/MiniDump/x86/RegisterContextWindowsMiniDump_x86.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-//===-- RegisterContextWindowsMiniDump_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/lldb-private-types.h"
-#include "lldb/Host/windows/windows.h"
-
-#include "RegisterContextWindowsMiniDump_x86.h"
-
-using namespace lldb;
-
-namespace lldb_private
-{
-
-RegisterContextWindowsMiniDump_x86::RegisterContextWindowsMiniDump_x86(Thread &thread, uint32_t concrete_frame_idx, const CONTEXT *context)
- : RegisterContextWindows_x86(thread, concrete_frame_idx)
-{
- if (context)
- {
- m_context = *context;
- m_context_stale = false;
- }
-}
-
-RegisterContextWindowsMiniDump_x86::~RegisterContextWindowsMiniDump_x86()
-{
-}
-
-bool
-RegisterContextWindowsMiniDump_x86::WriteRegister(const RegisterInfo * /* reg_info */, const RegisterValue & /* reg_value */)
-{
- return false;
-}
-
-bool
-RegisterContextWindowsMiniDump_x86::CacheAllRegisterValues()
-{
- // Since this is post-mortem debugging, we either have the context or we don't.
- return !m_context_stale;
-}
-
-} // namespace lldb_private
diff --git a/source/Plugins/Process/Windows/MiniDump/x86/RegisterContextWindowsMiniDump_x86.h b/source/Plugins/Process/Windows/MiniDump/x86/RegisterContextWindowsMiniDump_x86.h
deleted file mode 100644
index d36e0cfd9e7b..000000000000
--- a/source/Plugins/Process/Windows/MiniDump/x86/RegisterContextWindowsMiniDump_x86.h
+++ /dev/null
@@ -1,36 +0,0 @@
-//===-- RegisterContextWindowsMiniDump_x86.h ------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_RegisterContextWindowsMiniDump_x86_H_
-#define liblldb_RegisterContextWindowsMiniDump_x86_H_
-
-#include "lldb/lldb-forward.h"
-#include "Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.h"
-
-namespace lldb_private
-{
-
-class Thread;
-
-class RegisterContextWindowsMiniDump_x86 : public RegisterContextWindows_x86
-{
- public:
- RegisterContextWindowsMiniDump_x86(Thread &thread, uint32_t concrete_frame_idx, const CONTEXT *context);
-
- virtual ~RegisterContextWindowsMiniDump_x86();
-
- bool WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value) override;
-
- protected:
- bool CacheAllRegisterValues() override;
-};
-
-}
-
-#endif // #ifndef liblldb_RegisterContextWindowsMiniDump_x86_H_
diff --git a/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/source/Plugins/Process/elf-core/ProcessElfCore.cpp
index a729d2beee77..6ac308fe559c 100644
--- a/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -28,8 +28,8 @@
#include "llvm/Support/ELF.h"
-#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
#include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h"
+#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
// Project includes
#include "ProcessElfCore.h"
@@ -37,482 +37,443 @@
using namespace lldb_private;
-ConstString
-ProcessElfCore::GetPluginNameStatic()
-{
- static ConstString g_name("elf-core");
- return g_name;
+ConstString ProcessElfCore::GetPluginNameStatic() {
+ static ConstString g_name("elf-core");
+ return g_name;
}
-const char *
-ProcessElfCore::GetPluginDescriptionStatic()
-{
- return "ELF core dump plug-in.";
+const char *ProcessElfCore::GetPluginDescriptionStatic() {
+ return "ELF core dump plug-in.";
}
-void
-ProcessElfCore::Terminate()
-{
- PluginManager::UnregisterPlugin (ProcessElfCore::CreateInstance);
+void ProcessElfCore::Terminate() {
+ PluginManager::UnregisterPlugin(ProcessElfCore::CreateInstance);
}
-
-lldb::ProcessSP
-ProcessElfCore::CreateInstance (lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec *crash_file)
-{
- lldb::ProcessSP process_sp;
- if (crash_file)
- {
- // Read enough data for a ELF32 header or ELF64 header
- const size_t header_size = sizeof(llvm::ELF::Elf64_Ehdr);
-
- lldb::DataBufferSP data_sp (crash_file->ReadFileContents(0, header_size));
- if (data_sp && data_sp->GetByteSize() == header_size &&
- elf::ELFHeader::MagicBytesMatch (data_sp->GetBytes()))
- {
- elf::ELFHeader elf_header;
- DataExtractor data(data_sp, lldb::eByteOrderLittle, 4);
- lldb::offset_t data_offset = 0;
- if (elf_header.Parse(data, &data_offset))
- {
- if (elf_header.e_type == llvm::ELF::ET_CORE)
- process_sp.reset(new ProcessElfCore (target_sp, listener_sp, *crash_file));
- }
- }
+lldb::ProcessSP ProcessElfCore::CreateInstance(lldb::TargetSP target_sp,
+ lldb::ListenerSP listener_sp,
+ const FileSpec *crash_file) {
+ lldb::ProcessSP process_sp;
+ if (crash_file) {
+ // Read enough data for a ELF32 header or ELF64 header
+ const size_t header_size = sizeof(llvm::ELF::Elf64_Ehdr);
+
+ lldb::DataBufferSP data_sp(crash_file->ReadFileContents(0, header_size));
+ if (data_sp && data_sp->GetByteSize() == header_size &&
+ elf::ELFHeader::MagicBytesMatch(data_sp->GetBytes())) {
+ elf::ELFHeader elf_header;
+ DataExtractor data(data_sp, lldb::eByteOrderLittle, 4);
+ lldb::offset_t data_offset = 0;
+ if (elf_header.Parse(data, &data_offset)) {
+ if (elf_header.e_type == llvm::ELF::ET_CORE)
+ process_sp.reset(
+ new ProcessElfCore(target_sp, listener_sp, *crash_file));
+ }
}
- return process_sp;
+ }
+ return process_sp;
}
-bool
-ProcessElfCore::CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name)
-{
- // For now we are just making sure the file exists for a given module
- if (!m_core_module_sp && m_core_file.Exists())
- {
- ModuleSpec core_module_spec(m_core_file, target_sp->GetArchitecture());
- Error error (ModuleList::GetSharedModule (core_module_spec, m_core_module_sp,
- NULL, NULL, NULL));
- if (m_core_module_sp)
- {
- ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
- if (core_objfile && core_objfile->GetType() == ObjectFile::eTypeCoreFile)
- return true;
- }
+bool ProcessElfCore::CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) {
+ // For now we are just making sure the file exists for a given module
+ if (!m_core_module_sp && m_core_file.Exists()) {
+ ModuleSpec core_module_spec(m_core_file, target_sp->GetArchitecture());
+ Error error(ModuleList::GetSharedModule(core_module_spec, m_core_module_sp,
+ NULL, NULL, NULL));
+ if (m_core_module_sp) {
+ ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
+ if (core_objfile && core_objfile->GetType() == ObjectFile::eTypeCoreFile)
+ return true;
}
- return false;
+ }
+ return false;
}
//----------------------------------------------------------------------
// ProcessElfCore constructor
//----------------------------------------------------------------------
-ProcessElfCore::ProcessElfCore(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
- const FileSpec &core_file) :
- Process (target_sp, listener_sp),
- m_core_module_sp (),
- m_core_file (core_file),
- m_dyld_plugin_name (),
- m_os(llvm::Triple::UnknownOS),
- m_thread_data_valid(false),
- m_thread_data(),
- m_core_aranges ()
-{
-}
+ProcessElfCore::ProcessElfCore(lldb::TargetSP target_sp,
+ lldb::ListenerSP listener_sp,
+ const FileSpec &core_file)
+ : Process(target_sp, listener_sp), m_core_module_sp(),
+ m_core_file(core_file), m_dyld_plugin_name(),
+ m_os(llvm::Triple::UnknownOS), m_thread_data_valid(false),
+ m_thread_data(), m_core_aranges() {}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-ProcessElfCore::~ProcessElfCore()
-{
- Clear();
- // We need to call finalize on the process before destroying ourselves
- // to make sure all of the broadcaster cleanup goes as planned. If we
- // destruct this class, then Process::~Process() might have problems
- // trying to fully destroy the broadcaster.
- Finalize();
+ProcessElfCore::~ProcessElfCore() {
+ Clear();
+ // We need to call finalize on the process before destroying ourselves
+ // to make sure all of the broadcaster cleanup goes as planned. If we
+ // destruct this class, then Process::~Process() might have problems
+ // trying to fully destroy the broadcaster.
+ Finalize();
}
//----------------------------------------------------------------------
// PluginInterface
//----------------------------------------------------------------------
-ConstString
-ProcessElfCore::GetPluginName()
-{
- return GetPluginNameStatic();
+ConstString ProcessElfCore::GetPluginName() { return GetPluginNameStatic(); }
+
+uint32_t ProcessElfCore::GetPluginVersion() { return 1; }
+
+lldb::addr_t ProcessElfCore::AddAddressRangeFromLoadSegment(
+ const elf::ELFProgramHeader *header) {
+ const lldb::addr_t addr = header->p_vaddr;
+ FileRange file_range(header->p_offset, header->p_filesz);
+ VMRangeToFileOffset::Entry range_entry(addr, header->p_memsz, file_range);
+
+ VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back();
+ if (last_entry && last_entry->GetRangeEnd() == range_entry.GetRangeBase() &&
+ last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase() &&
+ last_entry->GetByteSize() == last_entry->data.GetByteSize()) {
+ last_entry->SetRangeEnd(range_entry.GetRangeEnd());
+ last_entry->data.SetRangeEnd(range_entry.data.GetRangeEnd());
+ } else {
+ m_core_aranges.Append(range_entry);
+ }
+
+ // Keep a separate map of permissions that that isn't coalesced so all ranges
+ // are maintained.
+ const uint32_t permissions =
+ ((header->p_flags & llvm::ELF::PF_R) ? lldb::ePermissionsReadable : 0u) |
+ ((header->p_flags & llvm::ELF::PF_W) ? lldb::ePermissionsWritable : 0u) |
+ ((header->p_flags & llvm::ELF::PF_X) ? lldb::ePermissionsExecutable : 0u);
+
+ m_core_range_infos.Append(
+ VMRangeToPermissions::Entry(addr, header->p_memsz, permissions));
+
+ return addr;
}
-uint32_t
-ProcessElfCore::GetPluginVersion()
-{
- return 1;
-}
+//----------------------------------------------------------------------
+// Process Control
+//----------------------------------------------------------------------
+Error ProcessElfCore::DoLoadCore() {
+ Error error;
+ if (!m_core_module_sp) {
+ error.SetErrorString("invalid core module");
+ return error;
+ }
-lldb::addr_t
-ProcessElfCore::AddAddressRangeFromLoadSegment(const elf::ELFProgramHeader *header)
-{
- const lldb::addr_t addr = header->p_vaddr;
- FileRange file_range (header->p_offset, header->p_filesz);
- VMRangeToFileOffset::Entry range_entry(addr, header->p_memsz, file_range);
-
- VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back();
- if (last_entry &&
- last_entry->GetRangeEnd() == range_entry.GetRangeBase() &&
- last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase() &&
- last_entry->GetByteSize() == last_entry->data.GetByteSize())
- {
- last_entry->SetRangeEnd (range_entry.GetRangeEnd());
- last_entry->data.SetRangeEnd (range_entry.data.GetRangeEnd());
- }
- else
- {
- m_core_aranges.Append(range_entry);
- }
+ ObjectFileELF *core = (ObjectFileELF *)(m_core_module_sp->GetObjectFile());
+ if (core == NULL) {
+ error.SetErrorString("invalid core object file");
+ return error;
+ }
- // Keep a separate map of permissions that that isn't coalesced so all ranges
- // are maintained.
- const uint32_t permissions = ((header->p_flags & llvm::ELF::PF_R) ? lldb::ePermissionsReadable : 0) |
- ((header->p_flags & llvm::ELF::PF_W) ? lldb::ePermissionsWritable : 0) |
- ((header->p_flags & llvm::ELF::PF_X) ? lldb::ePermissionsExecutable : 0);
+ const uint32_t num_segments = core->GetProgramHeaderCount();
+ if (num_segments == 0) {
+ error.SetErrorString("core file has no segments");
+ return error;
+ }
- m_core_range_infos.Append(VMRangeToPermissions::Entry(addr, header->p_memsz, permissions));
+ SetCanJIT(false);
- return addr;
-}
+ m_thread_data_valid = true;
-//----------------------------------------------------------------------
-// Process Control
-//----------------------------------------------------------------------
-Error
-ProcessElfCore::DoLoadCore ()
-{
- Error error;
- if (!m_core_module_sp)
- {
- error.SetErrorString ("invalid core module");
- return error;
- }
+ bool ranges_are_sorted = true;
+ lldb::addr_t vm_addr = 0;
+ /// Walk through segments and Thread and Address Map information.
+ /// PT_NOTE - Contains Thread and Register information
+ /// PT_LOAD - Contains a contiguous range of Process Address Space
+ for (uint32_t i = 1; i <= num_segments; i++) {
+ const elf::ELFProgramHeader *header = core->GetProgramHeaderByIndex(i);
+ assert(header != NULL);
- ObjectFileELF *core = (ObjectFileELF *)(m_core_module_sp->GetObjectFile());
- if (core == NULL)
- {
- error.SetErrorString ("invalid core object file");
- return error;
- }
+ DataExtractor data = core->GetSegmentDataByIndex(i);
- const uint32_t num_segments = core->GetProgramHeaderCount();
- if (num_segments == 0)
- {
- error.SetErrorString ("core file has no segments");
+ // Parse thread contexts and auxv structure
+ if (header->p_type == llvm::ELF::PT_NOTE) {
+ error = ParseThreadContextsFromNoteSegment(header, data);
+ if (error.Fail())
return error;
}
-
- SetCanJIT(false);
-
- m_thread_data_valid = true;
-
- bool ranges_are_sorted = true;
- lldb::addr_t vm_addr = 0;
- /// Walk through segments and Thread and Address Map information.
- /// PT_NOTE - Contains Thread and Register information
- /// PT_LOAD - Contains a contiguous range of Process Address Space
- for(uint32_t i = 1; i <= num_segments; i++)
- {
- const elf::ELFProgramHeader *header = core->GetProgramHeaderByIndex(i);
- assert(header != NULL);
-
- DataExtractor data = core->GetSegmentDataByIndex(i);
-
- // Parse thread contexts and auxv structure
- if (header->p_type == llvm::ELF::PT_NOTE)
- ParseThreadContextsFromNoteSegment(header, data);
-
- // PT_LOAD segments contains address map
- if (header->p_type == llvm::ELF::PT_LOAD)
- {
- lldb::addr_t last_addr = AddAddressRangeFromLoadSegment(header);
- if (vm_addr > last_addr)
- ranges_are_sorted = false;
- vm_addr = last_addr;
- }
+ // PT_LOAD segments contains address map
+ if (header->p_type == llvm::ELF::PT_LOAD) {
+ lldb::addr_t last_addr = AddAddressRangeFromLoadSegment(header);
+ if (vm_addr > last_addr)
+ ranges_are_sorted = false;
+ vm_addr = last_addr;
}
-
- if (!ranges_are_sorted)
- {
- m_core_aranges.Sort();
- m_core_range_infos.Sort();
+ }
+
+ if (!ranges_are_sorted) {
+ m_core_aranges.Sort();
+ m_core_range_infos.Sort();
+ }
+
+ // Even if the architecture is set in the target, we need to override
+ // it to match the core file which is always single arch.
+ ArchSpec arch(m_core_module_sp->GetArchitecture());
+ if (arch.IsValid())
+ GetTarget().SetArchitecture(arch);
+
+ SetUnixSignals(UnixSignals::Create(GetArchitecture()));
+
+ // Ensure we found at least one thread that was stopped on a signal.
+ bool siginfo_signal_found = false;
+ bool prstatus_signal_found = false;
+ // Check we found a signal in a SIGINFO note.
+ for (const auto &thread_data: m_thread_data) {
+ if (thread_data.signo != 0)
+ siginfo_signal_found = true;
+ if (thread_data.prstatus_sig != 0)
+ prstatus_signal_found = true;
+ }
+ if (!siginfo_signal_found) {
+ // If we don't have signal from SIGINFO use the signal from each threads
+ // PRSTATUS note.
+ if (prstatus_signal_found) {
+ for (auto &thread_data: m_thread_data)
+ thread_data.signo = thread_data.prstatus_sig;
+ } else if (m_thread_data.size() > 0) {
+ // If all else fails force the first thread to be SIGSTOP
+ m_thread_data.begin()->signo =
+ GetUnixSignals()->GetSignalNumberFromName("SIGSTOP");
}
-
- // Even if the architecture is set in the target, we need to override
- // it to match the core file which is always single arch.
- ArchSpec arch (m_core_module_sp->GetArchitecture());
- if (arch.IsValid())
- GetTarget().SetArchitecture(arch);
-
- SetUnixSignals(UnixSignals::Create(GetArchitecture()));
-
- // Core files are useless without the main executable. See if we can locate the main
- // executable using data we found in the core file notes.
- lldb::ModuleSP exe_module_sp = GetTarget().GetExecutableModule();
- if (!exe_module_sp)
- {
- // The first entry in the NT_FILE might be our executable
- if (!m_nt_file_entries.empty())
- {
- ModuleSpec exe_module_spec;
- exe_module_spec.GetArchitecture() = arch;
- exe_module_spec.GetFileSpec().SetFile(m_nt_file_entries[0].path.GetCString(), false);
- if (exe_module_spec.GetFileSpec())
- {
- exe_module_sp = GetTarget().GetSharedModule(exe_module_spec);
- if (exe_module_sp)
- GetTarget().SetExecutableModule(exe_module_sp, false);
- }
- }
+ }
+
+ // Core files are useless without the main executable. See if we can locate
+ // the main
+ // executable using data we found in the core file notes.
+ lldb::ModuleSP exe_module_sp = GetTarget().GetExecutableModule();
+ if (!exe_module_sp) {
+ // The first entry in the NT_FILE might be our executable
+ if (!m_nt_file_entries.empty()) {
+ ModuleSpec exe_module_spec;
+ exe_module_spec.GetArchitecture() = arch;
+ exe_module_spec.GetFileSpec().SetFile(
+ m_nt_file_entries[0].path.GetCString(), false);
+ if (exe_module_spec.GetFileSpec()) {
+ exe_module_sp = GetTarget().GetSharedModule(exe_module_spec);
+ if (exe_module_sp)
+ GetTarget().SetExecutableModule(exe_module_sp, false);
+ }
}
- return error;
+ }
+ return error;
}
-lldb_private::DynamicLoader *
-ProcessElfCore::GetDynamicLoader ()
-{
- if (m_dyld_ap.get() == NULL)
- m_dyld_ap.reset (DynamicLoader::FindPlugin(this, DynamicLoaderPOSIXDYLD::GetPluginNameStatic().GetCString()));
- return m_dyld_ap.get();
+lldb_private::DynamicLoader *ProcessElfCore::GetDynamicLoader() {
+ if (m_dyld_ap.get() == NULL)
+ m_dyld_ap.reset(DynamicLoader::FindPlugin(
+ this, DynamicLoaderPOSIXDYLD::GetPluginNameStatic().GetCString()));
+ return m_dyld_ap.get();
}
-bool
-ProcessElfCore::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
-{
- const uint32_t num_threads = GetNumThreadContexts ();
- if (!m_thread_data_valid)
- return false;
-
- for (lldb::tid_t tid = 0; tid < num_threads; ++tid)
- {
- const ThreadData &td = m_thread_data[tid];
- lldb::ThreadSP thread_sp(new ThreadElfCore (*this, td));
- new_thread_list.AddThread (thread_sp);
- }
- return new_thread_list.GetSize(false) > 0;
-}
+bool ProcessElfCore::UpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) {
+ const uint32_t num_threads = GetNumThreadContexts();
+ if (!m_thread_data_valid)
+ return false;
-void
-ProcessElfCore::RefreshStateAfterStop ()
-{
+ for (lldb::tid_t tid = 0; tid < num_threads; ++tid) {
+ const ThreadData &td = m_thread_data[tid];
+ lldb::ThreadSP thread_sp(new ThreadElfCore(*this, td));
+ new_thread_list.AddThread(thread_sp);
+ }
+ return new_thread_list.GetSize(false) > 0;
}
-Error
-ProcessElfCore::DoDestroy ()
-{
- return Error();
-}
+void ProcessElfCore::RefreshStateAfterStop() {}
+
+Error ProcessElfCore::DoDestroy() { return Error(); }
//------------------------------------------------------------------
// Process Queries
//------------------------------------------------------------------
-bool
-ProcessElfCore::IsAlive ()
-{
- return true;
-}
+bool ProcessElfCore::IsAlive() { return true; }
//------------------------------------------------------------------
// Process Memory
//------------------------------------------------------------------
-size_t
-ProcessElfCore::ReadMemory (lldb::addr_t addr, void *buf, size_t size, Error &error)
-{
- // Don't allow the caching that lldb_private::Process::ReadMemory does
- // since in core files we have it all cached our our core file anyway.
- return DoReadMemory (addr, buf, size, error);
+size_t ProcessElfCore::ReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ Error &error) {
+ // Don't allow the caching that lldb_private::Process::ReadMemory does
+ // since in core files we have it all cached our our core file anyway.
+ return DoReadMemory(addr, buf, size, error);
}
-Error
-ProcessElfCore::GetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &region_info)
-{
- region_info.Clear();
- const VMRangeToPermissions::Entry *permission_entry = m_core_range_infos.FindEntryThatContainsOrFollows(load_addr);
- if (permission_entry)
- {
- if (permission_entry->Contains(load_addr))
- {
- region_info.GetRange().SetRangeBase(permission_entry->GetRangeBase());
- region_info.GetRange().SetRangeEnd(permission_entry->GetRangeEnd());
- const Flags permissions(permission_entry->data);
- region_info.SetReadable(permissions.Test(lldb::ePermissionsReadable) ? MemoryRegionInfo::eYes
- : MemoryRegionInfo::eNo);
- region_info.SetWritable(permissions.Test(lldb::ePermissionsWritable) ? MemoryRegionInfo::eYes
- : MemoryRegionInfo::eNo);
- region_info.SetExecutable(permissions.Test(lldb::ePermissionsExecutable) ? MemoryRegionInfo::eYes
- : MemoryRegionInfo::eNo);
- region_info.SetMapped(MemoryRegionInfo::eYes);
- }
- else if (load_addr < permission_entry->GetRangeBase())
- {
- region_info.GetRange().SetRangeBase(load_addr);
- region_info.GetRange().SetRangeEnd(permission_entry->GetRangeBase());
- region_info.SetReadable(MemoryRegionInfo::eNo);
- region_info.SetWritable(MemoryRegionInfo::eNo);
- region_info.SetExecutable(MemoryRegionInfo::eNo);
- region_info.SetMapped(MemoryRegionInfo::eNo);
- }
- return Error();
+Error ProcessElfCore::GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &region_info) {
+ region_info.Clear();
+ const VMRangeToPermissions::Entry *permission_entry =
+ m_core_range_infos.FindEntryThatContainsOrFollows(load_addr);
+ if (permission_entry) {
+ if (permission_entry->Contains(load_addr)) {
+ region_info.GetRange().SetRangeBase(permission_entry->GetRangeBase());
+ region_info.GetRange().SetRangeEnd(permission_entry->GetRangeEnd());
+ const Flags permissions(permission_entry->data);
+ region_info.SetReadable(permissions.Test(lldb::ePermissionsReadable)
+ ? MemoryRegionInfo::eYes
+ : MemoryRegionInfo::eNo);
+ region_info.SetWritable(permissions.Test(lldb::ePermissionsWritable)
+ ? MemoryRegionInfo::eYes
+ : MemoryRegionInfo::eNo);
+ region_info.SetExecutable(permissions.Test(lldb::ePermissionsExecutable)
+ ? MemoryRegionInfo::eYes
+ : MemoryRegionInfo::eNo);
+ region_info.SetMapped(MemoryRegionInfo::eYes);
+ } else if (load_addr < permission_entry->GetRangeBase()) {
+ region_info.GetRange().SetRangeBase(load_addr);
+ region_info.GetRange().SetRangeEnd(permission_entry->GetRangeBase());
+ region_info.SetReadable(MemoryRegionInfo::eNo);
+ region_info.SetWritable(MemoryRegionInfo::eNo);
+ region_info.SetExecutable(MemoryRegionInfo::eNo);
+ region_info.SetMapped(MemoryRegionInfo::eNo);
}
-
- region_info.GetRange().SetRangeBase(load_addr);
- region_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
- region_info.SetReadable(MemoryRegionInfo::eNo);
- region_info.SetWritable(MemoryRegionInfo::eNo);
- region_info.SetExecutable(MemoryRegionInfo::eNo);
- region_info.SetMapped(MemoryRegionInfo::eNo);
return Error();
+ }
+
+ region_info.GetRange().SetRangeBase(load_addr);
+ region_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
+ region_info.SetReadable(MemoryRegionInfo::eNo);
+ region_info.SetWritable(MemoryRegionInfo::eNo);
+ region_info.SetExecutable(MemoryRegionInfo::eNo);
+ region_info.SetMapped(MemoryRegionInfo::eNo);
+ return Error();
}
-size_t
-ProcessElfCore::DoReadMemory (lldb::addr_t addr, void *buf, size_t size, Error &error)
-{
- ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
-
- if (core_objfile == NULL)
- return 0;
-
- // Get the address range
- const VMRangeToFileOffset::Entry *address_range = m_core_aranges.FindEntryThatContains (addr);
- if (address_range == NULL || address_range->GetRangeEnd() < addr)
- {
- error.SetErrorStringWithFormat ("core file does not contain 0x%" PRIx64, addr);
- return 0;
- }
-
- // Convert the address into core file offset
- const lldb::addr_t offset = addr - address_range->GetRangeBase();
- const lldb::addr_t file_start = address_range->data.GetRangeBase();
- const lldb::addr_t file_end = address_range->data.GetRangeEnd();
- size_t bytes_to_read = size; // Number of bytes to read from the core file
- size_t bytes_copied = 0; // Number of bytes actually read from the core file
- size_t zero_fill_size = 0; // Padding
- lldb::addr_t bytes_left = 0; // Number of bytes available in the core file from the given address
-
- // Figure out how many on-disk bytes remain in this segment
- // starting at the given offset
- if (file_end > file_start + offset)
- bytes_left = file_end - (file_start + offset);
-
- // Figure out how many bytes we need to zero-fill if we are
- // reading more bytes than available in the on-disk segment
- if (bytes_to_read > bytes_left)
- {
- zero_fill_size = bytes_to_read - bytes_left;
- bytes_to_read = bytes_left;
- }
-
- // If there is data available on the core file read it
- if (bytes_to_read)
- bytes_copied = core_objfile->CopyData(offset + file_start, bytes_to_read, buf);
-
- assert(zero_fill_size <= size);
- // Pad remaining bytes
- if (zero_fill_size)
- memset(((char *)buf) + bytes_copied, 0, zero_fill_size);
-
- return bytes_copied + zero_fill_size;
+size_t ProcessElfCore::DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ Error &error) {
+ ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
+
+ if (core_objfile == NULL)
+ return 0;
+
+ // Get the address range
+ const VMRangeToFileOffset::Entry *address_range =
+ m_core_aranges.FindEntryThatContains(addr);
+ if (address_range == NULL || address_range->GetRangeEnd() < addr) {
+ error.SetErrorStringWithFormat("core file does not contain 0x%" PRIx64,
+ addr);
+ return 0;
+ }
+
+ // Convert the address into core file offset
+ const lldb::addr_t offset = addr - address_range->GetRangeBase();
+ const lldb::addr_t file_start = address_range->data.GetRangeBase();
+ const lldb::addr_t file_end = address_range->data.GetRangeEnd();
+ size_t bytes_to_read = size; // Number of bytes to read from the core file
+ size_t bytes_copied = 0; // Number of bytes actually read from the core file
+ size_t zero_fill_size = 0; // Padding
+ lldb::addr_t bytes_left =
+ 0; // Number of bytes available in the core file from the given address
+
+ // Figure out how many on-disk bytes remain in this segment
+ // starting at the given offset
+ if (file_end > file_start + offset)
+ bytes_left = file_end - (file_start + offset);
+
+ // Figure out how many bytes we need to zero-fill if we are
+ // reading more bytes than available in the on-disk segment
+ if (bytes_to_read > bytes_left) {
+ zero_fill_size = bytes_to_read - bytes_left;
+ bytes_to_read = bytes_left;
+ }
+
+ // If there is data available on the core file read it
+ if (bytes_to_read)
+ bytes_copied =
+ core_objfile->CopyData(offset + file_start, bytes_to_read, buf);
+
+ assert(zero_fill_size <= size);
+ // Pad remaining bytes
+ if (zero_fill_size)
+ memset(((char *)buf) + bytes_copied, 0, zero_fill_size);
+
+ return bytes_copied + zero_fill_size;
}
-void
-ProcessElfCore::Clear()
-{
- m_thread_list.Clear();
- m_os = llvm::Triple::UnknownOS;
+void ProcessElfCore::Clear() {
+ m_thread_list.Clear();
+ m_os = llvm::Triple::UnknownOS;
- SetUnixSignals(std::make_shared<UnixSignals>());
+ SetUnixSignals(std::make_shared<UnixSignals>());
}
-void
-ProcessElfCore::Initialize()
-{
- static std::once_flag g_once_flag;
+void ProcessElfCore::Initialize() {
+ static std::once_flag g_once_flag;
- std::call_once(g_once_flag, []()
- {
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(), CreateInstance);
- });
+ std::call_once(g_once_flag, []() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
+ });
}
-lldb::addr_t
-ProcessElfCore::GetImageInfoAddress()
-{
- ObjectFile *obj_file = GetTarget().GetExecutableModule()->GetObjectFile();
- Address addr = obj_file->GetImageInfoAddress(&GetTarget());
+lldb::addr_t ProcessElfCore::GetImageInfoAddress() {
+ ObjectFile *obj_file = GetTarget().GetExecutableModule()->GetObjectFile();
+ Address addr = obj_file->GetImageInfoAddress(&GetTarget());
- if (addr.IsValid())
- return addr.GetLoadAddress(&GetTarget());
- return LLDB_INVALID_ADDRESS;
+ if (addr.IsValid())
+ return addr.GetLoadAddress(&GetTarget());
+ return LLDB_INVALID_ADDRESS;
}
/// Core files PT_NOTE segment descriptor types
enum {
- NT_PRSTATUS = 1,
- NT_FPREGSET,
- NT_PRPSINFO,
- NT_TASKSTRUCT,
- NT_PLATFORM,
- NT_AUXV,
- NT_FILE = 0x46494c45
+ NT_PRSTATUS = 1,
+ NT_FPREGSET,
+ NT_PRPSINFO,
+ NT_TASKSTRUCT,
+ NT_PLATFORM,
+ NT_AUXV,
+ NT_FILE = 0x46494c45,
+ NT_PRXFPREG = 0x46e62b7f,
+ NT_SIGINFO = 0x53494749,
};
namespace FREEBSD {
enum {
- NT_PRSTATUS = 1,
- NT_FPREGSET,
- NT_PRPSINFO,
- NT_THRMISC = 7,
- NT_PROCSTAT_AUXV = 16,
- NT_PPC_VMX = 0x100
+ NT_PRSTATUS = 1,
+ NT_FPREGSET,
+ NT_PRPSINFO,
+ NT_THRMISC = 7,
+ NT_PROCSTAT_AUXV = 16,
+ NT_PPC_VMX = 0x100
};
-
}
// Parse a FreeBSD NT_PRSTATUS note - see FreeBSD sys/procfs.h for details.
-static void
-ParseFreeBSDPrStatus(ThreadData &thread_data, DataExtractor &data,
- ArchSpec &arch)
-{
- lldb::offset_t offset = 0;
- bool lp64 = (arch.GetMachine() == llvm::Triple::aarch64 ||
- arch.GetMachine() == llvm::Triple::mips64 ||
- arch.GetMachine() == llvm::Triple::ppc64 ||
- arch.GetMachine() == llvm::Triple::x86_64);
- int pr_version = data.GetU32(&offset);
-
- Log *log (GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- {
- if (pr_version > 1)
- log->Printf("FreeBSD PRSTATUS unexpected version %d", pr_version);
- }
-
- // Skip padding, pr_statussz, pr_gregsetsz, pr_fpregsetsz, pr_osreldate
- if (lp64)
- offset += 32;
- else
- offset += 16;
-
- thread_data.signo = data.GetU32(&offset); // pr_cursig
- thread_data.tid = data.GetU32(&offset); // pr_pid
- if (lp64)
- offset += 4;
-
- size_t len = data.GetByteSize() - offset;
- thread_data.gpregset = DataExtractor(data, offset, len);
+static void ParseFreeBSDPrStatus(ThreadData &thread_data, DataExtractor &data,
+ ArchSpec &arch) {
+ lldb::offset_t offset = 0;
+ bool lp64 = (arch.GetMachine() == llvm::Triple::aarch64 ||
+ arch.GetMachine() == llvm::Triple::mips64 ||
+ arch.GetMachine() == llvm::Triple::ppc64 ||
+ arch.GetMachine() == llvm::Triple::x86_64);
+ int pr_version = data.GetU32(&offset);
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log) {
+ if (pr_version > 1)
+ log->Printf("FreeBSD PRSTATUS unexpected version %d", pr_version);
+ }
+
+ // Skip padding, pr_statussz, pr_gregsetsz, pr_fpregsetsz, pr_osreldate
+ if (lp64)
+ offset += 32;
+ else
+ offset += 16;
+
+ thread_data.signo = data.GetU32(&offset); // pr_cursig
+ thread_data.tid = data.GetU32(&offset); // pr_pid
+ if (lp64)
+ offset += 4;
+
+ size_t len = data.GetByteSize() - offset;
+ thread_data.gpregset = DataExtractor(data, offset, len);
}
-static void
-ParseFreeBSDThrMisc(ThreadData &thread_data, DataExtractor &data)
-{
- lldb::offset_t offset = 0;
- thread_data.name = data.GetCStr(&offset, 20);
+static void ParseFreeBSDThrMisc(ThreadData &thread_data, DataExtractor &data) {
+ lldb::offset_t offset = 0;
+ thread_data.name = data.GetCStr(&offset, 20);
}
/// Parse Thread context from PT_NOTE segment and store it in the thread list
@@ -525,183 +486,189 @@ ParseFreeBSDThrMisc(ThreadData &thread_data, DataExtractor &data)
/// b) NT_PRPSINFO - Process info(pid..)
/// c) NT_FPREGSET - Floating point registers
/// 4) The NOTE entries can be in any order
-/// 5) If a core file contains multiple thread contexts then there is two data forms
-/// a) Each thread context(2 or more NOTE entries) contained in its own segment (PT_NOTE)
+/// 5) If a core file contains multiple thread contexts then there is two data
+/// forms
+/// a) Each thread context(2 or more NOTE entries) contained in its own
+/// segment (PT_NOTE)
/// b) All thread context is stored in a single segment(PT_NOTE).
-/// This case is little tricker since while parsing we have to find where the
+/// This case is little tricker since while parsing we have to find where
+/// the
/// new thread starts. The current implementation marks beginning of
/// new thread when it finds NT_PRSTATUS or NT_PRPSINFO NOTE entry.
/// For case (b) there may be either one NT_PRPSINFO per thread, or a single
/// one that applies to all threads (depending on the platform type).
-void
-ProcessElfCore::ParseThreadContextsFromNoteSegment(const elf::ELFProgramHeader *segment_header,
- DataExtractor segment_data)
-{
- assert(segment_header && segment_header->p_type == llvm::ELF::PT_NOTE);
-
- lldb::offset_t offset = 0;
- std::unique_ptr<ThreadData> thread_data(new ThreadData);
- bool have_prstatus = false;
- bool have_prpsinfo = false;
-
- ArchSpec arch = GetArchitecture();
- ELFLinuxPrPsInfo prpsinfo;
- ELFLinuxPrStatus prstatus;
- size_t header_size;
- size_t len;
-
- // Loop through the NOTE entires in the segment
- while (offset < segment_header->p_filesz)
- {
- ELFNote note = ELFNote();
- note.Parse(segment_data, &offset);
-
- // Beginning of new thread
- if ((note.n_type == NT_PRSTATUS && have_prstatus) ||
- (note.n_type == NT_PRPSINFO && have_prpsinfo))
- {
- assert(thread_data->gpregset.GetByteSize() > 0);
- // Add the new thread to thread list
- m_thread_data.push_back(*thread_data);
- *thread_data = ThreadData();
- have_prstatus = false;
- have_prpsinfo = false;
- }
+Error ProcessElfCore::ParseThreadContextsFromNoteSegment(
+ const elf::ELFProgramHeader *segment_header, DataExtractor segment_data) {
+ assert(segment_header && segment_header->p_type == llvm::ELF::PT_NOTE);
+
+ lldb::offset_t offset = 0;
+ std::unique_ptr<ThreadData> thread_data(new ThreadData);
+ bool have_prstatus = false;
+ bool have_prpsinfo = false;
+
+ ArchSpec arch = GetArchitecture();
+ ELFLinuxPrPsInfo prpsinfo;
+ ELFLinuxPrStatus prstatus;
+ ELFLinuxSigInfo siginfo;
+ size_t header_size;
+ size_t len;
+ Error error;
+
+ // Loop through the NOTE entires in the segment
+ while (offset < segment_header->p_filesz) {
+ ELFNote note = ELFNote();
+ note.Parse(segment_data, &offset);
+
+ // Beginning of new thread
+ if ((note.n_type == NT_PRSTATUS && have_prstatus) ||
+ (note.n_type == NT_PRPSINFO && have_prpsinfo)) {
+ assert(thread_data->gpregset.GetByteSize() > 0);
+ // Add the new thread to thread list
+ m_thread_data.push_back(*thread_data);
+ *thread_data = ThreadData();
+ have_prstatus = false;
+ have_prpsinfo = false;
+ }
- size_t note_start, note_size;
- note_start = offset;
- note_size = llvm::alignTo(note.n_descsz, 4);
-
- // Store the NOTE information in the current thread
- DataExtractor note_data (segment_data, note_start, note_size);
- note_data.SetAddressByteSize(m_core_module_sp->GetArchitecture().GetAddressByteSize());
- if (note.n_name == "FreeBSD")
- {
- m_os = llvm::Triple::FreeBSD;
- switch (note.n_type)
- {
- case FREEBSD::NT_PRSTATUS:
- have_prstatus = true;
- ParseFreeBSDPrStatus(*thread_data, note_data, arch);
- break;
- case FREEBSD::NT_FPREGSET:
- thread_data->fpregset = note_data;
- break;
- case FREEBSD::NT_PRPSINFO:
- have_prpsinfo = true;
- break;
- case FREEBSD::NT_THRMISC:
- ParseFreeBSDThrMisc(*thread_data, note_data);
- break;
- case FREEBSD::NT_PROCSTAT_AUXV:
- // FIXME: FreeBSD sticks an int at the beginning of the note
- m_auxv = DataExtractor(segment_data, note_start + 4, note_size - 4);
- break;
- case FREEBSD::NT_PPC_VMX:
- thread_data->vregset = note_data;
- break;
- default:
- break;
- }
+ size_t note_start, note_size;
+ note_start = offset;
+ note_size = llvm::alignTo(note.n_descsz, 4);
+
+ // Store the NOTE information in the current thread
+ DataExtractor note_data(segment_data, note_start, note_size);
+ note_data.SetAddressByteSize(
+ m_core_module_sp->GetArchitecture().GetAddressByteSize());
+ if (note.n_name == "FreeBSD") {
+ m_os = llvm::Triple::FreeBSD;
+ switch (note.n_type) {
+ case FREEBSD::NT_PRSTATUS:
+ have_prstatus = true;
+ ParseFreeBSDPrStatus(*thread_data, note_data, arch);
+ break;
+ case FREEBSD::NT_FPREGSET:
+ thread_data->fpregset = note_data;
+ break;
+ case FREEBSD::NT_PRPSINFO:
+ have_prpsinfo = true;
+ break;
+ case FREEBSD::NT_THRMISC:
+ ParseFreeBSDThrMisc(*thread_data, note_data);
+ break;
+ case FREEBSD::NT_PROCSTAT_AUXV:
+ // FIXME: FreeBSD sticks an int at the beginning of the note
+ m_auxv = DataExtractor(segment_data, note_start + 4, note_size - 4);
+ break;
+ case FREEBSD::NT_PPC_VMX:
+ thread_data->vregset = note_data;
+ break;
+ default:
+ break;
+ }
+ } else if (note.n_name == "CORE") {
+ switch (note.n_type) {
+ case NT_PRSTATUS:
+ have_prstatus = true;
+ error = prstatus.Parse(note_data, arch);
+ if (error.Fail())
+ return error;
+ thread_data->prstatus_sig = prstatus.pr_cursig;
+ thread_data->tid = prstatus.pr_pid;
+ header_size = ELFLinuxPrStatus::GetSize(arch);
+ len = note_data.GetByteSize() - header_size;
+ thread_data->gpregset = DataExtractor(note_data, header_size, len);
+ break;
+ case NT_FPREGSET:
+ // In a i386 core file NT_FPREGSET is present, but it's not the result
+ // of the FXSAVE instruction like in 64 bit files.
+ // The result from FXSAVE is in NT_PRXFPREG for i386 core files
+ if (arch.GetCore() == ArchSpec::eCore_x86_64_x86_64)
+ thread_data->fpregset = note_data;
+ break;
+ case NT_PRPSINFO:
+ have_prpsinfo = true;
+ error = prpsinfo.Parse(note_data, arch);
+ if (error.Fail())
+ return error;
+ thread_data->name = prpsinfo.pr_fname;
+ SetID(prpsinfo.pr_pid);
+ break;
+ case NT_AUXV:
+ m_auxv = DataExtractor(note_data);
+ break;
+ case NT_FILE: {
+ m_nt_file_entries.clear();
+ lldb::offset_t offset = 0;
+ const uint64_t count = note_data.GetAddress(&offset);
+ note_data.GetAddress(&offset); // Skip page size
+ for (uint64_t i = 0; i < count; ++i) {
+ NT_FILE_Entry entry;
+ entry.start = note_data.GetAddress(&offset);
+ entry.end = note_data.GetAddress(&offset);
+ entry.file_ofs = note_data.GetAddress(&offset);
+ m_nt_file_entries.push_back(entry);
}
- else if (note.n_name == "CORE")
- {
- switch (note.n_type)
- {
- case NT_PRSTATUS:
- have_prstatus = true;
- prstatus.Parse(note_data, arch);
- thread_data->signo = prstatus.pr_cursig;
- thread_data->tid = prstatus.pr_pid;
- header_size = ELFLinuxPrStatus::GetSize(arch);
- len = note_data.GetByteSize() - header_size;
- thread_data->gpregset = DataExtractor(note_data, header_size, len);
- break;
- case NT_FPREGSET:
- thread_data->fpregset = note_data;
- break;
- case NT_PRPSINFO:
- have_prpsinfo = true;
- prpsinfo.Parse(note_data, arch);
- thread_data->name = prpsinfo.pr_fname;
- SetID(prpsinfo.pr_pid);
- break;
- case NT_AUXV:
- m_auxv = DataExtractor(note_data);
- break;
- case NT_FILE:
- {
- m_nt_file_entries.clear();
- lldb::offset_t offset = 0;
- const uint64_t count = note_data.GetAddress(&offset);
- note_data.GetAddress(&offset); // Skip page size
- for (uint64_t i = 0; i<count; ++i)
- {
- NT_FILE_Entry entry;
- entry.start = note_data.GetAddress(&offset);
- entry.end = note_data.GetAddress(&offset);
- entry.file_ofs = note_data.GetAddress(&offset);
- m_nt_file_entries.push_back(entry);
- }
- for (uint64_t i = 0; i<count; ++i)
- {
- const char *path = note_data.GetCStr(&offset);
- if (path && path[0])
- m_nt_file_entries[i].path.SetCString(path);
- }
- }
- break;
- default:
- break;
- }
+ for (uint64_t i = 0; i < count; ++i) {
+ const char *path = note_data.GetCStr(&offset);
+ if (path && path[0])
+ m_nt_file_entries[i].path.SetCString(path);
}
-
- offset += note_size;
- }
- // Add last entry in the note section
- if (thread_data && thread_data->gpregset.GetByteSize() > 0)
- {
- m_thread_data.push_back(*thread_data);
+ } break;
+ case NT_SIGINFO: {
+ error = siginfo.Parse(note_data, arch);
+ if (error.Fail())
+ return error;
+ thread_data->signo = siginfo.si_signo;
+ } break;
+ default:
+ break;
+ }
+ } else if (note.n_name == "LINUX") {
+ switch (note.n_type) {
+ case NT_PRXFPREG:
+ thread_data->fpregset = note_data;
+ }
}
+
+ offset += note_size;
+ }
+ // Add last entry in the note section
+ if (thread_data && thread_data->gpregset.GetByteSize() > 0) {
+ m_thread_data.push_back(*thread_data);
+ }
+
+ return error;
}
-uint32_t
-ProcessElfCore::GetNumThreadContexts ()
-{
- if (!m_thread_data_valid)
- DoLoadCore();
- return m_thread_data.size();
+uint32_t ProcessElfCore::GetNumThreadContexts() {
+ if (!m_thread_data_valid)
+ DoLoadCore();
+ return m_thread_data.size();
}
-ArchSpec
-ProcessElfCore::GetArchitecture()
-{
- ObjectFileELF *core_file = (ObjectFileELF *)(m_core_module_sp->GetObjectFile());
- ArchSpec arch;
- core_file->GetArchitecture(arch);
- return arch;
+ArchSpec ProcessElfCore::GetArchitecture() {
+ ObjectFileELF *core_file =
+ (ObjectFileELF *)(m_core_module_sp->GetObjectFile());
+ ArchSpec arch;
+ core_file->GetArchitecture(arch);
+ return arch;
}
-const lldb::DataBufferSP
-ProcessElfCore::GetAuxvData()
-{
- const uint8_t *start = m_auxv.GetDataStart();
- size_t len = m_auxv.GetByteSize();
- lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(start, len));
- return buffer;
+const lldb::DataBufferSP ProcessElfCore::GetAuxvData() {
+ const uint8_t *start = m_auxv.GetDataStart();
+ size_t len = m_auxv.GetByteSize();
+ lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(start, len));
+ return buffer;
}
-bool
-ProcessElfCore::GetProcessInfo(ProcessInstanceInfo &info)
-{
- info.Clear();
- info.SetProcessID(GetID());
- info.SetArchitecture(GetArchitecture());
- lldb::ModuleSP module_sp = GetTarget().GetExecutableModule();
- if (module_sp)
- {
- const bool add_exe_file_as_first_arg = false;
- info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(), add_exe_file_as_first_arg);
- }
- return true;
+bool ProcessElfCore::GetProcessInfo(ProcessInstanceInfo &info) {
+ info.Clear();
+ info.SetProcessID(GetID());
+ info.SetArchitecture(GetArchitecture());
+ lldb::ModuleSP module_sp = GetTarget().GetExecutableModule();
+ if (module_sp) {
+ const bool add_exe_file_as_first_arg = false;
+ info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(),
+ add_exe_file_as_first_arg);
+ }
+ return true;
}
diff --git a/source/Plugins/Process/elf-core/ProcessElfCore.h b/source/Plugins/Process/elf-core/ProcessElfCore.h
index 4bcbb363d3f8..a8dde47b3079 100644
--- a/source/Plugins/Process/elf-core/ProcessElfCore.h
+++ b/source/Plugins/Process/elf-core/ProcessElfCore.h
@@ -32,151 +32,144 @@
struct ThreadData;
-class ProcessElfCore : public lldb_private::Process
-{
+class ProcessElfCore : public lldb_private::Process {
public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- static lldb::ProcessSP
- CreateInstance (lldb::TargetSP target_sp,
- lldb::ListenerSP listener_sp,
- const lldb_private::FileSpec *crash_file_path);
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ 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
- //------------------------------------------------------------------
- ProcessElfCore(lldb::TargetSP target_sp,
- lldb::ListenerSP listener_sp,
- const lldb_private::FileSpec &core_file);
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ ProcessElfCore(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
+ const lldb_private::FileSpec &core_file);
- ~ProcessElfCore() override;
+ ~ProcessElfCore() override;
- //------------------------------------------------------------------
- // Check if a given Process
- //------------------------------------------------------------------
- bool CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) override;
+ //------------------------------------------------------------------
+ // Check if a given Process
+ //------------------------------------------------------------------
+ bool CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) override;
- //------------------------------------------------------------------
- // Creating a new process, or attaching to an existing one
- //------------------------------------------------------------------
- lldb_private::Error DoLoadCore() override;
+ //------------------------------------------------------------------
+ // Creating a new process, or attaching to an existing one
+ //------------------------------------------------------------------
+ lldb_private::Error DoLoadCore() override;
- lldb_private::DynamicLoader *GetDynamicLoader() override;
+ lldb_private::DynamicLoader *GetDynamicLoader() override;
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString GetPluginName() override;
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
- uint32_t GetPluginVersion() override;
+ uint32_t GetPluginVersion() override;
- //------------------------------------------------------------------
- // Process Control
- //------------------------------------------------------------------
- lldb_private::Error DoDestroy() override;
+ //------------------------------------------------------------------
+ // Process Control
+ //------------------------------------------------------------------
+ lldb_private::Error DoDestroy() override;
- void RefreshStateAfterStop() override;
+ void RefreshStateAfterStop() override;
- //------------------------------------------------------------------
- // Process Queries
- //------------------------------------------------------------------
- bool IsAlive() override;
+ //------------------------------------------------------------------
+ // Process Queries
+ //------------------------------------------------------------------
+ bool IsAlive() override;
- //------------------------------------------------------------------
- // Process Memory
- //------------------------------------------------------------------
- size_t ReadMemory(lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error) override;
+ //------------------------------------------------------------------
+ // Process Memory
+ //------------------------------------------------------------------
+ size_t ReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ lldb_private::Error &error) override;
- size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error) override;
+ size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ lldb_private::Error &error) override;
- lldb_private::Error
- GetMemoryRegionInfo(lldb::addr_t load_addr, lldb_private::MemoryRegionInfo &region_info) override;
+ lldb_private::Error
+ GetMemoryRegionInfo(lldb::addr_t load_addr,
+ lldb_private::MemoryRegionInfo &region_info) override;
- lldb::addr_t GetImageInfoAddress() override;
+ lldb::addr_t GetImageInfoAddress() override;
- lldb_private::ArchSpec
- GetArchitecture();
+ lldb_private::ArchSpec GetArchitecture();
- // Returns AUXV structure found in the core file
- const lldb::DataBufferSP
- GetAuxvData() override;
+ // Returns AUXV structure found in the core file
+ const lldb::DataBufferSP GetAuxvData() override;
- bool
- GetProcessInfo(lldb_private::ProcessInstanceInfo &info) override;
+ bool GetProcessInfo(lldb_private::ProcessInstanceInfo &info) override;
protected:
- void
- Clear ( );
+ void Clear();
- 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;
private:
- struct NT_FILE_Entry
- {
- lldb::addr_t start;
- lldb::addr_t end;
- lldb::addr_t file_ofs;
- lldb_private::ConstString path;
- };
-
- //------------------------------------------------------------------
- // For ProcessElfCore only
- //------------------------------------------------------------------
- typedef lldb_private::Range<lldb::addr_t, lldb::addr_t> FileRange;
- typedef lldb_private::RangeDataArray<lldb::addr_t, lldb::addr_t, FileRange, 1> VMRangeToFileOffset;
- typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, uint32_t> VMRangeToPermissions;
-
- lldb::ModuleSP m_core_module_sp;
- lldb_private::FileSpec m_core_file;
- std::string m_dyld_plugin_name;
- DISALLOW_COPY_AND_ASSIGN (ProcessElfCore);
-
- llvm::Triple::OSType m_os;
-
- // True if m_thread_contexts contains valid entries
- bool m_thread_data_valid;
-
- // Contain thread data read from NOTE segments
- std::vector<ThreadData> m_thread_data;
-
- // AUXV structure found from the NOTE segment
- lldb_private::DataExtractor m_auxv;
-
- // Address ranges found in the core
- VMRangeToFileOffset m_core_aranges;
-
- // Permissions for all ranges
- VMRangeToPermissions m_core_range_infos;
-
- // NT_FILE entries found from the NOTE segment
- std::vector<NT_FILE_Entry> m_nt_file_entries;
-
- // Parse thread(s) data structures(prstatus, prpsinfo) from given NOTE segment
- void
- ParseThreadContextsFromNoteSegment (const elf::ELFProgramHeader *segment_header,
- lldb_private::DataExtractor segment_data);
-
- // Returns number of thread contexts stored in the core file
- uint32_t
- GetNumThreadContexts();
-
- // Parse a contiguous address range of the process from LOAD segment
- lldb::addr_t
- AddAddressRangeFromLoadSegment(const elf::ELFProgramHeader *header);
+ struct NT_FILE_Entry {
+ lldb::addr_t start;
+ lldb::addr_t end;
+ lldb::addr_t file_ofs;
+ lldb_private::ConstString path;
+ };
+
+ //------------------------------------------------------------------
+ // For ProcessElfCore only
+ //------------------------------------------------------------------
+ typedef lldb_private::Range<lldb::addr_t, lldb::addr_t> FileRange;
+ typedef lldb_private::RangeDataArray<lldb::addr_t, lldb::addr_t, FileRange, 1>
+ VMRangeToFileOffset;
+ typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, uint32_t>
+ VMRangeToPermissions;
+
+ lldb::ModuleSP m_core_module_sp;
+ lldb_private::FileSpec m_core_file;
+ std::string m_dyld_plugin_name;
+ DISALLOW_COPY_AND_ASSIGN(ProcessElfCore);
+
+ llvm::Triple::OSType m_os;
+
+ // True if m_thread_contexts contains valid entries
+ bool m_thread_data_valid;
+
+ // Contain thread data read from NOTE segments
+ std::vector<ThreadData> m_thread_data;
+
+ // AUXV structure found from the NOTE segment
+ lldb_private::DataExtractor m_auxv;
+
+ // Address ranges found in the core
+ VMRangeToFileOffset m_core_aranges;
+
+ // Permissions for all ranges
+ VMRangeToPermissions m_core_range_infos;
+
+ // NT_FILE entries found from the NOTE segment
+ std::vector<NT_FILE_Entry> m_nt_file_entries;
+
+ // Parse thread(s) data structures(prstatus, prpsinfo) from given NOTE segment
+ lldb_private::Error ParseThreadContextsFromNoteSegment(
+ const elf::ELFProgramHeader *segment_header,
+ lldb_private::DataExtractor segment_data);
+
+ // Returns number of thread contexts stored in the core file
+ uint32_t GetNumThreadContexts();
+
+ // Parse a contiguous address range of the process from LOAD segment
+ lldb::addr_t
+ AddAddressRangeFromLoadSegment(const elf::ELFProgramHeader *header);
};
#endif // liblldb_ProcessElfCore_h_
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
index 6778aeaaac00..81d88e69b97f 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextCorePOSIX_arm.cpp ----------------------*- C++ -*-===//
+//===-- RegisterContextPOSIXCore_arm.cpp ------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,87 +7,65 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Core/DataExtractor.h"
+#include "RegisterContextPOSIXCore_arm.h"
+
#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Thread.h"
-#include "RegisterContextPOSIXCore_arm.h"
using namespace lldb_private;
-RegisterContextCorePOSIX_arm::RegisterContextCorePOSIX_arm(Thread &thread,
- RegisterInfoInterface *register_info,
- const DataExtractor &gpregset,
- const DataExtractor &fpregset)
- : RegisterContextPOSIX_arm(thread, 0, register_info)
-{
- m_gpr_buffer.reset(new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
- m_gpr.SetData(m_gpr_buffer);
- m_gpr.SetByteOrder(gpregset.GetByteOrder());
+RegisterContextCorePOSIX_arm::RegisterContextCorePOSIX_arm(
+ Thread &thread, RegisterInfoInterface *register_info,
+ const DataExtractor &gpregset, const DataExtractor &fpregset)
+ : RegisterContextPOSIX_arm(thread, 0, register_info) {
+ m_gpr_buffer.reset(
+ new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
+ m_gpr.SetData(m_gpr_buffer);
+ m_gpr.SetByteOrder(gpregset.GetByteOrder());
}
-RegisterContextCorePOSIX_arm::~RegisterContextCorePOSIX_arm()
-{
-}
+RegisterContextCorePOSIX_arm::~RegisterContextCorePOSIX_arm() {}
-bool
-RegisterContextCorePOSIX_arm::ReadGPR()
-{
- return true;
-}
+bool RegisterContextCorePOSIX_arm::ReadGPR() { return true; }
-bool
-RegisterContextCorePOSIX_arm::ReadFPR()
-{
- return false;
-}
+bool RegisterContextCorePOSIX_arm::ReadFPR() { return false; }
-bool
-RegisterContextCorePOSIX_arm::WriteGPR()
-{
- assert(0);
- return false;
+bool RegisterContextCorePOSIX_arm::WriteGPR() {
+ assert(0);
+ return false;
}
-bool
-RegisterContextCorePOSIX_arm::WriteFPR()
-{
- assert(0);
- return false;
+bool RegisterContextCorePOSIX_arm::WriteFPR() {
+ assert(0);
+ return false;
}
-bool
-RegisterContextCorePOSIX_arm::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
-{
- lldb::offset_t offset = reg_info->byte_offset;
- uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
- if (offset == reg_info->byte_offset + reg_info->byte_size)
- {
- value = v;
- return true;
- }
- return false;
+bool RegisterContextCorePOSIX_arm::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &value) {
+ lldb::offset_t offset = reg_info->byte_offset;
+ uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
+ if (offset == reg_info->byte_offset + reg_info->byte_size) {
+ value = v;
+ return true;
+ }
+ return false;
}
-bool
-RegisterContextCorePOSIX_arm::ReadAllRegisterValues(lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextCorePOSIX_arm::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_arm::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value)
-{
- return false;
+bool RegisterContextCorePOSIX_arm::WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &value) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_arm::WriteAllRegisterValues(const lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextCorePOSIX_arm::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_arm::HardwareSingleStep(bool enable)
-{
- return false;
+bool RegisterContextCorePOSIX_arm::HardwareSingleStep(bool enable) {
+ return false;
}
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h
index 0e74897b5b5c..c0850e5e414e 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h
@@ -1,4 +1,4 @@
-//===-- RegisterContextCorePOSIX_arm.h --------------------------*- C++ -*-===//
+//===-- RegisterContextPOSIXCore_arm.h --------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,53 +14,44 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/DataBufferHeap.h"
#include "Plugins/Process/Utility/RegisterContextPOSIX_arm.h"
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/DataExtractor.h"
-class RegisterContextCorePOSIX_arm :
- public RegisterContextPOSIX_arm
-{
+class RegisterContextCorePOSIX_arm : public RegisterContextPOSIX_arm {
public:
- RegisterContextCorePOSIX_arm (lldb_private::Thread &thread,
- lldb_private::RegisterInfoInterface *register_info,
- const lldb_private::DataExtractor &gpregset,
- const lldb_private::DataExtractor &fpregset);
+ RegisterContextCorePOSIX_arm(
+ lldb_private::Thread &thread,
+ lldb_private::RegisterInfoInterface *register_info,
+ const lldb_private::DataExtractor &gpregset,
+ const lldb_private::DataExtractor &fpregset);
- ~RegisterContextCorePOSIX_arm() override;
+ ~RegisterContextCorePOSIX_arm() override;
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value) override;
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) override;
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value) override;
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) override;
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- bool
- HardwareSingleStep(bool enable) override;
+ bool HardwareSingleStep(bool enable) override;
protected:
- bool
- ReadGPR() override;
+ bool ReadGPR() override;
- bool
- ReadFPR() override;
+ bool ReadFPR() override;
- bool
- WriteGPR() override;
+ bool WriteGPR() override;
- bool
- WriteFPR() override;
+ bool WriteFPR() override;
private:
- lldb::DataBufferSP m_gpr_buffer;
- lldb_private::DataExtractor m_gpr;
+ lldb::DataBufferSP m_gpr_buffer;
+ lldb_private::DataExtractor m_gpr;
};
#endif // liblldb_RegisterContextCorePOSIX_arm_h_
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
index 7cfdd415ad5b..41c02bf94c37 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextCorePOSIX_arm64.cpp ----------------------*- C++ -*-===//
+//===-- RegisterContextPOSIXCore_arm64.cpp ----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,87 +7,65 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Core/DataExtractor.h"
+#include "RegisterContextPOSIXCore_arm64.h"
+
#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Thread.h"
-#include "RegisterContextPOSIXCore_arm64.h"
using namespace lldb_private;
-RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64(Thread &thread,
- RegisterInfoInterface *register_info,
- const DataExtractor &gpregset,
- const DataExtractor &fpregset)
- : RegisterContextPOSIX_arm64(thread, 0, register_info)
-{
- m_gpr_buffer.reset(new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
- m_gpr.SetData(m_gpr_buffer);
- m_gpr.SetByteOrder(gpregset.GetByteOrder());
+RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64(
+ Thread &thread, RegisterInfoInterface *register_info,
+ const DataExtractor &gpregset, const DataExtractor &fpregset)
+ : RegisterContextPOSIX_arm64(thread, 0, register_info) {
+ m_gpr_buffer.reset(
+ new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
+ m_gpr.SetData(m_gpr_buffer);
+ m_gpr.SetByteOrder(gpregset.GetByteOrder());
}
-RegisterContextCorePOSIX_arm64::~RegisterContextCorePOSIX_arm64()
-{
-}
+RegisterContextCorePOSIX_arm64::~RegisterContextCorePOSIX_arm64() {}
-bool
-RegisterContextCorePOSIX_arm64::ReadGPR()
-{
- return true;
-}
+bool RegisterContextCorePOSIX_arm64::ReadGPR() { return true; }
-bool
-RegisterContextCorePOSIX_arm64::ReadFPR()
-{
- return false;
-}
+bool RegisterContextCorePOSIX_arm64::ReadFPR() { return false; }
-bool
-RegisterContextCorePOSIX_arm64::WriteGPR()
-{
- assert(0);
- return false;
+bool RegisterContextCorePOSIX_arm64::WriteGPR() {
+ assert(0);
+ return false;
}
-bool
-RegisterContextCorePOSIX_arm64::WriteFPR()
-{
- assert(0);
- return false;
+bool RegisterContextCorePOSIX_arm64::WriteFPR() {
+ assert(0);
+ return false;
}
-bool
-RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
-{
- lldb::offset_t offset = reg_info->byte_offset;
- uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
- if (offset == reg_info->byte_offset + reg_info->byte_size)
- {
- value = v;
- return true;
- }
- return false;
+bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &value) {
+ lldb::offset_t offset = reg_info->byte_offset;
+ uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
+ if (offset == reg_info->byte_offset + reg_info->byte_size) {
+ value = v;
+ return true;
+ }
+ return false;
}
-bool
-RegisterContextCorePOSIX_arm64::ReadAllRegisterValues(lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextCorePOSIX_arm64::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_arm64::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value)
-{
- return false;
+bool RegisterContextCorePOSIX_arm64::WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &value) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_arm64::WriteAllRegisterValues(const lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextCorePOSIX_arm64::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_arm64::HardwareSingleStep(bool enable)
-{
- return false;
+bool RegisterContextCorePOSIX_arm64::HardwareSingleStep(bool enable) {
+ return false;
}
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
index 9b05edb1935f..da3e5bff605c 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
@@ -1,4 +1,4 @@
-//===-- RegisterContextCorePOSIX_arm64.h ------------------------*- C++ -*-===//
+//===-- RegisterContextPOSIXCore_arm64.h ------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,53 +14,44 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/DataBufferHeap.h"
#include "Plugins/Process/Utility/RegisterContextPOSIX_arm64.h"
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/DataExtractor.h"
-class RegisterContextCorePOSIX_arm64 :
- public RegisterContextPOSIX_arm64
-{
+class RegisterContextCorePOSIX_arm64 : public RegisterContextPOSIX_arm64 {
public:
- RegisterContextCorePOSIX_arm64 (lldb_private::Thread &thread,
- lldb_private::RegisterInfoInterface *register_info,
- const lldb_private::DataExtractor &gpregset,
- const lldb_private::DataExtractor &fpregset);
+ RegisterContextCorePOSIX_arm64(
+ lldb_private::Thread &thread,
+ lldb_private::RegisterInfoInterface *register_info,
+ const lldb_private::DataExtractor &gpregset,
+ const lldb_private::DataExtractor &fpregset);
- ~RegisterContextCorePOSIX_arm64() override;
+ ~RegisterContextCorePOSIX_arm64() override;
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value) override;
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) override;
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value) override;
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) override;
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- bool
- HardwareSingleStep(bool enable) override;
+ bool HardwareSingleStep(bool enable) override;
protected:
- bool
- ReadGPR() override;
+ bool ReadGPR() override;
- bool
- ReadFPR() override;
+ bool ReadFPR() override;
- bool
- WriteGPR() override;
+ bool WriteGPR() override;
- bool
- WriteFPR() override;
+ bool WriteFPR() override;
private:
- lldb::DataBufferSP m_gpr_buffer;
- lldb_private::DataExtractor m_gpr;
+ lldb::DataBufferSP m_gpr_buffer;
+ lldb_private::DataExtractor m_gpr;
};
#endif // liblldb_RegisterContextCorePOSIX_arm64_h_
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp
index 9d908e371a32..6a168d314fd7 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextCorePOSIX_mips64.cpp ---------------------*- C++ -*-===//
+//===-- RegisterContextPOSIXCore_mips64.cpp ---------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,87 +7,65 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Core/DataExtractor.h"
+#include "RegisterContextPOSIXCore_mips64.h"
+
#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Thread.h"
-#include "RegisterContextPOSIXCore_mips64.h"
using namespace lldb_private;
-RegisterContextCorePOSIX_mips64::RegisterContextCorePOSIX_mips64(Thread &thread,
- RegisterInfoInterface *register_info,
- const DataExtractor &gpregset,
- const DataExtractor &fpregset)
- : RegisterContextPOSIX_mips64(thread, 0, register_info)
-{
- m_gpr_buffer.reset(new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
- m_gpr.SetData(m_gpr_buffer);
- m_gpr.SetByteOrder(gpregset.GetByteOrder());
+RegisterContextCorePOSIX_mips64::RegisterContextCorePOSIX_mips64(
+ Thread &thread, RegisterInfoInterface *register_info,
+ const DataExtractor &gpregset, const DataExtractor &fpregset)
+ : RegisterContextPOSIX_mips64(thread, 0, register_info) {
+ m_gpr_buffer.reset(
+ new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
+ m_gpr.SetData(m_gpr_buffer);
+ m_gpr.SetByteOrder(gpregset.GetByteOrder());
}
-RegisterContextCorePOSIX_mips64::~RegisterContextCorePOSIX_mips64()
-{
-}
+RegisterContextCorePOSIX_mips64::~RegisterContextCorePOSIX_mips64() {}
-bool
-RegisterContextCorePOSIX_mips64::ReadGPR()
-{
- return true;
-}
+bool RegisterContextCorePOSIX_mips64::ReadGPR() { return true; }
-bool
-RegisterContextCorePOSIX_mips64::ReadFPR()
-{
- return false;
-}
+bool RegisterContextCorePOSIX_mips64::ReadFPR() { return false; }
-bool
-RegisterContextCorePOSIX_mips64::WriteGPR()
-{
- assert(0);
- return false;
+bool RegisterContextCorePOSIX_mips64::WriteGPR() {
+ assert(0);
+ return false;
}
-bool
-RegisterContextCorePOSIX_mips64::WriteFPR()
-{
- assert(0);
- return false;
+bool RegisterContextCorePOSIX_mips64::WriteFPR() {
+ assert(0);
+ return false;
}
-bool
-RegisterContextCorePOSIX_mips64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
-{
- lldb::offset_t offset = reg_info->byte_offset;
- uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
- if (offset == reg_info->byte_offset + reg_info->byte_size)
- {
- value = v;
- return true;
- }
- return false;
+bool RegisterContextCorePOSIX_mips64::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &value) {
+ lldb::offset_t offset = reg_info->byte_offset;
+ uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
+ if (offset == reg_info->byte_offset + reg_info->byte_size) {
+ value = v;
+ return true;
+ }
+ return false;
}
-bool
-RegisterContextCorePOSIX_mips64::ReadAllRegisterValues(lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextCorePOSIX_mips64::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_mips64::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value)
-{
- return false;
+bool RegisterContextCorePOSIX_mips64::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &value) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_mips64::WriteAllRegisterValues(const lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextCorePOSIX_mips64::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_mips64::HardwareSingleStep(bool enable)
-{
- return false;
+bool RegisterContextCorePOSIX_mips64::HardwareSingleStep(bool enable) {
+ return false;
}
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h
index 6cbfd504b7db..b1deca3d3178 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h
@@ -1,4 +1,4 @@
-//===-- RegisterContextCorePOSIX_mips64.h -----------------------*- C++ -*-===//
+//===-- RegisterContextPOSIXCore_mips64.h -----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,53 +14,44 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/DataBufferHeap.h"
#include "Plugins/Process/Utility/RegisterContextPOSIX_mips64.h"
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/DataExtractor.h"
-class RegisterContextCorePOSIX_mips64 :
- public RegisterContextPOSIX_mips64
-{
+class RegisterContextCorePOSIX_mips64 : public RegisterContextPOSIX_mips64 {
public:
- RegisterContextCorePOSIX_mips64 (lldb_private::Thread &thread,
- lldb_private::RegisterInfoInterface *register_info,
- const lldb_private::DataExtractor &gpregset,
- const lldb_private::DataExtractor &fpregset);
+ RegisterContextCorePOSIX_mips64(
+ lldb_private::Thread &thread,
+ lldb_private::RegisterInfoInterface *register_info,
+ const lldb_private::DataExtractor &gpregset,
+ const lldb_private::DataExtractor &fpregset);
- ~RegisterContextCorePOSIX_mips64() override;
+ ~RegisterContextCorePOSIX_mips64() override;
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value) override;
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) override;
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value) override;
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) override;
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- bool
- HardwareSingleStep(bool enable) override;
+ bool HardwareSingleStep(bool enable) override;
protected:
- bool
- ReadGPR() override;
+ bool ReadGPR() override;
- bool
- ReadFPR() override;
+ bool ReadFPR() override;
- bool
- WriteGPR() override;
+ bool WriteGPR() override;
- bool
- WriteFPR() override;
+ bool WriteFPR() override;
private:
- lldb::DataBufferSP m_gpr_buffer;
- lldb_private::DataExtractor m_gpr;
+ lldb::DataBufferSP m_gpr_buffer;
+ lldb_private::DataExtractor m_gpr;
};
#endif // liblldb_RegisterContextCorePOSIX_mips64_h_
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp
index 9d8c97849ff8..edfa1902c327 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextCorePOSIX_powerpc.cpp ---------------------*- C++ -*-===//
+//===-- RegisterContextPOSIXCore_powerpc.cpp --------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,127 +7,100 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Core/DataExtractor.h"
+#include "RegisterContextPOSIXCore_powerpc.h"
+
+#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Thread.h"
-#include "RegisterContextPOSIXCore_powerpc.h"
using namespace lldb_private;
-RegisterContextCorePOSIX_powerpc::RegisterContextCorePOSIX_powerpc(Thread &thread,
- RegisterInfoInterface *register_info,
- const DataExtractor &gpregset,
- const DataExtractor &fpregset,
- const DataExtractor &vregset)
- : RegisterContextPOSIX_powerpc(thread, 0, register_info)
-{
- m_gpr_buffer.reset(new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
- m_gpr.SetData(m_gpr_buffer);
- m_gpr.SetByteOrder(gpregset.GetByteOrder());
- m_fpr_buffer.reset(new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize()));
- m_fpr.SetData(m_fpr_buffer);
- m_fpr.SetByteOrder(fpregset.GetByteOrder());
- m_vec_buffer.reset(new DataBufferHeap(vregset.GetDataStart(), vregset.GetByteSize()));
- m_vec.SetData(m_vec_buffer);
- m_vec.SetByteOrder(fpregset.GetByteOrder());
+RegisterContextCorePOSIX_powerpc::RegisterContextCorePOSIX_powerpc(
+ Thread &thread, RegisterInfoInterface *register_info,
+ const DataExtractor &gpregset, const DataExtractor &fpregset,
+ const DataExtractor &vregset)
+ : RegisterContextPOSIX_powerpc(thread, 0, register_info) {
+ m_gpr_buffer.reset(
+ new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
+ m_gpr.SetData(m_gpr_buffer);
+ m_gpr.SetByteOrder(gpregset.GetByteOrder());
+ m_fpr_buffer.reset(
+ new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize()));
+ m_fpr.SetData(m_fpr_buffer);
+ m_fpr.SetByteOrder(fpregset.GetByteOrder());
+ m_vec_buffer.reset(
+ new DataBufferHeap(vregset.GetDataStart(), vregset.GetByteSize()));
+ m_vec.SetData(m_vec_buffer);
+ m_vec.SetByteOrder(vregset.GetByteOrder());
}
-RegisterContextCorePOSIX_powerpc::~RegisterContextCorePOSIX_powerpc()
-{
-}
+RegisterContextCorePOSIX_powerpc::~RegisterContextCorePOSIX_powerpc() {}
-bool
-RegisterContextCorePOSIX_powerpc::ReadGPR()
-{
- return true;
-}
+bool RegisterContextCorePOSIX_powerpc::ReadGPR() { return true; }
-bool
-RegisterContextCorePOSIX_powerpc::ReadFPR()
-{
- return true;
-}
+bool RegisterContextCorePOSIX_powerpc::ReadFPR() { return true; }
-bool
-RegisterContextCorePOSIX_powerpc::ReadVMX()
-{
- return true;
-}
+bool RegisterContextCorePOSIX_powerpc::ReadVMX() { return true; }
-bool
-RegisterContextCorePOSIX_powerpc::WriteGPR()
-{
- assert(0);
- return false;
+bool RegisterContextCorePOSIX_powerpc::WriteGPR() {
+ assert(0);
+ return false;
}
-bool
-RegisterContextCorePOSIX_powerpc::WriteFPR()
-{
- assert(0);
- return false;
+bool RegisterContextCorePOSIX_powerpc::WriteFPR() {
+ assert(0);
+ return false;
}
-bool
-RegisterContextCorePOSIX_powerpc::WriteVMX()
-{
- assert(0);
- return false;
+bool RegisterContextCorePOSIX_powerpc::WriteVMX() {
+ assert(0);
+ return false;
}
-bool
-RegisterContextCorePOSIX_powerpc::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
-{
- lldb::offset_t offset = reg_info->byte_offset;
- if (IsFPR(reg_info->kinds[lldb::eRegisterKindLLDB])) {
- uint64_t v = m_fpr.GetMaxU64(&offset, reg_info->byte_size);
- if (offset == reg_info->byte_offset + reg_info->byte_size)
- {
- value = v;
- return true;
- }
- } else if (IsVMX(reg_info->kinds[lldb::eRegisterKindLLDB])) {
- uint32_t v[4];
- offset = m_vec.CopyData(offset, reg_info->byte_size, &v);
- if (offset == reg_info->byte_size)
- {
- value.SetBytes(v, reg_info->byte_size, m_vec.GetByteOrder());
- return true;
- }
- } else {
- uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
- if (offset == reg_info->byte_offset + reg_info->byte_size)
- {
- if (reg_info->byte_size < sizeof(v))
- value = (uint32_t)v;
- else
- value = v;
- return true;
- }
+bool RegisterContextCorePOSIX_powerpc::ReadRegister(
+ const RegisterInfo *reg_info, RegisterValue &value) {
+ lldb::offset_t offset = reg_info->byte_offset;
+ if (IsFPR(reg_info->kinds[lldb::eRegisterKindLLDB])) {
+ uint64_t v = m_fpr.GetMaxU64(&offset, reg_info->byte_size);
+ if (offset == reg_info->byte_offset + reg_info->byte_size) {
+ value = v;
+ return true;
+ }
+ } else if (IsVMX(reg_info->kinds[lldb::eRegisterKindLLDB])) {
+ uint32_t v[4];
+ offset = m_vec.CopyData(offset, reg_info->byte_size, &v);
+ if (offset == reg_info->byte_size) {
+ value.SetBytes(v, reg_info->byte_size, m_vec.GetByteOrder());
+ return true;
+ }
+ } else {
+ uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
+ if (offset == reg_info->byte_offset + reg_info->byte_size) {
+ if (reg_info->byte_size < sizeof(v))
+ value = (uint32_t)v;
+ else
+ value = v;
+ return true;
}
- return false;
+ }
+ return false;
}
-bool
-RegisterContextCorePOSIX_powerpc::ReadAllRegisterValues(lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextCorePOSIX_powerpc::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_powerpc::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value)
-{
- return false;
+bool RegisterContextCorePOSIX_powerpc::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &value) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_powerpc::WriteAllRegisterValues(const lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextCorePOSIX_powerpc::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_powerpc::HardwareSingleStep(bool enable)
-{
- return false;
+bool RegisterContextCorePOSIX_powerpc::HardwareSingleStep(bool enable) {
+ return false;
}
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h
index 0f587fd1459c..8e6315f06636 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h
@@ -1,4 +1,4 @@
-//===-- RegisterContextCorePOSIX_powerpc.h ----------------------*- C++ -*-===//
+//===-- RegisterContextPOSIXCore_powerpc.h ----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,64 +14,52 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/DataBufferHeap.h"
#include "Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h"
+#include "lldb/Core/DataExtractor.h"
-class RegisterContextCorePOSIX_powerpc :
- public RegisterContextPOSIX_powerpc
-{
+class RegisterContextCorePOSIX_powerpc : public RegisterContextPOSIX_powerpc {
public:
- RegisterContextCorePOSIX_powerpc (lldb_private::Thread &thread,
- lldb_private::RegisterInfoInterface *register_info,
- const lldb_private::DataExtractor &gpregset,
- const lldb_private::DataExtractor &fpregset,
- const lldb_private::DataExtractor &vregset);
+ RegisterContextCorePOSIX_powerpc(
+ lldb_private::Thread &thread,
+ lldb_private::RegisterInfoInterface *register_info,
+ const lldb_private::DataExtractor &gpregset,
+ const lldb_private::DataExtractor &fpregset,
+ const lldb_private::DataExtractor &vregset);
- ~RegisterContextCorePOSIX_powerpc() override;
+ ~RegisterContextCorePOSIX_powerpc() override;
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value) override;
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) override;
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value) override;
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) override;
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- bool
- HardwareSingleStep(bool enable) override;
+ bool HardwareSingleStep(bool enable) override;
protected:
- bool
- ReadGPR() override;
+ bool ReadGPR() override;
- bool
- ReadFPR() override;
+ bool ReadFPR() override;
- bool
- ReadVMX() override;
+ bool ReadVMX() override;
- bool
- WriteGPR() override;
+ bool WriteGPR() override;
- bool
- WriteFPR() override;
+ bool WriteFPR() override;
- bool
- WriteVMX() override;
+ bool WriteVMX() override;
private:
- lldb::DataBufferSP m_gpr_buffer;
- lldb::DataBufferSP m_fpr_buffer;
- lldb::DataBufferSP m_vec_buffer;
- lldb_private::DataExtractor m_gpr;
- lldb_private::DataExtractor m_fpr;
- lldb_private::DataExtractor m_vec;
+ lldb::DataBufferSP m_gpr_buffer;
+ lldb::DataBufferSP m_fpr_buffer;
+ lldb::DataBufferSP m_vec_buffer;
+ lldb_private::DataExtractor m_gpr;
+ lldb_private::DataExtractor m_fpr;
+ lldb_private::DataExtractor m_vec;
};
#endif // liblldb_RegisterContextCorePOSIX_powerpc_h_
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp
index d2f0a8dd3671..6db817789612 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextCorePOSIX_s390x.cpp ----------------------*- C++ -*-===//
+//===-- RegisterContextPOSIXCore_s390x.cpp ----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,109 +7,87 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Core/DataExtractor.h"
+#include "RegisterContextPOSIXCore_s390x.h"
+
+#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Thread.h"
-#include "RegisterContextPOSIXCore_s390x.h"
using namespace lldb_private;
-RegisterContextCorePOSIX_s390x::RegisterContextCorePOSIX_s390x(Thread &thread, RegisterInfoInterface *register_info,
- const DataExtractor &gpregset,
- const DataExtractor &fpregset)
- : RegisterContextPOSIX_s390x(thread, 0, register_info)
-{
- m_gpr_buffer.reset(new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
- m_gpr.SetData(m_gpr_buffer);
- m_gpr.SetByteOrder(gpregset.GetByteOrder());
-
- m_fpr_buffer.reset(new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize()));
- m_fpr.SetData(m_fpr_buffer);
- m_fpr.SetByteOrder(fpregset.GetByteOrder());
+RegisterContextCorePOSIX_s390x::RegisterContextCorePOSIX_s390x(
+ Thread &thread, RegisterInfoInterface *register_info,
+ const DataExtractor &gpregset, const DataExtractor &fpregset)
+ : RegisterContextPOSIX_s390x(thread, 0, register_info) {
+ m_gpr_buffer.reset(
+ new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
+ m_gpr.SetData(m_gpr_buffer);
+ m_gpr.SetByteOrder(gpregset.GetByteOrder());
+
+ m_fpr_buffer.reset(
+ new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize()));
+ m_fpr.SetData(m_fpr_buffer);
+ m_fpr.SetByteOrder(fpregset.GetByteOrder());
}
-RegisterContextCorePOSIX_s390x::~RegisterContextCorePOSIX_s390x()
-{
-}
+RegisterContextCorePOSIX_s390x::~RegisterContextCorePOSIX_s390x() {}
-bool
-RegisterContextCorePOSIX_s390x::ReadGPR()
-{
- return true;
-}
+bool RegisterContextCorePOSIX_s390x::ReadGPR() { return true; }
+
+bool RegisterContextCorePOSIX_s390x::ReadFPR() { return true; }
-bool
-RegisterContextCorePOSIX_s390x::ReadFPR()
-{
- return true;
+bool RegisterContextCorePOSIX_s390x::WriteGPR() {
+ assert(0);
+ return false;
}
-bool
-RegisterContextCorePOSIX_s390x::WriteGPR()
-{
- assert(0);
- return false;
+bool RegisterContextCorePOSIX_s390x::WriteFPR() {
+ assert(0);
+ return false;
}
-bool
-RegisterContextCorePOSIX_s390x::WriteFPR()
-{
- assert(0);
+bool RegisterContextCorePOSIX_s390x::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &value) {
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ if (reg == LLDB_INVALID_REGNUM)
return false;
-}
-bool
-RegisterContextCorePOSIX_s390x::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
-{
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (reg == LLDB_INVALID_REGNUM)
- return false;
-
- if (IsGPR(reg))
- {
- lldb::offset_t offset = reg_info->byte_offset;
- uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
- if (offset == reg_info->byte_offset + reg_info->byte_size)
- {
- value.SetUInt(v, reg_info->byte_size);
- return true;
- }
+ if (IsGPR(reg)) {
+ lldb::offset_t offset = reg_info->byte_offset;
+ uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
+ if (offset == reg_info->byte_offset + reg_info->byte_size) {
+ value.SetUInt(v, reg_info->byte_size);
+ return true;
}
-
- if (IsFPR(reg))
- {
- lldb::offset_t offset = reg_info->byte_offset;
- uint64_t v = m_fpr.GetMaxU64(&offset, reg_info->byte_size);
- if (offset == reg_info->byte_offset + reg_info->byte_size)
- {
- value.SetUInt(v, reg_info->byte_size);
- return true;
- }
+ }
+
+ if (IsFPR(reg)) {
+ lldb::offset_t offset = reg_info->byte_offset;
+ uint64_t v = m_fpr.GetMaxU64(&offset, reg_info->byte_size);
+ if (offset == reg_info->byte_offset + reg_info->byte_size) {
+ value.SetUInt(v, reg_info->byte_size);
+ return true;
}
+ }
- return false;
+ return false;
}
-bool
-RegisterContextCorePOSIX_s390x::ReadAllRegisterValues(lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextCorePOSIX_s390x::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_s390x::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value)
-{
- return false;
+bool RegisterContextCorePOSIX_s390x::WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &value) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_s390x::WriteAllRegisterValues(const lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextCorePOSIX_s390x::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_s390x::HardwareSingleStep(bool enable)
-{
- return false;
+bool RegisterContextCorePOSIX_s390x::HardwareSingleStep(bool enable) {
+ return false;
}
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h
index 8bb6fe1771ef..516e5c57e2b9 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h
@@ -1,4 +1,4 @@
-//===-- RegisterContextCorePOSIX_s390x.h ------------------------*- C++ -*-===//
+//===-- RegisterContextPOSIXCore_s390x.h ------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,52 +14,46 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/DataBufferHeap.h"
#include "Plugins/Process/Utility/RegisterContextPOSIX_s390x.h"
+#include "lldb/Core/DataExtractor.h"
-class RegisterContextCorePOSIX_s390x : public RegisterContextPOSIX_s390x
-{
+class RegisterContextCorePOSIX_s390x : public RegisterContextPOSIX_s390x {
public:
- RegisterContextCorePOSIX_s390x(lldb_private::Thread &thread, lldb_private::RegisterInfoInterface *register_info,
- const lldb_private::DataExtractor &gpregset,
- const lldb_private::DataExtractor &fpregset);
+ RegisterContextCorePOSIX_s390x(
+ lldb_private::Thread &thread,
+ lldb_private::RegisterInfoInterface *register_info,
+ const lldb_private::DataExtractor &gpregset,
+ const lldb_private::DataExtractor &fpregset);
- ~RegisterContextCorePOSIX_s390x() override;
+ ~RegisterContextCorePOSIX_s390x() override;
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value) override;
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) override;
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value) override;
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) override;
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- bool
- HardwareSingleStep(bool enable) override;
+ bool HardwareSingleStep(bool enable) override;
protected:
- bool
- ReadGPR() override;
+ bool ReadGPR() override;
- bool
- ReadFPR() override;
+ bool ReadFPR() override;
- bool
- WriteGPR() override;
+ bool WriteGPR() override;
- bool
- WriteFPR() override;
+ bool WriteFPR() override;
private:
- lldb::DataBufferSP m_gpr_buffer;
- lldb_private::DataExtractor m_gpr;
+ lldb::DataBufferSP m_gpr_buffer;
+ lldb_private::DataExtractor m_gpr;
- lldb::DataBufferSP m_fpr_buffer;
- lldb_private::DataExtractor m_fpr;
+ lldb::DataBufferSP m_fpr_buffer;
+ lldb_private::DataExtractor m_fpr;
};
#endif // liblldb_RegisterContextCorePOSIX_s390x_h_
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp
index 926c7aff3603..7f8223f7752e 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextCorePOSIX_x86_64.cpp ---------------------*- C++ -*-===//
+//===-- RegisterContextPOSIXCore_x86_64.cpp ---------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,93 +7,92 @@
//
//===----------------------------------------------------------------------===//
+#include "RegisterContextPOSIXCore_x86_64.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Thread.h"
-#include "RegisterContextPOSIXCore_x86_64.h"
using namespace lldb_private;
-RegisterContextCorePOSIX_x86_64::RegisterContextCorePOSIX_x86_64(Thread &thread,
- RegisterInfoInterface *register_info,
- const DataExtractor &gpregset,
- const DataExtractor &fpregset)
- : RegisterContextPOSIX_x86 (thread, 0, register_info)
-{
- size_t size, len;
-
- size = GetGPRSize();
- m_gpregset = new uint8_t[size];
- len = gpregset.ExtractBytes (0, size, lldb::eByteOrderLittle, m_gpregset);
- assert(len == size);
-}
+RegisterContextCorePOSIX_x86_64::RegisterContextCorePOSIX_x86_64(
+ Thread &thread, RegisterInfoInterface *register_info,
+ const DataExtractor &gpregset, const DataExtractor &fpregset)
+ : RegisterContextPOSIX_x86(thread, 0, register_info) {
+ size_t size, len;
+
+ size = GetGPRSize();
+ m_gpregset.reset(new uint8_t[size]);
+ len =
+ gpregset.ExtractBytes(0, size, lldb::eByteOrderLittle, m_gpregset.get());
+ if (len != size)
+ m_gpregset.reset();
-RegisterContextCorePOSIX_x86_64::~RegisterContextCorePOSIX_x86_64()
-{
- delete [] m_gpregset;
+ size = sizeof(FXSAVE);
+ m_fpregset.reset(new uint8_t[size]);
+ len =
+ fpregset.ExtractBytes(0, size, lldb::eByteOrderLittle, m_fpregset.get());
+ if (len != size)
+ m_fpregset.reset();
}
-bool
-RegisterContextCorePOSIX_x86_64::ReadGPR()
-{
- return m_gpregset != NULL;
+bool RegisterContextCorePOSIX_x86_64::ReadGPR() {
+ return m_gpregset != nullptr;
}
-bool
-RegisterContextCorePOSIX_x86_64::ReadFPR()
-{
- return false;
+bool RegisterContextCorePOSIX_x86_64::ReadFPR() {
+ return m_fpregset != nullptr;
}
-bool
-RegisterContextCorePOSIX_x86_64::WriteGPR()
-{
- assert(0);
- return false;
+bool RegisterContextCorePOSIX_x86_64::WriteGPR() {
+ assert(0);
+ return false;
}
-bool
-RegisterContextCorePOSIX_x86_64::WriteFPR()
-{
- assert(0);
- return false;
+bool RegisterContextCorePOSIX_x86_64::WriteFPR() {
+ assert(0);
+ return false;
}
-bool
-RegisterContextCorePOSIX_x86_64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
-{
- switch (reg_info->byte_size)
- {
- case 4:
- value = *(uint32_t *)(m_gpregset + reg_info->byte_offset);
- return true;
- case 8:
- value = *(uint64_t *)(m_gpregset + reg_info->byte_offset);
- return true;
- }
+bool RegisterContextCorePOSIX_x86_64::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &value) {
+ const uint8_t *src;
+ size_t offset;
+ const size_t fxsave_offset = reg_info->byte_offset - GetFXSAVEOffset();
+ // make the offset relative to the beginning of the FXSAVE structure
+ // because this is the data that we have (not the entire UserArea)
+
+ if (m_gpregset && reg_info->byte_offset < GetGPRSize()) {
+ src = m_gpregset.get();
+ offset = reg_info->byte_offset;
+ } else if (m_fpregset && fxsave_offset < sizeof(FXSAVE)) {
+ src = m_fpregset.get();
+ offset = fxsave_offset;
+ } else {
return false;
+ }
+
+ Error error;
+ value.SetFromMemoryData(reg_info, src + offset, reg_info->byte_size,
+ lldb::eByteOrderLittle, error);
+
+ return error.Success();
}
-bool
-RegisterContextCorePOSIX_x86_64::ReadAllRegisterValues(lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextCorePOSIX_x86_64::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_x86_64::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value)
-{
- return false;
+bool RegisterContextCorePOSIX_x86_64::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &value) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_x86_64::WriteAllRegisterValues(const lldb::DataBufferSP &data_sp)
-{
- return false;
+bool RegisterContextCorePOSIX_x86_64::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ return false;
}
-bool
-RegisterContextCorePOSIX_x86_64::HardwareSingleStep(bool enable)
-{
- return false;
+bool RegisterContextCorePOSIX_x86_64::HardwareSingleStep(bool enable) {
+ return false;
}
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h
index 60f2ad33b4a5..8340368f8c3c 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h
@@ -1,4 +1,4 @@
-//===-- RegisterContextCorePOSIX_x86_64.h -----------------------*- C++ -*-===//
+//===-- RegisterContextPOSIXCore_x86_64.h -----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,49 +16,38 @@
// Project includes
#include "Plugins/Process/Utility/RegisterContextPOSIX_x86.h"
-class RegisterContextCorePOSIX_x86_64 :
- public RegisterContextPOSIX_x86
-{
+class RegisterContextCorePOSIX_x86_64 : public RegisterContextPOSIX_x86 {
public:
- RegisterContextCorePOSIX_x86_64 (lldb_private::Thread &thread,
- lldb_private::RegisterInfoInterface *register_info,
- const lldb_private::DataExtractor &gpregset,
- const lldb_private::DataExtractor &fpregset);
+ RegisterContextCorePOSIX_x86_64(
+ lldb_private::Thread &thread,
+ lldb_private::RegisterInfoInterface *register_info,
+ const lldb_private::DataExtractor &gpregset,
+ const lldb_private::DataExtractor &fpregset);
- ~RegisterContextCorePOSIX_x86_64() override;
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) override;
- bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value) override;
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) override;
- bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value) override;
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
-
- bool
- HardwareSingleStep(bool enable) override;
+ bool HardwareSingleStep(bool enable) override;
protected:
- bool
- ReadGPR() override;
+ bool ReadGPR() override;
- bool
- ReadFPR() override;
+ bool ReadFPR() override;
- bool
- WriteGPR() override;
+ bool WriteGPR() override;
- bool
- WriteFPR() override;
+ bool WriteFPR() override;
private:
- uint8_t *m_gpregset;
+ std::unique_ptr<uint8_t[]> m_gpregset;
+ std::unique_ptr<uint8_t[]> m_fpregset;
};
#endif // liblldb_RegisterContextCorePOSIX_x86_64_h_
diff --git a/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/source/Plugins/Process/elf-core/ThreadElfCore.cpp
index e4cfa68044f1..86b15c0d2fbe 100644
--- a/source/Plugins/Process/elf-core/ThreadElfCore.cpp
+++ b/source/Plugins/Process/elf-core/ThreadElfCore.cpp
@@ -14,24 +14,24 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/Unwind.h"
-#include "ThreadElfCore.h"
-#include "ProcessElfCore.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_arm.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_arm64.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_s390x.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.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/RegisterContextLinux_arm.h"
+#include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
+#include "Plugins/Process/Utility/RegisterContextLinux_s390x.h"
+#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
+#include "ProcessElfCore.h"
#include "RegisterContextPOSIXCore_arm.h"
#include "RegisterContextPOSIXCore_arm64.h"
#include "RegisterContextPOSIXCore_mips64.h"
#include "RegisterContextPOSIXCore_powerpc.h"
#include "RegisterContextPOSIXCore_s390x.h"
#include "RegisterContextPOSIXCore_x86_64.h"
+#include "ThreadElfCore.h"
using namespace lldb;
using namespace lldb_private;
@@ -39,223 +39,325 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// Construct a Thread object with given data
//----------------------------------------------------------------------
-ThreadElfCore::ThreadElfCore (Process &process, const ThreadData &td) :
- Thread(process, td.tid),
- m_thread_name(td.name),
- m_thread_reg_ctx_sp (),
- m_signo(td.signo),
- m_gpregset_data(td.gpregset),
- m_fpregset_data(td.fpregset),
- m_vregset_data(td.vregset)
-{
-}
+ThreadElfCore::ThreadElfCore(Process &process, const ThreadData &td)
+ : Thread(process, td.tid), m_thread_name(td.name), m_thread_reg_ctx_sp(),
+ m_signo(td.signo), m_gpregset_data(td.gpregset),
+ m_fpregset_data(td.fpregset), m_vregset_data(td.vregset) {}
-ThreadElfCore::~ThreadElfCore ()
-{
- DestroyThread();
+ThreadElfCore::~ThreadElfCore() { DestroyThread(); }
+
+void ThreadElfCore::RefreshStateAfterStop() {
+ GetRegisterContext()->InvalidateIfNeeded(false);
}
-void
-ThreadElfCore::RefreshStateAfterStop()
-{
- GetRegisterContext()->InvalidateIfNeeded (false);
+void ThreadElfCore::ClearStackFrames() {
+ Unwind *unwinder = GetUnwinder();
+ if (unwinder)
+ unwinder->Clear();
+ Thread::ClearStackFrames();
}
-void
-ThreadElfCore::ClearStackFrames ()
-{
- Unwind *unwinder = GetUnwinder ();
- if (unwinder)
- unwinder->Clear();
- Thread::ClearStackFrames();
+RegisterContextSP ThreadElfCore::GetRegisterContext() {
+ if (m_reg_context_sp.get() == NULL) {
+ m_reg_context_sp = CreateRegisterContextForFrame(NULL);
+ }
+ return m_reg_context_sp;
}
RegisterContextSP
-ThreadElfCore::GetRegisterContext ()
-{
- if (m_reg_context_sp.get() == NULL) {
- m_reg_context_sp = CreateRegisterContextForFrame (NULL);
+ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
+ RegisterContextSP reg_ctx_sp;
+ uint32_t concrete_frame_idx = 0;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
+
+ if (frame)
+ concrete_frame_idx = frame->GetConcreteFrameIndex();
+
+ if (concrete_frame_idx == 0) {
+ if (m_thread_reg_ctx_sp)
+ return m_thread_reg_ctx_sp;
+
+ ProcessElfCore *process = static_cast<ProcessElfCore *>(GetProcess().get());
+ ArchSpec arch = process->GetArchitecture();
+ RegisterInfoInterface *reg_interface = NULL;
+
+ switch (arch.GetTriple().getOS()) {
+ case llvm::Triple::FreeBSD: {
+ switch (arch.GetMachine()) {
+ case llvm::Triple::aarch64:
+ reg_interface = new RegisterInfoPOSIX_arm64(arch);
+ break;
+ case llvm::Triple::arm:
+ reg_interface = new RegisterContextFreeBSD_arm(arch);
+ break;
+ case llvm::Triple::ppc:
+ reg_interface = new RegisterContextFreeBSD_powerpc32(arch);
+ break;
+ case llvm::Triple::ppc64:
+ reg_interface = new RegisterContextFreeBSD_powerpc64(arch);
+ break;
+ case llvm::Triple::mips64:
+ reg_interface = new RegisterContextFreeBSD_mips64(arch);
+ break;
+ case llvm::Triple::x86:
+ reg_interface = new RegisterContextFreeBSD_i386(arch);
+ break;
+ case llvm::Triple::x86_64:
+ reg_interface = new RegisterContextFreeBSD_x86_64(arch);
+ break;
+ default:
+ break;
+ }
+ break;
}
- return m_reg_context_sp;
-}
-RegisterContextSP
-ThreadElfCore::CreateRegisterContextForFrame (StackFrame *frame)
-{
- RegisterContextSP reg_ctx_sp;
- uint32_t concrete_frame_idx = 0;
- Log *log (GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
-
- if (frame)
- concrete_frame_idx = frame->GetConcreteFrameIndex ();
-
- if (concrete_frame_idx == 0)
- {
- if (m_thread_reg_ctx_sp)
- return m_thread_reg_ctx_sp;
-
- ProcessElfCore *process = static_cast<ProcessElfCore *>(GetProcess().get());
- ArchSpec arch = process->GetArchitecture();
- RegisterInfoInterface *reg_interface = NULL;
-
- switch (arch.GetTriple().getOS())
- {
- case llvm::Triple::FreeBSD:
- {
- switch (arch.GetMachine())
- {
- case llvm::Triple::aarch64:
- reg_interface = new RegisterContextFreeBSD_arm64(arch);
- break;
- case llvm::Triple::arm:
- reg_interface = new RegisterContextFreeBSD_arm(arch);
- break;
- case llvm::Triple::ppc:
- reg_interface = new RegisterContextFreeBSD_powerpc32(arch);
- break;
- case llvm::Triple::ppc64:
- reg_interface = new RegisterContextFreeBSD_powerpc64(arch);
- break;
- case llvm::Triple::mips64:
- reg_interface = new RegisterContextFreeBSD_mips64(arch);
- break;
- case llvm::Triple::x86:
- reg_interface = new RegisterContextFreeBSD_i386(arch);
- break;
- case llvm::Triple::x86_64:
- reg_interface = new RegisterContextFreeBSD_x86_64(arch);
- break;
- default:
- break;
- }
- break;
- }
-
- case llvm::Triple::Linux:
- {
- switch (arch.GetMachine())
- {
- case llvm::Triple::arm:
- reg_interface = new RegisterContextLinux_arm(arch);
- break;
- case llvm::Triple::aarch64:
- reg_interface = new RegisterContextLinux_arm64(arch);
- break;
- case llvm::Triple::systemz:
- reg_interface = new RegisterContextLinux_s390x(arch);
- break;
- case llvm::Triple::x86_64:
- reg_interface = new RegisterContextLinux_x86_64(arch);
- break;
- default:
- break;
- }
- break;
- }
-
- default:
- break;
- }
-
- if (!reg_interface) {
- if (log)
- log->Printf ("elf-core::%s:: Architecture(%d) or OS(%d) not supported",
- __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS());
- assert (false && "Architecture or OS not supported");
- }
-
- switch (arch.GetMachine())
- {
- case llvm::Triple::aarch64:
- m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm64 (*this, reg_interface, m_gpregset_data, m_fpregset_data));
- break;
- case llvm::Triple::arm:
- m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm (*this, reg_interface, m_gpregset_data, m_fpregset_data));
- break;
- case llvm::Triple::mips64:
- m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64 (*this, reg_interface, m_gpregset_data, m_fpregset_data));
- break;
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_powerpc (*this, reg_interface, m_gpregset_data, m_fpregset_data, m_vregset_data));
- break;
- case llvm::Triple::systemz:
- m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_s390x (*this, reg_interface, m_gpregset_data, m_fpregset_data));
- break;
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64 (*this, reg_interface, m_gpregset_data, m_fpregset_data));
- break;
- default:
- break;
- }
-
- reg_ctx_sp = m_thread_reg_ctx_sp;
+ case llvm::Triple::Linux: {
+ switch (arch.GetMachine()) {
+ case llvm::Triple::arm:
+ reg_interface = new RegisterContextLinux_arm(arch);
+ break;
+ case llvm::Triple::aarch64:
+ reg_interface = new RegisterInfoPOSIX_arm64(arch);
+ break;
+ case llvm::Triple::systemz:
+ reg_interface = new RegisterContextLinux_s390x(arch);
+ break;
+ case llvm::Triple::x86:
+ reg_interface = new RegisterContextLinux_i386(arch);
+ break;
+ case llvm::Triple::x86_64:
+ reg_interface = new RegisterContextLinux_x86_64(arch);
+ break;
+ default:
+ break;
+ }
+ break;
}
- else if (m_unwinder_ap.get())
- {
- reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame);
+
+ default:
+ break;
}
- return reg_ctx_sp;
-}
-bool
-ThreadElfCore::CalculateStopInfo ()
-{
- ProcessSP process_sp (GetProcess());
- if (process_sp)
- {
- SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, m_signo));
- return true;
+ if (!reg_interface) {
+ if (log)
+ log->Printf("elf-core::%s:: Architecture(%d) or OS(%d) not supported",
+ __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS());
+ assert(false && "Architecture or OS not supported");
}
- return false;
+
+ switch (arch.GetMachine()) {
+ case llvm::Triple::aarch64:
+ m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm64(
+ *this, reg_interface, m_gpregset_data, m_fpregset_data));
+ break;
+ case llvm::Triple::arm:
+ m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm(
+ *this, reg_interface, m_gpregset_data, m_fpregset_data));
+ break;
+ case llvm::Triple::mips64:
+ m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64(
+ *this, reg_interface, m_gpregset_data, m_fpregset_data));
+ break;
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
+ m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_powerpc(
+ *this, reg_interface, m_gpregset_data, m_fpregset_data,
+ m_vregset_data));
+ break;
+ case llvm::Triple::systemz:
+ m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_s390x(
+ *this, reg_interface, m_gpregset_data, m_fpregset_data));
+ break;
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64(
+ *this, reg_interface, m_gpregset_data, m_fpregset_data));
+ break;
+ default:
+ break;
+ }
+
+ reg_ctx_sp = m_thread_reg_ctx_sp;
+ } else if (m_unwinder_ap.get()) {
+ reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame(frame);
+ }
+ return reg_ctx_sp;
+}
+
+bool ThreadElfCore::CalculateStopInfo() {
+ ProcessSP process_sp(GetProcess());
+ if (process_sp) {
+ SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, m_signo));
+ return true;
+ }
+ return false;
}
//----------------------------------------------------------------
// Parse PRSTATUS from NOTE entry
//----------------------------------------------------------------
-ELFLinuxPrStatus::ELFLinuxPrStatus()
-{
- memset(this, 0, sizeof(ELFLinuxPrStatus));
+ELFLinuxPrStatus::ELFLinuxPrStatus() {
+ memset(this, 0, sizeof(ELFLinuxPrStatus));
}
-bool
-ELFLinuxPrStatus::Parse(DataExtractor &data, ArchSpec &arch)
-{
- ByteOrder byteorder = data.GetByteOrder();
- size_t len;
- switch(arch.GetCore())
- {
- case ArchSpec::eCore_s390x_generic:
- case ArchSpec::eCore_x86_64_x86_64:
- len = data.ExtractBytes(0, ELFLINUXPRSTATUS64_SIZE, byteorder, this);
- return len == ELFLINUXPRSTATUS64_SIZE;
- default:
- return false;
- }
+Error ELFLinuxPrStatus::Parse(DataExtractor &data, ArchSpec &arch) {
+ Error error;
+ ByteOrder byteorder = data.GetByteOrder();
+ if (GetSize(arch) > data.GetByteSize()) {
+ error.SetErrorStringWithFormat(
+ "NT_PRSTATUS size should be %zu, but the remaining bytes are: %" PRIu64,
+ GetSize(arch), data.GetByteSize());
+ return error;
+ }
+
+ switch (arch.GetCore()) {
+ case ArchSpec::eCore_s390x_generic:
+ case ArchSpec::eCore_x86_64_x86_64:
+ data.ExtractBytes(0, sizeof(ELFLinuxPrStatus), byteorder, this);
+ break;
+ case ArchSpec::eCore_x86_32_i386:
+ case ArchSpec::eCore_x86_32_i486: {
+ // Parsing from a 32 bit ELF core file, and populating/reusing the structure
+ // properly, because the struct is for the 64 bit version
+ offset_t offset = 0;
+ si_signo = data.GetU32(&offset);
+ si_code = data.GetU32(&offset);
+ si_errno = data.GetU32(&offset);
+
+ pr_cursig = data.GetU16(&offset);
+ offset += 2; // pad
+
+ pr_sigpend = data.GetU32(&offset);
+ pr_sighold = data.GetU32(&offset);
+
+ pr_pid = data.GetU32(&offset);
+ pr_ppid = data.GetU32(&offset);
+ pr_pgrp = data.GetU32(&offset);
+ pr_sid = data.GetU32(&offset);
+
+ pr_utime.tv_sec = data.GetU32(&offset);
+ pr_utime.tv_usec = data.GetU32(&offset);
+
+ pr_stime.tv_sec = data.GetU32(&offset);
+ pr_stime.tv_usec = data.GetU32(&offset);
+
+ pr_cutime.tv_sec = data.GetU32(&offset);
+ pr_cutime.tv_usec = data.GetU32(&offset);
+
+ pr_cstime.tv_sec = data.GetU32(&offset);
+ pr_cstime.tv_usec = data.GetU32(&offset);
+
+ break;
+ }
+ default:
+ error.SetErrorStringWithFormat("ELFLinuxPrStatus::%s Unknown architecture",
+ __FUNCTION__);
+ break;
+ }
+
+ return error;
}
//----------------------------------------------------------------
// Parse PRPSINFO from NOTE entry
//----------------------------------------------------------------
-ELFLinuxPrPsInfo::ELFLinuxPrPsInfo()
-{
- memset(this, 0, sizeof(ELFLinuxPrPsInfo));
+ELFLinuxPrPsInfo::ELFLinuxPrPsInfo() {
+ memset(this, 0, sizeof(ELFLinuxPrPsInfo));
}
-bool
-ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch)
-{
- ByteOrder byteorder = data.GetByteOrder();
- size_t len;
- switch(arch.GetCore())
- {
- case ArchSpec::eCore_s390x_generic:
- case ArchSpec::eCore_x86_64_x86_64:
- len = data.ExtractBytes(0, ELFLINUXPRPSINFO64_SIZE, byteorder, this);
- return len == ELFLINUXPRPSINFO64_SIZE;
- default:
- return false;
- }
+Error ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch) {
+ Error error;
+ ByteOrder byteorder = data.GetByteOrder();
+ if (GetSize(arch) > data.GetByteSize()) {
+ error.SetErrorStringWithFormat(
+ "NT_PRPSINFO size should be %zu, but the remaining bytes are: %" PRIu64,
+ GetSize(arch), data.GetByteSize());
+ return error;
+ }
+
+ switch (arch.GetCore()) {
+ case ArchSpec::eCore_s390x_generic:
+ case ArchSpec::eCore_x86_64_x86_64:
+ data.ExtractBytes(0, sizeof(ELFLinuxPrPsInfo), byteorder, this);
+ break;
+ case ArchSpec::eCore_x86_32_i386:
+ case ArchSpec::eCore_x86_32_i486: {
+ // Parsing from a 32 bit ELF core file, and populating/reusing the structure
+ // properly, because the struct is for the 64 bit version
+ size_t size = 0;
+ offset_t offset = 0;
+
+ pr_state = data.GetU8(&offset);
+ pr_sname = data.GetU8(&offset);
+ pr_zomb = data.GetU8(&offset);
+ pr_nice = data.GetU8(&offset);
+
+ pr_flag = data.GetU32(&offset);
+ pr_uid = data.GetU16(&offset);
+ pr_gid = data.GetU16(&offset);
+
+ pr_pid = data.GetU32(&offset);
+ pr_ppid = data.GetU32(&offset);
+ pr_pgrp = data.GetU32(&offset);
+ pr_sid = data.GetU32(&offset);
+
+ size = 16;
+ data.ExtractBytes(offset, size, byteorder, pr_fname);
+ offset += size;
+
+ size = 80;
+ data.ExtractBytes(offset, size, byteorder, pr_psargs);
+ offset += size;
+
+ break;
+ }
+ default:
+ error.SetErrorStringWithFormat("ELFLinuxPrPsInfo::%s Unknown architecture",
+ __FUNCTION__);
+ break;
+ }
+
+ return error;
}
+//----------------------------------------------------------------
+// Parse SIGINFO from NOTE entry
+//----------------------------------------------------------------
+ELFLinuxSigInfo::ELFLinuxSigInfo() {
+ memset(this, 0, sizeof(ELFLinuxSigInfo));
+}
+
+Error ELFLinuxSigInfo::Parse(DataExtractor &data, const ArchSpec &arch) {
+ Error error;
+ ByteOrder byteorder = data.GetByteOrder();
+ if (GetSize(arch) > data.GetByteSize()) {
+ error.SetErrorStringWithFormat(
+ "NT_SIGINFO size should be %zu, but the remaining bytes are: %" PRIu64,
+ GetSize(arch), data.GetByteSize());
+ return error;
+ }
+
+ switch (arch.GetCore()) {
+ case ArchSpec::eCore_x86_64_x86_64:
+ data.ExtractBytes(0, sizeof(ELFLinuxPrStatus), byteorder, this);
+ break;
+ case ArchSpec::eCore_s390x_generic:
+ case ArchSpec::eCore_x86_32_i386:
+ case ArchSpec::eCore_x86_32_i486: {
+ // Parsing from a 32 bit ELF core file, and populating/reusing the structure
+ // properly, because the struct is for the 64 bit version
+ offset_t offset = 0;
+ si_signo = data.GetU32(&offset);
+ si_code = data.GetU32(&offset);
+ si_errno = data.GetU32(&offset);
+
+ break;
+ }
+ default:
+ error.SetErrorStringWithFormat("ELFLinuxSigInfo::%s Unknown architecture",
+ __FUNCTION__);
+ break;
+ }
+
+ return error;
+}
diff --git a/source/Plugins/Process/elf-core/ThreadElfCore.h b/source/Plugins/Process/elf-core/ThreadElfCore.h
index b4e990140675..1957ac243ceb 100644
--- a/source/Plugins/Process/elf-core/ThreadElfCore.h
+++ b/source/Plugins/Process/elf-core/ThreadElfCore.h
@@ -16,168 +16,204 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/Target/Thread.h"
#include "lldb/Core/DataExtractor.h"
+#include "lldb/Target/Thread.h"
-struct compat_timeval
-{
- int64_t tv_sec;
- int32_t tv_usec;
+struct compat_timeval {
+ alignas(8) uint64_t tv_sec;
+ alignas(8) uint64_t tv_usec;
};
// PRSTATUS structure's size differs based on architecture.
-// Currently parsing done only for x86-64 architecture by
-// simply reading data from the buffer.
-// The following macros are used to specify the size.
-// Calculating size using sizeof() wont work because of padding.
-#define ELFLINUXPRSTATUS64_SIZE (112)
-#define ELFLINUXPRPSINFO64_SIZE (132)
+// This is the layout in the x86-64 arch.
+// In the i386 case we parse it manually and fill it again
+// in the same structure
+// The gp registers are also a part of this struct, but they are handled
+// separately
#undef si_signo
#undef si_code
#undef si_errno
-struct ELFLinuxPrStatus
-{
- int32_t si_signo;
- int32_t si_code;
- int32_t si_errno;
-
- int16_t pr_cursig;
-
- uint64_t pr_sigpend;
- uint64_t pr_sighold;
-
- uint32_t pr_pid;
- uint32_t pr_ppid;
- uint32_t pr_pgrp;
- uint32_t pr_sid;
-
- compat_timeval pr_utime;
- compat_timeval pr_stime;
- compat_timeval pr_cutime;
- compat_timeval pr_cstime;
-
- ELFLinuxPrStatus();
-
- bool
- Parse(lldb_private::DataExtractor &data, lldb_private::ArchSpec &arch);
-
- static size_t
- GetSize(lldb_private::ArchSpec &arch)
- {
- switch(arch.GetCore())
- {
- case lldb_private::ArchSpec::eCore_s390x_generic:
- case lldb_private::ArchSpec::eCore_x86_64_x86_64:
- return ELFLINUXPRSTATUS64_SIZE;
- default:
- return 0;
- }
+struct ELFLinuxPrStatus {
+ int32_t si_signo;
+ int32_t si_code;
+ int32_t si_errno;
+
+ int16_t pr_cursig;
+
+ alignas(8) uint64_t pr_sigpend;
+ alignas(8) uint64_t pr_sighold;
+
+ uint32_t pr_pid;
+ uint32_t pr_ppid;
+ uint32_t pr_pgrp;
+ uint32_t pr_sid;
+
+ compat_timeval pr_utime;
+ compat_timeval pr_stime;
+ compat_timeval pr_cutime;
+ compat_timeval pr_cstime;
+
+ ELFLinuxPrStatus();
+
+ lldb_private::Error Parse(lldb_private::DataExtractor &data,
+ lldb_private::ArchSpec &arch);
+
+ // Return the bytesize of the structure
+ // 64 bit - just sizeof
+ // 32 bit - hardcoded because we are reusing the struct, but some of the
+ // members are smaller -
+ // so the layout is not the same
+ static size_t GetSize(lldb_private::ArchSpec &arch) {
+ switch (arch.GetCore()) {
+ case lldb_private::ArchSpec::eCore_s390x_generic:
+ case lldb_private::ArchSpec::eCore_x86_64_x86_64:
+ return sizeof(ELFLinuxPrStatus);
+ case lldb_private::ArchSpec::eCore_x86_32_i386:
+ case lldb_private::ArchSpec::eCore_x86_32_i486:
+ return 72;
+ default:
+ return 0;
+ }
+ }
+};
+
+static_assert(sizeof(ELFLinuxPrStatus) == 112,
+ "sizeof ELFLinuxPrStatus is not correct!");
+
+struct ELFLinuxSigInfo {
+ int32_t si_signo;
+ int32_t si_code;
+ int32_t si_errno;
+
+ ELFLinuxSigInfo();
+
+ lldb_private::Error Parse(lldb_private::DataExtractor &data,
+ const lldb_private::ArchSpec &arch);
+
+ // Return the bytesize of the structure
+ // 64 bit - just sizeof
+ // 32 bit - hardcoded because we are reusing the struct, but some of the
+ // members are smaller -
+ // so the layout is not the same
+ static size_t GetSize(const lldb_private::ArchSpec &arch) {
+ switch (arch.GetCore()) {
+ case lldb_private::ArchSpec::eCore_x86_64_x86_64:
+ return sizeof(ELFLinuxSigInfo);
+ case lldb_private::ArchSpec::eCore_s390x_generic:
+ case lldb_private::ArchSpec::eCore_x86_32_i386:
+ case lldb_private::ArchSpec::eCore_x86_32_i486:
+ return 12;
+ default:
+ return 0;
}
+ }
};
-struct ELFLinuxPrPsInfo
-{
- char pr_state;
- char pr_sname;
- char pr_zomb;
- char pr_nice;
- uint64_t pr_flag;
- uint32_t pr_uid;
- uint32_t pr_gid;
- int32_t pr_pid;
- int32_t pr_ppid;
- int32_t pr_pgrp;
- int32_t pr_sid;
- char pr_fname[16];
- char pr_psargs[80];
-
- ELFLinuxPrPsInfo();
-
- bool
- Parse(lldb_private::DataExtractor &data, lldb_private::ArchSpec &arch);
-
- static size_t
- GetSize(lldb_private::ArchSpec &arch)
- {
- switch(arch.GetCore())
- {
- case lldb_private::ArchSpec::eCore_s390x_generic:
- case lldb_private::ArchSpec::eCore_x86_64_x86_64:
- return ELFLINUXPRPSINFO64_SIZE;
- default:
- return 0;
- }
+static_assert(sizeof(ELFLinuxSigInfo) == 12,
+ "sizeof ELFLinuxSigInfo is not correct!");
+
+// PRPSINFO structure's size differs based on architecture.
+// This is the layout in the x86-64 arch case.
+// In the i386 case we parse it manually and fill it again
+// in the same structure
+struct ELFLinuxPrPsInfo {
+ char pr_state;
+ char pr_sname;
+ char pr_zomb;
+ char pr_nice;
+ alignas(8) uint64_t pr_flag;
+ uint32_t pr_uid;
+ uint32_t pr_gid;
+ int32_t pr_pid;
+ int32_t pr_ppid;
+ int32_t pr_pgrp;
+ int32_t pr_sid;
+ char pr_fname[16];
+ char pr_psargs[80];
+
+ ELFLinuxPrPsInfo();
+
+ lldb_private::Error Parse(lldb_private::DataExtractor &data,
+ lldb_private::ArchSpec &arch);
+
+ // Return the bytesize of the structure
+ // 64 bit - just sizeof
+ // 32 bit - hardcoded because we are reusing the struct, but some of the
+ // members are smaller -
+ // so the layout is not the same
+ static size_t GetSize(lldb_private::ArchSpec &arch) {
+ switch (arch.GetCore()) {
+ case lldb_private::ArchSpec::eCore_s390x_generic:
+ case lldb_private::ArchSpec::eCore_x86_64_x86_64:
+ return sizeof(ELFLinuxPrPsInfo);
+ case lldb_private::ArchSpec::eCore_x86_32_i386:
+ case lldb_private::ArchSpec::eCore_x86_32_i486:
+ return 124;
+ default:
+ return 0;
}
+ }
};
-struct ThreadData
-{
- lldb_private::DataExtractor gpregset;
- lldb_private::DataExtractor fpregset;
- lldb_private::DataExtractor vregset;
- lldb::tid_t tid;
- int signo;
- std::string name;
+static_assert(sizeof(ELFLinuxPrPsInfo) == 136,
+ "sizeof ELFLinuxPrPsInfo is not correct!");
+
+struct ThreadData {
+ lldb_private::DataExtractor gpregset;
+ lldb_private::DataExtractor fpregset;
+ lldb_private::DataExtractor vregset;
+ lldb::tid_t tid;
+ int signo = 0;
+ int prstatus_sig = 0;
+ std::string name;
};
-class ThreadElfCore : public lldb_private::Thread
-{
+class ThreadElfCore : public lldb_private::Thread {
public:
- ThreadElfCore (lldb_private::Process &process, const ThreadData &td);
+ ThreadElfCore(lldb_private::Process &process, const ThreadData &td);
- ~ThreadElfCore() override;
+ ~ThreadElfCore() override;
- void
- RefreshStateAfterStop() override;
+ void RefreshStateAfterStop() 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;
- void
- ClearStackFrames() override;
+ void ClearStackFrames() override;
- static bool
- ThreadIDIsValid (lldb::tid_t thread)
- {
- return thread != 0;
- }
+ static bool ThreadIDIsValid(lldb::tid_t thread) { return thread != 0; }
- const char *
- GetName() override
- {
- if (m_thread_name.empty())
- return NULL;
- return m_thread_name.c_str();
- }
+ const char *GetName() override {
+ if (m_thread_name.empty())
+ return NULL;
+ return m_thread_name.c_str();
+ }
- void
- SetName(const char *name) override
- {
- if (name && name[0])
- m_thread_name.assign (name);
- else
- m_thread_name.clear();
- }
+ void SetName(const char *name) override {
+ if (name && name[0])
+ m_thread_name.assign(name);
+ else
+ m_thread_name.clear();
+ }
protected:
- //------------------------------------------------------------------
- // Member variables.
- //------------------------------------------------------------------
- std::string m_thread_name;
- lldb::RegisterContextSP m_thread_reg_ctx_sp;
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ std::string m_thread_name;
+ lldb::RegisterContextSP m_thread_reg_ctx_sp;
- int m_signo;
+ int m_signo;
- lldb_private::DataExtractor m_gpregset_data;
- lldb_private::DataExtractor m_fpregset_data;
- lldb_private::DataExtractor m_vregset_data;
+ lldb_private::DataExtractor m_gpregset_data;
+ lldb_private::DataExtractor m_fpregset_data;
+ lldb_private::DataExtractor m_vregset_data;
- bool CalculateStopInfo() override;
+ bool CalculateStopInfo() override;
};
#endif // liblldb_ThreadElfCore_h_
diff --git a/source/Plugins/Process/gdb-remote/CMakeLists.txt b/source/Plugins/Process/gdb-remote/CMakeLists.txt
index 8dbfa453f2c2..b28522725868 100644
--- a/source/Plugins/Process/gdb-remote/CMakeLists.txt
+++ b/source/Plugins/Process/gdb-remote/CMakeLists.txt
@@ -3,6 +3,7 @@ if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
endif()
add_lldb_library(lldbPluginProcessGDBRemote
+ GDBRemoteClientBase.cpp
GDBRemoteCommunication.cpp
GDBRemoteCommunicationClient.cpp
GDBRemoteCommunicationServer.cpp
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
new file mode 100644
index 000000000000..1e20a090161d
--- /dev/null
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
@@ -0,0 +1,376 @@
+//===-- GDBRemoteClientBase.cpp ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GDBRemoteClientBase.h"
+
+#include "llvm/ADT/StringExtras.h"
+
+#include "lldb/Target/Process.h"
+#include "lldb/Target/UnixSignals.h"
+#include "lldb/Utility/LLDBAssert.h"
+
+#include "ProcessGDBRemoteLog.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_gdb_remote;
+using namespace std::chrono;
+
+static const seconds kInterruptTimeout(5);
+
+/////////////////////////
+// GDBRemoteClientBase //
+/////////////////////////
+
+GDBRemoteClientBase::ContinueDelegate::~ContinueDelegate() = default;
+
+GDBRemoteClientBase::GDBRemoteClientBase(const char *comm_name,
+ const char *listener_name)
+ : GDBRemoteCommunication(comm_name, listener_name), m_async_count(0),
+ m_is_running(false), m_should_stop(false) {}
+
+StateType GDBRemoteClientBase::SendContinuePacketAndWaitForResponse(
+ ContinueDelegate &delegate, const UnixSignals &signals,
+ llvm::StringRef payload, StringExtractorGDBRemote &response) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ response.Clear();
+
+ {
+ std::lock_guard<std::mutex> lock(m_mutex);
+ m_continue_packet = payload;
+ m_should_stop = false;
+ }
+ ContinueLock cont_lock(*this);
+ if (!cont_lock)
+ return eStateInvalid;
+ OnRunPacketSent(true);
+
+ for (;;) {
+ PacketResult read_result = ReadPacket(response, kInterruptTimeout, false);
+ switch (read_result) {
+ case PacketResult::ErrorReplyTimeout: {
+ std::lock_guard<std::mutex> lock(m_mutex);
+ if (m_async_count == 0)
+ continue;
+ if (steady_clock::now() >= m_interrupt_time + kInterruptTimeout)
+ return eStateInvalid;
+ }
+ case PacketResult::Success:
+ break;
+ default:
+ if (log)
+ log->Printf("GDBRemoteClientBase::%s () ReadPacket(...) => false",
+ __FUNCTION__);
+ return eStateInvalid;
+ }
+ if (response.Empty())
+ return eStateInvalid;
+
+ const char stop_type = response.GetChar();
+ if (log)
+ log->Printf("GDBRemoteClientBase::%s () got packet: %s", __FUNCTION__,
+ response.GetStringRef().c_str());
+
+ switch (stop_type) {
+ case 'W':
+ case 'X':
+ return eStateExited;
+ case 'E':
+ // ERROR
+ return eStateInvalid;
+ default:
+ if (log)
+ log->Printf("GDBRemoteClientBase::%s () unrecognized async packet",
+ __FUNCTION__);
+ return eStateInvalid;
+ case 'O': {
+ std::string inferior_stdout;
+ response.GetHexByteString(inferior_stdout);
+ delegate.HandleAsyncStdout(inferior_stdout);
+ break;
+ }
+ case 'A':
+ delegate.HandleAsyncMisc(
+ llvm::StringRef(response.GetStringRef()).substr(1));
+ break;
+ case 'J':
+ delegate.HandleAsyncStructuredDataPacket(response.GetStringRef());
+ break;
+ case 'T':
+ case 'S':
+ // Do this with the continue lock held.
+ const bool should_stop = ShouldStop(signals, response);
+ response.SetFilePos(0);
+
+ // The packet we should resume with. In the future
+ // we should check our thread list and "do the right thing"
+ // for new threads that show up while we stop and run async
+ // packets. Setting the packet to 'c' to continue all threads
+ // is the right thing to do 99.99% of the time because if a
+ // thread was single stepping, and we sent an interrupt, we
+ // will notice above that we didn't stop due to an interrupt
+ // but stopped due to stepping and we would _not_ continue.
+ // This packet may get modified by the async actions (e.g. to send a
+ // signal).
+ m_continue_packet = 'c';
+ cont_lock.unlock();
+
+ delegate.HandleStopReply();
+ if (should_stop)
+ return eStateStopped;
+
+ switch (cont_lock.lock()) {
+ case ContinueLock::LockResult::Success:
+ break;
+ case ContinueLock::LockResult::Failed:
+ return eStateInvalid;
+ case ContinueLock::LockResult::Cancelled:
+ return eStateStopped;
+ }
+ OnRunPacketSent(false);
+ break;
+ }
+ }
+}
+
+bool GDBRemoteClientBase::SendAsyncSignal(int signo) {
+ Lock lock(*this, true);
+ if (!lock || !lock.DidInterrupt())
+ return false;
+
+ m_continue_packet = 'C';
+ m_continue_packet += llvm::hexdigit((signo / 16) % 16);
+ m_continue_packet += llvm::hexdigit(signo % 16);
+ return true;
+}
+
+bool GDBRemoteClientBase::Interrupt() {
+ Lock lock(*this, true);
+ if (!lock.DidInterrupt())
+ return false;
+ m_should_stop = true;
+ return true;
+}
+GDBRemoteCommunication::PacketResult
+GDBRemoteClientBase::SendPacketAndWaitForResponse(
+ llvm::StringRef payload, StringExtractorGDBRemote &response,
+ bool send_async) {
+ Lock lock(*this, send_async);
+ if (!lock) {
+ if (Log *log =
+ ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS))
+ log->Printf("GDBRemoteClientBase::%s failed to get mutex, not sending "
+ "packet '%.*s' (send_async=%d)",
+ __FUNCTION__, int(payload.size()), payload.data(),
+ send_async);
+ return PacketResult::ErrorSendFailed;
+ }
+
+ return SendPacketAndWaitForResponseNoLock(payload, response);
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteClientBase::SendPacketAndWaitForResponseNoLock(
+ llvm::StringRef payload, StringExtractorGDBRemote &response) {
+ PacketResult packet_result = SendPacketNoLock(payload);
+ if (packet_result != PacketResult::Success)
+ return packet_result;
+
+ const size_t max_response_retries = 3;
+ for (size_t i = 0; i < max_response_retries; ++i) {
+ packet_result = ReadPacket(response, GetPacketTimeout(), true);
+ // Make sure we received a response
+ if (packet_result != PacketResult::Success)
+ return packet_result;
+ // Make sure our response is valid for the payload that was sent
+ if (response.ValidateResponse())
+ return packet_result;
+ // Response says it wasn't valid
+ Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS);
+ if (log)
+ log->Printf(
+ "error: packet with payload \"%.*s\" got invalid response \"%s\": %s",
+ int(payload.size()), payload.data(), response.GetStringRef().c_str(),
+ (i == (max_response_retries - 1))
+ ? "using invalid response and giving up"
+ : "ignoring response and waiting for another");
+ }
+ return packet_result;
+}
+
+bool GDBRemoteClientBase::SendvContPacket(llvm::StringRef payload,
+ StringExtractorGDBRemote &response) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ if (log)
+ log->Printf("GDBRemoteCommunicationClient::%s ()", __FUNCTION__);
+
+ // we want to lock down packet sending while we continue
+ Lock lock(*this, true);
+
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationClient::%s () sending vCont packet: %.*s",
+ __FUNCTION__, int(payload.size()), payload.data());
+
+ if (SendPacketNoLock(payload) != PacketResult::Success)
+ return false;
+
+ OnRunPacketSent(true);
+
+ // wait for the response to the vCont
+ if (ReadPacket(response, llvm::None, false) == PacketResult::Success) {
+ if (response.IsOKResponse())
+ return true;
+ }
+
+ return false;
+}
+bool GDBRemoteClientBase::ShouldStop(const UnixSignals &signals,
+ StringExtractorGDBRemote &response) {
+ std::lock_guard<std::mutex> lock(m_mutex);
+
+ if (m_async_count == 0)
+ return true; // We were not interrupted. The process stopped on its own.
+
+ // Older debugserver stubs (before April 2016) can return two
+ // stop-reply packets in response to a ^C packet.
+ // Additionally, all debugservers still return two stop replies if
+ // the inferior stops due to some other reason before the remote
+ // stub manages to interrupt it. We need to wait for this
+ // additional packet to make sure the packet sequence does not get
+ // skewed.
+ StringExtractorGDBRemote extra_stop_reply_packet;
+ ReadPacket(extra_stop_reply_packet, milliseconds(100), false);
+
+ // Interrupting is typically done using SIGSTOP or SIGINT, so if
+ // the process stops with some other signal, we definitely want to
+ // stop.
+ const uint8_t signo = response.GetHexU8(UINT8_MAX);
+ if (signo != signals.GetSignalNumberFromName("SIGSTOP") &&
+ signo != signals.GetSignalNumberFromName("SIGINT"))
+ return true;
+
+ // We probably only stopped to perform some async processing, so continue
+ // after that is done.
+ // TODO: This is not 100% correct, as the process may have been stopped with
+ // SIGINT or SIGSTOP that was not caused by us (e.g. raise(SIGINT)). This will
+ // normally cause a stop, but if it's done concurrently with a async
+ // interrupt, that stop will get eaten (llvm.org/pr20231).
+ return false;
+}
+
+void GDBRemoteClientBase::OnRunPacketSent(bool first) {
+ if (first)
+ BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
+}
+
+///////////////////////////////////////
+// GDBRemoteClientBase::ContinueLock //
+///////////////////////////////////////
+
+GDBRemoteClientBase::ContinueLock::ContinueLock(GDBRemoteClientBase &comm)
+ : m_comm(comm), m_acquired(false) {
+ lock();
+}
+
+GDBRemoteClientBase::ContinueLock::~ContinueLock() {
+ if (m_acquired)
+ unlock();
+}
+
+void GDBRemoteClientBase::ContinueLock::unlock() {
+ lldbassert(m_acquired);
+ {
+ std::unique_lock<std::mutex> lock(m_comm.m_mutex);
+ m_comm.m_is_running = false;
+ }
+ m_comm.m_cv.notify_all();
+ m_acquired = false;
+}
+
+GDBRemoteClientBase::ContinueLock::LockResult
+GDBRemoteClientBase::ContinueLock::lock() {
+ Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS);
+ if (log)
+ log->Printf("GDBRemoteClientBase::ContinueLock::%s() resuming with %s",
+ __FUNCTION__, m_comm.m_continue_packet.c_str());
+
+ lldbassert(!m_acquired);
+ std::unique_lock<std::mutex> lock(m_comm.m_mutex);
+ m_comm.m_cv.wait(lock, [this] { return m_comm.m_async_count == 0; });
+ if (m_comm.m_should_stop) {
+ m_comm.m_should_stop = false;
+ if (log)
+ log->Printf("GDBRemoteClientBase::ContinueLock::%s() cancelled",
+ __FUNCTION__);
+ return LockResult::Cancelled;
+ }
+ if (m_comm.SendPacketNoLock(m_comm.m_continue_packet) !=
+ PacketResult::Success)
+ return LockResult::Failed;
+
+ lldbassert(!m_comm.m_is_running);
+ m_comm.m_is_running = true;
+ m_acquired = true;
+ return LockResult::Success;
+}
+
+///////////////////////////////
+// GDBRemoteClientBase::Lock //
+///////////////////////////////
+
+GDBRemoteClientBase::Lock::Lock(GDBRemoteClientBase &comm, bool interrupt)
+ : m_async_lock(comm.m_async_mutex, std::defer_lock), m_comm(comm),
+ m_acquired(false), m_did_interrupt(false) {
+ SyncWithContinueThread(interrupt);
+ if (m_acquired)
+ m_async_lock.lock();
+}
+
+void GDBRemoteClientBase::Lock::SyncWithContinueThread(bool interrupt) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ std::unique_lock<std::mutex> lock(m_comm.m_mutex);
+ if (m_comm.m_is_running && !interrupt)
+ return; // We were asked to avoid interrupting the sender. Lock is not
+ // acquired.
+
+ ++m_comm.m_async_count;
+ if (m_comm.m_is_running) {
+ if (m_comm.m_async_count == 1) {
+ // The sender has sent the continue packet and we are the first async
+ // packet. Let's interrupt it.
+ const char ctrl_c = '\x03';
+ ConnectionStatus status = eConnectionStatusSuccess;
+ size_t bytes_written = m_comm.Write(&ctrl_c, 1, status, NULL);
+ if (bytes_written == 0) {
+ --m_comm.m_async_count;
+ if (log)
+ log->Printf("GDBRemoteClientBase::Lock::Lock failed to send "
+ "interrupt packet");
+ return;
+ }
+ if (log)
+ log->PutCString("GDBRemoteClientBase::Lock::Lock sent packet: \\x03");
+ m_comm.m_interrupt_time = steady_clock::now();
+ }
+ m_comm.m_cv.wait(lock, [this] { return m_comm.m_is_running == false; });
+ m_did_interrupt = true;
+ }
+ m_acquired = true;
+}
+
+GDBRemoteClientBase::Lock::~Lock() {
+ if (!m_acquired)
+ return;
+ {
+ std::unique_lock<std::mutex> lock(m_comm.m_mutex);
+ --m_comm.m_async_count;
+ }
+ m_comm.m_cv.notify_one();
+}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h
new file mode 100644
index 000000000000..2646405c9b91
--- /dev/null
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h
@@ -0,0 +1,144 @@
+//===-- GDBRemoteClientBase.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_GDBRemoteClientBase_h_
+#define liblldb_GDBRemoteClientBase_h_
+
+#include "GDBRemoteCommunication.h"
+
+#include <condition_variable>
+
+namespace lldb_private {
+namespace process_gdb_remote {
+
+class GDBRemoteClientBase : public GDBRemoteCommunication {
+public:
+ struct ContinueDelegate {
+ virtual ~ContinueDelegate();
+ virtual void HandleAsyncStdout(llvm::StringRef out) = 0;
+ virtual void HandleAsyncMisc(llvm::StringRef data) = 0;
+ virtual void HandleStopReply() = 0;
+
+ // =========================================================================
+ /// Process asynchronously-received structured data.
+ ///
+ /// @param[in] data
+ /// The complete data packet, expected to start with JSON-async.
+ // =========================================================================
+ virtual void HandleAsyncStructuredDataPacket(llvm::StringRef data) = 0;
+ };
+
+ GDBRemoteClientBase(const char *comm_name, const char *listener_name);
+
+ bool SendAsyncSignal(int signo);
+
+ bool Interrupt();
+
+ lldb::StateType SendContinuePacketAndWaitForResponse(
+ ContinueDelegate &delegate, const UnixSignals &signals,
+ llvm::StringRef payload, StringExtractorGDBRemote &response);
+
+ PacketResult SendPacketAndWaitForResponse(llvm::StringRef payload,
+ StringExtractorGDBRemote &response,
+ bool send_async);
+
+ bool SendvContPacket(llvm::StringRef payload,
+ StringExtractorGDBRemote &response);
+
+ class Lock {
+ public:
+ Lock(GDBRemoteClientBase &comm, bool interrupt);
+ ~Lock();
+
+ explicit operator bool() { return m_acquired; }
+
+ // Whether we had to interrupt the continue thread to acquire the
+ // connection.
+ bool DidInterrupt() const { return m_did_interrupt; }
+
+ private:
+ std::unique_lock<std::recursive_mutex> m_async_lock;
+ GDBRemoteClientBase &m_comm;
+ bool m_acquired;
+ bool m_did_interrupt;
+
+ void SyncWithContinueThread(bool interrupt);
+ };
+
+protected:
+ PacketResult
+ SendPacketAndWaitForResponseNoLock(llvm::StringRef payload,
+ StringExtractorGDBRemote &response);
+
+ virtual void OnRunPacketSent(bool first);
+
+private:
+ // Variables handling synchronization between the Continue thread and any
+ // other threads
+ // wishing to send packets over the connection. Either the continue thread has
+ // control over
+ // the connection (m_is_running == true) or the connection is free for an
+ // arbitrary number of
+ // other senders to take which indicate their interest by incrementing
+ // m_async_count.
+ // Semantics of individual states:
+ // - m_continue_packet == false, m_async_count == 0: connection is free
+ // - m_continue_packet == true, m_async_count == 0: only continue thread is
+ // present
+ // - m_continue_packet == true, m_async_count > 0: continue thread has
+ // control, async threads
+ // should interrupt it and wait for it to set m_continue_packet to false
+ // - m_continue_packet == false, m_async_count > 0: async threads have
+ // control, continue
+ // thread needs to wait for them to finish (m_async_count goes down to 0).
+ std::mutex m_mutex;
+ std::condition_variable m_cv;
+ // Packet with which to resume after an async interrupt. Can be changed by an
+ // async thread
+ // e.g. to inject a signal.
+ std::string m_continue_packet;
+ // When was the interrupt packet sent. Used to make sure we time out if the
+ // stub does not
+ // respond to interrupt requests.
+ std::chrono::time_point<std::chrono::steady_clock> m_interrupt_time;
+ uint32_t m_async_count;
+ bool m_is_running;
+ bool m_should_stop; // Whether we should resume after a stop.
+ // end of continue thread synchronization block
+
+ // This handles the synchronization between individual async threads. For now
+ // they just use a
+ // simple mutex.
+ std::recursive_mutex m_async_mutex;
+
+ bool ShouldStop(const UnixSignals &signals,
+ StringExtractorGDBRemote &response);
+
+ class ContinueLock {
+ public:
+ enum class LockResult { Success, Cancelled, Failed };
+
+ explicit ContinueLock(GDBRemoteClientBase &comm);
+ ~ContinueLock();
+ explicit operator bool() { return m_acquired; }
+
+ LockResult lock();
+
+ void unlock();
+
+ private:
+ GDBRemoteClientBase &m_comm;
+ bool m_acquired;
+ };
+};
+
+} // namespace process_gdb_remote
+} // namespace lldb_private
+
+#endif // liblldb_GDBRemoteCommunicationClient_h_
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index f164b1411be8..bd87521fe6e7 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-
#include "GDBRemoteCommunication.h"
// C Includes
@@ -29,25 +28,25 @@
#include "lldb/Host/Socket.h"
#include "lldb/Host/StringConvert.h"
#include "lldb/Host/ThreadLauncher.h"
-#include "lldb/Host/TimeValue.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/ScopedPrinter.h"
// Project includes
#include "ProcessGDBRemoteLog.h"
#if defined(__APPLE__)
-# define DEBUGSERVER_BASENAME "debugserver"
+#define DEBUGSERVER_BASENAME "debugserver"
#else
-# define DEBUGSERVER_BASENAME "lldb-server"
+#define DEBUGSERVER_BASENAME "lldb-server"
#endif
-#if defined (HAVE_LIBCOMPRESSION)
+#if defined(HAVE_LIBCOMPRESSION)
#include <compression.h>
#endif
-#if defined (HAVE_LIBZ)
+#if defined(HAVE_LIBZ)
#include <zlib.h>
#endif
@@ -55,1449 +54,1309 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
-GDBRemoteCommunication::History::History (uint32_t size) :
- m_packets(),
- m_curr_idx (0),
- m_total_packet_count (0),
- m_dumped_to_log (false)
-{
- m_packets.resize(size);
+GDBRemoteCommunication::History::History(uint32_t size)
+ : m_packets(), m_curr_idx(0), m_total_packet_count(0),
+ m_dumped_to_log(false) {
+ m_packets.resize(size);
}
-GDBRemoteCommunication::History::~History ()
-{
+GDBRemoteCommunication::History::~History() {}
+
+void GDBRemoteCommunication::History::AddPacket(char packet_char,
+ PacketType type,
+ uint32_t bytes_transmitted) {
+ const size_t size = m_packets.size();
+ if (size > 0) {
+ const uint32_t idx = GetNextIndex();
+ m_packets[idx].packet.assign(1, packet_char);
+ m_packets[idx].type = type;
+ m_packets[idx].bytes_transmitted = bytes_transmitted;
+ m_packets[idx].packet_idx = m_total_packet_count;
+ m_packets[idx].tid = Host::GetCurrentThreadID();
+ }
}
-void
-GDBRemoteCommunication::History::AddPacket (char packet_char,
- PacketType type,
- uint32_t bytes_transmitted)
-{
- const size_t size = m_packets.size();
- if (size > 0)
- {
- const uint32_t idx = GetNextIndex();
- m_packets[idx].packet.assign (1, packet_char);
- m_packets[idx].type = type;
- m_packets[idx].bytes_transmitted = bytes_transmitted;
- m_packets[idx].packet_idx = m_total_packet_count;
- m_packets[idx].tid = Host::GetCurrentThreadID();
- }
+void GDBRemoteCommunication::History::AddPacket(const std::string &src,
+ uint32_t src_len,
+ PacketType type,
+ uint32_t bytes_transmitted) {
+ const size_t size = m_packets.size();
+ if (size > 0) {
+ const uint32_t idx = GetNextIndex();
+ m_packets[idx].packet.assign(src, 0, src_len);
+ m_packets[idx].type = type;
+ m_packets[idx].bytes_transmitted = bytes_transmitted;
+ m_packets[idx].packet_idx = m_total_packet_count;
+ m_packets[idx].tid = Host::GetCurrentThreadID();
+ }
}
-void
-GDBRemoteCommunication::History::AddPacket (const std::string &src,
- uint32_t src_len,
- PacketType type,
- uint32_t bytes_transmitted)
-{
- const size_t size = m_packets.size();
- if (size > 0)
- {
- const uint32_t idx = GetNextIndex();
- m_packets[idx].packet.assign (src, 0, src_len);
- m_packets[idx].type = type;
- m_packets[idx].bytes_transmitted = bytes_transmitted;
- m_packets[idx].packet_idx = m_total_packet_count;
- m_packets[idx].tid = Host::GetCurrentThreadID();
- }
+void GDBRemoteCommunication::History::Dump(Stream &strm) const {
+ const uint32_t size = GetNumPacketsInHistory();
+ const uint32_t first_idx = GetFirstSavedPacketIndex();
+ const uint32_t stop_idx = m_curr_idx + size;
+ for (uint32_t i = first_idx; i < stop_idx; ++i) {
+ const uint32_t idx = NormalizeIndex(i);
+ const Entry &entry = m_packets[idx];
+ if (entry.type == ePacketTypeInvalid || entry.packet.empty())
+ break;
+ strm.Printf("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s\n",
+ entry.packet_idx, entry.tid, entry.bytes_transmitted,
+ (entry.type == ePacketTypeSend) ? "send" : "read",
+ entry.packet.c_str());
+ }
}
-void
-GDBRemoteCommunication::History::Dump (Stream &strm) const
-{
- const uint32_t size = GetNumPacketsInHistory ();
- const uint32_t first_idx = GetFirstSavedPacketIndex ();
+void GDBRemoteCommunication::History::Dump(Log *log) const {
+ if (log && !m_dumped_to_log) {
+ m_dumped_to_log = true;
+ const uint32_t size = GetNumPacketsInHistory();
+ const uint32_t first_idx = GetFirstSavedPacketIndex();
const uint32_t stop_idx = m_curr_idx + size;
- for (uint32_t i = first_idx; i < stop_idx; ++i)
- {
- const uint32_t idx = NormalizeIndex (i);
- const Entry &entry = m_packets[idx];
- if (entry.type == ePacketTypeInvalid || entry.packet.empty())
- break;
- strm.Printf ("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s\n",
- entry.packet_idx,
- entry.tid,
- entry.bytes_transmitted,
- (entry.type == ePacketTypeSend) ? "send" : "read",
- entry.packet.c_str());
- }
-}
-
-void
-GDBRemoteCommunication::History::Dump (Log *log) const
-{
- if (log && !m_dumped_to_log)
- {
- m_dumped_to_log = true;
- const uint32_t size = GetNumPacketsInHistory ();
- const uint32_t first_idx = GetFirstSavedPacketIndex ();
- const uint32_t stop_idx = m_curr_idx + size;
- for (uint32_t i = first_idx; i < stop_idx; ++i)
- {
- const uint32_t idx = NormalizeIndex (i);
- const Entry &entry = m_packets[idx];
- if (entry.type == ePacketTypeInvalid || entry.packet.empty())
- break;
- log->Printf ("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s",
- entry.packet_idx,
- entry.tid,
- entry.bytes_transmitted,
- (entry.type == ePacketTypeSend) ? "send" : "read",
- entry.packet.c_str());
- }
+ for (uint32_t i = first_idx; i < stop_idx; ++i) {
+ const uint32_t idx = NormalizeIndex(i);
+ const Entry &entry = m_packets[idx];
+ if (entry.type == ePacketTypeInvalid || entry.packet.empty())
+ break;
+ log->Printf("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s",
+ entry.packet_idx, entry.tid, entry.bytes_transmitted,
+ (entry.type == ePacketTypeSend) ? "send" : "read",
+ entry.packet.c_str());
}
+ }
}
//----------------------------------------------------------------------
// GDBRemoteCommunication constructor
//----------------------------------------------------------------------
-GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name,
- const char *listener_name) :
- Communication(comm_name),
+GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name,
+ const char *listener_name)
+ : Communication(comm_name),
#ifdef LLDB_CONFIGURATION_DEBUG
- m_packet_timeout (1000),
+ m_packet_timeout(1000),
#else
- m_packet_timeout (1),
+ m_packet_timeout(1),
#endif
- m_echo_number(0),
- m_supports_qEcho (eLazyBoolCalculate),
- m_sequence_mutex (Mutex::eMutexTypeRecursive),
- m_public_is_running (false),
- m_private_is_running (false),
- m_history (512),
- m_send_acks (true),
- m_compression_type (CompressionType::None),
- m_listen_url ()
-{
+ m_echo_number(0), m_supports_qEcho(eLazyBoolCalculate), m_history(512),
+ m_send_acks(true), m_compression_type(CompressionType::None),
+ m_listen_url() {
}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-GDBRemoteCommunication::~GDBRemoteCommunication()
-{
- if (IsConnected())
- {
- Disconnect();
- }
-
- // Stop the communications read thread which is used to parse all
- // incoming packets. This function will block until the read
- // thread returns.
- if (m_read_thread_enabled)
- StopReadThread();
+GDBRemoteCommunication::~GDBRemoteCommunication() {
+ if (IsConnected()) {
+ Disconnect();
+ }
+
+ // Stop the communications read thread which is used to parse all
+ // incoming packets. This function will block until the read
+ // thread returns.
+ if (m_read_thread_enabled)
+ StopReadThread();
}
-char
-GDBRemoteCommunication::CalculcateChecksum (const char *payload, size_t payload_length)
-{
- int checksum = 0;
+char GDBRemoteCommunication::CalculcateChecksum(llvm::StringRef payload) {
+ int checksum = 0;
- for (size_t i = 0; i < payload_length; ++i)
- checksum += payload[i];
+ for (char c : payload)
+ checksum += c;
- return checksum & 255;
+ return checksum & 255;
}
-size_t
-GDBRemoteCommunication::SendAck ()
-{
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
- ConnectionStatus status = eConnectionStatusSuccess;
- char ch = '+';
- const size_t bytes_written = Write (&ch, 1, status, NULL);
- if (log)
- log->Printf ("<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch);
- m_history.AddPacket (ch, History::ePacketTypeSend, bytes_written);
- return bytes_written;
+size_t GDBRemoteCommunication::SendAck() {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
+ ConnectionStatus status = eConnectionStatusSuccess;
+ char ch = '+';
+ const size_t bytes_written = Write(&ch, 1, status, NULL);
+ if (log)
+ log->Printf("<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch);
+ m_history.AddPacket(ch, History::ePacketTypeSend, bytes_written);
+ return bytes_written;
}
-size_t
-GDBRemoteCommunication::SendNack ()
-{
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
- ConnectionStatus status = eConnectionStatusSuccess;
- char ch = '-';
- const size_t bytes_written = Write (&ch, 1, status, NULL);
- if (log)
- log->Printf("<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch);
- m_history.AddPacket (ch, History::ePacketTypeSend, bytes_written);
- return bytes_written;
+size_t GDBRemoteCommunication::SendNack() {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
+ ConnectionStatus status = eConnectionStatusSuccess;
+ char ch = '-';
+ const size_t bytes_written = Write(&ch, 1, status, NULL);
+ if (log)
+ log->Printf("<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch);
+ m_history.AddPacket(ch, History::ePacketTypeSend, bytes_written);
+ return bytes_written;
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunication::SendPacket (const char *payload, size_t payload_length)
-{
- Mutex::Locker locker(m_sequence_mutex);
- return SendPacketNoLock (payload, payload_length);
-}
+GDBRemoteCommunication::SendPacketNoLock(llvm::StringRef payload) {
+ if (IsConnected()) {
+ StreamString packet(0, 4, eByteOrderBig);
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_length)
-{
- if (IsConnected())
- {
- StreamString packet(0, 4, eByteOrderBig);
-
- packet.PutChar('$');
- packet.Write (payload, payload_length);
- packet.PutChar('#');
- packet.PutHex8(CalculcateChecksum (payload, payload_length));
-
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
- ConnectionStatus status = eConnectionStatusSuccess;
- const char *packet_data = packet.GetData();
- const size_t packet_length = packet.GetSize();
- size_t bytes_written = Write (packet_data, packet_length, status, NULL);
- if (log)
- {
- size_t binary_start_offset = 0;
- if (strncmp(packet_data, "$vFile:pwrite:", strlen("$vFile:pwrite:")) == 0)
- {
- const char *first_comma = strchr(packet_data, ',');
- if (first_comma)
- {
- const char *second_comma = strchr(first_comma + 1, ',');
- if (second_comma)
- binary_start_offset = second_comma - packet_data + 1;
- }
- }
-
- // If logging was just enabled and we have history, then dump out what
- // we have to the log so we get the historical context. The Dump() call that
- // logs all of the packet will set a boolean so that we don't dump this more
- // than once
- if (!m_history.DidDumpToLog ())
- m_history.Dump (log);
-
- if (binary_start_offset)
- {
- StreamString strm;
- // Print non binary data header
- strm.Printf("<%4" PRIu64 "> send packet: %.*s", (uint64_t)bytes_written, (int)binary_start_offset, packet_data);
- const uint8_t *p;
- // Print binary data exactly as sent
- for (p = (const uint8_t*)packet_data + binary_start_offset; *p != '#'; ++p)
- strm.Printf("\\x%2.2x", *p);
- // Print the checksum
- strm.Printf("%*s", (int)3, p);
- log->PutCString(strm.GetString().c_str());
- }
- else
- log->Printf("<%4" PRIu64 "> send packet: %.*s", (uint64_t)bytes_written, (int)packet_length, packet_data);
- }
+ packet.PutChar('$');
+ packet.Write(payload.data(), payload.size());
+ packet.PutChar('#');
+ packet.PutHex8(CalculcateChecksum(payload));
- m_history.AddPacket (packet.GetString(), packet_length, History::ePacketTypeSend, bytes_written);
-
-
- if (bytes_written == packet_length)
- {
- if (GetSendAcks ())
- return GetAck ();
- else
- return PacketResult::Success;
- }
- else
- {
- if (log)
- log->Printf ("error: failed to send packet: %.*s", (int)packet_length, packet_data);
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
+ ConnectionStatus status = eConnectionStatusSuccess;
+ // TODO: Don't shimmy through a std::string, just use StringRef.
+ std::string packet_str = packet.GetString();
+ const char *packet_data = packet_str.c_str();
+ const size_t packet_length = packet.GetSize();
+ size_t bytes_written = Write(packet_data, packet_length, status, NULL);
+ if (log) {
+ size_t binary_start_offset = 0;
+ if (strncmp(packet_data, "$vFile:pwrite:", strlen("$vFile:pwrite:")) ==
+ 0) {
+ const char *first_comma = strchr(packet_data, ',');
+ if (first_comma) {
+ const char *second_comma = strchr(first_comma + 1, ',');
+ if (second_comma)
+ binary_start_offset = second_comma - packet_data + 1;
}
+ }
+
+ // If logging was just enabled and we have history, then dump out what
+ // we have to the log so we get the historical context. The Dump() call
+ // that
+ // logs all of the packet will set a boolean so that we don't dump this
+ // more
+ // than once
+ if (!m_history.DidDumpToLog())
+ m_history.Dump(log);
+
+ if (binary_start_offset) {
+ StreamString strm;
+ // Print non binary data header
+ strm.Printf("<%4" PRIu64 "> send packet: %.*s", (uint64_t)bytes_written,
+ (int)binary_start_offset, packet_data);
+ const uint8_t *p;
+ // Print binary data exactly as sent
+ for (p = (const uint8_t *)packet_data + binary_start_offset; *p != '#';
+ ++p)
+ strm.Printf("\\x%2.2x", *p);
+ // Print the checksum
+ strm.Printf("%*s", (int)3, p);
+ log->PutString(strm.GetString());
+ } else
+ log->Printf("<%4" PRIu64 "> send packet: %.*s", (uint64_t)bytes_written,
+ (int)packet_length, packet_data);
}
- return PacketResult::ErrorSendFailed;
-}
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunication::GetAck ()
-{
- StringExtractorGDBRemote packet;
- PacketResult result = ReadPacket (packet, GetPacketTimeoutInMicroSeconds (), false);
- if (result == PacketResult::Success)
- {
- if (packet.GetResponseType() == StringExtractorGDBRemote::ResponseType::eAck)
- return PacketResult::Success;
- else
- return PacketResult::ErrorSendAck;
- }
- return result;
-}
+ m_history.AddPacket(packet.GetString(), packet_length,
+ History::ePacketTypeSend, bytes_written);
-bool
-GDBRemoteCommunication::GetSequenceMutex (Mutex::Locker& locker, const char *failure_message)
-{
- if (IsRunning())
- return locker.TryLock (m_sequence_mutex, failure_message);
-
- locker.Lock (m_sequence_mutex);
- return true;
+ if (bytes_written == packet_length) {
+ if (GetSendAcks())
+ return GetAck();
+ else
+ return PacketResult::Success;
+ } else {
+ if (log)
+ log->Printf("error: failed to send packet: %.*s", (int)packet_length,
+ packet_data);
+ }
+ }
+ return PacketResult::ErrorSendFailed;
}
-
-bool
-GDBRemoteCommunication::WaitForNotRunningPrivate (const TimeValue *timeout_ptr)
-{
- return m_private_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
+GDBRemoteCommunication::PacketResult GDBRemoteCommunication::GetAck() {
+ StringExtractorGDBRemote packet;
+ PacketResult result = ReadPacket(packet, GetPacketTimeout(), false);
+ if (result == PacketResult::Success) {
+ if (packet.GetResponseType() ==
+ StringExtractorGDBRemote::ResponseType::eAck)
+ return PacketResult::Success;
+ else
+ return PacketResult::ErrorSendAck;
+ }
+ return result;
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunication::ReadPacket (StringExtractorGDBRemote &response, uint32_t timeout_usec, bool sync_on_timeout)
-{
- if (m_read_thread_enabled)
- return PopPacketFromQueue (response, timeout_usec);
- else
- return WaitForPacketWithTimeoutMicroSecondsNoLock (response, timeout_usec, sync_on_timeout);
+GDBRemoteCommunication::ReadPacket(StringExtractorGDBRemote &response,
+ Timeout<std::micro> timeout,
+ bool sync_on_timeout) {
+ if (m_read_thread_enabled)
+ return PopPacketFromQueue(response, timeout);
+ else
+ return WaitForPacketNoLock(response, timeout, sync_on_timeout);
}
-
// This function is called when a packet is requested.
// A whole packet is popped from the packet queue and returned to the caller.
// Packets are placed into this queue from the communication read thread.
// See GDBRemoteCommunication::AppendBytesToCache.
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunication::PopPacketFromQueue (StringExtractorGDBRemote &response, uint32_t timeout_usec)
-{
- // Calculate absolute timeout value
- TimeValue timeout = TimeValue::Now();
- timeout.OffsetWithMicroSeconds(timeout_usec);
-
- do
- {
- // scope for the mutex
- {
- // lock down the packet queue
- Mutex::Locker locker(m_packet_queue_mutex);
-
- // Wait on condition variable.
- if (m_packet_queue.size() == 0)
- m_condition_queue_not_empty.Wait(m_packet_queue_mutex, &timeout);
-
- if (m_packet_queue.size() > 0)
- {
- // get the front element of the queue
- response = m_packet_queue.front();
-
- // remove the front element
- m_packet_queue.pop();
-
- // we got a packet
- return PacketResult::Success;
- }
- }
-
- // Disconnected
- if (!IsConnected())
- return PacketResult::ErrorDisconnected;
-
- // Loop while not timed out
- } while (TimeValue::Now() < timeout);
-
- return PacketResult::ErrorReplyTimeout;
+GDBRemoteCommunication::PopPacketFromQueue(StringExtractorGDBRemote &response,
+ Timeout<std::micro> timeout) {
+ auto pred = [&] { return !m_packet_queue.empty() && IsConnected(); };
+ // lock down the packet queue
+ std::unique_lock<std::mutex> lock(m_packet_queue_mutex);
+
+ if (!timeout)
+ m_condition_queue_not_empty.wait(lock, pred);
+ else {
+ if (!m_condition_queue_not_empty.wait_for(lock, *timeout, pred))
+ return PacketResult::ErrorReplyTimeout;
+ if (!IsConnected())
+ return PacketResult::ErrorDisconnected;
+ }
+
+ // get the front element of the queue
+ response = m_packet_queue.front();
+
+ // remove the front element
+ m_packet_queue.pop();
+
+ // we got a packet
+ return PacketResult::Success;
}
-
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunication::WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractorGDBRemote &packet, uint32_t timeout_usec, bool sync_on_timeout)
-{
- uint8_t buffer[8192];
- Error error;
+GDBRemoteCommunication::WaitForPacketNoLock(StringExtractorGDBRemote &packet,
+ Timeout<std::micro> timeout,
+ bool sync_on_timeout) {
+ uint8_t buffer[8192];
+ Error error;
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS | GDBR_LOG_VERBOSE));
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS |
+ GDBR_LOG_VERBOSE));
- // Check for a packet from our cache first without trying any reading...
- if (CheckForPacket(NULL, 0, packet) != PacketType::Invalid)
- return PacketResult::Success;
+ // Check for a packet from our cache first without trying any reading...
+ if (CheckForPacket(NULL, 0, packet) != PacketType::Invalid)
+ return PacketResult::Success;
- bool timed_out = false;
- bool disconnected = false;
- while (IsConnected() && !timed_out)
- {
- lldb::ConnectionStatus status = eConnectionStatusNoConnection;
- size_t bytes_read = Read (buffer, sizeof(buffer), timeout_usec, status, &error);
-
- if (log)
- log->Printf ("%s: Read (buffer, (sizeof(buffer), timeout_usec = 0x%x, status = %s, error = %s) => bytes_read = %" PRIu64,
- __PRETTY_FUNCTION__,
- timeout_usec,
- Communication::ConnectionStatusAsCString (status),
- error.AsCString(),
- (uint64_t)bytes_read);
-
- if (bytes_read > 0)
- {
- if (CheckForPacket(buffer, bytes_read, packet) != PacketType::Invalid)
- return PacketResult::Success;
- }
- else
- {
- switch (status)
- {
- case eConnectionStatusTimedOut:
- case eConnectionStatusInterrupted:
- if (sync_on_timeout)
- {
- //------------------------------------------------------------------
- /// Sync the remote GDB server and make sure we get a response that
- /// corresponds to what we send.
- ///
- /// Sends a "qEcho" packet and makes sure it gets the exact packet
- /// echoed back. If the qEcho packet isn't supported, we send a qC
- /// packet and make sure we get a valid thread ID back. We use the
- /// "qC" packet since its response if very unique: is responds with
- /// "QC%x" where %x is the thread ID of the current thread. This
- /// makes the response unique enough from other packet responses to
- /// ensure we are back on track.
- ///
- /// This packet is needed after we time out sending a packet so we
- /// can ensure that we are getting the response for the packet we
- /// are sending. There are no sequence IDs in the GDB remote
- /// protocol (there used to be, but they are not supported anymore)
- /// so if you timeout sending packet "abc", you might then send
- /// packet "cde" and get the response for the previous "abc" packet.
- /// Many responses are "OK" or "" (unsupported) or "EXX" (error) so
- /// many responses for packets can look like responses for other
- /// packets. So if we timeout, we need to ensure that we can get
- /// back on track. If we can't get back on track, we must
- /// disconnect.
- //------------------------------------------------------------------
- bool sync_success = false;
- bool got_actual_response = false;
- // We timed out, we need to sync back up with the
- char echo_packet[32];
- int echo_packet_len = 0;
- RegularExpression response_regex;
-
- if (m_supports_qEcho == eLazyBoolYes)
- {
- echo_packet_len = ::snprintf (echo_packet, sizeof(echo_packet), "qEcho:%u", ++m_echo_number);
- std::string regex_str = "^";
- regex_str += echo_packet;
- regex_str += "$";
- response_regex.Compile(regex_str.c_str());
- }
- else
- {
- echo_packet_len = ::snprintf (echo_packet, sizeof(echo_packet), "qC");
- response_regex.Compile("^QC[0-9A-Fa-f]+$");
- }
-
- PacketResult echo_packet_result = SendPacketNoLock (echo_packet, echo_packet_len);
- if (echo_packet_result == PacketResult::Success)
- {
- const uint32_t max_retries = 3;
- uint32_t successful_responses = 0;
- for (uint32_t i=0; i<max_retries; ++i)
- {
- StringExtractorGDBRemote echo_response;
- echo_packet_result = WaitForPacketWithTimeoutMicroSecondsNoLock (echo_response, timeout_usec, false);
- if (echo_packet_result == PacketResult::Success)
- {
- ++successful_responses;
- if (response_regex.Execute(echo_response.GetStringRef().c_str()))
- {
- sync_success = true;
- break;
- }
- else if (successful_responses == 1)
- {
- // We got something else back as the first successful response, it probably is
- // the response to the packet we actually wanted, so copy it over if this
- // is the first success and continue to try to get the qEcho response
- packet = echo_response;
- got_actual_response = true;
- }
- }
- else if (echo_packet_result == PacketResult::ErrorReplyTimeout)
- continue; // Packet timed out, continue waiting for a response
- else
- break; // Something else went wrong getting the packet back, we failed and are done trying
- }
- }
-
- // We weren't able to sync back up with the server, we must abort otherwise
- // all responses might not be from the right packets...
- if (sync_success)
- {
- // We timed out, but were able to recover
- if (got_actual_response)
- {
- // We initially timed out, but we did get a response that came in before the successful
- // reply to our qEcho packet, so lets say everything is fine...
- return PacketResult::Success;
- }
- }
- else
- {
- disconnected = true;
- Disconnect();
- }
+ bool timed_out = false;
+ bool disconnected = false;
+ while (IsConnected() && !timed_out) {
+ lldb::ConnectionStatus status = eConnectionStatusNoConnection;
+ size_t bytes_read = Read(buffer, sizeof(buffer), timeout, status, &error);
+
+ if (log)
+ log->Printf("%s: Read (buffer, (sizeof(buffer), timeout = %ld us, "
+ "status = %s, error = %s) => bytes_read = %" PRIu64,
+ LLVM_PRETTY_FUNCTION, long(timeout ? timeout->count() : -1),
+ Communication::ConnectionStatusAsCString(status),
+ error.AsCString(), (uint64_t)bytes_read);
+
+ if (bytes_read > 0) {
+ if (CheckForPacket(buffer, bytes_read, packet) != PacketType::Invalid)
+ return PacketResult::Success;
+ } else {
+ switch (status) {
+ case eConnectionStatusTimedOut:
+ case eConnectionStatusInterrupted:
+ if (sync_on_timeout) {
+ //------------------------------------------------------------------
+ /// Sync the remote GDB server and make sure we get a response that
+ /// corresponds to what we send.
+ ///
+ /// Sends a "qEcho" packet and makes sure it gets the exact packet
+ /// echoed back. If the qEcho packet isn't supported, we send a qC
+ /// packet and make sure we get a valid thread ID back. We use the
+ /// "qC" packet since its response if very unique: is responds with
+ /// "QC%x" where %x is the thread ID of the current thread. This
+ /// makes the response unique enough from other packet responses to
+ /// ensure we are back on track.
+ ///
+ /// This packet is needed after we time out sending a packet so we
+ /// can ensure that we are getting the response for the packet we
+ /// are sending. There are no sequence IDs in the GDB remote
+ /// protocol (there used to be, but they are not supported anymore)
+ /// so if you timeout sending packet "abc", you might then send
+ /// packet "cde" and get the response for the previous "abc" packet.
+ /// Many responses are "OK" or "" (unsupported) or "EXX" (error) so
+ /// many responses for packets can look like responses for other
+ /// packets. So if we timeout, we need to ensure that we can get
+ /// back on track. If we can't get back on track, we must
+ /// disconnect.
+ //------------------------------------------------------------------
+ bool sync_success = false;
+ bool got_actual_response = false;
+ // We timed out, we need to sync back up with the
+ char echo_packet[32];
+ int echo_packet_len = 0;
+ RegularExpression response_regex;
+
+ if (m_supports_qEcho == eLazyBoolYes) {
+ echo_packet_len = ::snprintf(echo_packet, sizeof(echo_packet),
+ "qEcho:%u", ++m_echo_number);
+ std::string regex_str = "^";
+ regex_str += echo_packet;
+ regex_str += "$";
+ response_regex.Compile(regex_str);
+ } else {
+ echo_packet_len =
+ ::snprintf(echo_packet, sizeof(echo_packet), "qC");
+ response_regex.Compile(llvm::StringRef("^QC[0-9A-Fa-f]+$"));
+ }
+
+ PacketResult echo_packet_result =
+ SendPacketNoLock(llvm::StringRef(echo_packet, echo_packet_len));
+ if (echo_packet_result == PacketResult::Success) {
+ const uint32_t max_retries = 3;
+ uint32_t successful_responses = 0;
+ for (uint32_t i = 0; i < max_retries; ++i) {
+ StringExtractorGDBRemote echo_response;
+ echo_packet_result =
+ WaitForPacketNoLock(echo_response, timeout, false);
+ if (echo_packet_result == PacketResult::Success) {
+ ++successful_responses;
+ if (response_regex.Execute(echo_response.GetStringRef())) {
+ sync_success = true;
+ break;
+ } else if (successful_responses == 1) {
+ // We got something else back as the first successful
+ // response, it probably is
+ // the response to the packet we actually wanted, so copy it
+ // over if this
+ // is the first success and continue to try to get the qEcho
+ // response
+ packet = echo_response;
+ got_actual_response = true;
}
- timed_out = true;
- break;
- case eConnectionStatusSuccess:
- //printf ("status = success but error = %s\n", error.AsCString("<invalid>"));
- break;
-
- case eConnectionStatusEndOfFile:
- case eConnectionStatusNoConnection:
- case eConnectionStatusLostConnection:
- case eConnectionStatusError:
- disconnected = true;
- Disconnect();
- break;
+ } else if (echo_packet_result == PacketResult::ErrorReplyTimeout)
+ continue; // Packet timed out, continue waiting for a response
+ else
+ break; // Something else went wrong getting the packet back, we
+ // failed and are done trying
}
+ }
+
+ // We weren't able to sync back up with the server, we must abort
+ // otherwise
+ // all responses might not be from the right packets...
+ if (sync_success) {
+ // We timed out, but were able to recover
+ if (got_actual_response) {
+ // We initially timed out, but we did get a response that came in
+ // before the successful
+ // reply to our qEcho packet, so lets say everything is fine...
+ return PacketResult::Success;
+ }
+ } else {
+ disconnected = true;
+ Disconnect();
+ }
}
+ timed_out = true;
+ break;
+ case eConnectionStatusSuccess:
+ // printf ("status = success but error = %s\n",
+ // error.AsCString("<invalid>"));
+ break;
+
+ case eConnectionStatusEndOfFile:
+ case eConnectionStatusNoConnection:
+ case eConnectionStatusLostConnection:
+ case eConnectionStatusError:
+ disconnected = true;
+ Disconnect();
+ break;
+ }
}
- packet.Clear ();
- if (disconnected)
- return PacketResult::ErrorDisconnected;
- if (timed_out)
- return PacketResult::ErrorReplyTimeout;
- else
- return PacketResult::ErrorReplyFailed;
+ }
+ packet.Clear();
+ if (disconnected)
+ return PacketResult::ErrorDisconnected;
+ if (timed_out)
+ return PacketResult::ErrorReplyTimeout;
+ else
+ return PacketResult::ErrorReplyFailed;
}
-bool
-GDBRemoteCommunication::DecompressPacket ()
-{
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
-
- if (!CompressionIsEnabled())
- return true;
-
- size_t pkt_size = m_bytes.size();
-
- // Smallest possible compressed packet is $N#00 - an uncompressed empty reply, most commonly indicating
- // an unsupported packet. Anything less than 5 characters, it's definitely not a compressed packet.
- if (pkt_size < 5)
- return true;
-
- if (m_bytes[0] != '$' && m_bytes[0] != '%')
- return true;
- if (m_bytes[1] != 'C' && m_bytes[1] != 'N')
- return true;
-
- size_t hash_mark_idx = m_bytes.find ('#');
- if (hash_mark_idx == std::string::npos)
- return true;
- if (hash_mark_idx + 2 >= m_bytes.size())
- return true;
-
- if (!::isxdigit (m_bytes[hash_mark_idx + 1]) || !::isxdigit (m_bytes[hash_mark_idx + 2]))
- return true;
-
- size_t content_length = pkt_size - 5; // not counting '$', 'C' | 'N', '#', & the two hex checksum chars
- size_t content_start = 2; // The first character of the compressed/not-compressed text of the packet
- size_t checksum_idx = hash_mark_idx + 1; // The first character of the two hex checksum characters
-
- // Normally size_of_first_packet == m_bytes.size() but m_bytes may contain multiple packets.
- // size_of_first_packet is the size of the initial packet which we'll replace with the decompressed
- // version of, leaving the rest of m_bytes unmodified.
- size_t size_of_first_packet = hash_mark_idx + 3;
-
- // Compressed packets ("$C") start with a base10 number which is the size of the uncompressed payload,
- // then a : and then the compressed data. e.g. $C1024:<binary>#00
- // Update content_start and content_length to only include the <binary> part of the packet.
-
- uint64_t decompressed_bufsize = ULONG_MAX;
- if (m_bytes[1] == 'C')
- {
- size_t i = content_start;
- while (i < hash_mark_idx && isdigit(m_bytes[i]))
- i++;
- if (i < hash_mark_idx && m_bytes[i] == ':')
- {
- i++;
- content_start = i;
- content_length = hash_mark_idx - content_start;
- std::string bufsize_str (m_bytes.data() + 2, i - 2 - 1);
- errno = 0;
- decompressed_bufsize = ::strtoul (bufsize_str.c_str(), NULL, 10);
- if (errno != 0 || decompressed_bufsize == ULONG_MAX)
- {
- m_bytes.erase (0, size_of_first_packet);
- return false;
- }
- }
- }
+bool GDBRemoteCommunication::DecompressPacket() {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
- if (GetSendAcks ())
- {
- char packet_checksum_cstr[3];
- packet_checksum_cstr[0] = m_bytes[checksum_idx];
- packet_checksum_cstr[1] = m_bytes[checksum_idx + 1];
- packet_checksum_cstr[2] = '\0';
- long packet_checksum = strtol (packet_checksum_cstr, NULL, 16);
-
- long actual_checksum = CalculcateChecksum (m_bytes.data() + 1, hash_mark_idx - 1);
- bool success = packet_checksum == actual_checksum;
- if (!success)
- {
- if (log)
- log->Printf ("error: checksum mismatch: %.*s expected 0x%2.2x, got 0x%2.2x",
- (int)(pkt_size),
- m_bytes.c_str(),
- (uint8_t)packet_checksum,
- (uint8_t)actual_checksum);
- }
- // Send the ack or nack if needed
- if (!success)
- {
- SendNack();
- m_bytes.erase (0, size_of_first_packet);
- return false;
- }
- else
- {
- SendAck();
- }
- }
+ if (!CompressionIsEnabled())
+ return true;
- if (m_bytes[1] == 'N')
- {
- // This packet was not compressed -- delete the 'N' character at the
- // start and the packet may be processed as-is.
- m_bytes.erase(1, 1);
- return true;
- }
+ size_t pkt_size = m_bytes.size();
- // Reverse the gdb-remote binary escaping that was done to the compressed text to
- // guard characters like '$', '#', '}', etc.
- std::vector<uint8_t> unescaped_content;
- unescaped_content.reserve (content_length);
- size_t i = content_start;
- while (i < hash_mark_idx)
- {
- if (m_bytes[i] == '}')
- {
- i++;
- unescaped_content.push_back (m_bytes[i] ^ 0x20);
- }
- else
- {
- unescaped_content.push_back (m_bytes[i]);
- }
- i++;
- }
+ // Smallest possible compressed packet is $N#00 - an uncompressed empty reply,
+ // most commonly indicating
+ // an unsupported packet. Anything less than 5 characters, it's definitely
+ // not a compressed packet.
+ if (pkt_size < 5)
+ return true;
- uint8_t *decompressed_buffer = nullptr;
- size_t decompressed_bytes = 0;
+ if (m_bytes[0] != '$' && m_bytes[0] != '%')
+ return true;
+ if (m_bytes[1] != 'C' && m_bytes[1] != 'N')
+ return true;
- if (decompressed_bufsize != ULONG_MAX)
- {
- decompressed_buffer = (uint8_t *) malloc (decompressed_bufsize + 1);
- if (decompressed_buffer == nullptr)
- {
- m_bytes.erase (0, size_of_first_packet);
- return false;
- }
+ size_t hash_mark_idx = m_bytes.find('#');
+ if (hash_mark_idx == std::string::npos)
+ return true;
+ if (hash_mark_idx + 2 >= m_bytes.size())
+ return true;
- }
+ if (!::isxdigit(m_bytes[hash_mark_idx + 1]) ||
+ !::isxdigit(m_bytes[hash_mark_idx + 2]))
+ return true;
-#if defined (HAVE_LIBCOMPRESSION)
- // libcompression is weak linked so check that compression_decode_buffer() is available
- if (compression_decode_buffer != NULL &&
- (m_compression_type == CompressionType::ZlibDeflate
- || m_compression_type == CompressionType::LZFSE
- || m_compression_type == CompressionType::LZ4))
- {
- compression_algorithm compression_type;
- if (m_compression_type == CompressionType::ZlibDeflate)
- compression_type = COMPRESSION_ZLIB;
- else if (m_compression_type == CompressionType::LZFSE)
- compression_type = COMPRESSION_LZFSE;
- else if (m_compression_type == CompressionType::LZ4)
- compression_type = COMPRESSION_LZ4_RAW;
- else if (m_compression_type == CompressionType::LZMA)
- compression_type = COMPRESSION_LZMA;
-
-
- // If we have the expected size of the decompressed payload, we can allocate
- // the right-sized buffer and do it. If we don't have that information, we'll
- // need to try decoding into a big buffer and if the buffer wasn't big enough,
- // increase it and try again.
-
- if (decompressed_bufsize != ULONG_MAX && decompressed_buffer != nullptr)
- {
- decompressed_bytes = compression_decode_buffer (decompressed_buffer, decompressed_bufsize + 10 ,
- (uint8_t*) unescaped_content.data(),
- unescaped_content.size(),
- NULL,
- compression_type);
- }
+ size_t content_length =
+ pkt_size -
+ 5; // not counting '$', 'C' | 'N', '#', & the two hex checksum chars
+ size_t content_start = 2; // The first character of the
+ // compressed/not-compressed text of the packet
+ size_t checksum_idx =
+ hash_mark_idx +
+ 1; // The first character of the two hex checksum characters
+
+ // Normally size_of_first_packet == m_bytes.size() but m_bytes may contain
+ // multiple packets.
+ // size_of_first_packet is the size of the initial packet which we'll replace
+ // with the decompressed
+ // version of, leaving the rest of m_bytes unmodified.
+ size_t size_of_first_packet = hash_mark_idx + 3;
+
+ // Compressed packets ("$C") start with a base10 number which is the size of
+ // the uncompressed payload,
+ // then a : and then the compressed data. e.g. $C1024:<binary>#00
+ // Update content_start and content_length to only include the <binary> part
+ // of the packet.
+
+ uint64_t decompressed_bufsize = ULONG_MAX;
+ if (m_bytes[1] == 'C') {
+ size_t i = content_start;
+ while (i < hash_mark_idx && isdigit(m_bytes[i]))
+ i++;
+ if (i < hash_mark_idx && m_bytes[i] == ':') {
+ i++;
+ content_start = i;
+ content_length = hash_mark_idx - content_start;
+ std::string bufsize_str(m_bytes.data() + 2, i - 2 - 1);
+ errno = 0;
+ decompressed_bufsize = ::strtoul(bufsize_str.c_str(), NULL, 10);
+ if (errno != 0 || decompressed_bufsize == ULONG_MAX) {
+ m_bytes.erase(0, size_of_first_packet);
+ return false;
+ }
}
-#endif
-
-#if defined (HAVE_LIBZ)
- if (decompressed_bytes == 0
- && decompressed_bufsize != ULONG_MAX
- && decompressed_buffer != nullptr
- && m_compression_type == CompressionType::ZlibDeflate)
- {
- z_stream stream;
- memset (&stream, 0, sizeof (z_stream));
- stream.next_in = (Bytef *) unescaped_content.data();
- stream.avail_in = (uInt) unescaped_content.size();
- stream.total_in = 0;
- stream.next_out = (Bytef *) decompressed_buffer;
- stream.avail_out = decompressed_bufsize;
- stream.total_out = 0;
- stream.zalloc = Z_NULL;
- stream.zfree = Z_NULL;
- stream.opaque = Z_NULL;
-
- if (inflateInit2 (&stream, -15) == Z_OK)
- {
- int status = inflate (&stream, Z_NO_FLUSH);
- inflateEnd (&stream);
- if (status == Z_STREAM_END)
- {
- decompressed_bytes = stream.total_out;
- }
- }
+ }
+
+ if (GetSendAcks()) {
+ char packet_checksum_cstr[3];
+ packet_checksum_cstr[0] = m_bytes[checksum_idx];
+ packet_checksum_cstr[1] = m_bytes[checksum_idx + 1];
+ packet_checksum_cstr[2] = '\0';
+ long packet_checksum = strtol(packet_checksum_cstr, NULL, 16);
+
+ long actual_checksum = CalculcateChecksum(
+ llvm::StringRef(m_bytes).substr(1, hash_mark_idx - 1));
+ bool success = packet_checksum == actual_checksum;
+ if (!success) {
+ if (log)
+ log->Printf(
+ "error: checksum mismatch: %.*s expected 0x%2.2x, got 0x%2.2x",
+ (int)(pkt_size), m_bytes.c_str(), (uint8_t)packet_checksum,
+ (uint8_t)actual_checksum);
}
-#endif
+ // Send the ack or nack if needed
+ if (!success) {
+ SendNack();
+ m_bytes.erase(0, size_of_first_packet);
+ return false;
+ } else {
+ SendAck();
+ }
+ }
- if (decompressed_bytes == 0 || decompressed_buffer == nullptr)
- {
- if (decompressed_buffer)
- free (decompressed_buffer);
- m_bytes.erase (0, size_of_first_packet);
- return false;
+ if (m_bytes[1] == 'N') {
+ // This packet was not compressed -- delete the 'N' character at the
+ // start and the packet may be processed as-is.
+ m_bytes.erase(1, 1);
+ return true;
+ }
+
+ // Reverse the gdb-remote binary escaping that was done to the compressed text
+ // to
+ // guard characters like '$', '#', '}', etc.
+ std::vector<uint8_t> unescaped_content;
+ unescaped_content.reserve(content_length);
+ size_t i = content_start;
+ while (i < hash_mark_idx) {
+ if (m_bytes[i] == '}') {
+ i++;
+ unescaped_content.push_back(m_bytes[i] ^ 0x20);
+ } else {
+ unescaped_content.push_back(m_bytes[i]);
}
+ i++;
+ }
+
+ uint8_t *decompressed_buffer = nullptr;
+ size_t decompressed_bytes = 0;
- std::string new_packet;
- new_packet.reserve (decompressed_bytes + 6);
- new_packet.push_back (m_bytes[0]);
- new_packet.append ((const char *) decompressed_buffer, decompressed_bytes);
- new_packet.push_back ('#');
- if (GetSendAcks ())
- {
- uint8_t decompressed_checksum = CalculcateChecksum ((const char *) decompressed_buffer, decompressed_bytes);
- char decompressed_checksum_str[3];
- snprintf (decompressed_checksum_str, 3, "%02x", decompressed_checksum);
- new_packet.append (decompressed_checksum_str);
+ if (decompressed_bufsize != ULONG_MAX) {
+ decompressed_buffer = (uint8_t *)malloc(decompressed_bufsize + 1);
+ if (decompressed_buffer == nullptr) {
+ m_bytes.erase(0, size_of_first_packet);
+ return false;
}
- else
- {
- new_packet.push_back ('0');
- new_packet.push_back ('0');
+ }
+
+#if defined(HAVE_LIBCOMPRESSION)
+ // libcompression is weak linked so check that compression_decode_buffer() is
+ // available
+ if (compression_decode_buffer != NULL &&
+ (m_compression_type == CompressionType::ZlibDeflate ||
+ m_compression_type == CompressionType::LZFSE ||
+ m_compression_type == CompressionType::LZ4)) {
+ compression_algorithm compression_type;
+ if (m_compression_type == CompressionType::ZlibDeflate)
+ compression_type = COMPRESSION_ZLIB;
+ else if (m_compression_type == CompressionType::LZFSE)
+ compression_type = COMPRESSION_LZFSE;
+ else if (m_compression_type == CompressionType::LZ4)
+ compression_type = COMPRESSION_LZ4_RAW;
+ else if (m_compression_type == CompressionType::LZMA)
+ compression_type = COMPRESSION_LZMA;
+
+ // If we have the expected size of the decompressed payload, we can allocate
+ // the right-sized buffer and do it. If we don't have that information,
+ // we'll
+ // need to try decoding into a big buffer and if the buffer wasn't big
+ // enough,
+ // increase it and try again.
+
+ if (decompressed_bufsize != ULONG_MAX && decompressed_buffer != nullptr) {
+ decompressed_bytes = compression_decode_buffer(
+ decompressed_buffer, decompressed_bufsize + 10,
+ (uint8_t *)unescaped_content.data(), unescaped_content.size(), NULL,
+ compression_type);
}
+ }
+#endif
- m_bytes.replace (0, size_of_first_packet, new_packet.data(), new_packet.size());
+#if defined(HAVE_LIBZ)
+ if (decompressed_bytes == 0 && decompressed_bufsize != ULONG_MAX &&
+ decompressed_buffer != nullptr &&
+ m_compression_type == CompressionType::ZlibDeflate) {
+ z_stream stream;
+ memset(&stream, 0, sizeof(z_stream));
+ stream.next_in = (Bytef *)unescaped_content.data();
+ stream.avail_in = (uInt)unescaped_content.size();
+ stream.total_in = 0;
+ stream.next_out = (Bytef *)decompressed_buffer;
+ stream.avail_out = decompressed_bufsize;
+ stream.total_out = 0;
+ stream.zalloc = Z_NULL;
+ stream.zfree = Z_NULL;
+ stream.opaque = Z_NULL;
+
+ if (inflateInit2(&stream, -15) == Z_OK) {
+ int status = inflate(&stream, Z_NO_FLUSH);
+ inflateEnd(&stream);
+ if (status == Z_STREAM_END) {
+ decompressed_bytes = stream.total_out;
+ }
+ }
+ }
+#endif
- free (decompressed_buffer);
- return true;
+ if (decompressed_bytes == 0 || decompressed_buffer == nullptr) {
+ if (decompressed_buffer)
+ free(decompressed_buffer);
+ m_bytes.erase(0, size_of_first_packet);
+ return false;
+ }
+
+ std::string new_packet;
+ new_packet.reserve(decompressed_bytes + 6);
+ new_packet.push_back(m_bytes[0]);
+ new_packet.append((const char *)decompressed_buffer, decompressed_bytes);
+ new_packet.push_back('#');
+ if (GetSendAcks()) {
+ uint8_t decompressed_checksum = CalculcateChecksum(
+ llvm::StringRef((const char *)decompressed_buffer, decompressed_bytes));
+ char decompressed_checksum_str[3];
+ snprintf(decompressed_checksum_str, 3, "%02x", decompressed_checksum);
+ new_packet.append(decompressed_checksum_str);
+ } else {
+ new_packet.push_back('0');
+ new_packet.push_back('0');
+ }
+
+ m_bytes.replace(0, size_of_first_packet, new_packet.data(),
+ new_packet.size());
+
+ free(decompressed_buffer);
+ return true;
}
GDBRemoteCommunication::PacketType
-GDBRemoteCommunication::CheckForPacket (const uint8_t *src, size_t src_len, StringExtractorGDBRemote &packet)
-{
- // Put the packet data into the buffer in a thread safe fashion
- std::lock_guard<std::recursive_mutex> guard(m_bytes_mutex);
-
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
-
- if (src && src_len > 0)
- {
- if (log && log->GetVerbose())
- {
- StreamString s;
- log->Printf ("GDBRemoteCommunication::%s adding %u bytes: %.*s",
- __FUNCTION__,
- (uint32_t)src_len,
- (uint32_t)src_len,
- src);
- }
- m_bytes.append ((const char *)src, src_len);
+GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
+ StringExtractorGDBRemote &packet) {
+ // Put the packet data into the buffer in a thread safe fashion
+ std::lock_guard<std::recursive_mutex> guard(m_bytes_mutex);
+
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
+
+ if (src && src_len > 0) {
+ if (log && log->GetVerbose()) {
+ StreamString s;
+ log->Printf("GDBRemoteCommunication::%s adding %u bytes: %.*s",
+ __FUNCTION__, (uint32_t)src_len, (uint32_t)src_len, src);
+ }
+ m_bytes.append((const char *)src, src_len);
+ }
+
+ bool isNotifyPacket = false;
+
+ // Parse up the packets into gdb remote packets
+ if (!m_bytes.empty()) {
+ // end_idx must be one past the last valid packet byte. Start
+ // it off with an invalid value that is the same as the current
+ // index.
+ size_t content_start = 0;
+ size_t content_length = 0;
+ size_t total_length = 0;
+ size_t checksum_idx = std::string::npos;
+
+ // Size of packet before it is decompressed, for logging purposes
+ size_t original_packet_size = m_bytes.size();
+ if (CompressionIsEnabled()) {
+ if (DecompressPacket() == false) {
+ packet.Clear();
+ return GDBRemoteCommunication::PacketType::Standard;
+ }
}
- bool isNotifyPacket = false;
-
- // Parse up the packets into gdb remote packets
- if (!m_bytes.empty())
- {
- // end_idx must be one past the last valid packet byte. Start
- // it off with an invalid value that is the same as the current
- // index.
- size_t content_start = 0;
- size_t content_length = 0;
- size_t total_length = 0;
- size_t checksum_idx = std::string::npos;
-
- // Size of packet before it is decompressed, for logging purposes
- size_t original_packet_size = m_bytes.size();
- if (CompressionIsEnabled())
- {
- if (DecompressPacket() == false)
- {
- packet.Clear();
- return GDBRemoteCommunication::PacketType::Standard;
- }
+ switch (m_bytes[0]) {
+ case '+': // Look for ack
+ case '-': // Look for cancel
+ case '\x03': // ^C to halt target
+ content_length = total_length = 1; // The command is one byte long...
+ break;
+
+ case '%': // Async notify packet
+ isNotifyPacket = true;
+ LLVM_FALLTHROUGH;
+
+ case '$':
+ // Look for a standard gdb packet?
+ {
+ size_t hash_pos = m_bytes.find('#');
+ if (hash_pos != std::string::npos) {
+ if (hash_pos + 2 < m_bytes.size()) {
+ checksum_idx = hash_pos + 1;
+ // Skip the dollar sign
+ content_start = 1;
+ // Don't include the # in the content or the $ in the content length
+ content_length = hash_pos - 1;
+
+ total_length =
+ hash_pos + 3; // Skip the # and the two hex checksum bytes
+ } else {
+ // Checksum bytes aren't all here yet
+ content_length = std::string::npos;
+ }
}
-
- switch (m_bytes[0])
- {
- case '+': // Look for ack
- case '-': // Look for cancel
- case '\x03': // ^C to halt target
- content_length = total_length = 1; // The command is one byte long...
- break;
-
- case '%': // Async notify packet
- isNotifyPacket = true;
- LLVM_FALLTHROUGH;
-
- case '$':
- // Look for a standard gdb packet?
- {
- size_t hash_pos = m_bytes.find('#');
- if (hash_pos != std::string::npos)
- {
- if (hash_pos + 2 < m_bytes.size())
- {
- checksum_idx = hash_pos + 1;
- // Skip the dollar sign
- content_start = 1;
- // Don't include the # in the content or the $ in the content length
- content_length = hash_pos - 1;
-
- total_length = hash_pos + 3; // Skip the # and the two hex checksum bytes
- }
- else
- {
- // Checksum bytes aren't all here yet
- content_length = std::string::npos;
- }
- }
- }
- break;
-
- default:
- {
- // We have an unexpected byte and we need to flush all bad
- // data that is in m_bytes, so we need to find the first
- // byte that is a '+' (ACK), '-' (NACK), \x03 (CTRL+C interrupt),
- // or '$' character (start of packet header) or of course,
- // the end of the data in m_bytes...
- const size_t bytes_len = m_bytes.size();
- bool done = false;
- uint32_t idx;
- for (idx = 1; !done && idx < bytes_len; ++idx)
- {
- switch (m_bytes[idx])
- {
- case '+':
- case '-':
- case '\x03':
- case '%':
- case '$':
- done = true;
- break;
-
- default:
- break;
- }
- }
- if (log)
- log->Printf ("GDBRemoteCommunication::%s tossing %u junk bytes: '%.*s'",
- __FUNCTION__, idx - 1, idx - 1, m_bytes.c_str());
- m_bytes.erase(0, idx - 1);
- }
- break;
+ }
+ break;
+
+ default: {
+ // We have an unexpected byte and we need to flush all bad
+ // data that is in m_bytes, so we need to find the first
+ // byte that is a '+' (ACK), '-' (NACK), \x03 (CTRL+C interrupt),
+ // or '$' character (start of packet header) or of course,
+ // the end of the data in m_bytes...
+ const size_t bytes_len = m_bytes.size();
+ bool done = false;
+ uint32_t idx;
+ for (idx = 1; !done && idx < bytes_len; ++idx) {
+ switch (m_bytes[idx]) {
+ case '+':
+ case '-':
+ case '\x03':
+ case '%':
+ case '$':
+ done = true;
+ break;
+
+ default:
+ break;
}
+ }
+ if (log)
+ log->Printf("GDBRemoteCommunication::%s tossing %u junk bytes: '%.*s'",
+ __FUNCTION__, idx - 1, idx - 1, m_bytes.c_str());
+ m_bytes.erase(0, idx - 1);
+ } break;
+ }
- if (content_length == std::string::npos)
- {
- packet.Clear();
- return GDBRemoteCommunication::PacketType::Invalid;
- }
- else if (total_length > 0)
- {
-
- // We have a valid packet...
- assert (content_length <= m_bytes.size());
- assert (total_length <= m_bytes.size());
- assert (content_length <= total_length);
- size_t content_end = content_start + content_length;
-
- bool success = true;
- std::string &packet_str = packet.GetStringRef();
- if (log)
- {
- // If logging was just enabled and we have history, then dump out what
- // we have to the log so we get the historical context. The Dump() call that
- // logs all of the packet will set a boolean so that we don't dump this more
- // than once
- if (!m_history.DidDumpToLog ())
- m_history.Dump (log);
-
- bool binary = false;
- // Only detect binary for packets that start with a '$' and have a '#CC' checksum
- if (m_bytes[0] == '$' && total_length > 4)
- {
- for (size_t i=0; !binary && i<total_length; ++i)
- {
- if (isprint (m_bytes[i]) == 0 && isspace (m_bytes[i]) == 0)
- {
- binary = true;
- }
- }
- }
- if (binary)
- {
- StreamString strm;
- // Packet header...
- if (CompressionIsEnabled())
- strm.Printf("<%4" PRIu64 ":%" PRIu64 "> read packet: %c", (uint64_t) original_packet_size, (uint64_t)total_length, m_bytes[0]);
- else
- strm.Printf("<%4" PRIu64 "> read packet: %c", (uint64_t)total_length, m_bytes[0]);
- for (size_t i=content_start; i<content_end; ++i)
- {
- // Remove binary escaped bytes when displaying the packet...
- const char ch = m_bytes[i];
- if (ch == 0x7d)
- {
- // 0x7d is the escape character. The next character is to
- // be XOR'd with 0x20.
- const char escapee = m_bytes[++i] ^ 0x20;
- strm.Printf("%2.2x", escapee);
- }
- else
- {
- strm.Printf("%2.2x", (uint8_t)ch);
- }
- }
- // Packet footer...
- strm.Printf("%c%c%c", m_bytes[total_length-3], m_bytes[total_length-2], m_bytes[total_length-1]);
- log->PutCString(strm.GetString().c_str());
- }
- else
- {
- if (CompressionIsEnabled())
- log->Printf("<%4" PRIu64 ":%" PRIu64 "> read packet: %.*s", (uint64_t) original_packet_size, (uint64_t)total_length, (int)(total_length), m_bytes.c_str());
- else
- log->Printf("<%4" PRIu64 "> read packet: %.*s", (uint64_t)total_length, (int)(total_length), m_bytes.c_str());
- }
+ if (content_length == std::string::npos) {
+ packet.Clear();
+ return GDBRemoteCommunication::PacketType::Invalid;
+ } else if (total_length > 0) {
+
+ // We have a valid packet...
+ assert(content_length <= m_bytes.size());
+ assert(total_length <= m_bytes.size());
+ assert(content_length <= total_length);
+ size_t content_end = content_start + content_length;
+
+ bool success = true;
+ std::string &packet_str = packet.GetStringRef();
+ if (log) {
+ // If logging was just enabled and we have history, then dump out what
+ // we have to the log so we get the historical context. The Dump() call
+ // that
+ // logs all of the packet will set a boolean so that we don't dump this
+ // more
+ // than once
+ if (!m_history.DidDumpToLog())
+ m_history.Dump(log);
+
+ bool binary = false;
+ // Only detect binary for packets that start with a '$' and have a '#CC'
+ // checksum
+ if (m_bytes[0] == '$' && total_length > 4) {
+ for (size_t i = 0; !binary && i < total_length; ++i) {
+ if (isprint(m_bytes[i]) == 0 && isspace(m_bytes[i]) == 0) {
+ binary = true;
}
-
- m_history.AddPacket (m_bytes.c_str(), total_length, History::ePacketTypeRecv, total_length);
-
- // Clear packet_str in case there is some existing data in it.
- packet_str.clear();
- // Copy the packet from m_bytes to packet_str expanding the
- // run-length encoding in the process.
- // Reserve enough byte for the most common case (no RLE used)
- packet_str.reserve(m_bytes.length());
- for (std::string::const_iterator c = m_bytes.begin() + content_start; c != m_bytes.begin() + content_end; ++c)
- {
- if (*c == '*')
- {
- // '*' indicates RLE. Next character will give us the
- // repeat count and previous character is what is to be
- // repeated.
- char char_to_repeat = packet_str.back();
- // Number of time the previous character is repeated
- int repeat_count = *++c + 3 - ' ';
- // We have the char_to_repeat and repeat_count. Now push
- // it in the packet.
- for (int i = 0; i < repeat_count; ++i)
- packet_str.push_back(char_to_repeat);
- }
- else if (*c == 0x7d)
- {
- // 0x7d is the escape character. The next character is to
- // be XOR'd with 0x20.
- char escapee = *++c ^ 0x20;
- packet_str.push_back(escapee);
- }
- else
- {
- packet_str.push_back(*c);
- }
+ }
+ }
+ if (binary) {
+ StreamString strm;
+ // Packet header...
+ if (CompressionIsEnabled())
+ strm.Printf("<%4" PRIu64 ":%" PRIu64 "> read packet: %c",
+ (uint64_t)original_packet_size, (uint64_t)total_length,
+ m_bytes[0]);
+ else
+ strm.Printf("<%4" PRIu64 "> read packet: %c",
+ (uint64_t)total_length, m_bytes[0]);
+ for (size_t i = content_start; i < content_end; ++i) {
+ // Remove binary escaped bytes when displaying the packet...
+ const char ch = m_bytes[i];
+ if (ch == 0x7d) {
+ // 0x7d is the escape character. The next character is to
+ // be XOR'd with 0x20.
+ const char escapee = m_bytes[++i] ^ 0x20;
+ strm.Printf("%2.2x", escapee);
+ } else {
+ strm.Printf("%2.2x", (uint8_t)ch);
}
-
- if (m_bytes[0] == '$' || m_bytes[0] == '%')
- {
- assert (checksum_idx < m_bytes.size());
- if (::isxdigit (m_bytes[checksum_idx+0]) ||
- ::isxdigit (m_bytes[checksum_idx+1]))
- {
- if (GetSendAcks ())
- {
- const char *packet_checksum_cstr = &m_bytes[checksum_idx];
- char packet_checksum = strtol (packet_checksum_cstr, NULL, 16);
- char actual_checksum = CalculcateChecksum (packet_str.c_str(), packet_str.size());
- success = packet_checksum == actual_checksum;
- if (!success)
- {
- if (log)
- log->Printf ("error: checksum mismatch: %.*s expected 0x%2.2x, got 0x%2.2x",
- (int)(total_length),
- m_bytes.c_str(),
- (uint8_t)packet_checksum,
- (uint8_t)actual_checksum);
- }
- // Send the ack or nack if needed
- if (!success)
- SendNack();
- else
- SendAck();
- }
- }
- else
- {
- success = false;
- if (log)
- log->Printf ("error: invalid checksum in packet: '%s'\n", m_bytes.c_str());
- }
+ }
+ // Packet footer...
+ strm.Printf("%c%c%c", m_bytes[total_length - 3],
+ m_bytes[total_length - 2], m_bytes[total_length - 1]);
+ log->PutString(strm.GetString());
+ } else {
+ if (CompressionIsEnabled())
+ log->Printf("<%4" PRIu64 ":%" PRIu64 "> read packet: %.*s",
+ (uint64_t)original_packet_size, (uint64_t)total_length,
+ (int)(total_length), m_bytes.c_str());
+ else
+ log->Printf("<%4" PRIu64 "> read packet: %.*s",
+ (uint64_t)total_length, (int)(total_length),
+ m_bytes.c_str());
+ }
+ }
+
+ m_history.AddPacket(m_bytes, total_length, History::ePacketTypeRecv,
+ total_length);
+
+ // Clear packet_str in case there is some existing data in it.
+ packet_str.clear();
+ // Copy the packet from m_bytes to packet_str expanding the
+ // run-length encoding in the process.
+ // Reserve enough byte for the most common case (no RLE used)
+ packet_str.reserve(m_bytes.length());
+ for (std::string::const_iterator c = m_bytes.begin() + content_start;
+ c != m_bytes.begin() + content_end; ++c) {
+ if (*c == '*') {
+ // '*' indicates RLE. Next character will give us the
+ // repeat count and previous character is what is to be
+ // repeated.
+ char char_to_repeat = packet_str.back();
+ // Number of time the previous character is repeated
+ int repeat_count = *++c + 3 - ' ';
+ // We have the char_to_repeat and repeat_count. Now push
+ // it in the packet.
+ for (int i = 0; i < repeat_count; ++i)
+ packet_str.push_back(char_to_repeat);
+ } else if (*c == 0x7d) {
+ // 0x7d is the escape character. The next character is to
+ // be XOR'd with 0x20.
+ char escapee = *++c ^ 0x20;
+ packet_str.push_back(escapee);
+ } else {
+ packet_str.push_back(*c);
+ }
+ }
+
+ if (m_bytes[0] == '$' || m_bytes[0] == '%') {
+ assert(checksum_idx < m_bytes.size());
+ if (::isxdigit(m_bytes[checksum_idx + 0]) ||
+ ::isxdigit(m_bytes[checksum_idx + 1])) {
+ if (GetSendAcks()) {
+ const char *packet_checksum_cstr = &m_bytes[checksum_idx];
+ char packet_checksum = strtol(packet_checksum_cstr, NULL, 16);
+ char actual_checksum = CalculcateChecksum(packet_str);
+ success = packet_checksum == actual_checksum;
+ if (!success) {
+ if (log)
+ log->Printf("error: checksum mismatch: %.*s expected 0x%2.2x, "
+ "got 0x%2.2x",
+ (int)(total_length), m_bytes.c_str(),
+ (uint8_t)packet_checksum, (uint8_t)actual_checksum);
}
-
- m_bytes.erase(0, total_length);
- packet.SetFilePos(0);
-
- if (isNotifyPacket)
- return GDBRemoteCommunication::PacketType::Notify;
+ // Send the ack or nack if needed
+ if (!success)
+ SendNack();
else
- return GDBRemoteCommunication::PacketType::Standard;
+ SendAck();
+ }
+ } else {
+ success = false;
+ if (log)
+ log->Printf("error: invalid checksum in packet: '%s'\n",
+ m_bytes.c_str());
}
+ }
+
+ m_bytes.erase(0, total_length);
+ packet.SetFilePos(0);
+
+ if (isNotifyPacket)
+ return GDBRemoteCommunication::PacketType::Notify;
+ else
+ return GDBRemoteCommunication::PacketType::Standard;
}
- packet.Clear();
- return GDBRemoteCommunication::PacketType::Invalid;
+ }
+ packet.Clear();
+ return GDBRemoteCommunication::PacketType::Invalid;
}
-Error
-GDBRemoteCommunication::StartListenThread (const char *hostname, uint16_t port)
-{
- Error error;
- if (m_listen_thread.IsJoinable())
- {
- error.SetErrorString("listen thread already running");
- }
+Error GDBRemoteCommunication::StartListenThread(const char *hostname,
+ uint16_t port) {
+ Error error;
+ if (m_listen_thread.IsJoinable()) {
+ error.SetErrorString("listen thread already running");
+ } else {
+ char listen_url[512];
+ if (hostname && hostname[0])
+ snprintf(listen_url, sizeof(listen_url), "listen://%s:%i", hostname,
+ port);
else
- {
- char listen_url[512];
- if (hostname && hostname[0])
- snprintf(listen_url, sizeof(listen_url), "listen://%s:%i", hostname, port);
- else
- snprintf(listen_url, sizeof(listen_url), "listen://%i", port);
- m_listen_url = listen_url;
- SetConnection(new ConnectionFileDescriptor());
- m_listen_thread = ThreadLauncher::LaunchThread(listen_url, GDBRemoteCommunication::ListenThread, this, &error);
- }
- return error;
+ snprintf(listen_url, sizeof(listen_url), "listen://%i", port);
+ m_listen_url = listen_url;
+ SetConnection(new ConnectionFileDescriptor());
+ m_listen_thread = ThreadLauncher::LaunchThread(
+ listen_url, GDBRemoteCommunication::ListenThread, this, &error);
+ }
+ return error;
}
-bool
-GDBRemoteCommunication::JoinListenThread ()
-{
- if (m_listen_thread.IsJoinable())
- m_listen_thread.Join(nullptr);
- return true;
+bool GDBRemoteCommunication::JoinListenThread() {
+ if (m_listen_thread.IsJoinable())
+ m_listen_thread.Join(nullptr);
+ return true;
}
lldb::thread_result_t
-GDBRemoteCommunication::ListenThread (lldb::thread_arg_t arg)
-{
- GDBRemoteCommunication *comm = (GDBRemoteCommunication *)arg;
- Error error;
- ConnectionFileDescriptor *connection = (ConnectionFileDescriptor *)comm->GetConnection ();
-
- if (connection)
- {
- // Do the listen on another thread so we can continue on...
- if (connection->Connect(comm->m_listen_url.c_str(), &error) != eConnectionStatusSuccess)
- comm->SetConnection(NULL);
- }
- return NULL;
+GDBRemoteCommunication::ListenThread(lldb::thread_arg_t arg) {
+ GDBRemoteCommunication *comm = (GDBRemoteCommunication *)arg;
+ Error error;
+ ConnectionFileDescriptor *connection =
+ (ConnectionFileDescriptor *)comm->GetConnection();
+
+ if (connection) {
+ // Do the listen on another thread so we can continue on...
+ if (connection->Connect(comm->m_listen_url.c_str(), &error) !=
+ eConnectionStatusSuccess)
+ comm->SetConnection(NULL);
+ }
+ return NULL;
}
-Error
-GDBRemoteCommunication::StartDebugserverProcess (const char *url,
- Platform *platform,
- ProcessLaunchInfo &launch_info,
- uint16_t *port,
- const Args& inferior_args)
-{
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
+Error GDBRemoteCommunication::StartDebugserverProcess(
+ const char *url, Platform *platform, ProcessLaunchInfo &launch_info,
+ uint16_t *port, const Args *inferior_args, int pass_comm_fd) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ if (log)
+ log->Printf("GDBRemoteCommunication::%s(url=%s, port=%" PRIu16 ")",
+ __FUNCTION__, url ? url : "<empty>",
+ port ? *port : uint16_t(0));
+
+ Error error;
+ // If we locate debugserver, keep that located version around
+ static FileSpec g_debugserver_file_spec;
+
+ char debugserver_path[PATH_MAX];
+ FileSpec &debugserver_file_spec = launch_info.GetExecutableFile();
+
+ // Always check to see if we have an environment override for the path
+ // to the debugserver to use and use it if we do.
+ const char *env_debugserver_path = getenv("LLDB_DEBUGSERVER_PATH");
+ if (env_debugserver_path) {
+ debugserver_file_spec.SetFile(env_debugserver_path, false);
if (log)
- log->Printf ("GDBRemoteCommunication::%s(url=%s, port=%" PRIu16 ")", __FUNCTION__, url ? url : "<empty>", port ? *port : uint16_t(0));
-
- Error error;
- // If we locate debugserver, keep that located version around
- static FileSpec g_debugserver_file_spec;
-
- char debugserver_path[PATH_MAX];
- FileSpec &debugserver_file_spec = launch_info.GetExecutableFile();
-
- // Always check to see if we have an environment override for the path
- // to the debugserver to use and use it if we do.
- const char *env_debugserver_path = getenv("LLDB_DEBUGSERVER_PATH");
- if (env_debugserver_path)
- {
- debugserver_file_spec.SetFile (env_debugserver_path, false);
+ log->Printf("GDBRemoteCommunication::%s() gdb-remote stub exe path set "
+ "from environment variable: %s",
+ __FUNCTION__, env_debugserver_path);
+ } else
+ debugserver_file_spec = g_debugserver_file_spec;
+ bool debugserver_exists = debugserver_file_spec.Exists();
+ if (!debugserver_exists) {
+ // The debugserver binary is in the LLDB.framework/Resources
+ // directory.
+ if (HostInfo::GetLLDBPath(ePathTypeSupportExecutableDir,
+ debugserver_file_spec)) {
+ debugserver_file_spec.AppendPathComponent(DEBUGSERVER_BASENAME);
+ debugserver_exists = debugserver_file_spec.Exists();
+ if (debugserver_exists) {
if (log)
- log->Printf ("GDBRemoteCommunication::%s() gdb-remote stub exe path set from environment variable: %s", __FUNCTION__, env_debugserver_path);
- }
- else
- debugserver_file_spec = g_debugserver_file_spec;
- bool debugserver_exists = debugserver_file_spec.Exists();
- if (!debugserver_exists)
- {
- // The debugserver binary is in the LLDB.framework/Resources
- // directory.
- if (HostInfo::GetLLDBPath(ePathTypeSupportExecutableDir, debugserver_file_spec))
- {
- debugserver_file_spec.AppendPathComponent (DEBUGSERVER_BASENAME);
- debugserver_exists = debugserver_file_spec.Exists();
- if (debugserver_exists)
- {
- if (log)
- log->Printf ("GDBRemoteCommunication::%s() found gdb-remote stub exe '%s'", __FUNCTION__, debugserver_file_spec.GetPath ().c_str ());
-
- g_debugserver_file_spec = debugserver_file_spec;
- }
- else
- {
- debugserver_file_spec = platform->LocateExecutable(DEBUGSERVER_BASENAME);
- if (debugserver_file_spec)
- {
- // Platform::LocateExecutable() wouldn't return a path if it doesn't exist
- debugserver_exists = true;
- }
- else
- {
- if (log)
- log->Printf ("GDBRemoteCommunication::%s() could not find gdb-remote stub exe '%s'", __FUNCTION__, debugserver_file_spec.GetPath ().c_str ());
- }
- // Don't cache the platform specific GDB server binary as it could change
- // from platform to platform
- g_debugserver_file_spec.Clear();
- }
+ log->Printf(
+ "GDBRemoteCommunication::%s() found gdb-remote stub exe '%s'",
+ __FUNCTION__, debugserver_file_spec.GetPath().c_str());
+
+ g_debugserver_file_spec = debugserver_file_spec;
+ } else {
+ debugserver_file_spec =
+ platform->LocateExecutable(DEBUGSERVER_BASENAME);
+ if (debugserver_file_spec) {
+ // Platform::LocateExecutable() wouldn't return a path if it doesn't
+ // exist
+ debugserver_exists = true;
+ } else {
+ if (log)
+ log->Printf("GDBRemoteCommunication::%s() could not find "
+ "gdb-remote stub exe '%s'",
+ __FUNCTION__, debugserver_file_spec.GetPath().c_str());
}
+ // Don't cache the platform specific GDB server binary as it could
+ // change
+ // from platform to platform
+ g_debugserver_file_spec.Clear();
+ }
}
-
- if (debugserver_exists)
- {
- debugserver_file_spec.GetPath (debugserver_path, sizeof(debugserver_path));
+ }
+
+ if (debugserver_exists) {
+ debugserver_file_spec.GetPath(debugserver_path, sizeof(debugserver_path));
- Args &debugserver_args = launch_info.GetArguments();
- debugserver_args.Clear();
- char arg_cstr[PATH_MAX];
+ Args &debugserver_args = launch_info.GetArguments();
+ debugserver_args.Clear();
+ char arg_cstr[PATH_MAX];
- // Start args with "debugserver /file/path -r --"
- debugserver_args.AppendArgument(debugserver_path);
+ // Start args with "debugserver /file/path -r --"
+ debugserver_args.AppendArgument(llvm::StringRef(debugserver_path));
#if !defined(__APPLE__)
- // First argument to lldb-server must be mode in which to run.
- debugserver_args.AppendArgument("gdbserver");
+ // First argument to lldb-server must be mode in which to run.
+ debugserver_args.AppendArgument(llvm::StringRef("gdbserver"));
#endif
- // If a url is supplied then use it
- if (url)
- debugserver_args.AppendArgument(url);
+ // If a url is supplied then use it
+ if (url)
+ debugserver_args.AppendArgument(llvm::StringRef(url));
+
+ if (pass_comm_fd >= 0) {
+ StreamString fd_arg;
+ fd_arg.Printf("--fd=%i", pass_comm_fd);
+ debugserver_args.AppendArgument(fd_arg.GetString());
+ // Send "pass_comm_fd" down to the inferior so it can use it to
+ // communicate back with this process
+ launch_info.AppendDuplicateFileAction(pass_comm_fd, pass_comm_fd);
+ }
- // use native registers, not the GDB registers
- debugserver_args.AppendArgument("--native-regs");
+ // use native registers, not the GDB registers
+ debugserver_args.AppendArgument(llvm::StringRef("--native-regs"));
- if (launch_info.GetLaunchInSeparateProcessGroup())
- {
- debugserver_args.AppendArgument("--setsid");
- }
+ if (launch_info.GetLaunchInSeparateProcessGroup()) {
+ debugserver_args.AppendArgument(llvm::StringRef("--setsid"));
+ }
- llvm::SmallString<PATH_MAX> named_pipe_path;
- // socket_pipe is used by debug server to communicate back either
- // TCP port or domain socket name which it listens on.
- // The second purpose of the pipe to serve as a synchronization point -
- // once data is written to the pipe, debug server is up and running.
- Pipe socket_pipe;
-
- // port is null when debug server should listen on domain socket -
- // we're not interested in port value but rather waiting for debug server
- // to become available.
- if ((port != nullptr && *port == 0) || port == nullptr)
- {
- if (url)
- {
- // Create a temporary file to get the stdout/stderr and redirect the
- // output of the command into this file. We will later read this file
- // if all goes well and fill the data into "command_output_ptr"
-
-#if defined(__APPLE__)
- // Binding to port zero, we need to figure out what port it ends up
- // using using a named pipe...
- error = socket_pipe.CreateWithUniqueName("debugserver-named-pipe", false, named_pipe_path);
- if (error.Fail())
- {
- if (log)
- log->Printf("GDBRemoteCommunication::%s() "
- "named pipe creation failed: %s",
- __FUNCTION__, error.AsCString());
- return error;
- }
- debugserver_args.AppendArgument("--named-pipe");
- debugserver_args.AppendArgument(named_pipe_path.c_str());
-#else
- // Binding to port zero, we need to figure out what port it ends up
- // using using an unnamed pipe...
- error = socket_pipe.CreateNew(true);
- if (error.Fail())
- {
- if (log)
- log->Printf("GDBRemoteCommunication::%s() "
- "unnamed pipe creation failed: %s",
- __FUNCTION__, error.AsCString());
- return error;
- }
- int write_fd = socket_pipe.GetWriteFileDescriptor();
- debugserver_args.AppendArgument("--pipe");
- debugserver_args.AppendArgument(std::to_string(write_fd).c_str());
- launch_info.AppendCloseFileAction(socket_pipe.GetReadFileDescriptor());
-#endif
- }
- else
- {
- // No host and port given, so lets listen on our end and make the debugserver
- // connect to us..
- error = StartListenThread ("127.0.0.1", 0);
- if (error.Fail())
- {
- if (log)
- log->Printf ("GDBRemoteCommunication::%s() unable to start listen thread: %s", __FUNCTION__, error.AsCString());
- return error;
- }
-
- ConnectionFileDescriptor *connection = (ConnectionFileDescriptor *)GetConnection ();
- // Wait for 10 seconds to resolve the bound port
- *port = connection->GetListeningPort(10);
- if (*port > 0)
- {
- char port_cstr[32];
- snprintf(port_cstr, sizeof(port_cstr), "127.0.0.1:%i", *port);
- // Send the host and port down that debugserver and specify an option
- // so that it connects back to the port we are listening to in this process
- debugserver_args.AppendArgument("--reverse-connect");
- debugserver_args.AppendArgument(port_cstr);
- }
- else
- {
- error.SetErrorString ("failed to bind to port 0 on 127.0.0.1");
- if (log)
- log->Printf ("GDBRemoteCommunication::%s() failed: %s", __FUNCTION__, error.AsCString());
- return error;
- }
- }
- }
-
- const char *env_debugserver_log_file = getenv("LLDB_DEBUGSERVER_LOG_FILE");
- if (env_debugserver_log_file)
- {
- ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-file=%s", env_debugserver_log_file);
- debugserver_args.AppendArgument(arg_cstr);
- }
-
+ llvm::SmallString<PATH_MAX> named_pipe_path;
+ // socket_pipe is used by debug server to communicate back either
+ // TCP port or domain socket name which it listens on.
+ // The second purpose of the pipe to serve as a synchronization point -
+ // once data is written to the pipe, debug server is up and running.
+ Pipe socket_pipe;
+
+ // port is null when debug server should listen on domain socket -
+ // we're not interested in port value but rather waiting for debug server
+ // to become available.
+ if (pass_comm_fd == -1 &&
+ ((port != nullptr && *port == 0) || port == nullptr)) {
+ if (url) {
+// Create a temporary file to get the stdout/stderr and redirect the
+// output of the command into this file. We will later read this file
+// if all goes well and fill the data into "command_output_ptr"
#if defined(__APPLE__)
- const char *env_debugserver_log_flags = getenv("LLDB_DEBUGSERVER_LOG_FLAGS");
- if (env_debugserver_log_flags)
- {
- ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-flags=%s", env_debugserver_log_flags);
- debugserver_args.AppendArgument(arg_cstr);
+ // Binding to port zero, we need to figure out what port it ends up
+ // using using a named pipe...
+ error = socket_pipe.CreateWithUniqueName("debugserver-named-pipe",
+ false, named_pipe_path);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("GDBRemoteCommunication::%s() "
+ "named pipe creation failed: %s",
+ __FUNCTION__, error.AsCString());
+ return error;
}
+ debugserver_args.AppendArgument(llvm::StringRef("--named-pipe"));
+ debugserver_args.AppendArgument(named_pipe_path);
#else
- const char *env_debugserver_log_channels = getenv("LLDB_SERVER_LOG_CHANNELS");
- if (env_debugserver_log_channels)
- {
- ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-channels=%s", env_debugserver_log_channels);
- debugserver_args.AppendArgument(arg_cstr);
+ // Binding to port zero, we need to figure out what port it ends up
+ // using using an unnamed pipe...
+ error = socket_pipe.CreateNew(true);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("GDBRemoteCommunication::%s() "
+ "unnamed pipe creation failed: %s",
+ __FUNCTION__, error.AsCString());
+ return error;
}
+ int write_fd = socket_pipe.GetWriteFileDescriptor();
+ debugserver_args.AppendArgument(llvm::StringRef("--pipe"));
+ debugserver_args.AppendArgument(llvm::to_string(write_fd));
+ launch_info.AppendCloseFileAction(socket_pipe.GetReadFileDescriptor());
#endif
-
- // Add additional args, starting with LLDB_DEBUGSERVER_EXTRA_ARG_1 until an env var doesn't come back.
- uint32_t env_var_index = 1;
- bool has_env_var;
- do
- {
- char env_var_name[64];
- snprintf (env_var_name, sizeof (env_var_name), "LLDB_DEBUGSERVER_EXTRA_ARG_%" PRIu32, env_var_index++);
- const char *extra_arg = getenv(env_var_name);
- has_env_var = extra_arg != nullptr;
-
- if (has_env_var)
- {
- debugserver_args.AppendArgument (extra_arg);
- if (log)
- log->Printf ("GDBRemoteCommunication::%s adding env var %s contents to stub command line (%s)", __FUNCTION__, env_var_name, extra_arg);
- }
- } while (has_env_var);
-
- if (inferior_args.GetArgumentCount() > 0)
- {
- debugserver_args.AppendArgument ("--");
- debugserver_args.AppendArguments (inferior_args);
+ } else {
+ // No host and port given, so lets listen on our end and make the
+ // debugserver
+ // connect to us..
+ error = StartListenThread("127.0.0.1", 0);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("GDBRemoteCommunication::%s() unable to start listen "
+ "thread: %s",
+ __FUNCTION__, error.AsCString());
+ return error;
}
- // Copy the current environment to the gdbserver/debugserver instance
- StringList env;
- if (Host::GetEnvironment(env))
- {
- for (size_t i = 0; i < env.GetSize(); ++i)
- launch_info.GetEnvironmentEntries().AppendArgument(env[i].c_str());
+ ConnectionFileDescriptor *connection =
+ (ConnectionFileDescriptor *)GetConnection();
+ // Wait for 10 seconds to resolve the bound port
+ uint16_t port_ = connection->GetListeningPort(10);
+ if (port_ > 0) {
+ char port_cstr[32];
+ snprintf(port_cstr, sizeof(port_cstr), "127.0.0.1:%i", port_);
+ // Send the host and port down that debugserver and specify an option
+ // so that it connects back to the port we are listening to in this
+ // process
+ debugserver_args.AppendArgument(llvm::StringRef("--reverse-connect"));
+ debugserver_args.AppendArgument(llvm::StringRef(port_cstr));
+ if (port)
+ *port = port_;
+ } else {
+ error.SetErrorString("failed to bind to port 0 on 127.0.0.1");
+ if (log)
+ log->Printf("GDBRemoteCommunication::%s() failed: %s", __FUNCTION__,
+ error.AsCString());
+ return error;
}
+ }
+ }
- // Close STDIN, STDOUT and STDERR.
- launch_info.AppendCloseFileAction (STDIN_FILENO);
- launch_info.AppendCloseFileAction (STDOUT_FILENO);
- launch_info.AppendCloseFileAction (STDERR_FILENO);
+ const char *env_debugserver_log_file = getenv("LLDB_DEBUGSERVER_LOG_FILE");
+ if (env_debugserver_log_file) {
+ ::snprintf(arg_cstr, sizeof(arg_cstr), "--log-file=%s",
+ env_debugserver_log_file);
+ debugserver_args.AppendArgument(llvm::StringRef(arg_cstr));
+ }
- // Redirect STDIN, STDOUT and STDERR to "/dev/null".
- launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false);
- launch_info.AppendSuppressFileAction (STDOUT_FILENO, false, true);
- launch_info.AppendSuppressFileAction (STDERR_FILENO, false, true);
+#if defined(__APPLE__)
+ const char *env_debugserver_log_flags =
+ getenv("LLDB_DEBUGSERVER_LOG_FLAGS");
+ if (env_debugserver_log_flags) {
+ ::snprintf(arg_cstr, sizeof(arg_cstr), "--log-flags=%s",
+ env_debugserver_log_flags);
+ debugserver_args.AppendArgument(llvm::StringRef(arg_cstr));
+ }
+#else
+ const char *env_debugserver_log_channels =
+ getenv("LLDB_SERVER_LOG_CHANNELS");
+ if (env_debugserver_log_channels) {
+ ::snprintf(arg_cstr, sizeof(arg_cstr), "--log-channels=%s",
+ env_debugserver_log_channels);
+ debugserver_args.AppendArgument(llvm::StringRef(arg_cstr));
+ }
+#endif
+ // Add additional args, starting with LLDB_DEBUGSERVER_EXTRA_ARG_1 until an
+ // env var doesn't come back.
+ uint32_t env_var_index = 1;
+ bool has_env_var;
+ do {
+ char env_var_name[64];
+ snprintf(env_var_name, sizeof(env_var_name),
+ "LLDB_DEBUGSERVER_EXTRA_ARG_%" PRIu32, env_var_index++);
+ const char *extra_arg = getenv(env_var_name);
+ has_env_var = extra_arg != nullptr;
+
+ if (has_env_var) {
+ debugserver_args.AppendArgument(llvm::StringRef(extra_arg));
if (log)
- {
- StreamString string_stream;
- Platform *const platform = nullptr;
- launch_info.Dump(string_stream, platform);
- log->Printf("launch info for gdb-remote stub:\n%s", string_stream.GetString().c_str());
- }
- error = Host::LaunchProcess(launch_info);
-
- if (error.Success() &&
- launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
- {
- if (named_pipe_path.size() > 0)
- {
- error = socket_pipe.OpenAsReader(named_pipe_path, false);
- if (error.Fail())
- if (log)
- log->Printf("GDBRemoteCommunication::%s() "
- "failed to open named pipe %s for reading: %s",
- __FUNCTION__, named_pipe_path.c_str(), error.AsCString());
- }
-
- if (socket_pipe.CanWrite())
- socket_pipe.CloseWriteFileDescriptor();
- if (socket_pipe.CanRead())
- {
- char port_cstr[PATH_MAX] = {0};
- port_cstr[0] = '\0';
- size_t num_bytes = sizeof(port_cstr);
- // Read port from pipe with 10 second timeout.
- error = socket_pipe.ReadWithTimeout(port_cstr, num_bytes,
- std::chrono::seconds{10}, num_bytes);
- if (error.Success() && (port != nullptr))
- {
- assert(num_bytes > 0 && port_cstr[num_bytes-1] == '\0');
- *port = StringConvert::ToUInt32(port_cstr, 0);
- if (log)
- log->Printf("GDBRemoteCommunication::%s() "
- "debugserver listens %u port",
- __FUNCTION__, *port);
- }
- else
- {
- if (log)
- log->Printf("GDBRemoteCommunication::%s() "
- "failed to read a port value from pipe %s: %s",
- __FUNCTION__, named_pipe_path.c_str(), error.AsCString());
-
- }
- socket_pipe.Close();
- }
-
- if (named_pipe_path.size() > 0)
- {
- const auto err = socket_pipe.Delete(named_pipe_path);
- if (err.Fail())
- {
- if (log)
- log->Printf ("GDBRemoteCommunication::%s failed to delete pipe %s: %s",
- __FUNCTION__, named_pipe_path.c_str(), err.AsCString());
- }
- }
+ log->Printf("GDBRemoteCommunication::%s adding env var %s contents "
+ "to stub command line (%s)",
+ __FUNCTION__, env_var_name, extra_arg);
+ }
+ } while (has_env_var);
+
+ if (inferior_args && inferior_args->GetArgumentCount() > 0) {
+ debugserver_args.AppendArgument(llvm::StringRef("--"));
+ debugserver_args.AppendArguments(*inferior_args);
+ }
- // Make sure we actually connect with the debugserver...
- JoinListenThread();
- }
+ // Copy the current environment to the gdbserver/debugserver instance
+ StringList env;
+ if (Host::GetEnvironment(env)) {
+ for (size_t i = 0; i < env.GetSize(); ++i)
+ launch_info.GetEnvironmentEntries().AppendArgument(env[i]);
}
- else
- {
- error.SetErrorStringWithFormat ("unable to locate " DEBUGSERVER_BASENAME );
+
+ // Close STDIN, STDOUT and STDERR.
+ launch_info.AppendCloseFileAction(STDIN_FILENO);
+ launch_info.AppendCloseFileAction(STDOUT_FILENO);
+ launch_info.AppendCloseFileAction(STDERR_FILENO);
+
+ // Redirect STDIN, STDOUT and STDERR to "/dev/null".
+ launch_info.AppendSuppressFileAction(STDIN_FILENO, true, false);
+ launch_info.AppendSuppressFileAction(STDOUT_FILENO, false, true);
+ launch_info.AppendSuppressFileAction(STDERR_FILENO, false, true);
+
+ if (log) {
+ StreamString string_stream;
+ Platform *const platform = nullptr;
+ launch_info.Dump(string_stream, platform);
+ log->Printf("launch info for gdb-remote stub:\n%s",
+ string_stream.GetData());
}
+ error = Host::LaunchProcess(launch_info);
+
+ if (error.Success() &&
+ (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) &&
+ pass_comm_fd == -1) {
+ if (named_pipe_path.size() > 0) {
+ error = socket_pipe.OpenAsReader(named_pipe_path, false);
+ if (error.Fail())
+ if (log)
+ log->Printf("GDBRemoteCommunication::%s() "
+ "failed to open named pipe %s for reading: %s",
+ __FUNCTION__, named_pipe_path.c_str(),
+ error.AsCString());
+ }
+
+ if (socket_pipe.CanWrite())
+ socket_pipe.CloseWriteFileDescriptor();
+ if (socket_pipe.CanRead()) {
+ char port_cstr[PATH_MAX] = {0};
+ port_cstr[0] = '\0';
+ size_t num_bytes = sizeof(port_cstr);
+ // Read port from pipe with 10 second timeout.
+ error = socket_pipe.ReadWithTimeout(
+ port_cstr, num_bytes, std::chrono::seconds{10}, num_bytes);
+ if (error.Success() && (port != nullptr)) {
+ assert(num_bytes > 0 && port_cstr[num_bytes - 1] == '\0');
+ *port = StringConvert::ToUInt32(port_cstr, 0);
+ if (log)
+ log->Printf("GDBRemoteCommunication::%s() "
+ "debugserver listens %u port",
+ __FUNCTION__, *port);
+ } else {
+ if (log)
+ log->Printf("GDBRemoteCommunication::%s() "
+ "failed to read a port value from pipe %s: %s",
+ __FUNCTION__, named_pipe_path.c_str(),
+ error.AsCString());
+ }
+ socket_pipe.Close();
+ }
+
+ if (named_pipe_path.size() > 0) {
+ const auto err = socket_pipe.Delete(named_pipe_path);
+ if (err.Fail()) {
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunication::%s failed to delete pipe %s: %s",
+ __FUNCTION__, named_pipe_path.c_str(), err.AsCString());
+ }
+ }
- if (error.Fail())
- {
- if (log)
- log->Printf ("GDBRemoteCommunication::%s() failed: %s", __FUNCTION__, error.AsCString());
+ // Make sure we actually connect with the debugserver...
+ JoinListenThread();
}
+ } else {
+ error.SetErrorStringWithFormat("unable to locate " DEBUGSERVER_BASENAME);
+ }
- return error;
-}
+ if (error.Fail()) {
+ if (log)
+ log->Printf("GDBRemoteCommunication::%s() failed: %s", __FUNCTION__,
+ error.AsCString());
+ }
-void
-GDBRemoteCommunication::DumpHistory(Stream &strm)
-{
- m_history.Dump (strm);
+ return error;
}
-GDBRemoteCommunication::ScopedTimeout::ScopedTimeout (GDBRemoteCommunication& gdb_comm,
- uint32_t timeout) :
- m_gdb_comm (gdb_comm)
-{
- m_saved_timeout = m_gdb_comm.SetPacketTimeout (timeout);
+void GDBRemoteCommunication::DumpHistory(Stream &strm) { m_history.Dump(strm); }
+
+GDBRemoteCommunication::ScopedTimeout::ScopedTimeout(
+ GDBRemoteCommunication &gdb_comm, std::chrono::seconds timeout)
+ : m_gdb_comm(gdb_comm) {
+ m_saved_timeout = m_gdb_comm.SetPacketTimeout(timeout);
}
-GDBRemoteCommunication::ScopedTimeout::~ScopedTimeout ()
-{
- m_gdb_comm.SetPacketTimeout (m_saved_timeout);
+GDBRemoteCommunication::ScopedTimeout::~ScopedTimeout() {
+ m_gdb_comm.SetPacketTimeout(m_saved_timeout);
}
-// This function is called via the Communications class read thread when bytes become available
-// for this connection. This function will consume all incoming bytes and try to parse whole
-// packets as they become available. Full packets are placed in a queue, so that all packet
-// requests can simply pop from this queue. Async notification packets will be dispatched
+// This function is called via the Communications class read thread when bytes
+// become available
+// for this connection. This function will consume all incoming bytes and try to
+// parse whole
+// packets as they become available. Full packets are placed in a queue, so that
+// all packet
+// requests can simply pop from this queue. Async notification packets will be
+// dispatched
// immediately to the ProcessGDBRemote Async thread via an event.
-void GDBRemoteCommunication::AppendBytesToCache (const uint8_t * bytes, size_t len, bool broadcast, lldb::ConnectionStatus status)
-{
- StringExtractorGDBRemote packet;
-
- while (true)
- {
- PacketType type = CheckForPacket(bytes, len, packet);
-
- // scrub the data so we do not pass it back to CheckForPacket
- // on future passes of the loop
- bytes = nullptr;
- len = 0;
-
- // we may have received no packet so lets bail out
- if (type == PacketType::Invalid)
- break;
-
- if (type == PacketType::Standard)
- {
- // scope for the mutex
- {
- // lock down the packet queue
- Mutex::Locker locker(m_packet_queue_mutex);
- // push a new packet into the queue
- m_packet_queue.push(packet);
- // Signal condition variable that we have a packet
- m_condition_queue_not_empty.Signal();
-
- }
- }
+void GDBRemoteCommunication::AppendBytesToCache(const uint8_t *bytes,
+ size_t len, bool broadcast,
+ lldb::ConnectionStatus status) {
+ StringExtractorGDBRemote packet;
+
+ while (true) {
+ PacketType type = CheckForPacket(bytes, len, packet);
+
+ // scrub the data so we do not pass it back to CheckForPacket
+ // on future passes of the loop
+ bytes = nullptr;
+ len = 0;
+
+ // we may have received no packet so lets bail out
+ if (type == PacketType::Invalid)
+ break;
+
+ if (type == PacketType::Standard) {
+ // scope for the mutex
+ {
+ // lock down the packet queue
+ std::lock_guard<std::mutex> guard(m_packet_queue_mutex);
+ // push a new packet into the queue
+ m_packet_queue.push(packet);
+ // Signal condition variable that we have a packet
+ m_condition_queue_not_empty.notify_one();
+ }
+ }
- if (type == PacketType::Notify)
- {
- // put this packet into an event
- const char *pdata = packet.GetStringRef().c_str();
+ if (type == PacketType::Notify) {
+ // put this packet into an event
+ const char *pdata = packet.GetStringRef().c_str();
- // as the communication class, we are a broadcaster and the
- // async thread is tuned to listen to us
- BroadcastEvent(
- eBroadcastBitGdbReadThreadGotNotify,
- new EventDataBytes(pdata));
- }
+ // as the communication class, we are a broadcaster and the
+ // async thread is tuned to listen to us
+ BroadcastEvent(eBroadcastBitGdbReadThreadGotNotify,
+ new EventDataBytes(pdata));
}
+ }
}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
index 2a01bcec260c..1f3fa17cfc26 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -12,365 +12,275 @@
// C Includes
// C++ Includes
-#include <string>
+#include <condition_variable>
+#include <mutex>
#include <queue>
+#include <string>
#include <vector>
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-public.h"
#include "lldb/Core/Communication.h"
#include "lldb/Core/Listener.h"
#include "lldb/Host/HostThread.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Host/Predicate.h"
-#include "lldb/Host/TimeValue.h"
#include "lldb/Interpreter/Args.h"
+#include "lldb/lldb-public.h"
#include "Utility/StringExtractorGDBRemote.h"
namespace lldb_private {
namespace process_gdb_remote {
-typedef enum
-{
- eStoppointInvalid = -1,
- eBreakpointSoftware = 0,
- eBreakpointHardware,
- eWatchpointWrite,
- eWatchpointRead,
- eWatchpointReadWrite
+typedef enum {
+ eStoppointInvalid = -1,
+ eBreakpointSoftware = 0,
+ eBreakpointHardware,
+ eWatchpointWrite,
+ eWatchpointRead,
+ eWatchpointReadWrite
} GDBStoppointType;
-enum class CompressionType
-{
- None = 0, // no compression
- ZlibDeflate, // zlib's deflate compression scheme, requires zlib or Apple's libcompression
- LZFSE, // an Apple compression scheme, requires Apple's libcompression
- LZ4, // lz compression - called "lz4 raw" in libcompression terms, compat with https://code.google.com/p/lz4/
- LZMA, // Lempel–Ziv–Markov chain algorithm
+enum class CompressionType {
+ None = 0, // no compression
+ ZlibDeflate, // zlib's deflate compression scheme, requires zlib or Apple's
+ // libcompression
+ LZFSE, // an Apple compression scheme, requires Apple's libcompression
+ LZ4, // lz compression - called "lz4 raw" in libcompression terms, compat with
+ // https://code.google.com/p/lz4/
+ LZMA, // Lempel–Ziv–Markov chain algorithm
};
class ProcessGDBRemote;
-class GDBRemoteCommunication : public Communication
-{
+class GDBRemoteCommunication : public Communication {
public:
- enum
- {
- eBroadcastBitRunPacketSent = kLoUserBroadcastBit,
- eBroadcastBitGdbReadThreadGotNotify = kLoUserBroadcastBit << 1 // Sent when we received a notify packet.
- };
+ enum {
+ eBroadcastBitRunPacketSent = kLoUserBroadcastBit,
+ eBroadcastBitGdbReadThreadGotNotify =
+ kLoUserBroadcastBit << 1 // Sent when we received a notify packet.
+ };
+
+ enum class PacketType { Invalid = 0, Standard, Notify };
+
+ enum class PacketResult {
+ Success = 0, // Success
+ ErrorSendFailed, // Error sending the packet
+ ErrorSendAck, // Didn't get an ack back after sending a packet
+ ErrorReplyFailed, // Error getting the reply
+ ErrorReplyTimeout, // Timed out waiting for reply
+ ErrorReplyInvalid, // Got a reply but it wasn't valid for the packet that
+ // was sent
+ ErrorReplyAck, // Sending reply ack failed
+ ErrorDisconnected, // We were disconnected
+ ErrorNoSequenceLock // We couldn't get the sequence lock for a multi-packet
+ // request
+ };
+
+ // Class to change the timeout for a given scope and restore it to the
+ // original value when the
+ // created ScopedTimeout object got out of scope
+ class ScopedTimeout {
+ public:
+ ScopedTimeout(GDBRemoteCommunication &gdb_comm,
+ std::chrono::seconds timeout);
+ ~ScopedTimeout();
+
+ private:
+ GDBRemoteCommunication &m_gdb_comm;
+ std::chrono::seconds m_saved_timeout;
+ };
+
+ GDBRemoteCommunication(const char *comm_name, const char *listener_name);
+
+ ~GDBRemoteCommunication() override;
+
+ PacketResult GetAck();
+
+ size_t SendAck();
+
+ size_t SendNack();
+
+ char CalculcateChecksum(llvm::StringRef payload);
+
+ PacketType CheckForPacket(const uint8_t *src, size_t src_len,
+ StringExtractorGDBRemote &packet);
+
+ bool GetSendAcks() { return m_send_acks; }
+
+ //------------------------------------------------------------------
+ // Set the global packet timeout.
+ //
+ // For clients, this is the timeout that gets used when sending
+ // packets and waiting for responses. For servers, this is used when waiting
+ // for ACKs.
+ //------------------------------------------------------------------
+ std::chrono::seconds SetPacketTimeout(std::chrono::seconds packet_timeout) {
+ const auto old_packet_timeout = m_packet_timeout;
+ m_packet_timeout = packet_timeout;
+ return old_packet_timeout;
+ }
+
+ std::chrono::seconds GetPacketTimeout() const { return m_packet_timeout; }
+
+ //------------------------------------------------------------------
+ // Start a debugserver instance on the current host using the
+ // supplied connection URL.
+ //------------------------------------------------------------------
+ Error StartDebugserverProcess(
+ const char *url,
+ Platform *platform, // If non nullptr, then check with the platform for
+ // the GDB server binary if it can't be located
+ ProcessLaunchInfo &launch_info, uint16_t *port, const Args *inferior_args,
+ int pass_comm_fd); // Communication file descriptor to pass during
+ // fork/exec to avoid having to connect/accept
+
+ void DumpHistory(Stream &strm);
- enum class PacketType
- {
- Invalid = 0,
- Standard,
- Notify
- };
-
- enum class PacketResult
- {
- Success = 0, // Success
- ErrorSendFailed, // Error sending the packet
- ErrorSendAck, // Didn't get an ack back after sending a packet
- ErrorReplyFailed, // Error getting the reply
- ErrorReplyTimeout, // Timed out waiting for reply
- ErrorReplyInvalid, // Got a reply but it wasn't valid for the packet that was sent
- ErrorReplyAck, // Sending reply ack failed
- ErrorDisconnected, // We were disconnected
- ErrorNoSequenceLock // We couldn't get the sequence lock for a multi-packet request
+protected:
+ class History {
+ public:
+ enum PacketType {
+ ePacketTypeInvalid = 0,
+ ePacketTypeSend,
+ ePacketTypeRecv
};
- // Class to change the timeout for a given scope and restore it to the original value when the
- // created ScopedTimeout object got out of scope
- class ScopedTimeout
- {
- public:
- ScopedTimeout (GDBRemoteCommunication& gdb_comm, uint32_t timeout);
- ~ScopedTimeout ();
-
- private:
- GDBRemoteCommunication& m_gdb_comm;
- uint32_t m_saved_timeout;
+ struct Entry {
+ Entry()
+ : packet(), type(ePacketTypeInvalid), bytes_transmitted(0),
+ packet_idx(0), tid(LLDB_INVALID_THREAD_ID) {}
+
+ void Clear() {
+ packet.clear();
+ type = ePacketTypeInvalid;
+ bytes_transmitted = 0;
+ packet_idx = 0;
+ tid = LLDB_INVALID_THREAD_ID;
+ }
+ std::string packet;
+ PacketType type;
+ uint32_t bytes_transmitted;
+ uint32_t packet_idx;
+ lldb::tid_t tid;
};
- GDBRemoteCommunication(const char *comm_name,
- const char *listener_name);
-
- ~GDBRemoteCommunication() override;
-
- PacketResult
- GetAck ();
-
- size_t
- SendAck ();
+ History(uint32_t size);
- size_t
- SendNack ();
+ ~History();
- char
- CalculcateChecksum (const char *payload,
- size_t payload_length);
+ // For single char packets for ack, nack and /x03
+ void AddPacket(char packet_char, PacketType type,
+ uint32_t bytes_transmitted);
- bool
- GetSequenceMutex(Mutex::Locker& locker, const char *failure_message = nullptr);
+ void AddPacket(const std::string &src, uint32_t src_len, PacketType type,
+ uint32_t bytes_transmitted);
- PacketType
- CheckForPacket (const uint8_t *src,
- size_t src_len,
- StringExtractorGDBRemote &packet);
+ void Dump(Stream &strm) const;
- bool
- IsRunning() const
- {
- return m_public_is_running.GetValue();
- }
+ void Dump(Log *log) const;
- bool
- GetSendAcks ()
- {
- return m_send_acks;
- }
+ bool DidDumpToLog() const { return m_dumped_to_log; }
- //------------------------------------------------------------------
- // Client and server must implement these pure virtual functions
- //------------------------------------------------------------------
- virtual bool
- GetThreadSuffixSupported () = 0;
-
- //------------------------------------------------------------------
- // Set the global packet timeout.
- //
- // For clients, this is the timeout that gets used when sending
- // packets and waiting for responses. For servers, this might not
- // get used, and if it doesn't this should be moved to the
- // GDBRemoteCommunicationClient.
- //------------------------------------------------------------------
- uint32_t
- SetPacketTimeout (uint32_t packet_timeout)
- {
- const uint32_t old_packet_timeout = m_packet_timeout;
- m_packet_timeout = packet_timeout;
- return old_packet_timeout;
+ protected:
+ uint32_t GetFirstSavedPacketIndex() const {
+ if (m_total_packet_count < m_packets.size())
+ return 0;
+ else
+ return m_curr_idx + 1;
}
- uint32_t
- GetPacketTimeoutInMicroSeconds () const
- {
- return m_packet_timeout * TimeValue::MicroSecPerSec;
+ uint32_t GetNumPacketsInHistory() const {
+ if (m_total_packet_count < m_packets.size())
+ return m_total_packet_count;
+ else
+ return (uint32_t)m_packets.size();
}
- //------------------------------------------------------------------
- // Start a debugserver instance on the current host using the
- // supplied connection URL.
- //------------------------------------------------------------------
- Error
- StartDebugserverProcess(const char *url,
- Platform *platform, // If non nullptr, then check with the platform for the GDB server binary if it can't be located
- ProcessLaunchInfo &launch_info,
- uint16_t *port,
- const Args& inferior_args = Args());
-
- void
- DumpHistory(Stream &strm);
-
-protected:
- class History
- {
- public:
- enum PacketType
- {
- ePacketTypeInvalid = 0,
- ePacketTypeSend,
- ePacketTypeRecv
- };
-
- struct Entry
- {
- Entry() :
- packet(),
- type (ePacketTypeInvalid),
- bytes_transmitted (0),
- packet_idx (0),
- tid (LLDB_INVALID_THREAD_ID)
- {
- }
-
- void
- Clear ()
- {
- packet.clear();
- type = ePacketTypeInvalid;
- bytes_transmitted = 0;
- packet_idx = 0;
- tid = LLDB_INVALID_THREAD_ID;
- }
- std::string packet;
- PacketType type;
- uint32_t bytes_transmitted;
- uint32_t packet_idx;
- lldb::tid_t tid;
- };
-
- History (uint32_t size);
-
- ~History ();
-
- // For single char packets for ack, nack and /x03
- void
- AddPacket (char packet_char,
- PacketType type,
- uint32_t bytes_transmitted);
-
- void
- AddPacket (const std::string &src,
- uint32_t src_len,
- PacketType type,
- uint32_t bytes_transmitted);
-
- void
- Dump (Stream &strm) const;
-
- void
- Dump (Log *log) const;
-
- bool
- DidDumpToLog () const
- {
- return m_dumped_to_log;
- }
-
- protected:
- uint32_t
- GetFirstSavedPacketIndex () const
- {
- if (m_total_packet_count < m_packets.size())
- return 0;
- else
- return m_curr_idx + 1;
- }
-
- uint32_t
- GetNumPacketsInHistory () const
- {
- if (m_total_packet_count < m_packets.size())
- return m_total_packet_count;
- else
- return (uint32_t)m_packets.size();
- }
-
- uint32_t
- GetNextIndex()
- {
- ++m_total_packet_count;
- const uint32_t idx = m_curr_idx;
- m_curr_idx = NormalizeIndex(idx + 1);
- return idx;
- }
-
- uint32_t
- NormalizeIndex (uint32_t i) const
- {
- return i % m_packets.size();
- }
-
- std::vector<Entry> m_packets;
- uint32_t m_curr_idx;
- uint32_t m_total_packet_count;
- mutable bool m_dumped_to_log;
- };
-
- uint32_t m_packet_timeout;
- uint32_t m_echo_number;
- LazyBool m_supports_qEcho;
-#ifdef ENABLE_MUTEX_ERROR_CHECKING
- TrackingMutex m_sequence_mutex;
-#else
- Mutex m_sequence_mutex; // Restrict access to sending/receiving packets to a single thread at a time
-#endif
- Predicate<bool> m_public_is_running;
- Predicate<bool> m_private_is_running;
- History m_history;
- bool m_send_acks;
- bool m_is_platform; // Set to true if this class represents a platform,
- // false if this class represents a debug session for
- // a single process
-
- CompressionType m_compression_type;
-
- PacketResult
- SendPacket (const char *payload,
- size_t payload_length);
-
- PacketResult
- SendPacketNoLock (const char *payload,
- size_t payload_length);
-
- PacketResult
- ReadPacket (StringExtractorGDBRemote &response, uint32_t timeout_usec, bool sync_on_timeout);
-
- // Pop a packet from the queue in a thread safe manner
- PacketResult
- PopPacketFromQueue (StringExtractorGDBRemote &response, uint32_t timeout_usec);
-
- PacketResult
- WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractorGDBRemote &response,
- uint32_t timeout_usec,
- bool sync_on_timeout);
-
- bool
- WaitForNotRunningPrivate (const TimeValue *timeout_ptr);
-
- bool
- CompressionIsEnabled ()
- {
- return m_compression_type != CompressionType::None;
+ uint32_t GetNextIndex() {
+ ++m_total_packet_count;
+ const uint32_t idx = m_curr_idx;
+ m_curr_idx = NormalizeIndex(idx + 1);
+ return idx;
}
- // If compression is enabled, decompress the packet in m_bytes and update
- // m_bytes with the uncompressed version.
- // Returns 'true' packet was decompressed and m_bytes is the now-decompressed text.
- // Returns 'false' if unable to decompress or if the checksum was invalid.
- //
- // NB: Once the packet has been decompressed, checksum cannot be computed based
- // on m_bytes. The checksum was for the compressed packet.
- bool
- DecompressPacket ();
-
- Error
- StartListenThread (const char *hostname = "127.0.0.1", uint16_t port = 0);
-
- bool
- JoinListenThread ();
-
- static lldb::thread_result_t
- ListenThread (lldb::thread_arg_t arg);
-
- // GDB-Remote read thread
- // . this thread constantly tries to read from the communication
- // class and stores all packets received in a queue. The usual
- // threads read requests simply pop packets off the queue in the
- // usual order.
- // This setup allows us to intercept and handle async packets, such
- // as the notify packet.
-
- // This method is defined as part of communication.h
- // when the read thread gets any bytes it will pass them on to this function
- void AppendBytesToCache(const uint8_t * bytes,
- size_t len,
- bool broadcast,
- lldb::ConnectionStatus status) override;
+ uint32_t NormalizeIndex(uint32_t i) const { return i % m_packets.size(); }
+
+ std::vector<Entry> m_packets;
+ uint32_t m_curr_idx;
+ uint32_t m_total_packet_count;
+ mutable bool m_dumped_to_log;
+ };
+
+ std::chrono::seconds m_packet_timeout;
+ uint32_t m_echo_number;
+ LazyBool m_supports_qEcho;
+ History m_history;
+ bool m_send_acks;
+ bool m_is_platform; // Set to true if this class represents a platform,
+ // false if this class represents a debug session for
+ // a single process
+
+ CompressionType m_compression_type;
+
+ PacketResult SendPacketNoLock(llvm::StringRef payload);
+
+ PacketResult ReadPacket(StringExtractorGDBRemote &response,
+ Timeout<std::micro> timeout, bool sync_on_timeout);
+
+ // Pop a packet from the queue in a thread safe manner
+ PacketResult PopPacketFromQueue(StringExtractorGDBRemote &response,
+ Timeout<std::micro> timeout);
+
+ PacketResult WaitForPacketNoLock(StringExtractorGDBRemote &response,
+ Timeout<std::micro> timeout,
+ bool sync_on_timeout);
+
+ bool CompressionIsEnabled() {
+ return m_compression_type != CompressionType::None;
+ }
+
+ // If compression is enabled, decompress the packet in m_bytes and update
+ // m_bytes with the uncompressed version.
+ // Returns 'true' packet was decompressed and m_bytes is the now-decompressed
+ // text.
+ // Returns 'false' if unable to decompress or if the checksum was invalid.
+ //
+ // NB: Once the packet has been decompressed, checksum cannot be computed
+ // based
+ // on m_bytes. The checksum was for the compressed packet.
+ bool DecompressPacket();
+
+ Error StartListenThread(const char *hostname = "127.0.0.1",
+ uint16_t port = 0);
+
+ bool JoinListenThread();
+
+ static lldb::thread_result_t ListenThread(lldb::thread_arg_t arg);
+
+ // GDB-Remote read thread
+ // . this thread constantly tries to read from the communication
+ // class and stores all packets received in a queue. The usual
+ // threads read requests simply pop packets off the queue in the
+ // usual order.
+ // This setup allows us to intercept and handle async packets, such
+ // as the notify packet.
+
+ // This method is defined as part of communication.h
+ // when the read thread gets any bytes it will pass them on to this function
+ void AppendBytesToCache(const uint8_t *bytes, size_t len, bool broadcast,
+ lldb::ConnectionStatus status) override;
private:
- std::queue<StringExtractorGDBRemote> m_packet_queue; // The packet queue
- lldb_private::Mutex m_packet_queue_mutex; // Mutex for accessing queue
- Condition m_condition_queue_not_empty; // Condition variable to wait for packets
+ std::queue<StringExtractorGDBRemote> m_packet_queue; // The packet queue
+ std::mutex m_packet_queue_mutex; // Mutex for accessing queue
+ std::condition_variable
+ m_condition_queue_not_empty; // Condition variable to wait for packets
- HostThread m_listen_thread;
- std::string m_listen_url;
+ HostThread m_listen_thread;
+ std::string m_listen_url;
- DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunication);
+ DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunication);
};
} // namespace process_gdb_remote
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index a792bbbd1385..f9bbaef60215 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-
#include "GDBRemoteCommunicationClient.h"
// C Includes
@@ -15,48 +14,48 @@
#include <sys/stat.h>
// C++ Includes
-#include <sstream>
#include <numeric>
+#include <sstream>
// Other libraries and framework includes
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/Triple.h"
-#include "lldb/Interpreter/Args.h"
+#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/State.h"
#include "lldb/Core/StreamGDBRemote.h"
#include "lldb/Core/StreamString.h"
-#include "lldb/Host/ConnectionFileDescriptor.h"
-#include "lldb/Host/Endian.h"
-#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/StringConvert.h"
-#include "lldb/Host/TimeValue.h"
+#include "lldb/Interpreter/Args.h"
#include "lldb/Symbol/Symbol.h"
-#include "lldb/Target/Target.h"
#include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/Target/Target.h"
#include "lldb/Target/UnixSignals.h"
+#include "lldb/Utility/JSON.h"
+#include "lldb/Utility/LLDBAssert.h"
// Project includes
-#include "Utility/StringExtractorGDBRemote.h"
#include "ProcessGDBRemote.h"
#include "ProcessGDBRemoteLog.h"
+#include "Utility/StringExtractorGDBRemote.h"
#include "lldb/Host/Config.h"
-#if defined (HAVE_LIBCOMPRESSION)
+#include "llvm/ADT/StringSwitch.h"
+
+#if defined(HAVE_LIBCOMPRESSION)
#include <compression.h>
#endif
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
+using namespace std::chrono;
//----------------------------------------------------------------------
// GDBRemoteCommunicationClient constructor
//----------------------------------------------------------------------
GDBRemoteCommunicationClient::GDBRemoteCommunicationClient()
- : GDBRemoteCommunication("gdb-remote.client", "gdb-remote.client.rx_packet"),
+ : GDBRemoteClientBase("gdb-remote.client", "gdb-remote.client.rx_packet"),
m_supports_not_sending_acks(eLazyBoolCalculate),
m_supports_thread_suffix(eLazyBoolCalculate),
m_supports_threads_in_stop_reply(eLazyBoolCalculate),
@@ -77,8 +76,7 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient()
m_watchpoints_trigger_after_instruction(eLazyBoolCalculate),
m_attach_or_wait_reply(eLazyBoolCalculate),
m_prepare_for_reg_writing_reply(eLazyBoolCalculate),
- m_supports_p(eLazyBoolCalculate),
- m_supports_x(eLazyBoolCalculate),
+ m_supports_p(eLazyBoolCalculate), m_supports_x(eLazyBoolCalculate),
m_avoid_g_packets(eLazyBoolCalculate),
m_supports_QSaveRegisterState(eLazyBoolCalculate),
m_supports_qXfer_auxv_read(eLazyBoolCalculate),
@@ -88,503 +86,449 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient()
m_supports_augmented_libraries_svr4_read(eLazyBoolCalculate),
m_supports_jThreadExtendedInfo(eLazyBoolCalculate),
m_supports_jLoadedDynamicLibrariesInfos(eLazyBoolCalculate),
- m_supports_qProcessInfoPID(true),
- m_supports_qfProcessInfo(true),
- m_supports_qUserName(true),
- m_supports_qGroupName(true),
- m_supports_qThreadStopInfo(true),
- m_supports_z0(true),
- m_supports_z1(true),
- m_supports_z2(true),
- m_supports_z3(true),
- m_supports_z4(true),
- m_supports_QEnvironment(true),
- m_supports_QEnvironmentHexEncoded(true),
- m_supports_qSymbol(true),
- m_qSymbol_requests_done(false),
- m_supports_qModuleInfo(true),
- m_supports_jThreadsInfo(true),
- m_curr_pid(LLDB_INVALID_PROCESS_ID),
- m_curr_tid(LLDB_INVALID_THREAD_ID),
+ m_supports_jGetSharedCacheInfo(eLazyBoolCalculate),
+ m_supports_qProcessInfoPID(true), m_supports_qfProcessInfo(true),
+ m_supports_qUserName(true), m_supports_qGroupName(true),
+ m_supports_qThreadStopInfo(true), m_supports_z0(true),
+ m_supports_z1(true), m_supports_z2(true), m_supports_z3(true),
+ m_supports_z4(true), m_supports_QEnvironment(true),
+ m_supports_QEnvironmentHexEncoded(true), m_supports_qSymbol(true),
+ m_qSymbol_requests_done(false), m_supports_qModuleInfo(true),
+ m_supports_jThreadsInfo(true), m_supports_jModulesInfo(true),
+ m_curr_pid(LLDB_INVALID_PROCESS_ID), m_curr_tid(LLDB_INVALID_THREAD_ID),
m_curr_tid_run(LLDB_INVALID_THREAD_ID),
- m_num_supported_hardware_watchpoints(0),
- m_async_mutex(),
- m_async_packet_predicate(false),
- m_async_packet(),
- m_async_result(PacketResult::Success),
- m_async_response(),
- m_async_signal(-1),
- m_interrupt_sent(false),
- m_thread_id_to_used_usec_map(),
- m_host_arch(),
- m_process_arch(),
- m_os_version_major(UINT32_MAX),
- m_os_version_minor(UINT32_MAX),
- m_os_version_update(UINT32_MAX),
- m_os_build(),
- m_os_kernel(),
- m_hostname(),
- m_gdb_server_name(),
- m_gdb_server_version(UINT32_MAX),
- m_default_packet_timeout(0),
- m_max_packet_size(0)
-{
-}
+ m_num_supported_hardware_watchpoints(0), m_host_arch(), m_process_arch(),
+ m_os_version_major(UINT32_MAX), m_os_version_minor(UINT32_MAX),
+ m_os_version_update(UINT32_MAX), m_os_build(), m_os_kernel(),
+ m_hostname(), m_gdb_server_name(), m_gdb_server_version(UINT32_MAX),
+ m_default_packet_timeout(0), m_max_packet_size(0),
+ m_qSupported_response(), m_supported_async_json_packets_is_valid(false),
+ m_supported_async_json_packets_sp() {}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient()
-{
- if (IsConnected())
- Disconnect();
-}
-
-bool
-GDBRemoteCommunicationClient::HandshakeWithServer (Error *error_ptr)
-{
- ResetDiscoverableSettings(false);
-
- // Start the read thread after we send the handshake ack since if we
- // fail to send the handshake ack, there is no reason to continue...
- if (SendAck())
- {
- // Wait for any responses that might have been queued up in the remote
- // GDB server and flush them all
- StringExtractorGDBRemote response;
- PacketResult packet_result = PacketResult::Success;
- const uint32_t timeout_usec = 10 * 1000; // Wait for 10 ms for a response
- while (packet_result == PacketResult::Success)
- packet_result = ReadPacket (response, timeout_usec, false);
-
- // The return value from QueryNoAckModeSupported() is true if the packet
- // was sent and _any_ response (including UNIMPLEMENTED) was received),
- // or false if no response was received. This quickly tells us if we have
- // a live connection to a remote GDB server...
- if (QueryNoAckModeSupported())
- {
- return true;
- }
- else
- {
- if (error_ptr)
- error_ptr->SetErrorString("failed to get reply to handshake packet");
- }
- }
- else
- {
- if (error_ptr)
- error_ptr->SetErrorString("failed to send the handshake ack");
- }
- return false;
+GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient() {
+ if (IsConnected())
+ Disconnect();
}
-bool
-GDBRemoteCommunicationClient::GetEchoSupported ()
-{
- if (m_supports_qEcho == eLazyBoolCalculate)
- {
- GetRemoteQSupported();
- }
- return m_supports_qEcho == eLazyBoolYes;
-}
+bool GDBRemoteCommunicationClient::HandshakeWithServer(Error *error_ptr) {
+ ResetDiscoverableSettings(false);
+ // Start the read thread after we send the handshake ack since if we
+ // fail to send the handshake ack, there is no reason to continue...
+ if (SendAck()) {
+ // Wait for any responses that might have been queued up in the remote
+ // GDB server and flush them all
+ StringExtractorGDBRemote response;
+ PacketResult packet_result = PacketResult::Success;
+ while (packet_result == PacketResult::Success)
+ packet_result = ReadPacket(response, milliseconds(10), false);
-bool
-GDBRemoteCommunicationClient::GetAugmentedLibrariesSVR4ReadSupported ()
-{
- if (m_supports_augmented_libraries_svr4_read == eLazyBoolCalculate)
- {
- GetRemoteQSupported();
+ // The return value from QueryNoAckModeSupported() is true if the packet
+ // was sent and _any_ response (including UNIMPLEMENTED) was received),
+ // or false if no response was received. This quickly tells us if we have
+ // a live connection to a remote GDB server...
+ if (QueryNoAckModeSupported()) {
+ return true;
+ } else {
+ if (error_ptr)
+ error_ptr->SetErrorString("failed to get reply to handshake packet");
}
- return m_supports_augmented_libraries_svr4_read == eLazyBoolYes;
+ } else {
+ if (error_ptr)
+ error_ptr->SetErrorString("failed to send the handshake ack");
+ }
+ return false;
}
-bool
-GDBRemoteCommunicationClient::GetQXferLibrariesSVR4ReadSupported ()
-{
- if (m_supports_qXfer_libraries_svr4_read == eLazyBoolCalculate)
- {
- GetRemoteQSupported();
- }
- return m_supports_qXfer_libraries_svr4_read == eLazyBoolYes;
+bool GDBRemoteCommunicationClient::GetEchoSupported() {
+ if (m_supports_qEcho == eLazyBoolCalculate) {
+ GetRemoteQSupported();
+ }
+ return m_supports_qEcho == eLazyBoolYes;
}
-bool
-GDBRemoteCommunicationClient::GetQXferLibrariesReadSupported ()
-{
- if (m_supports_qXfer_libraries_read == eLazyBoolCalculate)
- {
- GetRemoteQSupported();
- }
- return m_supports_qXfer_libraries_read == eLazyBoolYes;
+bool GDBRemoteCommunicationClient::GetAugmentedLibrariesSVR4ReadSupported() {
+ if (m_supports_augmented_libraries_svr4_read == eLazyBoolCalculate) {
+ GetRemoteQSupported();
+ }
+ return m_supports_augmented_libraries_svr4_read == eLazyBoolYes;
}
-bool
-GDBRemoteCommunicationClient::GetQXferAuxvReadSupported ()
-{
- if (m_supports_qXfer_auxv_read == eLazyBoolCalculate)
- {
- GetRemoteQSupported();
- }
- return m_supports_qXfer_auxv_read == eLazyBoolYes;
+bool GDBRemoteCommunicationClient::GetQXferLibrariesSVR4ReadSupported() {
+ if (m_supports_qXfer_libraries_svr4_read == eLazyBoolCalculate) {
+ GetRemoteQSupported();
+ }
+ return m_supports_qXfer_libraries_svr4_read == eLazyBoolYes;
}
-bool
-GDBRemoteCommunicationClient::GetQXferFeaturesReadSupported ()
-{
- if (m_supports_qXfer_features_read == eLazyBoolCalculate)
- {
- GetRemoteQSupported();
- }
- return m_supports_qXfer_features_read == eLazyBoolYes;
+bool GDBRemoteCommunicationClient::GetQXferLibrariesReadSupported() {
+ if (m_supports_qXfer_libraries_read == eLazyBoolCalculate) {
+ GetRemoteQSupported();
+ }
+ return m_supports_qXfer_libraries_read == eLazyBoolYes;
}
-uint64_t
-GDBRemoteCommunicationClient::GetRemoteMaxPacketSize()
-{
- if (m_max_packet_size == 0)
- {
- GetRemoteQSupported();
- }
- return m_max_packet_size;
+bool GDBRemoteCommunicationClient::GetQXferAuxvReadSupported() {
+ if (m_supports_qXfer_auxv_read == eLazyBoolCalculate) {
+ GetRemoteQSupported();
+ }
+ return m_supports_qXfer_auxv_read == eLazyBoolYes;
}
-bool
-GDBRemoteCommunicationClient::QueryNoAckModeSupported ()
-{
- if (m_supports_not_sending_acks == eLazyBoolCalculate)
- {
- m_send_acks = true;
- m_supports_not_sending_acks = eLazyBoolNo;
-
- // This is the first real packet that we'll send in a debug session and it may take a little
- // longer than normal to receive a reply. Wait at least 6 seconds for a reply to this packet.
-
- const uint32_t minimum_timeout = 6;
- uint32_t old_timeout = GetPacketTimeoutInMicroSeconds() / lldb_private::TimeValue::MicroSecPerSec;
- GDBRemoteCommunication::ScopedTimeout timeout (*this, std::max (old_timeout, minimum_timeout));
-
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- {
- m_send_acks = false;
- m_supports_not_sending_acks = eLazyBoolYes;
- }
- return true;
- }
- }
- return false;
+bool GDBRemoteCommunicationClient::GetQXferFeaturesReadSupported() {
+ if (m_supports_qXfer_features_read == eLazyBoolCalculate) {
+ GetRemoteQSupported();
+ }
+ return m_supports_qXfer_features_read == eLazyBoolYes;
}
-void
-GDBRemoteCommunicationClient::GetListThreadsInStopReplySupported ()
-{
- if (m_supports_threads_in_stop_reply == eLazyBoolCalculate)
- {
- m_supports_threads_in_stop_reply = eLazyBoolNo;
-
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- m_supports_threads_in_stop_reply = eLazyBoolYes;
- }
- }
+uint64_t GDBRemoteCommunicationClient::GetRemoteMaxPacketSize() {
+ if (m_max_packet_size == 0) {
+ GetRemoteQSupported();
+ }
+ return m_max_packet_size;
}
-bool
-GDBRemoteCommunicationClient::GetVAttachOrWaitSupported ()
-{
- if (m_attach_or_wait_reply == eLazyBoolCalculate)
- {
- m_attach_or_wait_reply = eLazyBoolNo;
-
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- m_attach_or_wait_reply = eLazyBoolYes;
- }
- }
- if (m_attach_or_wait_reply == eLazyBoolYes)
- return true;
- else
- return false;
-}
+bool GDBRemoteCommunicationClient::QueryNoAckModeSupported() {
+ if (m_supports_not_sending_acks == eLazyBoolCalculate) {
+ m_send_acks = true;
+ m_supports_not_sending_acks = eLazyBoolNo;
-bool
-GDBRemoteCommunicationClient::GetSyncThreadStateSupported ()
-{
- if (m_prepare_for_reg_writing_reply == eLazyBoolCalculate)
- {
- m_prepare_for_reg_writing_reply = eLazyBoolNo;
-
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("qSyncThreadStateSupported", response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- m_prepare_for_reg_writing_reply = eLazyBoolYes;
- }
+ // This is the first real packet that we'll send in a debug session and it
+ // may take a little
+ // longer than normal to receive a reply. Wait at least 6 seconds for a
+ // reply to this packet.
+
+ ScopedTimeout timeout(*this, std::max(GetPacketTimeout(), seconds(6)));
+
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse()) {
+ m_send_acks = false;
+ m_supports_not_sending_acks = eLazyBoolYes;
+ }
+ return true;
}
- if (m_prepare_for_reg_writing_reply == eLazyBoolYes)
- return true;
- else
- return false;
+ }
+ return false;
}
+void GDBRemoteCommunicationClient::GetListThreadsInStopReplySupported() {
+ if (m_supports_threads_in_stop_reply == eLazyBoolCalculate) {
+ m_supports_threads_in_stop_reply = eLazyBoolNo;
-void
-GDBRemoteCommunicationClient::ResetDiscoverableSettings (bool did_exec)
-{
- if (did_exec == false)
- {
- // Hard reset everything, this is when we first connect to a GDB server
- m_supports_not_sending_acks = eLazyBoolCalculate;
- m_supports_thread_suffix = eLazyBoolCalculate;
- m_supports_threads_in_stop_reply = eLazyBoolCalculate;
- m_supports_vCont_c = eLazyBoolCalculate;
- m_supports_vCont_C = eLazyBoolCalculate;
- m_supports_vCont_s = eLazyBoolCalculate;
- m_supports_vCont_S = eLazyBoolCalculate;
- m_supports_p = eLazyBoolCalculate;
- m_supports_x = eLazyBoolCalculate;
- m_supports_QSaveRegisterState = eLazyBoolCalculate;
- m_qHostInfo_is_valid = eLazyBoolCalculate;
- m_curr_pid_is_valid = eLazyBoolCalculate;
- m_qGDBServerVersion_is_valid = eLazyBoolCalculate;
- m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
- m_supports_memory_region_info = eLazyBoolCalculate;
- m_prepare_for_reg_writing_reply = eLazyBoolCalculate;
- m_attach_or_wait_reply = eLazyBoolCalculate;
- m_avoid_g_packets = eLazyBoolCalculate;
- m_supports_qXfer_auxv_read = eLazyBoolCalculate;
- m_supports_qXfer_libraries_read = eLazyBoolCalculate;
- m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate;
- m_supports_qXfer_features_read = eLazyBoolCalculate;
- m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate;
- m_supports_qProcessInfoPID = true;
- m_supports_qfProcessInfo = true;
- m_supports_qUserName = true;
- m_supports_qGroupName = true;
- m_supports_qThreadStopInfo = true;
- m_supports_z0 = true;
- m_supports_z1 = true;
- m_supports_z2 = true;
- m_supports_z3 = true;
- m_supports_z4 = true;
- m_supports_QEnvironment = true;
- m_supports_QEnvironmentHexEncoded = true;
- m_supports_qSymbol = true;
- m_qSymbol_requests_done = false;
- m_supports_qModuleInfo = true;
- m_host_arch.Clear();
- m_os_version_major = UINT32_MAX;
- m_os_version_minor = UINT32_MAX;
- m_os_version_update = UINT32_MAX;
- m_os_build.clear();
- m_os_kernel.clear();
- m_hostname.clear();
- m_gdb_server_name.clear();
- m_gdb_server_version = UINT32_MAX;
- m_default_packet_timeout = 0;
- m_max_packet_size = 0;
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response,
+ false) == PacketResult::Success) {
+ if (response.IsOKResponse())
+ m_supports_threads_in_stop_reply = eLazyBoolYes;
}
-
- // These flags should be reset when we first connect to a GDB server
- // and when our inferior process execs
- m_qProcessInfo_is_valid = eLazyBoolCalculate;
- m_process_arch.Clear();
+ }
}
-void
-GDBRemoteCommunicationClient::GetRemoteQSupported ()
-{
- // Clear out any capabilities we expect to see in the qSupported response
- m_supports_qXfer_auxv_read = eLazyBoolNo;
- m_supports_qXfer_libraries_read = eLazyBoolNo;
- m_supports_qXfer_libraries_svr4_read = eLazyBoolNo;
- m_supports_augmented_libraries_svr4_read = eLazyBoolNo;
- m_supports_qXfer_features_read = eLazyBoolNo;
- m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if not, we assume no limit
-
- // build the qSupported packet
- std::vector<std::string> features = {"xmlRegisters=i386,arm,mips"};
- StreamString packet;
- packet.PutCString( "qSupported" );
- for ( uint32_t i = 0; i < features.size( ); ++i )
- {
- packet.PutCString( i==0 ? ":" : ";");
- packet.PutCString( features[i].c_str( ) );
- }
+bool GDBRemoteCommunicationClient::GetVAttachOrWaitSupported() {
+ if (m_attach_or_wait_reply == eLazyBoolCalculate) {
+ m_attach_or_wait_reply = eLazyBoolNo;
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet.GetData(),
- response,
- /*send_async=*/false) == PacketResult::Success)
- {
- const char *response_cstr = response.GetStringRef().c_str();
- if (::strstr (response_cstr, "qXfer:auxv:read+"))
- m_supports_qXfer_auxv_read = eLazyBoolYes;
- if (::strstr (response_cstr, "qXfer:libraries-svr4:read+"))
- m_supports_qXfer_libraries_svr4_read = eLazyBoolYes;
- if (::strstr (response_cstr, "augmented-libraries-svr4-read"))
- {
- m_supports_qXfer_libraries_svr4_read = eLazyBoolYes; // implied
- m_supports_augmented_libraries_svr4_read = eLazyBoolYes;
- }
- if (::strstr (response_cstr, "qXfer:libraries:read+"))
- m_supports_qXfer_libraries_read = eLazyBoolYes;
- if (::strstr (response_cstr, "qXfer:features:read+"))
- m_supports_qXfer_features_read = eLazyBoolYes;
-
-
- // Look for a list of compressions in the features list e.g.
- // qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-deflate,lzma
- const char *features_list = ::strstr (response_cstr, "qXfer:features:");
- if (features_list)
- {
- const char *compressions = ::strstr (features_list, "SupportedCompressions=");
- if (compressions)
- {
- std::vector<std::string> supported_compressions;
- compressions += sizeof ("SupportedCompressions=") - 1;
- const char *end_of_compressions = strchr (compressions, ';');
- if (end_of_compressions == NULL)
- {
- end_of_compressions = strchr (compressions, '\0');
- }
- const char *current_compression = compressions;
- while (current_compression < end_of_compressions)
- {
- const char *next_compression_name = strchr (current_compression, ',');
- const char *end_of_this_word = next_compression_name;
- if (next_compression_name == NULL || end_of_compressions < next_compression_name)
- {
- end_of_this_word = end_of_compressions;
- }
-
- if (end_of_this_word)
- {
- if (end_of_this_word == current_compression)
- {
- current_compression++;
- }
- else
- {
- std::string this_compression (current_compression, end_of_this_word - current_compression);
- supported_compressions.push_back (this_compression);
- current_compression = end_of_this_word + 1;
- }
- }
- else
- {
- supported_compressions.push_back (current_compression);
- current_compression = end_of_compressions;
- }
- }
+ if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response,
+ false) == PacketResult::Success) {
+ if (response.IsOKResponse())
+ m_attach_or_wait_reply = eLazyBoolYes;
+ }
+ }
+ if (m_attach_or_wait_reply == eLazyBoolYes)
+ return true;
+ else
+ return false;
+}
- if (supported_compressions.size() > 0)
- {
- MaybeEnableCompression (supported_compressions);
- }
- }
- }
+bool GDBRemoteCommunicationClient::GetSyncThreadStateSupported() {
+ if (m_prepare_for_reg_writing_reply == eLazyBoolCalculate) {
+ m_prepare_for_reg_writing_reply = eLazyBoolNo;
- if (::strstr (response_cstr, "qEcho"))
- m_supports_qEcho = eLazyBoolYes;
- else
- m_supports_qEcho = eLazyBoolNo;
-
- const char *packet_size_str = ::strstr (response_cstr, "PacketSize=");
- if (packet_size_str)
- {
- StringExtractorGDBRemote packet_response(packet_size_str + strlen("PacketSize="));
- m_max_packet_size = packet_response.GetHexMaxU64(/*little_endian=*/false, UINT64_MAX);
- if (m_max_packet_size == 0)
- {
- m_max_packet_size = UINT64_MAX; // Must have been a garbled response
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
- if (log)
- log->Printf ("Garbled PacketSize spec in qSupported response");
- }
- }
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse("qSyncThreadStateSupported", response,
+ false) == PacketResult::Success) {
+ if (response.IsOKResponse())
+ m_prepare_for_reg_writing_reply = eLazyBoolYes;
}
+ }
+ if (m_prepare_for_reg_writing_reply == eLazyBoolYes)
+ return true;
+ else
+ return false;
}
-bool
-GDBRemoteCommunicationClient::GetThreadSuffixSupported ()
-{
- if (m_supports_thread_suffix == eLazyBoolCalculate)
- {
- StringExtractorGDBRemote response;
- m_supports_thread_suffix = eLazyBoolNo;
- if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- m_supports_thread_suffix = eLazyBoolYes;
- }
+void GDBRemoteCommunicationClient::ResetDiscoverableSettings(bool did_exec) {
+ if (did_exec == false) {
+ // Hard reset everything, this is when we first connect to a GDB server
+ m_supports_not_sending_acks = eLazyBoolCalculate;
+ m_supports_thread_suffix = eLazyBoolCalculate;
+ m_supports_threads_in_stop_reply = eLazyBoolCalculate;
+ m_supports_vCont_c = eLazyBoolCalculate;
+ m_supports_vCont_C = eLazyBoolCalculate;
+ m_supports_vCont_s = eLazyBoolCalculate;
+ m_supports_vCont_S = eLazyBoolCalculate;
+ m_supports_p = eLazyBoolCalculate;
+ m_supports_x = eLazyBoolCalculate;
+ m_supports_QSaveRegisterState = eLazyBoolCalculate;
+ m_qHostInfo_is_valid = eLazyBoolCalculate;
+ m_curr_pid_is_valid = eLazyBoolCalculate;
+ m_qGDBServerVersion_is_valid = eLazyBoolCalculate;
+ m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
+ m_supports_memory_region_info = eLazyBoolCalculate;
+ m_prepare_for_reg_writing_reply = eLazyBoolCalculate;
+ m_attach_or_wait_reply = eLazyBoolCalculate;
+ m_avoid_g_packets = eLazyBoolCalculate;
+ m_supports_qXfer_auxv_read = eLazyBoolCalculate;
+ m_supports_qXfer_libraries_read = eLazyBoolCalculate;
+ m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate;
+ m_supports_qXfer_features_read = eLazyBoolCalculate;
+ m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate;
+ m_supports_qProcessInfoPID = true;
+ m_supports_qfProcessInfo = true;
+ m_supports_qUserName = true;
+ m_supports_qGroupName = true;
+ m_supports_qThreadStopInfo = true;
+ m_supports_z0 = true;
+ m_supports_z1 = true;
+ m_supports_z2 = true;
+ m_supports_z3 = true;
+ m_supports_z4 = true;
+ m_supports_QEnvironment = true;
+ m_supports_QEnvironmentHexEncoded = true;
+ m_supports_qSymbol = true;
+ m_qSymbol_requests_done = false;
+ m_supports_qModuleInfo = true;
+ m_host_arch.Clear();
+ m_os_version_major = UINT32_MAX;
+ m_os_version_minor = UINT32_MAX;
+ m_os_version_update = UINT32_MAX;
+ m_os_build.clear();
+ m_os_kernel.clear();
+ m_hostname.clear();
+ m_gdb_server_name.clear();
+ m_gdb_server_version = UINT32_MAX;
+ m_default_packet_timeout = seconds(0);
+ m_max_packet_size = 0;
+ m_qSupported_response.clear();
+ m_supported_async_json_packets_is_valid = false;
+ m_supported_async_json_packets_sp.reset();
+ m_supports_jModulesInfo = true;
+ }
+
+ // These flags should be reset when we first connect to a GDB server
+ // and when our inferior process execs
+ m_qProcessInfo_is_valid = eLazyBoolCalculate;
+ m_process_arch.Clear();
+}
+
+void GDBRemoteCommunicationClient::GetRemoteQSupported() {
+ // Clear out any capabilities we expect to see in the qSupported response
+ m_supports_qXfer_auxv_read = eLazyBoolNo;
+ m_supports_qXfer_libraries_read = eLazyBoolNo;
+ m_supports_qXfer_libraries_svr4_read = eLazyBoolNo;
+ m_supports_augmented_libraries_svr4_read = eLazyBoolNo;
+ m_supports_qXfer_features_read = eLazyBoolNo;
+ m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if
+ // not, we assume no limit
+
+ // build the qSupported packet
+ std::vector<std::string> features = {"xmlRegisters=i386,arm,mips"};
+ StreamString packet;
+ packet.PutCString("qSupported");
+ for (uint32_t i = 0; i < features.size(); ++i) {
+ packet.PutCString(i == 0 ? ":" : ";");
+ packet.PutCString(features[i]);
+ }
+
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet.GetString(), response,
+ /*send_async=*/false) ==
+ PacketResult::Success) {
+ const char *response_cstr = response.GetStringRef().c_str();
+
+ // Hang on to the qSupported packet, so that platforms can do custom
+ // configuration of the transport before attaching/launching the
+ // process.
+ m_qSupported_response = response_cstr;
+
+ if (::strstr(response_cstr, "qXfer:auxv:read+"))
+ m_supports_qXfer_auxv_read = eLazyBoolYes;
+ if (::strstr(response_cstr, "qXfer:libraries-svr4:read+"))
+ m_supports_qXfer_libraries_svr4_read = eLazyBoolYes;
+ if (::strstr(response_cstr, "augmented-libraries-svr4-read")) {
+ m_supports_qXfer_libraries_svr4_read = eLazyBoolYes; // implied
+ m_supports_augmented_libraries_svr4_read = eLazyBoolYes;
+ }
+ if (::strstr(response_cstr, "qXfer:libraries:read+"))
+ m_supports_qXfer_libraries_read = eLazyBoolYes;
+ if (::strstr(response_cstr, "qXfer:features:read+"))
+ m_supports_qXfer_features_read = eLazyBoolYes;
+
+ // Look for a list of compressions in the features list e.g.
+ // qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-deflate,lzma
+ const char *features_list = ::strstr(response_cstr, "qXfer:features:");
+ if (features_list) {
+ const char *compressions =
+ ::strstr(features_list, "SupportedCompressions=");
+ if (compressions) {
+ std::vector<std::string> supported_compressions;
+ compressions += sizeof("SupportedCompressions=") - 1;
+ const char *end_of_compressions = strchr(compressions, ';');
+ if (end_of_compressions == NULL) {
+ end_of_compressions = strchr(compressions, '\0');
+ }
+ const char *current_compression = compressions;
+ while (current_compression < end_of_compressions) {
+ const char *next_compression_name = strchr(current_compression, ',');
+ const char *end_of_this_word = next_compression_name;
+ if (next_compression_name == NULL ||
+ end_of_compressions < next_compression_name) {
+ end_of_this_word = end_of_compressions;
+ }
+
+ if (end_of_this_word) {
+ if (end_of_this_word == current_compression) {
+ current_compression++;
+ } else {
+ std::string this_compression(
+ current_compression, end_of_this_word - current_compression);
+ supported_compressions.push_back(this_compression);
+ current_compression = end_of_this_word + 1;
+ }
+ } else {
+ supported_compressions.push_back(current_compression);
+ current_compression = end_of_compressions;
+ }
+ }
+
+ if (supported_compressions.size() > 0) {
+ MaybeEnableCompression(supported_compressions);
+ }
+ }
+ }
+
+ if (::strstr(response_cstr, "qEcho"))
+ m_supports_qEcho = eLazyBoolYes;
+ else
+ m_supports_qEcho = eLazyBoolNo;
+
+ const char *packet_size_str = ::strstr(response_cstr, "PacketSize=");
+ if (packet_size_str) {
+ StringExtractorGDBRemote packet_response(packet_size_str +
+ strlen("PacketSize="));
+ m_max_packet_size =
+ packet_response.GetHexMaxU64(/*little_endian=*/false, UINT64_MAX);
+ if (m_max_packet_size == 0) {
+ m_max_packet_size = UINT64_MAX; // Must have been a garbled response
+ Log *log(
+ ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ if (log)
+ log->Printf("Garbled PacketSize spec in qSupported response");
+ }
}
- return m_supports_thread_suffix;
+ }
}
-bool
-GDBRemoteCommunicationClient::GetVContSupported (char flavor)
-{
- if (m_supports_vCont_c == eLazyBoolCalculate)
- {
- StringExtractorGDBRemote response;
- m_supports_vCont_any = eLazyBoolNo;
- m_supports_vCont_all = eLazyBoolNo;
- m_supports_vCont_c = eLazyBoolNo;
- m_supports_vCont_C = eLazyBoolNo;
- m_supports_vCont_s = eLazyBoolNo;
- m_supports_vCont_S = eLazyBoolNo;
- if (SendPacketAndWaitForResponse("vCont?", response, false) == PacketResult::Success)
- {
- const char *response_cstr = response.GetStringRef().c_str();
- if (::strstr (response_cstr, ";c"))
- m_supports_vCont_c = eLazyBoolYes;
-
- if (::strstr (response_cstr, ";C"))
- m_supports_vCont_C = eLazyBoolYes;
-
- if (::strstr (response_cstr, ";s"))
- m_supports_vCont_s = eLazyBoolYes;
-
- if (::strstr (response_cstr, ";S"))
- m_supports_vCont_S = eLazyBoolYes;
-
- if (m_supports_vCont_c == eLazyBoolYes &&
- m_supports_vCont_C == eLazyBoolYes &&
- m_supports_vCont_s == eLazyBoolYes &&
- m_supports_vCont_S == eLazyBoolYes)
- {
- m_supports_vCont_all = eLazyBoolYes;
- }
-
- if (m_supports_vCont_c == eLazyBoolYes ||
- m_supports_vCont_C == eLazyBoolYes ||
- m_supports_vCont_s == eLazyBoolYes ||
- m_supports_vCont_S == eLazyBoolYes)
- {
- m_supports_vCont_any = eLazyBoolYes;
- }
- }
- }
-
- switch (flavor)
- {
- case 'a': return m_supports_vCont_any;
- case 'A': return m_supports_vCont_all;
- case 'c': return m_supports_vCont_c;
- case 'C': return m_supports_vCont_C;
- case 's': return m_supports_vCont_s;
- case 'S': return m_supports_vCont_S;
- default: break;
+
+bool GDBRemoteCommunicationClient::GetThreadSuffixSupported() {
+ if (m_supports_thread_suffix == eLazyBoolCalculate) {
+ StringExtractorGDBRemote response;
+ m_supports_thread_suffix = eLazyBoolNo;
+ if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response,
+ false) == PacketResult::Success) {
+ if (response.IsOKResponse())
+ m_supports_thread_suffix = eLazyBoolYes;
}
- return false;
+ }
+ return m_supports_thread_suffix;
+}
+bool GDBRemoteCommunicationClient::GetVContSupported(char flavor) {
+ if (m_supports_vCont_c == eLazyBoolCalculate) {
+ StringExtractorGDBRemote response;
+ m_supports_vCont_any = eLazyBoolNo;
+ m_supports_vCont_all = eLazyBoolNo;
+ m_supports_vCont_c = eLazyBoolNo;
+ m_supports_vCont_C = eLazyBoolNo;
+ m_supports_vCont_s = eLazyBoolNo;
+ m_supports_vCont_S = eLazyBoolNo;
+ if (SendPacketAndWaitForResponse("vCont?", response, false) ==
+ PacketResult::Success) {
+ const char *response_cstr = response.GetStringRef().c_str();
+ if (::strstr(response_cstr, ";c"))
+ m_supports_vCont_c = eLazyBoolYes;
+
+ if (::strstr(response_cstr, ";C"))
+ m_supports_vCont_C = eLazyBoolYes;
+
+ if (::strstr(response_cstr, ";s"))
+ m_supports_vCont_s = eLazyBoolYes;
+
+ if (::strstr(response_cstr, ";S"))
+ m_supports_vCont_S = eLazyBoolYes;
+
+ if (m_supports_vCont_c == eLazyBoolYes &&
+ m_supports_vCont_C == eLazyBoolYes &&
+ m_supports_vCont_s == eLazyBoolYes &&
+ m_supports_vCont_S == eLazyBoolYes) {
+ m_supports_vCont_all = eLazyBoolYes;
+ }
+
+ if (m_supports_vCont_c == eLazyBoolYes ||
+ m_supports_vCont_C == eLazyBoolYes ||
+ m_supports_vCont_s == eLazyBoolYes ||
+ m_supports_vCont_S == eLazyBoolYes) {
+ m_supports_vCont_any = eLazyBoolYes;
+ }
+ }
+ }
+
+ switch (flavor) {
+ case 'a':
+ return m_supports_vCont_any;
+ case 'A':
+ return m_supports_vCont_all;
+ case 'c':
+ return m_supports_vCont_c;
+ case 'C':
+ return m_supports_vCont_C;
+ case 's':
+ return m_supports_vCont_s;
+ case 'S':
+ return m_supports_vCont_S;
+ default:
+ break;
+ }
+ return false;
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationClient::SendThreadSpecificPacketAndWaitForResponse(
+ lldb::tid_t tid, StreamString &&payload, StringExtractorGDBRemote &response,
+ bool send_async) {
+ Lock lock(*this, send_async);
+ if (!lock) {
+ if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(
+ GDBR_LOG_PROCESS | GDBR_LOG_PACKETS))
+ log->Printf("GDBRemoteCommunicationClient::%s: Didn't get sequence mutex "
+ "for %s packet.",
+ __FUNCTION__, payload.GetData());
+ return PacketResult::ErrorNoSequenceLock;
+ }
+
+ if (GetThreadSuffixSupported())
+ payload.Printf(";thread:%4.4" PRIx64 ";", tid);
+ else {
+ if (!SetCurrentThread(tid))
+ return PacketResult::ErrorSendFailed;
+ }
+
+ return SendPacketAndWaitForResponseNoLock(payload.GetString(), response);
}
// Check if the target supports 'p' packet. It sends out a 'p'
@@ -592,4043 +536,3098 @@ GDBRemoteCommunicationClient::GetVContSupported (char flavor)
// that support is available.
//
// Takes a valid thread ID because p needs to apply to a thread.
-bool
-GDBRemoteCommunicationClient::GetpPacketSupported (lldb::tid_t tid)
-{
- if (m_supports_p == eLazyBoolCalculate)
- {
- StringExtractorGDBRemote response;
- m_supports_p = eLazyBoolNo;
- char packet[256];
- if (GetThreadSuffixSupported())
- snprintf(packet, sizeof(packet), "p0;thread:%" PRIx64 ";", tid);
- else
- snprintf(packet, sizeof(packet), "p0");
-
- if (SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success)
- {
- if (response.IsNormalResponse())
- m_supports_p = eLazyBoolYes;
- }
- }
- return m_supports_p;
-}
-
-StructuredData::ObjectSP
-GDBRemoteCommunicationClient::GetThreadsInfo()
-{
- // Get information on all threads at one using the "jThreadsInfo" packet
- StructuredData::ObjectSP object_sp;
-
- if (m_supports_jThreadsInfo)
- {
- StringExtractorGDBRemote response;
- response.SetResponseValidatorToJSON();
- if (SendPacketAndWaitForResponse("jThreadsInfo", response, false) == PacketResult::Success)
- {
- if (response.IsUnsupportedResponse())
- {
- m_supports_jThreadsInfo = false;
- }
- else if (!response.Empty())
- {
- object_sp = StructuredData::ParseJSON (response.GetStringRef());
- }
- }
+bool GDBRemoteCommunicationClient::GetpPacketSupported(lldb::tid_t tid) {
+ if (m_supports_p == eLazyBoolCalculate) {
+ m_supports_p = eLazyBoolNo;
+ StreamString payload;
+ payload.PutCString("p0");
+ StringExtractorGDBRemote response;
+ if (SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload),
+ response, false) ==
+ PacketResult::Success &&
+ response.IsNormalResponse()) {
+ m_supports_p = eLazyBoolYes;
}
- return object_sp;
+ }
+ return m_supports_p;
}
+StructuredData::ObjectSP GDBRemoteCommunicationClient::GetThreadsInfo() {
+ // Get information on all threads at one using the "jThreadsInfo" packet
+ StructuredData::ObjectSP object_sp;
-bool
-GDBRemoteCommunicationClient::GetThreadExtendedInfoSupported ()
-{
- if (m_supports_jThreadExtendedInfo == eLazyBoolCalculate)
- {
- StringExtractorGDBRemote response;
- m_supports_jThreadExtendedInfo = eLazyBoolNo;
- if (SendPacketAndWaitForResponse("jThreadExtendedInfo:", response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- {
- m_supports_jThreadExtendedInfo = eLazyBoolYes;
- }
- }
+ if (m_supports_jThreadsInfo) {
+ StringExtractorGDBRemote response;
+ response.SetResponseValidatorToJSON();
+ if (SendPacketAndWaitForResponse("jThreadsInfo", response, false) ==
+ PacketResult::Success) {
+ if (response.IsUnsupportedResponse()) {
+ m_supports_jThreadsInfo = false;
+ } else if (!response.Empty()) {
+ object_sp = StructuredData::ParseJSON(response.GetStringRef());
+ }
}
- return m_supports_jThreadExtendedInfo;
+ }
+ return object_sp;
}
-bool
-GDBRemoteCommunicationClient::GetLoadedDynamicLibrariesInfosSupported ()
-{
- if (m_supports_jLoadedDynamicLibrariesInfos == eLazyBoolCalculate)
- {
- StringExtractorGDBRemote response;
- m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolNo;
- if (SendPacketAndWaitForResponse("jGetLoadedDynamicLibrariesInfos:", response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- {
- m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolYes;
- }
- }
+bool GDBRemoteCommunicationClient::GetThreadExtendedInfoSupported() {
+ if (m_supports_jThreadExtendedInfo == eLazyBoolCalculate) {
+ StringExtractorGDBRemote response;
+ m_supports_jThreadExtendedInfo = eLazyBoolNo;
+ if (SendPacketAndWaitForResponse("jThreadExtendedInfo:", response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse()) {
+ m_supports_jThreadExtendedInfo = eLazyBoolYes;
+ }
}
- return m_supports_jLoadedDynamicLibrariesInfos;
+ }
+ return m_supports_jThreadExtendedInfo;
}
-bool
-GDBRemoteCommunicationClient::GetxPacketSupported ()
-{
- if (m_supports_x == eLazyBoolCalculate)
- {
- StringExtractorGDBRemote response;
- m_supports_x = eLazyBoolNo;
- char packet[256];
- snprintf (packet, sizeof (packet), "x0,0");
- if (SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- m_supports_x = eLazyBoolYes;
- }
+bool GDBRemoteCommunicationClient::GetLoadedDynamicLibrariesInfosSupported() {
+ if (m_supports_jLoadedDynamicLibrariesInfos == eLazyBoolCalculate) {
+ StringExtractorGDBRemote response;
+ m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolNo;
+ if (SendPacketAndWaitForResponse("jGetLoadedDynamicLibrariesInfos:",
+ response,
+ false) == PacketResult::Success) {
+ if (response.IsOKResponse()) {
+ m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolYes;
+ }
}
- return m_supports_x;
+ }
+ return m_supports_jLoadedDynamicLibrariesInfos;
}
-GDBRemoteCommunicationClient::PacketResult
-GDBRemoteCommunicationClient::SendPacketsAndConcatenateResponses
-(
- const char *payload_prefix,
- std::string &response_string
-)
-{
- Mutex::Locker locker;
- if (!GetSequenceMutex(locker,
- "ProcessGDBRemote::SendPacketsAndConcatenateResponses() failed due to not getting the sequence mutex"))
- {
- Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
- if (log)
- log->Printf("error: failed to get packet sequence mutex, not sending packets with prefix '%s'",
- payload_prefix);
- return PacketResult::ErrorNoSequenceLock;
- }
-
- response_string = "";
- std::string payload_prefix_str(payload_prefix);
- unsigned int response_size = 0x1000;
- if (response_size > GetRemoteMaxPacketSize()) { // May send qSupported packet
- response_size = GetRemoteMaxPacketSize();
- }
-
- for (unsigned int offset = 0; true; offset += response_size)
- {
- StringExtractorGDBRemote this_response;
- // Construct payload
- char sizeDescriptor[128];
- snprintf(sizeDescriptor, sizeof(sizeDescriptor), "%x,%x", offset, response_size);
- PacketResult result = SendPacketAndWaitForResponse((payload_prefix_str + sizeDescriptor).c_str(),
- this_response,
- /*send_async=*/false);
- if (result != PacketResult::Success)
- return result;
-
- const std::string &this_string = this_response.GetStringRef();
-
- // Check for m or l as first character; l seems to mean this is the last chunk
- char first_char = *this_string.c_str();
- if (first_char != 'm' && first_char != 'l')
- {
- return PacketResult::ErrorReplyInvalid;
- }
- // Concatenate the result so far (skipping 'm' or 'l')
- response_string.append(this_string, 1, std::string::npos);
- if (first_char == 'l')
- // We're done
- return PacketResult::Success;
+bool GDBRemoteCommunicationClient::GetSharedCacheInfoSupported() {
+ if (m_supports_jGetSharedCacheInfo == eLazyBoolCalculate) {
+ StringExtractorGDBRemote response;
+ m_supports_jGetSharedCacheInfo = eLazyBoolNo;
+ if (SendPacketAndWaitForResponse("jGetSharedCacheInfo:", response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse()) {
+ m_supports_jGetSharedCacheInfo = eLazyBoolYes;
+ }
}
+ }
+ return m_supports_jGetSharedCacheInfo;
}
-GDBRemoteCommunicationClient::PacketResult
-GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
-(
- const char *payload,
- StringExtractorGDBRemote &response,
- bool send_async
-)
-{
- return SendPacketAndWaitForResponse (payload,
- ::strlen (payload),
- response,
- send_async);
-}
-
-GDBRemoteCommunicationClient::PacketResult
-GDBRemoteCommunicationClient::SendPacketAndWaitForResponseNoLock (const char *payload,
- size_t payload_length,
- StringExtractorGDBRemote &response)
-{
- PacketResult packet_result = SendPacketNoLock(payload, payload_length);
- if (packet_result == PacketResult::Success)
- {
- const size_t max_response_retries = 3;
- for (size_t i=0; i<max_response_retries; ++i)
- {
- packet_result = ReadPacket(response, GetPacketTimeoutInMicroSeconds (), true);
- // Make sure we received a response
- if (packet_result != PacketResult::Success)
- return packet_result;
- // Make sure our response is valid for the payload that was sent
- if (response.ValidateResponse())
- return packet_result;
- // Response says it wasn't valid
- Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS);
- if (log)
- log->Printf("error: packet with payload \"%*s\" got invalid response \"%s\": %s",
- (int)payload_length,
- payload,
- response.GetStringRef().c_str(),
- (i == (max_response_retries - 1)) ? "using invalid response and giving up" : "ignoring response and waiting for another");
- }
+bool GDBRemoteCommunicationClient::GetxPacketSupported() {
+ if (m_supports_x == eLazyBoolCalculate) {
+ StringExtractorGDBRemote response;
+ m_supports_x = eLazyBoolNo;
+ char packet[256];
+ snprintf(packet, sizeof(packet), "x0,0");
+ if (SendPacketAndWaitForResponse(packet, response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse())
+ m_supports_x = eLazyBoolYes;
}
- return packet_result;
+ }
+ return m_supports_x;
}
GDBRemoteCommunicationClient::PacketResult
-GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
-(
- const char *payload,
- size_t payload_length,
- StringExtractorGDBRemote &response,
- bool send_async
-)
-{
- PacketResult packet_result = PacketResult::ErrorSendFailed;
- Mutex::Locker locker;
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
-
- // In order to stop async notifications from being processed in the middle of the
- // send/receive sequence Hijack the broadcast. Then rebroadcast any events when we are done.
- static ListenerSP hijack_listener_sp(Listener::MakeListener("lldb.NotifyHijacker"));
- HijackBroadcaster(hijack_listener_sp, eBroadcastBitGdbReadThreadGotNotify);
-
- if (GetSequenceMutex (locker))
- {
- packet_result = SendPacketAndWaitForResponseNoLock (payload, payload_length, response);
- }
- else
- {
- if (send_async)
- {
- if (IsRunning())
- {
- std::lock_guard<std::recursive_mutex> guard(m_async_mutex);
- m_async_packet.assign(payload, payload_length);
- m_async_response.CopyResponseValidator(response);
- m_async_packet_predicate.SetValue (true, eBroadcastNever);
-
- if (log)
- log->Printf ("async: async packet = %s", m_async_packet.c_str());
-
- bool timed_out = false;
- if (SendInterrupt(locker, 2, timed_out))
- {
- if (m_interrupt_sent)
- {
- m_interrupt_sent = false;
- TimeValue timeout_time;
- timeout_time = TimeValue::Now();
- timeout_time.OffsetWithSeconds (m_packet_timeout);
-
- if (log)
- log->Printf ("async: sent interrupt");
-
- if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out))
- {
- if (log)
- log->Printf ("async: got response");
-
- // Swap the response buffer to avoid malloc and string copy
- response.GetStringRef().swap (m_async_response.GetStringRef());
- packet_result = m_async_result;
- }
- else
- {
- if (log)
- log->Printf ("async: timed out waiting for response");
- }
-
- // Make sure we wait until the continue packet has been sent again...
- if (m_private_is_running.WaitForValueEqualTo (true, &timeout_time, &timed_out))
- {
- if (log)
- {
- if (timed_out)
- log->Printf ("async: timed out waiting for process to resume, but process was resumed");
- else
- log->Printf ("async: async packet sent");
- }
- }
- else
- {
- if (log)
- log->Printf ("async: timed out waiting for process to resume");
- }
- }
- else
- {
- // We had a racy condition where we went to send the interrupt
- // yet we were able to get the lock, so the process must have
- // just stopped?
- if (log)
- log->Printf ("async: got lock without sending interrupt");
- // Send the packet normally since we got the lock
- packet_result = SendPacketAndWaitForResponseNoLock (payload, payload_length, response);
- }
- }
- else
- {
- if (log)
- log->Printf ("async: failed to interrupt");
- }
-
- m_async_response.SetResponseValidator(nullptr, nullptr);
-
- }
- else
- {
- if (log)
- log->Printf ("async: not running, async is ignored");
- }
- }
- else
- {
- if (log)
- log->Printf("error: failed to get packet sequence mutex, not sending packet '%*s'", (int) payload_length, payload);
- }
- }
-
- // Remove our Hijacking listener from the broadcast.
- RestoreBroadcaster();
-
- // If a notification event occurred, rebroadcast since it can now be processed safely.
- EventSP event_sp;
- if (hijack_listener_sp->GetNextEvent(event_sp))
- BroadcastEvent(event_sp);
-
- return packet_result;
-}
-
-static const char *end_delimiter = "--end--;";
-static const int end_delimiter_len = 8;
-
-std::string
-GDBRemoteCommunicationClient::HarmonizeThreadIdsForProfileData
-( ProcessGDBRemote *process,
- StringExtractorGDBRemote& profileDataExtractor
-)
-{
- std::map<uint64_t, uint32_t> new_thread_id_to_used_usec_map;
- std::stringstream final_output;
- std::string name, value;
-
- // Going to assuming thread_used_usec comes first, else bail out.
- while (profileDataExtractor.GetNameColonValue(name, value))
- {
- if (name.compare("thread_used_id") == 0)
- {
- StringExtractor threadIDHexExtractor(value.c_str());
- uint64_t thread_id = threadIDHexExtractor.GetHexMaxU64(false, 0);
-
- bool has_used_usec = false;
- uint32_t curr_used_usec = 0;
- std::string usec_name, usec_value;
- uint32_t input_file_pos = profileDataExtractor.GetFilePos();
- if (profileDataExtractor.GetNameColonValue(usec_name, usec_value))
- {
- if (usec_name.compare("thread_used_usec") == 0)
- {
- has_used_usec = true;
- curr_used_usec = strtoull(usec_value.c_str(), NULL, 0);
- }
- else
- {
- // We didn't find what we want, it is probably
- // an older version. Bail out.
- profileDataExtractor.SetFilePos(input_file_pos);
- }
- }
-
- if (has_used_usec)
- {
- uint32_t prev_used_usec = 0;
- std::map<uint64_t, uint32_t>::iterator iterator = m_thread_id_to_used_usec_map.find(thread_id);
- if (iterator != m_thread_id_to_used_usec_map.end())
- {
- prev_used_usec = m_thread_id_to_used_usec_map[thread_id];
- }
-
- uint32_t real_used_usec = curr_used_usec - prev_used_usec;
- // A good first time record is one that runs for at least 0.25 sec
- bool good_first_time = (prev_used_usec == 0) && (real_used_usec > 250000);
- bool good_subsequent_time = (prev_used_usec > 0) &&
- ((real_used_usec > 0) || (process->HasAssignedIndexIDToThread(thread_id)));
-
- if (good_first_time || good_subsequent_time)
- {
- // We try to avoid doing too many index id reservation,
- // resulting in fast increase of index ids.
-
- final_output << name << ":";
- int32_t index_id = process->AssignIndexIDToThread(thread_id);
- final_output << index_id << ";";
-
- final_output << usec_name << ":" << usec_value << ";";
- }
- else
- {
- // Skip past 'thread_used_name'.
- std::string local_name, local_value;
- profileDataExtractor.GetNameColonValue(local_name, local_value);
- }
-
- // Store current time as previous time so that they can be compared later.
- new_thread_id_to_used_usec_map[thread_id] = curr_used_usec;
- }
- else
- {
- // Bail out and use old string.
- final_output << name << ":" << value << ";";
- }
- }
- else
- {
- final_output << name << ":" << value << ";";
- }
- }
- final_output << end_delimiter;
- m_thread_id_to_used_usec_map = new_thread_id_to_used_usec_map;
-
- return final_output.str();
-}
-
-bool
-GDBRemoteCommunicationClient::SendvContPacket
-(
- ProcessGDBRemote *process,
- const char *payload,
- size_t packet_length,
- StringExtractorGDBRemote &response
-)
-{
-
- m_curr_tid = LLDB_INVALID_THREAD_ID;
- Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf("GDBRemoteCommunicationClient::%s ()", __FUNCTION__);
-
- // we want to lock down packet sending while we continue
- Mutex::Locker locker(m_sequence_mutex);
-
- // here we broadcast this before we even send the packet!!
- // this signals doContinue() to exit
- BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
-
- // set the public state to running
- m_public_is_running.SetValue(true, eBroadcastNever);
-
- // Set the starting continue packet into "continue_packet". This packet
- // may change if we are interrupted and we continue after an async packet...
- std::string continue_packet(payload, packet_length);
-
- if (log)
- log->Printf("GDBRemoteCommunicationClient::%s () sending vCont packet: %s", __FUNCTION__, continue_packet.c_str());
-
- if (SendPacketNoLock(continue_packet.c_str(), continue_packet.size()) != PacketResult::Success)
- return false;
-
- // set the private state to running and broadcast this
- m_private_is_running.SetValue(true, eBroadcastAlways);
-
+GDBRemoteCommunicationClient::SendPacketsAndConcatenateResponses(
+ const char *payload_prefix, std::string &response_string) {
+ Lock lock(*this, false);
+ if (!lock) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
+ GDBR_LOG_PACKETS));
if (log)
- log->Printf("GDBRemoteCommunicationClient::%s () ReadPacket(%s)", __FUNCTION__, continue_packet.c_str());
-
- // wait for the response to the vCont
- if (ReadPacket(response, UINT32_MAX, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- return true;
- }
-
- return false;
-}
-
-StateType
-GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse
-(
- ProcessGDBRemote *process,
- const char *payload,
- size_t packet_length,
- StringExtractorGDBRemote &response
-)
-{
- m_curr_tid = LLDB_INVALID_THREAD_ID;
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
- if (log)
- log->Printf ("GDBRemoteCommunicationClient::%s ()", __FUNCTION__);
-
- Mutex::Locker locker(m_sequence_mutex);
- StateType state = eStateRunning;
-
- m_public_is_running.SetValue (true, eBroadcastNever);
- // Set the starting continue packet into "continue_packet". This packet
- // may change if we are interrupted and we continue after an async packet...
- std::string continue_packet(payload, packet_length);
-
- const auto sigstop_signo = process->GetUnixSignals()->GetSignalNumberFromName("SIGSTOP");
- const auto sigint_signo = process->GetUnixSignals()->GetSignalNumberFromName("SIGINT");
-
- bool got_async_packet = false;
- bool broadcast_sent = false;
-
- while (state == eStateRunning)
- {
- if (!got_async_packet)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationClient::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str());
- if (SendPacketNoLock(continue_packet.c_str(), continue_packet.size()) != PacketResult::Success)
- state = eStateInvalid;
- else
- m_interrupt_sent = false;
-
- if (! broadcast_sent)
- {
- BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
- broadcast_sent = true;
- }
-
- m_private_is_running.SetValue (true, eBroadcastAlways);
- }
-
- got_async_packet = false;
-
- if (log)
- log->Printf ("GDBRemoteCommunicationClient::%s () ReadPacket(%s)", __FUNCTION__, continue_packet.c_str());
-
- if (ReadPacket(response, UINT32_MAX, false) == PacketResult::Success)
- {
- if (response.Empty())
- state = eStateInvalid;
- else
- {
- const char stop_type = response.GetChar();
- if (log)
- log->Printf ("GDBRemoteCommunicationClient::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str());
- switch (stop_type)
- {
- case 'T':
- case 'S':
- {
- if (process->GetStopID() == 0)
- {
- if (process->GetID() == LLDB_INVALID_PROCESS_ID)
- {
- lldb::pid_t pid = GetCurrentProcessID ();
- if (pid != LLDB_INVALID_PROCESS_ID)
- process->SetID (pid);
- }
- process->BuildDynamicRegisterInfo (true);
- }
-
- // Privately notify any internal threads that we have stopped
- // in case we wanted to interrupt our process, yet we might
- // send a packet and continue without returning control to the
- // user.
- m_private_is_running.SetValue (false, eBroadcastAlways);
-
- const uint8_t signo = response.GetHexU8 (UINT8_MAX);
-
- bool continue_after_async = m_async_signal != -1 || m_async_packet_predicate.GetValue();
- if (continue_after_async || m_interrupt_sent)
- {
- // We sent an interrupt packet to stop the inferior process
- // for an async signal or to send an async packet while running
- // but we might have been single stepping and received the
- // stop packet for the step instead of for the interrupt packet.
- // Typically when an interrupt is sent a SIGINT or SIGSTOP
- // is used, so if we get anything else, we need to try and
- // get another stop reply packet that may have been sent
- // due to sending the interrupt when the target is stopped
- // which will just re-send a copy of the last stop reply
- // packet. If we don't do this, then the reply for our
- // async packet will be the repeat stop reply packet and cause
- // a lot of trouble for us! We also have some debugserver
- // binaries that would send two stop replies anytime the process
- // was interrupted, so we need to also check for an extra
- // stop reply packet if we interrupted the process
- const bool received_nonstop_signal = signo != sigint_signo && signo != sigstop_signo;
- if (m_interrupt_sent || received_nonstop_signal)
- {
- if (received_nonstop_signal)
- continue_after_async = false;
-
- // Try for a very brief time (0.1s) to get another stop reply
- // packet to make sure it doesn't get in the way
- StringExtractorGDBRemote extra_stop_reply_packet;
- uint32_t timeout_usec = 100000;
- if (ReadPacket (extra_stop_reply_packet, timeout_usec, false) == PacketResult::Success)
- {
- switch (extra_stop_reply_packet.GetChar())
- {
- case 'T':
- case 'S':
- // We did get an extra stop reply, which means
- // our interrupt didn't stop the target so we
- // shouldn't continue after the async signal
- // or packet is sent...
- continue_after_async = false;
- break;
- }
- }
- }
- }
-
- if (m_async_signal != -1)
- {
- if (log)
- log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal));
-
- // Save off the async signal we are supposed to send
- const int async_signal = m_async_signal;
- // Clear the async signal member so we don't end up
- // sending the signal multiple times...
- m_async_signal = -1;
- // Check which signal we stopped with
- if (signo == async_signal)
- {
- if (log)
- log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo));
-
- // We already stopped with a signal that we wanted
- // to stop with, so we are done
- }
- else
- {
- // We stopped with a different signal that the one
- // we wanted to stop with, so now we must resume
- // with the signal we want
- char signal_packet[32];
- int signal_packet_len = 0;
- signal_packet_len = ::snprintf (signal_packet,
- sizeof (signal_packet),
- "C%2.2x",
- async_signal);
-
- if (log)
- log->Printf ("async: stopped with signal %s, resume with %s",
- Host::GetSignalAsCString (signo),
- Host::GetSignalAsCString (async_signal));
-
- // Set the continue packet to resume even if the
- // interrupt didn't cause our stop (ignore continue_after_async)
- continue_packet.assign(signal_packet, signal_packet_len);
- continue;
- }
- }
- else if (m_async_packet_predicate.GetValue())
- {
- Log * packet_log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
-
- // We are supposed to send an asynchronous packet while
- // we are running.
- m_async_response.Clear();
- if (m_async_packet.empty())
- {
- m_async_result = PacketResult::ErrorSendFailed;
- if (packet_log)
- packet_log->Printf ("async: error: empty async packet");
-
- }
- else
- {
- if (packet_log)
- packet_log->Printf ("async: sending packet");
-
- m_async_result = SendPacketAndWaitForResponse (&m_async_packet[0],
- m_async_packet.size(),
- m_async_response,
- false);
- }
- // Let the other thread that was trying to send the async
- // packet know that the packet has been sent and response is
- // ready...
- m_async_packet_predicate.SetValue(false, eBroadcastAlways);
-
- if (packet_log)
- packet_log->Printf ("async: sent packet, continue_after_async = %i", continue_after_async);
-
- // Set the continue packet to resume if our interrupt
- // for the async packet did cause the stop
- if (continue_after_async)
- {
- // Reverting this for now as it is causing deadlocks
- // in programs (<rdar://problem/11529853>). In the future
- // we should check our thread list and "do the right thing"
- // for new threads that show up while we stop and run async
- // packets. Setting the packet to 'c' to continue all threads
- // is the right thing to do 99.99% of the time because if a
- // thread was single stepping, and we sent an interrupt, we
- // will notice above that we didn't stop due to an interrupt
- // but stopped due to stepping and we would _not_ continue.
- continue_packet.assign (1, 'c');
- continue;
- }
- }
- // Stop with signal and thread info
- state = eStateStopped;
- }
- break;
-
- case 'W':
- case 'X':
- // process exited
- state = eStateExited;
- break;
-
- case 'O':
- // STDOUT
- {
- got_async_packet = true;
- std::string inferior_stdout;
- inferior_stdout.reserve(response.GetBytesLeft () / 2);
-
- uint8_t ch;
- while (response.GetHexU8Ex(ch))
- {
- if (ch != 0)
- inferior_stdout.append(1, (char)ch);
- }
- process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size());
- }
- break;
-
- case 'A':
- // Async miscellaneous reply. Right now, only profile data is coming through this channel.
- {
- got_async_packet = true;
- std::string input = response.GetStringRef().substr(1); // '1' to move beyond 'A'
- if (m_partial_profile_data.length() > 0)
- {
- m_partial_profile_data.append(input);
- input = m_partial_profile_data;
- m_partial_profile_data.clear();
- }
-
- size_t found, pos = 0, len = input.length();
- while ((found = input.find(end_delimiter, pos)) != std::string::npos)
- {
- StringExtractorGDBRemote profileDataExtractor(input.substr(pos, found).c_str());
- std::string profile_data = HarmonizeThreadIdsForProfileData(process, profileDataExtractor);
- process->BroadcastAsyncProfileData (profile_data);
-
- pos = found + end_delimiter_len;
- }
-
- if (pos < len)
- {
- // Last incomplete chunk.
- m_partial_profile_data = input.substr(pos);
- }
- }
- break;
-
- case 'E':
- // ERROR
- state = eStateInvalid;
- break;
-
- default:
- if (log)
- log->Printf ("GDBRemoteCommunicationClient::%s () unrecognized async packet", __FUNCTION__);
- state = eStateInvalid;
- break;
- }
- }
- }
- else
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationClient::%s () ReadPacket(...) => false", __FUNCTION__);
- state = eStateInvalid;
- }
- }
- if (log)
- log->Printf ("GDBRemoteCommunicationClient::%s () => %s", __FUNCTION__, StateAsCString(state));
- response.SetFilePos(0);
- m_private_is_running.SetValue (false, eBroadcastAlways);
- m_public_is_running.SetValue (false, eBroadcastAlways);
- return state;
-}
-
-bool
-GDBRemoteCommunicationClient::SendAsyncSignal (int signo)
-{
- std::lock_guard<std::recursive_mutex> guard(m_async_mutex);
- m_async_signal = signo;
- bool timed_out = false;
- Mutex::Locker locker;
- if (SendInterrupt (locker, 1, timed_out))
- return true;
- m_async_signal = -1;
- return false;
-}
-
-// This function takes a mutex locker as a parameter in case the GetSequenceMutex
-// actually succeeds. If it doesn't succeed in acquiring the sequence mutex
-// (the expected result), then it will send the halt packet. If it does succeed
-// then the caller that requested the interrupt will want to keep the sequence
-// locked down so that no one else can send packets while the caller has control.
-// This function usually gets called when we are running and need to stop the
-// target. It can also be used when we are running and we need to do something
-// else (like read/write memory), so we need to interrupt the running process
-// (gdb remote protocol requires this), and do what we need to do, then resume.
-
-bool
-GDBRemoteCommunicationClient::SendInterrupt
-(
- Mutex::Locker& locker,
- uint32_t seconds_to_wait_for_stop,
- bool &timed_out
-)
-{
- timed_out = false;
- Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
-
- if (IsRunning())
- {
- // Only send an interrupt if our debugserver is running...
- if (GetSequenceMutex (locker))
- {
- if (log)
- log->Printf ("SendInterrupt () - got sequence mutex without having to interrupt");
- }
- else
- {
- // Someone has the mutex locked waiting for a response or for the
- // inferior to stop, so send the interrupt on the down low...
- char ctrl_c = '\x03';
- ConnectionStatus status = eConnectionStatusSuccess;
- size_t bytes_written = Write (&ctrl_c, 1, status, NULL);
- if (log)
- log->PutCString("send packet: \\x03");
- if (bytes_written > 0)
- {
- m_interrupt_sent = true;
- if (seconds_to_wait_for_stop)
- {
- TimeValue timeout;
- if (seconds_to_wait_for_stop)
- {
- timeout = TimeValue::Now();
- timeout.OffsetWithSeconds (seconds_to_wait_for_stop);
- }
- if (m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out))
- {
- if (log)
- log->PutCString ("SendInterrupt () - sent interrupt, private state stopped");
- return true;
- }
- else
- {
- if (log)
- log->Printf ("SendInterrupt () - sent interrupt, timed out wating for async thread resume");
- }
- }
- else
- {
- if (log)
- log->Printf ("SendInterrupt () - sent interrupt, not waiting for stop...");
- return true;
- }
- }
- else
- {
- if (log)
- log->Printf ("SendInterrupt () - failed to write interrupt");
- }
- return false;
- }
- }
- else
- {
- if (log)
- log->Printf ("SendInterrupt () - not running");
- }
- return true;
-}
-
-lldb::pid_t
-GDBRemoteCommunicationClient::GetCurrentProcessID (bool allow_lazy)
-{
- if (allow_lazy && m_curr_pid_is_valid == eLazyBoolYes)
- return m_curr_pid;
-
- // First try to retrieve the pid via the qProcessInfo request.
- GetCurrentProcessInfo (allow_lazy);
- if (m_curr_pid_is_valid == eLazyBoolYes)
- {
- // We really got it.
+ log->Printf("error: failed to get packet sequence mutex, not sending "
+ "packets with prefix '%s'",
+ payload_prefix);
+ return PacketResult::ErrorNoSequenceLock;
+ }
+
+ response_string = "";
+ std::string payload_prefix_str(payload_prefix);
+ unsigned int response_size = 0x1000;
+ if (response_size > GetRemoteMaxPacketSize()) { // May send qSupported packet
+ response_size = GetRemoteMaxPacketSize();
+ }
+
+ for (unsigned int offset = 0; true; offset += response_size) {
+ StringExtractorGDBRemote this_response;
+ // Construct payload
+ char sizeDescriptor[128];
+ snprintf(sizeDescriptor, sizeof(sizeDescriptor), "%x,%x", offset,
+ response_size);
+ PacketResult result = SendPacketAndWaitForResponseNoLock(
+ payload_prefix_str + sizeDescriptor, this_response);
+ if (result != PacketResult::Success)
+ return result;
+
+ const std::string &this_string = this_response.GetStringRef();
+
+ // Check for m or l as first character; l seems to mean this is the last
+ // chunk
+ char first_char = *this_string.c_str();
+ if (first_char != 'm' && first_char != 'l') {
+ return PacketResult::ErrorReplyInvalid;
+ }
+ // Concatenate the result so far (skipping 'm' or 'l')
+ response_string.append(this_string, 1, std::string::npos);
+ if (first_char == 'l')
+ // We're done
+ return PacketResult::Success;
+ }
+}
+
+lldb::pid_t GDBRemoteCommunicationClient::GetCurrentProcessID(bool allow_lazy) {
+ if (allow_lazy && m_curr_pid_is_valid == eLazyBoolYes)
+ return m_curr_pid;
+
+ // First try to retrieve the pid via the qProcessInfo request.
+ GetCurrentProcessInfo(allow_lazy);
+ if (m_curr_pid_is_valid == eLazyBoolYes) {
+ // We really got it.
+ return m_curr_pid;
+ } else {
+ // If we don't get a response for qProcessInfo, check if $qC gives us a
+ // result.
+ // $qC only returns a real process id on older debugserver and lldb-platform
+ // stubs.
+ // The gdb remote protocol documents $qC as returning the thread id, which
+ // newer
+ // debugserver and lldb-gdbserver stubs return correctly.
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse("qC", response, false) ==
+ PacketResult::Success) {
+ if (response.GetChar() == 'Q') {
+ if (response.GetChar() == 'C') {
+ m_curr_pid = response.GetHexMaxU32(false, LLDB_INVALID_PROCESS_ID);
+ if (m_curr_pid != LLDB_INVALID_PROCESS_ID) {
+ m_curr_pid_is_valid = eLazyBoolYes;
+ return m_curr_pid;
+ }
+ }
+ }
+ }
+
+ // If we don't get a response for $qC, check if $qfThreadID gives us a
+ // result.
+ if (m_curr_pid == LLDB_INVALID_PROCESS_ID) {
+ std::vector<lldb::tid_t> thread_ids;
+ bool sequence_mutex_unavailable;
+ size_t size;
+ size = GetCurrentThreadIDs(thread_ids, sequence_mutex_unavailable);
+ if (size && sequence_mutex_unavailable == false) {
+ m_curr_pid = thread_ids.front();
+ m_curr_pid_is_valid = eLazyBoolYes;
return m_curr_pid;
+ }
+ }
+ }
+
+ return LLDB_INVALID_PROCESS_ID;
+}
+
+bool GDBRemoteCommunicationClient::GetLaunchSuccess(std::string &error_str) {
+ error_str.clear();
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse("qLaunchSuccess", response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse())
+ return true;
+ if (response.GetChar() == 'E') {
+ // A string the describes what failed when launching...
+ error_str = response.GetStringRef().substr(1);
+ } else {
+ error_str.assign("unknown error occurred launching process");
+ }
+ } else {
+ error_str.assign("timed out waiting for app to launch");
+ }
+ return false;
+}
+
+int GDBRemoteCommunicationClient::SendArgumentsPacket(
+ const ProcessLaunchInfo &launch_info) {
+ // Since we don't get the send argv0 separate from the executable path, we
+ // need to
+ // make sure to use the actual executable path found in the launch_info...
+ std::vector<const char *> argv;
+ FileSpec exe_file = launch_info.GetExecutableFile();
+ std::string exe_path;
+ const char *arg = NULL;
+ const Args &launch_args = launch_info.GetArguments();
+ if (exe_file)
+ exe_path = exe_file.GetPath(false);
+ else {
+ arg = launch_args.GetArgumentAtIndex(0);
+ if (arg)
+ exe_path = arg;
+ }
+ if (!exe_path.empty()) {
+ argv.push_back(exe_path.c_str());
+ for (uint32_t i = 1; (arg = launch_args.GetArgumentAtIndex(i)) != NULL;
+ ++i) {
+ if (arg)
+ argv.push_back(arg);
+ }
+ }
+ if (!argv.empty()) {
+ StreamString packet;
+ packet.PutChar('A');
+ for (size_t i = 0, n = argv.size(); i < n; ++i) {
+ arg = argv[i];
+ const int arg_len = strlen(arg);
+ if (i > 0)
+ packet.PutChar(',');
+ packet.Printf("%i,%i,", arg_len * 2, (int)i);
+ packet.PutBytesAsRawHex8(arg, arg_len);
}
- else
- {
- // If we don't get a response for qProcessInfo, check if $qC gives us a result.
- // $qC only returns a real process id on older debugserver and lldb-platform stubs.
- // The gdb remote protocol documents $qC as returning the thread id, which newer
- // debugserver and lldb-gdbserver stubs return correctly.
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, false) == PacketResult::Success)
- {
- if (response.GetChar() == 'Q')
- {
- if (response.GetChar() == 'C')
- {
- m_curr_pid = response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID);
- if (m_curr_pid != LLDB_INVALID_PROCESS_ID)
- {
- m_curr_pid_is_valid = eLazyBoolYes;
- return m_curr_pid;
- }
- }
- }
- }
-
- // If we don't get a response for $qC, check if $qfThreadID gives us a result.
- if (m_curr_pid == LLDB_INVALID_PROCESS_ID)
- {
- std::vector<lldb::tid_t> thread_ids;
- bool sequence_mutex_unavailable;
- size_t size;
- size = GetCurrentThreadIDs (thread_ids, sequence_mutex_unavailable);
- if (size && sequence_mutex_unavailable == false)
- {
- m_curr_pid = thread_ids.front();
- m_curr_pid_is_valid = eLazyBoolYes;
- return m_curr_pid;
- }
- }
- }
-
- return LLDB_INVALID_PROCESS_ID;
-}
-bool
-GDBRemoteCommunicationClient::GetLaunchSuccess (std::string &error_str)
-{
- error_str.clear();
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- return true;
- if (response.GetChar() == 'E')
- {
- // A string the describes what failed when launching...
- error_str = response.GetStringRef().substr(1);
- }
- else
- {
- error_str.assign ("unknown error occurred launching process");
- }
- }
- else
- {
- error_str.assign ("timed out waiting for app to launch");
+ if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse())
+ return 0;
+ uint8_t error = response.GetError();
+ if (error)
+ return error;
}
- return false;
+ }
+ return -1;
}
-int
-GDBRemoteCommunicationClient::SendArgumentsPacket (const ProcessLaunchInfo &launch_info)
-{
- // Since we don't get the send argv0 separate from the executable path, we need to
- // make sure to use the actual executable path found in the launch_info...
- std::vector<const char *> argv;
- FileSpec exe_file = launch_info.GetExecutableFile();
- std::string exe_path;
- const char *arg = NULL;
- const Args &launch_args = launch_info.GetArguments();
- if (exe_file)
- exe_path = exe_file.GetPath(false);
- else
- {
- arg = launch_args.GetArgumentAtIndex(0);
- if (arg)
- exe_path = arg;
- }
- if (!exe_path.empty())
- {
- argv.push_back(exe_path.c_str());
- for (uint32_t i=1; (arg = launch_args.GetArgumentAtIndex(i)) != NULL; ++i)
- {
- if (arg)
- argv.push_back(arg);
+int GDBRemoteCommunicationClient::SendEnvironmentPacket(
+ char const *name_equal_value) {
+ if (name_equal_value && name_equal_value[0]) {
+ StreamString packet;
+ bool send_hex_encoding = false;
+ for (const char *p = name_equal_value;
+ *p != '\0' && send_hex_encoding == false; ++p) {
+ if (isprint(*p)) {
+ switch (*p) {
+ case '$':
+ case '#':
+ case '*':
+ case '}':
+ send_hex_encoding = true;
+ break;
+ default:
+ break;
}
+ } else {
+ // We have non printable characters, lets hex encode this...
+ send_hex_encoding = true;
+ }
}
- if (!argv.empty())
- {
- StreamString packet;
- packet.PutChar('A');
- for (size_t i = 0, n = argv.size(); i < n; ++i)
- {
- arg = argv[i];
- const int arg_len = strlen(arg);
- if (i > 0)
- packet.PutChar(',');
- packet.Printf("%i,%i,", arg_len * 2, (int)i);
- packet.PutBytesAsRawHex8 (arg, arg_len);
- }
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- return 0;
- uint8_t error = response.GetError();
- if (error)
- return error;
+ StringExtractorGDBRemote response;
+ if (send_hex_encoding) {
+ if (m_supports_QEnvironmentHexEncoded) {
+ packet.PutCString("QEnvironmentHexEncoded:");
+ packet.PutBytesAsRawHex8(name_equal_value, strlen(name_equal_value));
+ if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse())
+ return 0;
+ uint8_t error = response.GetError();
+ if (error)
+ return error;
+ if (response.IsUnsupportedResponse())
+ m_supports_QEnvironmentHexEncoded = false;
}
- }
- return -1;
-}
+ }
-int
-GDBRemoteCommunicationClient::SendEnvironmentPacket (char const *name_equal_value)
-{
- if (name_equal_value && name_equal_value[0])
- {
- StreamString packet;
- bool send_hex_encoding = false;
- for (const char *p = name_equal_value; *p != '\0' && send_hex_encoding == false; ++p)
- {
- if (isprint(*p))
- {
- switch (*p)
- {
- case '$':
- case '#':
- case '*':
- case '}':
- send_hex_encoding = true;
- break;
- default:
- break;
- }
- }
- else
- {
- // We have non printable characters, lets hex encode this...
- send_hex_encoding = true;
- }
- }
-
- StringExtractorGDBRemote response;
- if (send_hex_encoding)
- {
- if (m_supports_QEnvironmentHexEncoded)
- {
- packet.PutCString("QEnvironmentHexEncoded:");
- packet.PutBytesAsRawHex8 (name_equal_value, strlen(name_equal_value));
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- return 0;
- uint8_t error = response.GetError();
- if (error)
- return error;
- if (response.IsUnsupportedResponse())
- m_supports_QEnvironmentHexEncoded = false;
- }
- }
-
- }
- else if (m_supports_QEnvironment)
- {
- packet.Printf("QEnvironment:%s", name_equal_value);
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- return 0;
- uint8_t error = response.GetError();
- if (error)
- return error;
- if (response.IsUnsupportedResponse())
- m_supports_QEnvironment = false;
- }
- }
+ } else if (m_supports_QEnvironment) {
+ packet.Printf("QEnvironment:%s", name_equal_value);
+ if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse())
+ return 0;
+ uint8_t error = response.GetError();
+ if (error)
+ return error;
+ if (response.IsUnsupportedResponse())
+ m_supports_QEnvironment = false;
+ }
}
- return -1;
+ }
+ return -1;
}
-int
-GDBRemoteCommunicationClient::SendLaunchArchPacket (char const *arch)
-{
- if (arch && arch[0])
- {
- StreamString packet;
- packet.Printf("QLaunchArch:%s", arch);
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- return 0;
- uint8_t error = response.GetError();
- if (error)
- return error;
- }
+int GDBRemoteCommunicationClient::SendLaunchArchPacket(char const *arch) {
+ if (arch && arch[0]) {
+ StreamString packet;
+ packet.Printf("QLaunchArch:%s", arch);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse())
+ return 0;
+ uint8_t error = response.GetError();
+ if (error)
+ return error;
}
- return -1;
+ }
+ return -1;
}
-int
-GDBRemoteCommunicationClient::SendLaunchEventDataPacket (char const *data, bool *was_supported)
-{
- if (data && *data != '\0')
- {
- StreamString packet;
- packet.Printf("QSetProcessEvent:%s", data);
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- {
- if (was_supported)
- *was_supported = true;
- return 0;
- }
- else if (response.IsUnsupportedResponse())
- {
- if (was_supported)
- *was_supported = false;
- return -1;
- }
- else
- {
- uint8_t error = response.GetError();
- if (was_supported)
- *was_supported = true;
- if (error)
- return error;
- }
- }
+int GDBRemoteCommunicationClient::SendLaunchEventDataPacket(
+ char const *data, bool *was_supported) {
+ if (data && *data != '\0') {
+ StreamString packet;
+ packet.Printf("QSetProcessEvent:%s", data);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse()) {
+ if (was_supported)
+ *was_supported = true;
+ return 0;
+ } else if (response.IsUnsupportedResponse()) {
+ if (was_supported)
+ *was_supported = false;
+ return -1;
+ } else {
+ uint8_t error = response.GetError();
+ if (was_supported)
+ *was_supported = true;
+ if (error)
+ return error;
+ }
}
- return -1;
+ }
+ return -1;
}
-bool
-GDBRemoteCommunicationClient::GetOSVersion (uint32_t &major,
- uint32_t &minor,
- uint32_t &update)
-{
- if (GetHostInfo ())
- {
- if (m_os_version_major != UINT32_MAX)
- {
- major = m_os_version_major;
- minor = m_os_version_minor;
- update = m_os_version_update;
- return true;
- }
+bool GDBRemoteCommunicationClient::GetOSVersion(uint32_t &major,
+ uint32_t &minor,
+ uint32_t &update) {
+ if (GetHostInfo()) {
+ if (m_os_version_major != UINT32_MAX) {
+ major = m_os_version_major;
+ minor = m_os_version_minor;
+ update = m_os_version_update;
+ return true;
}
- return false;
+ }
+ return false;
}
-bool
-GDBRemoteCommunicationClient::GetOSBuildString (std::string &s)
-{
- if (GetHostInfo ())
- {
- if (!m_os_build.empty())
- {
- s = m_os_build;
- return true;
- }
+bool GDBRemoteCommunicationClient::GetOSBuildString(std::string &s) {
+ if (GetHostInfo()) {
+ if (!m_os_build.empty()) {
+ s = m_os_build;
+ return true;
}
- s.clear();
- return false;
+ }
+ s.clear();
+ return false;
}
-
-bool
-GDBRemoteCommunicationClient::GetOSKernelDescription (std::string &s)
-{
- if (GetHostInfo ())
- {
- if (!m_os_kernel.empty())
- {
- s = m_os_kernel;
- return true;
- }
+bool GDBRemoteCommunicationClient::GetOSKernelDescription(std::string &s) {
+ if (GetHostInfo()) {
+ if (!m_os_kernel.empty()) {
+ s = m_os_kernel;
+ return true;
}
- s.clear();
- return false;
+ }
+ s.clear();
+ return false;
}
-bool
-GDBRemoteCommunicationClient::GetHostname (std::string &s)
-{
- if (GetHostInfo ())
- {
- if (!m_hostname.empty())
- {
- s = m_hostname;
- return true;
- }
+bool GDBRemoteCommunicationClient::GetHostname(std::string &s) {
+ if (GetHostInfo()) {
+ if (!m_hostname.empty()) {
+ s = m_hostname;
+ return true;
}
- s.clear();
- return false;
+ }
+ s.clear();
+ return false;
}
-ArchSpec
-GDBRemoteCommunicationClient::GetSystemArchitecture ()
-{
- if (GetHostInfo ())
- return m_host_arch;
- return ArchSpec();
+ArchSpec GDBRemoteCommunicationClient::GetSystemArchitecture() {
+ if (GetHostInfo())
+ return m_host_arch;
+ return ArchSpec();
}
const lldb_private::ArchSpec &
-GDBRemoteCommunicationClient::GetProcessArchitecture ()
-{
- if (m_qProcessInfo_is_valid == eLazyBoolCalculate)
- GetCurrentProcessInfo ();
- return m_process_arch;
+GDBRemoteCommunicationClient::GetProcessArchitecture() {
+ if (m_qProcessInfo_is_valid == eLazyBoolCalculate)
+ GetCurrentProcessInfo();
+ return m_process_arch;
}
-bool
-GDBRemoteCommunicationClient::GetGDBServerVersion()
-{
- if (m_qGDBServerVersion_is_valid == eLazyBoolCalculate)
- {
- m_gdb_server_name.clear();
- m_gdb_server_version = 0;
- m_qGDBServerVersion_is_valid = eLazyBoolNo;
-
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse ("qGDBServerVersion", response, false) == PacketResult::Success)
- {
- if (response.IsNormalResponse())
- {
- std::string name;
- std::string value;
- bool success = false;
- while (response.GetNameColonValue(name, value))
- {
- if (name.compare("name") == 0)
- {
- success = true;
- m_gdb_server_name.swap(value);
- }
- else if (name.compare("version") == 0)
- {
- size_t dot_pos = value.find('.');
- if (dot_pos != std::string::npos)
- value[dot_pos] = '\0';
- const uint32_t version = StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0);
- if (version != UINT32_MAX)
- {
- success = true;
- m_gdb_server_version = version;
- }
- }
- }
- if (success)
- m_qGDBServerVersion_is_valid = eLazyBoolYes;
- }
- }
- }
- return m_qGDBServerVersion_is_valid == eLazyBoolYes;
-}
+bool GDBRemoteCommunicationClient::GetGDBServerVersion() {
+ if (m_qGDBServerVersion_is_valid == eLazyBoolCalculate) {
+ m_gdb_server_name.clear();
+ m_gdb_server_version = 0;
+ m_qGDBServerVersion_is_valid = eLazyBoolNo;
-void
-GDBRemoteCommunicationClient::MaybeEnableCompression (std::vector<std::string> supported_compressions)
-{
- CompressionType avail_type = CompressionType::None;
- std::string avail_name;
-
-#if defined (HAVE_LIBCOMPRESSION)
- // libcompression is weak linked so test if compression_decode_buffer() is available
- if (compression_decode_buffer != NULL && avail_type == CompressionType::None)
- {
- for (auto compression : supported_compressions)
- {
- if (compression == "lzfse")
- {
- avail_type = CompressionType::LZFSE;
- avail_name = compression;
- break;
- }
- }
- }
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse("qGDBServerVersion", response, false) ==
+ PacketResult::Success) {
+ if (response.IsNormalResponse()) {
+ llvm::StringRef name, value;
+ bool success = false;
+ while (response.GetNameColonValue(name, value)) {
+ if (name.equals("name")) {
+ success = true;
+ m_gdb_server_name = value;
+ } else if (name.equals("version")) {
+ llvm::StringRef major, minor;
+ std::tie(major, minor) = value.split('.');
+ if (!major.getAsInteger(0, m_gdb_server_version))
+ success = true;
+ }
+ }
+ if (success)
+ m_qGDBServerVersion_is_valid = eLazyBoolYes;
+ }
+ }
+ }
+ return m_qGDBServerVersion_is_valid == eLazyBoolYes;
+}
+
+void GDBRemoteCommunicationClient::MaybeEnableCompression(
+ std::vector<std::string> supported_compressions) {
+ CompressionType avail_type = CompressionType::None;
+ std::string avail_name;
+
+#if defined(HAVE_LIBCOMPRESSION)
+ // libcompression is weak linked so test if compression_decode_buffer() is
+ // available
+ if (compression_decode_buffer != NULL &&
+ avail_type == CompressionType::None) {
+ for (auto compression : supported_compressions) {
+ if (compression == "lzfse") {
+ avail_type = CompressionType::LZFSE;
+ avail_name = compression;
+ break;
+ }
+ }
+ }
#endif
-#if defined (HAVE_LIBCOMPRESSION)
- // libcompression is weak linked so test if compression_decode_buffer() is available
- if (compression_decode_buffer != NULL && avail_type == CompressionType::None)
- {
- for (auto compression : supported_compressions)
- {
- if (compression == "zlib-deflate")
- {
- avail_type = CompressionType::ZlibDeflate;
- avail_name = compression;
- break;
- }
- }
- }
+#if defined(HAVE_LIBCOMPRESSION)
+ // libcompression is weak linked so test if compression_decode_buffer() is
+ // available
+ if (compression_decode_buffer != NULL &&
+ avail_type == CompressionType::None) {
+ for (auto compression : supported_compressions) {
+ if (compression == "zlib-deflate") {
+ avail_type = CompressionType::ZlibDeflate;
+ avail_name = compression;
+ break;
+ }
+ }
+ }
#endif
-#if defined (HAVE_LIBZ)
- if (avail_type == CompressionType::None)
- {
- for (auto compression : supported_compressions)
- {
- if (compression == "zlib-deflate")
- {
- avail_type = CompressionType::ZlibDeflate;
- avail_name = compression;
- break;
- }
- }
+#if defined(HAVE_LIBZ)
+ if (avail_type == CompressionType::None) {
+ for (auto compression : supported_compressions) {
+ if (compression == "zlib-deflate") {
+ avail_type = CompressionType::ZlibDeflate;
+ avail_name = compression;
+ break;
+ }
}
+ }
#endif
-#if defined (HAVE_LIBCOMPRESSION)
- // libcompression is weak linked so test if compression_decode_buffer() is available
- if (compression_decode_buffer != NULL && avail_type == CompressionType::None)
- {
- for (auto compression : supported_compressions)
- {
- if (compression == "lz4")
- {
- avail_type = CompressionType::LZ4;
- avail_name = compression;
- break;
- }
- }
- }
+#if defined(HAVE_LIBCOMPRESSION)
+ // libcompression is weak linked so test if compression_decode_buffer() is
+ // available
+ if (compression_decode_buffer != NULL &&
+ avail_type == CompressionType::None) {
+ for (auto compression : supported_compressions) {
+ if (compression == "lz4") {
+ avail_type = CompressionType::LZ4;
+ avail_name = compression;
+ break;
+ }
+ }
+ }
#endif
-#if defined (HAVE_LIBCOMPRESSION)
- // libcompression is weak linked so test if compression_decode_buffer() is available
- if (compression_decode_buffer != NULL && avail_type == CompressionType::None)
- {
- for (auto compression : supported_compressions)
- {
- if (compression == "lzma")
- {
- avail_type = CompressionType::LZMA;
- avail_name = compression;
- break;
- }
- }
- }
+#if defined(HAVE_LIBCOMPRESSION)
+ // libcompression is weak linked so test if compression_decode_buffer() is
+ // available
+ if (compression_decode_buffer != NULL &&
+ avail_type == CompressionType::None) {
+ for (auto compression : supported_compressions) {
+ if (compression == "lzma") {
+ avail_type = CompressionType::LZMA;
+ avail_name = compression;
+ break;
+ }
+ }
+ }
#endif
- if (avail_type != CompressionType::None)
- {
- StringExtractorGDBRemote response;
- std::string packet = "QEnableCompression:type:" + avail_name + ";";
- if (SendPacketAndWaitForResponse (packet.c_str(), response, false) != PacketResult::Success)
- return;
-
- if (response.IsOKResponse())
- {
- m_compression_type = avail_type;
- }
- }
-}
+ if (avail_type != CompressionType::None) {
+ StringExtractorGDBRemote response;
+ std::string packet = "QEnableCompression:type:" + avail_name + ";";
+ if (SendPacketAndWaitForResponse(packet, response, false) !=
+ PacketResult::Success)
+ return;
-const char *
-GDBRemoteCommunicationClient::GetGDBServerProgramName()
-{
- if (GetGDBServerVersion())
- {
- if (!m_gdb_server_name.empty())
- return m_gdb_server_name.c_str();
+ if (response.IsOKResponse()) {
+ m_compression_type = avail_type;
}
- return NULL;
+ }
}
-uint32_t
-GDBRemoteCommunicationClient::GetGDBServerProgramVersion()
-{
- if (GetGDBServerVersion())
- return m_gdb_server_version;
- return 0;
+const char *GDBRemoteCommunicationClient::GetGDBServerProgramName() {
+ if (GetGDBServerVersion()) {
+ if (!m_gdb_server_name.empty())
+ return m_gdb_server_name.c_str();
+ }
+ return NULL;
}
-bool
-GDBRemoteCommunicationClient::GetDefaultThreadId (lldb::tid_t &tid)
-{
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("qC",response,false) != PacketResult::Success)
- return false;
-
- if (!response.IsNormalResponse())
- return false;
-
- if (response.GetChar() == 'Q' && response.GetChar() == 'C')
- tid = response.GetHexMaxU32(true, -1);
-
- return true;
+uint32_t GDBRemoteCommunicationClient::GetGDBServerProgramVersion() {
+ if (GetGDBServerVersion())
+ return m_gdb_server_version;
+ return 0;
}
-bool
-GDBRemoteCommunicationClient::GetHostInfo (bool force)
-{
- Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS));
-
- if (force || m_qHostInfo_is_valid == eLazyBoolCalculate)
- {
- m_qHostInfo_is_valid = eLazyBoolNo;
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse ("qHostInfo", response, false) == PacketResult::Success)
- {
- if (response.IsNormalResponse())
- {
- std::string name;
- std::string value;
- uint32_t cpu = LLDB_INVALID_CPUTYPE;
- uint32_t sub = 0;
- std::string arch_name;
- std::string os_name;
- std::string vendor_name;
- std::string triple;
- std::string distribution_id;
- uint32_t pointer_byte_size = 0;
- StringExtractor extractor;
- ByteOrder byte_order = eByteOrderInvalid;
- uint32_t num_keys_decoded = 0;
- while (response.GetNameColonValue(name, value))
- {
- if (name.compare("cputype") == 0)
- {
- // exception type in big endian hex
- cpu = StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
- if (cpu != LLDB_INVALID_CPUTYPE)
- ++num_keys_decoded;
- }
- else if (name.compare("cpusubtype") == 0)
- {
- // exception count in big endian hex
- sub = StringConvert::ToUInt32 (value.c_str(), 0, 0);
- if (sub != 0)
- ++num_keys_decoded;
- }
- else if (name.compare("arch") == 0)
- {
- arch_name.swap (value);
- ++num_keys_decoded;
- }
- else if (name.compare("triple") == 0)
- {
- extractor.GetStringRef ().swap (value);
- extractor.SetFilePos(0);
- extractor.GetHexByteString (triple);
- ++num_keys_decoded;
- }
- else if (name.compare ("distribution_id") == 0)
- {
- extractor.GetStringRef ().swap (value);
- extractor.SetFilePos (0);
- extractor.GetHexByteString (distribution_id);
- ++num_keys_decoded;
- }
- else if (name.compare("os_build") == 0)
- {
- extractor.GetStringRef().swap(value);
- extractor.SetFilePos(0);
- extractor.GetHexByteString (m_os_build);
- ++num_keys_decoded;
- }
- else if (name.compare("hostname") == 0)
- {
- extractor.GetStringRef().swap(value);
- extractor.SetFilePos(0);
- extractor.GetHexByteString (m_hostname);
- ++num_keys_decoded;
- }
- else if (name.compare("os_kernel") == 0)
- {
- extractor.GetStringRef().swap(value);
- extractor.SetFilePos(0);
- extractor.GetHexByteString (m_os_kernel);
- ++num_keys_decoded;
- }
- else if (name.compare("ostype") == 0)
- {
- os_name.swap (value);
- ++num_keys_decoded;
- }
- else if (name.compare("vendor") == 0)
- {
- vendor_name.swap(value);
- ++num_keys_decoded;
- }
- else if (name.compare("endian") == 0)
- {
- ++num_keys_decoded;
- if (value.compare("little") == 0)
- byte_order = eByteOrderLittle;
- else if (value.compare("big") == 0)
- byte_order = eByteOrderBig;
- else if (value.compare("pdp") == 0)
- byte_order = eByteOrderPDP;
- else
- --num_keys_decoded;
- }
- else if (name.compare("ptrsize") == 0)
- {
- pointer_byte_size = StringConvert::ToUInt32 (value.c_str(), 0, 0);
- if (pointer_byte_size != 0)
- ++num_keys_decoded;
- }
- else if ((name.compare("os_version") == 0) ||
- (name.compare("version") == 0)) // Older debugserver binaries used the "version" key instead of "os_version"...
- {
- Args::StringToVersion (value.c_str(),
- m_os_version_major,
- m_os_version_minor,
- m_os_version_update);
- if (m_os_version_major != UINT32_MAX)
- ++num_keys_decoded;
- }
- else if (name.compare("watchpoint_exceptions_received") == 0)
- {
- ++num_keys_decoded;
- if (strcmp(value.c_str(),"before") == 0)
- m_watchpoints_trigger_after_instruction = eLazyBoolNo;
- else if (strcmp(value.c_str(),"after") == 0)
- m_watchpoints_trigger_after_instruction = eLazyBoolYes;
- else
- --num_keys_decoded;
- }
- else if (name.compare("default_packet_timeout") == 0)
- {
- m_default_packet_timeout = StringConvert::ToUInt32(value.c_str(), 0);
- if (m_default_packet_timeout > 0)
- {
- SetPacketTimeout(m_default_packet_timeout);
- ++num_keys_decoded;
- }
- }
+bool GDBRemoteCommunicationClient::GetDefaultThreadId(lldb::tid_t &tid) {
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse("qC", response, false) !=
+ PacketResult::Success)
+ return false;
- }
-
- if (num_keys_decoded > 0)
- m_qHostInfo_is_valid = eLazyBoolYes;
-
- if (triple.empty())
- {
- if (arch_name.empty())
- {
- if (cpu != LLDB_INVALID_CPUTYPE)
- {
- m_host_arch.SetArchitecture (eArchTypeMachO, cpu, sub);
- if (pointer_byte_size)
- {
- assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
- }
- if (byte_order != eByteOrderInvalid)
- {
- assert (byte_order == m_host_arch.GetByteOrder());
- }
-
- if (!vendor_name.empty())
- m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
- if (!os_name.empty())
- m_host_arch.GetTriple().setOSName (llvm::StringRef (os_name));
-
- }
- }
- else
- {
- std::string triple;
- triple += arch_name;
- if (!vendor_name.empty() || !os_name.empty())
- {
- triple += '-';
- if (vendor_name.empty())
- triple += "unknown";
- else
- triple += vendor_name;
- triple += '-';
- if (os_name.empty())
- triple += "unknown";
- else
- triple += os_name;
- }
- m_host_arch.SetTriple (triple.c_str());
-
- llvm::Triple &host_triple = m_host_arch.GetTriple();
- if (host_triple.getVendor() == llvm::Triple::Apple && host_triple.getOS() == llvm::Triple::Darwin)
- {
- switch (m_host_arch.GetMachine())
- {
- case llvm::Triple::aarch64:
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- host_triple.setOS(llvm::Triple::IOS);
- break;
- default:
- host_triple.setOS(llvm::Triple::MacOSX);
- break;
- }
- }
- if (pointer_byte_size)
- {
- assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
- }
- if (byte_order != eByteOrderInvalid)
- {
- assert (byte_order == m_host_arch.GetByteOrder());
- }
-
- }
- }
- else
- {
- m_host_arch.SetTriple (triple.c_str());
- if (pointer_byte_size)
- {
- assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
- }
- if (byte_order != eByteOrderInvalid)
- {
- assert (byte_order == m_host_arch.GetByteOrder());
- }
+ if (!response.IsNormalResponse())
+ return false;
- if (log)
- log->Printf ("GDBRemoteCommunicationClient::%s parsed host architecture as %s, triple as %s from triple text %s", __FUNCTION__, m_host_arch.GetArchitectureName () ? m_host_arch.GetArchitectureName () : "<null-arch-name>", m_host_arch.GetTriple ().getTriple ().c_str(), triple.c_str ());
- }
- if (!distribution_id.empty ())
- m_host_arch.SetDistributionId (distribution_id.c_str ());
- }
- }
- }
- return m_qHostInfo_is_valid == eLazyBoolYes;
-}
+ if (response.GetChar() == 'Q' && response.GetChar() == 'C')
+ tid = response.GetHexMaxU32(true, -1);
-int
-GDBRemoteCommunicationClient::SendAttach
-(
- lldb::pid_t pid,
- StringExtractorGDBRemote& response
-)
-{
- if (pid != LLDB_INVALID_PROCESS_ID)
- {
- char packet[64];
- const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%" PRIx64, pid);
- assert (packet_len < (int)sizeof(packet));
- if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.IsErrorResponse())
- return response.GetError();
- return 0;
- }
- }
- return -1;
+ return true;
}
-int
-GDBRemoteCommunicationClient::SendStdinNotification (const char* data, size_t data_len)
-{
- StreamString packet;
- packet.PutCString("I");
- packet.PutBytesAsRawHex8(data, data_len);
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
- {
- return 0;
- }
- return response.GetError();
+bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS));
+ if (force || m_qHostInfo_is_valid == eLazyBoolCalculate) {
+ m_qHostInfo_is_valid = eLazyBoolNo;
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse("qHostInfo", response, false) ==
+ PacketResult::Success) {
+ if (response.IsNormalResponse()) {
+ llvm::StringRef name;
+ llvm::StringRef value;
+ uint32_t cpu = LLDB_INVALID_CPUTYPE;
+ uint32_t sub = 0;
+ std::string arch_name;
+ std::string os_name;
+ std::string vendor_name;
+ std::string triple;
+ std::string distribution_id;
+ uint32_t pointer_byte_size = 0;
+ ByteOrder byte_order = eByteOrderInvalid;
+ uint32_t num_keys_decoded = 0;
+ while (response.GetNameColonValue(name, value)) {
+ if (name.equals("cputype")) {
+ // exception type in big endian hex
+ if (!value.getAsInteger(0, cpu))
+ ++num_keys_decoded;
+ } else if (name.equals("cpusubtype")) {
+ // exception count in big endian hex
+ if (!value.getAsInteger(0, sub))
+ ++num_keys_decoded;
+ } else if (name.equals("arch")) {
+ arch_name = value;
+ ++num_keys_decoded;
+ } else if (name.equals("triple")) {
+ StringExtractor extractor(value);
+ extractor.GetHexByteString(triple);
+ ++num_keys_decoded;
+ } else if (name.equals("distribution_id")) {
+ StringExtractor extractor(value);
+ extractor.GetHexByteString(distribution_id);
+ ++num_keys_decoded;
+ } else if (name.equals("os_build")) {
+ StringExtractor extractor(value);
+ extractor.GetHexByteString(m_os_build);
+ ++num_keys_decoded;
+ } else if (name.equals("hostname")) {
+ StringExtractor extractor(value);
+ extractor.GetHexByteString(m_hostname);
+ ++num_keys_decoded;
+ } else if (name.equals("os_kernel")) {
+ StringExtractor extractor(value);
+ extractor.GetHexByteString(m_os_kernel);
+ ++num_keys_decoded;
+ } else if (name.equals("ostype")) {
+ os_name = value;
+ ++num_keys_decoded;
+ } else if (name.equals("vendor")) {
+ vendor_name = value;
+ ++num_keys_decoded;
+ } else if (name.equals("endian")) {
+ byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
+ .Case("little", eByteOrderLittle)
+ .Case("big", eByteOrderBig)
+ .Case("pdp", eByteOrderPDP)
+ .Default(eByteOrderInvalid);
+ if (byte_order != eByteOrderInvalid)
+ ++num_keys_decoded;
+ } else if (name.equals("ptrsize")) {
+ if (!value.getAsInteger(0, pointer_byte_size))
+ ++num_keys_decoded;
+ } else if (name.equals("os_version") ||
+ name.equals(
+ "version")) // Older debugserver binaries used the
+ // "version" key instead of
+ // "os_version"...
+ {
+ Args::StringToVersion(value, m_os_version_major, m_os_version_minor,
+ m_os_version_update);
+ if (m_os_version_major != UINT32_MAX)
+ ++num_keys_decoded;
+ } else if (name.equals("watchpoint_exceptions_received")) {
+ m_watchpoints_trigger_after_instruction =
+ llvm::StringSwitch<LazyBool>(value)
+ .Case("before", eLazyBoolNo)
+ .Case("after", eLazyBoolYes)
+ .Default(eLazyBoolCalculate);
+ if (m_watchpoints_trigger_after_instruction != eLazyBoolCalculate)
+ ++num_keys_decoded;
+ } else if (name.equals("default_packet_timeout")) {
+ uint32_t timeout_seconds;
+ if (!value.getAsInteger(0, timeout_seconds)) {
+ m_default_packet_timeout = seconds(timeout_seconds);
+ SetPacketTimeout(m_default_packet_timeout);
+ ++num_keys_decoded;
+ }
+ }
+ }
+
+ if (num_keys_decoded > 0)
+ m_qHostInfo_is_valid = eLazyBoolYes;
+
+ if (triple.empty()) {
+ if (arch_name.empty()) {
+ if (cpu != LLDB_INVALID_CPUTYPE) {
+ m_host_arch.SetArchitecture(eArchTypeMachO, cpu, sub);
+ if (pointer_byte_size) {
+ assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
+ }
+ if (byte_order != eByteOrderInvalid) {
+ assert(byte_order == m_host_arch.GetByteOrder());
+ }
+
+ if (!vendor_name.empty())
+ m_host_arch.GetTriple().setVendorName(
+ llvm::StringRef(vendor_name));
+ if (!os_name.empty())
+ m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
+ }
+ } else {
+ std::string triple;
+ triple += arch_name;
+ if (!vendor_name.empty() || !os_name.empty()) {
+ triple += '-';
+ if (vendor_name.empty())
+ triple += "unknown";
+ else
+ triple += vendor_name;
+ triple += '-';
+ if (os_name.empty())
+ triple += "unknown";
+ else
+ triple += os_name;
+ }
+ m_host_arch.SetTriple(triple.c_str());
+
+ llvm::Triple &host_triple = m_host_arch.GetTriple();
+ if (host_triple.getVendor() == llvm::Triple::Apple &&
+ host_triple.getOS() == llvm::Triple::Darwin) {
+ switch (m_host_arch.GetMachine()) {
+ case llvm::Triple::aarch64:
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ host_triple.setOS(llvm::Triple::IOS);
+ break;
+ default:
+ host_triple.setOS(llvm::Triple::MacOSX);
+ break;
+ }
+ }
+ if (pointer_byte_size) {
+ assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
+ }
+ if (byte_order != eByteOrderInvalid) {
+ assert(byte_order == m_host_arch.GetByteOrder());
+ }
+ }
+ } else {
+ m_host_arch.SetTriple(triple.c_str());
+ if (pointer_byte_size) {
+ assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
+ }
+ if (byte_order != eByteOrderInvalid) {
+ assert(byte_order == m_host_arch.GetByteOrder());
+ }
+
+ if (log)
+ log->Printf("GDBRemoteCommunicationClient::%s parsed host "
+ "architecture as %s, triple as %s from triple text %s",
+ __FUNCTION__, m_host_arch.GetArchitectureName()
+ ? m_host_arch.GetArchitectureName()
+ : "<null-arch-name>",
+ m_host_arch.GetTriple().getTriple().c_str(),
+ triple.c_str());
+ }
+ if (!distribution_id.empty())
+ m_host_arch.SetDistributionId(distribution_id.c_str());
+ }
+ }
+ }
+ return m_qHostInfo_is_valid == eLazyBoolYes;
+}
+
+int GDBRemoteCommunicationClient::SendAttach(
+ lldb::pid_t pid, StringExtractorGDBRemote &response) {
+ if (pid != LLDB_INVALID_PROCESS_ID) {
+ char packet[64];
+ const int packet_len =
+ ::snprintf(packet, sizeof(packet), "vAttach;%" PRIx64, pid);
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
+ assert(packet_len < (int)sizeof(packet));
+ if (SendPacketAndWaitForResponse(packet, response, false) ==
+ PacketResult::Success) {
+ if (response.IsErrorResponse())
+ return response.GetError();
+ return 0;
+ }
+ }
+ return -1;
+}
+
+int GDBRemoteCommunicationClient::SendStdinNotification(const char *data,
+ size_t data_len) {
+ StreamString packet;
+ packet.PutCString("I");
+ packet.PutBytesAsRawHex8(data, data_len);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ PacketResult::Success) {
+ return 0;
+ }
+ return response.GetError();
}
const lldb_private::ArchSpec &
-GDBRemoteCommunicationClient::GetHostArchitecture ()
-{
- if (m_qHostInfo_is_valid == eLazyBoolCalculate)
- GetHostInfo ();
- return m_host_arch;
+GDBRemoteCommunicationClient::GetHostArchitecture() {
+ if (m_qHostInfo_is_valid == eLazyBoolCalculate)
+ GetHostInfo();
+ return m_host_arch;
}
-uint32_t
-GDBRemoteCommunicationClient::GetHostDefaultPacketTimeout ()
-{
- if (m_qHostInfo_is_valid == eLazyBoolCalculate)
- GetHostInfo ();
- return m_default_packet_timeout;
+seconds GDBRemoteCommunicationClient::GetHostDefaultPacketTimeout() {
+ if (m_qHostInfo_is_valid == eLazyBoolCalculate)
+ GetHostInfo();
+ return m_default_packet_timeout;
}
-addr_t
-GDBRemoteCommunicationClient::AllocateMemory (size_t size, uint32_t permissions)
-{
- if (m_supports_alloc_dealloc_memory != eLazyBoolNo)
- {
- m_supports_alloc_dealloc_memory = eLazyBoolYes;
- char packet[64];
- const int packet_len = ::snprintf (packet, sizeof(packet), "_M%" PRIx64 ",%s%s%s",
- (uint64_t)size,
- permissions & lldb::ePermissionsReadable ? "r" : "",
- permissions & lldb::ePermissionsWritable ? "w" : "",
- permissions & lldb::ePermissionsExecutable ? "x" : "");
- assert (packet_len < (int)sizeof(packet));
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.IsUnsupportedResponse())
- m_supports_alloc_dealloc_memory = eLazyBoolNo;
- else if (!response.IsErrorResponse())
- return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
- }
- else
- {
- m_supports_alloc_dealloc_memory = eLazyBoolNo;
- }
- }
- return LLDB_INVALID_ADDRESS;
+addr_t GDBRemoteCommunicationClient::AllocateMemory(size_t size,
+ uint32_t permissions) {
+ if (m_supports_alloc_dealloc_memory != eLazyBoolNo) {
+ m_supports_alloc_dealloc_memory = eLazyBoolYes;
+ char packet[64];
+ const int packet_len = ::snprintf(
+ packet, sizeof(packet), "_M%" PRIx64 ",%s%s%s", (uint64_t)size,
+ permissions & lldb::ePermissionsReadable ? "r" : "",
+ permissions & lldb::ePermissionsWritable ? "w" : "",
+ permissions & lldb::ePermissionsExecutable ? "x" : "");
+ assert(packet_len < (int)sizeof(packet));
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet, response, false) ==
+ PacketResult::Success) {
+ if (response.IsUnsupportedResponse())
+ m_supports_alloc_dealloc_memory = eLazyBoolNo;
+ else if (!response.IsErrorResponse())
+ return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
+ } else {
+ m_supports_alloc_dealloc_memory = eLazyBoolNo;
+ }
+ }
+ return LLDB_INVALID_ADDRESS;
+}
+
+bool GDBRemoteCommunicationClient::DeallocateMemory(addr_t addr) {
+ if (m_supports_alloc_dealloc_memory != eLazyBoolNo) {
+ m_supports_alloc_dealloc_memory = eLazyBoolYes;
+ char packet[64];
+ const int packet_len =
+ ::snprintf(packet, sizeof(packet), "_m%" PRIx64, (uint64_t)addr);
+ assert(packet_len < (int)sizeof(packet));
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet, response, false) ==
+ PacketResult::Success) {
+ if (response.IsUnsupportedResponse())
+ m_supports_alloc_dealloc_memory = eLazyBoolNo;
+ else if (response.IsOKResponse())
+ return true;
+ } else {
+ m_supports_alloc_dealloc_memory = eLazyBoolNo;
+ }
+ }
+ return false;
+}
+
+Error GDBRemoteCommunicationClient::Detach(bool keep_stopped) {
+ Error error;
+
+ if (keep_stopped) {
+ if (m_supports_detach_stay_stopped == eLazyBoolCalculate) {
+ char packet[64];
+ const int packet_len =
+ ::snprintf(packet, sizeof(packet), "qSupportsDetachAndStayStopped:");
+ assert(packet_len < (int)sizeof(packet));
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet, response, false) ==
+ PacketResult::Success &&
+ response.IsOKResponse()) {
+ m_supports_detach_stay_stopped = eLazyBoolYes;
+ } else {
+ m_supports_detach_stay_stopped = eLazyBoolNo;
+ }
+ }
+
+ if (m_supports_detach_stay_stopped == eLazyBoolNo) {
+ error.SetErrorString("Stays stopped not supported by this target.");
+ return error;
+ } else {
+ StringExtractorGDBRemote response;
+ PacketResult packet_result =
+ SendPacketAndWaitForResponse("D1", response, false);
+ if (packet_result != PacketResult::Success)
+ error.SetErrorString("Sending extended disconnect packet failed.");
+ }
+ } else {
+ StringExtractorGDBRemote response;
+ PacketResult packet_result =
+ SendPacketAndWaitForResponse("D", response, false);
+ if (packet_result != PacketResult::Success)
+ error.SetErrorString("Sending disconnect packet failed.");
+ }
+ return error;
}
-bool
-GDBRemoteCommunicationClient::DeallocateMemory (addr_t addr)
-{
- if (m_supports_alloc_dealloc_memory != eLazyBoolNo)
- {
- m_supports_alloc_dealloc_memory = eLazyBoolYes;
- char packet[64];
- const int packet_len = ::snprintf(packet, sizeof(packet), "_m%" PRIx64, (uint64_t)addr);
- assert (packet_len < (int)sizeof(packet));
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.IsUnsupportedResponse())
- m_supports_alloc_dealloc_memory = eLazyBoolNo;
- else if (response.IsOKResponse())
- return true;
- }
- else
- {
- m_supports_alloc_dealloc_memory = eLazyBoolNo;
- }
- }
- return false;
-}
+Error GDBRemoteCommunicationClient::GetMemoryRegionInfo(
+ lldb::addr_t addr, lldb_private::MemoryRegionInfo &region_info) {
+ Error error;
+ region_info.Clear();
-Error
-GDBRemoteCommunicationClient::Detach (bool keep_stopped)
-{
- Error error;
-
- if (keep_stopped)
- {
- if (m_supports_detach_stay_stopped == eLazyBoolCalculate)
- {
- char packet[64];
- const int packet_len = ::snprintf(packet, sizeof(packet), "qSupportsDetachAndStayStopped:");
- assert (packet_len < (int)sizeof(packet));
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success
- && response.IsOKResponse())
- {
- m_supports_detach_stay_stopped = eLazyBoolYes;
- }
+ if (m_supports_memory_region_info != eLazyBoolNo) {
+ m_supports_memory_region_info = eLazyBoolYes;
+ char packet[64];
+ const int packet_len = ::snprintf(
+ packet, sizeof(packet), "qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);
+ assert(packet_len < (int)sizeof(packet));
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet, response, false) ==
+ PacketResult::Success) {
+ llvm::StringRef name;
+ llvm::StringRef value;
+ addr_t addr_value = LLDB_INVALID_ADDRESS;
+ bool success = true;
+ bool saw_permissions = false;
+ while (success && response.GetNameColonValue(name, value)) {
+ if (name.equals("start")) {
+ if (!value.getAsInteger(16, addr_value))
+ region_info.GetRange().SetRangeBase(addr_value);
+ } else if (name.equals("size")) {
+ if (!value.getAsInteger(16, addr_value))
+ region_info.GetRange().SetByteSize(addr_value);
+ } else if (name.equals("permissions") &&
+ region_info.GetRange().IsValid()) {
+ saw_permissions = true;
+ if (region_info.GetRange().Contains(addr)) {
+ if (value.find('r') != llvm::StringRef::npos)
+ region_info.SetReadable(MemoryRegionInfo::eYes);
else
- {
- m_supports_detach_stay_stopped = eLazyBoolNo;
- }
- }
+ region_info.SetReadable(MemoryRegionInfo::eNo);
- if (m_supports_detach_stay_stopped == eLazyBoolNo)
- {
- error.SetErrorString("Stays stopped not supported by this target.");
- return error;
- }
- else
- {
- StringExtractorGDBRemote response;
- PacketResult packet_result = SendPacketAndWaitForResponse ("D1", 2, response, false);
- if (packet_result != PacketResult::Success)
- error.SetErrorString ("Sending extended disconnect packet failed.");
- }
- }
- else
- {
- StringExtractorGDBRemote response;
- PacketResult packet_result = SendPacketAndWaitForResponse ("D", 1, response, false);
- if (packet_result != PacketResult::Success)
- error.SetErrorString ("Sending disconnect packet failed.");
- }
- return error;
-}
+ if (value.find('w') != llvm::StringRef::npos)
+ region_info.SetWritable(MemoryRegionInfo::eYes);
+ else
+ region_info.SetWritable(MemoryRegionInfo::eNo);
-Error
-GDBRemoteCommunicationClient::GetMemoryRegionInfo (lldb::addr_t addr,
- lldb_private::MemoryRegionInfo &region_info)
-{
- Error error;
+ if (value.find('x') != llvm::StringRef::npos)
+ region_info.SetExecutable(MemoryRegionInfo::eYes);
+ else
+ region_info.SetExecutable(MemoryRegionInfo::eNo);
+
+ region_info.SetMapped(MemoryRegionInfo::eYes);
+ } else {
+ // The reported region does not contain this address -- we're
+ // looking at an unmapped page
+ region_info.SetReadable(MemoryRegionInfo::eNo);
+ region_info.SetWritable(MemoryRegionInfo::eNo);
+ region_info.SetExecutable(MemoryRegionInfo::eNo);
+ region_info.SetMapped(MemoryRegionInfo::eNo);
+ }
+ } else if (name.equals("name")) {
+ StringExtractorGDBRemote name_extractor(value);
+ std::string name;
+ name_extractor.GetHexByteString(name);
+ region_info.SetName(name.c_str());
+ } else if (name.equals("error")) {
+ StringExtractorGDBRemote error_extractor(value);
+ std::string error_string;
+ // Now convert the HEX bytes into a string value
+ error_extractor.GetHexByteString(error_string);
+ error.SetErrorString(error_string.c_str());
+ }
+ }
+
+ // We got a valid address range back but no permissions -- which means
+ // this is an unmapped page
+ if (region_info.GetRange().IsValid() && saw_permissions == false) {
+ region_info.SetReadable(MemoryRegionInfo::eNo);
+ region_info.SetWritable(MemoryRegionInfo::eNo);
+ region_info.SetExecutable(MemoryRegionInfo::eNo);
+ region_info.SetMapped(MemoryRegionInfo::eNo);
+ }
+ } else {
+ m_supports_memory_region_info = eLazyBoolNo;
+ }
+ }
+
+ if (m_supports_memory_region_info == eLazyBoolNo) {
+ error.SetErrorString("qMemoryRegionInfo is not supported");
+ }
+ if (error.Fail())
region_info.Clear();
-
- if (m_supports_memory_region_info != eLazyBoolNo)
- {
- m_supports_memory_region_info = eLazyBoolYes;
- char packet[64];
- const int packet_len = ::snprintf(packet, sizeof(packet), "qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);
- assert (packet_len < (int)sizeof(packet));
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
- {
- std::string name;
- std::string value;
- addr_t addr_value;
- bool success = true;
- bool saw_permissions = false;
- while (success && response.GetNameColonValue(name, value))
- {
- if (name.compare ("start") == 0)
- {
- addr_value = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_ADDRESS, 16, &success);
- if (success)
- region_info.GetRange().SetRangeBase(addr_value);
- }
- else if (name.compare ("size") == 0)
- {
- addr_value = StringConvert::ToUInt64(value.c_str(), 0, 16, &success);
- if (success)
- region_info.GetRange().SetByteSize (addr_value);
- }
- else if (name.compare ("permissions") == 0 && region_info.GetRange().IsValid())
- {
- saw_permissions = true;
- if (region_info.GetRange().Contains (addr))
- {
- if (value.find('r') != std::string::npos)
- region_info.SetReadable (MemoryRegionInfo::eYes);
- else
- region_info.SetReadable (MemoryRegionInfo::eNo);
-
- if (value.find('w') != std::string::npos)
- region_info.SetWritable (MemoryRegionInfo::eYes);
- else
- region_info.SetWritable (MemoryRegionInfo::eNo);
-
- if (value.find('x') != std::string::npos)
- region_info.SetExecutable (MemoryRegionInfo::eYes);
- else
- region_info.SetExecutable (MemoryRegionInfo::eNo);
-
- region_info.SetMapped(MemoryRegionInfo::eYes);
- }
- else
- {
- // The reported region does not contain this address -- we're looking at an unmapped page
- region_info.SetReadable (MemoryRegionInfo::eNo);
- region_info.SetWritable (MemoryRegionInfo::eNo);
- region_info.SetExecutable (MemoryRegionInfo::eNo);
- region_info.SetMapped(MemoryRegionInfo::eNo);
- }
- }
- else if (name.compare ("error") == 0)
- {
- StringExtractorGDBRemote name_extractor;
- // Swap "value" over into "name_extractor"
- name_extractor.GetStringRef().swap(value);
- // Now convert the HEX bytes into a string value
- name_extractor.GetHexByteString (value);
- error.SetErrorString(value.c_str());
- }
- }
-
- // We got a valid address range back but no permissions -- which means this is an unmapped page
- if (region_info.GetRange().IsValid() && saw_permissions == false)
- {
- region_info.SetReadable (MemoryRegionInfo::eNo);
- region_info.SetWritable (MemoryRegionInfo::eNo);
- region_info.SetExecutable (MemoryRegionInfo::eNo);
- region_info.SetMapped(MemoryRegionInfo::eNo);
- }
- }
- else
- {
- m_supports_memory_region_info = eLazyBoolNo;
- }
- }
-
- if (m_supports_memory_region_info == eLazyBoolNo)
- {
- error.SetErrorString("qMemoryRegionInfo is not supported");
- }
- if (error.Fail())
- region_info.Clear();
- return error;
-
+ return error;
}
-Error
-GDBRemoteCommunicationClient::GetWatchpointSupportInfo (uint32_t &num)
-{
- Error error;
+Error GDBRemoteCommunicationClient::GetWatchpointSupportInfo(uint32_t &num) {
+ Error error;
- if (m_supports_watchpoint_support_info == eLazyBoolYes)
- {
- num = m_num_supported_hardware_watchpoints;
- return error;
- }
+ if (m_supports_watchpoint_support_info == eLazyBoolYes) {
+ num = m_num_supported_hardware_watchpoints;
+ return error;
+ }
- // Set num to 0 first.
- num = 0;
- if (m_supports_watchpoint_support_info != eLazyBoolNo)
- {
- char packet[64];
- const int packet_len = ::snprintf(packet, sizeof(packet), "qWatchpointSupportInfo:");
- assert (packet_len < (int)sizeof(packet));
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
- {
- m_supports_watchpoint_support_info = eLazyBoolYes;
- std::string name;
- std::string value;
- while (response.GetNameColonValue(name, value))
- {
- if (name.compare ("num") == 0)
- {
- num = StringConvert::ToUInt32(value.c_str(), 0, 0);
- m_num_supported_hardware_watchpoints = num;
- }
- }
- }
- else
- {
- m_supports_watchpoint_support_info = eLazyBoolNo;
+ // Set num to 0 first.
+ num = 0;
+ if (m_supports_watchpoint_support_info != eLazyBoolNo) {
+ char packet[64];
+ const int packet_len =
+ ::snprintf(packet, sizeof(packet), "qWatchpointSupportInfo:");
+ assert(packet_len < (int)sizeof(packet));
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet, response, false) ==
+ PacketResult::Success) {
+ m_supports_watchpoint_support_info = eLazyBoolYes;
+ llvm::StringRef name;
+ llvm::StringRef value;
+ while (response.GetNameColonValue(name, value)) {
+ if (name.equals("num")) {
+ value.getAsInteger(0, m_num_supported_hardware_watchpoints);
+ num = m_num_supported_hardware_watchpoints;
}
+ }
+ } else {
+ m_supports_watchpoint_support_info = eLazyBoolNo;
}
+ }
- if (m_supports_watchpoint_support_info == eLazyBoolNo)
- {
- error.SetErrorString("qWatchpointSupportInfo is not supported");
- }
- return error;
-
+ if (m_supports_watchpoint_support_info == eLazyBoolNo) {
+ error.SetErrorString("qWatchpointSupportInfo is not supported");
+ }
+ return error;
}
-lldb_private::Error
-GDBRemoteCommunicationClient::GetWatchpointSupportInfo (uint32_t &num, bool& after, const ArchSpec &arch)
-{
- Error error(GetWatchpointSupportInfo(num));
- if (error.Success())
- error = GetWatchpointsTriggerAfterInstruction(after, arch);
- return error;
+lldb_private::Error GDBRemoteCommunicationClient::GetWatchpointSupportInfo(
+ uint32_t &num, bool &after, const ArchSpec &arch) {
+ Error error(GetWatchpointSupportInfo(num));
+ if (error.Success())
+ error = GetWatchpointsTriggerAfterInstruction(after, arch);
+ return error;
}
lldb_private::Error
-GDBRemoteCommunicationClient::GetWatchpointsTriggerAfterInstruction (bool &after, const ArchSpec &arch)
-{
- Error error;
- llvm::Triple::ArchType atype = arch.GetMachine();
-
- // we assume watchpoints will happen after running the relevant opcode
- // and we only want to override this behavior if we have explicitly
- // received a qHostInfo telling us otherwise
- if (m_qHostInfo_is_valid != eLazyBoolYes)
- {
- // On targets like MIPS, watchpoint exceptions are always generated
- // before the instruction is executed. The connected target may not
- // support qHostInfo or qWatchpointSupportInfo packets.
- if (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel
- || atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el)
- after = false;
- else
- after = true;
- }
+GDBRemoteCommunicationClient::GetWatchpointsTriggerAfterInstruction(
+ bool &after, const ArchSpec &arch) {
+ Error error;
+ llvm::Triple::ArchType atype = arch.GetMachine();
+
+ // we assume watchpoints will happen after running the relevant opcode
+ // and we only want to override this behavior if we have explicitly
+ // received a qHostInfo telling us otherwise
+ if (m_qHostInfo_is_valid != eLazyBoolYes) {
+ // On targets like MIPS, watchpoint exceptions are always generated
+ // before the instruction is executed. The connected target may not
+ // support qHostInfo or qWatchpointSupportInfo packets.
+ if (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel ||
+ atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el)
+ after = false;
else
- {
- // For MIPS, set m_watchpoints_trigger_after_instruction to eLazyBoolNo
- // if it is not calculated before.
- if (m_watchpoints_trigger_after_instruction == eLazyBoolCalculate &&
- (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel
- || atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el))
- m_watchpoints_trigger_after_instruction = eLazyBoolNo;
-
- after = (m_watchpoints_trigger_after_instruction != eLazyBoolNo);
- }
- return error;
-}
-
-int
-GDBRemoteCommunicationClient::SetSTDIN(const FileSpec &file_spec)
-{
- if (file_spec)
- {
- std::string path{file_spec.GetPath(false)};
- StreamString packet;
- packet.PutCString("QSetSTDIN:");
- packet.PutCStringAsRawHex8(path.c_str());
-
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- return 0;
- uint8_t error = response.GetError();
- if (error)
- return error;
- }
- }
- return -1;
-}
+ after = true;
+ } else {
+ // For MIPS, set m_watchpoints_trigger_after_instruction to eLazyBoolNo
+ // if it is not calculated before.
+ if (m_watchpoints_trigger_after_instruction == eLazyBoolCalculate &&
+ (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel ||
+ atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el))
+ m_watchpoints_trigger_after_instruction = eLazyBoolNo;
+
+ after = (m_watchpoints_trigger_after_instruction != eLazyBoolNo);
+ }
+ return error;
+}
+
+int GDBRemoteCommunicationClient::SetSTDIN(const FileSpec &file_spec) {
+ if (file_spec) {
+ std::string path{file_spec.GetPath(false)};
+ StreamString packet;
+ packet.PutCString("QSetSTDIN:");
+ packet.PutCStringAsRawHex8(path.c_str());
-int
-GDBRemoteCommunicationClient::SetSTDOUT(const FileSpec &file_spec)
-{
- if (file_spec)
- {
- std::string path{file_spec.GetPath(false)};
- StreamString packet;
- packet.PutCString("QSetSTDOUT:");
- packet.PutCStringAsRawHex8(path.c_str());
-
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- return 0;
- uint8_t error = response.GetError();
- if (error)
- return error;
- }
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse())
+ return 0;
+ uint8_t error = response.GetError();
+ if (error)
+ return error;
}
- return -1;
+ }
+ return -1;
}
-int
-GDBRemoteCommunicationClient::SetSTDERR(const FileSpec &file_spec)
-{
- if (file_spec)
- {
- std::string path{file_spec.GetPath(false)};
- StreamString packet;
- packet.PutCString("QSetSTDERR:");
- packet.PutCStringAsRawHex8(path.c_str());
-
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- return 0;
- uint8_t error = response.GetError();
- if (error)
- return error;
- }
- }
- return -1;
-}
+int GDBRemoteCommunicationClient::SetSTDOUT(const FileSpec &file_spec) {
+ if (file_spec) {
+ std::string path{file_spec.GetPath(false)};
+ StreamString packet;
+ packet.PutCString("QSetSTDOUT:");
+ packet.PutCStringAsRawHex8(path.c_str());
-bool
-GDBRemoteCommunicationClient::GetWorkingDir(FileSpec &working_dir)
-{
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse ("qGetWorkingDir", response, false) == PacketResult::Success)
- {
- if (response.IsUnsupportedResponse())
- return false;
- if (response.IsErrorResponse())
- return false;
- std::string cwd;
- response.GetHexByteString(cwd);
- working_dir.SetFile(cwd, false, GetHostArchitecture());
- return !cwd.empty();
+ if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse())
+ return 0;
+ uint8_t error = response.GetError();
+ if (error)
+ return error;
}
- return false;
+ }
+ return -1;
}
-int
-GDBRemoteCommunicationClient::SetWorkingDir(const FileSpec &working_dir)
-{
- if (working_dir)
- {
- std::string path{working_dir.GetPath(false)};
- StreamString packet;
- packet.PutCString("QSetWorkingDir:");
- packet.PutCStringAsRawHex8(path.c_str());
-
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- return 0;
- uint8_t error = response.GetError();
- if (error)
- return error;
- }
- }
- return -1;
-}
+int GDBRemoteCommunicationClient::SetSTDERR(const FileSpec &file_spec) {
+ if (file_spec) {
+ std::string path{file_spec.GetPath(false)};
+ StreamString packet;
+ packet.PutCString("QSetSTDERR:");
+ packet.PutCStringAsRawHex8(path.c_str());
-int
-GDBRemoteCommunicationClient::SetDisableASLR (bool enable)
-{
- char packet[32];
- const int packet_len = ::snprintf (packet, sizeof (packet), "QSetDisableASLR:%i", enable ? 1 : 0);
- assert (packet_len < (int)sizeof(packet));
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- return 0;
- uint8_t error = response.GetError();
- if (error)
- return error;
+ if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse())
+ return 0;
+ uint8_t error = response.GetError();
+ if (error)
+ return error;
}
- return -1;
-}
+ }
+ return -1;
+}
+
+bool GDBRemoteCommunicationClient::GetWorkingDir(FileSpec &working_dir) {
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse("qGetWorkingDir", response, false) ==
+ PacketResult::Success) {
+ if (response.IsUnsupportedResponse())
+ return false;
+ if (response.IsErrorResponse())
+ return false;
+ std::string cwd;
+ response.GetHexByteString(cwd);
+ working_dir.SetFile(cwd, false, GetHostArchitecture());
+ return !cwd.empty();
+ }
+ return false;
+}
+
+int GDBRemoteCommunicationClient::SetWorkingDir(const FileSpec &working_dir) {
+ if (working_dir) {
+ std::string path{working_dir.GetPath(false)};
+ StreamString packet;
+ packet.PutCString("QSetWorkingDir:");
+ packet.PutCStringAsRawHex8(path.c_str());
-int
-GDBRemoteCommunicationClient::SetDetachOnError (bool enable)
-{
- char packet[32];
- const int packet_len = ::snprintf (packet, sizeof (packet), "QSetDetachOnError:%i", enable ? 1 : 0);
- assert (packet_len < (int)sizeof(packet));
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- return 0;
- uint8_t error = response.GetError();
- if (error)
- return error;
+ if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse())
+ return 0;
+ uint8_t error = response.GetError();
+ if (error)
+ return error;
}
- return -1;
-}
-
+ }
+ return -1;
+}
+
+int GDBRemoteCommunicationClient::SetDisableASLR(bool enable) {
+ char packet[32];
+ const int packet_len =
+ ::snprintf(packet, sizeof(packet), "QSetDisableASLR:%i", enable ? 1 : 0);
+ assert(packet_len < (int)sizeof(packet));
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet, response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse())
+ return 0;
+ uint8_t error = response.GetError();
+ if (error)
+ return error;
+ }
+ return -1;
+}
+
+int GDBRemoteCommunicationClient::SetDetachOnError(bool enable) {
+ char packet[32];
+ const int packet_len = ::snprintf(packet, sizeof(packet),
+ "QSetDetachOnError:%i", enable ? 1 : 0);
+ assert(packet_len < (int)sizeof(packet));
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet, response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse())
+ return 0;
+ uint8_t error = response.GetError();
+ if (error)
+ return error;
+ }
+ return -1;
+}
+
+bool GDBRemoteCommunicationClient::DecodeProcessInfoResponse(
+ StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info) {
+ if (response.IsNormalResponse()) {
+ llvm::StringRef name;
+ llvm::StringRef value;
+ StringExtractor extractor;
-bool
-GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info)
-{
- if (response.IsNormalResponse())
- {
+ uint32_t cpu = LLDB_INVALID_CPUTYPE;
+ uint32_t sub = 0;
+ std::string vendor;
+ std::string os_type;
+
+ while (response.GetNameColonValue(name, value)) {
+ if (name.equals("pid")) {
+ lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
+ value.getAsInteger(0, pid);
+ process_info.SetProcessID(pid);
+ } else if (name.equals("ppid")) {
+ lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
+ value.getAsInteger(0, pid);
+ process_info.SetParentProcessID(pid);
+ } else if (name.equals("uid")) {
+ uint32_t uid = UINT32_MAX;
+ value.getAsInteger(0, uid);
+ process_info.SetUserID(uid);
+ } else if (name.equals("euid")) {
+ uint32_t uid = UINT32_MAX;
+ value.getAsInteger(0, uid);
+ process_info.SetEffectiveGroupID(uid);
+ } else if (name.equals("gid")) {
+ uint32_t gid = UINT32_MAX;
+ value.getAsInteger(0, gid);
+ process_info.SetGroupID(gid);
+ } else if (name.equals("egid")) {
+ uint32_t gid = UINT32_MAX;
+ value.getAsInteger(0, gid);
+ process_info.SetEffectiveGroupID(gid);
+ } else if (name.equals("triple")) {
+ StringExtractor extractor(value);
+ std::string triple;
+ extractor.GetHexByteString(triple);
+ process_info.GetArchitecture().SetTriple(triple.c_str());
+ } else if (name.equals("name")) {
+ StringExtractor extractor(value);
+ // The process name from ASCII hex bytes since we can't
+ // control the characters in a process name
std::string name;
- std::string value;
- StringExtractor extractor;
-
- uint32_t cpu = LLDB_INVALID_CPUTYPE;
- uint32_t sub = 0;
- std::string vendor;
- std::string os_type;
-
- while (response.GetNameColonValue(name, value))
- {
- if (name.compare("pid") == 0)
- {
- process_info.SetProcessID (StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
- }
- else if (name.compare("ppid") == 0)
- {
- process_info.SetParentProcessID (StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
- }
- else if (name.compare("uid") == 0)
- {
- process_info.SetUserID (StringConvert::ToUInt32 (value.c_str(), UINT32_MAX, 0));
- }
- else if (name.compare("euid") == 0)
- {
- process_info.SetEffectiveUserID (StringConvert::ToUInt32 (value.c_str(), UINT32_MAX, 0));
- }
- else if (name.compare("gid") == 0)
- {
- process_info.SetGroupID (StringConvert::ToUInt32 (value.c_str(), UINT32_MAX, 0));
- }
- else if (name.compare("egid") == 0)
- {
- process_info.SetEffectiveGroupID (StringConvert::ToUInt32 (value.c_str(), UINT32_MAX, 0));
- }
- else if (name.compare("triple") == 0)
- {
- StringExtractor extractor;
- extractor.GetStringRef().swap(value);
- extractor.SetFilePos(0);
- extractor.GetHexByteString (value);
- process_info.GetArchitecture ().SetTriple (value.c_str());
- }
- else if (name.compare("name") == 0)
- {
- StringExtractor extractor;
- // The process name from ASCII hex bytes since we can't
- // control the characters in a process name
- extractor.GetStringRef().swap(value);
- extractor.SetFilePos(0);
- extractor.GetHexByteString (value);
- process_info.GetExecutableFile().SetFile (value.c_str(), false);
- }
- else if (name.compare("cputype") == 0)
- {
- cpu = StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 16);
- }
- else if (name.compare("cpusubtype") == 0)
- {
- sub = StringConvert::ToUInt32 (value.c_str(), 0, 16);
- }
- else if (name.compare("vendor") == 0)
- {
- vendor = value;
- }
- else if (name.compare("ostype") == 0)
- {
- os_type = value;
- }
- }
-
- if (cpu != LLDB_INVALID_CPUTYPE && !vendor.empty() && !os_type.empty())
- {
- if (vendor == "apple")
- {
- process_info.GetArchitecture().SetArchitecture (eArchTypeMachO, cpu, sub);
- process_info.GetArchitecture().GetTriple().setVendorName (llvm::StringRef (vendor));
- process_info.GetArchitecture().GetTriple().setOSName (llvm::StringRef (os_type));
- }
- }
-
- if (process_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
- return true;
- }
- return false;
-}
-
-bool
-GDBRemoteCommunicationClient::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
-{
- process_info.Clear();
-
- if (m_supports_qProcessInfoPID)
- {
- char packet[32];
- const int packet_len = ::snprintf (packet, sizeof (packet), "qProcessInfoPID:%" PRIu64, pid);
- assert (packet_len < (int)sizeof(packet));
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
- {
- return DecodeProcessInfoResponse (response, process_info);
- }
- else
- {
- m_supports_qProcessInfoPID = false;
- return false;
- }
- }
- return false;
-}
-
-bool
-GDBRemoteCommunicationClient::GetCurrentProcessInfo (bool allow_lazy)
-{
- Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
-
- if (allow_lazy)
- {
- if (m_qProcessInfo_is_valid == eLazyBoolYes)
- return true;
- if (m_qProcessInfo_is_valid == eLazyBoolNo)
- return false;
- }
-
- GetHostInfo ();
-
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse ("qProcessInfo", response, false) == PacketResult::Success)
- {
- if (response.IsNormalResponse())
- {
- std::string name;
- std::string value;
- uint32_t cpu = LLDB_INVALID_CPUTYPE;
- uint32_t sub = 0;
- std::string arch_name;
- std::string os_name;
- std::string vendor_name;
- std::string triple;
- std::string elf_abi;
- uint32_t pointer_byte_size = 0;
- StringExtractor extractor;
- ByteOrder byte_order = eByteOrderInvalid;
- uint32_t num_keys_decoded = 0;
- lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
- while (response.GetNameColonValue(name, value))
- {
- if (name.compare("cputype") == 0)
- {
- cpu = StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 16);
- if (cpu != LLDB_INVALID_CPUTYPE)
- ++num_keys_decoded;
- }
- else if (name.compare("cpusubtype") == 0)
- {
- sub = StringConvert::ToUInt32 (value.c_str(), 0, 16);
- if (sub != 0)
- ++num_keys_decoded;
- }
- else if (name.compare("triple") == 0)
- {
- StringExtractor extractor;
- extractor.GetStringRef().swap(value);
- extractor.SetFilePos(0);
- extractor.GetHexByteString (triple);
- ++num_keys_decoded;
- }
- else if (name.compare("ostype") == 0)
- {
- os_name.swap (value);
- ++num_keys_decoded;
- }
- else if (name.compare("vendor") == 0)
- {
- vendor_name.swap(value);
- ++num_keys_decoded;
- }
- else if (name.compare("endian") == 0)
- {
- ++num_keys_decoded;
- if (value.compare("little") == 0)
- byte_order = eByteOrderLittle;
- else if (value.compare("big") == 0)
- byte_order = eByteOrderBig;
- else if (value.compare("pdp") == 0)
- byte_order = eByteOrderPDP;
- else
- --num_keys_decoded;
- }
- else if (name.compare("ptrsize") == 0)
- {
- pointer_byte_size = StringConvert::ToUInt32 (value.c_str(), 0, 16);
- if (pointer_byte_size != 0)
- ++num_keys_decoded;
- }
- else if (name.compare("pid") == 0)
- {
- pid = StringConvert::ToUInt64(value.c_str(), 0, 16);
- if (pid != LLDB_INVALID_PROCESS_ID)
- ++num_keys_decoded;
- }
- else if (name.compare("elf_abi") == 0)
- {
- elf_abi = value;
- ++num_keys_decoded;
- }
- }
- if (num_keys_decoded > 0)
- m_qProcessInfo_is_valid = eLazyBoolYes;
- if (pid != LLDB_INVALID_PROCESS_ID)
- {
- m_curr_pid_is_valid = eLazyBoolYes;
- m_curr_pid = pid;
- }
-
- // Set the ArchSpec from the triple if we have it.
- if (!triple.empty ())
- {
- m_process_arch.SetTriple (triple.c_str ());
- m_process_arch.SetFlags(elf_abi);
- if (pointer_byte_size)
- {
- assert (pointer_byte_size == m_process_arch.GetAddressByteSize());
- }
- }
- else if (cpu != LLDB_INVALID_CPUTYPE && !os_name.empty() && !vendor_name.empty())
- {
- llvm::Triple triple(llvm::Twine("-") + vendor_name + "-" + os_name);
-
- assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);
- switch (triple.getObjectFormat()) {
- case llvm::Triple::MachO:
- m_process_arch.SetArchitecture (eArchTypeMachO, cpu, sub);
- break;
- case llvm::Triple::ELF:
- m_process_arch.SetArchitecture (eArchTypeELF, cpu, sub);
- break;
- case llvm::Triple::COFF:
- m_process_arch.SetArchitecture (eArchTypeCOFF, cpu, sub);
- break;
- case llvm::Triple::UnknownObjectFormat:
- if (log)
- log->Printf("error: failed to determine target architecture");
- return false;
- }
-
- if (pointer_byte_size)
- {
- assert (pointer_byte_size == m_process_arch.GetAddressByteSize());
- }
- if (byte_order != eByteOrderInvalid)
- {
- assert (byte_order == m_process_arch.GetByteOrder());
- }
- m_process_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
- m_process_arch.GetTriple().setOSName(llvm::StringRef (os_name));
- m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
- m_host_arch.GetTriple().setOSName (llvm::StringRef (os_name));
- }
- return true;
- }
- }
- else
- {
- m_qProcessInfo_is_valid = eLazyBoolNo;
- }
-
- return false;
-}
-
-
-uint32_t
-GDBRemoteCommunicationClient::FindProcesses (const ProcessInstanceInfoMatch &match_info,
- ProcessInstanceInfoList &process_infos)
-{
- process_infos.Clear();
-
- if (m_supports_qfProcessInfo)
- {
- StreamString packet;
- packet.PutCString ("qfProcessInfo");
- if (!match_info.MatchAllProcesses())
- {
- packet.PutChar (':');
- const char *name = match_info.GetProcessInfo().GetName();
- bool has_name_match = false;
- if (name && name[0])
- {
- has_name_match = true;
- NameMatchType name_match_type = match_info.GetNameMatchType();
- switch (name_match_type)
- {
- case eNameMatchIgnore:
- has_name_match = false;
- break;
-
- case eNameMatchEquals:
- packet.PutCString ("name_match:equals;");
- break;
-
- case eNameMatchContains:
- packet.PutCString ("name_match:contains;");
- break;
-
- case eNameMatchStartsWith:
- packet.PutCString ("name_match:starts_with;");
- break;
-
- case eNameMatchEndsWith:
- packet.PutCString ("name_match:ends_with;");
- break;
-
- case eNameMatchRegularExpression:
- packet.PutCString ("name_match:regex;");
- break;
- }
- if (has_name_match)
- {
- packet.PutCString ("name:");
- packet.PutBytesAsRawHex8(name, ::strlen(name));
- packet.PutChar (';');
- }
- }
-
- if (match_info.GetProcessInfo().ProcessIDIsValid())
- packet.Printf("pid:%" PRIu64 ";",match_info.GetProcessInfo().GetProcessID());
- if (match_info.GetProcessInfo().ParentProcessIDIsValid())
- packet.Printf("parent_pid:%" PRIu64 ";",match_info.GetProcessInfo().GetParentProcessID());
- if (match_info.GetProcessInfo().UserIDIsValid())
- packet.Printf("uid:%u;",match_info.GetProcessInfo().GetUserID());
- if (match_info.GetProcessInfo().GroupIDIsValid())
- packet.Printf("gid:%u;",match_info.GetProcessInfo().GetGroupID());
- if (match_info.GetProcessInfo().EffectiveUserIDIsValid())
- packet.Printf("euid:%u;",match_info.GetProcessInfo().GetEffectiveUserID());
- if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
- packet.Printf("egid:%u;",match_info.GetProcessInfo().GetEffectiveGroupID());
- if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
- packet.Printf("all_users:%u;",match_info.GetMatchAllUsers() ? 1 : 0);
- if (match_info.GetProcessInfo().GetArchitecture().IsValid())
- {
- const ArchSpec &match_arch = match_info.GetProcessInfo().GetArchitecture();
- const llvm::Triple &triple = match_arch.GetTriple();
- packet.PutCString("triple:");
- packet.PutCString(triple.getTriple().c_str());
- packet.PutChar (';');
- }
- }
- StringExtractorGDBRemote response;
- // Increase timeout as the first qfProcessInfo packet takes a long time
- // on Android. The value of 1min was arrived at empirically.
- GDBRemoteCommunication::ScopedTimeout timeout (*this, 60);
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
- {
- do
- {
- ProcessInstanceInfo process_info;
- if (!DecodeProcessInfoResponse (response, process_info))
- break;
- process_infos.Append(process_info);
- response.GetStringRef().clear();
- response.SetFilePos(0);
- } while (SendPacketAndWaitForResponse ("qsProcessInfo", strlen ("qsProcessInfo"), response, false) == PacketResult::Success);
- }
- else
- {
- m_supports_qfProcessInfo = false;
- return 0;
- }
- }
- return process_infos.GetSize();
-
-}
-
-bool
-GDBRemoteCommunicationClient::GetUserName (uint32_t uid, std::string &name)
-{
- if (m_supports_qUserName)
- {
- char packet[32];
- const int packet_len = ::snprintf (packet, sizeof (packet), "qUserName:%i", uid);
- assert (packet_len < (int)sizeof(packet));
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.IsNormalResponse())
- {
- // Make sure we parsed the right number of characters. The response is
- // the hex encoded user name and should make up the entire packet.
- // If there are any non-hex ASCII bytes, the length won't match below..
- if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
- return true;
- }
- }
- else
- {
- m_supports_qUserName = false;
- return false;
- }
- }
- return false;
-
-}
-
-bool
-GDBRemoteCommunicationClient::GetGroupName (uint32_t gid, std::string &name)
-{
- if (m_supports_qGroupName)
- {
- char packet[32];
- const int packet_len = ::snprintf (packet, sizeof (packet), "qGroupName:%i", gid);
- assert (packet_len < (int)sizeof(packet));
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.IsNormalResponse())
- {
- // Make sure we parsed the right number of characters. The response is
- // the hex encoded group name and should make up the entire packet.
- // If there are any non-hex ASCII bytes, the length won't match below..
- if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
- return true;
- }
- }
- else
- {
- m_supports_qGroupName = false;
- return false;
- }
- }
- return false;
-}
-
-bool
-GDBRemoteCommunicationClient::SetNonStopMode (const bool enable)
-{
- // Form non-stop packet request
+ extractor.GetHexByteString(name);
+ process_info.GetExecutableFile().SetFile(name, false);
+ } else if (name.equals("cputype")) {
+ value.getAsInteger(0, cpu);
+ } else if (name.equals("cpusubtype")) {
+ value.getAsInteger(0, sub);
+ } else if (name.equals("vendor")) {
+ vendor = value;
+ } else if (name.equals("ostype")) {
+ os_type = value;
+ }
+ }
+
+ if (cpu != LLDB_INVALID_CPUTYPE && !vendor.empty() && !os_type.empty()) {
+ if (vendor == "apple") {
+ process_info.GetArchitecture().SetArchitecture(eArchTypeMachO, cpu,
+ sub);
+ process_info.GetArchitecture().GetTriple().setVendorName(
+ llvm::StringRef(vendor));
+ process_info.GetArchitecture().GetTriple().setOSName(
+ llvm::StringRef(os_type));
+ }
+ }
+
+ if (process_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
+ return true;
+ }
+ return false;
+}
+
+bool GDBRemoteCommunicationClient::GetProcessInfo(
+ lldb::pid_t pid, ProcessInstanceInfo &process_info) {
+ process_info.Clear();
+
+ if (m_supports_qProcessInfoPID) {
char packet[32];
- const int packet_len = ::snprintf(packet, sizeof(packet), "QNonStop:%1d", (int)enable);
+ const int packet_len =
+ ::snprintf(packet, sizeof(packet), "qProcessInfoPID:%" PRIu64, pid);
assert(packet_len < (int)sizeof(packet));
-
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
StringExtractorGDBRemote response;
- // Send to target
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- if (response.IsOKResponse())
- return true;
-
- // Failed or not supported
- return false;
-
-}
-
-static void
-MakeSpeedTestPacket(StreamString &packet, uint32_t send_size, uint32_t recv_size)
-{
- packet.Clear();
- packet.Printf ("qSpeedTest:response_size:%i;data:", recv_size);
- uint32_t bytes_left = send_size;
- while (bytes_left > 0)
- {
- if (bytes_left >= 26)
- {
- packet.PutCString("abcdefghijklmnopqrstuvwxyz");
- bytes_left -= 26;
- }
- else
- {
- packet.Printf ("%*.*s;", bytes_left, bytes_left, "abcdefghijklmnopqrstuvwxyz");
- bytes_left = 0;
- }
- }
-}
-
-template<typename T>
-T calculate_standard_deviation(const std::vector<T> &v)
-{
- T sum = std::accumulate(std::begin(v), std::end(v), T(0));
- T mean = sum / (T)v.size();
- T accum = T(0);
- std::for_each (std::begin(v), std::end(v), [&](const T d) {
- T delta = d - mean;
- accum += delta * delta;
- });
-
- T stdev = sqrt(accum / (v.size()-1));
- return stdev;
-}
-
-void
-GDBRemoteCommunicationClient::TestPacketSpeed (const uint32_t num_packets, uint32_t max_send, uint32_t max_recv, bool json, Stream &strm)
-{
- uint32_t i;
- TimeValue start_time, end_time;
- uint64_t total_time_nsec;
- if (SendSpeedTestPacket (0, 0))
- {
- StreamString packet;
- if (json)
- strm.Printf("{ \"packet_speeds\" : {\n \"num_packets\" : %u,\n \"results\" : [", num_packets);
- else
- strm.Printf("Testing sending %u packets of various sizes:\n", num_packets);
- strm.Flush();
-
- uint32_t result_idx = 0;
- uint32_t send_size;
- std::vector<float> packet_times;
-
- for (send_size = 0; send_size <= max_send; send_size ? send_size *= 2 : send_size = 4)
- {
- for (uint32_t recv_size = 0; recv_size <= max_recv; recv_size ? recv_size *= 2 : recv_size = 4)
- {
- MakeSpeedTestPacket (packet, send_size, recv_size);
-
- packet_times.clear();
- // Test how long it takes to send 'num_packets' packets
- start_time = TimeValue::Now();
- for (i=0; i<num_packets; ++i)
- {
- TimeValue packet_start_time = TimeValue::Now();
- StringExtractorGDBRemote response;
- SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false);
- TimeValue packet_end_time = TimeValue::Now();
- uint64_t packet_time_nsec = packet_end_time.GetAsNanoSecondsSinceJan1_1970() - packet_start_time.GetAsNanoSecondsSinceJan1_1970();
- packet_times.push_back((float)packet_time_nsec);
- }
- end_time = TimeValue::Now();
- total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
-
- float packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec;
- float total_ms = (float)total_time_nsec/(float)TimeValue::NanoSecPerMilliSec;
- float average_ms_per_packet = total_ms / num_packets;
- const float standard_deviation = calculate_standard_deviation<float>(packet_times);
- if (json)
- {
- strm.Printf ("%s\n {\"send_size\" : %6" PRIu32 ", \"recv_size\" : %6" PRIu32 ", \"total_time_nsec\" : %12" PRIu64 ", \"standard_deviation_nsec\" : %9" PRIu64 " }", result_idx > 0 ? "," : "", send_size, recv_size, total_time_nsec, (uint64_t)standard_deviation);
- ++result_idx;
- }
- else
- {
- strm.Printf ("qSpeedTest(send=%-7u, recv=%-7u) in %" PRIu64 ".%9.9" PRIu64 " sec for %9.2f packets/sec (%10.6f ms per packet) with standard deviation of %10.6f ms\n",
- send_size,
- recv_size,
- total_time_nsec / TimeValue::NanoSecPerSec,
- total_time_nsec % TimeValue::NanoSecPerSec,
- packets_per_second,
- average_ms_per_packet,
- standard_deviation/(float)TimeValue::NanoSecPerMilliSec);
- }
- strm.Flush();
- }
- }
-
- const uint64_t k_recv_amount = 4*1024*1024; // Receive amount in bytes
-
- const float k_recv_amount_mb = (float)k_recv_amount/(1024.0f*1024.0f);
- if (json)
- strm.Printf("\n ]\n },\n \"download_speed\" : {\n \"byte_size\" : %" PRIu64 ",\n \"results\" : [", k_recv_amount);
- else
- strm.Printf("Testing receiving %2.1fMB of data using varying receive packet sizes:\n", k_recv_amount_mb);
- strm.Flush();
- send_size = 0;
- result_idx = 0;
- for (uint32_t recv_size = 32; recv_size <= max_recv; recv_size *= 2)
- {
- MakeSpeedTestPacket (packet, send_size, recv_size);
-
- // If we have a receive size, test how long it takes to receive 4MB of data
- if (recv_size > 0)
- {
- start_time = TimeValue::Now();
- uint32_t bytes_read = 0;
- uint32_t packet_count = 0;
- while (bytes_read < k_recv_amount)
- {
- StringExtractorGDBRemote response;
- SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false);
- bytes_read += recv_size;
- ++packet_count;
- }
- end_time = TimeValue::Now();
- total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
- float mb_second = ((((float)k_recv_amount)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec) / (1024.0*1024.0);
- float packets_per_second = (((float)packet_count)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec;
- float total_ms = (float)total_time_nsec/(float)TimeValue::NanoSecPerMilliSec;
- float average_ms_per_packet = total_ms / packet_count;
-
- if (json)
- {
- strm.Printf ("%s\n {\"send_size\" : %6" PRIu32 ", \"recv_size\" : %6" PRIu32 ", \"total_time_nsec\" : %12" PRIu64 " }", result_idx > 0 ? "," : "", send_size, recv_size, total_time_nsec);
- ++result_idx;
- }
- else
- {
- strm.Printf ("qSpeedTest(send=%-7u, recv=%-7u) %6u packets needed to receive %2.1fMB in %" PRIu64 ".%9.9" PRIu64 " sec for %f MB/sec for %9.2f packets/sec (%10.6f ms per packet)\n",
- send_size,
- recv_size,
- packet_count,
- k_recv_amount_mb,
- total_time_nsec / TimeValue::NanoSecPerSec,
- total_time_nsec % TimeValue::NanoSecPerSec,
- mb_second,
- packets_per_second,
- average_ms_per_packet);
- }
- strm.Flush();
- }
- }
- if (json)
- strm.Printf("\n ]\n }\n}\n");
- else
- strm.EOL();
- }
-}
-
-bool
-GDBRemoteCommunicationClient::SendSpeedTestPacket (uint32_t send_size, uint32_t recv_size)
-{
+ if (SendPacketAndWaitForResponse(packet, response, false) ==
+ PacketResult::Success) {
+ return DecodeProcessInfoResponse(response, process_info);
+ } else {
+ m_supports_qProcessInfoPID = false;
+ return false;
+ }
+ }
+ return false;
+}
+
+bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
+ GDBR_LOG_PACKETS));
+
+ if (allow_lazy) {
+ if (m_qProcessInfo_is_valid == eLazyBoolYes)
+ return true;
+ if (m_qProcessInfo_is_valid == eLazyBoolNo)
+ return false;
+ }
+
+ GetHostInfo();
+
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse("qProcessInfo", response, false) ==
+ PacketResult::Success) {
+ if (response.IsNormalResponse()) {
+ llvm::StringRef name;
+ llvm::StringRef value;
+ uint32_t cpu = LLDB_INVALID_CPUTYPE;
+ uint32_t sub = 0;
+ std::string arch_name;
+ std::string os_name;
+ std::string vendor_name;
+ std::string triple;
+ std::string elf_abi;
+ uint32_t pointer_byte_size = 0;
+ StringExtractor extractor;
+ ByteOrder byte_order = eByteOrderInvalid;
+ uint32_t num_keys_decoded = 0;
+ lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
+ while (response.GetNameColonValue(name, value)) {
+ if (name.equals("cputype")) {
+ if (!value.getAsInteger(16, cpu))
+ ++num_keys_decoded;
+ } else if (name.equals("cpusubtype")) {
+ if (!value.getAsInteger(16, sub))
+ ++num_keys_decoded;
+ } else if (name.equals("triple")) {
+ StringExtractor extractor(value);
+ extractor.GetHexByteString(triple);
+ ++num_keys_decoded;
+ } else if (name.equals("ostype")) {
+ os_name = value;
+ ++num_keys_decoded;
+ } else if (name.equals("vendor")) {
+ vendor_name = value;
+ ++num_keys_decoded;
+ } else if (name.equals("endian")) {
+ byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
+ .Case("little", eByteOrderLittle)
+ .Case("big", eByteOrderBig)
+ .Case("pdp", eByteOrderPDP)
+ .Default(eByteOrderInvalid);
+ if (byte_order != eByteOrderInvalid)
+ ++num_keys_decoded;
+ } else if (name.equals("ptrsize")) {
+ if (!value.getAsInteger(16, pointer_byte_size))
+ ++num_keys_decoded;
+ } else if (name.equals("pid")) {
+ if (!value.getAsInteger(16, pid))
+ ++num_keys_decoded;
+ } else if (name.equals("elf_abi")) {
+ elf_abi = value;
+ ++num_keys_decoded;
+ }
+ }
+ if (num_keys_decoded > 0)
+ m_qProcessInfo_is_valid = eLazyBoolYes;
+ if (pid != LLDB_INVALID_PROCESS_ID) {
+ m_curr_pid_is_valid = eLazyBoolYes;
+ m_curr_pid = pid;
+ }
+
+ // Set the ArchSpec from the triple if we have it.
+ if (!triple.empty()) {
+ m_process_arch.SetTriple(triple.c_str());
+ m_process_arch.SetFlags(elf_abi);
+ if (pointer_byte_size) {
+ assert(pointer_byte_size == m_process_arch.GetAddressByteSize());
+ }
+ } else if (cpu != LLDB_INVALID_CPUTYPE && !os_name.empty() &&
+ !vendor_name.empty()) {
+ llvm::Triple triple(llvm::Twine("-") + vendor_name + "-" + os_name);
+
+ assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);
+ switch (triple.getObjectFormat()) {
+ case llvm::Triple::MachO:
+ m_process_arch.SetArchitecture(eArchTypeMachO, cpu, sub);
+ break;
+ case llvm::Triple::ELF:
+ m_process_arch.SetArchitecture(eArchTypeELF, cpu, sub);
+ break;
+ case llvm::Triple::COFF:
+ m_process_arch.SetArchitecture(eArchTypeCOFF, cpu, sub);
+ break;
+ case llvm::Triple::UnknownObjectFormat:
+ if (log)
+ log->Printf("error: failed to determine target architecture");
+ return false;
+ }
+
+ if (pointer_byte_size) {
+ assert(pointer_byte_size == m_process_arch.GetAddressByteSize());
+ }
+ if (byte_order != eByteOrderInvalid) {
+ assert(byte_order == m_process_arch.GetByteOrder());
+ }
+ m_process_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
+ m_process_arch.GetTriple().setOSName(llvm::StringRef(os_name));
+ m_host_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
+ m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
+ }
+ return true;
+ }
+ } else {
+ m_qProcessInfo_is_valid = eLazyBoolNo;
+ }
+
+ return false;
+}
+
+uint32_t GDBRemoteCommunicationClient::FindProcesses(
+ const ProcessInstanceInfoMatch &match_info,
+ ProcessInstanceInfoList &process_infos) {
+ process_infos.Clear();
+
+ if (m_supports_qfProcessInfo) {
StreamString packet;
- packet.Printf ("qSpeedTest:response_size:%i;data:", recv_size);
- uint32_t bytes_left = send_size;
- while (bytes_left > 0)
- {
- if (bytes_left >= 26)
- {
- packet.PutCString("abcdefghijklmnopqrstuvwxyz");
- bytes_left -= 26;
- }
- else
- {
- packet.Printf ("%*.*s;", bytes_left, bytes_left, "abcdefghijklmnopqrstuvwxyz");
- bytes_left = 0;
- }
+ packet.PutCString("qfProcessInfo");
+ if (!match_info.MatchAllProcesses()) {
+ packet.PutChar(':');
+ const char *name = match_info.GetProcessInfo().GetName();
+ bool has_name_match = false;
+ if (name && name[0]) {
+ has_name_match = true;
+ NameMatchType name_match_type = match_info.GetNameMatchType();
+ switch (name_match_type) {
+ case eNameMatchIgnore:
+ has_name_match = false;
+ break;
+
+ case eNameMatchEquals:
+ packet.PutCString("name_match:equals;");
+ break;
+
+ case eNameMatchContains:
+ packet.PutCString("name_match:contains;");
+ break;
+
+ case eNameMatchStartsWith:
+ packet.PutCString("name_match:starts_with;");
+ break;
+
+ case eNameMatchEndsWith:
+ packet.PutCString("name_match:ends_with;");
+ break;
+
+ case eNameMatchRegularExpression:
+ packet.PutCString("name_match:regex;");
+ break;
+ }
+ if (has_name_match) {
+ packet.PutCString("name:");
+ packet.PutBytesAsRawHex8(name, ::strlen(name));
+ packet.PutChar(';');
+ }
+ }
+
+ if (match_info.GetProcessInfo().ProcessIDIsValid())
+ packet.Printf("pid:%" PRIu64 ";",
+ match_info.GetProcessInfo().GetProcessID());
+ if (match_info.GetProcessInfo().ParentProcessIDIsValid())
+ packet.Printf("parent_pid:%" PRIu64 ";",
+ match_info.GetProcessInfo().GetParentProcessID());
+ if (match_info.GetProcessInfo().UserIDIsValid())
+ packet.Printf("uid:%u;", match_info.GetProcessInfo().GetUserID());
+ if (match_info.GetProcessInfo().GroupIDIsValid())
+ packet.Printf("gid:%u;", match_info.GetProcessInfo().GetGroupID());
+ if (match_info.GetProcessInfo().EffectiveUserIDIsValid())
+ packet.Printf("euid:%u;",
+ match_info.GetProcessInfo().GetEffectiveUserID());
+ if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
+ packet.Printf("egid:%u;",
+ match_info.GetProcessInfo().GetEffectiveGroupID());
+ if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
+ packet.Printf("all_users:%u;", match_info.GetMatchAllUsers() ? 1 : 0);
+ if (match_info.GetProcessInfo().GetArchitecture().IsValid()) {
+ const ArchSpec &match_arch =
+ match_info.GetProcessInfo().GetArchitecture();
+ const llvm::Triple &triple = match_arch.GetTriple();
+ packet.PutCString("triple:");
+ packet.PutCString(triple.getTriple());
+ packet.PutChar(';');
+ }
}
-
StringExtractorGDBRemote response;
- return SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success;
-}
-
-bool
-GDBRemoteCommunicationClient::LaunchGDBServer (const char *remote_accept_hostname,
- lldb::pid_t &pid,
- uint16_t &port,
- std::string &socket_name)
-{
- pid = LLDB_INVALID_PROCESS_ID;
- port = 0;
- socket_name.clear();
-
+ // Increase timeout as the first qfProcessInfo packet takes a long time
+ // on Android. The value of 1min was arrived at empirically.
+ ScopedTimeout timeout(*this, minutes(1));
+ if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ PacketResult::Success) {
+ do {
+ ProcessInstanceInfo process_info;
+ if (!DecodeProcessInfoResponse(response, process_info))
+ break;
+ process_infos.Append(process_info);
+ response.GetStringRef().clear();
+ response.SetFilePos(0);
+ } while (SendPacketAndWaitForResponse("qsProcessInfo", response, false) ==
+ PacketResult::Success);
+ } else {
+ m_supports_qfProcessInfo = false;
+ return 0;
+ }
+ }
+ return process_infos.GetSize();
+}
+
+bool GDBRemoteCommunicationClient::GetUserName(uint32_t uid,
+ std::string &name) {
+ if (m_supports_qUserName) {
+ char packet[32];
+ const int packet_len =
+ ::snprintf(packet, sizeof(packet), "qUserName:%i", uid);
+ assert(packet_len < (int)sizeof(packet));
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
StringExtractorGDBRemote response;
- StreamString stream;
- stream.PutCString("qLaunchGDBServer;");
- std::string hostname;
- if (remote_accept_hostname && remote_accept_hostname[0])
- hostname = remote_accept_hostname;
+ if (SendPacketAndWaitForResponse(packet, response, false) ==
+ PacketResult::Success) {
+ if (response.IsNormalResponse()) {
+ // Make sure we parsed the right number of characters. The response is
+ // the hex encoded user name and should make up the entire packet.
+ // If there are any non-hex ASCII bytes, the length won't match below..
+ if (response.GetHexByteString(name) * 2 ==
+ response.GetStringRef().size())
+ return true;
+ }
+ } else {
+ m_supports_qUserName = false;
+ return false;
+ }
+ }
+ return false;
+}
+
+bool GDBRemoteCommunicationClient::GetGroupName(uint32_t gid,
+ std::string &name) {
+ if (m_supports_qGroupName) {
+ char packet[32];
+ const int packet_len =
+ ::snprintf(packet, sizeof(packet), "qGroupName:%i", gid);
+ assert(packet_len < (int)sizeof(packet));
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet, response, false) ==
+ PacketResult::Success) {
+ if (response.IsNormalResponse()) {
+ // Make sure we parsed the right number of characters. The response is
+ // the hex encoded group name and should make up the entire packet.
+ // If there are any non-hex ASCII bytes, the length won't match below..
+ if (response.GetHexByteString(name) * 2 ==
+ response.GetStringRef().size())
+ return true;
+ }
+ } else {
+ m_supports_qGroupName = false;
+ return false;
+ }
+ }
+ return false;
+}
+
+bool GDBRemoteCommunicationClient::SetNonStopMode(const bool enable) {
+ // Form non-stop packet request
+ char packet[32];
+ const int packet_len =
+ ::snprintf(packet, sizeof(packet), "QNonStop:%1d", (int)enable);
+ assert(packet_len < (int)sizeof(packet));
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
+
+ StringExtractorGDBRemote response;
+ // Send to target
+ if (SendPacketAndWaitForResponse(packet, response, false) ==
+ PacketResult::Success)
+ if (response.IsOKResponse())
+ return true;
+
+ // Failed or not supported
+ return false;
+}
+
+static void MakeSpeedTestPacket(StreamString &packet, uint32_t send_size,
+ uint32_t recv_size) {
+ packet.Clear();
+ packet.Printf("qSpeedTest:response_size:%i;data:", recv_size);
+ uint32_t bytes_left = send_size;
+ while (bytes_left > 0) {
+ if (bytes_left >= 26) {
+ packet.PutCString("abcdefghijklmnopqrstuvwxyz");
+ bytes_left -= 26;
+ } else {
+ packet.Printf("%*.*s;", bytes_left, bytes_left,
+ "abcdefghijklmnopqrstuvwxyz");
+ bytes_left = 0;
+ }
+ }
+}
+
+duration<float>
+calculate_standard_deviation(const std::vector<duration<float>> &v) {
+ using Dur = duration<float>;
+ Dur sum = std::accumulate(std::begin(v), std::end(v), Dur());
+ Dur mean = sum / v.size();
+ float accum = 0;
+ for (auto d : v) {
+ float delta = (d - mean).count();
+ accum += delta * delta;
+ };
+
+ return Dur(sqrtf(accum / (v.size() - 1)));
+}
+
+void GDBRemoteCommunicationClient::TestPacketSpeed(const uint32_t num_packets,
+ uint32_t max_send,
+ uint32_t max_recv,
+ uint64_t recv_amount,
+ bool json, Stream &strm) {
+ uint32_t i;
+ if (SendSpeedTestPacket(0, 0)) {
+ StreamString packet;
+ if (json)
+ strm.Printf("{ \"packet_speeds\" : {\n \"num_packets\" : %u,\n "
+ "\"results\" : [",
+ num_packets);
else
- {
- if (HostInfo::GetHostname(hostname))
- {
- // Make the GDB server we launch only accept connections from this host
- stream.Printf("host:%s;", hostname.c_str());
- }
- else
- {
- // Make the GDB server we launch accept connections from any host since we can't figure out the hostname
- stream.Printf("host:*;");
+ strm.Printf("Testing sending %u packets of various sizes:\n",
+ num_packets);
+ strm.Flush();
+
+ uint32_t result_idx = 0;
+ uint32_t send_size;
+ std::vector<duration<float>> packet_times;
+
+ for (send_size = 0; send_size <= max_send;
+ send_size ? send_size *= 2 : send_size = 4) {
+ for (uint32_t recv_size = 0; recv_size <= max_recv;
+ recv_size ? recv_size *= 2 : recv_size = 4) {
+ MakeSpeedTestPacket(packet, send_size, recv_size);
+
+ packet_times.clear();
+ // Test how long it takes to send 'num_packets' packets
+ const auto start_time = steady_clock::now();
+ for (i = 0; i < num_packets; ++i) {
+ const auto packet_start_time = steady_clock::now();
+ StringExtractorGDBRemote response;
+ SendPacketAndWaitForResponse(packet.GetString(), response, false);
+ const auto packet_end_time = steady_clock::now();
+ packet_times.push_back(packet_end_time - packet_start_time);
+ }
+ const auto end_time = steady_clock::now();
+ const auto total_time = end_time - start_time;
+
+ float packets_per_second =
+ ((float)num_packets) / duration<float>(total_time).count();
+ auto average_per_packet = total_time / num_packets;
+ const duration<float> standard_deviation =
+ calculate_standard_deviation(packet_times);
+ if (json) {
+ strm.Printf("%s\n {\"send_size\" : %6" PRIu32
+ ", \"recv_size\" : %6" PRIu32
+ ", \"total_time_nsec\" : %12" PRIu64
+ ", \"standard_deviation_nsec\" : %9" PRIu64 " }",
+ result_idx > 0 ? "," : "", send_size, recv_size,
+ duration_cast<nanoseconds>(total_time).count(),
+ duration_cast<nanoseconds>(standard_deviation).count());
+ ++result_idx;
+ } else {
+ strm.Printf(
+ "qSpeedTest(send=%-7u, recv=%-7u) in %.9f"
+ " sec for %9.2f packets/sec (%10.6f ms per packet) with standard "
+ "deviation of %10.6f ms\n",
+ send_size, recv_size, duration<float>(total_time).count(),
+ packets_per_second,
+ duration<float, std::milli>(average_per_packet).count(),
+ duration<float, std::milli>(standard_deviation).count());
}
+ strm.Flush();
+ }
}
- const char *packet = stream.GetData();
- int packet_len = stream.GetSize();
-
- // give the process a few seconds to startup
- GDBRemoteCommunication::ScopedTimeout timeout (*this, 10);
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- {
- std::string name;
- std::string value;
- StringExtractor extractor;
- while (response.GetNameColonValue(name, value))
- {
- if (name.compare("port") == 0)
- port = StringConvert::ToUInt32(value.c_str(), 0, 0);
- else if (name.compare("pid") == 0)
- pid = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_PROCESS_ID, 0);
- else if (name.compare("socket_name") == 0)
- {
- extractor.GetStringRef().swap(value);
- extractor.SetFilePos(0);
- extractor.GetHexByteString(value);
-
- socket_name = value;
- }
+ const float k_recv_amount_mb = (float)recv_amount / (1024.0f * 1024.0f);
+ if (json)
+ strm.Printf("\n ]\n },\n \"download_speed\" : {\n \"byte_size\" "
+ ": %" PRIu64 ",\n \"results\" : [",
+ recv_amount);
+ else
+ strm.Printf("Testing receiving %2.1fMB of data using varying receive "
+ "packet sizes:\n",
+ k_recv_amount_mb);
+ strm.Flush();
+ send_size = 0;
+ result_idx = 0;
+ for (uint32_t recv_size = 32; recv_size <= max_recv; recv_size *= 2) {
+ MakeSpeedTestPacket(packet, send_size, recv_size);
+
+ // If we have a receive size, test how long it takes to receive 4MB of
+ // data
+ if (recv_size > 0) {
+ const auto start_time = steady_clock::now();
+ uint32_t bytes_read = 0;
+ uint32_t packet_count = 0;
+ while (bytes_read < recv_amount) {
+ StringExtractorGDBRemote response;
+ SendPacketAndWaitForResponse(packet.GetString(), response, false);
+ bytes_read += recv_size;
+ ++packet_count;
+ }
+ const auto end_time = steady_clock::now();
+ const auto total_time = end_time - start_time;
+ float mb_second = ((float)recv_amount) /
+ duration<float>(total_time).count() /
+ (1024.0 * 1024.0);
+ float packets_per_second =
+ ((float)packet_count) / duration<float>(total_time).count();
+ const auto average_per_packet = total_time / packet_count;
+
+ if (json) {
+ strm.Printf("%s\n {\"send_size\" : %6" PRIu32
+ ", \"recv_size\" : %6" PRIu32
+ ", \"total_time_nsec\" : %12" PRIu64 " }",
+ result_idx > 0 ? "," : "", send_size, recv_size,
+ duration_cast<nanoseconds>(total_time).count());
+ ++result_idx;
+ } else {
+ strm.Printf("qSpeedTest(send=%-7u, recv=%-7u) %6u packets needed to "
+ "receive %2.1fMB in %.9f"
+ " sec for %f MB/sec for %9.2f packets/sec (%10.6f ms per "
+ "packet)\n",
+ send_size, recv_size, packet_count, k_recv_amount_mb,
+ duration<float>(total_time).count(), mb_second,
+ packets_per_second,
+ duration<float, std::milli>(average_per_packet).count());
}
- return true;
+ strm.Flush();
+ }
}
- return false;
+ if (json)
+ strm.Printf("\n ]\n }\n}\n");
+ else
+ strm.EOL();
+ }
+}
+
+bool GDBRemoteCommunicationClient::SendSpeedTestPacket(uint32_t send_size,
+ uint32_t recv_size) {
+ StreamString packet;
+ packet.Printf("qSpeedTest:response_size:%i;data:", recv_size);
+ uint32_t bytes_left = send_size;
+ while (bytes_left > 0) {
+ if (bytes_left >= 26) {
+ packet.PutCString("abcdefghijklmnopqrstuvwxyz");
+ bytes_left -= 26;
+ } else {
+ packet.Printf("%*.*s;", bytes_left, bytes_left,
+ "abcdefghijklmnopqrstuvwxyz");
+ bytes_left = 0;
+ }
+ }
+
+ StringExtractorGDBRemote response;
+ return SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ PacketResult::Success;
+}
+
+bool GDBRemoteCommunicationClient::LaunchGDBServer(
+ const char *remote_accept_hostname, lldb::pid_t &pid, uint16_t &port,
+ std::string &socket_name) {
+ pid = LLDB_INVALID_PROCESS_ID;
+ port = 0;
+ socket_name.clear();
+
+ StringExtractorGDBRemote response;
+ StreamString stream;
+ stream.PutCString("qLaunchGDBServer;");
+ std::string hostname;
+ if (remote_accept_hostname && remote_accept_hostname[0])
+ hostname = remote_accept_hostname;
+ else {
+ if (HostInfo::GetHostname(hostname)) {
+ // Make the GDB server we launch only accept connections from this host
+ stream.Printf("host:%s;", hostname.c_str());
+ } else {
+ // Make the GDB server we launch accept connections from any host since we
+ // can't figure out the hostname
+ stream.Printf("host:*;");
+ }
+ }
+ // give the process a few seconds to startup
+ ScopedTimeout timeout(*this, seconds(10));
+
+ if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ PacketResult::Success) {
+ llvm::StringRef name;
+ llvm::StringRef value;
+ while (response.GetNameColonValue(name, value)) {
+ if (name.equals("port"))
+ value.getAsInteger(0, port);
+ else if (name.equals("pid"))
+ value.getAsInteger(0, pid);
+ else if (name.compare("socket_name") == 0) {
+ StringExtractor extractor(value);
+ extractor.GetHexByteString(socket_name);
+ }
+ }
+ return true;
+ }
+ return false;
}
-size_t
-GDBRemoteCommunicationClient::QueryGDBServer (std::vector<std::pair<uint16_t, std::string>>& connection_urls)
-{
- connection_urls.clear();
+size_t GDBRemoteCommunicationClient::QueryGDBServer(
+ std::vector<std::pair<uint16_t, std::string>> &connection_urls) {
+ connection_urls.clear();
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("qQueryGDBServer", response, false) != PacketResult::Success)
- return 0;
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse("qQueryGDBServer", response, false) !=
+ PacketResult::Success)
+ return 0;
- StructuredData::ObjectSP data = StructuredData::ParseJSON(response.GetStringRef());
- if (!data)
- return 0;
+ StructuredData::ObjectSP data =
+ StructuredData::ParseJSON(response.GetStringRef());
+ if (!data)
+ return 0;
- StructuredData::Array* array = data->GetAsArray();
- if (!array)
- return 0;
+ StructuredData::Array *array = data->GetAsArray();
+ if (!array)
+ return 0;
- for (size_t i = 0, count = array->GetSize(); i < count; ++i)
- {
- StructuredData::Dictionary* element = nullptr;
- if (!array->GetItemAtIndexAsDictionary(i, element))
- continue;
+ for (size_t i = 0, count = array->GetSize(); i < count; ++i) {
+ StructuredData::Dictionary *element = nullptr;
+ if (!array->GetItemAtIndexAsDictionary(i, element))
+ continue;
- uint16_t port = 0;
- if (StructuredData::ObjectSP port_osp = element->GetValueForKey(llvm::StringRef("port")))
- port = port_osp->GetIntegerValue(0);
+ uint16_t port = 0;
+ if (StructuredData::ObjectSP port_osp =
+ element->GetValueForKey(llvm::StringRef("port")))
+ port = port_osp->GetIntegerValue(0);
- std::string socket_name;
- if (StructuredData::ObjectSP socket_name_osp = element->GetValueForKey(llvm::StringRef("socket_name")))
- socket_name = socket_name_osp->GetStringValue();
+ std::string socket_name;
+ if (StructuredData::ObjectSP socket_name_osp =
+ element->GetValueForKey(llvm::StringRef("socket_name")))
+ socket_name = socket_name_osp->GetStringValue();
- if (port != 0 || !socket_name.empty())
- connection_urls.emplace_back(port, socket_name);
- }
- return connection_urls.size();
+ if (port != 0 || !socket_name.empty())
+ connection_urls.emplace_back(port, socket_name);
+ }
+ return connection_urls.size();
}
-bool
-GDBRemoteCommunicationClient::KillSpawnedProcess (lldb::pid_t pid)
-{
- StreamString stream;
- stream.Printf ("qKillSpawnedProcess:%" PRId64 , pid);
- const char *packet = stream.GetData();
- int packet_len = stream.GetSize();
+bool GDBRemoteCommunicationClient::KillSpawnedProcess(lldb::pid_t pid) {
+ StreamString stream;
+ stream.Printf("qKillSpawnedProcess:%" PRId64, pid);
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- return true;
- }
- return false;
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse())
+ return true;
+ }
+ return false;
}
-bool
-GDBRemoteCommunicationClient::SetCurrentThread (uint64_t tid)
-{
- if (m_curr_tid == tid)
- return true;
-
- char packet[32];
- int packet_len;
- if (tid == UINT64_MAX)
- packet_len = ::snprintf (packet, sizeof(packet), "Hg-1");
- else
- packet_len = ::snprintf (packet, sizeof(packet), "Hg%" PRIx64, tid);
- assert (packet_len + 1 < (int)sizeof(packet));
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- {
- m_curr_tid = tid;
- return true;
- }
+bool GDBRemoteCommunicationClient::SetCurrentThread(uint64_t tid) {
+ if (m_curr_tid == tid)
+ return true;
- /*
- * Connected bare-iron target (like YAMON gdb-stub) may not have support for Hg packet.
- * The reply from '?' packet could be as simple as 'S05'. There is no packet which can
- * give us pid and/or tid. Assume pid=tid=1 in such cases.
- */
- if (response.IsUnsupportedResponse() && IsConnected())
- {
- m_curr_tid = 1;
- return true;
- }
- }
- return false;
-}
+ char packet[32];
+ int packet_len;
+ if (tid == UINT64_MAX)
+ packet_len = ::snprintf(packet, sizeof(packet), "Hg-1");
+ else
+ packet_len = ::snprintf(packet, sizeof(packet), "Hg%" PRIx64, tid);
+ assert(packet_len + 1 < (int)sizeof(packet));
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet, response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse()) {
+ m_curr_tid = tid;
+ return true;
+ }
+
+ /*
+ * Connected bare-iron target (like YAMON gdb-stub) may not have support for
+ * Hg packet.
+ * The reply from '?' packet could be as simple as 'S05'. There is no packet
+ * which can
+ * give us pid and/or tid. Assume pid=tid=1 in such cases.
+ */
+ if (response.IsUnsupportedResponse() && IsConnected()) {
+ m_curr_tid = 1;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool GDBRemoteCommunicationClient::SetCurrentThreadForRun(uint64_t tid) {
+ if (m_curr_tid_run == tid)
+ return true;
-bool
-GDBRemoteCommunicationClient::SetCurrentThreadForRun (uint64_t tid)
-{
- if (m_curr_tid_run == tid)
+ char packet[32];
+ int packet_len;
+ if (tid == UINT64_MAX)
+ packet_len = ::snprintf(packet, sizeof(packet), "Hc-1");
+ else
+ packet_len = ::snprintf(packet, sizeof(packet), "Hc%" PRIx64, tid);
+
+ assert(packet_len + 1 < (int)sizeof(packet));
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet, response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse()) {
+ m_curr_tid_run = tid;
+ return true;
+ }
+
+ /*
+ * Connected bare-iron target (like YAMON gdb-stub) may not have support for
+ * Hc packet.
+ * The reply from '?' packet could be as simple as 'S05'. There is no packet
+ * which can
+ * give us pid and/or tid. Assume pid=tid=1 in such cases.
+ */
+ if (response.IsUnsupportedResponse() && IsConnected()) {
+ m_curr_tid_run = 1;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool GDBRemoteCommunicationClient::GetStopReply(
+ StringExtractorGDBRemote &response) {
+ if (SendPacketAndWaitForResponse("?", response, false) ==
+ PacketResult::Success)
+ return response.IsNormalResponse();
+ return false;
+}
+
+bool GDBRemoteCommunicationClient::GetThreadStopInfo(
+ lldb::tid_t tid, StringExtractorGDBRemote &response) {
+ if (m_supports_qThreadStopInfo) {
+ char packet[256];
+ int packet_len =
+ ::snprintf(packet, sizeof(packet), "qThreadStopInfo%" PRIx64, tid);
+ assert(packet_len < (int)sizeof(packet));
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
+ if (SendPacketAndWaitForResponse(packet, response, false) ==
+ PacketResult::Success) {
+ if (response.IsUnsupportedResponse())
+ m_supports_qThreadStopInfo = false;
+ else if (response.IsNormalResponse())
return true;
-
- char packet[32];
- int packet_len;
- if (tid == UINT64_MAX)
- packet_len = ::snprintf (packet, sizeof(packet), "Hc-1");
- else
- packet_len = ::snprintf (packet, sizeof(packet), "Hc%" PRIx64, tid);
-
- assert (packet_len + 1 < (int)sizeof(packet));
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- {
- m_curr_tid_run = tid;
- return true;
- }
-
- /*
- * Connected bare-iron target (like YAMON gdb-stub) may not have support for Hc packet.
- * The reply from '?' packet could be as simple as 'S05'. There is no packet which can
- * give us pid and/or tid. Assume pid=tid=1 in such cases.
- */
- if (response.IsUnsupportedResponse() && IsConnected())
- {
- m_curr_tid_run = 1;
- return true;
- }
+ else
+ return false;
+ } else {
+ m_supports_qThreadStopInfo = false;
}
- return false;
+ }
+ return false;
}
-bool
-GDBRemoteCommunicationClient::GetStopReply (StringExtractorGDBRemote &response)
-{
- if (SendPacketAndWaitForResponse("?", 1, response, false) == PacketResult::Success)
- return response.IsNormalResponse();
- return false;
-}
+uint8_t GDBRemoteCommunicationClient::SendGDBStoppointTypePacket(
+ GDBStoppointType type, bool insert, addr_t addr, uint32_t length) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ if (log)
+ log->Printf("GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
+ __FUNCTION__, insert ? "add" : "remove", addr);
-bool
-GDBRemoteCommunicationClient::GetThreadStopInfo (lldb::tid_t tid, StringExtractorGDBRemote &response)
-{
- if (m_supports_qThreadStopInfo)
- {
- char packet[256];
- int packet_len = ::snprintf(packet, sizeof(packet), "qThreadStopInfo%" PRIx64, tid);
- assert (packet_len < (int)sizeof(packet));
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.IsUnsupportedResponse())
- m_supports_qThreadStopInfo = false;
- else if (response.IsNormalResponse())
- return true;
- else
- return false;
- }
- else
- {
- m_supports_qThreadStopInfo = false;
- }
+ // Check if the stub is known not to support this breakpoint type
+ if (!SupportsGDBStoppointPacket(type))
+ return UINT8_MAX;
+ // Construct the breakpoint packet
+ char packet[64];
+ const int packet_len =
+ ::snprintf(packet, sizeof(packet), "%c%i,%" PRIx64 ",%x",
+ insert ? 'Z' : 'z', type, addr, length);
+ // Check we haven't overwritten the end of the packet buffer
+ assert(packet_len + 1 < (int)sizeof(packet));
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
+ StringExtractorGDBRemote response;
+ // Make sure the response is either "OK", "EXX" where XX are two hex digits,
+ // or "" (unsupported)
+ response.SetResponseValidatorToOKErrorNotSupported();
+ // Try to send the breakpoint packet, and check that it was correctly sent
+ if (SendPacketAndWaitForResponse(packet, response, true) ==
+ PacketResult::Success) {
+ // Receive and OK packet when the breakpoint successfully placed
+ if (response.IsOKResponse())
+ return 0;
+
+ // Error while setting breakpoint, send back specific error
+ if (response.IsErrorResponse())
+ return response.GetError();
+
+ // Empty packet informs us that breakpoint is not supported
+ if (response.IsUnsupportedResponse()) {
+ // Disable this breakpoint type since it is unsupported
+ switch (type) {
+ case eBreakpointSoftware:
+ m_supports_z0 = false;
+ break;
+ case eBreakpointHardware:
+ m_supports_z1 = false;
+ break;
+ case eWatchpointWrite:
+ m_supports_z2 = false;
+ break;
+ case eWatchpointRead:
+ m_supports_z3 = false;
+ break;
+ case eWatchpointReadWrite:
+ m_supports_z4 = false;
+ break;
+ case eStoppointInvalid:
+ return UINT8_MAX;
+ }
}
- return false;
+ }
+ // Signal generic failure
+ return UINT8_MAX;
}
+size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs(
+ std::vector<lldb::tid_t> &thread_ids, bool &sequence_mutex_unavailable) {
+ thread_ids.clear();
-uint8_t
-GDBRemoteCommunicationClient::SendGDBStoppointTypePacket (GDBStoppointType type, bool insert, addr_t addr, uint32_t length)
-{
- Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
- if (log)
- log->Printf ("GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
- __FUNCTION__, insert ? "add" : "remove", addr);
-
- // Check if the stub is known not to support this breakpoint type
- if (!SupportsGDBStoppointPacket(type))
- return UINT8_MAX;
- // Construct the breakpoint packet
- char packet[64];
- const int packet_len = ::snprintf (packet,
- sizeof(packet),
- "%c%i,%" PRIx64 ",%x",
- insert ? 'Z' : 'z',
- type,
- addr,
- length);
- // Check we haven't overwritten the end of the packet buffer
- assert (packet_len + 1 < (int)sizeof(packet));
+ Lock lock(*this, false);
+ if (lock) {
+ sequence_mutex_unavailable = false;
StringExtractorGDBRemote response;
- // Make sure the response is either "OK", "EXX" where XX are two hex digits, or "" (unsupported)
- response.SetResponseValidatorToOKErrorNotSupported();
- // Try to send the breakpoint packet, and check that it was correctly sent
- if (SendPacketAndWaitForResponse(packet, packet_len, response, true) == PacketResult::Success)
- {
- // Receive and OK packet when the breakpoint successfully placed
- if (response.IsOKResponse())
- return 0;
-
- // Error while setting breakpoint, send back specific error
- if (response.IsErrorResponse())
- return response.GetError();
-
- // Empty packet informs us that breakpoint is not supported
- if (response.IsUnsupportedResponse())
- {
- // Disable this breakpoint type since it is unsupported
- switch (type)
- {
- case eBreakpointSoftware: m_supports_z0 = false; break;
- case eBreakpointHardware: m_supports_z1 = false; break;
- case eWatchpointWrite: m_supports_z2 = false; break;
- case eWatchpointRead: m_supports_z3 = false; break;
- case eWatchpointReadWrite: m_supports_z4 = false; break;
- case eStoppointInvalid: return UINT8_MAX;
- }
- }
- }
- // Signal generic failure
- return UINT8_MAX;
-}
-
-size_t
-GDBRemoteCommunicationClient::GetCurrentThreadIDs (std::vector<lldb::tid_t> &thread_ids,
- bool &sequence_mutex_unavailable)
-{
- Mutex::Locker locker;
- thread_ids.clear();
-
- if (GetSequenceMutex (locker, "ProcessGDBRemote::UpdateThreadList() failed due to not getting the sequence mutex"))
- {
- sequence_mutex_unavailable = false;
- StringExtractorGDBRemote response;
-
- PacketResult packet_result;
- for (packet_result = SendPacketAndWaitForResponseNoLock ("qfThreadInfo", strlen("qfThreadInfo"), response);
- packet_result == PacketResult::Success && response.IsNormalResponse();
- packet_result = SendPacketAndWaitForResponseNoLock ("qsThreadInfo", strlen("qsThreadInfo"), response))
- {
- char ch = response.GetChar();
- if (ch == 'l')
- break;
- if (ch == 'm')
- {
- do
- {
- tid_t tid = response.GetHexMaxU64(false, LLDB_INVALID_THREAD_ID);
-
- if (tid != LLDB_INVALID_THREAD_ID)
- {
- thread_ids.push_back (tid);
- }
- ch = response.GetChar(); // Skip the command separator
- } while (ch == ','); // Make sure we got a comma separator
- }
- }
- /*
- * Connected bare-iron target (like YAMON gdb-stub) may not have support for
- * qProcessInfo, qC and qfThreadInfo packets. The reply from '?' packet could
- * be as simple as 'S05'. There is no packet which can give us pid and/or tid.
- * Assume pid=tid=1 in such cases.
- */
- if (response.IsUnsupportedResponse() && thread_ids.size() == 0 && IsConnected())
- {
- thread_ids.push_back (1);
- }
- }
- else
- {
-#if defined (LLDB_CONFIGURATION_DEBUG)
- // assert(!"ProcessGDBRemote::UpdateThreadList() failed due to not getting the sequence mutex");
+ PacketResult packet_result;
+ for (packet_result =
+ SendPacketAndWaitForResponseNoLock("qfThreadInfo", response);
+ packet_result == PacketResult::Success && response.IsNormalResponse();
+ packet_result =
+ SendPacketAndWaitForResponseNoLock("qsThreadInfo", response)) {
+ char ch = response.GetChar();
+ if (ch == 'l')
+ break;
+ if (ch == 'm') {
+ do {
+ tid_t tid = response.GetHexMaxU64(false, LLDB_INVALID_THREAD_ID);
+
+ if (tid != LLDB_INVALID_THREAD_ID) {
+ thread_ids.push_back(tid);
+ }
+ ch = response.GetChar(); // Skip the command separator
+ } while (ch == ','); // Make sure we got a comma separator
+ }
+ }
+
+ /*
+ * Connected bare-iron target (like YAMON gdb-stub) may not have support for
+ * qProcessInfo, qC and qfThreadInfo packets. The reply from '?' packet
+ * could
+ * be as simple as 'S05'. There is no packet which can give us pid and/or
+ * tid.
+ * Assume pid=tid=1 in such cases.
+ */
+ if (response.IsUnsupportedResponse() && thread_ids.size() == 0 &&
+ IsConnected()) {
+ thread_ids.push_back(1);
+ }
+ } else {
+#if defined(LLDB_CONFIGURATION_DEBUG)
+// assert(!"ProcessGDBRemote::UpdateThreadList() failed due to not getting the
+// sequence mutex");
#else
- Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
- if (log)
- log->Printf("error: failed to get packet sequence mutex, not sending packet 'qfThreadInfo'");
+ Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
+ GDBR_LOG_PACKETS));
+ if (log)
+ log->Printf("error: failed to get packet sequence mutex, not sending "
+ "packet 'qfThreadInfo'");
#endif
- sequence_mutex_unavailable = true;
- }
- return thread_ids.size();
+ sequence_mutex_unavailable = true;
+ }
+ return thread_ids.size();
}
-lldb::addr_t
-GDBRemoteCommunicationClient::GetShlibInfoAddr()
-{
- if (!IsRunning())
- {
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("qShlibInfoAddr", ::strlen ("qShlibInfoAddr"), response, false) == PacketResult::Success)
- {
- if (response.IsNormalResponse())
- return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
- }
- }
+lldb::addr_t GDBRemoteCommunicationClient::GetShlibInfoAddr() {
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse("qShlibInfoAddr", response, false) !=
+ PacketResult::Success ||
+ !response.IsNormalResponse())
return LLDB_INVALID_ADDRESS;
-}
-
-lldb_private::Error
-GDBRemoteCommunicationClient::RunShellCommand(const char *command, // Shouldn't be NULL
- const FileSpec &working_dir, // Pass empty FileSpec to use the current working directory
- int *status_ptr, // Pass NULL if you don't want the process exit status
- int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
- std::string *command_output, // Pass NULL if you don't want the command output
- uint32_t timeout_sec) // Timeout in seconds to wait for shell program to finish
-{
- lldb_private::StreamString stream;
- stream.PutCString("qPlatform_shell:");
- stream.PutBytesAsRawHex8(command, strlen(command));
- stream.PutChar(',');
- stream.PutHex32(timeout_sec);
- if (working_dir)
- {
- std::string path{working_dir.GetPath(false)};
- stream.PutChar(',');
- stream.PutCStringAsRawHex8(path.c_str());
- }
- const char *packet = stream.GetData();
- int packet_len = stream.GetSize();
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.GetChar() != 'F')
- return Error("malformed reply");
- if (response.GetChar() != ',')
- return Error("malformed reply");
- uint32_t exitcode = response.GetHexMaxU32(false, UINT32_MAX);
- if (exitcode == UINT32_MAX)
- return Error("unable to run remote process");
- else if (status_ptr)
- *status_ptr = exitcode;
- if (response.GetChar() != ',')
- return Error("malformed reply");
- uint32_t signo = response.GetHexMaxU32(false, UINT32_MAX);
- if (signo_ptr)
- *signo_ptr = signo;
- if (response.GetChar() != ',')
- return Error("malformed reply");
- std::string output;
- response.GetEscapedBinaryData(output);
- if (command_output)
- command_output->assign(output);
- return Error();
- }
- return Error("unable to send packet");
-}
-
-Error
-GDBRemoteCommunicationClient::MakeDirectory(const FileSpec &file_spec,
- uint32_t file_permissions)
-{
- std::string path{file_spec.GetPath(false)};
- lldb_private::StreamString stream;
- stream.PutCString("qPlatform_mkdir:");
- stream.PutHex32(file_permissions);
+ return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
+}
+
+lldb_private::Error GDBRemoteCommunicationClient::RunShellCommand(
+ const char *command, // Shouldn't be NULL
+ const FileSpec &
+ working_dir, // Pass empty FileSpec to use the current working directory
+ int *status_ptr, // Pass NULL if you don't want the process exit status
+ int *signo_ptr, // Pass NULL if you don't want the signal that caused the
+ // process to exit
+ std::string
+ *command_output, // Pass NULL if you don't want the command output
+ uint32_t
+ timeout_sec) // Timeout in seconds to wait for shell program to finish
+{
+ lldb_private::StreamString stream;
+ stream.PutCString("qPlatform_shell:");
+ stream.PutBytesAsRawHex8(command, strlen(command));
+ stream.PutChar(',');
+ stream.PutHex32(timeout_sec);
+ if (working_dir) {
+ std::string path{working_dir.GetPath(false)};
stream.PutChar(',');
stream.PutCStringAsRawHex8(path.c_str());
- const char *packet = stream.GetData();
- int packet_len = stream.GetSize();
- StringExtractorGDBRemote response;
-
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) != PacketResult::Success)
- return Error("failed to send '%s' packet", packet);
-
+ }
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ PacketResult::Success) {
if (response.GetChar() != 'F')
- return Error("invalid response to '%s' packet", packet);
-
- return Error(response.GetU32(UINT32_MAX), eErrorTypePOSIX);
-}
-
-Error
-GDBRemoteCommunicationClient::SetFilePermissions(const FileSpec &file_spec,
- uint32_t file_permissions)
-{
- std::string path{file_spec.GetPath(false)};
- lldb_private::StreamString stream;
- stream.PutCString("qPlatform_chmod:");
- stream.PutHex32(file_permissions);
- stream.PutChar(',');
- stream.PutCStringAsRawHex8(path.c_str());
- const char *packet = stream.GetData();
- int packet_len = stream.GetSize();
- StringExtractorGDBRemote response;
-
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) != PacketResult::Success)
- return Error("failed to send '%s' packet", packet);
-
- if (response.GetChar() != 'F')
- return Error("invalid response to '%s' packet", packet);
-
- return Error(response.GetU32(UINT32_MAX), eErrorTypePOSIX);
-}
-
-static uint64_t
-ParseHostIOPacketResponse (StringExtractorGDBRemote &response,
- uint64_t fail_result,
- Error &error)
-{
- response.SetFilePos(0);
- if (response.GetChar() != 'F')
- return fail_result;
- int32_t result = response.GetS32 (-2);
- if (result == -2)
- return fail_result;
- if (response.GetChar() == ',')
- {
- int result_errno = response.GetS32 (-2);
- if (result_errno != -2)
- error.SetError(result_errno, eErrorTypePOSIX);
- else
- error.SetError(-1, eErrorTypeGeneric);
- }
+ return Error("malformed reply");
+ if (response.GetChar() != ',')
+ return Error("malformed reply");
+ uint32_t exitcode = response.GetHexMaxU32(false, UINT32_MAX);
+ if (exitcode == UINT32_MAX)
+ return Error("unable to run remote process");
+ else if (status_ptr)
+ *status_ptr = exitcode;
+ if (response.GetChar() != ',')
+ return Error("malformed reply");
+ uint32_t signo = response.GetHexMaxU32(false, UINT32_MAX);
+ if (signo_ptr)
+ *signo_ptr = signo;
+ if (response.GetChar() != ',')
+ return Error("malformed reply");
+ std::string output;
+ response.GetEscapedBinaryData(output);
+ if (command_output)
+ command_output->assign(output);
+ return Error();
+ }
+ return Error("unable to send packet");
+}
+
+Error GDBRemoteCommunicationClient::MakeDirectory(const FileSpec &file_spec,
+ uint32_t file_permissions) {
+ std::string path{file_spec.GetPath(false)};
+ lldb_private::StreamString stream;
+ stream.PutCString("qPlatform_mkdir:");
+ stream.PutHex32(file_permissions);
+ stream.PutChar(',');
+ stream.PutCStringAsRawHex8(path.c_str());
+ llvm::StringRef packet = stream.GetString();
+ StringExtractorGDBRemote response;
+
+ if (SendPacketAndWaitForResponse(packet, response, false) !=
+ PacketResult::Success)
+ return Error("failed to send '%s' packet", packet.str().c_str());
+
+ if (response.GetChar() != 'F')
+ return Error("invalid response to '%s' packet", packet.str().c_str());
+
+ return Error(response.GetU32(UINT32_MAX), eErrorTypePOSIX);
+}
+
+Error GDBRemoteCommunicationClient::SetFilePermissions(
+ const FileSpec &file_spec, uint32_t file_permissions) {
+ std::string path{file_spec.GetPath(false)};
+ lldb_private::StreamString stream;
+ stream.PutCString("qPlatform_chmod:");
+ stream.PutHex32(file_permissions);
+ stream.PutChar(',');
+ stream.PutCStringAsRawHex8(path.c_str());
+ llvm::StringRef packet = stream.GetString();
+ StringExtractorGDBRemote response;
+
+ if (SendPacketAndWaitForResponse(packet, response, false) !=
+ PacketResult::Success)
+ return Error("failed to send '%s' packet", stream.GetData());
+
+ if (response.GetChar() != 'F')
+ return Error("invalid response to '%s' packet", stream.GetData());
+
+ return Error(response.GetU32(UINT32_MAX), eErrorTypePOSIX);
+}
+
+static uint64_t ParseHostIOPacketResponse(StringExtractorGDBRemote &response,
+ uint64_t fail_result, Error &error) {
+ response.SetFilePos(0);
+ if (response.GetChar() != 'F')
+ return fail_result;
+ int32_t result = response.GetS32(-2);
+ if (result == -2)
+ return fail_result;
+ if (response.GetChar() == ',') {
+ int result_errno = response.GetS32(-2);
+ if (result_errno != -2)
+ error.SetError(result_errno, eErrorTypePOSIX);
else
- error.Clear();
- return result;
+ error.SetError(-1, eErrorTypeGeneric);
+ } else
+ error.Clear();
+ return result;
}
lldb::user_id_t
-GDBRemoteCommunicationClient::OpenFile (const lldb_private::FileSpec& file_spec,
- uint32_t flags,
- mode_t mode,
- Error &error)
-{
- std::string path(file_spec.GetPath(false));
- lldb_private::StreamString stream;
- stream.PutCString("vFile:open:");
- if (path.empty())
- return UINT64_MAX;
- stream.PutCStringAsRawHex8(path.c_str());
- stream.PutChar(',');
- stream.PutHex32(flags);
- stream.PutChar(',');
- stream.PutHex32(mode);
- const char* packet = stream.GetData();
- int packet_len = stream.GetSize();
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- {
- return ParseHostIOPacketResponse (response, UINT64_MAX, error);
- }
+GDBRemoteCommunicationClient::OpenFile(const lldb_private::FileSpec &file_spec,
+ uint32_t flags, mode_t mode,
+ Error &error) {
+ std::string path(file_spec.GetPath(false));
+ lldb_private::StreamString stream;
+ stream.PutCString("vFile:open:");
+ if (path.empty())
return UINT64_MAX;
-}
-
-bool
-GDBRemoteCommunicationClient::CloseFile (lldb::user_id_t fd,
- Error &error)
-{
- lldb_private::StreamString stream;
- stream.Printf("vFile:close:%i", (int)fd);
- const char* packet = stream.GetData();
- int packet_len = stream.GetSize();
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- {
- return ParseHostIOPacketResponse (response, -1, error) == 0;
- }
- return false;
+ stream.PutCStringAsRawHex8(path.c_str());
+ stream.PutChar(',');
+ stream.PutHex32(flags);
+ stream.PutChar(',');
+ stream.PutHex32(mode);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ PacketResult::Success) {
+ return ParseHostIOPacketResponse(response, UINT64_MAX, error);
+ }
+ return UINT64_MAX;
+}
+
+bool GDBRemoteCommunicationClient::CloseFile(lldb::user_id_t fd, Error &error) {
+ lldb_private::StreamString stream;
+ stream.Printf("vFile:close:%i", (int)fd);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ PacketResult::Success) {
+ return ParseHostIOPacketResponse(response, -1, error) == 0;
+ }
+ return false;
}
// Extension of host I/O packets to get the file size.
-lldb::user_id_t
-GDBRemoteCommunicationClient::GetFileSize (const lldb_private::FileSpec& file_spec)
-{
- std::string path(file_spec.GetPath(false));
- lldb_private::StreamString stream;
- stream.PutCString("vFile:size:");
- stream.PutCStringAsRawHex8(path.c_str());
- const char* packet = stream.GetData();
- int packet_len = stream.GetSize();
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.GetChar() != 'F')
- return UINT64_MAX;
- uint32_t retcode = response.GetHexMaxU64(false, UINT64_MAX);
- return retcode;
- }
- return UINT64_MAX;
+lldb::user_id_t GDBRemoteCommunicationClient::GetFileSize(
+ const lldb_private::FileSpec &file_spec) {
+ std::string path(file_spec.GetPath(false));
+ lldb_private::StreamString stream;
+ stream.PutCString("vFile:size:");
+ stream.PutCStringAsRawHex8(path.c_str());
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.GetChar() != 'F')
+ return UINT64_MAX;
+ uint32_t retcode = response.GetHexMaxU64(false, UINT64_MAX);
+ return retcode;
+ }
+ return UINT64_MAX;
+}
+
+Error GDBRemoteCommunicationClient::GetFilePermissions(
+ const FileSpec &file_spec, uint32_t &file_permissions) {
+ std::string path{file_spec.GetPath(false)};
+ Error error;
+ lldb_private::StreamString stream;
+ stream.PutCString("vFile:mode:");
+ stream.PutCStringAsRawHex8(path.c_str());
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.GetChar() != 'F') {
+ error.SetErrorStringWithFormat("invalid response to '%s' packet",
+ stream.GetData());
+ } else {
+ const uint32_t mode = response.GetS32(-1);
+ if (static_cast<int32_t>(mode) == -1) {
+ if (response.GetChar() == ',') {
+ int response_errno = response.GetS32(-1);
+ if (response_errno > 0)
+ error.SetError(response_errno, lldb::eErrorTypePOSIX);
+ else
+ error.SetErrorToGenericError();
+ } else
+ error.SetErrorToGenericError();
+ } else {
+ file_permissions = mode & (S_IRWXU | S_IRWXG | S_IRWXO);
+ }
+ }
+ } else {
+ error.SetErrorStringWithFormat("failed to send '%s' packet",
+ stream.GetData());
+ }
+ return error;
+}
+
+uint64_t GDBRemoteCommunicationClient::ReadFile(lldb::user_id_t fd,
+ uint64_t offset, void *dst,
+ uint64_t dst_len,
+ Error &error) {
+ lldb_private::StreamString stream;
+ stream.Printf("vFile:pread:%i,%" PRId64 ",%" PRId64, (int)fd, dst_len,
+ offset);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.GetChar() != 'F')
+ return 0;
+ uint32_t retcode = response.GetHexMaxU32(false, UINT32_MAX);
+ if (retcode == UINT32_MAX)
+ return retcode;
+ const char next = (response.Peek() ? *response.Peek() : 0);
+ if (next == ',')
+ return 0;
+ if (next == ';') {
+ response.GetChar(); // skip the semicolon
+ std::string buffer;
+ if (response.GetEscapedBinaryData(buffer)) {
+ const uint64_t data_to_write =
+ std::min<uint64_t>(dst_len, buffer.size());
+ if (data_to_write > 0)
+ memcpy(dst, &buffer[0], data_to_write);
+ return data_to_write;
+ }
+ }
+ }
+ return 0;
+}
+
+uint64_t GDBRemoteCommunicationClient::WriteFile(lldb::user_id_t fd,
+ uint64_t offset,
+ const void *src,
+ uint64_t src_len,
+ Error &error) {
+ lldb_private::StreamGDBRemote stream;
+ stream.Printf("vFile:pwrite:%i,%" PRId64 ",", (int)fd, offset);
+ stream.PutEscapedBytes(src, src_len);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.GetChar() != 'F') {
+ error.SetErrorStringWithFormat("write file failed");
+ return 0;
+ }
+ uint64_t bytes_written = response.GetU64(UINT64_MAX);
+ if (bytes_written == UINT64_MAX) {
+ error.SetErrorToGenericError();
+ if (response.GetChar() == ',') {
+ int response_errno = response.GetS32(-1);
+ if (response_errno > 0)
+ error.SetError(response_errno, lldb::eErrorTypePOSIX);
+ }
+ return 0;
+ }
+ return bytes_written;
+ } else {
+ error.SetErrorString("failed to send vFile:pwrite packet");
+ }
+ return 0;
+}
+
+Error GDBRemoteCommunicationClient::CreateSymlink(const FileSpec &src,
+ const FileSpec &dst) {
+ std::string src_path{src.GetPath(false)}, dst_path{dst.GetPath(false)};
+ Error error;
+ lldb_private::StreamGDBRemote stream;
+ stream.PutCString("vFile:symlink:");
+ // the unix symlink() command reverses its parameters where the dst if first,
+ // so we follow suit here
+ stream.PutCStringAsRawHex8(dst_path.c_str());
+ stream.PutChar(',');
+ stream.PutCStringAsRawHex8(src_path.c_str());
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.GetChar() == 'F') {
+ uint32_t result = response.GetU32(UINT32_MAX);
+ if (result != 0) {
+ error.SetErrorToGenericError();
+ if (response.GetChar() == ',') {
+ int response_errno = response.GetS32(-1);
+ if (response_errno > 0)
+ error.SetError(response_errno, lldb::eErrorTypePOSIX);
+ }
+ }
+ } else {
+ // Should have returned with 'F<result>[,<errno>]'
+ error.SetErrorStringWithFormat("symlink failed");
+ }
+ } else {
+ error.SetErrorString("failed to send vFile:symlink packet");
+ }
+ return error;
+}
+
+Error GDBRemoteCommunicationClient::Unlink(const FileSpec &file_spec) {
+ std::string path{file_spec.GetPath(false)};
+ Error error;
+ lldb_private::StreamGDBRemote stream;
+ stream.PutCString("vFile:unlink:");
+ // the unix symlink() command reverses its parameters where the dst if first,
+ // so we follow suit here
+ stream.PutCStringAsRawHex8(path.c_str());
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.GetChar() == 'F') {
+ uint32_t result = response.GetU32(UINT32_MAX);
+ if (result != 0) {
+ error.SetErrorToGenericError();
+ if (response.GetChar() == ',') {
+ int response_errno = response.GetS32(-1);
+ if (response_errno > 0)
+ error.SetError(response_errno, lldb::eErrorTypePOSIX);
+ }
+ }
+ } else {
+ // Should have returned with 'F<result>[,<errno>]'
+ error.SetErrorStringWithFormat("unlink failed");
+ }
+ } else {
+ error.SetErrorString("failed to send vFile:unlink packet");
+ }
+ return error;
}
-Error
-GDBRemoteCommunicationClient::GetFilePermissions(const FileSpec &file_spec,
- uint32_t &file_permissions)
-{
- std::string path{file_spec.GetPath(false)};
- Error error;
- lldb_private::StreamString stream;
- stream.PutCString("vFile:mode:");
- stream.PutCStringAsRawHex8(path.c_str());
- const char* packet = stream.GetData();
- int packet_len = stream.GetSize();
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.GetChar() != 'F')
- {
- error.SetErrorStringWithFormat ("invalid response to '%s' packet", packet);
- }
- else
- {
- const uint32_t mode = response.GetS32(-1);
- if (static_cast<int32_t>(mode) == -1)
- {
- if (response.GetChar() == ',')
- {
- int response_errno = response.GetS32(-1);
- if (response_errno > 0)
- error.SetError(response_errno, lldb::eErrorTypePOSIX);
- else
- error.SetErrorToGenericError();
- }
- else
- error.SetErrorToGenericError();
- }
- else
- {
- file_permissions = mode & (S_IRWXU|S_IRWXG|S_IRWXO);
- }
- }
- }
- else
- {
- error.SetErrorStringWithFormat ("failed to send '%s' packet", packet);
- }
- return error;
-}
+// Extension of host I/O packets to get whether a file exists.
+bool GDBRemoteCommunicationClient::GetFileExists(
+ const lldb_private::FileSpec &file_spec) {
+ std::string path(file_spec.GetPath(false));
+ lldb_private::StreamString stream;
+ stream.PutCString("vFile:exists:");
+ stream.PutCStringAsRawHex8(path.c_str());
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.GetChar() != 'F')
+ return false;
+ if (response.GetChar() != ',')
+ return false;
+ bool retcode = (response.GetChar() != '0');
+ return retcode;
+ }
+ return false;
+}
+
+bool GDBRemoteCommunicationClient::CalculateMD5(
+ const lldb_private::FileSpec &file_spec, uint64_t &high, uint64_t &low) {
+ std::string path(file_spec.GetPath(false));
+ lldb_private::StreamString stream;
+ stream.PutCString("vFile:MD5:");
+ stream.PutCStringAsRawHex8(path.c_str());
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ PacketResult::Success) {
+ if (response.GetChar() != 'F')
+ return false;
+ if (response.GetChar() != ',')
+ return false;
+ if (response.Peek() && *response.Peek() == 'x')
+ return false;
+ low = response.GetHexMaxU64(false, UINT64_MAX);
+ high = response.GetHexMaxU64(false, UINT64_MAX);
+ return true;
+ }
+ return false;
+}
+
+bool GDBRemoteCommunicationClient::AvoidGPackets(ProcessGDBRemote *process) {
+ // Some targets have issues with g/G packets and we need to avoid using them
+ if (m_avoid_g_packets == eLazyBoolCalculate) {
+ if (process) {
+ m_avoid_g_packets = eLazyBoolNo;
+ const ArchSpec &arch = process->GetTarget().GetArchitecture();
+ if (arch.IsValid() &&
+ arch.GetTriple().getVendor() == llvm::Triple::Apple &&
+ arch.GetTriple().getOS() == llvm::Triple::IOS &&
+ arch.GetTriple().getArch() == llvm::Triple::aarch64) {
+ m_avoid_g_packets = eLazyBoolYes;
+ uint32_t gdb_server_version = GetGDBServerProgramVersion();
+ if (gdb_server_version != 0) {
+ const char *gdb_server_name = GetGDBServerProgramName();
+ if (gdb_server_name && strcmp(gdb_server_name, "debugserver") == 0) {
+ if (gdb_server_version >= 310)
+ m_avoid_g_packets = eLazyBoolNo;
+ }
+ }
+ }
+ }
+ }
+ return m_avoid_g_packets == eLazyBoolYes;
+}
+
+DataBufferSP GDBRemoteCommunicationClient::ReadRegister(lldb::tid_t tid,
+ uint32_t reg) {
+ StreamString payload;
+ payload.Printf("p%x", reg);
+ StringExtractorGDBRemote response;
+ if (SendThreadSpecificPacketAndWaitForResponse(
+ tid, std::move(payload), response, false) != PacketResult::Success ||
+ !response.IsNormalResponse())
+ return nullptr;
+
+ DataBufferSP buffer_sp(
+ new DataBufferHeap(response.GetStringRef().size() / 2, 0));
+ response.GetHexBytes(buffer_sp->GetData(), '\xcc');
+ return buffer_sp;
+}
+
+DataBufferSP GDBRemoteCommunicationClient::ReadAllRegisters(lldb::tid_t tid) {
+ StreamString payload;
+ payload.PutChar('g');
+ StringExtractorGDBRemote response;
+ if (SendThreadSpecificPacketAndWaitForResponse(
+ tid, std::move(payload), response, false) != PacketResult::Success ||
+ !response.IsNormalResponse())
+ return nullptr;
+
+ DataBufferSP buffer_sp(
+ new DataBufferHeap(response.GetStringRef().size() / 2, 0));
+ response.GetHexBytes(buffer_sp->GetData(), '\xcc');
+ return buffer_sp;
+}
+
+bool GDBRemoteCommunicationClient::WriteRegister(lldb::tid_t tid,
+ uint32_t reg_num,
+ llvm::ArrayRef<uint8_t> data) {
+ StreamString payload;
+ payload.Printf("P%x=", reg_num);
+ payload.PutBytesAsRawHex8(data.data(), data.size(),
+ endian::InlHostByteOrder(),
+ endian::InlHostByteOrder());
+ StringExtractorGDBRemote response;
+ return SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload),
+ response, false) ==
+ PacketResult::Success &&
+ response.IsOKResponse();
+}
+
+bool GDBRemoteCommunicationClient::WriteAllRegisters(
+ lldb::tid_t tid, llvm::ArrayRef<uint8_t> data) {
+ StreamString payload;
+ payload.PutChar('G');
+ payload.PutBytesAsRawHex8(data.data(), data.size(),
+ endian::InlHostByteOrder(),
+ endian::InlHostByteOrder());
+ StringExtractorGDBRemote response;
+ return SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload),
+ response, false) ==
+ PacketResult::Success &&
+ response.IsOKResponse();
+}
+
+bool GDBRemoteCommunicationClient::SaveRegisterState(lldb::tid_t tid,
+ uint32_t &save_id) {
+ save_id = 0; // Set to invalid save ID
+ if (m_supports_QSaveRegisterState == eLazyBoolNo)
+ return false;
-uint64_t
-GDBRemoteCommunicationClient::ReadFile (lldb::user_id_t fd,
- uint64_t offset,
- void *dst,
- uint64_t dst_len,
- Error &error)
-{
- lldb_private::StreamString stream;
- stream.Printf("vFile:pread:%i,%" PRId64 ",%" PRId64, (int)fd, dst_len, offset);
- const char* packet = stream.GetData();
- int packet_len = stream.GetSize();
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.GetChar() != 'F')
- return 0;
- uint32_t retcode = response.GetHexMaxU32(false, UINT32_MAX);
- if (retcode == UINT32_MAX)
- return retcode;
- const char next = (response.Peek() ? *response.Peek() : 0);
- if (next == ',')
- return 0;
- if (next == ';')
- {
- response.GetChar(); // skip the semicolon
- std::string buffer;
- if (response.GetEscapedBinaryData(buffer))
- {
- const uint64_t data_to_write = std::min<uint64_t>(dst_len, buffer.size());
- if (data_to_write > 0)
- memcpy(dst, &buffer[0], data_to_write);
- return data_to_write;
- }
- }
- }
- return 0;
-}
+ m_supports_QSaveRegisterState = eLazyBoolYes;
+ StreamString payload;
+ payload.PutCString("QSaveRegisterState");
+ StringExtractorGDBRemote response;
+ if (SendThreadSpecificPacketAndWaitForResponse(
+ tid, std::move(payload), response, false) != PacketResult::Success)
+ return false;
-uint64_t
-GDBRemoteCommunicationClient::WriteFile (lldb::user_id_t fd,
- uint64_t offset,
- const void* src,
- uint64_t src_len,
- Error &error)
-{
- lldb_private::StreamGDBRemote stream;
- stream.Printf("vFile:pwrite:%i,%" PRId64 ",", (int)fd, offset);
- stream.PutEscapedBytes(src, src_len);
- const char* packet = stream.GetData();
- int packet_len = stream.GetSize();
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.GetChar() != 'F')
- {
- error.SetErrorStringWithFormat("write file failed");
- return 0;
- }
- uint64_t bytes_written = response.GetU64(UINT64_MAX);
- if (bytes_written == UINT64_MAX)
- {
- error.SetErrorToGenericError();
- if (response.GetChar() == ',')
- {
- int response_errno = response.GetS32(-1);
- if (response_errno > 0)
- error.SetError(response_errno, lldb::eErrorTypePOSIX);
- }
- return 0;
- }
- return bytes_written;
- }
- else
- {
- error.SetErrorString ("failed to send vFile:pwrite packet");
- }
- return 0;
-}
+ if (response.IsUnsupportedResponse())
+ m_supports_QSaveRegisterState = eLazyBoolNo;
-Error
-GDBRemoteCommunicationClient::CreateSymlink(const FileSpec &src, const FileSpec &dst)
-{
- std::string src_path{src.GetPath(false)},
- dst_path{dst.GetPath(false)};
- Error error;
- lldb_private::StreamGDBRemote stream;
- stream.PutCString("vFile:symlink:");
- // the unix symlink() command reverses its parameters where the dst if first,
- // so we follow suit here
- stream.PutCStringAsRawHex8(dst_path.c_str());
- stream.PutChar(',');
- stream.PutCStringAsRawHex8(src_path.c_str());
- const char* packet = stream.GetData();
- int packet_len = stream.GetSize();
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.GetChar() == 'F')
- {
- uint32_t result = response.GetU32(UINT32_MAX);
- if (result != 0)
- {
- error.SetErrorToGenericError();
- if (response.GetChar() == ',')
- {
- int response_errno = response.GetS32(-1);
- if (response_errno > 0)
- error.SetError(response_errno, lldb::eErrorTypePOSIX);
- }
- }
- }
- else
- {
- // Should have returned with 'F<result>[,<errno>]'
- error.SetErrorStringWithFormat("symlink failed");
- }
- }
- else
- {
- error.SetErrorString ("failed to send vFile:symlink packet");
- }
- return error;
-}
+ const uint32_t response_save_id = response.GetU32(0);
+ if (response_save_id == 0)
+ return false;
-Error
-GDBRemoteCommunicationClient::Unlink(const FileSpec &file_spec)
-{
- std::string path{file_spec.GetPath(false)};
- Error error;
- lldb_private::StreamGDBRemote stream;
- stream.PutCString("vFile:unlink:");
- // the unix symlink() command reverses its parameters where the dst if first,
- // so we follow suit here
- stream.PutCStringAsRawHex8(path.c_str());
- const char* packet = stream.GetData();
- int packet_len = stream.GetSize();
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.GetChar() == 'F')
- {
- uint32_t result = response.GetU32(UINT32_MAX);
- if (result != 0)
- {
- error.SetErrorToGenericError();
- if (response.GetChar() == ',')
- {
- int response_errno = response.GetS32(-1);
- if (response_errno > 0)
- error.SetError(response_errno, lldb::eErrorTypePOSIX);
- }
- }
- }
- else
- {
- // Should have returned with 'F<result>[,<errno>]'
- error.SetErrorStringWithFormat("unlink failed");
- }
- }
- else
- {
- error.SetErrorString ("failed to send vFile:unlink packet");
- }
- return error;
+ save_id = response_save_id;
+ return true;
}
-// Extension of host I/O packets to get whether a file exists.
-bool
-GDBRemoteCommunicationClient::GetFileExists (const lldb_private::FileSpec& file_spec)
-{
- std::string path(file_spec.GetPath(false));
- lldb_private::StreamString stream;
- stream.PutCString("vFile:exists:");
- stream.PutCStringAsRawHex8(path.c_str());
- const char* packet = stream.GetData();
- int packet_len = stream.GetSize();
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.GetChar() != 'F')
- return false;
- if (response.GetChar() != ',')
- return false;
- bool retcode = (response.GetChar() != '0');
- return retcode;
- }
+bool GDBRemoteCommunicationClient::RestoreRegisterState(lldb::tid_t tid,
+ uint32_t save_id) {
+ // We use the "m_supports_QSaveRegisterState" variable here because the
+ // QSaveRegisterState and QRestoreRegisterState packets must both be supported
+ // in
+ // order to be useful
+ if (m_supports_QSaveRegisterState == eLazyBoolNo)
return false;
-}
-bool
-GDBRemoteCommunicationClient::CalculateMD5 (const lldb_private::FileSpec& file_spec,
- uint64_t &high,
- uint64_t &low)
-{
- std::string path(file_spec.GetPath(false));
- lldb_private::StreamString stream;
- stream.PutCString("vFile:MD5:");
- stream.PutCStringAsRawHex8(path.c_str());
- const char* packet = stream.GetData();
- int packet_len = stream.GetSize();
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
- {
- if (response.GetChar() != 'F')
- return false;
- if (response.GetChar() != ',')
- return false;
- if (response.Peek() && *response.Peek() == 'x')
- return false;
- low = response.GetHexMaxU64(false, UINT64_MAX);
- high = response.GetHexMaxU64(false, UINT64_MAX);
- return true;
- }
+ StreamString payload;
+ payload.Printf("QRestoreRegisterState:%u", save_id);
+ StringExtractorGDBRemote response;
+ if (SendThreadSpecificPacketAndWaitForResponse(
+ tid, std::move(payload), response, false) != PacketResult::Success)
return false;
-}
-bool
-GDBRemoteCommunicationClient::AvoidGPackets (ProcessGDBRemote *process)
-{
- // Some targets have issues with g/G packets and we need to avoid using them
- if (m_avoid_g_packets == eLazyBoolCalculate)
- {
- if (process)
- {
- m_avoid_g_packets = eLazyBoolNo;
- const ArchSpec &arch = process->GetTarget().GetArchitecture();
- if (arch.IsValid()
- && arch.GetTriple().getVendor() == llvm::Triple::Apple
- && arch.GetTriple().getOS() == llvm::Triple::IOS
- && arch.GetTriple().getArch() == llvm::Triple::aarch64)
- {
- m_avoid_g_packets = eLazyBoolYes;
- uint32_t gdb_server_version = GetGDBServerProgramVersion();
- if (gdb_server_version != 0)
- {
- const char *gdb_server_name = GetGDBServerProgramName();
- if (gdb_server_name && strcmp(gdb_server_name, "debugserver") == 0)
- {
- if (gdb_server_version >= 310)
- m_avoid_g_packets = eLazyBoolNo;
- }
- }
- }
- }
- }
- return m_avoid_g_packets == eLazyBoolYes;
+ if (response.IsOKResponse())
+ return true;
+
+ if (response.IsUnsupportedResponse())
+ m_supports_QSaveRegisterState = eLazyBoolNo;
+ return false;
}
-bool
-GDBRemoteCommunicationClient::ReadRegister(lldb::tid_t tid, uint32_t reg, StringExtractorGDBRemote &response)
-{
- Mutex::Locker locker;
- if (GetSequenceMutex (locker, "Didn't get sequence mutex for p packet."))
- {
- const bool thread_suffix_supported = GetThreadSuffixSupported();
-
- if (thread_suffix_supported || SetCurrentThread(tid))
- {
- char packet[64];
- int packet_len = 0;
- if (thread_suffix_supported)
- packet_len = ::snprintf (packet, sizeof(packet), "p%x;thread:%4.4" PRIx64 ";", reg, tid);
- else
- packet_len = ::snprintf (packet, sizeof(packet), "p%x", reg);
- assert (packet_len < ((int)sizeof(packet) - 1));
- return SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success;
- }
- }
+bool GDBRemoteCommunicationClient::SyncThreadState(lldb::tid_t tid) {
+ if (!GetSyncThreadStateSupported())
return false;
+ StreamString packet;
+ StringExtractorGDBRemote response;
+ packet.Printf("QSyncThreadState:%4.4" PRIx64 ";", tid);
+ return SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+ GDBRemoteCommunication::PacketResult::Success &&
+ response.IsOKResponse();
}
+bool GDBRemoteCommunicationClient::GetModuleInfo(
+ const FileSpec &module_file_spec, const lldb_private::ArchSpec &arch_spec,
+ ModuleSpec &module_spec) {
+ if (!m_supports_qModuleInfo)
+ return false;
-bool
-GDBRemoteCommunicationClient::ReadAllRegisters (lldb::tid_t tid, StringExtractorGDBRemote &response)
-{
- Mutex::Locker locker;
- if (GetSequenceMutex (locker, "Didn't get sequence mutex for g packet."))
- {
- const bool thread_suffix_supported = GetThreadSuffixSupported();
-
- if (thread_suffix_supported || SetCurrentThread(tid))
- {
- char packet[64];
- int packet_len = 0;
- // Get all registers in one packet
- if (thread_suffix_supported)
- packet_len = ::snprintf (packet, sizeof(packet), "g;thread:%4.4" PRIx64 ";", tid);
- else
- packet_len = ::snprintf (packet, sizeof(packet), "g");
- assert (packet_len < ((int)sizeof(packet) - 1));
- return SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success;
- }
- }
+ std::string module_path = module_file_spec.GetPath(false);
+ if (module_path.empty())
return false;
-}
-bool
-GDBRemoteCommunicationClient::SaveRegisterState (lldb::tid_t tid, uint32_t &save_id)
-{
- save_id = 0; // Set to invalid save ID
- if (m_supports_QSaveRegisterState == eLazyBoolNo)
- return false;
-
- m_supports_QSaveRegisterState = eLazyBoolYes;
- Mutex::Locker locker;
- if (GetSequenceMutex (locker, "Didn't get sequence mutex for QSaveRegisterState."))
- {
- const bool thread_suffix_supported = GetThreadSuffixSupported();
- if (thread_suffix_supported || SetCurrentThread(tid))
- {
- char packet[256];
- if (thread_suffix_supported)
- ::snprintf (packet, sizeof(packet), "QSaveRegisterState;thread:%4.4" PRIx64 ";", tid);
- else
- ::snprintf(packet, sizeof(packet), "QSaveRegisterState");
-
- StringExtractorGDBRemote response;
-
- if (SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success)
- {
- if (response.IsUnsupportedResponse())
- {
- // This packet isn't supported, don't try calling it again
- m_supports_QSaveRegisterState = eLazyBoolNo;
- }
-
- const uint32_t response_save_id = response.GetU32(0);
- if (response_save_id != 0)
- {
- save_id = response_save_id;
- return true;
- }
- }
- }
- }
+
+ StreamString packet;
+ packet.PutCString("qModuleInfo:");
+ packet.PutCStringAsRawHex8(module_path.c_str());
+ packet.PutCString(";");
+ const auto &triple = arch_spec.GetTriple().getTriple();
+ packet.PutCStringAsRawHex8(triple.c_str());
+
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet.GetString(), response, false) !=
+ PacketResult::Success)
return false;
-}
-bool
-GDBRemoteCommunicationClient::RestoreRegisterState (lldb::tid_t tid, uint32_t save_id)
-{
- // We use the "m_supports_QSaveRegisterState" variable here because the
- // QSaveRegisterState and QRestoreRegisterState packets must both be supported in
- // order to be useful
- if (m_supports_QSaveRegisterState == eLazyBoolNo)
- return false;
-
- Mutex::Locker locker;
- if (GetSequenceMutex (locker, "Didn't get sequence mutex for QRestoreRegisterState."))
- {
- const bool thread_suffix_supported = GetThreadSuffixSupported();
- if (thread_suffix_supported || SetCurrentThread(tid))
- {
- char packet[256];
- if (thread_suffix_supported)
- ::snprintf (packet, sizeof(packet), "QRestoreRegisterState:%u;thread:%4.4" PRIx64 ";", save_id, tid);
- else
- ::snprintf (packet, sizeof(packet), "QRestoreRegisterState:%u" PRIx64 ";", save_id);
-
- StringExtractorGDBRemote response;
-
- if (SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- {
- return true;
- }
- else if (response.IsUnsupportedResponse())
- {
- // This packet isn't supported, don't try calling this packet or
- // QSaveRegisterState again...
- m_supports_QSaveRegisterState = eLazyBoolNo;
- }
- }
- }
- }
+ if (response.IsErrorResponse())
return false;
-}
-bool
-GDBRemoteCommunicationClient::GetModuleInfo (const FileSpec& module_file_spec,
- const lldb_private::ArchSpec& arch_spec,
- ModuleSpec &module_spec)
-{
- if (!m_supports_qModuleInfo)
- return false;
+ if (response.IsUnsupportedResponse()) {
+ m_supports_qModuleInfo = false;
+ return false;
+ }
+
+ llvm::StringRef name;
+ llvm::StringRef value;
+
+ module_spec.Clear();
+ module_spec.GetFileSpec() = module_file_spec;
+
+ while (response.GetNameColonValue(name, value)) {
+ if (name == "uuid" || name == "md5") {
+ StringExtractor extractor(value);
+ std::string uuid;
+ extractor.GetHexByteString(uuid);
+ module_spec.GetUUID().SetFromCString(uuid.c_str(), uuid.size() / 2);
+ } else if (name == "triple") {
+ StringExtractor extractor(value);
+ std::string triple;
+ extractor.GetHexByteString(triple);
+ module_spec.GetArchitecture().SetTriple(triple.c_str());
+ } else if (name == "file_offset") {
+ uint64_t ival = 0;
+ if (!value.getAsInteger(16, ival))
+ module_spec.SetObjectOffset(ival);
+ } else if (name == "file_size") {
+ uint64_t ival = 0;
+ if (!value.getAsInteger(16, ival))
+ module_spec.SetObjectSize(ival);
+ } else if (name == "file_path") {
+ StringExtractor extractor(value);
+ std::string path;
+ extractor.GetHexByteString(path);
+ module_spec.GetFileSpec() = FileSpec(path, false, arch_spec);
+ }
+ }
+
+ return true;
+}
+
+static llvm::Optional<ModuleSpec>
+ParseModuleSpec(StructuredData::Dictionary *dict) {
+ ModuleSpec result;
+ if (!dict)
+ return llvm::None;
+
+ std::string string;
+ uint64_t integer;
+
+ if (!dict->GetValueForKeyAsString("uuid", string))
+ return llvm::None;
+ result.GetUUID().SetFromCString(string.c_str(), string.size());
+
+ if (!dict->GetValueForKeyAsInteger("file_offset", integer))
+ return llvm::None;
+ result.SetObjectOffset(integer);
+
+ if (!dict->GetValueForKeyAsInteger("file_size", integer))
+ return llvm::None;
+ result.SetObjectSize(integer);
+
+ if (!dict->GetValueForKeyAsString("triple", string))
+ return llvm::None;
+ result.GetArchitecture().SetTriple(string.c_str());
+
+ if (!dict->GetValueForKeyAsString("file_path", string))
+ return llvm::None;
+ result.GetFileSpec() = FileSpec(string, false, result.GetArchitecture());
+
+ return result;
+}
+
+llvm::Optional<std::vector<ModuleSpec>>
+GDBRemoteCommunicationClient::GetModulesInfo(
+ llvm::ArrayRef<FileSpec> module_file_specs, const llvm::Triple &triple) {
+ if (!m_supports_jModulesInfo)
+ return llvm::None;
+
+ JSONArray::SP module_array_sp = std::make_shared<JSONArray>();
+ for (const FileSpec &module_file_spec : module_file_specs) {
+ JSONObject::SP module_sp = std::make_shared<JSONObject>();
+ module_array_sp->AppendObject(module_sp);
+ module_sp->SetObject(
+ "file", std::make_shared<JSONString>(module_file_spec.GetPath()));
+ module_sp->SetObject("triple",
+ std::make_shared<JSONString>(triple.getTriple()));
+ }
+ StreamString unescaped_payload;
+ unescaped_payload.PutCString("jModulesInfo:");
+ module_array_sp->Write(unescaped_payload);
+ StreamGDBRemote payload;
+ payload.PutEscapedBytes(unescaped_payload.GetString().data(),
+ unescaped_payload.GetSize());
+
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(payload.GetString(), response, false) !=
+ PacketResult::Success ||
+ response.IsErrorResponse())
+ return llvm::None;
+
+ if (response.IsUnsupportedResponse()) {
+ m_supports_jModulesInfo = false;
+ return llvm::None;
+ }
+
+ StructuredData::ObjectSP response_object_sp =
+ StructuredData::ParseJSON(response.GetStringRef());
+ if (!response_object_sp)
+ return llvm::None;
+
+ StructuredData::Array *response_array = response_object_sp->GetAsArray();
+ if (!response_array)
+ return llvm::None;
+
+ std::vector<ModuleSpec> result;
+ for (size_t i = 0; i < response_array->GetSize(); ++i) {
+ if (llvm::Optional<ModuleSpec> module_spec = ParseModuleSpec(
+ response_array->GetItemAtIndex(i)->GetAsDictionary()))
+ result.push_back(*module_spec);
+ }
+
+ return result;
+}
- std::string module_path = module_file_spec.GetPath (false);
- if (module_path.empty ())
- return false;
+// query the target remote for extended information using the qXfer packet
+//
+// example: object='features', annex='target.xml', out=<xml output>
+// return: 'true' on success
+// 'false' on failure (err set)
+bool GDBRemoteCommunicationClient::ReadExtFeature(
+ const lldb_private::ConstString object,
+ const lldb_private::ConstString annex, std::string &out,
+ lldb_private::Error &err) {
- StreamString packet;
- packet.PutCString("qModuleInfo:");
- packet.PutCStringAsRawHex8(module_path.c_str());
- packet.PutCString(";");
- const auto& triple = arch_spec.GetTriple().getTriple();
- packet.PutCStringAsRawHex8(triple.c_str());
+ std::stringstream output;
+ StringExtractorGDBRemote chunk;
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) != PacketResult::Success)
- return false;
+ uint64_t size = GetRemoteMaxPacketSize();
+ if (size == 0)
+ size = 0x1000;
+ size = size - 1; // Leave space for the 'm' or 'l' character in the response
+ int offset = 0;
+ bool active = true;
- if (response.IsErrorResponse ())
- return false;
+ // loop until all data has been read
+ while (active) {
- if (response.IsUnsupportedResponse ())
- {
- m_supports_qModuleInfo = false;
- return false;
- }
+ // send query extended feature packet
+ std::stringstream packet;
+ packet << "qXfer:" << object.AsCString("")
+ << ":read:" << annex.AsCString("") << ":" << std::hex << offset
+ << "," << std::hex << size;
- std::string name;
- std::string value;
- bool success;
- StringExtractor extractor;
+ GDBRemoteCommunication::PacketResult res =
+ SendPacketAndWaitForResponse(packet.str(), chunk, false);
- module_spec.Clear ();
- module_spec.GetFileSpec () = module_file_spec;
-
- while (response.GetNameColonValue (name, value))
- {
- if (name == "uuid" || name == "md5")
- {
- extractor.GetStringRef ().swap (value);
- extractor.SetFilePos (0);
- extractor.GetHexByteString (value);
- module_spec.GetUUID().SetFromCString (value.c_str(), value.size() / 2);
- }
- else if (name == "triple")
- {
- extractor.GetStringRef ().swap (value);
- extractor.SetFilePos (0);
- extractor.GetHexByteString (value);
- module_spec.GetArchitecture().SetTriple (value.c_str ());
- }
- else if (name == "file_offset")
- {
- const auto ival = StringConvert::ToUInt64 (value.c_str (), 0, 16, &success);
- if (success)
- module_spec.SetObjectOffset (ival);
- }
- else if (name == "file_size")
- {
- const auto ival = StringConvert::ToUInt64 (value.c_str (), 0, 16, &success);
- if (success)
- module_spec.SetObjectSize (ival);
- }
- else if (name == "file_path")
- {
- extractor.GetStringRef ().swap (value);
- extractor.SetFilePos (0);
- extractor.GetHexByteString (value);
- module_spec.GetFileSpec() = FileSpec(value.c_str(), false, arch_spec);
- }
+ if (res != GDBRemoteCommunication::PacketResult::Success) {
+ err.SetErrorString("Error sending $qXfer packet");
+ return false;
}
- return true;
-}
+ const std::string &str = chunk.GetStringRef();
+ if (str.length() == 0) {
+ // should have some data in chunk
+ err.SetErrorString("Empty response from $qXfer packet");
+ return false;
+ }
-// query the target remote for extended information using the qXfer packet
-//
-// example: object='features', annex='target.xml', out=<xml output>
-// return: 'true' on success
-// 'false' on failure (err set)
-bool
-GDBRemoteCommunicationClient::ReadExtFeature (const lldb_private::ConstString object,
- const lldb_private::ConstString annex,
- std::string & out,
- lldb_private::Error & err) {
-
- std::stringstream output;
- StringExtractorGDBRemote chunk;
-
- uint64_t size = GetRemoteMaxPacketSize();
- if (size == 0)
- size = 0x1000;
- size = size - 1; // Leave space for the 'm' or 'l' character in the response
- int offset = 0;
- bool active = true;
-
- // loop until all data has been read
- while ( active ) {
-
- // send query extended feature packet
- std::stringstream packet;
- packet << "qXfer:"
- << object.AsCString("") << ":read:"
- << annex.AsCString("") << ":"
- << std::hex << offset << ","
- << std::hex << size;
-
- GDBRemoteCommunication::PacketResult res =
- SendPacketAndWaitForResponse( packet.str().c_str(),
- chunk,
- false );
-
- if ( res != GDBRemoteCommunication::PacketResult::Success ) {
- err.SetErrorString( "Error sending $qXfer packet" );
- return false;
- }
+ // check packet code
+ switch (str[0]) {
+ // last chunk
+ case ('l'):
+ active = false;
+ LLVM_FALLTHROUGH;
- const std::string & str = chunk.GetStringRef( );
- if ( str.length() == 0 ) {
- // should have some data in chunk
- err.SetErrorString( "Empty response from $qXfer packet" );
- return false;
- }
+ // more chunks
+ case ('m'):
+ if (str.length() > 1)
+ output << &str[1];
+ offset += size;
+ break;
- // check packet code
- switch ( str[0] ) {
- // last chunk
- case ( 'l' ):
- active = false;
- LLVM_FALLTHROUGH;
-
- // more chunks
- case ( 'm' ) :
- if ( str.length() > 1 )
- output << &str[1];
- offset += size;
- break;
-
- // unknown chunk
- default:
- err.SetErrorString( "Invalid continuation code from $qXfer packet" );
- return false;
- }
+ // unknown chunk
+ default:
+ err.SetErrorString("Invalid continuation code from $qXfer packet");
+ return false;
}
+ }
- out = output.str( );
- err.Success( );
- return true;
+ out = output.str();
+ err.Success();
+ return true;
}
// Notify the target that gdb is prepared to serve symbol lookup requests.
// packet: "qSymbol::"
// reply:
// OK The target does not need to look up any (more) symbols.
-// qSymbol:<sym_name> The target requests the value of symbol sym_name (hex encoded).
-// LLDB may provide the value by sending another qSymbol packet
+// qSymbol:<sym_name> The target requests the value of symbol sym_name (hex
+// encoded).
+// LLDB may provide the value by sending another qSymbol
+// packet
// in the form of"qSymbol:<sym_value>:<sym_name>".
//
// Three examples:
//
// lldb sends: qSymbol::
// lldb receives: OK
-// Remote gdb stub does not need to know the addresses of any symbols, lldb does not
+// Remote gdb stub does not need to know the addresses of any symbols, lldb
+// does not
// need to ask again in this session.
//
// lldb sends: qSymbol::
// lldb receives: qSymbol:64697370617463685f71756575655f6f666673657473
// lldb sends: qSymbol::64697370617463685f71756575655f6f666673657473
// lldb receives: OK
-// Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb does not know
-// the address at this time. lldb needs to send qSymbol:: again when it has more
+// Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb does
+// not know
+// the address at this time. lldb needs to send qSymbol:: again when it has
+// more
// solibs loaded.
//
// lldb sends: qSymbol::
// lldb receives: qSymbol:64697370617463685f71756575655f6f666673657473
// lldb sends: qSymbol:2bc97554:64697370617463685f71756575655f6f666673657473
// lldb receives: OK
-// Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb says that it
-// is at address 0x2bc97554. Remote gdb stub sends 'OK' indicating that it does not
+// Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb says
+// that it
+// is at address 0x2bc97554. Remote gdb stub sends 'OK' indicating that it
+// does not
// need any more symbols. lldb does not need to ask again in this session.
-void
-GDBRemoteCommunicationClient::ServeSymbolLookups(lldb_private::Process *process)
-{
- // Set to true once we've resolved a symbol to an address for the remote stub.
- // If we get an 'OK' response after this, the remote stub doesn't need any more
- // symbols and we can stop asking.
- bool symbol_response_provided = false;
-
- // Is this the inital qSymbol:: packet?
- bool first_qsymbol_query = true;
-
- if (m_supports_qSymbol && m_qSymbol_requests_done == false)
- {
- Mutex::Locker locker;
- if (GetSequenceMutex(locker, "GDBRemoteCommunicationClient::ServeSymbolLookups() failed due to not getting the sequence mutex"))
- {
- StreamString packet;
- packet.PutCString ("qSymbol::");
- StringExtractorGDBRemote response;
- while (SendPacketAndWaitForResponseNoLock(packet.GetData(), packet.GetSize(), response) == PacketResult::Success)
- {
- if (response.IsOKResponse())
- {
- if (symbol_response_provided || first_qsymbol_query)
- {
- m_qSymbol_requests_done = true;
- }
-
- // We are done serving symbols requests
- return;
- }
- first_qsymbol_query = false;
+void GDBRemoteCommunicationClient::ServeSymbolLookups(
+ lldb_private::Process *process) {
+ // Set to true once we've resolved a symbol to an address for the remote stub.
+ // If we get an 'OK' response after this, the remote stub doesn't need any
+ // more
+ // symbols and we can stop asking.
+ bool symbol_response_provided = false;
+
+ // Is this the initial qSymbol:: packet?
+ bool first_qsymbol_query = true;
+
+ if (m_supports_qSymbol && m_qSymbol_requests_done == false) {
+ Lock lock(*this, false);
+ if (lock) {
+ StreamString packet;
+ packet.PutCString("qSymbol::");
+ StringExtractorGDBRemote response;
+ while (SendPacketAndWaitForResponseNoLock(packet.GetString(), response) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse()) {
+ if (symbol_response_provided || first_qsymbol_query) {
+ m_qSymbol_requests_done = true;
+ }
+
+ // We are done serving symbols requests
+ return;
+ }
+ first_qsymbol_query = false;
+
+ if (response.IsUnsupportedResponse()) {
+ // qSymbol is not supported by the current GDB server we are connected
+ // to
+ m_supports_qSymbol = false;
+ return;
+ } else {
+ llvm::StringRef response_str(response.GetStringRef());
+ if (response_str.startswith("qSymbol:")) {
+ response.SetFilePos(strlen("qSymbol:"));
+ std::string symbol_name;
+ if (response.GetHexByteString(symbol_name)) {
+ if (symbol_name.empty())
+ return;
+
+ addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
+ lldb_private::SymbolContextList sc_list;
+ if (process->GetTarget().GetImages().FindSymbolsWithNameAndType(
+ ConstString(symbol_name), eSymbolTypeAny, sc_list)) {
+ const size_t num_scs = sc_list.GetSize();
+ for (size_t sc_idx = 0;
+ sc_idx < num_scs &&
+ symbol_load_addr == LLDB_INVALID_ADDRESS;
+ ++sc_idx) {
+ SymbolContext sc;
+ if (sc_list.GetContextAtIndex(sc_idx, sc)) {
+ if (sc.symbol) {
+ switch (sc.symbol->GetType()) {
+ case eSymbolTypeInvalid:
+ case eSymbolTypeAbsolute:
+ case eSymbolTypeUndefined:
+ case eSymbolTypeSourceFile:
+ case eSymbolTypeHeaderFile:
+ case eSymbolTypeObjectFile:
+ case eSymbolTypeCommonBlock:
+ case eSymbolTypeBlock:
+ case eSymbolTypeLocal:
+ case eSymbolTypeParam:
+ case eSymbolTypeVariable:
+ case eSymbolTypeVariableType:
+ case eSymbolTypeLineEntry:
+ case eSymbolTypeLineHeader:
+ case eSymbolTypeScopeBegin:
+ case eSymbolTypeScopeEnd:
+ case eSymbolTypeAdditional:
+ case eSymbolTypeCompiler:
+ case eSymbolTypeInstrumentation:
+ case eSymbolTypeTrampoline:
+ break;
- if (response.IsUnsupportedResponse())
- {
- // qSymbol is not supported by the current GDB server we are connected to
- m_supports_qSymbol = false;
- return;
- }
- else
- {
- llvm::StringRef response_str(response.GetStringRef());
- if (response_str.startswith("qSymbol:"))
- {
- response.SetFilePos(strlen("qSymbol:"));
- std::string symbol_name;
- if (response.GetHexByteString(symbol_name))
- {
- if (symbol_name.empty())
- return;
-
- addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
- lldb_private::SymbolContextList sc_list;
- if (process->GetTarget().GetImages().FindSymbolsWithNameAndType(ConstString(symbol_name), eSymbolTypeAny, sc_list))
- {
- const size_t num_scs = sc_list.GetSize();
- for (size_t sc_idx=0; sc_idx<num_scs && symbol_load_addr == LLDB_INVALID_ADDRESS; ++sc_idx)
- {
- SymbolContext sc;
- if (sc_list.GetContextAtIndex(sc_idx, sc))
- {
- if (sc.symbol)
- {
- switch (sc.symbol->GetType())
- {
- case eSymbolTypeInvalid:
- case eSymbolTypeAbsolute:
- case eSymbolTypeUndefined:
- case eSymbolTypeSourceFile:
- case eSymbolTypeHeaderFile:
- case eSymbolTypeObjectFile:
- case eSymbolTypeCommonBlock:
- case eSymbolTypeBlock:
- case eSymbolTypeLocal:
- case eSymbolTypeParam:
- case eSymbolTypeVariable:
- case eSymbolTypeVariableType:
- case eSymbolTypeLineEntry:
- case eSymbolTypeLineHeader:
- case eSymbolTypeScopeBegin:
- case eSymbolTypeScopeEnd:
- case eSymbolTypeAdditional:
- case eSymbolTypeCompiler:
- case eSymbolTypeInstrumentation:
- case eSymbolTypeTrampoline:
- break;
-
- case eSymbolTypeCode:
- case eSymbolTypeResolver:
- case eSymbolTypeData:
- case eSymbolTypeRuntime:
- case eSymbolTypeException:
- case eSymbolTypeObjCClass:
- case eSymbolTypeObjCMetaClass:
- case eSymbolTypeObjCIVar:
- case eSymbolTypeReExported:
- symbol_load_addr = sc.symbol->GetLoadAddress(&process->GetTarget());
- break;
- }
- }
- }
- }
- }
- // This is the normal path where our symbol lookup was successful and we want
- // to send a packet with the new symbol value and see if another lookup needs to be
- // done.
-
- // Change "packet" to contain the requested symbol value and name
- packet.Clear();
- packet.PutCString("qSymbol:");
- if (symbol_load_addr != LLDB_INVALID_ADDRESS)
- {
- packet.Printf("%" PRIx64, symbol_load_addr);
- symbol_response_provided = true;
- }
- else
- {
- symbol_response_provided = false;
- }
- packet.PutCString(":");
- packet.PutBytesAsRawHex8(symbol_name.data(), symbol_name.size());
- continue; // go back to the while loop and send "packet" and wait for another response
- }
+ case eSymbolTypeCode:
+ case eSymbolTypeResolver:
+ case eSymbolTypeData:
+ case eSymbolTypeRuntime:
+ case eSymbolTypeException:
+ case eSymbolTypeObjCClass:
+ case eSymbolTypeObjCMetaClass:
+ case eSymbolTypeObjCIVar:
+ case eSymbolTypeReExported:
+ symbol_load_addr =
+ sc.symbol->GetLoadAddress(&process->GetTarget());
+ break;
+ }
}
+ }
}
- }
- // If we make it here, the symbol request packet response wasn't valid or
- // our symbol lookup failed so we must abort
- return;
+ }
+ // This is the normal path where our symbol lookup was successful
+ // and we want
+ // to send a packet with the new symbol value and see if another
+ // lookup needs to be
+ // done.
+
+ // Change "packet" to contain the requested symbol value and name
+ packet.Clear();
+ packet.PutCString("qSymbol:");
+ if (symbol_load_addr != LLDB_INVALID_ADDRESS) {
+ packet.Printf("%" PRIx64, symbol_load_addr);
+ symbol_response_provided = true;
+ } else {
+ symbol_response_provided = false;
+ }
+ packet.PutCString(":");
+ packet.PutBytesAsRawHex8(symbol_name.data(), symbol_name.size());
+ continue; // go back to the while loop and send "packet" and wait
+ // for another response
+ }
+ }
+ }
+ }
+ // If we make it here, the symbol request packet response wasn't valid or
+ // our symbol lookup failed so we must abort
+ return;
+
+ } else if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(
+ GDBR_LOG_PROCESS | GDBR_LOG_PACKETS)) {
+ log->Printf(
+ "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.",
+ __FUNCTION__);
+ }
+ }
+}
+
+StructuredData::Array *
+GDBRemoteCommunicationClient::GetSupportedStructuredDataPlugins() {
+ if (!m_supported_async_json_packets_is_valid) {
+ // Query the server for the array of supported asynchronous JSON
+ // packets.
+ m_supported_async_json_packets_is_valid = true;
- }
- }
-}
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ // Poll it now.
+ StringExtractorGDBRemote response;
+ const bool send_async = false;
+ if (SendPacketAndWaitForResponse("qStructuredDataPlugins", response,
+ send_async) == PacketResult::Success) {
+ m_supported_async_json_packets_sp =
+ StructuredData::ParseJSON(response.GetStringRef());
+ if (m_supported_async_json_packets_sp &&
+ !m_supported_async_json_packets_sp->GetAsArray()) {
+ // We were returned something other than a JSON array. This
+ // is invalid. Clear it out.
+ if (log)
+ log->Printf("GDBRemoteCommunicationClient::%s(): "
+ "QSupportedAsyncJSONPackets returned invalid "
+ "result: %s",
+ __FUNCTION__, response.GetStringRef().c_str());
+ m_supported_async_json_packets_sp.reset();
+ }
+ } else {
+ if (log)
+ log->Printf("GDBRemoteCommunicationClient::%s(): "
+ "QSupportedAsyncJSONPackets unsupported",
+ __FUNCTION__);
+ }
+
+ if (log && m_supported_async_json_packets_sp) {
+ StreamString stream;
+ m_supported_async_json_packets_sp->Dump(stream);
+ log->Printf("GDBRemoteCommunicationClient::%s(): supported async "
+ "JSON packets: %s",
+ __FUNCTION__, stream.GetData());
+ }
+ }
+
+ return m_supported_async_json_packets_sp
+ ? m_supported_async_json_packets_sp->GetAsArray()
+ : nullptr;
+}
+
+Error GDBRemoteCommunicationClient::ConfigureRemoteStructuredData(
+ const ConstString &type_name, const StructuredData::ObjectSP &config_sp) {
+ Error error;
+
+ if (type_name.GetLength() == 0) {
+ error.SetErrorString("invalid type_name argument");
+ return error;
+ }
+
+ // Build command: Configure{type_name}: serialized config
+ // data.
+ StreamGDBRemote stream;
+ stream.PutCString("QConfigure");
+ stream.PutCString(type_name.AsCString());
+ stream.PutChar(':');
+ if (config_sp) {
+ // Gather the plain-text version of the configuration data.
+ StreamString unescaped_stream;
+ config_sp->Dump(unescaped_stream);
+ unescaped_stream.Flush();
+
+ // Add it to the stream in escaped fashion.
+ stream.PutEscapedBytes(unescaped_stream.GetString().data(),
+ unescaped_stream.GetSize());
+ }
+ stream.Flush();
+
+ // Send the packet.
+ const bool send_async = false;
+ StringExtractorGDBRemote response;
+ auto result =
+ SendPacketAndWaitForResponse(stream.GetString(), response, send_async);
+ if (result == PacketResult::Success) {
+ // We failed if the config result comes back other than OK.
+ if (strcmp(response.GetStringRef().c_str(), "OK") == 0) {
+ // Okay!
+ error.Clear();
+ } else {
+ error.SetErrorStringWithFormat("configuring StructuredData feature "
+ "%s failed with error %s",
+ type_name.AsCString(),
+ response.GetStringRef().c_str());
+ }
+ } else {
+ // Can we get more data here on the failure?
+ error.SetErrorStringWithFormat("configuring StructuredData feature %s "
+ "failed when sending packet: "
+ "PacketResult=%d",
+ type_name.AsCString(), (int)result);
+ }
+ return error;
+}
+
+void GDBRemoteCommunicationClient::OnRunPacketSent(bool first) {
+ GDBRemoteClientBase::OnRunPacketSent(first);
+ m_curr_tid = LLDB_INVALID_THREAD_ID;
+}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index 096c4cf81015..83162a662e06 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -10,8 +10,11 @@
#ifndef liblldb_GDBRemoteCommunicationClient_h_
#define liblldb_GDBRemoteCommunicationClient_h_
+#include "GDBRemoteClientBase.h"
+
// C Includes
// C++ Includes
+#include <chrono>
#include <map>
#include <mutex>
#include <string>
@@ -23,660 +26,563 @@
#include "lldb/Core/StructuredData.h"
#include "lldb/Target/Process.h"
-#include "GDBRemoteCommunication.h"
+#include "llvm/ADT/Optional.h"
namespace lldb_private {
namespace process_gdb_remote {
-class GDBRemoteCommunicationClient : public GDBRemoteCommunication
-{
+class GDBRemoteCommunicationClient : public GDBRemoteClientBase {
public:
- GDBRemoteCommunicationClient();
-
- ~GDBRemoteCommunicationClient() override;
-
- //------------------------------------------------------------------
- // After connecting, send the handshake to the server to make sure
- // we are communicating with it.
- //------------------------------------------------------------------
- bool
- HandshakeWithServer (Error *error_ptr);
-
- PacketResult
- SendPacketAndWaitForResponse (const char *send_payload,
- StringExtractorGDBRemote &response,
- bool send_async);
-
- PacketResult
- SendPacketAndWaitForResponse (const char *send_payload,
- size_t send_length,
- StringExtractorGDBRemote &response,
- bool send_async);
-
- // For packets which specify a range of output to be returned,
- // return all of the output via a series of request packets of the form
- // <prefix>0,<size>
- // <prefix><size>,<size>
- // <prefix><size>*2,<size>
- // <prefix><size>*3,<size>
- // ...
- // until a "$l..." packet is received, indicating the end.
- // (size is in hex; this format is used by a standard gdbserver to
- // return the given portion of the output specified by <prefix>;
- // for example, "qXfer:libraries-svr4:read::fff,1000" means
- // "return a chunk of the xml description file for shared
- // library load addresses, where the chunk starts at offset 0xfff
- // and continues for 0x1000 bytes").
- // Concatenate the resulting server response packets together and
- // return in response_string. If any packet fails, the return value
- // indicates that failure and the returned string value is undefined.
- PacketResult
- SendPacketsAndConcatenateResponses (const char *send_payload_prefix,
- std::string &response_string);
-
- lldb::StateType
- SendContinuePacketAndWaitForResponse (ProcessGDBRemote *process,
- const char *packet_payload,
- size_t packet_length,
- StringExtractorGDBRemote &response);
-
- bool
- SendvContPacket (ProcessGDBRemote *process,
- const char *payload,
- size_t packet_length,
- StringExtractorGDBRemote &response);
-
- bool
- GetThreadSuffixSupported () override;
-
- // This packet is usually sent first and the boolean return value
- // indicates if the packet was send and any response was received
- // even in the response is UNIMPLEMENTED. If the packet failed to
- // get a response, then false is returned. This quickly tells us
- // if we were able to connect and communicate with the remote GDB
- // server
- bool
- QueryNoAckModeSupported ();
-
- void
- GetListThreadsInStopReplySupported ();
-
- bool
- SendAsyncSignal (int signo);
-
- bool
- SendInterrupt (Mutex::Locker &locker,
- uint32_t seconds_to_wait_for_stop,
- bool &timed_out);
-
- lldb::pid_t
- GetCurrentProcessID (bool allow_lazy = true);
-
- bool
- GetLaunchSuccess (std::string &error_str);
-
- bool
- LaunchGDBServer (const char *remote_accept_hostname,
- lldb::pid_t &pid,
- uint16_t &port,
- std::string &socket_name);
-
- size_t
- QueryGDBServer (std::vector<std::pair<uint16_t, std::string>>& connection_urls);
-
- bool
- KillSpawnedProcess (lldb::pid_t pid);
-
- //------------------------------------------------------------------
- /// Sends a GDB remote protocol 'A' packet that delivers program
- /// arguments to the remote server.
- ///
- /// @param[in] argv
- /// A NULL terminated array of const C strings to use as the
- /// arguments.
- ///
- /// @return
- /// Zero if the response was "OK", a positive value if the
- /// the response was "Exx" where xx are two hex digits, or
- /// -1 if the call is unsupported or any other unexpected
- /// response was received.
- //------------------------------------------------------------------
- int
- SendArgumentsPacket (const ProcessLaunchInfo &launch_info);
-
- //------------------------------------------------------------------
- /// Sends a "QEnvironment:NAME=VALUE" packet that will build up the
- /// environment that will get used when launching an application
- /// in conjunction with the 'A' packet. This function can be called
- /// multiple times in a row in order to pass on the desired
- /// environment that the inferior should be launched with.
- ///
- /// @param[in] name_equal_value
- /// A NULL terminated C string that contains a single environment
- /// in the format "NAME=VALUE".
- ///
- /// @return
- /// Zero if the response was "OK", a positive value if the
- /// the response was "Exx" where xx are two hex digits, or
- /// -1 if the call is unsupported or any other unexpected
- /// response was received.
- //------------------------------------------------------------------
- int
- SendEnvironmentPacket (char const *name_equal_value);
-
- int
- SendLaunchArchPacket (const char *arch);
-
- int
- SendLaunchEventDataPacket(const char *data, bool *was_supported = nullptr);
-
- //------------------------------------------------------------------
- /// Sends a "vAttach:PID" where PID is in hex.
- ///
- /// @param[in] pid
- /// A process ID for the remote gdb server to attach to.
- ///
- /// @param[out] response
- /// The response received from the gdb server. If the return
- /// value is zero, \a response will contain a stop reply
- /// packet.
- ///
- /// @return
- /// Zero if the attach was successful, or an error indicating
- /// an error code.
- //------------------------------------------------------------------
- int
- SendAttach (lldb::pid_t pid,
- StringExtractorGDBRemote& response);
-
- //------------------------------------------------------------------
- /// Sends a GDB remote protocol 'I' packet that delivers stdin
- /// data to the remote process.
- ///
- /// @param[in] data
- /// A pointer to stdin data.
- ///
- /// @param[in] data_len
- /// The number of bytes available at \a data.
- ///
- /// @return
- /// Zero if the attach was successful, or an error indicating
- /// an error code.
- //------------------------------------------------------------------
- int
- SendStdinNotification(const char* data, size_t data_len);
-
- //------------------------------------------------------------------
- /// Sets the path to use for stdin/out/err for a process
- /// that will be launched with the 'A' packet.
- ///
- /// @param[in] path
- /// The path to use for stdin/out/err
- ///
- /// @return
- /// Zero if the for success, or an error code for failure.
- //------------------------------------------------------------------
- int
- SetSTDIN(const FileSpec &file_spec);
- int
- SetSTDOUT(const FileSpec &file_spec);
- int
- SetSTDERR(const FileSpec &file_spec);
-
- //------------------------------------------------------------------
- /// Sets the disable ASLR flag to \a enable for a process that will
- /// be launched with the 'A' packet.
- ///
- /// @param[in] enable
- /// A boolean value indicating whether to disable ASLR or not.
- ///
- /// @return
- /// Zero if the for success, or an error code for failure.
- //------------------------------------------------------------------
- int
- SetDisableASLR (bool enable);
-
- //------------------------------------------------------------------
- /// Sets the DetachOnError flag to \a enable for the process controlled by the stub.
- ///
- /// @param[in] enable
- /// A boolean value indicating whether to detach on error or not.
- ///
- /// @return
- /// Zero if the for success, or an error code for failure.
- //------------------------------------------------------------------
- int
- SetDetachOnError (bool enable);
-
- //------------------------------------------------------------------
- /// Sets the working directory to \a path for a process that will
- /// be launched with the 'A' packet for non platform based
- /// connections. If this packet is sent to a GDB server that
- /// implements the platform, it will change the current working
- /// directory for the platform process.
- ///
- /// @param[in] working_dir
- /// The path to a directory to use when launching our process
- ///
- /// @return
- /// Zero if the for success, or an error code for failure.
- //------------------------------------------------------------------
- int
- SetWorkingDir(const FileSpec &working_dir);
-
- //------------------------------------------------------------------
- /// Gets the current working directory of a remote platform GDB
- /// server.
- ///
- /// @param[out] working_dir
- /// The current working directory on the remote platform.
- ///
- /// @return
- /// Boolean for success
- //------------------------------------------------------------------
- bool
- GetWorkingDir(FileSpec &working_dir);
-
- lldb::addr_t
- AllocateMemory (size_t size, uint32_t permissions);
-
- bool
- DeallocateMemory (lldb::addr_t addr);
-
- Error
- Detach (bool keep_stopped);
-
- Error
- GetMemoryRegionInfo (lldb::addr_t addr, MemoryRegionInfo &range_info);
-
- Error
- GetWatchpointSupportInfo (uint32_t &num);
-
- Error
- GetWatchpointSupportInfo (uint32_t &num, bool& after, const ArchSpec &arch);
-
- Error
- GetWatchpointsTriggerAfterInstruction (bool &after, const ArchSpec &arch);
-
- const ArchSpec &
- GetHostArchitecture ();
-
- uint32_t
- GetHostDefaultPacketTimeout();
-
- const ArchSpec &
- GetProcessArchitecture ();
-
- void
- GetRemoteQSupported();
-
- bool
- GetVContSupported (char flavor);
-
- bool
- GetpPacketSupported (lldb::tid_t tid);
-
- bool
- GetxPacketSupported ();
-
- bool
- GetVAttachOrWaitSupported ();
-
- bool
- GetSyncThreadStateSupported();
-
- void
- ResetDiscoverableSettings (bool did_exec);
-
- bool
- GetHostInfo (bool force = false);
-
- bool
- GetDefaultThreadId (lldb::tid_t &tid);
-
- bool
- GetOSVersion (uint32_t &major,
- uint32_t &minor,
- uint32_t &update);
-
- bool
- GetOSBuildString (std::string &s);
-
- bool
- GetOSKernelDescription (std::string &s);
-
- ArchSpec
- GetSystemArchitecture ();
-
- bool
- GetHostname (std::string &s);
-
- lldb::addr_t
- GetShlibInfoAddr();
-
- bool
- GetSupportsThreadSuffix ();
-
- bool
- GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info);
-
- uint32_t
- FindProcesses (const ProcessInstanceInfoMatch &process_match_info,
- ProcessInstanceInfoList &process_infos);
-
- bool
- GetUserName (uint32_t uid, std::string &name);
-
- bool
- GetGroupName (uint32_t gid, std::string &name);
-
- bool
- HasFullVContSupport ()
- {
- return GetVContSupported ('A');
- }
+ GDBRemoteCommunicationClient();
+
+ ~GDBRemoteCommunicationClient() override;
+
+ //------------------------------------------------------------------
+ // After connecting, send the handshake to the server to make sure
+ // we are communicating with it.
+ //------------------------------------------------------------------
+ bool HandshakeWithServer(Error *error_ptr);
+
+ // For packets which specify a range of output to be returned,
+ // return all of the output via a series of request packets of the form
+ // <prefix>0,<size>
+ // <prefix><size>,<size>
+ // <prefix><size>*2,<size>
+ // <prefix><size>*3,<size>
+ // ...
+ // until a "$l..." packet is received, indicating the end.
+ // (size is in hex; this format is used by a standard gdbserver to
+ // return the given portion of the output specified by <prefix>;
+ // for example, "qXfer:libraries-svr4:read::fff,1000" means
+ // "return a chunk of the xml description file for shared
+ // library load addresses, where the chunk starts at offset 0xfff
+ // and continues for 0x1000 bytes").
+ // Concatenate the resulting server response packets together and
+ // return in response_string. If any packet fails, the return value
+ // indicates that failure and the returned string value is undefined.
+ PacketResult
+ SendPacketsAndConcatenateResponses(const char *send_payload_prefix,
+ std::string &response_string);
+
+ bool GetThreadSuffixSupported();
+
+ // This packet is usually sent first and the boolean return value
+ // indicates if the packet was send and any response was received
+ // even in the response is UNIMPLEMENTED. If the packet failed to
+ // get a response, then false is returned. This quickly tells us
+ // if we were able to connect and communicate with the remote GDB
+ // server
+ bool QueryNoAckModeSupported();
+
+ void GetListThreadsInStopReplySupported();
+
+ lldb::pid_t GetCurrentProcessID(bool allow_lazy = true);
+
+ bool GetLaunchSuccess(std::string &error_str);
+
+ bool LaunchGDBServer(const char *remote_accept_hostname, lldb::pid_t &pid,
+ uint16_t &port, std::string &socket_name);
+
+ size_t QueryGDBServer(
+ std::vector<std::pair<uint16_t, std::string>> &connection_urls);
+
+ bool KillSpawnedProcess(lldb::pid_t pid);
+
+ //------------------------------------------------------------------
+ /// Sends a GDB remote protocol 'A' packet that delivers program
+ /// arguments to the remote server.
+ ///
+ /// @param[in] argv
+ /// A NULL terminated array of const C strings to use as the
+ /// arguments.
+ ///
+ /// @return
+ /// Zero if the response was "OK", a positive value if the
+ /// the response was "Exx" where xx are two hex digits, or
+ /// -1 if the call is unsupported or any other unexpected
+ /// response was received.
+ //------------------------------------------------------------------
+ int SendArgumentsPacket(const ProcessLaunchInfo &launch_info);
+
+ //------------------------------------------------------------------
+ /// Sends a "QEnvironment:NAME=VALUE" packet that will build up the
+ /// environment that will get used when launching an application
+ /// in conjunction with the 'A' packet. This function can be called
+ /// multiple times in a row in order to pass on the desired
+ /// environment that the inferior should be launched with.
+ ///
+ /// @param[in] name_equal_value
+ /// A NULL terminated C string that contains a single environment
+ /// in the format "NAME=VALUE".
+ ///
+ /// @return
+ /// Zero if the response was "OK", a positive value if the
+ /// the response was "Exx" where xx are two hex digits, or
+ /// -1 if the call is unsupported or any other unexpected
+ /// response was received.
+ //------------------------------------------------------------------
+ int SendEnvironmentPacket(char const *name_equal_value);
+
+ int SendLaunchArchPacket(const char *arch);
+
+ int SendLaunchEventDataPacket(const char *data,
+ bool *was_supported = nullptr);
+
+ //------------------------------------------------------------------
+ /// Sends a "vAttach:PID" where PID is in hex.
+ ///
+ /// @param[in] pid
+ /// A process ID for the remote gdb server to attach to.
+ ///
+ /// @param[out] response
+ /// The response received from the gdb server. If the return
+ /// value is zero, \a response will contain a stop reply
+ /// packet.
+ ///
+ /// @return
+ /// Zero if the attach was successful, or an error indicating
+ /// an error code.
+ //------------------------------------------------------------------
+ int SendAttach(lldb::pid_t pid, StringExtractorGDBRemote &response);
+
+ //------------------------------------------------------------------
+ /// Sends a GDB remote protocol 'I' packet that delivers stdin
+ /// data to the remote process.
+ ///
+ /// @param[in] data
+ /// A pointer to stdin data.
+ ///
+ /// @param[in] data_len
+ /// The number of bytes available at \a data.
+ ///
+ /// @return
+ /// Zero if the attach was successful, or an error indicating
+ /// an error code.
+ //------------------------------------------------------------------
+ int SendStdinNotification(const char *data, size_t data_len);
+
+ //------------------------------------------------------------------
+ /// Sets the path to use for stdin/out/err for a process
+ /// that will be launched with the 'A' packet.
+ ///
+ /// @param[in] path
+ /// The path to use for stdin/out/err
+ ///
+ /// @return
+ /// Zero if the for success, or an error code for failure.
+ //------------------------------------------------------------------
+ int SetSTDIN(const FileSpec &file_spec);
+ int SetSTDOUT(const FileSpec &file_spec);
+ int SetSTDERR(const FileSpec &file_spec);
+
+ //------------------------------------------------------------------
+ /// Sets the disable ASLR flag to \a enable for a process that will
+ /// be launched with the 'A' packet.
+ ///
+ /// @param[in] enable
+ /// A boolean value indicating whether to disable ASLR or not.
+ ///
+ /// @return
+ /// Zero if the for success, or an error code for failure.
+ //------------------------------------------------------------------
+ int SetDisableASLR(bool enable);
+
+ //------------------------------------------------------------------
+ /// Sets the DetachOnError flag to \a enable for the process controlled by the
+ /// stub.
+ ///
+ /// @param[in] enable
+ /// A boolean value indicating whether to detach on error or not.
+ ///
+ /// @return
+ /// Zero if the for success, or an error code for failure.
+ //------------------------------------------------------------------
+ int SetDetachOnError(bool enable);
+
+ //------------------------------------------------------------------
+ /// Sets the working directory to \a path for a process that will
+ /// be launched with the 'A' packet for non platform based
+ /// connections. If this packet is sent to a GDB server that
+ /// implements the platform, it will change the current working
+ /// directory for the platform process.
+ ///
+ /// @param[in] working_dir
+ /// The path to a directory to use when launching our process
+ ///
+ /// @return
+ /// Zero if the for success, or an error code for failure.
+ //------------------------------------------------------------------
+ int SetWorkingDir(const FileSpec &working_dir);
+
+ //------------------------------------------------------------------
+ /// Gets the current working directory of a remote platform GDB
+ /// server.
+ ///
+ /// @param[out] working_dir
+ /// The current working directory on the remote platform.
+ ///
+ /// @return
+ /// Boolean for success
+ //------------------------------------------------------------------
+ bool GetWorkingDir(FileSpec &working_dir);
+
+ lldb::addr_t AllocateMemory(size_t size, uint32_t permissions);
+
+ bool DeallocateMemory(lldb::addr_t addr);
+
+ Error Detach(bool keep_stopped);
+
+ Error GetMemoryRegionInfo(lldb::addr_t addr, MemoryRegionInfo &range_info);
+
+ Error GetWatchpointSupportInfo(uint32_t &num);
+
+ Error GetWatchpointSupportInfo(uint32_t &num, bool &after,
+ const ArchSpec &arch);
+
+ Error GetWatchpointsTriggerAfterInstruction(bool &after,
+ const ArchSpec &arch);
+
+ const ArchSpec &GetHostArchitecture();
+
+ std::chrono::seconds GetHostDefaultPacketTimeout();
+
+ const ArchSpec &GetProcessArchitecture();
+
+ void GetRemoteQSupported();
- bool
- HasAnyVContSupport ()
- {
- return GetVContSupported ('a');
- }
-
- bool
- GetStopReply (StringExtractorGDBRemote &response);
-
- bool
- GetThreadStopInfo (lldb::tid_t tid,
- StringExtractorGDBRemote &response);
-
- bool
- SupportsGDBStoppointPacket (GDBStoppointType type)
- {
- switch (type)
- {
- case eBreakpointSoftware: return m_supports_z0;
- case eBreakpointHardware: return m_supports_z1;
- case eWatchpointWrite: return m_supports_z2;
- case eWatchpointRead: return m_supports_z3;
- case eWatchpointReadWrite: return m_supports_z4;
- default: return false;
- }
- }
+ bool GetVContSupported(char flavor);
- uint8_t
- SendGDBStoppointTypePacket (GDBStoppointType type, // Type of breakpoint or watchpoint
- bool insert, // Insert or remove?
- lldb::addr_t addr, // Address of breakpoint or watchpoint
- uint32_t length); // Byte Size of breakpoint or watchpoint
-
- bool
- SetNonStopMode (const bool enable);
-
- void
- TestPacketSpeed (const uint32_t num_packets, uint32_t max_send, uint32_t max_recv, bool json, Stream &strm);
-
- // This packet is for testing the speed of the interface only. Both
- // the client and server need to support it, but this allows us to
- // measure the packet speed without any other work being done on the
- // other end and avoids any of that work affecting the packet send
- // and response times.
- bool
- SendSpeedTestPacket (uint32_t send_size,
- uint32_t recv_size);
-
- bool
- SetCurrentThread (uint64_t tid);
-
- bool
- SetCurrentThreadForRun (uint64_t tid);
-
- bool
- GetQXferAuxvReadSupported ();
-
- bool
- GetQXferLibrariesReadSupported ();
-
- bool
- GetQXferLibrariesSVR4ReadSupported ();
-
- uint64_t
- GetRemoteMaxPacketSize();
-
- bool
- GetEchoSupported ();
-
- bool
- GetAugmentedLibrariesSVR4ReadSupported ();
-
- bool
- GetQXferFeaturesReadSupported ();
-
- LazyBool
- SupportsAllocDeallocMemory () // const
- {
- // Uncomment this to have lldb pretend the debug server doesn't respond to alloc/dealloc memory packets.
- // m_supports_alloc_dealloc_memory = lldb_private::eLazyBoolNo;
- return m_supports_alloc_dealloc_memory;
- }
+ bool GetpPacketSupported(lldb::tid_t tid);
+
+ bool GetxPacketSupported();
+
+ bool GetVAttachOrWaitSupported();
+
+ bool GetSyncThreadStateSupported();
+
+ void ResetDiscoverableSettings(bool did_exec);
+
+ bool GetHostInfo(bool force = false);
+
+ bool GetDefaultThreadId(lldb::tid_t &tid);
+
+ bool GetOSVersion(uint32_t &major, uint32_t &minor, uint32_t &update);
+
+ bool GetOSBuildString(std::string &s);
+
+ bool GetOSKernelDescription(std::string &s);
+
+ ArchSpec GetSystemArchitecture();
+
+ bool GetHostname(std::string &s);
+
+ lldb::addr_t GetShlibInfoAddr();
+
+ bool GetSupportsThreadSuffix();
+
+ bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info);
- size_t
- GetCurrentThreadIDs (std::vector<lldb::tid_t> &thread_ids,
- bool &sequence_mutex_unavailable);
-
- bool
- GetInterruptWasSent () const
- {
- return m_interrupt_sent;
+ uint32_t FindProcesses(const ProcessInstanceInfoMatch &process_match_info,
+ ProcessInstanceInfoList &process_infos);
+
+ bool GetUserName(uint32_t uid, std::string &name);
+
+ bool GetGroupName(uint32_t gid, std::string &name);
+
+ bool HasFullVContSupport() { return GetVContSupported('A'); }
+
+ bool HasAnyVContSupport() { return GetVContSupported('a'); }
+
+ bool GetStopReply(StringExtractorGDBRemote &response);
+
+ bool GetThreadStopInfo(lldb::tid_t tid, StringExtractorGDBRemote &response);
+
+ bool SupportsGDBStoppointPacket(GDBStoppointType type) {
+ switch (type) {
+ case eBreakpointSoftware:
+ return m_supports_z0;
+ case eBreakpointHardware:
+ return m_supports_z1;
+ case eWatchpointWrite:
+ return m_supports_z2;
+ case eWatchpointRead:
+ return m_supports_z3;
+ case eWatchpointReadWrite:
+ return m_supports_z4;
+ default:
+ return false;
}
-
- lldb::user_id_t
- OpenFile (const FileSpec& file_spec, uint32_t flags, mode_t mode, Error &error);
-
- bool
- CloseFile (lldb::user_id_t fd, Error &error);
-
- lldb::user_id_t
- GetFileSize (const FileSpec& file_spec);
-
- Error
- GetFilePermissions(const FileSpec &file_spec, uint32_t &file_permissions);
-
- Error
- SetFilePermissions(const FileSpec &file_spec, uint32_t file_permissions);
-
- uint64_t
- ReadFile (lldb::user_id_t fd,
- uint64_t offset,
- void *dst,
- uint64_t dst_len,
- Error &error);
-
- uint64_t
- WriteFile (lldb::user_id_t fd,
- uint64_t offset,
- const void* src,
- uint64_t src_len,
- Error &error);
-
- Error
- CreateSymlink(const FileSpec &src,
- const FileSpec &dst);
-
- Error
- Unlink(const FileSpec &file_spec);
-
- Error
- MakeDirectory(const FileSpec &file_spec, uint32_t mode);
-
- bool
- GetFileExists (const FileSpec& file_spec);
-
- Error
- RunShellCommand(const char *command, // Shouldn't be nullptr
- const FileSpec &working_dir, // Pass empty FileSpec to use the current working directory
- int *status_ptr, // Pass nullptr if you don't want the process exit status
- int *signo_ptr, // Pass nullptr if you don't want the signal that caused the process to exit
- std::string *command_output, // Pass nullptr if you don't want the command output
- uint32_t timeout_sec); // Timeout in seconds to wait for shell program to finish
-
- bool
- CalculateMD5 (const FileSpec& file_spec, uint64_t &high, uint64_t &low);
-
- std::string
- HarmonizeThreadIdsForProfileData (ProcessGDBRemote *process,
- StringExtractorGDBRemote &inputStringExtractor);
-
- bool
- ReadRegister(lldb::tid_t tid,
- uint32_t reg_num, // Must be the eRegisterKindProcessPlugin register number, to be sent to the remote
- StringExtractorGDBRemote &response);
-
- bool
- ReadAllRegisters (lldb::tid_t tid,
- StringExtractorGDBRemote &response);
-
- bool
- SaveRegisterState (lldb::tid_t tid, uint32_t &save_id);
-
- bool
- RestoreRegisterState (lldb::tid_t tid, uint32_t save_id);
-
- const char *
- GetGDBServerProgramName();
-
- uint32_t
- GetGDBServerProgramVersion();
-
- bool
- AvoidGPackets(ProcessGDBRemote *process);
-
- StructuredData::ObjectSP
- GetThreadsInfo();
-
- bool
- GetThreadExtendedInfoSupported();
-
- bool
- GetLoadedDynamicLibrariesInfosSupported();
-
- bool
- GetModuleInfo (const FileSpec& module_file_spec,
- const ArchSpec& arch_spec,
- ModuleSpec &module_spec);
-
- bool
- ReadExtFeature (const lldb_private::ConstString object,
- const lldb_private::ConstString annex,
- std::string & out,
- lldb_private::Error & err);
-
- void
- ServeSymbolLookups(lldb_private::Process *process);
+ }
+
+ uint8_t SendGDBStoppointTypePacket(
+ GDBStoppointType type, // Type of breakpoint or watchpoint
+ bool insert, // Insert or remove?
+ lldb::addr_t addr, // Address of breakpoint or watchpoint
+ uint32_t length); // Byte Size of breakpoint or watchpoint
+
+ bool SetNonStopMode(const bool enable);
+
+ void TestPacketSpeed(const uint32_t num_packets, uint32_t max_send,
+ uint32_t max_recv, uint64_t recv_amount, bool json,
+ Stream &strm);
+
+ // This packet is for testing the speed of the interface only. Both
+ // the client and server need to support it, but this allows us to
+ // measure the packet speed without any other work being done on the
+ // other end and avoids any of that work affecting the packet send
+ // and response times.
+ bool SendSpeedTestPacket(uint32_t send_size, uint32_t recv_size);
+
+ bool SetCurrentThread(uint64_t tid);
+
+ bool SetCurrentThreadForRun(uint64_t tid);
+
+ bool GetQXferAuxvReadSupported();
+
+ bool GetQXferLibrariesReadSupported();
+
+ bool GetQXferLibrariesSVR4ReadSupported();
+
+ uint64_t GetRemoteMaxPacketSize();
+
+ bool GetEchoSupported();
+
+ bool GetAugmentedLibrariesSVR4ReadSupported();
+
+ bool GetQXferFeaturesReadSupported();
+
+ LazyBool SupportsAllocDeallocMemory() // const
+ {
+ // Uncomment this to have lldb pretend the debug server doesn't respond to
+ // alloc/dealloc memory packets.
+ // m_supports_alloc_dealloc_memory = lldb_private::eLazyBoolNo;
+ return m_supports_alloc_dealloc_memory;
+ }
+
+ size_t GetCurrentThreadIDs(std::vector<lldb::tid_t> &thread_ids,
+ bool &sequence_mutex_unavailable);
+
+ lldb::user_id_t OpenFile(const FileSpec &file_spec, uint32_t flags,
+ mode_t mode, Error &error);
+
+ bool CloseFile(lldb::user_id_t fd, Error &error);
+
+ lldb::user_id_t GetFileSize(const FileSpec &file_spec);
+
+ Error GetFilePermissions(const FileSpec &file_spec,
+ uint32_t &file_permissions);
+
+ Error SetFilePermissions(const FileSpec &file_spec,
+ uint32_t file_permissions);
+
+ uint64_t ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst,
+ uint64_t dst_len, Error &error);
+
+ uint64_t WriteFile(lldb::user_id_t fd, uint64_t offset, const void *src,
+ uint64_t src_len, Error &error);
+
+ Error CreateSymlink(const FileSpec &src, const FileSpec &dst);
+
+ Error Unlink(const FileSpec &file_spec);
+
+ Error MakeDirectory(const FileSpec &file_spec, uint32_t mode);
+
+ bool GetFileExists(const FileSpec &file_spec);
+
+ Error RunShellCommand(
+ const char *command, // Shouldn't be nullptr
+ const FileSpec &working_dir, // Pass empty FileSpec to use the current
+ // working directory
+ int *status_ptr, // Pass nullptr if you don't want the process exit status
+ int *signo_ptr, // Pass nullptr if you don't want the signal that caused
+ // the process to exit
+ std::string
+ *command_output, // Pass nullptr if you don't want the command output
+ uint32_t timeout_sec); // Timeout in seconds to wait for shell program to
+ // finish
+
+ bool CalculateMD5(const FileSpec &file_spec, uint64_t &high, uint64_t &low);
+
+ lldb::DataBufferSP ReadRegister(
+ lldb::tid_t tid,
+ uint32_t
+ reg_num); // Must be the eRegisterKindProcessPlugin register number
+
+ lldb::DataBufferSP ReadAllRegisters(lldb::tid_t tid);
+
+ bool
+ WriteRegister(lldb::tid_t tid,
+ uint32_t reg_num, // eRegisterKindProcessPlugin register number
+ llvm::ArrayRef<uint8_t> data);
+
+ bool WriteAllRegisters(lldb::tid_t tid, llvm::ArrayRef<uint8_t> data);
+
+ bool SaveRegisterState(lldb::tid_t tid, uint32_t &save_id);
+
+ bool RestoreRegisterState(lldb::tid_t tid, uint32_t save_id);
+
+ bool SyncThreadState(lldb::tid_t tid);
+
+ const char *GetGDBServerProgramName();
+
+ uint32_t GetGDBServerProgramVersion();
+
+ bool AvoidGPackets(ProcessGDBRemote *process);
+
+ StructuredData::ObjectSP GetThreadsInfo();
+
+ bool GetThreadExtendedInfoSupported();
+
+ bool GetLoadedDynamicLibrariesInfosSupported();
+
+ bool GetSharedCacheInfoSupported();
+
+ bool GetModuleInfo(const FileSpec &module_file_spec,
+ const ArchSpec &arch_spec, ModuleSpec &module_spec);
+
+ llvm::Optional<std::vector<ModuleSpec>>
+ GetModulesInfo(llvm::ArrayRef<FileSpec> module_file_specs,
+ const llvm::Triple &triple);
+
+ bool ReadExtFeature(const lldb_private::ConstString object,
+ const lldb_private::ConstString annex, std::string &out,
+ lldb_private::Error &err);
+
+ void ServeSymbolLookups(lldb_private::Process *process);
+
+ //------------------------------------------------------------------
+ /// Return the feature set supported by the gdb-remote server.
+ ///
+ /// This method returns the remote side's response to the qSupported
+ /// packet. The response is the complete string payload returned
+ /// to the client.
+ ///
+ /// @return
+ /// The string returned by the server to the qSupported query.
+ //------------------------------------------------------------------
+ const std::string &GetServerSupportedFeatures() const {
+ return m_qSupported_response;
+ }
+
+ //------------------------------------------------------------------
+ /// Return the array of async JSON packet types supported by the remote.
+ ///
+ /// This method returns the remote side's array of supported JSON
+ /// packet types as a list of type names. Each of the results are
+ /// expected to have an Enable{type_name} command to enable and configure
+ /// the related feature. Each type_name for an enabled feature will
+ /// possibly send async-style packets that contain a payload of a
+ /// binhex-encoded JSON dictionary. The dictionary will have a
+ /// string field named 'type', that contains the type_name of the
+ /// supported packet type.
+ ///
+ /// There is a Plugin category called structured-data plugins.
+ /// A plugin indicates whether it knows how to handle a type_name.
+ /// If so, it can be used to process the async JSON packet.
+ ///
+ /// @return
+ /// The string returned by the server to the qSupported query.
+ //------------------------------------------------------------------
+ lldb_private::StructuredData::Array *GetSupportedStructuredDataPlugins();
+
+ //------------------------------------------------------------------
+ /// Configure a StructuredData feature on the remote end.
+ ///
+ /// @see \b Process::ConfigureStructuredData(...) for details.
+ //------------------------------------------------------------------
+ Error
+ ConfigureRemoteStructuredData(const ConstString &type_name,
+ const StructuredData::ObjectSP &config_sp);
protected:
- LazyBool m_supports_not_sending_acks;
- LazyBool m_supports_thread_suffix;
- LazyBool m_supports_threads_in_stop_reply;
- LazyBool m_supports_vCont_all;
- LazyBool m_supports_vCont_any;
- LazyBool m_supports_vCont_c;
- LazyBool m_supports_vCont_C;
- LazyBool m_supports_vCont_s;
- LazyBool m_supports_vCont_S;
- LazyBool m_qHostInfo_is_valid;
- LazyBool m_curr_pid_is_valid;
- LazyBool m_qProcessInfo_is_valid;
- LazyBool m_qGDBServerVersion_is_valid;
- LazyBool m_supports_alloc_dealloc_memory;
- LazyBool m_supports_memory_region_info;
- LazyBool m_supports_watchpoint_support_info;
- LazyBool m_supports_detach_stay_stopped;
- LazyBool m_watchpoints_trigger_after_instruction;
- LazyBool m_attach_or_wait_reply;
- LazyBool m_prepare_for_reg_writing_reply;
- LazyBool m_supports_p;
- LazyBool m_supports_x;
- LazyBool m_avoid_g_packets;
- LazyBool m_supports_QSaveRegisterState;
- LazyBool m_supports_qXfer_auxv_read;
- LazyBool m_supports_qXfer_libraries_read;
- LazyBool m_supports_qXfer_libraries_svr4_read;
- LazyBool m_supports_qXfer_features_read;
- LazyBool m_supports_augmented_libraries_svr4_read;
- LazyBool m_supports_jThreadExtendedInfo;
- LazyBool m_supports_jLoadedDynamicLibrariesInfos;
-
- bool
- m_supports_qProcessInfoPID:1,
- m_supports_qfProcessInfo:1,
- m_supports_qUserName:1,
- m_supports_qGroupName:1,
- m_supports_qThreadStopInfo:1,
- m_supports_z0:1,
- m_supports_z1:1,
- m_supports_z2:1,
- m_supports_z3:1,
- m_supports_z4:1,
- m_supports_QEnvironment:1,
- m_supports_QEnvironmentHexEncoded:1,
- m_supports_qSymbol:1,
- m_qSymbol_requests_done:1,
- m_supports_qModuleInfo:1,
- m_supports_jThreadsInfo:1;
-
- lldb::pid_t m_curr_pid;
- lldb::tid_t m_curr_tid; // Current gdb remote protocol thread index for all other operations
- lldb::tid_t m_curr_tid_run; // Current gdb remote protocol thread index for continue, step, etc
-
- uint32_t m_num_supported_hardware_watchpoints;
-
- // If we need to send a packet while the target is running, the m_async_XXX
- // member variables take care of making this happen.
- std::recursive_mutex m_async_mutex;
- Predicate<bool> m_async_packet_predicate;
- std::string m_async_packet;
- PacketResult m_async_result;
- StringExtractorGDBRemote m_async_response;
- int m_async_signal; // We were asked to deliver a signal to the inferior process.
- bool m_interrupt_sent;
- std::string m_partial_profile_data;
- std::map<uint64_t, uint32_t> m_thread_id_to_used_usec_map;
-
- ArchSpec m_host_arch;
- ArchSpec m_process_arch;
- uint32_t m_os_version_major;
- uint32_t m_os_version_minor;
- uint32_t m_os_version_update;
- std::string m_os_build;
- std::string m_os_kernel;
- std::string m_hostname;
- std::string m_gdb_server_name; // from reply to qGDBServerVersion, empty if qGDBServerVersion is not supported
- uint32_t m_gdb_server_version; // from reply to qGDBServerVersion, zero if qGDBServerVersion is not supported
- uint32_t m_default_packet_timeout;
- uint64_t m_max_packet_size; // as returned by qSupported
-
- PacketResult
- SendPacketAndWaitForResponseNoLock (const char *payload,
- size_t payload_length,
- StringExtractorGDBRemote &response);
-
- bool
- GetCurrentProcessInfo (bool allow_lazy_pid = true);
-
- bool
- GetGDBServerVersion();
-
- // Given the list of compression types that the remote debug stub can support,
- // possibly enable compression if we find an encoding we can handle.
- void
- MaybeEnableCompression (std::vector<std::string> supported_compressions);
-
- bool
- DecodeProcessInfoResponse (StringExtractorGDBRemote &response,
- ProcessInstanceInfo &process_info);
+ LazyBool m_supports_not_sending_acks;
+ LazyBool m_supports_thread_suffix;
+ LazyBool m_supports_threads_in_stop_reply;
+ LazyBool m_supports_vCont_all;
+ LazyBool m_supports_vCont_any;
+ LazyBool m_supports_vCont_c;
+ LazyBool m_supports_vCont_C;
+ LazyBool m_supports_vCont_s;
+ LazyBool m_supports_vCont_S;
+ LazyBool m_qHostInfo_is_valid;
+ LazyBool m_curr_pid_is_valid;
+ LazyBool m_qProcessInfo_is_valid;
+ LazyBool m_qGDBServerVersion_is_valid;
+ LazyBool m_supports_alloc_dealloc_memory;
+ LazyBool m_supports_memory_region_info;
+ LazyBool m_supports_watchpoint_support_info;
+ LazyBool m_supports_detach_stay_stopped;
+ LazyBool m_watchpoints_trigger_after_instruction;
+ LazyBool m_attach_or_wait_reply;
+ LazyBool m_prepare_for_reg_writing_reply;
+ LazyBool m_supports_p;
+ LazyBool m_supports_x;
+ LazyBool m_avoid_g_packets;
+ LazyBool m_supports_QSaveRegisterState;
+ LazyBool m_supports_qXfer_auxv_read;
+ LazyBool m_supports_qXfer_libraries_read;
+ LazyBool m_supports_qXfer_libraries_svr4_read;
+ LazyBool m_supports_qXfer_features_read;
+ LazyBool m_supports_augmented_libraries_svr4_read;
+ LazyBool m_supports_jThreadExtendedInfo;
+ LazyBool m_supports_jLoadedDynamicLibrariesInfos;
+ LazyBool m_supports_jGetSharedCacheInfo;
+
+ bool m_supports_qProcessInfoPID : 1, m_supports_qfProcessInfo : 1,
+ m_supports_qUserName : 1, m_supports_qGroupName : 1,
+ m_supports_qThreadStopInfo : 1, m_supports_z0 : 1, m_supports_z1 : 1,
+ m_supports_z2 : 1, m_supports_z3 : 1, m_supports_z4 : 1,
+ m_supports_QEnvironment : 1, m_supports_QEnvironmentHexEncoded : 1,
+ m_supports_qSymbol : 1, m_qSymbol_requests_done : 1,
+ m_supports_qModuleInfo : 1, m_supports_jThreadsInfo : 1,
+ m_supports_jModulesInfo : 1;
+
+ lldb::pid_t m_curr_pid;
+ lldb::tid_t m_curr_tid; // Current gdb remote protocol thread index for all
+ // other operations
+ lldb::tid_t m_curr_tid_run; // Current gdb remote protocol thread index for
+ // continue, step, etc
+
+ uint32_t m_num_supported_hardware_watchpoints;
+
+ ArchSpec m_host_arch;
+ ArchSpec m_process_arch;
+ uint32_t m_os_version_major;
+ uint32_t m_os_version_minor;
+ uint32_t m_os_version_update;
+ std::string m_os_build;
+ std::string m_os_kernel;
+ std::string m_hostname;
+ std::string m_gdb_server_name; // from reply to qGDBServerVersion, empty if
+ // qGDBServerVersion is not supported
+ uint32_t m_gdb_server_version; // from reply to qGDBServerVersion, zero if
+ // qGDBServerVersion is not supported
+ std::chrono::seconds m_default_packet_timeout;
+ uint64_t m_max_packet_size; // as returned by qSupported
+ std::string m_qSupported_response; // the complete response to qSupported
+
+ bool m_supported_async_json_packets_is_valid;
+ lldb_private::StructuredData::ObjectSP m_supported_async_json_packets_sp;
+
+ bool GetCurrentProcessInfo(bool allow_lazy_pid = true);
+
+ bool GetGDBServerVersion();
+
+ // Given the list of compression types that the remote debug stub can support,
+ // possibly enable compression if we find an encoding we can handle.
+ void MaybeEnableCompression(std::vector<std::string> supported_compressions);
+
+ bool DecodeProcessInfoResponse(StringExtractorGDBRemote &response,
+ ProcessInstanceInfo &process_info);
+
+ void OnRunPacketSent(bool first) override;
+
+ PacketResult SendThreadSpecificPacketAndWaitForResponse(
+ lldb::tid_t tid, StreamString &&payload,
+ StringExtractorGDBRemote &response, bool send_async);
private:
- DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunicationClient);
+ DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationClient);
};
} // namespace process_gdb_remote
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
index 4ee66b84d474..934824e214dc 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
@@ -25,114 +25,96 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
-GDBRemoteCommunicationServer::GDBRemoteCommunicationServer(const char *comm_name,
- const char *listener_name) :
- GDBRemoteCommunication (comm_name, listener_name),
- m_exit_now (false)
-{
-}
+GDBRemoteCommunicationServer::GDBRemoteCommunicationServer(
+ const char *comm_name, const char *listener_name)
+ : GDBRemoteCommunication(comm_name, listener_name), m_exit_now(false) {}
-GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer()
-{
-}
+GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer() {}
void GDBRemoteCommunicationServer::RegisterPacketHandler(
- StringExtractorGDBRemote::ServerPacketType packet_type,
- PacketHandler handler)
-{
- m_packet_handlers[packet_type] = std::move(handler);
+ StringExtractorGDBRemote::ServerPacketType packet_type,
+ PacketHandler handler) {
+ m_packet_handlers[packet_type] = std::move(handler);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServer::GetPacketAndSendResponse (uint32_t timeout_usec,
- Error &error,
- bool &interrupt,
- bool &quit)
-{
- StringExtractorGDBRemote packet;
-
- PacketResult packet_result = WaitForPacketWithTimeoutMicroSecondsNoLock (packet, timeout_usec, false);
- if (packet_result == PacketResult::Success)
- {
- const StringExtractorGDBRemote::ServerPacketType packet_type = packet.GetServerPacketType ();
- switch (packet_type)
- {
- case StringExtractorGDBRemote::eServerPacketType_nack:
- case StringExtractorGDBRemote::eServerPacketType_ack:
- break;
-
- case StringExtractorGDBRemote::eServerPacketType_invalid:
- error.SetErrorString("invalid packet");
- quit = true;
- break;
-
- case StringExtractorGDBRemote::eServerPacketType_unimplemented:
- packet_result = SendUnimplementedResponse (packet.GetStringRef().c_str());
- break;
-
- default:
- auto handler_it = m_packet_handlers.find(packet_type);
- if (handler_it == m_packet_handlers.end())
- packet_result = SendUnimplementedResponse (packet.GetStringRef().c_str());
- else
- packet_result = handler_it->second (packet, error, interrupt, quit);
- break;
- }
+GDBRemoteCommunicationServer::GetPacketAndSendResponse(
+ Timeout<std::micro> timeout, Error &error, bool &interrupt, bool &quit) {
+ StringExtractorGDBRemote packet;
+
+ PacketResult packet_result = WaitForPacketNoLock(packet, timeout, false);
+ if (packet_result == PacketResult::Success) {
+ const StringExtractorGDBRemote::ServerPacketType packet_type =
+ packet.GetServerPacketType();
+ switch (packet_type) {
+ case StringExtractorGDBRemote::eServerPacketType_nack:
+ case StringExtractorGDBRemote::eServerPacketType_ack:
+ break;
+
+ case StringExtractorGDBRemote::eServerPacketType_invalid:
+ error.SetErrorString("invalid packet");
+ quit = true;
+ break;
+
+ case StringExtractorGDBRemote::eServerPacketType_unimplemented:
+ packet_result = SendUnimplementedResponse(packet.GetStringRef().c_str());
+ break;
+
+ default:
+ auto handler_it = m_packet_handlers.find(packet_type);
+ if (handler_it == m_packet_handlers.end())
+ packet_result =
+ SendUnimplementedResponse(packet.GetStringRef().c_str());
+ else
+ packet_result = handler_it->second(packet, error, interrupt, quit);
+ break;
}
- else
- {
- if (!IsConnected())
- {
- error.SetErrorString("lost connection");
- quit = true;
- }
- else
- {
- error.SetErrorString("timeout");
- }
+ } else {
+ if (!IsConnected()) {
+ error.SetErrorString("lost connection");
+ quit = true;
+ } else {
+ error.SetErrorString("timeout");
}
+ }
- // Check if anything occurred that would force us to want to exit.
- if (m_exit_now)
- quit = true;
+ // Check if anything occurred that would force us to want to exit.
+ if (m_exit_now)
+ quit = true;
- return packet_result;
+ return packet_result;
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServer::SendUnimplementedResponse (const char *)
-{
- // TODO: Log the packet we aren't handling...
- return SendPacketNoLock ("", 0);
+GDBRemoteCommunicationServer::SendUnimplementedResponse(const char *) {
+ // TODO: Log the packet we aren't handling...
+ return SendPacketNoLock("");
}
-
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServer::SendErrorResponse (uint8_t err)
-{
- char packet[16];
- int packet_len = ::snprintf (packet, sizeof(packet), "E%2.2x", err);
- assert (packet_len < (int)sizeof(packet));
- return SendPacketNoLock (packet, packet_len);
+GDBRemoteCommunicationServer::SendErrorResponse(uint8_t err) {
+ char packet[16];
+ int packet_len = ::snprintf(packet, sizeof(packet), "E%2.2x", err);
+ assert(packet_len < (int)sizeof(packet));
+ return SendPacketNoLock(llvm::StringRef(packet, packet_len));
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServer::SendIllFormedResponse (const StringExtractorGDBRemote &failed_packet, const char *message)
-{
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
- if (log)
- log->Printf ("GDBRemoteCommunicationServer::%s: ILLFORMED: '%s' (%s)", __FUNCTION__, failed_packet.GetStringRef ().c_str (), message ? message : "");
- return SendErrorResponse (0x03);
+GDBRemoteCommunicationServer::SendIllFormedResponse(
+ const StringExtractorGDBRemote &failed_packet, const char *message) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
+ if (log)
+ log->Printf("GDBRemoteCommunicationServer::%s: ILLFORMED: '%s' (%s)",
+ __FUNCTION__, failed_packet.GetStringRef().c_str(),
+ message ? message : "");
+ return SendErrorResponse(0x03);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServer::SendOKResponse ()
-{
- return SendPacketNoLock ("OK", 2);
+GDBRemoteCommunicationServer::SendOKResponse() {
+ return SendPacketNoLock("OK");
}
-bool
-GDBRemoteCommunicationServer::HandshakeWithClient()
-{
- return GetAck() == PacketResult::Success;
+bool GDBRemoteCommunicationServer::HandshakeWithClient() {
+ return GetAck() == PacketResult::Success;
}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
index 1d512bf1de59..0c583e62d76b 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
@@ -17,8 +17,8 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private-forward.h"
#include "GDBRemoteCommunication.h"
+#include "lldb/lldb-private-forward.h"
class StringExtractorGDBRemote;
@@ -27,52 +27,47 @@ namespace process_gdb_remote {
class ProcessGDBRemote;
-class GDBRemoteCommunicationServer : public GDBRemoteCommunication
-{
+class GDBRemoteCommunicationServer : public GDBRemoteCommunication {
public:
- using PortMap = std::map<uint16_t, lldb::pid_t>;
- using PacketHandler = std::function<PacketResult(StringExtractorGDBRemote &packet,
- Error &error,
- bool &interrupt,
- bool &quit)>;
+ using PortMap = std::map<uint16_t, lldb::pid_t>;
+ using PacketHandler =
+ std::function<PacketResult(StringExtractorGDBRemote &packet, Error &error,
+ bool &interrupt, bool &quit)>;
- GDBRemoteCommunicationServer(const char *comm_name,
- const char *listener_name);
+ GDBRemoteCommunicationServer(const char *comm_name,
+ const char *listener_name);
- ~GDBRemoteCommunicationServer() override;
+ ~GDBRemoteCommunicationServer() override;
- void RegisterPacketHandler(StringExtractorGDBRemote::ServerPacketType packet_type,
- PacketHandler handler);
+ void
+ RegisterPacketHandler(StringExtractorGDBRemote::ServerPacketType packet_type,
+ PacketHandler handler);
- PacketResult
- GetPacketAndSendResponse (uint32_t timeout_usec,
- Error &error,
- bool &interrupt,
- bool &quit);
+ PacketResult GetPacketAndSendResponse(Timeout<std::micro> timeout,
+ Error &error, bool &interrupt,
+ bool &quit);
- // After connecting, do a little handshake with the client to make sure
- // we are at least communicating
- bool
- HandshakeWithClient ();
+ // After connecting, do a little handshake with the client to make sure
+ // we are at least communicating
+ bool HandshakeWithClient();
protected:
- std::map<StringExtractorGDBRemote::ServerPacketType, PacketHandler> m_packet_handlers;
- bool m_exit_now; // use in asynchronous handling to indicate process should exit.
+ std::map<StringExtractorGDBRemote::ServerPacketType, PacketHandler>
+ m_packet_handlers;
+ bool m_exit_now; // use in asynchronous handling to indicate process should
+ // exit.
- PacketResult
- SendUnimplementedResponse (const char *packet);
+ PacketResult SendUnimplementedResponse(const char *packet);
- PacketResult
- SendErrorResponse (uint8_t error);
+ PacketResult SendErrorResponse(uint8_t error);
- PacketResult
- SendIllFormedResponse (const StringExtractorGDBRemote &packet, const char *error_message);
+ PacketResult SendIllFormedResponse(const StringExtractorGDBRemote &packet,
+ const char *error_message);
- PacketResult
- SendOKResponse ();
+ PacketResult SendOKResponse();
private:
- DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunicationServer);
+ DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationServer);
};
} // namespace process_gdb_remote
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
index 26a2e697e854..e4e6810f665c 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
@@ -12,12 +12,16 @@
#include <errno.h>
// C Includes
+
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+#endif
+
// C++ Includes
-#include <cstring>
#include <chrono>
+#include <cstring>
// Other libraries and framework includes
-#include "llvm/ADT/Triple.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/StreamGDBRemote.h"
@@ -34,6 +38,8 @@
#include "lldb/Target/FileAction.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
+#include "lldb/Utility/JSON.h"
+#include "llvm/ADT/Triple.h"
// Project includes
#include "ProcessGDBRemoteLog.h"
@@ -43,1214 +49,1252 @@
#include "lldb/Host/android/HostInfoAndroid.h"
#endif
+#include "llvm/ADT/StringSwitch.h"
+
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
#ifdef __ANDROID__
- const static uint32_t g_default_packet_timeout_sec = 20; // seconds
+const static uint32_t g_default_packet_timeout_sec = 20; // seconds
#else
- const static uint32_t g_default_packet_timeout_sec = 0; // not specified
+const static uint32_t g_default_packet_timeout_sec = 0; // not specified
#endif
//----------------------------------------------------------------------
// GDBRemoteCommunicationServerCommon constructor
//----------------------------------------------------------------------
-GDBRemoteCommunicationServerCommon::GDBRemoteCommunicationServerCommon(const char *comm_name, const char *listener_name) :
- GDBRemoteCommunicationServer (comm_name, listener_name),
- m_process_launch_info (),
- m_process_launch_error (),
- m_proc_infos (),
- m_proc_infos_index (0),
- m_thread_suffix_supported (false),
- m_list_threads_in_stop_reply (false)
-{
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_A,
- &GDBRemoteCommunicationServerCommon::Handle_A);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QEnvironment,
- &GDBRemoteCommunicationServerCommon::Handle_QEnvironment);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QEnvironmentHexEncoded,
- &GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qfProcessInfo,
- &GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qGroupName,
- &GDBRemoteCommunicationServerCommon::Handle_qGroupName);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qHostInfo,
- &GDBRemoteCommunicationServerCommon::Handle_qHostInfo);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QLaunchArch,
- &GDBRemoteCommunicationServerCommon::Handle_QLaunchArch);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qLaunchSuccess,
- &GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QListThreadsInStopReply,
- &GDBRemoteCommunicationServerCommon::Handle_QListThreadsInStopReply);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qEcho,
- &GDBRemoteCommunicationServerCommon::Handle_qEcho);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qModuleInfo,
- &GDBRemoteCommunicationServerCommon::Handle_qModuleInfo);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qPlatform_chmod,
- &GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qPlatform_mkdir,
- &GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qPlatform_shell,
- &GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qProcessInfoPID,
- &GDBRemoteCommunicationServerCommon::Handle_qProcessInfoPID);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetDetachOnError,
- &GDBRemoteCommunicationServerCommon::Handle_QSetDetachOnError);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetSTDERR,
- &GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetSTDIN,
- &GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetSTDOUT,
- &GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qSpeedTest,
- &GDBRemoteCommunicationServerCommon::Handle_qSpeedTest);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qsProcessInfo,
- &GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode,
- &GDBRemoteCommunicationServerCommon::Handle_QStartNoAckMode);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qSupported,
- &GDBRemoteCommunicationServerCommon::Handle_qSupported);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QThreadSuffixSupported,
- &GDBRemoteCommunicationServerCommon::Handle_QThreadSuffixSupported);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qUserName,
- &GDBRemoteCommunicationServerCommon::Handle_qUserName);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_close,
- &GDBRemoteCommunicationServerCommon::Handle_vFile_Close);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_exists,
- &GDBRemoteCommunicationServerCommon::Handle_vFile_Exists);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_md5,
- &GDBRemoteCommunicationServerCommon::Handle_vFile_MD5);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_mode,
- &GDBRemoteCommunicationServerCommon::Handle_vFile_Mode);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_open,
- &GDBRemoteCommunicationServerCommon::Handle_vFile_Open);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_pread,
- &GDBRemoteCommunicationServerCommon::Handle_vFile_pRead);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_pwrite,
- &GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_size,
- &GDBRemoteCommunicationServerCommon::Handle_vFile_Size);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_stat,
- &GDBRemoteCommunicationServerCommon::Handle_vFile_Stat);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_symlink,
- &GDBRemoteCommunicationServerCommon::Handle_vFile_symlink);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_unlink,
- &GDBRemoteCommunicationServerCommon::Handle_vFile_unlink);
+GDBRemoteCommunicationServerCommon::GDBRemoteCommunicationServerCommon(
+ const char *comm_name, const char *listener_name)
+ : GDBRemoteCommunicationServer(comm_name, listener_name),
+ m_process_launch_info(), m_process_launch_error(), m_proc_infos(),
+ m_proc_infos_index(0), m_thread_suffix_supported(false),
+ m_list_threads_in_stop_reply(false) {
+ RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_A,
+ &GDBRemoteCommunicationServerCommon::Handle_A);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QEnvironment,
+ &GDBRemoteCommunicationServerCommon::Handle_QEnvironment);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QEnvironmentHexEncoded,
+ &GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qfProcessInfo,
+ &GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qGroupName,
+ &GDBRemoteCommunicationServerCommon::Handle_qGroupName);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qHostInfo,
+ &GDBRemoteCommunicationServerCommon::Handle_qHostInfo);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QLaunchArch,
+ &GDBRemoteCommunicationServerCommon::Handle_QLaunchArch);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qLaunchSuccess,
+ &GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QListThreadsInStopReply,
+ &GDBRemoteCommunicationServerCommon::Handle_QListThreadsInStopReply);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qEcho,
+ &GDBRemoteCommunicationServerCommon::Handle_qEcho);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qModuleInfo,
+ &GDBRemoteCommunicationServerCommon::Handle_qModuleInfo);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_jModulesInfo,
+ &GDBRemoteCommunicationServerCommon::Handle_jModulesInfo);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qPlatform_chmod,
+ &GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qPlatform_mkdir,
+ &GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qPlatform_shell,
+ &GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qProcessInfoPID,
+ &GDBRemoteCommunicationServerCommon::Handle_qProcessInfoPID);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QSetDetachOnError,
+ &GDBRemoteCommunicationServerCommon::Handle_QSetDetachOnError);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QSetSTDERR,
+ &GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QSetSTDIN,
+ &GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QSetSTDOUT,
+ &GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qSpeedTest,
+ &GDBRemoteCommunicationServerCommon::Handle_qSpeedTest);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qsProcessInfo,
+ &GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode,
+ &GDBRemoteCommunicationServerCommon::Handle_QStartNoAckMode);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qSupported,
+ &GDBRemoteCommunicationServerCommon::Handle_qSupported);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QThreadSuffixSupported,
+ &GDBRemoteCommunicationServerCommon::Handle_QThreadSuffixSupported);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qUserName,
+ &GDBRemoteCommunicationServerCommon::Handle_qUserName);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vFile_close,
+ &GDBRemoteCommunicationServerCommon::Handle_vFile_Close);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vFile_exists,
+ &GDBRemoteCommunicationServerCommon::Handle_vFile_Exists);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vFile_md5,
+ &GDBRemoteCommunicationServerCommon::Handle_vFile_MD5);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vFile_mode,
+ &GDBRemoteCommunicationServerCommon::Handle_vFile_Mode);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vFile_open,
+ &GDBRemoteCommunicationServerCommon::Handle_vFile_Open);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vFile_pread,
+ &GDBRemoteCommunicationServerCommon::Handle_vFile_pRead);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vFile_pwrite,
+ &GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vFile_size,
+ &GDBRemoteCommunicationServerCommon::Handle_vFile_Size);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vFile_stat,
+ &GDBRemoteCommunicationServerCommon::Handle_vFile_Stat);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vFile_symlink,
+ &GDBRemoteCommunicationServerCommon::Handle_vFile_symlink);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vFile_unlink,
+ &GDBRemoteCommunicationServerCommon::Handle_vFile_unlink);
}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-GDBRemoteCommunicationServerCommon::~GDBRemoteCommunicationServerCommon()
-{
-}
+GDBRemoteCommunicationServerCommon::~GDBRemoteCommunicationServerCommon() {}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qHostInfo (StringExtractorGDBRemote &packet)
-{
- StreamString response;
+GDBRemoteCommunicationServerCommon::Handle_qHostInfo(
+ StringExtractorGDBRemote &packet) {
+ StreamString response;
- // $cputype:16777223;cpusubtype:3;ostype:Darwin;vendor:apple;endian:little;ptrsize:8;#00
+ // $cputype:16777223;cpusubtype:3;ostype:Darwin;vendor:apple;endian:little;ptrsize:8;#00
- ArchSpec host_arch(HostInfo::GetArchitecture());
- const llvm::Triple &host_triple = host_arch.GetTriple();
- response.PutCString("triple:");
- response.PutCStringAsRawHex8(host_triple.getTriple().c_str());
- response.Printf (";ptrsize:%u;",host_arch.GetAddressByteSize());
-
- const char* distribution_id = host_arch.GetDistributionId ().AsCString ();
- if (distribution_id)
- {
- response.PutCString("distribution_id:");
- response.PutCStringAsRawHex8(distribution_id);
- response.PutCString(";");
- }
+ ArchSpec host_arch(HostInfo::GetArchitecture());
+ const llvm::Triple &host_triple = host_arch.GetTriple();
+ response.PutCString("triple:");
+ response.PutCStringAsRawHex8(host_triple.getTriple().c_str());
+ response.Printf(";ptrsize:%u;", host_arch.GetAddressByteSize());
+
+ const char *distribution_id = host_arch.GetDistributionId().AsCString();
+ if (distribution_id) {
+ response.PutCString("distribution_id:");
+ response.PutCStringAsRawHex8(distribution_id);
+ response.PutCString(";");
+ }
- // Only send out MachO info when lldb-platform/llgs is running on a MachO host.
#if defined(__APPLE__)
- uint32_t cpu = host_arch.GetMachOCPUType();
- uint32_t sub = host_arch.GetMachOCPUSubType();
- if (cpu != LLDB_INVALID_CPUTYPE)
- response.Printf ("cputype:%u;", cpu);
- if (sub != LLDB_INVALID_CPUTYPE)
- response.Printf ("cpusubtype:%u;", sub);
-
- if (cpu == ArchSpec::kCore_arm_any)
- response.Printf("watchpoint_exceptions_received:before;"); // On armv7 we use "synchronous" watchpoints which means the exception is delivered before the instruction executes.
- else
- response.Printf("watchpoint_exceptions_received:after;");
+ // For parity with debugserver, we'll include the vendor key.
+ response.PutCString("vendor:apple;");
+
+ // Send out MachO info.
+ uint32_t cpu = host_arch.GetMachOCPUType();
+ uint32_t sub = host_arch.GetMachOCPUSubType();
+ if (cpu != LLDB_INVALID_CPUTYPE)
+ response.Printf("cputype:%u;", cpu);
+ if (sub != LLDB_INVALID_CPUTYPE)
+ response.Printf("cpusubtype:%u;", sub);
+
+ if (cpu == ArchSpec::kCore_arm_any) {
+// Indicate the OS type.
+#if defined(TARGET_OS_TV) && TARGET_OS_TV == 1
+ response.PutCString("ostype:tvos;");
+#elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
+ response.PutCString("ostype:watchos;");
#else
- if (host_arch.GetMachine() == llvm::Triple::aarch64 ||
- host_arch.GetMachine() == llvm::Triple::aarch64_be ||
- host_arch.GetMachine() == llvm::Triple::arm ||
- host_arch.GetMachine() == llvm::Triple::armeb ||
- host_arch.GetMachine() == llvm::Triple::mips64 ||
- host_arch.GetMachine() == llvm::Triple::mips64el ||
- host_arch.GetMachine() == llvm::Triple::mips ||
- host_arch.GetMachine() == llvm::Triple::mipsel)
- response.Printf("watchpoint_exceptions_received:before;");
- else
- response.Printf("watchpoint_exceptions_received:after;");
+ response.PutCString("ostype:ios;");
#endif
- switch (endian::InlHostByteOrder())
- {
- case eByteOrderBig: response.PutCString ("endian:big;"); break;
- case eByteOrderLittle: response.PutCString ("endian:little;"); break;
- case eByteOrderPDP: response.PutCString ("endian:pdp;"); break;
- default: response.PutCString ("endian:unknown;"); break;
- }
+ // On arm, we use "synchronous" watchpoints which means the exception is
+ // delivered before the instruction executes.
+ response.PutCString("watchpoint_exceptions_received:before;");
+ } else {
+ response.PutCString("ostype:macosx;");
+ response.Printf("watchpoint_exceptions_received:after;");
+ }
- uint32_t major = UINT32_MAX;
- uint32_t minor = UINT32_MAX;
- uint32_t update = UINT32_MAX;
- if (HostInfo::GetOSVersion(major, minor, update))
- {
- if (major != UINT32_MAX)
- {
- response.Printf("os_version:%u", major);
- if (minor != UINT32_MAX)
- {
- response.Printf(".%u", minor);
- if (update != UINT32_MAX)
- response.Printf(".%u", update);
- }
- response.PutChar(';');
- }
- }
+#else
+ if (host_arch.GetMachine() == llvm::Triple::aarch64 ||
+ host_arch.GetMachine() == llvm::Triple::aarch64_be ||
+ host_arch.GetMachine() == llvm::Triple::arm ||
+ host_arch.GetMachine() == llvm::Triple::armeb ||
+ host_arch.GetMachine() == llvm::Triple::mips64 ||
+ host_arch.GetMachine() == llvm::Triple::mips64el ||
+ host_arch.GetMachine() == llvm::Triple::mips ||
+ host_arch.GetMachine() == llvm::Triple::mipsel)
+ response.Printf("watchpoint_exceptions_received:before;");
+ else
+ response.Printf("watchpoint_exceptions_received:after;");
+#endif
- std::string s;
- if (HostInfo::GetOSBuildString(s))
- {
- response.PutCString ("os_build:");
- response.PutCStringAsRawHex8(s.c_str());
- response.PutChar(';');
- }
- if (HostInfo::GetOSKernelDescription(s))
- {
- response.PutCString ("os_kernel:");
- response.PutCStringAsRawHex8(s.c_str());
- response.PutChar(';');
+ switch (endian::InlHostByteOrder()) {
+ case eByteOrderBig:
+ response.PutCString("endian:big;");
+ break;
+ case eByteOrderLittle:
+ response.PutCString("endian:little;");
+ break;
+ case eByteOrderPDP:
+ response.PutCString("endian:pdp;");
+ break;
+ default:
+ response.PutCString("endian:unknown;");
+ break;
+ }
+
+ uint32_t major = UINT32_MAX;
+ uint32_t minor = UINT32_MAX;
+ uint32_t update = UINT32_MAX;
+ if (HostInfo::GetOSVersion(major, minor, update)) {
+ if (major != UINT32_MAX) {
+ response.Printf("os_version:%u", major);
+ if (minor != UINT32_MAX) {
+ response.Printf(".%u", minor);
+ if (update != UINT32_MAX)
+ response.Printf(".%u", update);
+ }
+ response.PutChar(';');
}
+ }
+
+ std::string s;
+ if (HostInfo::GetOSBuildString(s)) {
+ response.PutCString("os_build:");
+ response.PutCStringAsRawHex8(s.c_str());
+ response.PutChar(';');
+ }
+ if (HostInfo::GetOSKernelDescription(s)) {
+ response.PutCString("os_kernel:");
+ response.PutCStringAsRawHex8(s.c_str());
+ response.PutChar(';');
+ }
#if defined(__APPLE__)
#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
- // For iOS devices, we are connected through a USB Mux so we never pretend
- // to actually have a hostname as far as the remote lldb that is connecting
- // to this lldb-platform is concerned
- response.PutCString ("hostname:");
- response.PutCStringAsRawHex8("127.0.0.1");
+ // For iOS devices, we are connected through a USB Mux so we never pretend
+ // to actually have a hostname as far as the remote lldb that is connecting
+ // to this lldb-platform is concerned
+ response.PutCString("hostname:");
+ response.PutCStringAsRawHex8("127.0.0.1");
+ response.PutChar(';');
+#else // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
+ if (HostInfo::GetHostname(s)) {
+ response.PutCString("hostname:");
+ response.PutCStringAsRawHex8(s.c_str());
response.PutChar(';');
-#else // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
- if (HostInfo::GetHostname(s))
- {
- response.PutCString ("hostname:");
- response.PutCStringAsRawHex8(s.c_str());
- response.PutChar(';');
- }
-#endif // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
+ }
+#endif // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
-#else // #if defined(__APPLE__)
- if (HostInfo::GetHostname(s))
- {
- response.PutCString ("hostname:");
- response.PutCStringAsRawHex8(s.c_str());
- response.PutChar(';');
- }
-#endif // #if defined(__APPLE__)
+#else // #if defined(__APPLE__)
+ if (HostInfo::GetHostname(s)) {
+ response.PutCString("hostname:");
+ response.PutCStringAsRawHex8(s.c_str());
+ response.PutChar(';');
+ }
+#endif // #if defined(__APPLE__)
- if (g_default_packet_timeout_sec > 0)
- response.Printf ("default_packet_timeout:%u;", g_default_packet_timeout_sec);
+ if (g_default_packet_timeout_sec > 0)
+ response.Printf("default_packet_timeout:%u;", g_default_packet_timeout_sec);
- return SendPacketNoLock (response.GetData(), response.GetSize());
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qProcessInfoPID (StringExtractorGDBRemote &packet)
-{
- // Packet format: "qProcessInfoPID:%i" where %i is the pid
- packet.SetFilePos (::strlen ("qProcessInfoPID:"));
- lldb::pid_t pid = packet.GetU32 (LLDB_INVALID_PROCESS_ID);
- if (pid != LLDB_INVALID_PROCESS_ID)
- {
- ProcessInstanceInfo proc_info;
- if (Host::GetProcessInfo (pid, proc_info))
- {
- StreamString response;
- CreateProcessInfoResponse (proc_info, response);
- return SendPacketNoLock (response.GetData(), response.GetSize());
- }
+GDBRemoteCommunicationServerCommon::Handle_qProcessInfoPID(
+ StringExtractorGDBRemote &packet) {
+ // Packet format: "qProcessInfoPID:%i" where %i is the pid
+ packet.SetFilePos(::strlen("qProcessInfoPID:"));
+ lldb::pid_t pid = packet.GetU32(LLDB_INVALID_PROCESS_ID);
+ if (pid != LLDB_INVALID_PROCESS_ID) {
+ ProcessInstanceInfo proc_info;
+ if (Host::GetProcessInfo(pid, proc_info)) {
+ StreamString response;
+ CreateProcessInfoResponse(proc_info, response);
+ return SendPacketNoLock(response.GetString());
}
- return SendErrorResponse (1);
+ }
+ return SendErrorResponse(1);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo (StringExtractorGDBRemote &packet)
-{
- m_proc_infos_index = 0;
- m_proc_infos.Clear();
-
- ProcessInstanceInfoMatch match_info;
- packet.SetFilePos(::strlen ("qfProcessInfo"));
- if (packet.GetChar() == ':')
- {
-
- std::string key;
- std::string value;
- while (packet.GetNameColonValue(key, value))
- {
- bool success = true;
- if (key.compare("name") == 0)
- {
- StringExtractor extractor;
- extractor.GetStringRef().swap(value);
- extractor.GetHexByteString (value);
- match_info.GetProcessInfo().GetExecutableFile().SetFile(value.c_str(), false);
- }
- else if (key.compare("name_match") == 0)
- {
- if (value.compare("equals") == 0)
- {
- match_info.SetNameMatchType (eNameMatchEquals);
- }
- else if (value.compare("starts_with") == 0)
- {
- match_info.SetNameMatchType (eNameMatchStartsWith);
- }
- else if (value.compare("ends_with") == 0)
- {
- match_info.SetNameMatchType (eNameMatchEndsWith);
- }
- else if (value.compare("contains") == 0)
- {
- match_info.SetNameMatchType (eNameMatchContains);
- }
- else if (value.compare("regex") == 0)
- {
- match_info.SetNameMatchType (eNameMatchRegularExpression);
- }
- else
- {
- success = false;
- }
- }
- else if (key.compare("pid") == 0)
- {
- match_info.GetProcessInfo().SetProcessID (StringConvert::ToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success));
- }
- else if (key.compare("parent_pid") == 0)
- {
- match_info.GetProcessInfo().SetParentProcessID (StringConvert::ToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success));
- }
- else if (key.compare("uid") == 0)
- {
- match_info.GetProcessInfo().SetUserID (StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0, &success));
- }
- else if (key.compare("gid") == 0)
- {
- match_info.GetProcessInfo().SetGroupID (StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0, &success));
- }
- else if (key.compare("euid") == 0)
- {
- match_info.GetProcessInfo().SetEffectiveUserID (StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0, &success));
- }
- else if (key.compare("egid") == 0)
- {
- match_info.GetProcessInfo().SetEffectiveGroupID (StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0, &success));
- }
- else if (key.compare("all_users") == 0)
- {
- match_info.SetMatchAllUsers(Args::StringToBoolean(value.c_str(), false, &success));
- }
- else if (key.compare("triple") == 0)
- {
- match_info.GetProcessInfo().GetArchitecture().SetTriple (value.c_str(), NULL);
- }
- else
- {
- success = false;
- }
-
- if (!success)
- return SendErrorResponse (2);
- }
- }
-
- if (Host::FindProcesses (match_info, m_proc_infos))
- {
- // We found something, return the first item by calling the get
- // subsequent process info packet handler...
- return Handle_qsProcessInfo (packet);
+GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo(
+ StringExtractorGDBRemote &packet) {
+ m_proc_infos_index = 0;
+ m_proc_infos.Clear();
+
+ ProcessInstanceInfoMatch match_info;
+ packet.SetFilePos(::strlen("qfProcessInfo"));
+ if (packet.GetChar() == ':') {
+ llvm::StringRef key;
+ llvm::StringRef value;
+ while (packet.GetNameColonValue(key, value)) {
+ bool success = true;
+ if (key.equals("name")) {
+ StringExtractor extractor(value);
+ std::string file;
+ extractor.GetHexByteString(file);
+ match_info.GetProcessInfo().GetExecutableFile().SetFile(file, false);
+ } else if (key.equals("name_match")) {
+ NameMatchType name_match =
+ llvm::StringSwitch<NameMatchType>(value)
+ .Case("equals", eNameMatchEquals)
+ .Case("starts_with", eNameMatchStartsWith)
+ .Case("ends_with", eNameMatchEndsWith)
+ .Case("contains", eNameMatchContains)
+ .Case("regex", eNameMatchRegularExpression)
+ .Default(eNameMatchIgnore);
+ match_info.SetNameMatchType(name_match);
+ if (name_match == eNameMatchIgnore)
+ return SendErrorResponse(2);
+ } else if (key.equals("pid")) {
+ lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
+ if (value.getAsInteger(0, pid))
+ return SendErrorResponse(2);
+ match_info.GetProcessInfo().SetProcessID(pid);
+ } else if (key.equals("parent_pid")) {
+ lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
+ if (value.getAsInteger(0, pid))
+ return SendErrorResponse(2);
+ match_info.GetProcessInfo().SetParentProcessID(pid);
+ } else if (key.equals("uid")) {
+ uint32_t uid = UINT32_MAX;
+ if (value.getAsInteger(0, uid))
+ return SendErrorResponse(2);
+ match_info.GetProcessInfo().SetUserID(uid);
+ } else if (key.equals("gid")) {
+ uint32_t gid = UINT32_MAX;
+ if (value.getAsInteger(0, gid))
+ return SendErrorResponse(2);
+ match_info.GetProcessInfo().SetGroupID(gid);
+ } else if (key.equals("euid")) {
+ uint32_t uid = UINT32_MAX;
+ if (value.getAsInteger(0, uid))
+ return SendErrorResponse(2);
+ match_info.GetProcessInfo().SetEffectiveUserID(uid);
+ } else if (key.equals("egid")) {
+ uint32_t gid = UINT32_MAX;
+ if (value.getAsInteger(0, gid))
+ return SendErrorResponse(2);
+ match_info.GetProcessInfo().SetEffectiveGroupID(gid);
+ } else if (key.equals("all_users")) {
+ match_info.SetMatchAllUsers(
+ Args::StringToBoolean(value, false, &success));
+ } else if (key.equals("triple")) {
+ match_info.GetProcessInfo().GetArchitecture().SetTriple(
+ value.str().c_str(), NULL);
+ } else {
+ success = false;
+ }
+
+ if (!success)
+ return SendErrorResponse(2);
}
- return SendErrorResponse (3);
+ }
+
+ if (Host::FindProcesses(match_info, m_proc_infos)) {
+ // We found something, return the first item by calling the get
+ // subsequent process info packet handler...
+ return Handle_qsProcessInfo(packet);
+ }
+ return SendErrorResponse(3);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo (StringExtractorGDBRemote &packet)
-{
- if (m_proc_infos_index < m_proc_infos.GetSize())
- {
- StreamString response;
- CreateProcessInfoResponse (m_proc_infos.GetProcessInfoAtIndex(m_proc_infos_index), response);
- ++m_proc_infos_index;
- return SendPacketNoLock (response.GetData(), response.GetSize());
- }
- return SendErrorResponse (4);
+GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo(
+ StringExtractorGDBRemote &packet) {
+ if (m_proc_infos_index < m_proc_infos.GetSize()) {
+ StreamString response;
+ CreateProcessInfoResponse(
+ m_proc_infos.GetProcessInfoAtIndex(m_proc_infos_index), response);
+ ++m_proc_infos_index;
+ return SendPacketNoLock(response.GetString());
+ }
+ return SendErrorResponse(4);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qUserName (StringExtractorGDBRemote &packet)
-{
+GDBRemoteCommunicationServerCommon::Handle_qUserName(
+ StringExtractorGDBRemote &packet) {
#if !defined(LLDB_DISABLE_POSIX)
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("GDBRemoteCommunicationServerCommon::%s begin", __FUNCTION__);
-
- // Packet format: "qUserName:%i" where %i is the uid
- packet.SetFilePos(::strlen ("qUserName:"));
- uint32_t uid = packet.GetU32 (UINT32_MAX);
- if (uid != UINT32_MAX)
- {
- std::string name;
- if (HostInfo::LookupUserName(uid, name))
- {
- StreamString response;
- response.PutCStringAsRawHex8 (name.c_str());
- return SendPacketNoLock (response.GetData(), response.GetSize());
- }
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerCommon::%s begin", __FUNCTION__);
+
+ // Packet format: "qUserName:%i" where %i is the uid
+ packet.SetFilePos(::strlen("qUserName:"));
+ uint32_t uid = packet.GetU32(UINT32_MAX);
+ if (uid != UINT32_MAX) {
+ std::string name;
+ if (HostInfo::LookupUserName(uid, name)) {
+ StreamString response;
+ response.PutCStringAsRawHex8(name.c_str());
+ return SendPacketNoLock(response.GetString());
}
- if (log)
- log->Printf("GDBRemoteCommunicationServerCommon::%s end", __FUNCTION__);
+ }
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerCommon::%s end", __FUNCTION__);
#endif
- return SendErrorResponse (5);
-
+ return SendErrorResponse(5);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qGroupName (StringExtractorGDBRemote &packet)
-{
+GDBRemoteCommunicationServerCommon::Handle_qGroupName(
+ StringExtractorGDBRemote &packet) {
#if !defined(LLDB_DISABLE_POSIX)
- // Packet format: "qGroupName:%i" where %i is the gid
- packet.SetFilePos(::strlen ("qGroupName:"));
- uint32_t gid = packet.GetU32 (UINT32_MAX);
- if (gid != UINT32_MAX)
- {
- std::string name;
- if (HostInfo::LookupGroupName(gid, name))
- {
- StreamString response;
- response.PutCStringAsRawHex8 (name.c_str());
- return SendPacketNoLock (response.GetData(), response.GetSize());
- }
+ // Packet format: "qGroupName:%i" where %i is the gid
+ packet.SetFilePos(::strlen("qGroupName:"));
+ uint32_t gid = packet.GetU32(UINT32_MAX);
+ if (gid != UINT32_MAX) {
+ std::string name;
+ if (HostInfo::LookupGroupName(gid, name)) {
+ StreamString response;
+ response.PutCStringAsRawHex8(name.c_str());
+ return SendPacketNoLock(response.GetString());
}
+ }
#endif
- return SendErrorResponse (6);
+ return SendErrorResponse(6);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qSpeedTest (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen ("qSpeedTest:"));
-
- std::string key;
- std::string value;
- bool success = packet.GetNameColonValue(key, value);
- if (success && key.compare("response_size") == 0)
- {
- uint32_t response_size = StringConvert::ToUInt32(value.c_str(), 0, 0, &success);
- if (success)
- {
- if (response_size == 0)
- return SendOKResponse();
- StreamString response;
- uint32_t bytes_left = response_size;
- response.PutCString("data:");
- while (bytes_left > 0)
- {
- if (bytes_left >= 26)
- {
- response.PutCString("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
- bytes_left -= 26;
- }
- else
- {
- response.Printf ("%*.*s;", bytes_left, bytes_left, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
- bytes_left = 0;
- }
- }
- return SendPacketNoLock (response.GetData(), response.GetSize());
+GDBRemoteCommunicationServerCommon::Handle_qSpeedTest(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("qSpeedTest:"));
+
+ llvm::StringRef key;
+ llvm::StringRef value;
+ bool success = packet.GetNameColonValue(key, value);
+ if (success && key.equals("response_size")) {
+ uint32_t response_size = 0;
+ if (!value.getAsInteger(0, response_size)) {
+ if (response_size == 0)
+ return SendOKResponse();
+ StreamString response;
+ uint32_t bytes_left = response_size;
+ response.PutCString("data:");
+ while (bytes_left > 0) {
+ if (bytes_left >= 26) {
+ response.PutCString("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+ bytes_left -= 26;
+ } else {
+ response.Printf("%*.*s;", bytes_left, bytes_left,
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+ bytes_left = 0;
}
+ }
+ return SendPacketNoLock(response.GetString());
}
- return SendErrorResponse (7);
+ }
+ return SendErrorResponse(7);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_Open (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen("vFile:open:"));
- std::string path;
- packet.GetHexByteStringTerminatedBy(path,',');
- if (!path.empty())
- {
- if (packet.GetChar() == ',')
- {
- uint32_t flags = File::ConvertOpenOptionsForPOSIXOpen(
- packet.GetHexMaxU32(false, 0));
- if (packet.GetChar() == ',')
- {
- mode_t mode = packet.GetHexMaxU32(false, 0600);
- Error error;
- const FileSpec path_spec{path, true};
- int fd = ::open(path_spec.GetCString(), flags, mode);
- const int save_errno = fd == -1 ? errno : 0;
- StreamString response;
- response.PutChar('F');
- response.Printf("%i", fd);
- if (save_errno)
- response.Printf(",%i", save_errno);
- return SendPacketNoLock(response.GetData(), response.GetSize());
- }
- }
+GDBRemoteCommunicationServerCommon::Handle_vFile_Open(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("vFile:open:"));
+ std::string path;
+ packet.GetHexByteStringTerminatedBy(path, ',');
+ if (!path.empty()) {
+ if (packet.GetChar() == ',') {
+ uint32_t flags =
+ File::ConvertOpenOptionsForPOSIXOpen(packet.GetHexMaxU32(false, 0));
+ if (packet.GetChar() == ',') {
+ mode_t mode = packet.GetHexMaxU32(false, 0600);
+ Error error;
+ const FileSpec path_spec{path, true};
+ int fd = ::open(path_spec.GetCString(), flags, mode);
+ const int save_errno = fd == -1 ? errno : 0;
+ StreamString response;
+ response.PutChar('F');
+ response.Printf("%i", fd);
+ if (save_errno)
+ response.Printf(",%i", save_errno);
+ return SendPacketNoLock(response.GetString());
+ }
}
- return SendErrorResponse(18);
+ }
+ return SendErrorResponse(18);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_Close (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen("vFile:close:"));
- int fd = packet.GetS32(-1);
- Error error;
- int err = -1;
- int save_errno = 0;
- if (fd >= 0)
- {
- err = close(fd);
- save_errno = err == -1 ? errno : 0;
- }
- else
- {
- save_errno = EINVAL;
- }
- StreamString response;
- response.PutChar('F');
- response.Printf("%i", err);
- if (save_errno)
- response.Printf(",%i", save_errno);
- return SendPacketNoLock(response.GetData(), response.GetSize());
+GDBRemoteCommunicationServerCommon::Handle_vFile_Close(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("vFile:close:"));
+ int fd = packet.GetS32(-1);
+ Error error;
+ int err = -1;
+ int save_errno = 0;
+ if (fd >= 0) {
+ err = close(fd);
+ save_errno = err == -1 ? errno : 0;
+ } else {
+ save_errno = EINVAL;
+ }
+ StreamString response;
+ response.PutChar('F');
+ response.Printf("%i", err);
+ if (save_errno)
+ response.Printf(",%i", save_errno);
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_pRead (StringExtractorGDBRemote &packet)
-{
+GDBRemoteCommunicationServerCommon::Handle_vFile_pRead(
+ StringExtractorGDBRemote &packet) {
#ifdef _WIN32
- // Not implemented on Windows
- return SendUnimplementedResponse("GDBRemoteCommunicationServerCommon::Handle_vFile_pRead() unimplemented");
+ // Not implemented on Windows
+ return SendUnimplementedResponse(
+ "GDBRemoteCommunicationServerCommon::Handle_vFile_pRead() unimplemented");
#else
- StreamGDBRemote response;
- packet.SetFilePos(::strlen("vFile:pread:"));
- int fd = packet.GetS32(-1);
- if (packet.GetChar() == ',')
- {
- uint64_t count = packet.GetU64(UINT64_MAX);
- if (packet.GetChar() == ',')
- {
- uint64_t offset = packet.GetU64(UINT32_MAX);
- if (count == UINT64_MAX)
- {
- response.Printf("F-1:%i", EINVAL);
- return SendPacketNoLock(response.GetData(), response.GetSize());
- }
-
- std::string buffer(count, 0);
- const ssize_t bytes_read = ::pread (fd, &buffer[0], buffer.size(), offset);
- const int save_errno = bytes_read == -1 ? errno : 0;
- response.PutChar('F');
- response.Printf("%zi", bytes_read);
- if (save_errno)
- response.Printf(",%i", save_errno);
- else
- {
- response.PutChar(';');
- response.PutEscapedBytes(&buffer[0], bytes_read);
- }
- return SendPacketNoLock(response.GetData(), response.GetSize());
- }
+ StreamGDBRemote response;
+ packet.SetFilePos(::strlen("vFile:pread:"));
+ int fd = packet.GetS32(-1);
+ if (packet.GetChar() == ',') {
+ uint64_t count = packet.GetU64(UINT64_MAX);
+ if (packet.GetChar() == ',') {
+ uint64_t offset = packet.GetU64(UINT32_MAX);
+ if (count == UINT64_MAX) {
+ response.Printf("F-1:%i", EINVAL);
+ return SendPacketNoLock(response.GetString());
+ }
+
+ std::string buffer(count, 0);
+ const ssize_t bytes_read = ::pread(fd, &buffer[0], buffer.size(), offset);
+ const int save_errno = bytes_read == -1 ? errno : 0;
+ response.PutChar('F');
+ response.Printf("%zi", bytes_read);
+ if (save_errno)
+ response.Printf(",%i", save_errno);
+ else {
+ response.PutChar(';');
+ response.PutEscapedBytes(&buffer[0], bytes_read);
+ }
+ return SendPacketNoLock(response.GetString());
}
- return SendErrorResponse(21);
+ }
+ return SendErrorResponse(21);
#endif
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite (StringExtractorGDBRemote &packet)
-{
+GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite(
+ StringExtractorGDBRemote &packet) {
#ifdef _WIN32
- return SendUnimplementedResponse("GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite() unimplemented");
+ return SendUnimplementedResponse("GDBRemoteCommunicationServerCommon::Handle_"
+ "vFile_pWrite() unimplemented");
#else
- packet.SetFilePos(::strlen("vFile:pwrite:"));
-
- StreamGDBRemote response;
- response.PutChar('F');
-
- int fd = packet.GetU32(UINT32_MAX);
- if (packet.GetChar() == ',')
- {
- off_t offset = packet.GetU64(UINT32_MAX);
- if (packet.GetChar() == ',')
- {
- std::string buffer;
- if (packet.GetEscapedBinaryData(buffer))
- {
- const ssize_t bytes_written = ::pwrite (fd, buffer.data(), buffer.size(), offset);
- const int save_errno = bytes_written == -1 ? errno : 0;
- response.Printf("%zi", bytes_written);
- if (save_errno)
- response.Printf(",%i", save_errno);
- }
- else
- {
- response.Printf ("-1,%i", EINVAL);
- }
- return SendPacketNoLock(response.GetData(), response.GetSize());
- }
+ packet.SetFilePos(::strlen("vFile:pwrite:"));
+
+ StreamGDBRemote response;
+ response.PutChar('F');
+
+ int fd = packet.GetU32(UINT32_MAX);
+ if (packet.GetChar() == ',') {
+ off_t offset = packet.GetU64(UINT32_MAX);
+ if (packet.GetChar() == ',') {
+ std::string buffer;
+ if (packet.GetEscapedBinaryData(buffer)) {
+ const ssize_t bytes_written =
+ ::pwrite(fd, buffer.data(), buffer.size(), offset);
+ const int save_errno = bytes_written == -1 ? errno : 0;
+ response.Printf("%zi", bytes_written);
+ if (save_errno)
+ response.Printf(",%i", save_errno);
+ } else {
+ response.Printf("-1,%i", EINVAL);
+ }
+ return SendPacketNoLock(response.GetString());
}
- return SendErrorResponse(27);
+ }
+ return SendErrorResponse(27);
#endif
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_Size (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen("vFile:size:"));
- std::string path;
- packet.GetHexByteString(path);
- if (!path.empty())
- {
- lldb::user_id_t retcode = FileSystem::GetFileSize(FileSpec(path.c_str(), false));
- StreamString response;
- response.PutChar('F');
- response.PutHex64(retcode);
- if (retcode == UINT64_MAX)
- {
- response.PutChar(',');
- response.PutHex64(retcode); // TODO: replace with Host::GetSyswideErrorCode()
- }
- return SendPacketNoLock(response.GetData(), response.GetSize());
+GDBRemoteCommunicationServerCommon::Handle_vFile_Size(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("vFile:size:"));
+ std::string path;
+ packet.GetHexByteString(path);
+ if (!path.empty()) {
+ lldb::user_id_t retcode = FileSystem::GetFileSize(FileSpec(path, false));
+ StreamString response;
+ response.PutChar('F');
+ response.PutHex64(retcode);
+ if (retcode == UINT64_MAX) {
+ response.PutChar(',');
+ response.PutHex64(
+ retcode); // TODO: replace with Host::GetSyswideErrorCode()
}
- return SendErrorResponse(22);
+ return SendPacketNoLock(response.GetString());
+ }
+ return SendErrorResponse(22);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_Mode (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen("vFile:mode:"));
- std::string path;
- packet.GetHexByteString(path);
- if (!path.empty())
- {
- Error error;
- const uint32_t mode = File::GetPermissions(FileSpec{path, true}, error);
- StreamString response;
- response.Printf("F%u", mode);
- if (mode == 0 || error.Fail())
- response.Printf(",%i", (int)error.GetError());
- return SendPacketNoLock(response.GetData(), response.GetSize());
- }
- return SendErrorResponse(23);
+GDBRemoteCommunicationServerCommon::Handle_vFile_Mode(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("vFile:mode:"));
+ std::string path;
+ packet.GetHexByteString(path);
+ if (!path.empty()) {
+ Error error;
+ const uint32_t mode = File::GetPermissions(FileSpec{path, true}, error);
+ StreamString response;
+ response.Printf("F%u", mode);
+ if (mode == 0 || error.Fail())
+ response.Printf(",%i", (int)error.GetError());
+ return SendPacketNoLock(response.GetString());
+ }
+ return SendErrorResponse(23);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_Exists (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen("vFile:exists:"));
- std::string path;
- packet.GetHexByteString(path);
- if (!path.empty())
- {
- bool retcode = FileSystem::GetFileExists(FileSpec(path.c_str(), false));
- StreamString response;
- response.PutChar('F');
- response.PutChar(',');
- if (retcode)
- response.PutChar('1');
- else
- response.PutChar('0');
- return SendPacketNoLock(response.GetData(), response.GetSize());
- }
- return SendErrorResponse(24);
+GDBRemoteCommunicationServerCommon::Handle_vFile_Exists(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("vFile:exists:"));
+ std::string path;
+ packet.GetHexByteString(path);
+ if (!path.empty()) {
+ bool retcode = FileSystem::GetFileExists(FileSpec(path, false));
+ StreamString response;
+ response.PutChar('F');
+ response.PutChar(',');
+ if (retcode)
+ response.PutChar('1');
+ else
+ response.PutChar('0');
+ return SendPacketNoLock(response.GetString());
+ }
+ return SendErrorResponse(24);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_symlink (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen("vFile:symlink:"));
- std::string dst, src;
- packet.GetHexByteStringTerminatedBy(dst, ',');
- packet.GetChar(); // Skip ',' char
- packet.GetHexByteString(src);
- Error error = FileSystem::Symlink(FileSpec{src, true}, FileSpec{dst, false});
- StreamString response;
- response.Printf("F%u,%u", error.GetError(), error.GetError());
- return SendPacketNoLock(response.GetData(), response.GetSize());
+GDBRemoteCommunicationServerCommon::Handle_vFile_symlink(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("vFile:symlink:"));
+ std::string dst, src;
+ packet.GetHexByteStringTerminatedBy(dst, ',');
+ packet.GetChar(); // Skip ',' char
+ packet.GetHexByteString(src);
+ Error error = FileSystem::Symlink(FileSpec{src, true}, FileSpec{dst, false});
+ StreamString response;
+ response.Printf("F%u,%u", error.GetError(), error.GetError());
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_unlink (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen("vFile:unlink:"));
- std::string path;
- packet.GetHexByteString(path);
- Error error = FileSystem::Unlink(FileSpec{path, true});
- StreamString response;
- response.Printf("F%u,%u", error.GetError(), error.GetError());
- return SendPacketNoLock(response.GetData(), response.GetSize());
+GDBRemoteCommunicationServerCommon::Handle_vFile_unlink(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("vFile:unlink:"));
+ std::string path;
+ packet.GetHexByteString(path);
+ Error error = FileSystem::Unlink(FileSpec{path, true});
+ StreamString response;
+ response.Printf("F%u,%u", error.GetError(), error.GetError());
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen("qPlatform_shell:"));
- std::string path;
- std::string working_dir;
- packet.GetHexByteStringTerminatedBy(path,',');
- if (!path.empty())
- {
- if (packet.GetChar() == ',')
- {
- // FIXME: add timeout to qPlatform_shell packet
- // uint32_t timeout = packet.GetHexMaxU32(false, 32);
- uint32_t timeout = 10;
- if (packet.GetChar() == ',')
- packet.GetHexByteString(working_dir);
- int status, signo;
- std::string output;
- Error err = Host::RunShellCommand(path.c_str(),
- FileSpec{working_dir, true},
- &status, &signo, &output, timeout);
- StreamGDBRemote response;
- if (err.Fail())
- {
- response.PutCString("F,");
- response.PutHex32(UINT32_MAX);
- }
- else
- {
- response.PutCString("F,");
- response.PutHex32(status);
- response.PutChar(',');
- response.PutHex32(signo);
- response.PutChar(',');
- response.PutEscapedBytes(output.c_str(), output.size());
- }
- return SendPacketNoLock(response.GetData(), response.GetSize());
- }
+GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("qPlatform_shell:"));
+ std::string path;
+ std::string working_dir;
+ packet.GetHexByteStringTerminatedBy(path, ',');
+ if (!path.empty()) {
+ if (packet.GetChar() == ',') {
+ // FIXME: add timeout to qPlatform_shell packet
+ // uint32_t timeout = packet.GetHexMaxU32(false, 32);
+ uint32_t timeout = 10;
+ if (packet.GetChar() == ',')
+ packet.GetHexByteString(working_dir);
+ int status, signo;
+ std::string output;
+ Error err =
+ Host::RunShellCommand(path.c_str(), FileSpec{working_dir, true},
+ &status, &signo, &output, timeout);
+ StreamGDBRemote response;
+ if (err.Fail()) {
+ response.PutCString("F,");
+ response.PutHex32(UINT32_MAX);
+ } else {
+ response.PutCString("F,");
+ response.PutHex32(status);
+ response.PutChar(',');
+ response.PutHex32(signo);
+ response.PutChar(',');
+ response.PutEscapedBytes(output.c_str(), output.size());
+ }
+ return SendPacketNoLock(response.GetString());
}
- return SendErrorResponse(24);
+ }
+ return SendErrorResponse(24);
}
-
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_Stat (StringExtractorGDBRemote &packet)
-{
- return SendUnimplementedResponse("GDBRemoteCommunicationServerCommon::Handle_vFile_Stat() unimplemented");
+GDBRemoteCommunicationServerCommon::Handle_vFile_Stat(
+ StringExtractorGDBRemote &packet) {
+ return SendUnimplementedResponse(
+ "GDBRemoteCommunicationServerCommon::Handle_vFile_Stat() unimplemented");
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_MD5 (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen("vFile:MD5:"));
- std::string path;
- packet.GetHexByteString(path);
- if (!path.empty())
- {
- uint64_t a,b;
- StreamGDBRemote response;
- if (!FileSystem::CalculateMD5(FileSpec(path.c_str(), false), a, b))
- {
- response.PutCString("F,");
- response.PutCString("x");
- }
- else
- {
- response.PutCString("F,");
- response.PutHex64(a);
- response.PutHex64(b);
- }
- return SendPacketNoLock(response.GetData(), response.GetSize());
+GDBRemoteCommunicationServerCommon::Handle_vFile_MD5(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("vFile:MD5:"));
+ std::string path;
+ packet.GetHexByteString(path);
+ if (!path.empty()) {
+ uint64_t a, b;
+ StreamGDBRemote response;
+ if (!FileSystem::CalculateMD5(FileSpec(path, false), a, b)) {
+ response.PutCString("F,");
+ response.PutCString("x");
+ } else {
+ response.PutCString("F,");
+ response.PutHex64(a);
+ response.PutHex64(b);
}
- return SendErrorResponse(25);
+ return SendPacketNoLock(response.GetString());
+ }
+ return SendErrorResponse(25);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen("qPlatform_mkdir:"));
- mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX);
- if (packet.GetChar() == ',')
- {
- std::string path;
- packet.GetHexByteString(path);
- Error error = FileSystem::MakeDirectory(FileSpec{path, false}, mode);
-
- StreamGDBRemote response;
- response.Printf("F%u", error.GetError());
-
- return SendPacketNoLock(response.GetData(), response.GetSize());
- }
- return SendErrorResponse(20);
+GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("qPlatform_mkdir:"));
+ mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX);
+ if (packet.GetChar() == ',') {
+ std::string path;
+ packet.GetHexByteString(path);
+ Error error = FileSystem::MakeDirectory(FileSpec{path, false}, mode);
+
+ StreamGDBRemote response;
+ response.Printf("F%u", error.GetError());
+
+ return SendPacketNoLock(response.GetString());
+ }
+ return SendErrorResponse(20);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen("qPlatform_chmod:"));
+GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("qPlatform_chmod:"));
- mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX);
- if (packet.GetChar() == ',')
- {
- std::string path;
- packet.GetHexByteString(path);
- Error error = FileSystem::SetFilePermissions(FileSpec{path, true}, mode);
+ mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX);
+ if (packet.GetChar() == ',') {
+ std::string path;
+ packet.GetHexByteString(path);
+ Error error = FileSystem::SetFilePermissions(FileSpec{path, true}, mode);
- StreamGDBRemote response;
- response.Printf("F%u", error.GetError());
+ StreamGDBRemote response;
+ response.Printf("F%u", error.GetError());
- return SendPacketNoLock(response.GetData(), response.GetSize());
- }
- return SendErrorResponse(19);
+ return SendPacketNoLock(response.GetString());
+ }
+ return SendErrorResponse(19);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qSupported (StringExtractorGDBRemote &packet)
-{
- StreamGDBRemote response;
-
- // Features common to lldb-platform and llgs.
- uint32_t max_packet_size = 128 * 1024; // 128KBytes is a reasonable max packet size--debugger can always use less
- response.Printf ("PacketSize=%x", max_packet_size);
-
- response.PutCString (";QStartNoAckMode+");
- response.PutCString (";QThreadSuffixSupported+");
- response.PutCString (";QListThreadsInStopReply+");
- response.PutCString (";qEcho+");
+GDBRemoteCommunicationServerCommon::Handle_qSupported(
+ StringExtractorGDBRemote &packet) {
+ StreamGDBRemote response;
+
+ // Features common to lldb-platform and llgs.
+ uint32_t max_packet_size = 128 * 1024; // 128KBytes is a reasonable max packet
+ // size--debugger can always use less
+ response.Printf("PacketSize=%x", max_packet_size);
+
+ response.PutCString(";QStartNoAckMode+");
+ response.PutCString(";QThreadSuffixSupported+");
+ response.PutCString(";QListThreadsInStopReply+");
+ response.PutCString(";qEcho+");
#if defined(__linux__)
- response.PutCString (";qXfer:auxv:read+");
+ response.PutCString(";qXfer:auxv:read+");
#endif
- return SendPacketNoLock(response.GetData(), response.GetSize());
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QThreadSuffixSupported (StringExtractorGDBRemote &packet)
-{
- m_thread_suffix_supported = true;
- return SendOKResponse();
+GDBRemoteCommunicationServerCommon::Handle_QThreadSuffixSupported(
+ StringExtractorGDBRemote &packet) {
+ m_thread_suffix_supported = true;
+ return SendOKResponse();
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QListThreadsInStopReply (StringExtractorGDBRemote &packet)
-{
- m_list_threads_in_stop_reply = true;
- return SendOKResponse();
+GDBRemoteCommunicationServerCommon::Handle_QListThreadsInStopReply(
+ StringExtractorGDBRemote &packet) {
+ m_list_threads_in_stop_reply = true;
+ return SendOKResponse();
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QSetDetachOnError (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen ("QSetDetachOnError:"));
- if (packet.GetU32(0))
- m_process_launch_info.GetFlags().Set (eLaunchFlagDetachOnError);
- else
- m_process_launch_info.GetFlags().Clear (eLaunchFlagDetachOnError);
- return SendOKResponse ();
+GDBRemoteCommunicationServerCommon::Handle_QSetDetachOnError(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("QSetDetachOnError:"));
+ if (packet.GetU32(0))
+ m_process_launch_info.GetFlags().Set(eLaunchFlagDetachOnError);
+ else
+ m_process_launch_info.GetFlags().Clear(eLaunchFlagDetachOnError);
+ return SendOKResponse();
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QStartNoAckMode (StringExtractorGDBRemote &packet)
-{
- // Send response first before changing m_send_acks to we ack this packet
- PacketResult packet_result = SendOKResponse ();
- m_send_acks = false;
- return packet_result;
+GDBRemoteCommunicationServerCommon::Handle_QStartNoAckMode(
+ StringExtractorGDBRemote &packet) {
+ // Send response first before changing m_send_acks to we ack this packet
+ PacketResult packet_result = SendOKResponse();
+ m_send_acks = false;
+ return packet_result;
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen ("QSetSTDIN:"));
- FileAction file_action;
- std::string path;
- packet.GetHexByteString(path);
- const bool read = false;
- const bool write = true;
- if (file_action.Open(STDIN_FILENO, FileSpec{path, false}, read, write))
- {
- m_process_launch_info.AppendFileAction(file_action);
- return SendOKResponse ();
- }
- return SendErrorResponse (15);
+GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("QSetSTDIN:"));
+ FileAction file_action;
+ std::string path;
+ packet.GetHexByteString(path);
+ const bool read = true;
+ const bool write = false;
+ if (file_action.Open(STDIN_FILENO, FileSpec{path, false}, read, write)) {
+ m_process_launch_info.AppendFileAction(file_action);
+ return SendOKResponse();
+ }
+ return SendErrorResponse(15);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen ("QSetSTDOUT:"));
- FileAction file_action;
- std::string path;
- packet.GetHexByteString(path);
- const bool read = true;
- const bool write = false;
- if (file_action.Open(STDOUT_FILENO, FileSpec{path, false}, read, write))
- {
- m_process_launch_info.AppendFileAction(file_action);
- return SendOKResponse ();
- }
- return SendErrorResponse (16);
+GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("QSetSTDOUT:"));
+ FileAction file_action;
+ std::string path;
+ packet.GetHexByteString(path);
+ const bool read = false;
+ const bool write = true;
+ if (file_action.Open(STDOUT_FILENO, FileSpec{path, false}, read, write)) {
+ m_process_launch_info.AppendFileAction(file_action);
+ return SendOKResponse();
+ }
+ return SendErrorResponse(16);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen ("QSetSTDERR:"));
- FileAction file_action;
- std::string path;
- packet.GetHexByteString(path);
- const bool read = true;
- const bool write = false;
- if (file_action.Open(STDERR_FILENO, FileSpec{path, false}, read, write))
- {
- m_process_launch_info.AppendFileAction(file_action);
- return SendOKResponse ();
- }
- return SendErrorResponse (17);
+GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("QSetSTDERR:"));
+ FileAction file_action;
+ std::string path;
+ packet.GetHexByteString(path);
+ const bool read = false;
+ const bool write = true;
+ if (file_action.Open(STDERR_FILENO, FileSpec{path, false}, read, write)) {
+ m_process_launch_info.AppendFileAction(file_action);
+ return SendOKResponse();
+ }
+ return SendErrorResponse(17);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess (StringExtractorGDBRemote &packet)
-{
- if (m_process_launch_error.Success())
- return SendOKResponse();
- StreamString response;
- response.PutChar('E');
- response.PutCString(m_process_launch_error.AsCString("<unknown error>"));
- return SendPacketNoLock (response.GetData(), response.GetSize());
+GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess(
+ StringExtractorGDBRemote &packet) {
+ if (m_process_launch_error.Success())
+ return SendOKResponse();
+ StreamString response;
+ response.PutChar('E');
+ response.PutCString(m_process_launch_error.AsCString("<unknown error>"));
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QEnvironment (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen ("QEnvironment:"));
- const uint32_t bytes_left = packet.GetBytesLeft();
- if (bytes_left > 0)
- {
- m_process_launch_info.GetEnvironmentEntries ().AppendArgument (packet.Peek());
- return SendOKResponse ();
- }
- return SendErrorResponse (12);
+GDBRemoteCommunicationServerCommon::Handle_QEnvironment(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("QEnvironment:"));
+ const uint32_t bytes_left = packet.GetBytesLeft();
+ if (bytes_left > 0) {
+ m_process_launch_info.GetEnvironmentEntries().AppendArgument(
+ llvm::StringRef::withNullAsEmpty(packet.Peek()));
+ return SendOKResponse();
+ }
+ return SendErrorResponse(12);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen("QEnvironmentHexEncoded:"));
- const uint32_t bytes_left = packet.GetBytesLeft();
- if (bytes_left > 0)
- {
- std::string str;
- packet.GetHexByteString(str);
- m_process_launch_info.GetEnvironmentEntries().AppendArgument(str.c_str());
- return SendOKResponse();
- }
- return SendErrorResponse(12);
+GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("QEnvironmentHexEncoded:"));
+ const uint32_t bytes_left = packet.GetBytesLeft();
+ if (bytes_left > 0) {
+ std::string str;
+ packet.GetHexByteString(str);
+ m_process_launch_info.GetEnvironmentEntries().AppendArgument(str);
+ return SendOKResponse();
+ }
+ return SendErrorResponse(12);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QLaunchArch (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen ("QLaunchArch:"));
- const uint32_t bytes_left = packet.GetBytesLeft();
- if (bytes_left > 0)
- {
- const char* arch_triple = packet.Peek();
- ArchSpec arch_spec(arch_triple,NULL);
- m_process_launch_info.SetArchitecture(arch_spec);
- return SendOKResponse();
- }
- return SendErrorResponse(13);
+GDBRemoteCommunicationServerCommon::Handle_QLaunchArch(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("QLaunchArch:"));
+ const uint32_t bytes_left = packet.GetBytesLeft();
+ if (bytes_left > 0) {
+ const char *arch_triple = packet.Peek();
+ ArchSpec arch_spec(arch_triple, NULL);
+ m_process_launch_info.SetArchitecture(arch_spec);
+ return SendOKResponse();
+ }
+ return SendErrorResponse(13);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_A (StringExtractorGDBRemote &packet)
-{
- // The 'A' packet is the most over designed packet ever here with
- // redundant argument indexes, redundant argument lengths and needed hex
- // encoded argument string values. Really all that is needed is a comma
- // separated hex encoded argument value list, but we will stay true to the
- // documented version of the 'A' packet here...
-
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- int actual_arg_index = 0;
-
- packet.SetFilePos(1); // Skip the 'A'
- bool success = true;
- while (success && packet.GetBytesLeft() > 0)
- {
- // Decode the decimal argument string length. This length is the
- // number of hex nibbles in the argument string value.
- const uint32_t arg_len = packet.GetU32(UINT32_MAX);
- if (arg_len == UINT32_MAX)
+GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) {
+ // The 'A' packet is the most over designed packet ever here with
+ // redundant argument indexes, redundant argument lengths and needed hex
+ // encoded argument string values. Really all that is needed is a comma
+ // separated hex encoded argument value list, but we will stay true to the
+ // documented version of the 'A' packet here...
+
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ int actual_arg_index = 0;
+
+ packet.SetFilePos(1); // Skip the 'A'
+ bool success = true;
+ while (success && packet.GetBytesLeft() > 0) {
+ // Decode the decimal argument string length. This length is the
+ // number of hex nibbles in the argument string value.
+ const uint32_t arg_len = packet.GetU32(UINT32_MAX);
+ if (arg_len == UINT32_MAX)
+ success = false;
+ else {
+ // Make sure the argument hex string length is followed by a comma
+ if (packet.GetChar() != ',')
+ success = false;
+ else {
+ // Decode the argument index. We ignore this really because
+ // who would really send down the arguments in a random order???
+ const uint32_t arg_idx = packet.GetU32(UINT32_MAX);
+ if (arg_idx == UINT32_MAX)
+ success = false;
+ else {
+ // Make sure the argument index is followed by a comma
+ if (packet.GetChar() != ',')
success = false;
- else
- {
- // Make sure the argument hex string length is followed by a comma
- if (packet.GetChar() != ',')
- success = false;
- else
- {
- // Decode the argument index. We ignore this really because
- // who would really send down the arguments in a random order???
- const uint32_t arg_idx = packet.GetU32(UINT32_MAX);
- if (arg_idx == UINT32_MAX)
- success = false;
- else
- {
- // Make sure the argument index is followed by a comma
- if (packet.GetChar() != ',')
- success = false;
- else
- {
- // Decode the argument string value from hex bytes
- // back into a UTF8 string and make sure the length
- // matches the one supplied in the packet
- std::string arg;
- if (packet.GetHexByteStringFixedLength(arg, arg_len) != (arg_len / 2))
- success = false;
- else
- {
- // If there are any bytes left
- if (packet.GetBytesLeft())
- {
- if (packet.GetChar() != ',')
- success = false;
- }
-
- if (success)
- {
- if (arg_idx == 0)
- m_process_launch_info.GetExecutableFile().SetFile(arg.c_str(), false);
- m_process_launch_info.GetArguments().AppendArgument(arg.c_str());
- if (log)
- log->Printf ("LLGSPacketHandler::%s added arg %d: \"%s\"", __FUNCTION__, actual_arg_index, arg.c_str ());
- ++actual_arg_index;
- }
- }
- }
- }
+ else {
+ // Decode the argument string value from hex bytes
+ // back into a UTF8 string and make sure the length
+ // matches the one supplied in the packet
+ std::string arg;
+ if (packet.GetHexByteStringFixedLength(arg, arg_len) !=
+ (arg_len / 2))
+ success = false;
+ else {
+ // If there are any bytes left
+ if (packet.GetBytesLeft()) {
+ if (packet.GetChar() != ',')
+ success = false;
+ }
+
+ if (success) {
+ if (arg_idx == 0)
+ m_process_launch_info.GetExecutableFile().SetFile(arg, false);
+ m_process_launch_info.GetArguments().AppendArgument(arg);
+ if (log)
+ log->Printf("LLGSPacketHandler::%s added arg %d: \"%s\"",
+ __FUNCTION__, actual_arg_index, arg.c_str());
+ ++actual_arg_index;
+ }
}
+ }
}
+ }
}
-
- if (success)
- {
- m_process_launch_error = LaunchProcess ();
- if (m_process_launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
- {
- return SendOKResponse ();
- }
- else
- {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("LLGSPacketHandler::%s failed to launch exe: %s",
- __FUNCTION__,
- m_process_launch_error.AsCString());
-
- }
+ }
+
+ if (success) {
+ m_process_launch_error = LaunchProcess();
+ if (m_process_launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) {
+ return SendOKResponse();
+ } else {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("LLGSPacketHandler::%s failed to launch exe: %s",
+ __FUNCTION__, m_process_launch_error.AsCString());
}
- return SendErrorResponse (8);
+ }
+ return SendErrorResponse(8);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qEcho (StringExtractorGDBRemote &packet)
-{
- // Just echo back the exact same packet for qEcho...
- return SendPacketNoLock(packet.GetStringRef().c_str(), packet.GetStringRef().size());
+GDBRemoteCommunicationServerCommon::Handle_qEcho(
+ StringExtractorGDBRemote &packet) {
+ // Just echo back the exact same packet for qEcho...
+ return SendPacketNoLock(packet.GetStringRef());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qModuleInfo (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen ("qModuleInfo:"));
-
- std::string module_path;
- packet.GetHexByteStringTerminatedBy(module_path, ';');
- if (module_path.empty())
- return SendErrorResponse (1);
-
- if (packet.GetChar() != ';')
- return SendErrorResponse (2);
-
- std::string triple;
- packet.GetHexByteString(triple);
- ArchSpec arch(triple.c_str());
-
- const FileSpec req_module_path_spec(module_path.c_str(), true);
- const FileSpec module_path_spec = FindModuleFile(req_module_path_spec.GetPath(), arch);
- const ModuleSpec module_spec(module_path_spec, arch);
-
- ModuleSpecList module_specs;
- if (!ObjectFile::GetModuleSpecifications(module_path_spec, 0, 0, module_specs))
- return SendErrorResponse (3);
+GDBRemoteCommunicationServerCommon::Handle_qModuleInfo(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("qModuleInfo:"));
+
+ std::string module_path;
+ packet.GetHexByteStringTerminatedBy(module_path, ';');
+ if (module_path.empty())
+ return SendErrorResponse(1);
+
+ if (packet.GetChar() != ';')
+ return SendErrorResponse(2);
+
+ std::string triple;
+ packet.GetHexByteString(triple);
+
+ ModuleSpec matched_module_spec = GetModuleInfo(module_path, triple);
+ if (!matched_module_spec.GetFileSpec())
+ return SendErrorResponse(3);
+
+ const auto file_offset = matched_module_spec.GetObjectOffset();
+ const auto file_size = matched_module_spec.GetObjectSize();
+ const auto uuid_str = matched_module_spec.GetUUID().GetAsString("");
+
+ StreamGDBRemote response;
+
+ if (uuid_str.empty()) {
+ std::string md5_hash;
+ if (!FileSystem::CalculateMD5AsString(matched_module_spec.GetFileSpec(),
+ file_offset, file_size, md5_hash))
+ return SendErrorResponse(5);
+ response.PutCString("md5:");
+ response.PutCStringAsRawHex8(md5_hash.c_str());
+ } else {
+ response.PutCString("uuid:");
+ response.PutCStringAsRawHex8(uuid_str.c_str());
+ }
+ response.PutChar(';');
+
+ const auto &module_arch = matched_module_spec.GetArchitecture();
+ response.PutCString("triple:");
+ response.PutCStringAsRawHex8(module_arch.GetTriple().getTriple().c_str());
+ response.PutChar(';');
+
+ response.PutCString("file_path:");
+ response.PutCStringAsRawHex8(matched_module_spec.GetFileSpec().GetCString());
+ response.PutChar(';');
+ response.PutCString("file_offset:");
+ response.PutHex64(file_offset);
+ response.PutChar(';');
+ response.PutCString("file_size:");
+ response.PutHex64(file_size);
+ response.PutChar(';');
+
+ return SendPacketNoLock(response.GetString());
+}
- ModuleSpec matched_module_spec;
- if (!module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec))
- return SendErrorResponse (4);
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerCommon::Handle_jModulesInfo(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("jModulesInfo:"));
+
+ StructuredData::ObjectSP object_sp = StructuredData::ParseJSON(packet.Peek());
+ if (!object_sp)
+ return SendErrorResponse(1);
+
+ StructuredData::Array *packet_array = object_sp->GetAsArray();
+ if (!packet_array)
+ return SendErrorResponse(2);
+
+ JSONArray::SP response_array_sp = std::make_shared<JSONArray>();
+ for (size_t i = 0; i < packet_array->GetSize(); ++i) {
+ StructuredData::Dictionary *query =
+ packet_array->GetItemAtIndex(i)->GetAsDictionary();
+ if (!query)
+ continue;
+ std::string file, triple;
+ if (!query->GetValueForKeyAsString("file", file) ||
+ !query->GetValueForKeyAsString("triple", triple))
+ continue;
+
+ ModuleSpec matched_module_spec = GetModuleInfo(file, triple);
+ if (!matched_module_spec.GetFileSpec())
+ continue;
const auto file_offset = matched_module_spec.GetObjectOffset();
const auto file_size = matched_module_spec.GetObjectSize();
const auto uuid_str = matched_module_spec.GetUUID().GetAsString("");
- StreamGDBRemote response;
-
if (uuid_str.empty())
- {
- std::string md5_hash;
- if (!FileSystem::CalculateMD5AsString(matched_module_spec.GetFileSpec(), file_offset, file_size, md5_hash))
- return SendErrorResponse (5);
- response.PutCString ("md5:");
- response.PutCStringAsRawHex8(md5_hash.c_str());
- }
- else{
- response.PutCString ("uuid:");
- response.PutCStringAsRawHex8(uuid_str.c_str());
- }
- response.PutChar(';');
+ continue;
+
+ JSONObject::SP response = std::make_shared<JSONObject>();
+ response_array_sp->AppendObject(response);
+ response->SetObject("uuid", std::make_shared<JSONString>(uuid_str));
+ response->SetObject(
+ "triple",
+ std::make_shared<JSONString>(
+ matched_module_spec.GetArchitecture().GetTriple().getTriple()));
+ response->SetObject("file_path",
+ std::make_shared<JSONString>(
+ matched_module_spec.GetFileSpec().GetPath()));
+ response->SetObject("file_offset",
+ std::make_shared<JSONNumber>(file_offset));
+ response->SetObject("file_size", std::make_shared<JSONNumber>(file_size));
+ }
+
+ StreamString response;
+ response_array_sp->Write(response);
+ StreamGDBRemote escaped_response;
+ escaped_response.PutEscapedBytes(response.GetString().data(),
+ response.GetSize());
+ return SendPacketNoLock(escaped_response.GetString());
+}
- const auto &module_arch = matched_module_spec.GetArchitecture();
+void GDBRemoteCommunicationServerCommon::CreateProcessInfoResponse(
+ const ProcessInstanceInfo &proc_info, StreamString &response) {
+ response.Printf(
+ "pid:%" PRIu64 ";ppid:%" PRIu64 ";uid:%i;gid:%i;euid:%i;egid:%i;",
+ proc_info.GetProcessID(), proc_info.GetParentProcessID(),
+ proc_info.GetUserID(), proc_info.GetGroupID(),
+ proc_info.GetEffectiveUserID(), proc_info.GetEffectiveGroupID());
+ response.PutCString("name:");
+ response.PutCStringAsRawHex8(proc_info.GetExecutableFile().GetCString());
+ response.PutChar(';');
+ const ArchSpec &proc_arch = proc_info.GetArchitecture();
+ if (proc_arch.IsValid()) {
+ const llvm::Triple &proc_triple = proc_arch.GetTriple();
response.PutCString("triple:");
- response.PutCStringAsRawHex8( module_arch.GetTriple().getTriple().c_str());
- response.PutChar(';');
-
- response.PutCString("file_path:");
- response.PutCStringAsRawHex8(module_path_spec.GetCString());
- response.PutChar(';');
- response.PutCString("file_offset:");
- response.PutHex64(file_offset);
+ response.PutCStringAsRawHex8(proc_triple.getTriple().c_str());
response.PutChar(';');
- response.PutCString("file_size:");
- response.PutHex64(file_size);
- response.PutChar(';');
-
- return SendPacketNoLock(response.GetData(), response.GetSize());
+ }
}
-void
-GDBRemoteCommunicationServerCommon::CreateProcessInfoResponse (const ProcessInstanceInfo &proc_info,
- StreamString &response)
-{
- response.Printf ("pid:%" PRIu64 ";ppid:%" PRIu64 ";uid:%i;gid:%i;euid:%i;egid:%i;",
- proc_info.GetProcessID(),
- proc_info.GetParentProcessID(),
- proc_info.GetUserID(),
- proc_info.GetGroupID(),
- proc_info.GetEffectiveUserID(),
- proc_info.GetEffectiveGroupID());
- response.PutCString ("name:");
- response.PutCStringAsRawHex8(proc_info.GetExecutableFile().GetCString());
+void GDBRemoteCommunicationServerCommon::
+ CreateProcessInfoResponse_DebugServerStyle(
+ const ProcessInstanceInfo &proc_info, StreamString &response) {
+ response.Printf("pid:%" PRIx64 ";parent-pid:%" PRIx64
+ ";real-uid:%x;real-gid:%x;effective-uid:%x;effective-gid:%x;",
+ proc_info.GetProcessID(), proc_info.GetParentProcessID(),
+ proc_info.GetUserID(), proc_info.GetGroupID(),
+ proc_info.GetEffectiveUserID(),
+ proc_info.GetEffectiveGroupID());
+
+ const ArchSpec &proc_arch = proc_info.GetArchitecture();
+ if (proc_arch.IsValid()) {
+ const llvm::Triple &proc_triple = proc_arch.GetTriple();
+#if defined(__APPLE__)
+ // We'll send cputype/cpusubtype.
+ const uint32_t cpu_type = proc_arch.GetMachOCPUType();
+ if (cpu_type != 0)
+ response.Printf("cputype:%" PRIx32 ";", cpu_type);
+
+ const uint32_t cpu_subtype = proc_arch.GetMachOCPUSubType();
+ if (cpu_subtype != 0)
+ response.Printf("cpusubtype:%" PRIx32 ";", cpu_subtype);
+
+ const std::string vendor = proc_triple.getVendorName();
+ if (!vendor.empty())
+ response.Printf("vendor:%s;", vendor.c_str());
+#else
+ // We'll send the triple.
+ response.PutCString("triple:");
+ response.PutCStringAsRawHex8(proc_triple.getTriple().c_str());
response.PutChar(';');
- const ArchSpec &proc_arch = proc_info.GetArchitecture();
- if (proc_arch.IsValid())
- {
- const llvm::Triple &proc_triple = proc_arch.GetTriple();
- response.PutCString("triple:");
- response.PutCStringAsRawHex8(proc_triple.getTriple().c_str());
- response.PutChar(';');
+#endif
+ std::string ostype = proc_triple.getOSName();
+ // Adjust so ostype reports ios for Apple/ARM and Apple/ARM64.
+ if (proc_triple.getVendor() == llvm::Triple::Apple) {
+ switch (proc_triple.getArch()) {
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ case llvm::Triple::aarch64:
+ ostype = "ios";
+ break;
+ default:
+ // No change.
+ break;
+ }
+ }
+ response.Printf("ostype:%s;", ostype.c_str());
+
+ switch (proc_arch.GetByteOrder()) {
+ case lldb::eByteOrderLittle:
+ response.PutCString("endian:little;");
+ break;
+ case lldb::eByteOrderBig:
+ response.PutCString("endian:big;");
+ break;
+ case lldb::eByteOrderPDP:
+ response.PutCString("endian:pdp;");
+ break;
+ default:
+ // Nothing.
+ break;
}
+ // In case of MIPS64, pointer size is depend on ELF ABI
+ // For N32 the pointer size is 4 and for N64 it is 8
+ std::string abi = proc_arch.GetTargetABI();
+ if (!abi.empty())
+ response.Printf("elf_abi:%s;", abi.c_str());
+ response.Printf("ptrsize:%d;", proc_arch.GetAddressByteSize());
+ }
}
-void
-GDBRemoteCommunicationServerCommon::CreateProcessInfoResponse_DebugServerStyle (
- const ProcessInstanceInfo &proc_info, StreamString &response)
-{
- response.Printf ("pid:%" PRIx64 ";parent-pid:%" PRIx64 ";real-uid:%x;real-gid:%x;effective-uid:%x;effective-gid:%x;",
- proc_info.GetProcessID(),
- proc_info.GetParentProcessID(),
- proc_info.GetUserID(),
- proc_info.GetGroupID(),
- proc_info.GetEffectiveUserID(),
- proc_info.GetEffectiveGroupID());
-
- const ArchSpec &proc_arch = proc_info.GetArchitecture();
- if (proc_arch.IsValid())
- {
- const llvm::Triple &proc_triple = proc_arch.GetTriple();
-#if defined(__APPLE__)
- // We'll send cputype/cpusubtype.
- const uint32_t cpu_type = proc_arch.GetMachOCPUType();
- if (cpu_type != 0)
- response.Printf ("cputype:%" PRIx32 ";", cpu_type);
-
- const uint32_t cpu_subtype = proc_arch.GetMachOCPUSubType();
- if (cpu_subtype != 0)
- response.Printf ("cpusubtype:%" PRIx32 ";", cpu_subtype);
-
- const std::string vendor = proc_triple.getVendorName ();
- if (!vendor.empty ())
- response.Printf ("vendor:%s;", vendor.c_str ());
+FileSpec GDBRemoteCommunicationServerCommon::FindModuleFile(
+ const std::string &module_path, const ArchSpec &arch) {
+#ifdef __ANDROID__
+ return HostInfoAndroid::ResolveLibraryPath(module_path, arch);
#else
- // We'll send the triple.
- response.PutCString("triple:");
- response.PutCStringAsRawHex8(proc_triple.getTriple().c_str());
- response.PutChar(';');
+ return FileSpec(module_path, true);
#endif
- std::string ostype = proc_triple.getOSName ();
- // Adjust so ostype reports ios for Apple/ARM and Apple/ARM64.
- if (proc_triple.getVendor () == llvm::Triple::Apple)
- {
- switch (proc_triple.getArch ())
- {
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- case llvm::Triple::aarch64:
- ostype = "ios";
- break;
- default:
- // No change.
- break;
- }
- }
- response.Printf ("ostype:%s;", ostype.c_str ());
+}
+ModuleSpec GDBRemoteCommunicationServerCommon::GetModuleInfo(
+ const std::string &module_path, const std::string &triple) {
+ ArchSpec arch(triple.c_str());
- switch (proc_arch.GetByteOrder ())
- {
- case lldb::eByteOrderLittle: response.PutCString ("endian:little;"); break;
- case lldb::eByteOrderBig: response.PutCString ("endian:big;"); break;
- case lldb::eByteOrderPDP: response.PutCString ("endian:pdp;"); break;
- default:
- // Nothing.
- break;
- }
+ const FileSpec req_module_path_spec(module_path, true);
+ const FileSpec module_path_spec =
+ FindModuleFile(req_module_path_spec.GetPath(), arch);
+ const ModuleSpec module_spec(module_path_spec, arch);
- // In case of MIPS64, pointer size is depend on ELF ABI
- // For N32 the pointer size is 4 and for N64 it is 8
- std::string abi = proc_arch.GetTargetABI();
- if (!abi.empty())
- response.Printf("elf_abi:%s;", abi.c_str());
- response.Printf("ptrsize:%d;", proc_arch.GetAddressByteSize());
- }
-}
+ ModuleSpecList module_specs;
+ if (!ObjectFile::GetModuleSpecifications(module_path_spec, 0, 0,
+ module_specs))
+ return ModuleSpec();
-FileSpec
-GDBRemoteCommunicationServerCommon::FindModuleFile(const std::string& module_path,
- const ArchSpec& arch)
-{
-#ifdef __ANDROID__
- return HostInfoAndroid::ResolveLibraryPath(module_path, arch);
-#else
- return FileSpec(module_path.c_str(), true);
-#endif
+ ModuleSpec matched_module_spec;
+ if (!module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec))
+ return ModuleSpec();
+
+ return matched_module_spec;
}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
index d2fd70042ccc..321a92266bdd 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
@@ -16,8 +16,8 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private-forward.h"
#include "lldb/Target/Process.h"
+#include "lldb/lldb-private-forward.h"
#include "GDBRemoteCommunicationServer.h"
#include "GDBRemoteCommunicationServerCommon.h"
@@ -29,175 +29,132 @@ namespace process_gdb_remote {
class ProcessGDBRemote;
-class GDBRemoteCommunicationServerCommon :
- public GDBRemoteCommunicationServer
-{
+class GDBRemoteCommunicationServerCommon : public GDBRemoteCommunicationServer {
public:
- GDBRemoteCommunicationServerCommon(const char *comm_name, const char *listener_name);
+ GDBRemoteCommunicationServerCommon(const char *comm_name,
+ const char *listener_name);
- ~GDBRemoteCommunicationServerCommon() override;
+ ~GDBRemoteCommunicationServerCommon() override;
protected:
- ProcessLaunchInfo m_process_launch_info;
- Error m_process_launch_error;
- ProcessInstanceInfoList m_proc_infos;
- uint32_t m_proc_infos_index;
- bool m_thread_suffix_supported;
- bool m_list_threads_in_stop_reply;
+ ProcessLaunchInfo m_process_launch_info;
+ Error m_process_launch_error;
+ ProcessInstanceInfoList m_proc_infos;
+ uint32_t m_proc_infos_index;
+ bool m_thread_suffix_supported;
+ bool m_list_threads_in_stop_reply;
+
+ PacketResult Handle_A(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_A (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qHostInfo(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qHostInfo (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qProcessInfoPID(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qProcessInfoPID (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qfProcessInfo(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qfProcessInfo (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qsProcessInfo(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qsProcessInfo (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qUserName(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qUserName (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qGroupName(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qGroupName (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qSpeedTest(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qSpeedTest (StringExtractorGDBRemote &packet);
+ PacketResult Handle_vFile_Open(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_vFile_Open (StringExtractorGDBRemote &packet);
+ PacketResult Handle_vFile_Close(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_vFile_Close (StringExtractorGDBRemote &packet);
+ PacketResult Handle_vFile_pRead(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_vFile_pRead (StringExtractorGDBRemote &packet);
+ PacketResult Handle_vFile_pWrite(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_vFile_pWrite (StringExtractorGDBRemote &packet);
+ PacketResult Handle_vFile_Size(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_vFile_Size (StringExtractorGDBRemote &packet);
+ PacketResult Handle_vFile_Mode(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_vFile_Mode (StringExtractorGDBRemote &packet);
+ PacketResult Handle_vFile_Exists(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_vFile_Exists (StringExtractorGDBRemote &packet);
+ PacketResult Handle_vFile_symlink(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_vFile_symlink (StringExtractorGDBRemote &packet);
+ PacketResult Handle_vFile_unlink(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_vFile_unlink (StringExtractorGDBRemote &packet);
+ PacketResult Handle_vFile_Stat(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_vFile_Stat (StringExtractorGDBRemote &packet);
+ PacketResult Handle_vFile_MD5(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_vFile_MD5 (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qEcho(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qEcho (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qModuleInfo(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qModuleInfo (StringExtractorGDBRemote &packet);
+ PacketResult Handle_jModulesInfo(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qPlatform_shell (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qPlatform_shell(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qPlatform_mkdir (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qPlatform_mkdir(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qPlatform_chmod (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qPlatform_chmod(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qSupported (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qSupported(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_QThreadSuffixSupported (StringExtractorGDBRemote &packet);
+ PacketResult Handle_QThreadSuffixSupported(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_QListThreadsInStopReply (StringExtractorGDBRemote &packet);
+ PacketResult Handle_QListThreadsInStopReply(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_QSetDetachOnError (StringExtractorGDBRemote &packet);
+ PacketResult Handle_QSetDetachOnError(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_QStartNoAckMode (StringExtractorGDBRemote &packet);
+ PacketResult Handle_QStartNoAckMode(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_QSetSTDIN (StringExtractorGDBRemote &packet);
+ PacketResult Handle_QSetSTDIN(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_QSetSTDOUT (StringExtractorGDBRemote &packet);
+ PacketResult Handle_QSetSTDOUT(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_QSetSTDERR (StringExtractorGDBRemote &packet);
+ PacketResult Handle_QSetSTDERR(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qLaunchSuccess (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qLaunchSuccess(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_QEnvironment (StringExtractorGDBRemote &packet);
+ PacketResult Handle_QEnvironment(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_QEnvironmentHexEncoded (StringExtractorGDBRemote &packet);
+ PacketResult Handle_QEnvironmentHexEncoded(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_QLaunchArch (StringExtractorGDBRemote &packet);
+ PacketResult Handle_QLaunchArch(StringExtractorGDBRemote &packet);
- static void
- CreateProcessInfoResponse (const ProcessInstanceInfo &proc_info,
- StreamString &response);
+ static void CreateProcessInfoResponse(const ProcessInstanceInfo &proc_info,
+ StreamString &response);
- static void
- CreateProcessInfoResponse_DebugServerStyle (const ProcessInstanceInfo &proc_info,
- StreamString &response);
+ static void CreateProcessInfoResponse_DebugServerStyle(
+ const ProcessInstanceInfo &proc_info, StreamString &response);
- template <typename T>
- void
- RegisterMemberFunctionHandler (StringExtractorGDBRemote::ServerPacketType packet_type,
- PacketResult (T::*handler) (StringExtractorGDBRemote& packet))
- {
- RegisterPacketHandler(packet_type,
- [this, handler] (StringExtractorGDBRemote packet,
- Error &error,
- bool &interrupt,
- bool &quit)
- {
- return (static_cast<T*>(this)->*handler) (packet);
- });
- }
+ template <typename T>
+ void RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::ServerPacketType packet_type,
+ PacketResult (T::*handler)(StringExtractorGDBRemote &packet)) {
+ RegisterPacketHandler(packet_type,
+ [this, handler](StringExtractorGDBRemote packet,
+ Error &error, bool &interrupt,
+ bool &quit) {
+ return (static_cast<T *>(this)->*handler)(packet);
+ });
+ }
- bool
- GetThreadSuffixSupported () override
- {
- return true;
- }
+ //------------------------------------------------------------------
+ /// Launch a process with the current launch settings.
+ ///
+ /// This method supports running an lldb-gdbserver or similar
+ /// server in a situation where the startup code has been provided
+ /// with all the information for a child process to be launched.
+ ///
+ /// @return
+ /// An Error object indicating the success or failure of the
+ /// launch.
+ //------------------------------------------------------------------
+ virtual Error LaunchProcess() = 0;
- //------------------------------------------------------------------
- /// Launch a process with the current launch settings.
- ///
- /// This method supports running an lldb-gdbserver or similar
- /// server in a situation where the startup code has been provided
- /// with all the information for a child process to be launched.
- ///
- /// @return
- /// An Error object indicating the success or failure of the
- /// launch.
- //------------------------------------------------------------------
- virtual Error
- LaunchProcess () = 0;
+ virtual FileSpec FindModuleFile(const std::string &module_path,
+ const ArchSpec &arch);
- virtual FileSpec
- FindModuleFile (const std::string& module_path, const ArchSpec& arch);
+private:
+ ModuleSpec GetModuleInfo(const std::string &module_path,
+ const std::string &triple);
};
} // namespace process_gdb_remote
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index c468ba33e858..bf72673f1769 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -16,13 +16,11 @@
// C Includes
// C++ Includes
-#include <cstring>
#include <chrono>
+#include <cstring>
#include <thread>
// Other libraries and framework includes
-#include "llvm/ADT/Triple.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Core/DataBuffer.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/RegisterValue.h"
@@ -36,20 +34,22 @@
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/StringConvert.h"
-#include "lldb/Host/TimeValue.h"
-#include "lldb/Target/FileAction.h"
-#include "lldb/Target/MemoryRegionInfo.h"
-#include "lldb/Host/common/NativeRegisterContext.h"
#include "lldb/Host/common/NativeProcessProtocol.h"
+#include "lldb/Host/common/NativeRegisterContext.h"
#include "lldb/Host/common/NativeThreadProtocol.h"
+#include "lldb/Interpreter/Args.h"
+#include "lldb/Target/FileAction.h"
+#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Utility/JSON.h"
#include "lldb/Utility/LLDBAssert.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/ScopedPrinter.h"
// Project includes
-#include "Utility/StringExtractorGDBRemote.h"
-#include "Utility/UriParser.h"
#include "ProcessGDBRemote.h"
#include "ProcessGDBRemoteLog.h"
+#include "Utility/StringExtractorGDBRemote.h"
+#include "Utility/UriParser.h"
using namespace lldb;
using namespace lldb_private;
@@ -60,2934 +60,3110 @@ using namespace llvm;
// GDBRemote Errors
//----------------------------------------------------------------------
-namespace
-{
- enum GDBRemoteServerError
- {
- // Set to the first unused error number in literal form below
- eErrorFirst = 29,
- eErrorNoProcess = eErrorFirst,
- eErrorResume,
- eErrorExitStatus
- };
+namespace {
+enum GDBRemoteServerError {
+ // Set to the first unused error number in literal form below
+ eErrorFirst = 29,
+ eErrorNoProcess = eErrorFirst,
+ eErrorResume,
+ eErrorExitStatus
+};
}
//----------------------------------------------------------------------
// GDBRemoteCommunicationServerLLGS constructor
//----------------------------------------------------------------------
-GDBRemoteCommunicationServerLLGS::GDBRemoteCommunicationServerLLGS(MainLoop &mainloop)
- : GDBRemoteCommunicationServerCommon("gdb-remote.server", "gdb-remote.server.rx_packet"),
- m_mainloop(mainloop),
- m_current_tid(LLDB_INVALID_THREAD_ID),
- m_continue_tid(LLDB_INVALID_THREAD_ID),
- m_debugged_process_mutex(),
- m_debugged_process_sp(),
- m_stdio_communication("process.stdio"),
+GDBRemoteCommunicationServerLLGS::GDBRemoteCommunicationServerLLGS(
+ MainLoop &mainloop)
+ : GDBRemoteCommunicationServerCommon("gdb-remote.server",
+ "gdb-remote.server.rx_packet"),
+ m_mainloop(mainloop), m_current_tid(LLDB_INVALID_THREAD_ID),
+ m_continue_tid(LLDB_INVALID_THREAD_ID), m_debugged_process_mutex(),
+ m_debugged_process_sp(), m_stdio_communication("process.stdio"),
m_inferior_prev_state(StateType::eStateInvalid),
- m_active_auxv_buffer_sp(),
- m_saved_registers_mutex(),
- m_saved_registers_map(),
- m_next_saved_registers_id(1),
- m_handshake_completed(false)
-{
- RegisterPacketHandlers();
-}
-
-void
-GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers()
-{
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_C,
- &GDBRemoteCommunicationServerLLGS::Handle_C);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_c,
- &GDBRemoteCommunicationServerLLGS::Handle_c);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_D,
- &GDBRemoteCommunicationServerLLGS::Handle_D);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_H,
- &GDBRemoteCommunicationServerLLGS::Handle_H);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_I,
- &GDBRemoteCommunicationServerLLGS::Handle_I);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_interrupt,
- &GDBRemoteCommunicationServerLLGS::Handle_interrupt);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_m,
- &GDBRemoteCommunicationServerLLGS::Handle_memory_read);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_M,
- &GDBRemoteCommunicationServerLLGS::Handle_M);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_p,
- &GDBRemoteCommunicationServerLLGS::Handle_p);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_P,
- &GDBRemoteCommunicationServerLLGS::Handle_P);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qC,
- &GDBRemoteCommunicationServerLLGS::Handle_qC);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qfThreadInfo,
- &GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qFileLoadAddress,
- &GDBRemoteCommunicationServerLLGS::Handle_qFileLoadAddress);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir,
- &GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qMemoryRegionInfo,
- &GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qMemoryRegionInfoSupported,
- &GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qProcessInfo,
- &GDBRemoteCommunicationServerLLGS::Handle_qProcessInfo);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qRegisterInfo,
- &GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QRestoreRegisterState,
- &GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSaveRegisterState,
- &GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetDisableASLR,
- &GDBRemoteCommunicationServerLLGS::Handle_QSetDisableASLR);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir,
- &GDBRemoteCommunicationServerLLGS::Handle_QSetWorkingDir);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qsThreadInfo,
- &GDBRemoteCommunicationServerLLGS::Handle_qsThreadInfo);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qThreadStopInfo,
- &GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_jThreadsInfo,
- &GDBRemoteCommunicationServerLLGS::Handle_jThreadsInfo);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qWatchpointSupportInfo,
- &GDBRemoteCommunicationServerLLGS::Handle_qWatchpointSupportInfo);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qXfer_auxv_read,
- &GDBRemoteCommunicationServerLLGS::Handle_qXfer_auxv_read);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_s,
- &GDBRemoteCommunicationServerLLGS::Handle_s);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_stop_reason,
- &GDBRemoteCommunicationServerLLGS::Handle_stop_reason); // ?
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vAttach,
- &GDBRemoteCommunicationServerLLGS::Handle_vAttach);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vCont,
- &GDBRemoteCommunicationServerLLGS::Handle_vCont);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vCont_actions,
- &GDBRemoteCommunicationServerLLGS::Handle_vCont_actions);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_x,
- &GDBRemoteCommunicationServerLLGS::Handle_memory_read);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_Z,
- &GDBRemoteCommunicationServerLLGS::Handle_Z);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_z,
- &GDBRemoteCommunicationServerLLGS::Handle_z);
-
- RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_k,
- [this](StringExtractorGDBRemote packet,
- Error &error,
- bool &interrupt,
- bool &quit)
- {
- quit = true;
- return this->Handle_k (packet);
- });
-}
-
-Error
-GDBRemoteCommunicationServerLLGS::SetLaunchArguments (const char *const args[], int argc)
-{
- if ((argc < 1) || !args || !args[0] || !args[0][0])
- return Error ("%s: no process command line specified to launch", __FUNCTION__);
-
- m_process_launch_info.SetArguments (const_cast<const char**> (args), true);
- return Error ();
-}
-
-Error
-GDBRemoteCommunicationServerLLGS::SetLaunchFlags (unsigned int launch_flags)
-{
- m_process_launch_info.GetFlags ().Set (launch_flags);
- return Error ();
-}
-
-Error
-GDBRemoteCommunicationServerLLGS::LaunchProcess ()
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- if (!m_process_launch_info.GetArguments ().GetArgumentCount ())
- return Error ("%s: no process command line specified to launch", __FUNCTION__);
-
- Error error;
- {
- std::lock_guard<std::recursive_mutex> guard(m_debugged_process_mutex);
- assert (!m_debugged_process_sp && "lldb-gdbserver creating debugged process but one already exists");
- error = NativeProcessProtocol::Launch(
- m_process_launch_info,
- *this,
- m_mainloop,
- m_debugged_process_sp);
- }
-
- if (!error.Success ())
- {
- fprintf (stderr, "%s: failed to launch executable %s", __FUNCTION__, m_process_launch_info.GetArguments ().GetArgumentAtIndex (0));
- return error;
- }
-
- // Handle mirroring of inferior stdout/stderr over the gdb-remote protocol
- // as needed.
- // llgs local-process debugging may specify PTY paths, which will make these
- // file actions non-null
- // process launch -i/e/o will also make these file actions non-null
- // nullptr means that the traffic is expected to flow over gdb-remote protocol
- if (
- m_process_launch_info.GetFileActionForFD(STDIN_FILENO) == nullptr ||
- m_process_launch_info.GetFileActionForFD(STDOUT_FILENO) == nullptr ||
- m_process_launch_info.GetFileActionForFD(STDERR_FILENO) == nullptr
- )
- {
- // nullptr means it's not redirected to file or pty (in case of LLGS local)
- // at least one of stdio will be transferred pty<->gdb-remote
- // we need to give the pty master handle to this object to read and/or write
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " setting up stdout/stderr redirection via $O gdb-remote commands", __FUNCTION__, m_debugged_process_sp->GetID ());
-
- // Setup stdout/stderr mapping from inferior to $O
- auto terminal_fd = m_debugged_process_sp->GetTerminalFileDescriptor ();
- if (terminal_fd >= 0)
- {
- if (log)
- log->Printf ("ProcessGDBRemoteCommunicationServerLLGS::%s setting inferior STDIO fd to %d", __FUNCTION__, terminal_fd);
- error = SetSTDIOFileDescriptor (terminal_fd);
- if (error.Fail ())
- return error;
- }
- else
- {
- if (log)
- log->Printf ("ProcessGDBRemoteCommunicationServerLLGS::%s ignoring inferior STDIO since terminal fd reported as %d", __FUNCTION__, terminal_fd);
- }
- }
- else
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " skipping stdout/stderr redirection via $O: inferior will communicate over client-provided file descriptors", __FUNCTION__, m_debugged_process_sp->GetID ());
- }
-
- printf ("Launched '%s' as process %" PRIu64 "...\n", m_process_launch_info.GetArguments ().GetArgumentAtIndex (0), m_process_launch_info.GetProcessID ());
-
+ m_active_auxv_buffer_sp(), m_saved_registers_mutex(),
+ m_saved_registers_map(), m_next_saved_registers_id(1),
+ m_handshake_completed(false) {
+ RegisterPacketHandlers();
+}
+
+void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() {
+ RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_C,
+ &GDBRemoteCommunicationServerLLGS::Handle_C);
+ RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_c,
+ &GDBRemoteCommunicationServerLLGS::Handle_c);
+ RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_D,
+ &GDBRemoteCommunicationServerLLGS::Handle_D);
+ RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_H,
+ &GDBRemoteCommunicationServerLLGS::Handle_H);
+ RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_I,
+ &GDBRemoteCommunicationServerLLGS::Handle_I);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_interrupt,
+ &GDBRemoteCommunicationServerLLGS::Handle_interrupt);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_m,
+ &GDBRemoteCommunicationServerLLGS::Handle_memory_read);
+ RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_M,
+ &GDBRemoteCommunicationServerLLGS::Handle_M);
+ RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_p,
+ &GDBRemoteCommunicationServerLLGS::Handle_p);
+ RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_P,
+ &GDBRemoteCommunicationServerLLGS::Handle_P);
+ RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qC,
+ &GDBRemoteCommunicationServerLLGS::Handle_qC);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qfThreadInfo,
+ &GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qFileLoadAddress,
+ &GDBRemoteCommunicationServerLLGS::Handle_qFileLoadAddress);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir,
+ &GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qMemoryRegionInfo,
+ &GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qMemoryRegionInfoSupported,
+ &GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qProcessInfo,
+ &GDBRemoteCommunicationServerLLGS::Handle_qProcessInfo);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qRegisterInfo,
+ &GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QRestoreRegisterState,
+ &GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QSaveRegisterState,
+ &GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QSetDisableASLR,
+ &GDBRemoteCommunicationServerLLGS::Handle_QSetDisableASLR);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir,
+ &GDBRemoteCommunicationServerLLGS::Handle_QSetWorkingDir);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qsThreadInfo,
+ &GDBRemoteCommunicationServerLLGS::Handle_qsThreadInfo);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qThreadStopInfo,
+ &GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_jThreadsInfo,
+ &GDBRemoteCommunicationServerLLGS::Handle_jThreadsInfo);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qWatchpointSupportInfo,
+ &GDBRemoteCommunicationServerLLGS::Handle_qWatchpointSupportInfo);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qXfer_auxv_read,
+ &GDBRemoteCommunicationServerLLGS::Handle_qXfer_auxv_read);
+ RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_s,
+ &GDBRemoteCommunicationServerLLGS::Handle_s);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_stop_reason,
+ &GDBRemoteCommunicationServerLLGS::Handle_stop_reason); // ?
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vAttach,
+ &GDBRemoteCommunicationServerLLGS::Handle_vAttach);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vCont,
+ &GDBRemoteCommunicationServerLLGS::Handle_vCont);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vCont_actions,
+ &GDBRemoteCommunicationServerLLGS::Handle_vCont_actions);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_x,
+ &GDBRemoteCommunicationServerLLGS::Handle_memory_read);
+ RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_Z,
+ &GDBRemoteCommunicationServerLLGS::Handle_Z);
+ RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_z,
+ &GDBRemoteCommunicationServerLLGS::Handle_z);
+
+ RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_k,
+ [this](StringExtractorGDBRemote packet, Error &error,
+ bool &interrupt, bool &quit) {
+ quit = true;
+ return this->Handle_k(packet);
+ });
+}
+
+Error GDBRemoteCommunicationServerLLGS::SetLaunchArguments(
+ const char *const args[], int argc) {
+ if ((argc < 1) || !args || !args[0] || !args[0][0])
+ return Error("%s: no process command line specified to launch",
+ __FUNCTION__);
+
+ m_process_launch_info.SetArguments(const_cast<const char **>(args), true);
+ return Error();
+}
+
+Error GDBRemoteCommunicationServerLLGS::SetLaunchFlags(
+ unsigned int launch_flags) {
+ m_process_launch_info.GetFlags().Set(launch_flags);
+ return Error();
+}
+
+Error GDBRemoteCommunicationServerLLGS::LaunchProcess() {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ if (!m_process_launch_info.GetArguments().GetArgumentCount())
+ return Error("%s: no process command line specified to launch",
+ __FUNCTION__);
+
+ const bool should_forward_stdio =
+ m_process_launch_info.GetFileActionForFD(STDIN_FILENO) == nullptr ||
+ m_process_launch_info.GetFileActionForFD(STDOUT_FILENO) == nullptr ||
+ m_process_launch_info.GetFileActionForFD(STDERR_FILENO) == nullptr;
+ m_process_launch_info.SetLaunchInSeparateProcessGroup(true);
+ m_process_launch_info.GetFlags().Set(eLaunchFlagDebug);
+
+ const bool default_to_use_pty = true;
+ m_process_launch_info.FinalizeFileActions(nullptr, default_to_use_pty);
+
+ Error error;
+ {
+ std::lock_guard<std::recursive_mutex> guard(m_debugged_process_mutex);
+ assert(!m_debugged_process_sp && "lldb-server creating debugged "
+ "process but one already exists");
+ error = NativeProcessProtocol::Launch(m_process_launch_info, *this,
+ m_mainloop, m_debugged_process_sp);
+ }
+
+ if (!error.Success()) {
+ fprintf(stderr, "%s: failed to launch executable %s", __FUNCTION__,
+ m_process_launch_info.GetArguments().GetArgumentAtIndex(0));
return error;
-}
-
-Error
-GDBRemoteCommunicationServerLLGS::AttachToProcess (lldb::pid_t pid)
-{
- Error error;
-
- Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS));
+ }
+
+ // Handle mirroring of inferior stdout/stderr over the gdb-remote protocol
+ // as needed.
+ // llgs local-process debugging may specify PTY paths, which will make these
+ // file actions non-null
+ // process launch -i/e/o will also make these file actions non-null
+ // nullptr means that the traffic is expected to flow over gdb-remote protocol
+ if (should_forward_stdio) {
+ // nullptr means it's not redirected to file or pty (in case of LLGS local)
+ // at least one of stdio will be transferred pty<->gdb-remote
+ // we need to give the pty master handle to this object to read and/or write
if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64, __FUNCTION__, pid);
-
- // Before we try to attach, make sure we aren't already monitoring something else.
- if (m_debugged_process_sp && m_debugged_process_sp->GetID() != LLDB_INVALID_PROCESS_ID)
- return Error("cannot attach to a process %" PRIu64 " when another process with pid %" PRIu64 " is being debugged.", pid, m_debugged_process_sp->GetID());
-
- // Try to attach.
- error = NativeProcessProtocol::Attach(pid, *this, m_mainloop, m_debugged_process_sp);
- if (!error.Success ())
- {
- fprintf (stderr, "%s: failed to attach to process %" PRIu64 ": %s", __FUNCTION__, pid, error.AsCString ());
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " setting up stdout/stderr redirection via $O gdb-remote commands",
+ __FUNCTION__, m_debugged_process_sp->GetID());
+
+ // Setup stdout/stderr mapping from inferior to $O
+ auto terminal_fd = m_debugged_process_sp->GetTerminalFileDescriptor();
+ if (terminal_fd >= 0) {
+ if (log)
+ log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s setting "
+ "inferior STDIO fd to %d",
+ __FUNCTION__, terminal_fd);
+ error = SetSTDIOFileDescriptor(terminal_fd);
+ if (error.Fail())
return error;
+ } else {
+ if (log)
+ log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s ignoring "
+ "inferior STDIO since terminal fd reported as %d",
+ __FUNCTION__, terminal_fd);
}
-
- // Setup stdout/stderr mapping from inferior.
- auto terminal_fd = m_debugged_process_sp->GetTerminalFileDescriptor ();
- if (terminal_fd >= 0)
- {
- if (log)
- log->Printf ("ProcessGDBRemoteCommunicationServerLLGS::%s setting inferior STDIO fd to %d", __FUNCTION__, terminal_fd);
- error = SetSTDIOFileDescriptor (terminal_fd);
- if (error.Fail ())
- return error;
- }
- else
- {
- if (log)
- log->Printf ("ProcessGDBRemoteCommunicationServerLLGS::%s ignoring inferior STDIO since terminal fd reported as %d", __FUNCTION__, terminal_fd);
- }
-
- printf ("Attached to process %" PRIu64 "...\n", pid);
-
+ } else {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " skipping stdout/stderr redirection via $O: inferior will "
+ "communicate over client-provided file descriptors",
+ __FUNCTION__, m_debugged_process_sp->GetID());
+ }
+
+ printf("Launched '%s' as process %" PRIu64 "...\n",
+ m_process_launch_info.GetArguments().GetArgumentAtIndex(0),
+ m_process_launch_info.GetProcessID());
+
+ return error;
+}
+
+Error GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) {
+ Error error;
+
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64,
+ __FUNCTION__, pid);
+
+ // Before we try to attach, make sure we aren't already monitoring something
+ // else.
+ if (m_debugged_process_sp &&
+ m_debugged_process_sp->GetID() != LLDB_INVALID_PROCESS_ID)
+ return Error("cannot attach to a process %" PRIu64
+ " when another process with pid %" PRIu64
+ " is being debugged.",
+ pid, m_debugged_process_sp->GetID());
+
+ // Try to attach.
+ error = NativeProcessProtocol::Attach(pid, *this, m_mainloop,
+ m_debugged_process_sp);
+ if (!error.Success()) {
+ fprintf(stderr, "%s: failed to attach to process %" PRIu64 ": %s",
+ __FUNCTION__, pid, error.AsCString());
return error;
-}
+ }
-void
-GDBRemoteCommunicationServerLLGS::InitializeDelegate (NativeProcessProtocol *process)
-{
- assert (process && "process cannot be NULL");
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ // Setup stdout/stderr mapping from inferior.
+ auto terminal_fd = m_debugged_process_sp->GetTerminalFileDescriptor();
+ if (terminal_fd >= 0) {
if (log)
- {
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s called with NativeProcessProtocol pid %" PRIu64 ", current state: %s",
- __FUNCTION__,
- process->GetID (),
- StateAsCString (process->GetState ()));
- }
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::SendWResponse (NativeProcessProtocol *process)
-{
- assert (process && "process cannot be NULL");
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- // send W notification
- ExitType exit_type = ExitType::eExitTypeInvalid;
- int return_code = 0;
- std::string exit_description;
-
- const bool got_exit_info = process->GetExitStatus (&exit_type, &return_code, exit_description);
- if (!got_exit_info)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 ", failed to retrieve process exit status", __FUNCTION__, process->GetID ());
-
- StreamGDBRemote response;
- response.PutChar ('E');
- response.PutHex8 (GDBRemoteServerError::eErrorExitStatus);
- return SendPacketNoLock(response.GetData(), response.GetSize());
- }
- else
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 ", returning exit type %d, return code %d [%s]", __FUNCTION__, process->GetID (), exit_type, return_code, exit_description.c_str ());
-
- StreamGDBRemote response;
-
- char return_type_code;
- switch (exit_type)
- {
- case ExitType::eExitTypeExit:
- return_type_code = 'W';
- break;
- case ExitType::eExitTypeSignal:
- return_type_code = 'X';
- break;
- case ExitType::eExitTypeStop:
- return_type_code = 'S';
- break;
- case ExitType::eExitTypeInvalid:
- return_type_code = 'E';
- break;
- }
- response.PutChar (return_type_code);
+ log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s setting "
+ "inferior STDIO fd to %d",
+ __FUNCTION__, terminal_fd);
+ error = SetSTDIOFileDescriptor(terminal_fd);
+ if (error.Fail())
+ return error;
+ } else {
+ if (log)
+ log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s ignoring "
+ "inferior STDIO since terminal fd reported as %d",
+ __FUNCTION__, terminal_fd);
+ }
- // POSIX exit status limited to unsigned 8 bits.
- response.PutHex8 (return_code);
+ printf("Attached to process %" PRIu64 "...\n", pid);
- return SendPacketNoLock(response.GetData(), response.GetSize());
- }
+ return error;
}
-static void
-AppendHexValue (StreamString &response, const uint8_t* buf, uint32_t buf_size, bool swap)
-{
- int64_t i;
- if (swap)
- {
- for (i = buf_size-1; i >= 0; i--)
- response.PutHex8 (buf[i]);
- }
- else
- {
- for (i = 0; i < buf_size; i++)
- response.PutHex8 (buf[i]);
- }
+void GDBRemoteCommunicationServerLLGS::InitializeDelegate(
+ NativeProcessProtocol *process) {
+ assert(process && "process cannot be NULL");
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log) {
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s called with "
+ "NativeProcessProtocol pid %" PRIu64 ", current state: %s",
+ __FUNCTION__, process->GetID(),
+ StateAsCString(process->GetState()));
+ }
}
-static void
-WriteRegisterValueInHexFixedWidth (StreamString &response,
- NativeRegisterContextSP &reg_ctx_sp,
- const RegisterInfo &reg_info,
- const RegisterValue *reg_value_p)
-{
- RegisterValue reg_value;
- if (!reg_value_p)
- {
- Error error = reg_ctx_sp->ReadRegister (&reg_info, reg_value);
- if (error.Success ())
- reg_value_p = &reg_value;
- // else log.
- }
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::SendWResponse(
+ NativeProcessProtocol *process) {
+ assert(process && "process cannot be NULL");
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ // send W notification
+ ExitType exit_type = ExitType::eExitTypeInvalid;
+ int return_code = 0;
+ std::string exit_description;
+
+ const bool got_exit_info =
+ process->GetExitStatus(&exit_type, &return_code, exit_description);
+ if (!got_exit_info) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ ", failed to retrieve process exit status",
+ __FUNCTION__, process->GetID());
- if (reg_value_p)
- {
- AppendHexValue (response, (const uint8_t*) reg_value_p->GetBytes (), reg_value_p->GetByteSize (), false);
- }
- else
- {
- // Zero-out any unreadable values.
- if (reg_info.byte_size > 0)
- {
- std::basic_string<uint8_t> zeros(reg_info.byte_size, '\0');
- AppendHexValue (response, zeros.data(), zeros.size(), false);
- }
- }
-}
+ StreamGDBRemote response;
+ response.PutChar('E');
+ response.PutHex8(GDBRemoteServerError::eErrorExitStatus);
+ return SendPacketNoLock(response.GetString());
+ } else {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ ", returning exit type %d, return code %d [%s]",
+ __FUNCTION__, process->GetID(), exit_type, return_code,
+ exit_description.c_str());
-static JSONObject::SP
-GetRegistersAsJSON(NativeThreadProtocol &thread, bool abridged)
-{
- Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_THREAD));
+ StreamGDBRemote response;
- NativeRegisterContextSP reg_ctx_sp = thread.GetRegisterContext ();
- if (! reg_ctx_sp)
- return nullptr;
+ char return_type_code;
+ switch (exit_type) {
+ case ExitType::eExitTypeExit:
+ return_type_code = 'W';
+ break;
+ case ExitType::eExitTypeSignal:
+ return_type_code = 'X';
+ break;
+ case ExitType::eExitTypeStop:
+ return_type_code = 'S';
+ break;
+ case ExitType::eExitTypeInvalid:
+ return_type_code = 'E';
+ break;
+ }
+ response.PutChar(return_type_code);
+
+ // POSIX exit status limited to unsigned 8 bits.
+ response.PutHex8(return_code);
+
+ return SendPacketNoLock(response.GetString());
+ }
+}
+
+static void AppendHexValue(StreamString &response, const uint8_t *buf,
+ uint32_t buf_size, bool swap) {
+ int64_t i;
+ if (swap) {
+ for (i = buf_size - 1; i >= 0; i--)
+ response.PutHex8(buf[i]);
+ } else {
+ for (i = 0; i < buf_size; i++)
+ response.PutHex8(buf[i]);
+ }
+}
+
+static void WriteRegisterValueInHexFixedWidth(
+ StreamString &response, NativeRegisterContextSP &reg_ctx_sp,
+ const RegisterInfo &reg_info, const RegisterValue *reg_value_p) {
+ RegisterValue reg_value;
+ if (!reg_value_p) {
+ Error error = reg_ctx_sp->ReadRegister(&reg_info, reg_value);
+ if (error.Success())
+ reg_value_p = &reg_value;
+ // else log.
+ }
+
+ if (reg_value_p) {
+ AppendHexValue(response, (const uint8_t *)reg_value_p->GetBytes(),
+ reg_value_p->GetByteSize(), false);
+ } else {
+ // Zero-out any unreadable values.
+ if (reg_info.byte_size > 0) {
+ std::basic_string<uint8_t> zeros(reg_info.byte_size, '\0');
+ AppendHexValue(response, zeros.data(), zeros.size(), false);
+ }
+ }
+}
+
+static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread,
+ bool abridged) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+
+ NativeRegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
+ if (!reg_ctx_sp)
+ return nullptr;
- JSONObject::SP register_object_sp = std::make_shared<JSONObject>();
+ JSONObject::SP register_object_sp = std::make_shared<JSONObject>();
#ifdef LLDB_JTHREADSINFO_FULL_REGISTER_SET
- // Expedite all registers in the first register set (i.e. should be GPRs) that are not contained in other registers.
- const RegisterSet *reg_set_p = reg_ctx_sp->GetRegisterSet(0);
- if (! reg_set_p)
- return nullptr;
- for (const uint32_t *reg_num_p = reg_set_p->registers; *reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p)
- {
- uint32_t reg_num = *reg_num_p;
+ // Expedite all registers in the first register set (i.e. should be GPRs) that
+ // are not contained in other registers.
+ const RegisterSet *reg_set_p = reg_ctx_sp->GetRegisterSet(0);
+ if (!reg_set_p)
+ return nullptr;
+ for (const uint32_t *reg_num_p = reg_set_p->registers;
+ *reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p) {
+ uint32_t reg_num = *reg_num_p;
#else
- // Expedite only a couple of registers until we figure out why sending registers is
- // expensive.
- static const uint32_t k_expedited_registers[] = {
- LLDB_REGNUM_GENERIC_PC, LLDB_REGNUM_GENERIC_SP, LLDB_REGNUM_GENERIC_FP, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM
- };
- static const uint32_t k_abridged_expedited_registers[] = {
- LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM
- };
-
- for (const uint32_t *generic_reg_p = abridged ? k_abridged_expedited_registers : k_expedited_registers;
- *generic_reg_p != LLDB_INVALID_REGNUM;
- ++generic_reg_p)
- {
- uint32_t reg_num = reg_ctx_sp->ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, *generic_reg_p);
- if (reg_num == LLDB_INVALID_REGNUM)
- continue; // Target does not support the given register.
+ // Expedite only a couple of registers until we figure out why sending
+ // registers is
+ // expensive.
+ static const uint32_t k_expedited_registers[] = {
+ LLDB_REGNUM_GENERIC_PC, LLDB_REGNUM_GENERIC_SP, LLDB_REGNUM_GENERIC_FP,
+ LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM};
+ static const uint32_t k_abridged_expedited_registers[] = {
+ LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM};
+
+ for (const uint32_t *generic_reg_p = abridged ? k_abridged_expedited_registers
+ : k_expedited_registers;
+ *generic_reg_p != LLDB_INVALID_REGNUM; ++generic_reg_p) {
+ uint32_t reg_num = reg_ctx_sp->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, *generic_reg_p);
+ if (reg_num == LLDB_INVALID_REGNUM)
+ continue; // Target does not support the given register.
#endif
- const RegisterInfo *const reg_info_p = reg_ctx_sp->GetRegisterInfoAtIndex(reg_num);
- if (reg_info_p == nullptr)
- {
- if (log)
- log->Printf("%s failed to get register info for register index %" PRIu32,
- __FUNCTION__, reg_num);
- continue;
- }
-
- if (reg_info_p->value_regs != nullptr)
- continue; // Only expedite registers that are not contained in other registers.
-
- RegisterValue reg_value;
- Error error = reg_ctx_sp->ReadRegister(reg_info_p, reg_value);
- if (error.Fail())
- {
- if (log)
- log->Printf("%s failed to read register '%s' index %" PRIu32 ": %s", __FUNCTION__,
- reg_info_p->name ? reg_info_p->name : "<unnamed-register>", reg_num,
- error.AsCString ());
- continue;
- }
-
- StreamString stream;
- WriteRegisterValueInHexFixedWidth(stream, reg_ctx_sp, *reg_info_p, &reg_value);
-
- register_object_sp->SetObject(std::to_string(reg_num),
- std::make_shared<JSONString>(stream.GetString()));
- }
-
- return register_object_sp;
-}
-
-static const char *
-GetStopReasonString(StopReason stop_reason)
-{
- switch (stop_reason)
- {
- case eStopReasonTrace:
- return "trace";
- case eStopReasonBreakpoint:
- return "breakpoint";
- case eStopReasonWatchpoint:
- return "watchpoint";
- case eStopReasonSignal:
- return "signal";
- case eStopReasonException:
- return "exception";
- case eStopReasonExec:
- return "exec";
- case eStopReasonInstrumentation:
- case eStopReasonInvalid:
- case eStopReasonPlanComplete:
- case eStopReasonThreadExiting:
- case eStopReasonNone:
- break; // ignored
+ const RegisterInfo *const reg_info_p =
+ reg_ctx_sp->GetRegisterInfoAtIndex(reg_num);
+ if (reg_info_p == nullptr) {
+ if (log)
+ log->Printf(
+ "%s failed to get register info for register index %" PRIu32,
+ __FUNCTION__, reg_num);
+ continue;
}
- return nullptr;
-}
-static JSONArray::SP
-GetJSONThreadsInfo(NativeProcessProtocol &process, bool abridged)
-{
- Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+ if (reg_info_p->value_regs != nullptr)
+ continue; // Only expedite registers that are not contained in other
+ // registers.
- JSONArray::SP threads_array_sp = std::make_shared<JSONArray>();
-
- // Ensure we can get info on the given thread.
- uint32_t thread_idx = 0;
- for ( NativeThreadProtocolSP thread_sp;
- (thread_sp = process.GetThreadAtIndex(thread_idx)) != nullptr;
- ++thread_idx)
- {
-
- lldb::tid_t tid = thread_sp->GetID();
-
- // Grab the reason this thread stopped.
- struct ThreadStopInfo tid_stop_info;
- std::string description;
- if (!thread_sp->GetStopReason (tid_stop_info, description))
- return nullptr;
-
- const int signum = tid_stop_info.details.signal.signo;
- if (log)
- {
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 " got signal signo = %d, reason = %d, exc_type = %" PRIu64,
+ RegisterValue reg_value;
+ Error error = reg_ctx_sp->ReadRegister(reg_info_p, reg_value);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("%s failed to read register '%s' index %" PRIu32 ": %s",
__FUNCTION__,
- process.GetID (),
- tid,
- signum,
- tid_stop_info.reason,
- tid_stop_info.details.exception.type);
- }
-
- JSONObject::SP thread_obj_sp = std::make_shared<JSONObject>();
- threads_array_sp->AppendObject(thread_obj_sp);
-
- if (JSONObject::SP registers_sp = GetRegistersAsJSON(*thread_sp, abridged))
- thread_obj_sp->SetObject("registers", registers_sp);
-
- thread_obj_sp->SetObject("tid", std::make_shared<JSONNumber>(tid));
- if (signum != 0)
- thread_obj_sp->SetObject("signal", std::make_shared<JSONNumber>(signum));
+ reg_info_p->name ? reg_info_p->name : "<unnamed-register>",
+ reg_num, error.AsCString());
+ continue;
+ }
+
+ StreamString stream;
+ WriteRegisterValueInHexFixedWidth(stream, reg_ctx_sp, *reg_info_p,
+ &reg_value);
+
+ register_object_sp->SetObject(
+ llvm::to_string(reg_num),
+ std::make_shared<JSONString>(stream.GetString()));
+ }
+
+ return register_object_sp;
+}
+
+static const char *GetStopReasonString(StopReason stop_reason) {
+ switch (stop_reason) {
+ case eStopReasonTrace:
+ return "trace";
+ case eStopReasonBreakpoint:
+ return "breakpoint";
+ case eStopReasonWatchpoint:
+ return "watchpoint";
+ case eStopReasonSignal:
+ return "signal";
+ case eStopReasonException:
+ return "exception";
+ case eStopReasonExec:
+ return "exec";
+ case eStopReasonInstrumentation:
+ case eStopReasonInvalid:
+ case eStopReasonPlanComplete:
+ case eStopReasonThreadExiting:
+ case eStopReasonNone:
+ break; // ignored
+ }
+ return nullptr;
+}
+
+static JSONArray::SP GetJSONThreadsInfo(NativeProcessProtocol &process,
+ bool abridged) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+
+ JSONArray::SP threads_array_sp = std::make_shared<JSONArray>();
+
+ // Ensure we can get info on the given thread.
+ uint32_t thread_idx = 0;
+ for (NativeThreadProtocolSP thread_sp;
+ (thread_sp = process.GetThreadAtIndex(thread_idx)) != nullptr;
+ ++thread_idx) {
+
+ lldb::tid_t tid = thread_sp->GetID();
- const std::string thread_name = thread_sp->GetName ();
- if (! thread_name.empty())
- thread_obj_sp->SetObject("name", std::make_shared<JSONString>(thread_name));
-
- if (const char *stop_reason_str = GetStopReasonString(tid_stop_info.reason))
- thread_obj_sp->SetObject("reason", std::make_shared<JSONString>(stop_reason_str));
-
- if (! description.empty())
- thread_obj_sp->SetObject("description", std::make_shared<JSONString>(description));
-
- if ((tid_stop_info.reason == eStopReasonException) && tid_stop_info.details.exception.type)
- {
- thread_obj_sp->SetObject("metype",
- std::make_shared<JSONNumber>(tid_stop_info.details.exception.type));
-
- JSONArray::SP medata_array_sp = std::make_shared<JSONArray>();
- for (uint32_t i = 0; i < tid_stop_info.details.exception.data_count; ++i)
- {
- medata_array_sp->AppendObject(std::make_shared<JSONNumber>(
- tid_stop_info.details.exception.data[i]));
- }
- thread_obj_sp->SetObject("medata", medata_array_sp);
- }
+ // Grab the reason this thread stopped.
+ struct ThreadStopInfo tid_stop_info;
+ std::string description;
+ if (!thread_sp->GetStopReason(tid_stop_info, description))
+ return nullptr;
- // TODO: Expedite interesting regions of inferior memory
+ const int signum = tid_stop_info.details.signal.signo;
+ if (log) {
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " tid %" PRIu64
+ " got signal signo = %d, reason = %d, exc_type = %" PRIu64,
+ __FUNCTION__, process.GetID(), tid, signum,
+ tid_stop_info.reason, tid_stop_info.details.exception.type);
}
- return threads_array_sp;
-}
+ JSONObject::SP thread_obj_sp = std::make_shared<JSONObject>();
+ threads_array_sp->AppendObject(thread_obj_sp);
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread (lldb::tid_t tid)
-{
- Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+ if (JSONObject::SP registers_sp = GetRegistersAsJSON(*thread_sp, abridged))
+ thread_obj_sp->SetObject("registers", registers_sp);
- // Ensure we have a debugged process.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- return SendErrorResponse (50);
+ thread_obj_sp->SetObject("tid", std::make_shared<JSONNumber>(tid));
+ if (signum != 0)
+ thread_obj_sp->SetObject("signal", std::make_shared<JSONNumber>(signum));
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s preparing packet for pid %" PRIu64 " tid %" PRIu64,
- __FUNCTION__, m_debugged_process_sp->GetID (), tid);
+ const std::string thread_name = thread_sp->GetName();
+ if (!thread_name.empty())
+ thread_obj_sp->SetObject("name",
+ std::make_shared<JSONString>(thread_name));
- // Ensure we can get info on the given thread.
- NativeThreadProtocolSP thread_sp (m_debugged_process_sp->GetThreadByID (tid));
- if (!thread_sp)
- return SendErrorResponse (51);
+ if (const char *stop_reason_str = GetStopReasonString(tid_stop_info.reason))
+ thread_obj_sp->SetObject("reason",
+ std::make_shared<JSONString>(stop_reason_str));
- // Grab the reason this thread stopped.
- struct ThreadStopInfo tid_stop_info;
- std::string description;
- if (!thread_sp->GetStopReason (tid_stop_info, description))
- return SendErrorResponse (52);
+ if (!description.empty())
+ thread_obj_sp->SetObject("description",
+ std::make_shared<JSONString>(description));
- // FIXME implement register handling for exec'd inferiors.
- // if (tid_stop_info.reason == eStopReasonExec)
- // {
- // const bool force = true;
- // InitializeRegisters(force);
- // }
+ if ((tid_stop_info.reason == eStopReasonException) &&
+ tid_stop_info.details.exception.type) {
+ thread_obj_sp->SetObject(
+ "metype",
+ std::make_shared<JSONNumber>(tid_stop_info.details.exception.type));
- StreamString response;
- // Output the T packet with the thread
- response.PutChar ('T');
- int signum = tid_stop_info.details.signal.signo;
- if (log)
- {
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 " got signal signo = %d, reason = %d, exc_type = %" PRIu64,
- __FUNCTION__,
- m_debugged_process_sp->GetID (),
- tid,
- signum,
- tid_stop_info.reason,
- tid_stop_info.details.exception.type);
+ JSONArray::SP medata_array_sp = std::make_shared<JSONArray>();
+ for (uint32_t i = 0; i < tid_stop_info.details.exception.data_count;
+ ++i) {
+ medata_array_sp->AppendObject(std::make_shared<JSONNumber>(
+ tid_stop_info.details.exception.data[i]));
+ }
+ thread_obj_sp->SetObject("medata", medata_array_sp);
}
- // Print the signal number.
- response.PutHex8 (signum & 0xff);
-
- // Include the tid.
- response.Printf ("thread:%" PRIx64 ";", tid);
-
- // Include the thread name if there is one.
- const std::string thread_name = thread_sp->GetName ();
- if (!thread_name.empty ())
- {
- size_t thread_name_len = thread_name.length ();
+ // TODO: Expedite interesting regions of inferior memory
+ }
- if (::strcspn (thread_name.c_str (), "$#+-;:") == thread_name_len)
- {
- response.PutCString ("name:");
- response.PutCString (thread_name.c_str ());
- }
- else
- {
- // The thread name contains special chars, send as hex bytes.
- response.PutCString ("hexname:");
- response.PutCStringAsRawHex8 (thread_name.c_str ());
- }
- response.PutChar (';');
- }
-
- // If a 'QListThreadsInStopReply' was sent to enable this feature, we
- // will send all thread IDs back in the "threads" key whose value is
- // a list of hex thread IDs separated by commas:
- // "threads:10a,10b,10c;"
- // This will save the debugger from having to send a pair of qfThreadInfo
- // and qsThreadInfo packets, but it also might take a lot of room in the
- // stop reply packet, so it must be enabled only on systems where there
- // are no limits on packet lengths.
- if (m_list_threads_in_stop_reply)
- {
- response.PutCString ("threads:");
-
- uint32_t thread_index = 0;
- NativeThreadProtocolSP listed_thread_sp;
- for (listed_thread_sp = m_debugged_process_sp->GetThreadAtIndex (thread_index); listed_thread_sp; ++thread_index, listed_thread_sp = m_debugged_process_sp->GetThreadAtIndex (thread_index))
- {
- if (thread_index > 0)
- response.PutChar (',');
- response.Printf ("%" PRIx64, listed_thread_sp->GetID ());
- }
- response.PutChar (';');
-
- // Include JSON info that describes the stop reason for any threads
- // that actually have stop reasons. We use the new "jstopinfo" key
- // whose values is hex ascii JSON that contains the thread IDs
- // thread stop info only for threads that have stop reasons. Only send
- // this if we have more than one thread otherwise this packet has all
- // the info it needs.
- if (thread_index > 0)
- {
- const bool threads_with_valid_stop_info_only = true;
- JSONArray::SP threads_info_sp = GetJSONThreadsInfo(*m_debugged_process_sp,
- threads_with_valid_stop_info_only);
- if (threads_info_sp)
- {
- response.PutCString("jstopinfo:");
- StreamString unescaped_response;
- threads_info_sp->Write(unescaped_response);
- response.PutCStringAsRawHex8(unescaped_response.GetData());
- response.PutChar(';');
- }
- else if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to prepare a jstopinfo field for pid %" PRIu64,
- __FUNCTION__, m_debugged_process_sp->GetID());
+ return threads_array_sp;
+}
- }
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
+ lldb::tid_t tid) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+
+ // Ensure we have a debugged process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID))
+ return SendErrorResponse(50);
+
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s preparing packet for pid %" PRIu64
+ " tid %" PRIu64,
+ __FUNCTION__, m_debugged_process_sp->GetID(), tid);
+
+ // Ensure we can get info on the given thread.
+ NativeThreadProtocolSP thread_sp(m_debugged_process_sp->GetThreadByID(tid));
+ if (!thread_sp)
+ return SendErrorResponse(51);
+
+ // Grab the reason this thread stopped.
+ struct ThreadStopInfo tid_stop_info;
+ std::string description;
+ if (!thread_sp->GetStopReason(tid_stop_info, description))
+ return SendErrorResponse(52);
+
+ // FIXME implement register handling for exec'd inferiors.
+ // if (tid_stop_info.reason == eStopReasonExec)
+ // {
+ // const bool force = true;
+ // InitializeRegisters(force);
+ // }
+
+ StreamString response;
+ // Output the T packet with the thread
+ response.PutChar('T');
+ int signum = tid_stop_info.details.signal.signo;
+ if (log) {
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " tid %" PRIu64
+ " got signal signo = %d, reason = %d, exc_type = %" PRIu64,
+ __FUNCTION__, m_debugged_process_sp->GetID(), tid, signum,
+ tid_stop_info.reason, tid_stop_info.details.exception.type);
+ }
+
+ // Print the signal number.
+ response.PutHex8(signum & 0xff);
+
+ // Include the tid.
+ response.Printf("thread:%" PRIx64 ";", tid);
+
+ // Include the thread name if there is one.
+ const std::string thread_name = thread_sp->GetName();
+ if (!thread_name.empty()) {
+ size_t thread_name_len = thread_name.length();
+
+ if (::strcspn(thread_name.c_str(), "$#+-;:") == thread_name_len) {
+ response.PutCString("name:");
+ response.PutCString(thread_name);
+ } else {
+ // The thread name contains special chars, send as hex bytes.
+ response.PutCString("hexname:");
+ response.PutCStringAsRawHex8(thread_name.c_str());
+ }
+ response.PutChar(';');
+ }
+
+ // If a 'QListThreadsInStopReply' was sent to enable this feature, we
+ // will send all thread IDs back in the "threads" key whose value is
+ // a list of hex thread IDs separated by commas:
+ // "threads:10a,10b,10c;"
+ // This will save the debugger from having to send a pair of qfThreadInfo
+ // and qsThreadInfo packets, but it also might take a lot of room in the
+ // stop reply packet, so it must be enabled only on systems where there
+ // are no limits on packet lengths.
+ if (m_list_threads_in_stop_reply) {
+ response.PutCString("threads:");
+
+ uint32_t thread_index = 0;
+ NativeThreadProtocolSP listed_thread_sp;
+ for (listed_thread_sp =
+ m_debugged_process_sp->GetThreadAtIndex(thread_index);
+ listed_thread_sp; ++thread_index,
+ listed_thread_sp = m_debugged_process_sp->GetThreadAtIndex(
+ thread_index)) {
+ if (thread_index > 0)
+ response.PutChar(',');
+ response.Printf("%" PRIx64, listed_thread_sp->GetID());
+ }
+ response.PutChar(';');
+
+ // Include JSON info that describes the stop reason for any threads
+ // that actually have stop reasons. We use the new "jstopinfo" key
+ // whose values is hex ascii JSON that contains the thread IDs
+ // thread stop info only for threads that have stop reasons. Only send
+ // this if we have more than one thread otherwise this packet has all
+ // the info it needs.
+ if (thread_index > 0) {
+ const bool threads_with_valid_stop_info_only = true;
+ JSONArray::SP threads_info_sp = GetJSONThreadsInfo(
+ *m_debugged_process_sp, threads_with_valid_stop_info_only);
+ if (threads_info_sp) {
+ response.PutCString("jstopinfo:");
+ StreamString unescaped_response;
+ threads_info_sp->Write(unescaped_response);
+ response.PutCStringAsRawHex8(unescaped_response.GetData());
+ response.PutChar(';');
+ } else if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to prepare a "
+ "jstopinfo field for pid %" PRIu64,
+ __FUNCTION__, m_debugged_process_sp->GetID());
}
-
- //
- // Expedite registers.
- //
-
- // Grab the register context.
- NativeRegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext ();
- if (reg_ctx_sp)
- {
- // Expedite all registers in the first register set (i.e. should be GPRs) that are not contained in other registers.
- const RegisterSet *reg_set_p;
- if (reg_ctx_sp->GetRegisterSetCount () > 0 && ((reg_set_p = reg_ctx_sp->GetRegisterSet (0)) != nullptr))
- {
+ }
+
+ //
+ // Expedite registers.
+ //
+
+ // Grab the register context.
+ NativeRegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext();
+ if (reg_ctx_sp) {
+ // Expedite all registers in the first register set (i.e. should be GPRs)
+ // that are not contained in other registers.
+ const RegisterSet *reg_set_p;
+ if (reg_ctx_sp->GetRegisterSetCount() > 0 &&
+ ((reg_set_p = reg_ctx_sp->GetRegisterSet(0)) != nullptr)) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s expediting registers "
+ "from set '%s' (registers set count: %zu)",
+ __FUNCTION__,
+ reg_set_p->name ? reg_set_p->name : "<unnamed-set>",
+ reg_set_p->num_registers);
+
+ for (const uint32_t *reg_num_p = reg_set_p->registers;
+ *reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p) {
+ const RegisterInfo *const reg_info_p =
+ reg_ctx_sp->GetRegisterInfoAtIndex(*reg_num_p);
+ if (reg_info_p == nullptr) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to get "
+ "register info for register set '%s', register index "
+ "%" PRIu32,
+ __FUNCTION__,
+ reg_set_p->name ? reg_set_p->name : "<unnamed-set>",
+ *reg_num_p);
+ } else if (reg_info_p->value_regs == nullptr) {
+ // Only expediate registers that are not contained in other registers.
+ RegisterValue reg_value;
+ Error error = reg_ctx_sp->ReadRegister(reg_info_p, reg_value);
+ if (error.Success()) {
+ response.Printf("%.02x:", *reg_num_p);
+ WriteRegisterValueInHexFixedWidth(response, reg_ctx_sp, *reg_info_p,
+ &reg_value);
+ response.PutChar(';');
+ } else {
if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s expediting registers from set '%s' (registers set count: %zu)", __FUNCTION__, reg_set_p->name ? reg_set_p->name : "<unnamed-set>", reg_set_p->num_registers);
-
- for (const uint32_t *reg_num_p = reg_set_p->registers; *reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p)
- {
- const RegisterInfo *const reg_info_p = reg_ctx_sp->GetRegisterInfoAtIndex (*reg_num_p);
- if (reg_info_p == nullptr)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to get register info for register set '%s', register index %" PRIu32, __FUNCTION__, reg_set_p->name ? reg_set_p->name : "<unnamed-set>", *reg_num_p);
- }
- else if (reg_info_p->value_regs == nullptr)
- {
- // Only expediate registers that are not contained in other registers.
- RegisterValue reg_value;
- Error error = reg_ctx_sp->ReadRegister (reg_info_p, reg_value);
- if (error.Success ())
- {
- response.Printf ("%.02x:", *reg_num_p);
- WriteRegisterValueInHexFixedWidth(response, reg_ctx_sp, *reg_info_p, &reg_value);
- response.PutChar (';');
- }
- else
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to read register '%s' index %" PRIu32 ": %s", __FUNCTION__, reg_info_p->name ? reg_info_p->name : "<unnamed-register>", *reg_num_p, error.AsCString ());
-
- }
- }
- }
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to read "
+ "register '%s' index %" PRIu32 ": %s",
+ __FUNCTION__, reg_info_p->name ? reg_info_p->name
+ : "<unnamed-register>",
+ *reg_num_p, error.AsCString());
+ }
}
+ }
}
+ }
- const char* reason_str = GetStopReasonString(tid_stop_info.reason);
- if (reason_str != nullptr)
- {
- response.Printf ("reason:%s;", reason_str);
- }
+ const char *reason_str = GetStopReasonString(tid_stop_info.reason);
+ if (reason_str != nullptr) {
+ response.Printf("reason:%s;", reason_str);
+ }
- if (!description.empty())
- {
- // Description may contains special chars, send as hex bytes.
- response.PutCString ("description:");
- response.PutCStringAsRawHex8 (description.c_str ());
- response.PutChar (';');
- }
- else if ((tid_stop_info.reason == eStopReasonException) && tid_stop_info.details.exception.type)
- {
- response.PutCString ("metype:");
- response.PutHex64 (tid_stop_info.details.exception.type);
- response.PutCString (";mecount:");
- response.PutHex32 (tid_stop_info.details.exception.data_count);
- response.PutChar (';');
-
- for (uint32_t i = 0; i < tid_stop_info.details.exception.data_count; ++i)
- {
- response.PutCString ("medata:");
- response.PutHex64 (tid_stop_info.details.exception.data[i]);
- response.PutChar (';');
- }
+ if (!description.empty()) {
+ // Description may contains special chars, send as hex bytes.
+ response.PutCString("description:");
+ response.PutCStringAsRawHex8(description.c_str());
+ response.PutChar(';');
+ } else if ((tid_stop_info.reason == eStopReasonException) &&
+ tid_stop_info.details.exception.type) {
+ response.PutCString("metype:");
+ response.PutHex64(tid_stop_info.details.exception.type);
+ response.PutCString(";mecount:");
+ response.PutHex32(tid_stop_info.details.exception.data_count);
+ response.PutChar(';');
+
+ for (uint32_t i = 0; i < tid_stop_info.details.exception.data_count; ++i) {
+ response.PutCString("medata:");
+ response.PutHex64(tid_stop_info.details.exception.data[i]);
+ response.PutChar(';');
}
+ }
- return SendPacketNoLock (response.GetData(), response.GetSize());
+ return SendPacketNoLock(response.GetString());
}
-void
-GDBRemoteCommunicationServerLLGS::HandleInferiorState_Exited (NativeProcessProtocol *process)
-{
- assert (process && "process cannot be NULL");
-
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
-
- PacketResult result = SendStopReasonForState(StateType::eStateExited);
- if (result != PacketResult::Success)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to send stop notification for PID %" PRIu64 ", state: eStateExited", __FUNCTION__, process->GetID ());
- }
+void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Exited(
+ NativeProcessProtocol *process) {
+ assert(process && "process cannot be NULL");
- // Close the pipe to the inferior terminal i/o if we launched it
- // and set one up.
- MaybeCloseInferiorTerminalConnection ();
-
- // We are ready to exit the debug monitor.
- m_exit_now = true;
-}
-
-void
-GDBRemoteCommunicationServerLLGS::HandleInferiorState_Stopped (NativeProcessProtocol *process)
-{
- assert (process && "process cannot be NULL");
-
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
-
- // Send the stop reason unless this is the stop after the
- // launch or attach.
- switch (m_inferior_prev_state)
- {
- case eStateLaunching:
- case eStateAttaching:
- // Don't send anything per debugserver behavior.
- break;
- default:
- // In all other cases, send the stop reason.
- PacketResult result = SendStopReasonForState(StateType::eStateStopped);
- if (result != PacketResult::Success)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to send stop notification for PID %" PRIu64 ", state: eStateExited", __FUNCTION__, process->GetID ());
- }
- break;
- }
-}
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
-void
-GDBRemoteCommunicationServerLLGS::ProcessStateChanged (NativeProcessProtocol *process, lldb::StateType state)
-{
- assert (process && "process cannot be NULL");
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ PacketResult result = SendStopReasonForState(StateType::eStateExited);
+ if (result != PacketResult::Success) {
if (log)
- {
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s called with NativeProcessProtocol pid %" PRIu64 ", state: %s",
- __FUNCTION__,
- process->GetID (),
- StateAsCString (state));
- }
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to send stop "
+ "notification for PID %" PRIu64 ", state: eStateExited",
+ __FUNCTION__, process->GetID());
+ }
+
+ // Close the pipe to the inferior terminal i/o if we launched it
+ // and set one up.
+ MaybeCloseInferiorTerminalConnection();
+
+ // We are ready to exit the debug monitor.
+ m_exit_now = true;
+}
+
+void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Stopped(
+ NativeProcessProtocol *process) {
+ assert(process && "process cannot be NULL");
+
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
+
+ // Send the stop reason unless this is the stop after the
+ // launch or attach.
+ switch (m_inferior_prev_state) {
+ case eStateLaunching:
+ case eStateAttaching:
+ // Don't send anything per debugserver behavior.
+ break;
+ default:
+ // In all other cases, send the stop reason.
+ PacketResult result = SendStopReasonForState(StateType::eStateStopped);
+ if (result != PacketResult::Success) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to send stop "
+ "notification for PID %" PRIu64 ", state: eStateExited",
+ __FUNCTION__, process->GetID());
+ }
+ break;
+ }
+}
+
+void GDBRemoteCommunicationServerLLGS::ProcessStateChanged(
+ NativeProcessProtocol *process, lldb::StateType state) {
+ assert(process && "process cannot be NULL");
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log) {
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s called with "
+ "NativeProcessProtocol pid %" PRIu64 ", state: %s",
+ __FUNCTION__, process->GetID(), StateAsCString(state));
+ }
+
+ switch (state) {
+ case StateType::eStateRunning:
+ StartSTDIOForwarding();
+ break;
+
+ case StateType::eStateStopped:
+ // Make sure we get all of the pending stdout/stderr from the inferior
+ // and send it to the lldb host before we send the state change
+ // notification
+ SendProcessOutput();
+ // Then stop the forwarding, so that any late output (see llvm.org/pr25652)
+ // does not
+ // interfere with our protocol.
+ StopSTDIOForwarding();
+ HandleInferiorState_Stopped(process);
+ break;
- switch (state)
- {
- case StateType::eStateRunning:
- StartSTDIOForwarding();
- break;
-
- case StateType::eStateStopped:
- // Make sure we get all of the pending stdout/stderr from the inferior
- // and send it to the lldb host before we send the state change
- // notification
- SendProcessOutput();
- // Then stop the forwarding, so that any late output (see llvm.org/pr25652) does not
- // interfere with our protocol.
- StopSTDIOForwarding();
- HandleInferiorState_Stopped (process);
- break;
-
- case StateType::eStateExited:
- // Same as above
- SendProcessOutput();
- StopSTDIOForwarding();
- HandleInferiorState_Exited (process);
- break;
+ case StateType::eStateExited:
+ // Same as above
+ SendProcessOutput();
+ StopSTDIOForwarding();
+ HandleInferiorState_Exited(process);
+ break;
- default:
- if (log)
- {
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s didn't handle state change for pid %" PRIu64 ", new state: %s",
- __FUNCTION__,
- process->GetID (),
- StateAsCString (state));
- }
- break;
+ default:
+ if (log) {
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s didn't handle state "
+ "change for pid %" PRIu64 ", new state: %s",
+ __FUNCTION__, process->GetID(), StateAsCString(state));
}
+ break;
+ }
- // Remember the previous state reported to us.
- m_inferior_prev_state = state;
+ // Remember the previous state reported to us.
+ m_inferior_prev_state = state;
}
-void
-GDBRemoteCommunicationServerLLGS::DidExec (NativeProcessProtocol *process)
-{
- ClearProcessSpecificData ();
+void GDBRemoteCommunicationServerLLGS::DidExec(NativeProcessProtocol *process) {
+ ClearProcessSpecificData();
}
-void
-GDBRemoteCommunicationServerLLGS::DataAvailableCallback ()
-{
- Log *log (GetLogIfAnyCategoriesSet(GDBR_LOG_COMM));
+void GDBRemoteCommunicationServerLLGS::DataAvailableCallback() {
+ Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_COMM));
- if (! m_handshake_completed)
- {
- if (! HandshakeWithClient())
- {
- if(log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s handshake with client failed, exiting",
- __FUNCTION__);
- m_mainloop.RequestTermination();
- return;
- }
- m_handshake_completed = true;
+ if (!m_handshake_completed) {
+ if (!HandshakeWithClient()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s handshake with "
+ "client failed, exiting",
+ __FUNCTION__);
+ m_mainloop.RequestTermination();
+ return;
}
+ m_handshake_completed = true;
+ }
- bool interrupt = false;
- bool done = false;
- Error error;
- while (true)
- {
- const PacketResult result = GetPacketAndSendResponse (0, error, interrupt, done);
- if (result == PacketResult::ErrorReplyTimeout)
- break; // No more packets in the queue
-
- if ((result != PacketResult::Success))
- {
- if(log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s processing a packet failed: %s",
- __FUNCTION__, error.AsCString());
- m_mainloop.RequestTermination();
- break;
- }
+ bool interrupt = false;
+ bool done = false;
+ Error error;
+ while (true) {
+ const PacketResult result = GetPacketAndSendResponse(
+ std::chrono::microseconds(0), error, interrupt, done);
+ if (result == PacketResult::ErrorReplyTimeout)
+ break; // No more packets in the queue
+
+ if ((result != PacketResult::Success)) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s processing a packet "
+ "failed: %s",
+ __FUNCTION__, error.AsCString());
+ m_mainloop.RequestTermination();
+ break;
}
+ }
}
-Error
-GDBRemoteCommunicationServerLLGS::InitializeConnection (std::unique_ptr<Connection> &&connection)
-{
- IOObjectSP read_object_sp = connection->GetReadObject();
- GDBRemoteCommunicationServer::SetConnection(connection.release());
+Error GDBRemoteCommunicationServerLLGS::InitializeConnection(
+ std::unique_ptr<Connection> &&connection) {
+ IOObjectSP read_object_sp = connection->GetReadObject();
+ GDBRemoteCommunicationServer::SetConnection(connection.release());
- Error error;
- m_network_handle_up = m_mainloop.RegisterReadObject(read_object_sp,
- [this] (MainLoopBase &) { DataAvailableCallback(); }, error);
- return error;
+ Error error;
+ m_network_handle_up = m_mainloop.RegisterReadObject(
+ read_object_sp, [this](MainLoopBase &) { DataAvailableCallback(); },
+ error);
+ return error;
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::SendONotification (const char *buffer, uint32_t len)
-{
- if ((buffer == nullptr) || (len == 0))
- {
- // Nothing to send.
- return PacketResult::Success;
- }
-
- StreamString response;
- response.PutChar ('O');
- response.PutBytesAsRawHex8 (buffer, len);
-
- return SendPacketNoLock (response.GetData (), response.GetSize ());
-}
-
-Error
-GDBRemoteCommunicationServerLLGS::SetSTDIOFileDescriptor (int fd)
-{
- Error error;
-
- // Set up the reading/handling of process I/O
- std::unique_ptr<ConnectionFileDescriptor> conn_up (new ConnectionFileDescriptor (fd, true));
- if (!conn_up)
- {
- error.SetErrorString ("failed to create ConnectionFileDescriptor");
- return error;
- }
+GDBRemoteCommunicationServerLLGS::SendONotification(const char *buffer,
+ uint32_t len) {
+ if ((buffer == nullptr) || (len == 0)) {
+ // Nothing to send.
+ return PacketResult::Success;
+ }
- m_stdio_communication.SetCloseOnEOF (false);
- m_stdio_communication.SetConnection (conn_up.release());
- if (!m_stdio_communication.IsConnected ())
- {
- error.SetErrorString ("failed to set connection for inferior I/O communication");
- return error;
- }
+ StreamString response;
+ response.PutChar('O');
+ response.PutBytesAsRawHex8(buffer, len);
- return Error();
+ return SendPacketNoLock(response.GetString());
}
-void
-GDBRemoteCommunicationServerLLGS::StartSTDIOForwarding()
-{
- // Don't forward if not connected (e.g. when attaching).
- if (! m_stdio_communication.IsConnected())
- return;
-
- // llgs local-process debugging may specify PTY paths, which will make these
- // file actions non-null
- // process launch -e/o will also make these file actions non-null
- // nullptr means that the traffic is expected to flow over gdb-remote protocol
- if ( m_process_launch_info.GetFileActionForFD(STDOUT_FILENO) &&
- m_process_launch_info.GetFileActionForFD(STDERR_FILENO))
- return;
-
- Error error;
- lldbassert(! m_stdio_handle_up);
- m_stdio_handle_up = m_mainloop.RegisterReadObject(
- m_stdio_communication.GetConnection()->GetReadObject(),
- [this] (MainLoopBase &) { SendProcessOutput(); }, error);
-
- if (! m_stdio_handle_up)
- {
- // Not much we can do about the failure. Log it and continue without forwarding.
- if (Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS))
- log->Printf("GDBRemoteCommunicationServerLLGS::%s Failed to set up stdio forwarding: %s",
- __FUNCTION__, error.AsCString());
- }
-}
+Error GDBRemoteCommunicationServerLLGS::SetSTDIOFileDescriptor(int fd) {
+ Error error;
-void
-GDBRemoteCommunicationServerLLGS::StopSTDIOForwarding()
-{
- m_stdio_handle_up.reset();
-}
+ // Set up the reading/handling of process I/O
+ std::unique_ptr<ConnectionFileDescriptor> conn_up(
+ new ConnectionFileDescriptor(fd, true));
+ if (!conn_up) {
+ error.SetErrorString("failed to create ConnectionFileDescriptor");
+ return error;
+ }
-void
-GDBRemoteCommunicationServerLLGS::SendProcessOutput()
-{
- char buffer[1024];
- ConnectionStatus status;
- Error error;
- while (true)
- {
- size_t bytes_read = m_stdio_communication.Read(buffer, sizeof buffer, 0, status, &error);
- switch (status)
- {
- case eConnectionStatusSuccess:
- SendONotification(buffer, bytes_read);
- break;
- case eConnectionStatusLostConnection:
- case eConnectionStatusEndOfFile:
- case eConnectionStatusError:
- case eConnectionStatusNoConnection:
- if (Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS))
- log->Printf("GDBRemoteCommunicationServerLLGS::%s Stopping stdio forwarding as communication returned status %d (error: %s)", __FUNCTION__, status, error.AsCString());
- m_stdio_handle_up.reset();
- return;
-
- case eConnectionStatusInterrupted:
- case eConnectionStatusTimedOut:
- return;
- }
- }
+ m_stdio_communication.SetCloseOnEOF(false);
+ m_stdio_communication.SetConnection(conn_up.release());
+ if (!m_stdio_communication.IsConnected()) {
+ error.SetErrorString(
+ "failed to set connection for inferior I/O communication");
+ return error;
+ }
+
+ return Error();
+}
+
+void GDBRemoteCommunicationServerLLGS::StartSTDIOForwarding() {
+ // Don't forward if not connected (e.g. when attaching).
+ if (!m_stdio_communication.IsConnected())
+ return;
+
+ Error error;
+ lldbassert(!m_stdio_handle_up);
+ m_stdio_handle_up = m_mainloop.RegisterReadObject(
+ m_stdio_communication.GetConnection()->GetReadObject(),
+ [this](MainLoopBase &) { SendProcessOutput(); }, error);
+
+ if (!m_stdio_handle_up) {
+ // Not much we can do about the failure. Log it and continue without
+ // forwarding.
+ if (Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS))
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s Failed to set up stdio "
+ "forwarding: %s",
+ __FUNCTION__, error.AsCString());
+ }
+}
+
+void GDBRemoteCommunicationServerLLGS::StopSTDIOForwarding() {
+ m_stdio_handle_up.reset();
+}
+
+void GDBRemoteCommunicationServerLLGS::SendProcessOutput() {
+ char buffer[1024];
+ ConnectionStatus status;
+ Error error;
+ while (true) {
+ size_t bytes_read = m_stdio_communication.Read(
+ buffer, sizeof buffer, std::chrono::microseconds(0), status, &error);
+ switch (status) {
+ case eConnectionStatusSuccess:
+ SendONotification(buffer, bytes_read);
+ break;
+ case eConnectionStatusLostConnection:
+ case eConnectionStatusEndOfFile:
+ case eConnectionStatusError:
+ case eConnectionStatusNoConnection:
+ if (Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS))
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s Stopping stdio "
+ "forwarding as communication returned status %d (error: "
+ "%s)",
+ __FUNCTION__, status, error.AsCString());
+ m_stdio_handle_up.reset();
+ return;
+
+ case eConnectionStatusInterrupted:
+ case eConnectionStatusTimedOut:
+ return;
+ }
+ }
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qProcessInfo (StringExtractorGDBRemote &packet)
-{
- // Fail if we don't have a current process.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- return SendErrorResponse (68);
+GDBRemoteCommunicationServerLLGS::Handle_qProcessInfo(
+ StringExtractorGDBRemote &packet) {
+ // Fail if we don't have a current process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID))
+ return SendErrorResponse(68);
- lldb::pid_t pid = m_debugged_process_sp->GetID ();
+ lldb::pid_t pid = m_debugged_process_sp->GetID();
- if (pid == LLDB_INVALID_PROCESS_ID)
- return SendErrorResponse (1);
+ if (pid == LLDB_INVALID_PROCESS_ID)
+ return SendErrorResponse(1);
- ProcessInstanceInfo proc_info;
- if (!Host::GetProcessInfo (pid, proc_info))
- return SendErrorResponse (1);
+ ProcessInstanceInfo proc_info;
+ if (!Host::GetProcessInfo(pid, proc_info))
+ return SendErrorResponse(1);
- StreamString response;
- CreateProcessInfoResponse_DebugServerStyle(proc_info, response);
- return SendPacketNoLock (response.GetData (), response.GetSize ());
+ StreamString response;
+ CreateProcessInfoResponse_DebugServerStyle(proc_info, response);
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qC (StringExtractorGDBRemote &packet)
-{
- // Fail if we don't have a current process.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- return SendErrorResponse (68);
+GDBRemoteCommunicationServerLLGS::Handle_qC(StringExtractorGDBRemote &packet) {
+ // Fail if we don't have a current process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID))
+ return SendErrorResponse(68);
- // Make sure we set the current thread so g and p packets return
- // the data the gdb will expect.
- lldb::tid_t tid = m_debugged_process_sp->GetCurrentThreadID ();
- SetCurrentThreadID (tid);
+ // Make sure we set the current thread so g and p packets return
+ // the data the gdb will expect.
+ lldb::tid_t tid = m_debugged_process_sp->GetCurrentThreadID();
+ SetCurrentThreadID(tid);
- NativeThreadProtocolSP thread_sp = m_debugged_process_sp->GetCurrentThread ();
- if (!thread_sp)
- return SendErrorResponse (69);
+ NativeThreadProtocolSP thread_sp = m_debugged_process_sp->GetCurrentThread();
+ if (!thread_sp)
+ return SendErrorResponse(69);
- StreamString response;
- response.Printf ("QC%" PRIx64, thread_sp->GetID ());
+ StreamString response;
+ response.Printf("QC%" PRIx64, thread_sp->GetID());
- return SendPacketNoLock (response.GetData(), response.GetSize());
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_k (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+GDBRemoteCommunicationServerLLGS::Handle_k(StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- StopSTDIOForwarding();
+ StopSTDIOForwarding();
- if (! m_debugged_process_sp)
- {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s No debugged process found.", __FUNCTION__);
- return PacketResult::Success;
- }
+ if (!m_debugged_process_sp) {
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s No debugged process found.",
+ __FUNCTION__);
+ return PacketResult::Success;
+ }
- Error error = m_debugged_process_sp->Kill();
- if (error.Fail() && log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s Failed to kill debugged process %" PRIu64 ": %s",
- __FUNCTION__, m_debugged_process_sp->GetID(), error.AsCString());
+ Error error = m_debugged_process_sp->Kill();
+ if (error.Fail() && log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s Failed to kill debugged "
+ "process %" PRIu64 ": %s",
+ __FUNCTION__, m_debugged_process_sp->GetID(),
+ error.AsCString());
- // No OK response for kill packet.
- // return SendOKResponse ();
- return PacketResult::Success;
+ // No OK response for kill packet.
+ // return SendOKResponse ();
+ return PacketResult::Success;
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_QSetDisableASLR (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen ("QSetDisableASLR:"));
- if (packet.GetU32(0))
- m_process_launch_info.GetFlags().Set (eLaunchFlagDisableASLR);
- else
- m_process_launch_info.GetFlags().Clear (eLaunchFlagDisableASLR);
- return SendOKResponse ();
+GDBRemoteCommunicationServerLLGS::Handle_QSetDisableASLR(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("QSetDisableASLR:"));
+ if (packet.GetU32(0))
+ m_process_launch_info.GetFlags().Set(eLaunchFlagDisableASLR);
+ else
+ m_process_launch_info.GetFlags().Clear(eLaunchFlagDisableASLR);
+ return SendOKResponse();
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_QSetWorkingDir (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos (::strlen ("QSetWorkingDir:"));
- std::string path;
- packet.GetHexByteString (path);
- m_process_launch_info.SetWorkingDirectory(FileSpec{path, true});
- return SendOKResponse ();
+GDBRemoteCommunicationServerLLGS::Handle_QSetWorkingDir(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("QSetWorkingDir:"));
+ std::string path;
+ packet.GetHexByteString(path);
+ m_process_launch_info.SetWorkingDirectory(FileSpec{path, true});
+ return SendOKResponse();
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir (StringExtractorGDBRemote &packet)
-{
- FileSpec working_dir{m_process_launch_info.GetWorkingDirectory()};
- if (working_dir)
- {
- StreamString response;
- response.PutCStringAsRawHex8(working_dir.GetCString());
- return SendPacketNoLock(response.GetData(), response.GetSize());
- }
+GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir(
+ StringExtractorGDBRemote &packet) {
+ FileSpec working_dir{m_process_launch_info.GetWorkingDirectory()};
+ if (working_dir) {
+ StreamString response;
+ response.PutCStringAsRawHex8(working_dir.GetCString());
+ return SendPacketNoLock(response.GetString());
+ }
- return SendErrorResponse(14);
+ return SendErrorResponse(14);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_C (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS|LIBLLDB_LOG_THREAD));
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
-
- // Ensure we have a native process.
- if (!m_debugged_process_sp)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s no debugged process shared pointer", __FUNCTION__);
- return SendErrorResponse (0x36);
- }
-
- // Pull out the signal number.
- packet.SetFilePos (::strlen ("C"));
- if (packet.GetBytesLeft () < 1)
- {
- // Shouldn't be using a C without a signal.
- return SendIllFormedResponse (packet, "C packet specified without signal.");
- }
- const uint32_t signo = packet.GetHexMaxU32 (false, std::numeric_limits<uint32_t>::max ());
- if (signo == std::numeric_limits<uint32_t>::max ())
- return SendIllFormedResponse (packet, "failed to parse signal number");
-
- // Handle optional continue address.
- if (packet.GetBytesLeft () > 0)
- {
- // FIXME add continue at address support for $C{signo}[;{continue-address}].
- if (*packet.Peek () == ';')
- return SendUnimplementedResponse (packet.GetStringRef().c_str());
- else
- return SendIllFormedResponse (packet, "unexpected content after $C{signal-number}");
- }
+GDBRemoteCommunicationServerLLGS::Handle_C(StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
- ResumeActionList resume_actions (StateType::eStateRunning, 0);
- Error error;
-
- // We have two branches: what to do if a continue thread is specified (in which case we target
- // sending the signal to that thread), or when we don't have a continue thread set (in which
- // case we send a signal to the process).
-
- // TODO discuss with Greg Clayton, make sure this makes sense.
-
- lldb::tid_t signal_tid = GetContinueThreadID ();
- if (signal_tid != LLDB_INVALID_THREAD_ID)
- {
- // The resume action for the continue thread (or all threads if a continue thread is not set).
- ResumeAction action = { GetContinueThreadID (), StateType::eStateRunning, static_cast<int> (signo) };
-
- // Add the action for the continue thread (or all threads when the continue thread isn't present).
- resume_actions.Append (action);
- }
+ // Ensure we have a native process.
+ if (!m_debugged_process_sp) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s no debugged process "
+ "shared pointer",
+ __FUNCTION__);
+ return SendErrorResponse(0x36);
+ }
+
+ // Pull out the signal number.
+ packet.SetFilePos(::strlen("C"));
+ if (packet.GetBytesLeft() < 1) {
+ // Shouldn't be using a C without a signal.
+ return SendIllFormedResponse(packet, "C packet specified without signal.");
+ }
+ const uint32_t signo =
+ packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max());
+ if (signo == std::numeric_limits<uint32_t>::max())
+ return SendIllFormedResponse(packet, "failed to parse signal number");
+
+ // Handle optional continue address.
+ if (packet.GetBytesLeft() > 0) {
+ // FIXME add continue at address support for $C{signo}[;{continue-address}].
+ if (*packet.Peek() == ';')
+ return SendUnimplementedResponse(packet.GetStringRef().c_str());
else
- {
- // Send the signal to the process since we weren't targeting a specific continue thread with the signal.
- error = m_debugged_process_sp->Signal (signo);
- if (error.Fail ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to send signal for process %" PRIu64 ": %s",
- __FUNCTION__,
- m_debugged_process_sp->GetID (),
- error.AsCString ());
-
- return SendErrorResponse (0x52);
- }
- }
-
- // Resume the threads.
- error = m_debugged_process_sp->Resume (resume_actions);
- if (error.Fail ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to resume threads for process %" PRIu64 ": %s",
- __FUNCTION__,
- m_debugged_process_sp->GetID (),
- error.AsCString ());
+ return SendIllFormedResponse(
+ packet, "unexpected content after $C{signal-number}");
+ }
+
+ ResumeActionList resume_actions(StateType::eStateRunning, 0);
+ Error error;
+
+ // We have two branches: what to do if a continue thread is specified (in
+ // which case we target
+ // sending the signal to that thread), or when we don't have a continue thread
+ // set (in which
+ // case we send a signal to the process).
+
+ // TODO discuss with Greg Clayton, make sure this makes sense.
+
+ lldb::tid_t signal_tid = GetContinueThreadID();
+ if (signal_tid != LLDB_INVALID_THREAD_ID) {
+ // The resume action for the continue thread (or all threads if a continue
+ // thread is not set).
+ ResumeAction action = {GetContinueThreadID(), StateType::eStateRunning,
+ static_cast<int>(signo)};
+
+ // Add the action for the continue thread (or all threads when the continue
+ // thread isn't present).
+ resume_actions.Append(action);
+ } else {
+ // Send the signal to the process since we weren't targeting a specific
+ // continue thread with the signal.
+ error = m_debugged_process_sp->Signal(signo);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to send "
+ "signal for process %" PRIu64 ": %s",
+ __FUNCTION__, m_debugged_process_sp->GetID(),
+ error.AsCString());
+
+ return SendErrorResponse(0x52);
+ }
+ }
+
+ // Resume the threads.
+ error = m_debugged_process_sp->Resume(resume_actions);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to resume "
+ "threads for process %" PRIu64 ": %s",
+ __FUNCTION__, m_debugged_process_sp->GetID(),
+ error.AsCString());
- return SendErrorResponse (0x38);
- }
+ return SendErrorResponse(0x38);
+ }
- // Don't send an "OK" packet; response is the stopped/exited message.
- return PacketResult::Success;
+ // Don't send an "OK" packet; response is the stopped/exited message.
+ return PacketResult::Success;
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_c (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS|LIBLLDB_LOG_THREAD));
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
-
- packet.SetFilePos (packet.GetFilePos() + ::strlen ("c"));
+GDBRemoteCommunicationServerLLGS::Handle_c(StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
- // For now just support all continue.
- const bool has_continue_address = (packet.GetBytesLeft () > 0);
- if (has_continue_address)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s not implemented for c{address} variant [%s remains]", __FUNCTION__, packet.Peek ());
- return SendUnimplementedResponse (packet.GetStringRef().c_str());
- }
+ packet.SetFilePos(packet.GetFilePos() + ::strlen("c"));
- // Ensure we have a native process.
- if (!m_debugged_process_sp)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s no debugged process shared pointer", __FUNCTION__);
- return SendErrorResponse (0x36);
- }
+ // For now just support all continue.
+ const bool has_continue_address = (packet.GetBytesLeft() > 0);
+ if (has_continue_address) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s not implemented for "
+ "c{address} variant [%s remains]",
+ __FUNCTION__, packet.Peek());
+ return SendUnimplementedResponse(packet.GetStringRef().c_str());
+ }
+
+ // Ensure we have a native process.
+ if (!m_debugged_process_sp) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s no debugged process "
+ "shared pointer",
+ __FUNCTION__);
+ return SendErrorResponse(0x36);
+ }
- // Build the ResumeActionList
- ResumeActionList actions (StateType::eStateRunning, 0);
+ // Build the ResumeActionList
+ ResumeActionList actions(StateType::eStateRunning, 0);
- Error error = m_debugged_process_sp->Resume (actions);
- if (error.Fail ())
- {
- if (log)
- {
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s c failed for process %" PRIu64 ": %s",
- __FUNCTION__,
- m_debugged_process_sp->GetID (),
- error.AsCString ());
- }
- return SendErrorResponse (GDBRemoteServerError::eErrorResume);
+ Error error = m_debugged_process_sp->Resume(actions);
+ if (error.Fail()) {
+ if (log) {
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s c failed for process %" PRIu64
+ ": %s",
+ __FUNCTION__, m_debugged_process_sp->GetID(), error.AsCString());
}
+ return SendErrorResponse(GDBRemoteServerError::eErrorResume);
+ }
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s continued process %" PRIu64, __FUNCTION__, m_debugged_process_sp->GetID ());
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s continued process %" PRIu64,
+ __FUNCTION__, m_debugged_process_sp->GetID());
- // No response required from continue.
- return PacketResult::Success;
+ // No response required from continue.
+ return PacketResult::Success;
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_vCont_actions (StringExtractorGDBRemote &packet)
-{
- StreamString response;
- response.Printf("vCont;c;C;s;S");
+GDBRemoteCommunicationServerLLGS::Handle_vCont_actions(
+ StringExtractorGDBRemote &packet) {
+ StreamString response;
+ response.Printf("vCont;c;C;s;S");
- return SendPacketNoLock(response.GetData(), response.GetSize());
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_vCont (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s handling vCont packet", __FUNCTION__);
-
- packet.SetFilePos (::strlen ("vCont"));
+GDBRemoteCommunicationServerLLGS::Handle_vCont(
+ StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s handling vCont packet",
+ __FUNCTION__);
- if (packet.GetBytesLeft() == 0)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s missing action from vCont package", __FUNCTION__);
- return SendIllFormedResponse (packet, "Missing action from vCont package");
- }
+ packet.SetFilePos(::strlen("vCont"));
- // Check if this is all continue (no options or ";c").
- if (::strcmp (packet.Peek (), ";c") == 0)
- {
- // Move past the ';', then do a simple 'c'.
- packet.SetFilePos (packet.GetFilePos () + 1);
- return Handle_c (packet);
- }
- else if (::strcmp (packet.Peek (), ";s") == 0)
- {
- // Move past the ';', then do a simple 's'.
- packet.SetFilePos (packet.GetFilePos () + 1);
- return Handle_s (packet);
- }
+ if (packet.GetBytesLeft() == 0) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s missing action from "
+ "vCont package",
+ __FUNCTION__);
+ return SendIllFormedResponse(packet, "Missing action from vCont package");
+ }
+
+ // Check if this is all continue (no options or ";c").
+ if (::strcmp(packet.Peek(), ";c") == 0) {
+ // Move past the ';', then do a simple 'c'.
+ packet.SetFilePos(packet.GetFilePos() + 1);
+ return Handle_c(packet);
+ } else if (::strcmp(packet.Peek(), ";s") == 0) {
+ // Move past the ';', then do a simple 's'.
+ packet.SetFilePos(packet.GetFilePos() + 1);
+ return Handle_s(packet);
+ }
+
+ // Ensure we have a native process.
+ if (!m_debugged_process_sp) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s no debugged process "
+ "shared pointer",
+ __FUNCTION__);
+ return SendErrorResponse(0x36);
+ }
+
+ ResumeActionList thread_actions;
+
+ while (packet.GetBytesLeft() && *packet.Peek() == ';') {
+ // Skip the semi-colon.
+ packet.GetChar();
+
+ // Build up the thread action.
+ ResumeAction thread_action;
+ thread_action.tid = LLDB_INVALID_THREAD_ID;
+ thread_action.state = eStateInvalid;
+ thread_action.signal = 0;
+
+ const char action = packet.GetChar();
+ switch (action) {
+ case 'C':
+ thread_action.signal = packet.GetHexMaxU32(false, 0);
+ if (thread_action.signal == 0)
+ return SendIllFormedResponse(
+ packet, "Could not parse signal in vCont packet C action");
+ LLVM_FALLTHROUGH;
+
+ case 'c':
+ // Continue
+ thread_action.state = eStateRunning;
+ break;
+
+ case 'S':
+ thread_action.signal = packet.GetHexMaxU32(false, 0);
+ if (thread_action.signal == 0)
+ return SendIllFormedResponse(
+ packet, "Could not parse signal in vCont packet S action");
+ LLVM_FALLTHROUGH;
+
+ case 's':
+ // Step
+ thread_action.state = eStateStepping;
+ break;
- // Ensure we have a native process.
- if (!m_debugged_process_sp)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s no debugged process shared pointer", __FUNCTION__);
- return SendErrorResponse (0x36);
+ default:
+ return SendIllFormedResponse(packet, "Unsupported vCont action");
+ break;
}
- ResumeActionList thread_actions;
-
- while (packet.GetBytesLeft () && *packet.Peek () == ';')
- {
- // Skip the semi-colon.
- packet.GetChar ();
-
- // Build up the thread action.
- ResumeAction thread_action;
- thread_action.tid = LLDB_INVALID_THREAD_ID;
- thread_action.state = eStateInvalid;
- thread_action.signal = 0;
-
- const char action = packet.GetChar ();
- switch (action)
- {
- case 'C':
- thread_action.signal = packet.GetHexMaxU32 (false, 0);
- if (thread_action.signal == 0)
- return SendIllFormedResponse (packet, "Could not parse signal in vCont packet C action");
- LLVM_FALLTHROUGH;
-
- case 'c':
- // Continue
- thread_action.state = eStateRunning;
- break;
-
- case 'S':
- thread_action.signal = packet.GetHexMaxU32 (false, 0);
- if (thread_action.signal == 0)
- return SendIllFormedResponse (packet, "Could not parse signal in vCont packet S action");
- LLVM_FALLTHROUGH;
-
- case 's':
- // Step
- thread_action.state = eStateStepping;
- break;
-
- default:
- return SendIllFormedResponse (packet, "Unsupported vCont action");
- break;
- }
-
- // Parse out optional :{thread-id} value.
- if (packet.GetBytesLeft () && (*packet.Peek () == ':'))
- {
- // Consume the separator.
- packet.GetChar ();
-
- thread_action.tid = packet.GetHexMaxU32 (false, LLDB_INVALID_THREAD_ID);
- if (thread_action.tid == LLDB_INVALID_THREAD_ID)
- return SendIllFormedResponse (packet, "Could not parse thread number in vCont packet");
- }
+ // Parse out optional :{thread-id} value.
+ if (packet.GetBytesLeft() && (*packet.Peek() == ':')) {
+ // Consume the separator.
+ packet.GetChar();
- thread_actions.Append (thread_action);
+ thread_action.tid = packet.GetHexMaxU32(false, LLDB_INVALID_THREAD_ID);
+ if (thread_action.tid == LLDB_INVALID_THREAD_ID)
+ return SendIllFormedResponse(
+ packet, "Could not parse thread number in vCont packet");
}
- Error error = m_debugged_process_sp->Resume (thread_actions);
- if (error.Fail ())
- {
- if (log)
- {
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s vCont failed for process %" PRIu64 ": %s",
- __FUNCTION__,
- m_debugged_process_sp->GetID (),
- error.AsCString ());
- }
- return SendErrorResponse (GDBRemoteServerError::eErrorResume);
+ thread_actions.Append(thread_action);
+ }
+
+ Error error = m_debugged_process_sp->Resume(thread_actions);
+ if (error.Fail()) {
+ if (log) {
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s vCont failed for "
+ "process %" PRIu64 ": %s",
+ __FUNCTION__, m_debugged_process_sp->GetID(),
+ error.AsCString());
}
+ return SendErrorResponse(GDBRemoteServerError::eErrorResume);
+ }
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s continued process %" PRIu64, __FUNCTION__, m_debugged_process_sp->GetID ());
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s continued process %" PRIu64,
+ __FUNCTION__, m_debugged_process_sp->GetID());
- // No response required from vCont.
- return PacketResult::Success;
+ // No response required from vCont.
+ return PacketResult::Success;
}
-void
-GDBRemoteCommunicationServerLLGS::SetCurrentThreadID (lldb::tid_t tid)
-{
- Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_THREAD));
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s setting current thread id to %" PRIu64, __FUNCTION__, tid);
+void GDBRemoteCommunicationServerLLGS::SetCurrentThreadID(lldb::tid_t tid) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s setting current thread "
+ "id to %" PRIu64,
+ __FUNCTION__, tid);
- m_current_tid = tid;
- if (m_debugged_process_sp)
- m_debugged_process_sp->SetCurrentThreadID (m_current_tid);
+ m_current_tid = tid;
+ if (m_debugged_process_sp)
+ m_debugged_process_sp->SetCurrentThreadID(m_current_tid);
}
-void
-GDBRemoteCommunicationServerLLGS::SetContinueThreadID (lldb::tid_t tid)
-{
- Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_THREAD));
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s setting continue thread id to %" PRIu64, __FUNCTION__, tid);
+void GDBRemoteCommunicationServerLLGS::SetContinueThreadID(lldb::tid_t tid) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s setting continue thread "
+ "id to %" PRIu64,
+ __FUNCTION__, tid);
- m_continue_tid = tid;
+ m_continue_tid = tid;
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_stop_reason (StringExtractorGDBRemote &packet)
-{
- // Handle the $? gdbremote command.
+GDBRemoteCommunicationServerLLGS::Handle_stop_reason(
+ StringExtractorGDBRemote &packet) {
+ // Handle the $? gdbremote command.
- // If no process, indicate error
- if (!m_debugged_process_sp)
- return SendErrorResponse (02);
+ // If no process, indicate error
+ if (!m_debugged_process_sp)
+ return SendErrorResponse(02);
- return SendStopReasonForState (m_debugged_process_sp->GetState());
+ return SendStopReasonForState(m_debugged_process_sp->GetState());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::SendStopReasonForState (lldb::StateType process_state)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- switch (process_state)
- {
- case eStateAttaching:
- case eStateLaunching:
- case eStateRunning:
- case eStateStepping:
- case eStateDetached:
- // NOTE: gdb protocol doc looks like it should return $OK
- // when everything is running (i.e. no stopped result).
- return PacketResult::Success; // Ignore
-
- case eStateSuspended:
- case eStateStopped:
- case eStateCrashed:
- {
- lldb::tid_t tid = m_debugged_process_sp->GetCurrentThreadID ();
- // Make sure we set the current thread so g and p packets return
- // the data the gdb will expect.
- SetCurrentThreadID (tid);
- return SendStopReplyPacketForThread (tid);
- }
+GDBRemoteCommunicationServerLLGS::SendStopReasonForState(
+ lldb::StateType process_state) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ switch (process_state) {
+ case eStateAttaching:
+ case eStateLaunching:
+ case eStateRunning:
+ case eStateStepping:
+ case eStateDetached:
+ // NOTE: gdb protocol doc looks like it should return $OK
+ // when everything is running (i.e. no stopped result).
+ return PacketResult::Success; // Ignore
+
+ case eStateSuspended:
+ case eStateStopped:
+ case eStateCrashed: {
+ lldb::tid_t tid = m_debugged_process_sp->GetCurrentThreadID();
+ // Make sure we set the current thread so g and p packets return
+ // the data the gdb will expect.
+ SetCurrentThreadID(tid);
+ return SendStopReplyPacketForThread(tid);
+ }
- case eStateInvalid:
- case eStateUnloaded:
- case eStateExited:
- return SendWResponse(m_debugged_process_sp.get());
+ case eStateInvalid:
+ case eStateUnloaded:
+ case eStateExited:
+ return SendWResponse(m_debugged_process_sp.get());
- default:
- if (log)
- {
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 ", current state reporting not handled: %s",
- __FUNCTION__,
- m_debugged_process_sp->GetID (),
- StateAsCString (process_state));
- }
- break;
+ default:
+ if (log) {
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ ", current state reporting not handled: %s",
+ __FUNCTION__, m_debugged_process_sp->GetID(),
+ StateAsCString(process_state));
}
-
- return SendErrorResponse (0);
+ break;
+ }
+
+ return SendErrorResponse(0);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo (StringExtractorGDBRemote &packet)
-{
- // Fail if we don't have a current process.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- return SendErrorResponse (68);
-
- // Ensure we have a thread.
- NativeThreadProtocolSP thread_sp (m_debugged_process_sp->GetThreadAtIndex (0));
- if (!thread_sp)
- return SendErrorResponse (69);
-
- // Get the register context for the first thread.
- NativeRegisterContextSP reg_context_sp (thread_sp->GetRegisterContext ());
- if (!reg_context_sp)
- return SendErrorResponse (69);
-
- // Parse out the register number from the request.
- packet.SetFilePos (strlen("qRegisterInfo"));
- const uint32_t reg_index = packet.GetHexMaxU32 (false, std::numeric_limits<uint32_t>::max ());
- if (reg_index == std::numeric_limits<uint32_t>::max ())
- return SendErrorResponse (69);
-
- // Return the end of registers response if we've iterated one past the end of the register set.
- if (reg_index >= reg_context_sp->GetUserRegisterCount ())
- return SendErrorResponse (69);
-
- const RegisterInfo *reg_info = reg_context_sp->GetRegisterInfoAtIndex(reg_index);
- if (!reg_info)
- return SendErrorResponse (69);
-
- // Build the reginfos response.
- StreamGDBRemote response;
-
- response.PutCString ("name:");
- response.PutCString (reg_info->name);
- response.PutChar (';');
-
- if (reg_info->alt_name && reg_info->alt_name[0])
- {
- response.PutCString ("alt-name:");
- response.PutCString (reg_info->alt_name);
- response.PutChar (';');
- }
-
- response.Printf ("bitsize:%" PRIu32 ";offset:%" PRIu32 ";", reg_info->byte_size * 8, reg_info->byte_offset);
-
- switch (reg_info->encoding)
- {
- case eEncodingUint: response.PutCString ("encoding:uint;"); break;
- case eEncodingSint: response.PutCString ("encoding:sint;"); break;
- case eEncodingIEEE754: response.PutCString ("encoding:ieee754;"); break;
- case eEncodingVector: response.PutCString ("encoding:vector;"); break;
- default: break;
- }
-
- switch (reg_info->format)
- {
- case eFormatBinary: response.PutCString ("format:binary;"); break;
- case eFormatDecimal: response.PutCString ("format:decimal;"); break;
- case eFormatHex: response.PutCString ("format:hex;"); break;
- case eFormatFloat: response.PutCString ("format:float;"); break;
- case eFormatVectorOfSInt8: response.PutCString ("format:vector-sint8;"); break;
- case eFormatVectorOfUInt8: response.PutCString ("format:vector-uint8;"); break;
- case eFormatVectorOfSInt16: response.PutCString ("format:vector-sint16;"); break;
- case eFormatVectorOfUInt16: response.PutCString ("format:vector-uint16;"); break;
- case eFormatVectorOfSInt32: response.PutCString ("format:vector-sint32;"); break;
- case eFormatVectorOfUInt32: response.PutCString ("format:vector-uint32;"); break;
- case eFormatVectorOfFloat32: response.PutCString ("format:vector-float32;"); break;
- case eFormatVectorOfUInt128: response.PutCString ("format:vector-uint128;"); break;
- default: break;
- };
-
- const char *const register_set_name = reg_context_sp->GetRegisterSetNameForRegisterAtIndex(reg_index);
- if (register_set_name)
- {
- response.PutCString ("set:");
- response.PutCString (register_set_name);
- response.PutChar (';');
- }
-
- if (reg_info->kinds[RegisterKind::eRegisterKindEHFrame] != LLDB_INVALID_REGNUM)
- response.Printf ("ehframe:%" PRIu32 ";", reg_info->kinds[RegisterKind::eRegisterKindEHFrame]);
-
- if (reg_info->kinds[RegisterKind::eRegisterKindDWARF] != LLDB_INVALID_REGNUM)
- response.Printf ("dwarf:%" PRIu32 ";", reg_info->kinds[RegisterKind::eRegisterKindDWARF]);
-
- switch (reg_info->kinds[RegisterKind::eRegisterKindGeneric])
- {
- case LLDB_REGNUM_GENERIC_PC: response.PutCString("generic:pc;"); break;
- case LLDB_REGNUM_GENERIC_SP: response.PutCString("generic:sp;"); break;
- case LLDB_REGNUM_GENERIC_FP: response.PutCString("generic:fp;"); break;
- case LLDB_REGNUM_GENERIC_RA: response.PutCString("generic:ra;"); break;
- case LLDB_REGNUM_GENERIC_FLAGS: response.PutCString("generic:flags;"); break;
- case LLDB_REGNUM_GENERIC_ARG1: response.PutCString("generic:arg1;"); break;
- case LLDB_REGNUM_GENERIC_ARG2: response.PutCString("generic:arg2;"); break;
- case LLDB_REGNUM_GENERIC_ARG3: response.PutCString("generic:arg3;"); break;
- case LLDB_REGNUM_GENERIC_ARG4: response.PutCString("generic:arg4;"); break;
- case LLDB_REGNUM_GENERIC_ARG5: response.PutCString("generic:arg5;"); break;
- case LLDB_REGNUM_GENERIC_ARG6: response.PutCString("generic:arg6;"); break;
- case LLDB_REGNUM_GENERIC_ARG7: response.PutCString("generic:arg7;"); break;
- case LLDB_REGNUM_GENERIC_ARG8: response.PutCString("generic:arg8;"); break;
- default: break;
- }
-
- if (reg_info->value_regs && reg_info->value_regs[0] != LLDB_INVALID_REGNUM)
- {
- response.PutCString ("container-regs:");
- int i = 0;
- for (const uint32_t *reg_num = reg_info->value_regs; *reg_num != LLDB_INVALID_REGNUM; ++reg_num, ++i)
- {
- if (i > 0)
- response.PutChar (',');
- response.Printf ("%" PRIx32, *reg_num);
- }
- response.PutChar (';');
- }
-
- if (reg_info->invalidate_regs && reg_info->invalidate_regs[0])
- {
- response.PutCString ("invalidate-regs:");
- int i = 0;
- for (const uint32_t *reg_num = reg_info->invalidate_regs; *reg_num != LLDB_INVALID_REGNUM; ++reg_num, ++i)
- {
- if (i > 0)
- response.PutChar (',');
- response.Printf ("%" PRIx32, *reg_num);
- }
- response.PutChar (';');
- }
-
- if (reg_info->dynamic_size_dwarf_expr_bytes)
- {
- const size_t dwarf_opcode_len = reg_info->dynamic_size_dwarf_len;
- response.PutCString("dynamic_size_dwarf_expr_bytes:");
- for(uint32_t i = 0; i < dwarf_opcode_len; ++i)
- response.PutHex8 (reg_info->dynamic_size_dwarf_expr_bytes[i]);
- response.PutChar(';');
- }
- return SendPacketNoLock(response.GetData(), response.GetSize());
+GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo(
+ StringExtractorGDBRemote &packet) {
+ // Fail if we don't have a current process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID))
+ return SendErrorResponse(68);
+
+ // Ensure we have a thread.
+ NativeThreadProtocolSP thread_sp(m_debugged_process_sp->GetThreadAtIndex(0));
+ if (!thread_sp)
+ return SendErrorResponse(69);
+
+ // Get the register context for the first thread.
+ NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext());
+ if (!reg_context_sp)
+ return SendErrorResponse(69);
+
+ // Parse out the register number from the request.
+ packet.SetFilePos(strlen("qRegisterInfo"));
+ const uint32_t reg_index =
+ packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max());
+ if (reg_index == std::numeric_limits<uint32_t>::max())
+ return SendErrorResponse(69);
+
+ // Return the end of registers response if we've iterated one past the end of
+ // the register set.
+ if (reg_index >= reg_context_sp->GetUserRegisterCount())
+ return SendErrorResponse(69);
+
+ const RegisterInfo *reg_info =
+ reg_context_sp->GetRegisterInfoAtIndex(reg_index);
+ if (!reg_info)
+ return SendErrorResponse(69);
+
+ // Build the reginfos response.
+ StreamGDBRemote response;
+
+ response.PutCString("name:");
+ response.PutCString(reg_info->name);
+ response.PutChar(';');
+
+ if (reg_info->alt_name && reg_info->alt_name[0]) {
+ response.PutCString("alt-name:");
+ response.PutCString(reg_info->alt_name);
+ response.PutChar(';');
+ }
+
+ response.Printf("bitsize:%" PRIu32 ";offset:%" PRIu32 ";",
+ reg_info->byte_size * 8, reg_info->byte_offset);
+
+ switch (reg_info->encoding) {
+ case eEncodingUint:
+ response.PutCString("encoding:uint;");
+ break;
+ case eEncodingSint:
+ response.PutCString("encoding:sint;");
+ break;
+ case eEncodingIEEE754:
+ response.PutCString("encoding:ieee754;");
+ break;
+ case eEncodingVector:
+ response.PutCString("encoding:vector;");
+ break;
+ default:
+ break;
+ }
+
+ switch (reg_info->format) {
+ case eFormatBinary:
+ response.PutCString("format:binary;");
+ break;
+ case eFormatDecimal:
+ response.PutCString("format:decimal;");
+ break;
+ case eFormatHex:
+ response.PutCString("format:hex;");
+ break;
+ case eFormatFloat:
+ response.PutCString("format:float;");
+ break;
+ case eFormatVectorOfSInt8:
+ response.PutCString("format:vector-sint8;");
+ break;
+ case eFormatVectorOfUInt8:
+ response.PutCString("format:vector-uint8;");
+ break;
+ case eFormatVectorOfSInt16:
+ response.PutCString("format:vector-sint16;");
+ break;
+ case eFormatVectorOfUInt16:
+ response.PutCString("format:vector-uint16;");
+ break;
+ case eFormatVectorOfSInt32:
+ response.PutCString("format:vector-sint32;");
+ break;
+ case eFormatVectorOfUInt32:
+ response.PutCString("format:vector-uint32;");
+ break;
+ case eFormatVectorOfFloat32:
+ response.PutCString("format:vector-float32;");
+ break;
+ case eFormatVectorOfUInt64:
+ response.PutCString("format:vector-uint64;");
+ break;
+ case eFormatVectorOfUInt128:
+ response.PutCString("format:vector-uint128;");
+ break;
+ default:
+ break;
+ };
+
+ const char *const register_set_name =
+ reg_context_sp->GetRegisterSetNameForRegisterAtIndex(reg_index);
+ if (register_set_name) {
+ response.PutCString("set:");
+ response.PutCString(register_set_name);
+ response.PutChar(';');
+ }
+
+ if (reg_info->kinds[RegisterKind::eRegisterKindEHFrame] !=
+ LLDB_INVALID_REGNUM)
+ response.Printf("ehframe:%" PRIu32 ";",
+ reg_info->kinds[RegisterKind::eRegisterKindEHFrame]);
+
+ if (reg_info->kinds[RegisterKind::eRegisterKindDWARF] != LLDB_INVALID_REGNUM)
+ response.Printf("dwarf:%" PRIu32 ";",
+ reg_info->kinds[RegisterKind::eRegisterKindDWARF]);
+
+ switch (reg_info->kinds[RegisterKind::eRegisterKindGeneric]) {
+ case LLDB_REGNUM_GENERIC_PC:
+ response.PutCString("generic:pc;");
+ break;
+ case LLDB_REGNUM_GENERIC_SP:
+ response.PutCString("generic:sp;");
+ break;
+ case LLDB_REGNUM_GENERIC_FP:
+ response.PutCString("generic:fp;");
+ break;
+ case LLDB_REGNUM_GENERIC_RA:
+ response.PutCString("generic:ra;");
+ break;
+ case LLDB_REGNUM_GENERIC_FLAGS:
+ response.PutCString("generic:flags;");
+ break;
+ case LLDB_REGNUM_GENERIC_ARG1:
+ response.PutCString("generic:arg1;");
+ break;
+ case LLDB_REGNUM_GENERIC_ARG2:
+ response.PutCString("generic:arg2;");
+ break;
+ case LLDB_REGNUM_GENERIC_ARG3:
+ response.PutCString("generic:arg3;");
+ break;
+ case LLDB_REGNUM_GENERIC_ARG4:
+ response.PutCString("generic:arg4;");
+ break;
+ case LLDB_REGNUM_GENERIC_ARG5:
+ response.PutCString("generic:arg5;");
+ break;
+ case LLDB_REGNUM_GENERIC_ARG6:
+ response.PutCString("generic:arg6;");
+ break;
+ case LLDB_REGNUM_GENERIC_ARG7:
+ response.PutCString("generic:arg7;");
+ break;
+ case LLDB_REGNUM_GENERIC_ARG8:
+ response.PutCString("generic:arg8;");
+ break;
+ default:
+ break;
+ }
+
+ if (reg_info->value_regs && reg_info->value_regs[0] != LLDB_INVALID_REGNUM) {
+ response.PutCString("container-regs:");
+ int i = 0;
+ for (const uint32_t *reg_num = reg_info->value_regs;
+ *reg_num != LLDB_INVALID_REGNUM; ++reg_num, ++i) {
+ if (i > 0)
+ response.PutChar(',');
+ response.Printf("%" PRIx32, *reg_num);
+ }
+ response.PutChar(';');
+ }
+
+ if (reg_info->invalidate_regs && reg_info->invalidate_regs[0]) {
+ response.PutCString("invalidate-regs:");
+ int i = 0;
+ for (const uint32_t *reg_num = reg_info->invalidate_regs;
+ *reg_num != LLDB_INVALID_REGNUM; ++reg_num, ++i) {
+ if (i > 0)
+ response.PutChar(',');
+ response.Printf("%" PRIx32, *reg_num);
+ }
+ response.PutChar(';');
+ }
+
+ if (reg_info->dynamic_size_dwarf_expr_bytes) {
+ const size_t dwarf_opcode_len = reg_info->dynamic_size_dwarf_len;
+ response.PutCString("dynamic_size_dwarf_expr_bytes:");
+ for (uint32_t i = 0; i < dwarf_opcode_len; ++i)
+ response.PutHex8(reg_info->dynamic_size_dwarf_expr_bytes[i]);
+ response.PutChar(';');
+ }
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
-
- // Fail if we don't have a current process.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s() no process (%s), returning OK", __FUNCTION__, m_debugged_process_sp ? "invalid process id" : "null m_debugged_process_sp");
- return SendOKResponse ();
- }
-
- StreamGDBRemote response;
- response.PutChar ('m');
+GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo(
+ StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+ // Fail if we don't have a current process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s() starting thread iteration", __FUNCTION__);
-
- NativeThreadProtocolSP thread_sp;
- uint32_t thread_index;
- for (thread_index = 0, thread_sp = m_debugged_process_sp->GetThreadAtIndex (thread_index);
- thread_sp;
- ++thread_index, thread_sp = m_debugged_process_sp->GetThreadAtIndex (thread_index))
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s() iterated thread %" PRIu32 "(%s, tid=0x%" PRIx64 ")", __FUNCTION__, thread_index, thread_sp ? "is not null" : "null", thread_sp ? thread_sp->GetID () : LLDB_INVALID_THREAD_ID);
- if (thread_index > 0)
- response.PutChar(',');
- response.Printf ("%" PRIx64, thread_sp->GetID ());
- }
-
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s() no process (%s), "
+ "returning OK",
+ __FUNCTION__,
+ m_debugged_process_sp ? "invalid process id"
+ : "null m_debugged_process_sp");
+ return SendOKResponse();
+ }
+
+ StreamGDBRemote response;
+ response.PutChar('m');
+
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s() starting thread iteration",
+ __FUNCTION__);
+
+ NativeThreadProtocolSP thread_sp;
+ uint32_t thread_index;
+ for (thread_index = 0,
+ thread_sp = m_debugged_process_sp->GetThreadAtIndex(thread_index);
+ thread_sp; ++thread_index,
+ thread_sp = m_debugged_process_sp->GetThreadAtIndex(thread_index)) {
if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s() finished thread iteration", __FUNCTION__);
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s() iterated thread %" PRIu32
+ "(%s, tid=0x%" PRIx64 ")",
+ __FUNCTION__, thread_index, thread_sp ? "is not null" : "null",
+ thread_sp ? thread_sp->GetID() : LLDB_INVALID_THREAD_ID);
+ if (thread_index > 0)
+ response.PutChar(',');
+ response.Printf("%" PRIx64, thread_sp->GetID());
+ }
+
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s() finished thread iteration",
+ __FUNCTION__);
- return SendPacketNoLock(response.GetData(), response.GetSize());
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qsThreadInfo (StringExtractorGDBRemote &packet)
-{
- // FIXME for now we return the full thread list in the initial packet and always do nothing here.
- return SendPacketNoLock ("l", 1);
+GDBRemoteCommunicationServerLLGS::Handle_qsThreadInfo(
+ StringExtractorGDBRemote &packet) {
+ // FIXME for now we return the full thread list in the initial packet and
+ // always do nothing here.
+ return SendPacketNoLock("l");
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_p (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
-
- // Parse out the register number from the request.
- packet.SetFilePos (strlen("p"));
- const uint32_t reg_index = packet.GetHexMaxU32 (false, std::numeric_limits<uint32_t>::max ());
- if (reg_index == std::numeric_limits<uint32_t>::max ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, could not parse register number from request \"%s\"", __FUNCTION__, packet.GetStringRef ().c_str ());
- return SendErrorResponse (0x15);
- }
-
- // Get the thread to use.
- NativeThreadProtocolSP thread_sp = GetThreadFromSuffix (packet);
- if (!thread_sp)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no thread available", __FUNCTION__);
- return SendErrorResponse (0x15);
- }
-
- // Get the thread's register context.
- NativeRegisterContextSP reg_context_sp (thread_sp->GetRegisterContext ());
- if (!reg_context_sp)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 " failed, no register context available for the thread", __FUNCTION__, m_debugged_process_sp->GetID (), thread_sp->GetID ());
- return SendErrorResponse (0x15);
- }
-
- // Return the end of registers response if we've iterated one past the end of the register set.
- if (reg_index >= reg_context_sp->GetUserRegisterCount ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, requested register %" PRIu32 " beyond register count %" PRIu32, __FUNCTION__, reg_index, reg_context_sp->GetUserRegisterCount ());
- return SendErrorResponse (0x15);
- }
-
- const RegisterInfo *reg_info = reg_context_sp->GetRegisterInfoAtIndex(reg_index);
- if (!reg_info)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, requested register %" PRIu32 " returned NULL", __FUNCTION__, reg_index);
- return SendErrorResponse (0x15);
- }
-
- // Build the reginfos response.
- StreamGDBRemote response;
-
- // Retrieve the value
- RegisterValue reg_value;
- Error error = reg_context_sp->ReadRegister (reg_info, reg_value);
- if (error.Fail ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, read of requested register %" PRIu32 " (%s) failed: %s", __FUNCTION__, reg_index, reg_info->name, error.AsCString ());
- return SendErrorResponse (0x15);
- }
-
- const uint8_t *const data = reinterpret_cast<const uint8_t*> (reg_value.GetBytes ());
- if (!data)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to get data bytes from requested register %" PRIu32, __FUNCTION__, reg_index);
- return SendErrorResponse (0x15);
- }
+GDBRemoteCommunicationServerLLGS::Handle_p(StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+
+ // Parse out the register number from the request.
+ packet.SetFilePos(strlen("p"));
+ const uint32_t reg_index =
+ packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max());
+ if (reg_index == std::numeric_limits<uint32_t>::max()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, could not "
+ "parse register number from request \"%s\"",
+ __FUNCTION__, packet.GetStringRef().c_str());
+ return SendErrorResponse(0x15);
+ }
+
+ // Get the thread to use.
+ NativeThreadProtocolSP thread_sp = GetThreadFromSuffix(packet);
+ if (!thread_sp) {
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s failed, no thread available",
+ __FUNCTION__);
+ return SendErrorResponse(0x15);
+ }
+
+ // Get the thread's register context.
+ NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext());
+ if (!reg_context_sp) {
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64
+ " failed, no register context available for the thread",
+ __FUNCTION__, m_debugged_process_sp->GetID(), thread_sp->GetID());
+ return SendErrorResponse(0x15);
+ }
+
+ // Return the end of registers response if we've iterated one past the end of
+ // the register set.
+ if (reg_index >= reg_context_sp->GetUserRegisterCount()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested "
+ "register %" PRIu32 " beyond register count %" PRIu32,
+ __FUNCTION__, reg_index,
+ reg_context_sp->GetUserRegisterCount());
+ return SendErrorResponse(0x15);
+ }
+
+ const RegisterInfo *reg_info =
+ reg_context_sp->GetRegisterInfoAtIndex(reg_index);
+ if (!reg_info) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested "
+ "register %" PRIu32 " returned NULL",
+ __FUNCTION__, reg_index);
+ return SendErrorResponse(0x15);
+ }
+
+ // Build the reginfos response.
+ StreamGDBRemote response;
+
+ // Retrieve the value
+ RegisterValue reg_value;
+ Error error = reg_context_sp->ReadRegister(reg_info, reg_value);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, read of "
+ "requested register %" PRIu32 " (%s) failed: %s",
+ __FUNCTION__, reg_index, reg_info->name, error.AsCString());
+ return SendErrorResponse(0x15);
+ }
+
+ const uint8_t *const data =
+ reinterpret_cast<const uint8_t *>(reg_value.GetBytes());
+ if (!data) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to get data "
+ "bytes from requested register %" PRIu32,
+ __FUNCTION__, reg_index);
+ return SendErrorResponse(0x15);
+ }
- // FIXME flip as needed to get data in big/little endian format for this host.
- for (uint32_t i = 0; i < reg_value.GetByteSize (); ++i)
- response.PutHex8 (data[i]);
+ // FIXME flip as needed to get data in big/little endian format for this host.
+ for (uint32_t i = 0; i < reg_value.GetByteSize(); ++i)
+ response.PutHex8(data[i]);
- return SendPacketNoLock (response.GetData (), response.GetSize ());
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_P (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
-
- // Ensure there is more content.
- if (packet.GetBytesLeft () < 1)
- return SendIllFormedResponse (packet, "Empty P packet");
-
- // Parse out the register number from the request.
- packet.SetFilePos (strlen("P"));
- const uint32_t reg_index = packet.GetHexMaxU32 (false, std::numeric_limits<uint32_t>::max ());
- if (reg_index == std::numeric_limits<uint32_t>::max ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, could not parse register number from request \"%s\"", __FUNCTION__, packet.GetStringRef ().c_str ());
- return SendErrorResponse (0x29);
- }
-
- // Note debugserver would send an E30 here.
- if ((packet.GetBytesLeft () < 1) || (packet.GetChar () != '='))
- return SendIllFormedResponse (packet, "P packet missing '=' char after register number");
-
- // Get process architecture.
- ArchSpec process_arch;
- if (!m_debugged_process_sp || !m_debugged_process_sp->GetArchitecture (process_arch))
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to retrieve inferior architecture", __FUNCTION__);
- return SendErrorResponse (0x49);
- }
-
- // Parse out the value.
- uint8_t reg_bytes[32]; // big enough to support up to 256 bit ymmN register
- size_t reg_size = packet.GetHexBytesAvail (reg_bytes, sizeof(reg_bytes));
-
- // Get the thread to use.
- NativeThreadProtocolSP thread_sp = GetThreadFromSuffix (packet);
- if (!thread_sp)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no thread available (thread index 0)", __FUNCTION__);
- return SendErrorResponse (0x28);
- }
-
- // Get the thread's register context.
- NativeRegisterContextSP reg_context_sp (thread_sp->GetRegisterContext ());
- if (!reg_context_sp)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 " failed, no register context available for the thread", __FUNCTION__, m_debugged_process_sp->GetID (), thread_sp->GetID ());
- return SendErrorResponse (0x15);
- }
-
- const RegisterInfo *reg_info = reg_context_sp->GetRegisterInfoAtIndex (reg_index);
- if (!reg_info)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, requested register %" PRIu32 " returned NULL", __FUNCTION__, reg_index);
- return SendErrorResponse (0x48);
- }
-
- // Return the end of registers response if we've iterated one past the end of the register set.
- if (reg_index >= reg_context_sp->GetUserRegisterCount ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, requested register %" PRIu32 " beyond register count %" PRIu32, __FUNCTION__, reg_index, reg_context_sp->GetUserRegisterCount ());
- return SendErrorResponse (0x47);
- }
-
- // The dwarf expression are evaluate on host site
- // which may cause register size to change
- // Hence the reg_size may not be same as reg_info->bytes_size
- if ((reg_size != reg_info->byte_size) && !(reg_info->dynamic_size_dwarf_expr_bytes))
- {
- return SendIllFormedResponse (packet, "P packet register size is incorrect");
- }
-
- // Build the reginfos response.
- StreamGDBRemote response;
-
- RegisterValue reg_value (reg_bytes, reg_size, process_arch.GetByteOrder ());
- Error error = reg_context_sp->WriteRegister (reg_info, reg_value);
- if (error.Fail ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, write of requested register %" PRIu32 " (%s) failed: %s", __FUNCTION__, reg_index, reg_info->name, error.AsCString ());
- return SendErrorResponse (0x32);
- }
+GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+
+ // Ensure there is more content.
+ if (packet.GetBytesLeft() < 1)
+ return SendIllFormedResponse(packet, "Empty P packet");
+
+ // Parse out the register number from the request.
+ packet.SetFilePos(strlen("P"));
+ const uint32_t reg_index =
+ packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max());
+ if (reg_index == std::numeric_limits<uint32_t>::max()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, could not "
+ "parse register number from request \"%s\"",
+ __FUNCTION__, packet.GetStringRef().c_str());
+ return SendErrorResponse(0x29);
+ }
+
+ // Note debugserver would send an E30 here.
+ if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != '='))
+ return SendIllFormedResponse(
+ packet, "P packet missing '=' char after register number");
+
+ // Get process architecture.
+ ArchSpec process_arch;
+ if (!m_debugged_process_sp ||
+ !m_debugged_process_sp->GetArchitecture(process_arch)) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to retrieve "
+ "inferior architecture",
+ __FUNCTION__);
+ return SendErrorResponse(0x49);
+ }
+
+ // Parse out the value.
+ uint8_t reg_bytes[32]; // big enough to support up to 256 bit ymmN register
+ size_t reg_size = packet.GetHexBytesAvail(reg_bytes);
+
+ // Get the thread to use.
+ NativeThreadProtocolSP thread_sp = GetThreadFromSuffix(packet);
+ if (!thread_sp) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, no thread "
+ "available (thread index 0)",
+ __FUNCTION__);
+ return SendErrorResponse(0x28);
+ }
+
+ // Get the thread's register context.
+ NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext());
+ if (!reg_context_sp) {
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64
+ " failed, no register context available for the thread",
+ __FUNCTION__, m_debugged_process_sp->GetID(), thread_sp->GetID());
+ return SendErrorResponse(0x15);
+ }
+
+ const RegisterInfo *reg_info =
+ reg_context_sp->GetRegisterInfoAtIndex(reg_index);
+ if (!reg_info) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested "
+ "register %" PRIu32 " returned NULL",
+ __FUNCTION__, reg_index);
+ return SendErrorResponse(0x48);
+ }
+
+ // Return the end of registers response if we've iterated one past the end of
+ // the register set.
+ if (reg_index >= reg_context_sp->GetUserRegisterCount()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested "
+ "register %" PRIu32 " beyond register count %" PRIu32,
+ __FUNCTION__, reg_index,
+ reg_context_sp->GetUserRegisterCount());
+ return SendErrorResponse(0x47);
+ }
+
+ // The dwarf expression are evaluate on host site
+ // which may cause register size to change
+ // Hence the reg_size may not be same as reg_info->bytes_size
+ if ((reg_size != reg_info->byte_size) &&
+ !(reg_info->dynamic_size_dwarf_expr_bytes)) {
+ return SendIllFormedResponse(packet, "P packet register size is incorrect");
+ }
+
+ // Build the reginfos response.
+ StreamGDBRemote response;
+
+ RegisterValue reg_value(reg_bytes, reg_size, process_arch.GetByteOrder());
+ Error error = reg_context_sp->WriteRegister(reg_info, reg_value);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, write of "
+ "requested register %" PRIu32 " (%s) failed: %s",
+ __FUNCTION__, reg_index, reg_info->name, error.AsCString());
+ return SendErrorResponse(0x32);
+ }
- return SendOKResponse();
+ return SendOKResponse();
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_H (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
-
- // Fail if we don't have a current process.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
- return SendErrorResponse (0x15);
- }
-
- // Parse out which variant of $H is requested.
- packet.SetFilePos (strlen("H"));
- if (packet.GetBytesLeft () < 1)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, H command missing {g,c} variant", __FUNCTION__);
- return SendIllFormedResponse (packet, "H command missing {g,c} variant");
- }
-
- const char h_variant = packet.GetChar ();
- switch (h_variant)
- {
- case 'g':
- break;
-
- case 'c':
- break;
-
- default:
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, invalid $H variant %c", __FUNCTION__, h_variant);
- return SendIllFormedResponse (packet, "H variant unsupported, should be c or g");
- }
-
- // Parse out the thread number.
- // FIXME return a parse success/fail value. All values are valid here.
- const lldb::tid_t tid = packet.GetHexMaxU64 (false, std::numeric_limits<lldb::tid_t>::max ());
+GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
- // Ensure we have the given thread when not specifying -1 (all threads) or 0 (any thread).
- if (tid != LLDB_INVALID_THREAD_ID && tid != 0)
- {
- NativeThreadProtocolSP thread_sp (m_debugged_process_sp->GetThreadByID (tid));
- if (!thread_sp)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, tid %" PRIu64 " not found", __FUNCTION__, tid);
- return SendErrorResponse (0x15);
- }
- }
+ // Fail if we don't have a current process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
+ return SendErrorResponse(0x15);
+ }
+
+ // Parse out which variant of $H is requested.
+ packet.SetFilePos(strlen("H"));
+ if (packet.GetBytesLeft() < 1) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, H command "
+ "missing {g,c} variant",
+ __FUNCTION__);
+ return SendIllFormedResponse(packet, "H command missing {g,c} variant");
+ }
- // Now switch the given thread type.
- switch (h_variant)
- {
- case 'g':
- SetCurrentThreadID (tid);
- break;
+ const char h_variant = packet.GetChar();
+ switch (h_variant) {
+ case 'g':
+ break;
- case 'c':
- SetContinueThreadID (tid);
- break;
+ case 'c':
+ break;
- default:
- assert (false && "unsupported $H variant - shouldn't get here");
- return SendIllFormedResponse (packet, "H variant unsupported, should be c or g");
- }
-
- return SendOKResponse();
+ default:
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s failed, invalid $H variant %c",
+ __FUNCTION__, h_variant);
+ return SendIllFormedResponse(packet,
+ "H variant unsupported, should be c or g");
+ }
+
+ // Parse out the thread number.
+ // FIXME return a parse success/fail value. All values are valid here.
+ const lldb::tid_t tid =
+ packet.GetHexMaxU64(false, std::numeric_limits<lldb::tid_t>::max());
+
+ // Ensure we have the given thread when not specifying -1 (all threads) or 0
+ // (any thread).
+ if (tid != LLDB_INVALID_THREAD_ID && tid != 0) {
+ NativeThreadProtocolSP thread_sp(m_debugged_process_sp->GetThreadByID(tid));
+ if (!thread_sp) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, tid %" PRIu64
+ " not found",
+ __FUNCTION__, tid);
+ return SendErrorResponse(0x15);
+ }
+ }
+
+ // Now switch the given thread type.
+ switch (h_variant) {
+ case 'g':
+ SetCurrentThreadID(tid);
+ break;
+
+ case 'c':
+ SetContinueThreadID(tid);
+ break;
+
+ default:
+ assert(false && "unsupported $H variant - shouldn't get here");
+ return SendIllFormedResponse(packet,
+ "H variant unsupported, should be c or g");
+ }
+
+ return SendOKResponse();
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_I (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+GDBRemoteCommunicationServerLLGS::Handle_I(StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
- // Fail if we don't have a current process.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
- return SendErrorResponse (0x15);
- }
-
- packet.SetFilePos (::strlen("I"));
- char tmp[4096];
- for (;;)
- {
- size_t read = packet.GetHexBytesAvail(tmp, sizeof(tmp));
- if (read == 0)
- {
- break;
- }
- // write directly to stdin *this might block if stdin buffer is full*
- // TODO: enqueue this block in circular buffer and send window size to remote host
- ConnectionStatus status;
- Error error;
- m_stdio_communication.Write(tmp, read, status, &error);
- if (error.Fail())
- {
- return SendErrorResponse (0x15);
- }
+ // Fail if we don't have a current process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
+ return SendErrorResponse(0x15);
+ }
+
+ packet.SetFilePos(::strlen("I"));
+ uint8_t tmp[4096];
+ for (;;) {
+ size_t read = packet.GetHexBytesAvail(tmp);
+ if (read == 0) {
+ break;
+ }
+ // write directly to stdin *this might block if stdin buffer is full*
+ // TODO: enqueue this block in circular buffer and send window size to
+ // remote host
+ ConnectionStatus status;
+ Error error;
+ m_stdio_communication.Write(tmp, read, status, &error);
+ if (error.Fail()) {
+ return SendErrorResponse(0x15);
}
+ }
- return SendOKResponse();
+ return SendOKResponse();
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_interrupt (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
-
- // Fail if we don't have a current process.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
- return SendErrorResponse (0x15);
- }
-
- // Interrupt the process.
- Error error = m_debugged_process_sp->Interrupt ();
- if (error.Fail ())
- {
- if (log)
- {
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed for process %" PRIu64 ": %s",
- __FUNCTION__,
- m_debugged_process_sp->GetID (),
- error.AsCString ());
- }
- return SendErrorResponse (GDBRemoteServerError::eErrorResume);
- }
+GDBRemoteCommunicationServerLLGS::Handle_interrupt(
+ StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+ // Fail if we don't have a current process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s stopped process %" PRIu64, __FUNCTION__, m_debugged_process_sp->GetID ());
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
+ return SendErrorResponse(0x15);
+ }
+
+ // Interrupt the process.
+ Error error = m_debugged_process_sp->Interrupt();
+ if (error.Fail()) {
+ if (log) {
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s failed for process %" PRIu64
+ ": %s",
+ __FUNCTION__, m_debugged_process_sp->GetID(), error.AsCString());
+ }
+ return SendErrorResponse(GDBRemoteServerError::eErrorResume);
+ }
+
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s stopped process %" PRIu64,
+ __FUNCTION__, m_debugged_process_sp->GetID());
- // No response required from stop all.
- return PacketResult::Success;
+ // No response required from stop all.
+ return PacketResult::Success;
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_memory_read(StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
- return SendErrorResponse (0x15);
- }
-
- // Parse out the memory address.
- packet.SetFilePos (strlen("m"));
- if (packet.GetBytesLeft() < 1)
- return SendIllFormedResponse(packet, "Too short m packet");
-
- // Read the address. Punting on validation.
- // FIXME replace with Hex U64 read with no default value that fails on failed read.
- const lldb::addr_t read_addr = packet.GetHexMaxU64(false, 0);
-
- // Validate comma.
- if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ','))
- return SendIllFormedResponse(packet, "Comma sep missing in m packet");
-
- // Get # bytes to read.
- if (packet.GetBytesLeft() < 1)
- return SendIllFormedResponse(packet, "Length missing in m packet");
-
- const uint64_t byte_count = packet.GetHexMaxU64(false, 0);
- if (byte_count == 0)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s nothing to read: zero-length packet", __FUNCTION__);
- return SendOKResponse();
- }
-
- // Allocate the response buffer.
- std::string buf(byte_count, '\0');
- if (buf.empty())
- return SendErrorResponse (0x78);
-
-
- // Retrieve the process memory.
- size_t bytes_read = 0;
- Error error = m_debugged_process_sp->ReadMemoryWithoutTrap(read_addr, &buf[0], byte_count, bytes_read);
- if (error.Fail ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " mem 0x%" PRIx64 ": failed to read. Error: %s", __FUNCTION__, m_debugged_process_sp->GetID (), read_addr, error.AsCString ());
- return SendErrorResponse (0x08);
- }
+GDBRemoteCommunicationServerLLGS::Handle_memory_read(
+ StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (bytes_read == 0)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " mem 0x%" PRIx64 ": read 0 of %" PRIu64 " requested bytes", __FUNCTION__, m_debugged_process_sp->GetID (), read_addr, byte_count);
- return SendErrorResponse (0x08);
- }
-
- StreamGDBRemote response;
- packet.SetFilePos(0);
- char kind = packet.GetChar('?');
- if (kind == 'x')
- response.PutEscapedBytes(buf.data(), byte_count);
- else
- {
- assert(kind == 'm');
- for (size_t i = 0; i < bytes_read; ++i)
- response.PutHex8(buf[i]);
- }
-
- return SendPacketNoLock(response.GetData(), response.GetSize());
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
+ return SendErrorResponse(0x15);
+ }
+
+ // Parse out the memory address.
+ packet.SetFilePos(strlen("m"));
+ if (packet.GetBytesLeft() < 1)
+ return SendIllFormedResponse(packet, "Too short m packet");
+
+ // Read the address. Punting on validation.
+ // FIXME replace with Hex U64 read with no default value that fails on failed
+ // read.
+ const lldb::addr_t read_addr = packet.GetHexMaxU64(false, 0);
+
+ // Validate comma.
+ if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ','))
+ return SendIllFormedResponse(packet, "Comma sep missing in m packet");
+
+ // Get # bytes to read.
+ if (packet.GetBytesLeft() < 1)
+ return SendIllFormedResponse(packet, "Length missing in m packet");
+
+ const uint64_t byte_count = packet.GetHexMaxU64(false, 0);
+ if (byte_count == 0) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s nothing to read: "
+ "zero-length packet",
+ __FUNCTION__);
+ return SendOKResponse();
+ }
+
+ // Allocate the response buffer.
+ std::string buf(byte_count, '\0');
+ if (buf.empty())
+ return SendErrorResponse(0x78);
+
+ // Retrieve the process memory.
+ size_t bytes_read = 0;
+ Error error = m_debugged_process_sp->ReadMemoryWithoutTrap(
+ read_addr, &buf[0], byte_count, bytes_read);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " mem 0x%" PRIx64 ": failed to read. Error: %s",
+ __FUNCTION__, m_debugged_process_sp->GetID(), read_addr,
+ error.AsCString());
+ return SendErrorResponse(0x08);
+ }
+
+ if (bytes_read == 0) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " mem 0x%" PRIx64 ": read 0 of %" PRIu64 " requested bytes",
+ __FUNCTION__, m_debugged_process_sp->GetID(), read_addr,
+ byte_count);
+ return SendErrorResponse(0x08);
+ }
+
+ StreamGDBRemote response;
+ packet.SetFilePos(0);
+ char kind = packet.GetChar('?');
+ if (kind == 'x')
+ response.PutEscapedBytes(buf.data(), byte_count);
+ else {
+ assert(kind == 'm');
+ for (size_t i = 0; i < bytes_read; ++i)
+ response.PutHex8(buf[i]);
+ }
+
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_M (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
- return SendErrorResponse (0x15);
- }
-
- // Parse out the memory address.
- packet.SetFilePos (strlen("M"));
- if (packet.GetBytesLeft() < 1)
- return SendIllFormedResponse(packet, "Too short M packet");
-
- // Read the address. Punting on validation.
- // FIXME replace with Hex U64 read with no default value that fails on failed read.
- const lldb::addr_t write_addr = packet.GetHexMaxU64(false, 0);
-
- // Validate comma.
- if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ','))
- return SendIllFormedResponse(packet, "Comma sep missing in M packet");
-
- // Get # bytes to read.
- if (packet.GetBytesLeft() < 1)
- return SendIllFormedResponse(packet, "Length missing in M packet");
+GDBRemoteCommunicationServerLLGS::Handle_M(StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- const uint64_t byte_count = packet.GetHexMaxU64(false, 0);
- if (byte_count == 0)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s nothing to write: zero-length packet", __FUNCTION__);
- return PacketResult::Success;
- }
-
- // Validate colon.
- if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ':'))
- return SendIllFormedResponse(packet, "Comma sep missing in M packet after byte length");
-
- // Allocate the conversion buffer.
- std::vector<uint8_t> buf(byte_count, 0);
- if (buf.empty())
- return SendErrorResponse (0x78);
-
- // Convert the hex memory write contents to bytes.
- StreamGDBRemote response;
- const uint64_t convert_count = packet.GetHexBytes(&buf[0], byte_count, 0);
- if (convert_count != byte_count)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " mem 0x%" PRIx64 ": asked to write %" PRIu64 " bytes, but only found %" PRIu64 " to convert.", __FUNCTION__, m_debugged_process_sp->GetID (), write_addr, byte_count, convert_count);
- return SendIllFormedResponse (packet, "M content byte length specified did not match hex-encoded content length");
- }
-
- // Write the process memory.
- size_t bytes_written = 0;
- Error error = m_debugged_process_sp->WriteMemory (write_addr, &buf[0], byte_count, bytes_written);
- if (error.Fail ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " mem 0x%" PRIx64 ": failed to write. Error: %s", __FUNCTION__, m_debugged_process_sp->GetID (), write_addr, error.AsCString ());
- return SendErrorResponse (0x09);
- }
-
- if (bytes_written == 0)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " mem 0x%" PRIx64 ": wrote 0 of %" PRIu64 " requested bytes", __FUNCTION__, m_debugged_process_sp->GetID (), write_addr, byte_count);
- return SendErrorResponse (0x09);
- }
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
+ return SendErrorResponse(0x15);
+ }
+
+ // Parse out the memory address.
+ packet.SetFilePos(strlen("M"));
+ if (packet.GetBytesLeft() < 1)
+ return SendIllFormedResponse(packet, "Too short M packet");
+
+ // Read the address. Punting on validation.
+ // FIXME replace with Hex U64 read with no default value that fails on failed
+ // read.
+ const lldb::addr_t write_addr = packet.GetHexMaxU64(false, 0);
+
+ // Validate comma.
+ if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ','))
+ return SendIllFormedResponse(packet, "Comma sep missing in M packet");
+
+ // Get # bytes to read.
+ if (packet.GetBytesLeft() < 1)
+ return SendIllFormedResponse(packet, "Length missing in M packet");
+
+ const uint64_t byte_count = packet.GetHexMaxU64(false, 0);
+ if (byte_count == 0) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s nothing to write: "
+ "zero-length packet",
+ __FUNCTION__);
+ return PacketResult::Success;
+ }
+
+ // Validate colon.
+ if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ':'))
+ return SendIllFormedResponse(
+ packet, "Comma sep missing in M packet after byte length");
+
+ // Allocate the conversion buffer.
+ std::vector<uint8_t> buf(byte_count, 0);
+ if (buf.empty())
+ return SendErrorResponse(0x78);
+
+ // Convert the hex memory write contents to bytes.
+ StreamGDBRemote response;
+ const uint64_t convert_count = packet.GetHexBytes(buf, 0);
+ if (convert_count != byte_count) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " mem 0x%" PRIx64 ": asked to write %" PRIu64
+ " bytes, but only found %" PRIu64 " to convert.",
+ __FUNCTION__, m_debugged_process_sp->GetID(), write_addr,
+ byte_count, convert_count);
+ return SendIllFormedResponse(packet, "M content byte length specified did "
+ "not match hex-encoded content "
+ "length");
+ }
+
+ // Write the process memory.
+ size_t bytes_written = 0;
+ Error error = m_debugged_process_sp->WriteMemory(write_addr, &buf[0],
+ byte_count, bytes_written);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " mem 0x%" PRIx64 ": failed to write. Error: %s",
+ __FUNCTION__, m_debugged_process_sp->GetID(), write_addr,
+ error.AsCString());
+ return SendErrorResponse(0x09);
+ }
+
+ if (bytes_written == 0) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " mem 0x%" PRIx64 ": wrote 0 of %" PRIu64 " requested bytes",
+ __FUNCTION__, m_debugged_process_sp->GetID(), write_addr,
+ byte_count);
+ return SendErrorResponse(0x09);
+ }
- return SendOKResponse ();
+ return SendOKResponse();
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- // Currently only the NativeProcessProtocol knows if it can handle a qMemoryRegionInfoSupported
- // request, but we're not guaranteed to be attached to a process. For now we'll assume the
- // client only asks this when a process is being debugged.
-
- // Ensure we have a process running; otherwise, we can't figure this out
- // since we won't have a NativeProcessProtocol.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
- return SendErrorResponse (0x15);
- }
+GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported(
+ StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ // Currently only the NativeProcessProtocol knows if it can handle a
+ // qMemoryRegionInfoSupported
+ // request, but we're not guaranteed to be attached to a process. For now
+ // we'll assume the
+ // client only asks this when a process is being debugged.
+
+ // Ensure we have a process running; otherwise, we can't figure this out
+ // since we won't have a NativeProcessProtocol.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
+ return SendErrorResponse(0x15);
+ }
- // Test if we can get any region back when asking for the region around NULL.
- MemoryRegionInfo region_info;
- const Error error = m_debugged_process_sp->GetMemoryRegionInfo (0, region_info);
- if (error.Fail ())
- {
- // We don't support memory region info collection for this NativeProcessProtocol.
- return SendUnimplementedResponse ("");
- }
+ // Test if we can get any region back when asking for the region around NULL.
+ MemoryRegionInfo region_info;
+ const Error error =
+ m_debugged_process_sp->GetMemoryRegionInfo(0, region_info);
+ if (error.Fail()) {
+ // We don't support memory region info collection for this
+ // NativeProcessProtocol.
+ return SendUnimplementedResponse("");
+ }
- return SendOKResponse();
+ return SendOKResponse();
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- // Ensure we have a process.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
- return SendErrorResponse (0x15);
- }
-
- // Parse out the memory address.
- packet.SetFilePos (strlen("qMemoryRegionInfo:"));
- if (packet.GetBytesLeft() < 1)
- return SendIllFormedResponse(packet, "Too short qMemoryRegionInfo: packet");
-
- // Read the address. Punting on validation.
- const lldb::addr_t read_addr = packet.GetHexMaxU64(false, 0);
+GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo(
+ StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- StreamGDBRemote response;
-
- // Get the memory region info for the target address.
- MemoryRegionInfo region_info;
- const Error error = m_debugged_process_sp->GetMemoryRegionInfo (read_addr, region_info);
- if (error.Fail ())
- {
- // Return the error message.
-
- response.PutCString ("error:");
- response.PutCStringAsRawHex8 (error.AsCString ());
- response.PutChar (';');
- }
- else
- {
- // Range start and size.
- response.Printf ("start:%" PRIx64 ";size:%" PRIx64 ";", region_info.GetRange ().GetRangeBase (), region_info.GetRange ().GetByteSize ());
-
- // Permissions.
- if (region_info.GetReadable () ||
- region_info.GetWritable () ||
- region_info.GetExecutable ())
- {
- // Write permissions info.
- response.PutCString ("permissions:");
-
- if (region_info.GetReadable ())
- response.PutChar ('r');
- if (region_info.GetWritable ())
- response.PutChar('w');
- if (region_info.GetExecutable())
- response.PutChar ('x');
-
- response.PutChar (';');
- }
- }
-
- return SendPacketNoLock(response.GetData(), response.GetSize());
+ // Ensure we have a process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
+ return SendErrorResponse(0x15);
+ }
+
+ // Parse out the memory address.
+ packet.SetFilePos(strlen("qMemoryRegionInfo:"));
+ if (packet.GetBytesLeft() < 1)
+ return SendIllFormedResponse(packet, "Too short qMemoryRegionInfo: packet");
+
+ // Read the address. Punting on validation.
+ const lldb::addr_t read_addr = packet.GetHexMaxU64(false, 0);
+
+ StreamGDBRemote response;
+
+ // Get the memory region info for the target address.
+ MemoryRegionInfo region_info;
+ const Error error =
+ m_debugged_process_sp->GetMemoryRegionInfo(read_addr, region_info);
+ if (error.Fail()) {
+ // Return the error message.
+
+ response.PutCString("error:");
+ response.PutCStringAsRawHex8(error.AsCString());
+ response.PutChar(';');
+ } else {
+ // Range start and size.
+ response.Printf("start:%" PRIx64 ";size:%" PRIx64 ";",
+ region_info.GetRange().GetRangeBase(),
+ region_info.GetRange().GetByteSize());
+
+ // Permissions.
+ if (region_info.GetReadable() || region_info.GetWritable() ||
+ region_info.GetExecutable()) {
+ // Write permissions info.
+ response.PutCString("permissions:");
+
+ if (region_info.GetReadable())
+ response.PutChar('r');
+ if (region_info.GetWritable())
+ response.PutChar('w');
+ if (region_info.GetExecutable())
+ response.PutChar('x');
+
+ response.PutChar(';');
+ }
+
+ // Name
+ ConstString name = region_info.GetName();
+ if (name) {
+ response.PutCString("name:");
+ response.PutCStringAsRawHex8(name.AsCString());
+ response.PutChar(';');
+ }
+ }
+
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_Z (StringExtractorGDBRemote &packet)
-{
- // Ensure we have a process.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- {
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
- return SendErrorResponse (0x15);
- }
-
- // Parse out software or hardware breakpoint or watchpoint requested.
- packet.SetFilePos (strlen("Z"));
- if (packet.GetBytesLeft() < 1)
- return SendIllFormedResponse(packet, "Too short Z packet, missing software/hardware specifier");
-
- bool want_breakpoint = true;
- bool want_hardware = false;
- uint32_t watch_flags = 0;
-
- const GDBStoppointType stoppoint_type =
- GDBStoppointType(packet.GetS32 (eStoppointInvalid));
- switch (stoppoint_type)
- {
- case eBreakpointSoftware:
- want_hardware = false; want_breakpoint = true; break;
- case eBreakpointHardware:
- want_hardware = true; want_breakpoint = true; break;
- case eWatchpointWrite:
- watch_flags = 1;
- want_hardware = true; want_breakpoint = false; break;
- case eWatchpointRead:
- watch_flags = 2;
- want_hardware = true; want_breakpoint = false; break;
- case eWatchpointReadWrite:
- watch_flags = 3;
- want_hardware = true; want_breakpoint = false; break;
- case eStoppointInvalid:
- return SendIllFormedResponse(packet, "Z packet had invalid software/hardware specifier");
-
- }
-
- if ((packet.GetBytesLeft() < 1) || packet.GetChar () != ',')
- return SendIllFormedResponse(packet, "Malformed Z packet, expecting comma after stoppoint type");
-
- // Parse out the stoppoint address.
- if (packet.GetBytesLeft() < 1)
- return SendIllFormedResponse(packet, "Too short Z packet, missing address");
- const lldb::addr_t addr = packet.GetHexMaxU64(false, 0);
-
- if ((packet.GetBytesLeft() < 1) || packet.GetChar () != ',')
- return SendIllFormedResponse(packet, "Malformed Z packet, expecting comma after address");
-
- // Parse out the stoppoint size (i.e. size hint for opcode size).
- const uint32_t size = packet.GetHexMaxU32 (false, std::numeric_limits<uint32_t>::max ());
- if (size == std::numeric_limits<uint32_t>::max ())
- return SendIllFormedResponse(packet, "Malformed Z packet, failed to parse size argument");
-
- if (want_breakpoint)
- {
- // Try to set the breakpoint.
- const Error error = m_debugged_process_sp->SetBreakpoint (addr, size, want_hardware);
- if (error.Success ())
- return SendOKResponse ();
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
- " failed to set breakpoint: %s",
- __FUNCTION__,
- m_debugged_process_sp->GetID (),
- error.AsCString ());
- return SendErrorResponse (0x09);
- }
- else
- {
- // Try to set the watchpoint.
- const Error error = m_debugged_process_sp->SetWatchpoint (
- addr, size, watch_flags, want_hardware);
- if (error.Success ())
- return SendOKResponse ();
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
- " failed to set watchpoint: %s",
- __FUNCTION__,
- m_debugged_process_sp->GetID (),
- error.AsCString ());
- return SendErrorResponse (0x09);
- }
+GDBRemoteCommunicationServerLLGS::Handle_Z(StringExtractorGDBRemote &packet) {
+ // Ensure we have a process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
+ return SendErrorResponse(0x15);
+ }
+
+ // Parse out software or hardware breakpoint or watchpoint requested.
+ packet.SetFilePos(strlen("Z"));
+ if (packet.GetBytesLeft() < 1)
+ return SendIllFormedResponse(
+ packet, "Too short Z packet, missing software/hardware specifier");
+
+ bool want_breakpoint = true;
+ bool want_hardware = false;
+ uint32_t watch_flags = 0;
+
+ const GDBStoppointType stoppoint_type =
+ GDBStoppointType(packet.GetS32(eStoppointInvalid));
+ switch (stoppoint_type) {
+ case eBreakpointSoftware:
+ want_hardware = false;
+ want_breakpoint = true;
+ break;
+ case eBreakpointHardware:
+ want_hardware = true;
+ want_breakpoint = true;
+ break;
+ case eWatchpointWrite:
+ watch_flags = 1;
+ want_hardware = true;
+ want_breakpoint = false;
+ break;
+ case eWatchpointRead:
+ watch_flags = 2;
+ want_hardware = true;
+ want_breakpoint = false;
+ break;
+ case eWatchpointReadWrite:
+ watch_flags = 3;
+ want_hardware = true;
+ want_breakpoint = false;
+ break;
+ case eStoppointInvalid:
+ return SendIllFormedResponse(
+ packet, "Z packet had invalid software/hardware specifier");
+ }
+
+ if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',')
+ return SendIllFormedResponse(
+ packet, "Malformed Z packet, expecting comma after stoppoint type");
+
+ // Parse out the stoppoint address.
+ if (packet.GetBytesLeft() < 1)
+ return SendIllFormedResponse(packet, "Too short Z packet, missing address");
+ const lldb::addr_t addr = packet.GetHexMaxU64(false, 0);
+
+ if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',')
+ return SendIllFormedResponse(
+ packet, "Malformed Z packet, expecting comma after address");
+
+ // Parse out the stoppoint size (i.e. size hint for opcode size).
+ const uint32_t size =
+ packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max());
+ if (size == std::numeric_limits<uint32_t>::max())
+ return SendIllFormedResponse(
+ packet, "Malformed Z packet, failed to parse size argument");
+
+ if (want_breakpoint) {
+ // Try to set the breakpoint.
+ const Error error =
+ m_debugged_process_sp->SetBreakpoint(addr, size, want_hardware);
+ if (error.Success())
+ return SendOKResponse();
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " failed to set breakpoint: %s",
+ __FUNCTION__, m_debugged_process_sp->GetID(),
+ error.AsCString());
+ return SendErrorResponse(0x09);
+ } else {
+ // Try to set the watchpoint.
+ const Error error = m_debugged_process_sp->SetWatchpoint(
+ addr, size, watch_flags, want_hardware);
+ if (error.Success())
+ return SendOKResponse();
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " failed to set watchpoint: %s",
+ __FUNCTION__, m_debugged_process_sp->GetID(),
+ error.AsCString());
+ return SendErrorResponse(0x09);
+ }
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_z (StringExtractorGDBRemote &packet)
-{
- // Ensure we have a process.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- {
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
- return SendErrorResponse (0x15);
- }
-
- // Parse out software or hardware breakpoint or watchpoint requested.
- packet.SetFilePos (strlen("z"));
- if (packet.GetBytesLeft() < 1)
- return SendIllFormedResponse(packet, "Too short z packet, missing software/hardware specifier");
-
- bool want_breakpoint = true;
-
- const GDBStoppointType stoppoint_type =
- GDBStoppointType(packet.GetS32 (eStoppointInvalid));
- switch (stoppoint_type)
- {
- case eBreakpointHardware: want_breakpoint = true; break;
- case eBreakpointSoftware: want_breakpoint = true; break;
- case eWatchpointWrite: want_breakpoint = false; break;
- case eWatchpointRead: want_breakpoint = false; break;
- case eWatchpointReadWrite: want_breakpoint = false; break;
- default:
- return SendIllFormedResponse(packet, "z packet had invalid software/hardware specifier");
-
- }
-
- if ((packet.GetBytesLeft() < 1) || packet.GetChar () != ',')
- return SendIllFormedResponse(packet, "Malformed z packet, expecting comma after stoppoint type");
-
- // Parse out the stoppoint address.
- if (packet.GetBytesLeft() < 1)
- return SendIllFormedResponse(packet, "Too short z packet, missing address");
- const lldb::addr_t addr = packet.GetHexMaxU64(false, 0);
-
- if ((packet.GetBytesLeft() < 1) || packet.GetChar () != ',')
- return SendIllFormedResponse(packet, "Malformed z packet, expecting comma after address");
-
- /*
- // Parse out the stoppoint size (i.e. size hint for opcode size).
- const uint32_t size = packet.GetHexMaxU32 (false, std::numeric_limits<uint32_t>::max ());
- if (size == std::numeric_limits<uint32_t>::max ())
- return SendIllFormedResponse(packet, "Malformed z packet, failed to parse size argument");
- */
-
- if (want_breakpoint)
- {
- // Try to clear the breakpoint.
- const Error error = m_debugged_process_sp->RemoveBreakpoint (addr);
- if (error.Success ())
- return SendOKResponse ();
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
- " failed to remove breakpoint: %s",
- __FUNCTION__,
- m_debugged_process_sp->GetID (),
- error.AsCString ());
- return SendErrorResponse (0x09);
- }
- else
- {
- // Try to clear the watchpoint.
- const Error error = m_debugged_process_sp->RemoveWatchpoint (addr);
- if (error.Success ())
- return SendOKResponse ();
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
- " failed to remove watchpoint: %s",
- __FUNCTION__,
- m_debugged_process_sp->GetID (),
- error.AsCString ());
- return SendErrorResponse (0x09);
- }
+GDBRemoteCommunicationServerLLGS::Handle_z(StringExtractorGDBRemote &packet) {
+ // Ensure we have a process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
+ return SendErrorResponse(0x15);
+ }
+
+ // Parse out software or hardware breakpoint or watchpoint requested.
+ packet.SetFilePos(strlen("z"));
+ if (packet.GetBytesLeft() < 1)
+ return SendIllFormedResponse(
+ packet, "Too short z packet, missing software/hardware specifier");
+
+ bool want_breakpoint = true;
+
+ const GDBStoppointType stoppoint_type =
+ GDBStoppointType(packet.GetS32(eStoppointInvalid));
+ switch (stoppoint_type) {
+ case eBreakpointHardware:
+ want_breakpoint = true;
+ break;
+ case eBreakpointSoftware:
+ want_breakpoint = true;
+ break;
+ case eWatchpointWrite:
+ want_breakpoint = false;
+ break;
+ case eWatchpointRead:
+ want_breakpoint = false;
+ break;
+ case eWatchpointReadWrite:
+ want_breakpoint = false;
+ break;
+ default:
+ return SendIllFormedResponse(
+ packet, "z packet had invalid software/hardware specifier");
+ }
+
+ if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',')
+ return SendIllFormedResponse(
+ packet, "Malformed z packet, expecting comma after stoppoint type");
+
+ // Parse out the stoppoint address.
+ if (packet.GetBytesLeft() < 1)
+ return SendIllFormedResponse(packet, "Too short z packet, missing address");
+ const lldb::addr_t addr = packet.GetHexMaxU64(false, 0);
+
+ if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',')
+ return SendIllFormedResponse(
+ packet, "Malformed z packet, expecting comma after address");
+
+ /*
+ // Parse out the stoppoint size (i.e. size hint for opcode size).
+ const uint32_t size = packet.GetHexMaxU32 (false,
+ std::numeric_limits<uint32_t>::max ());
+ if (size == std::numeric_limits<uint32_t>::max ())
+ return SendIllFormedResponse(packet, "Malformed z packet, failed to parse
+ size argument");
+ */
+
+ if (want_breakpoint) {
+ // Try to clear the breakpoint.
+ const Error error = m_debugged_process_sp->RemoveBreakpoint(addr);
+ if (error.Success())
+ return SendOKResponse();
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " failed to remove breakpoint: %s",
+ __FUNCTION__, m_debugged_process_sp->GetID(),
+ error.AsCString());
+ return SendErrorResponse(0x09);
+ } else {
+ // Try to clear the watchpoint.
+ const Error error = m_debugged_process_sp->RemoveWatchpoint(addr);
+ if (error.Success())
+ return SendOKResponse();
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " failed to remove watchpoint: %s",
+ __FUNCTION__, m_debugged_process_sp->GetID(),
+ error.AsCString());
+ return SendErrorResponse(0x09);
+ }
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_s (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS|LIBLLDB_LOG_THREAD));
-
- // Ensure we have a process.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
- return SendErrorResponse (0x32);
- }
+GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
- // We first try to use a continue thread id. If any one or any all set, use the current thread.
- // Bail out if we don't have a thread id.
- lldb::tid_t tid = GetContinueThreadID ();
- if (tid == 0 || tid == LLDB_INVALID_THREAD_ID)
- tid = GetCurrentThreadID ();
- if (tid == LLDB_INVALID_THREAD_ID)
- return SendErrorResponse (0x33);
-
- // Double check that we have such a thread.
- // TODO investigate: on MacOSX we might need to do an UpdateThreads () here.
- NativeThreadProtocolSP thread_sp = m_debugged_process_sp->GetThreadByID (tid);
- if (!thread_sp || thread_sp->GetID () != tid)
- return SendErrorResponse (0x33);
-
- // Create the step action for the given thread.
- ResumeAction action = { tid, eStateStepping, 0 };
-
- // Setup the actions list.
- ResumeActionList actions;
- actions.Append (action);
-
- // All other threads stop while we're single stepping a thread.
- actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0);
- Error error = m_debugged_process_sp->Resume (actions);
- if (error.Fail ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 " Resume() failed with error: %s", __FUNCTION__, m_debugged_process_sp->GetID (), tid, error.AsCString ());
- return SendErrorResponse(0x49);
- }
+ // Ensure we have a process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
+ return SendErrorResponse(0x32);
+ }
+
+ // We first try to use a continue thread id. If any one or any all set, use
+ // the current thread.
+ // Bail out if we don't have a thread id.
+ lldb::tid_t tid = GetContinueThreadID();
+ if (tid == 0 || tid == LLDB_INVALID_THREAD_ID)
+ tid = GetCurrentThreadID();
+ if (tid == LLDB_INVALID_THREAD_ID)
+ return SendErrorResponse(0x33);
+
+ // Double check that we have such a thread.
+ // TODO investigate: on MacOSX we might need to do an UpdateThreads () here.
+ NativeThreadProtocolSP thread_sp = m_debugged_process_sp->GetThreadByID(tid);
+ if (!thread_sp || thread_sp->GetID() != tid)
+ return SendErrorResponse(0x33);
+
+ // Create the step action for the given thread.
+ ResumeAction action = {tid, eStateStepping, 0};
+
+ // Setup the actions list.
+ ResumeActionList actions;
+ actions.Append(action);
+
+ // All other threads stop while we're single stepping a thread.
+ actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0);
+ Error error = m_debugged_process_sp->Resume(actions);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " tid %" PRIu64 " Resume() failed with error: %s",
+ __FUNCTION__, m_debugged_process_sp->GetID(), tid,
+ error.AsCString());
+ return SendErrorResponse(0x49);
+ }
- // No response here - the stop or exit will come from the resulting action.
- return PacketResult::Success;
+ // No response here - the stop or exit will come from the resulting action.
+ return PacketResult::Success;
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qXfer_auxv_read (StringExtractorGDBRemote &packet)
-{
- // *BSD impls should be able to do this too.
+GDBRemoteCommunicationServerLLGS::Handle_qXfer_auxv_read(
+ StringExtractorGDBRemote &packet) {
+// *BSD impls should be able to do this too.
#if defined(__linux__)
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- // Parse out the offset.
- packet.SetFilePos (strlen("qXfer:auxv:read::"));
- if (packet.GetBytesLeft () < 1)
- return SendIllFormedResponse (packet, "qXfer:auxv:read:: packet missing offset");
-
- const uint64_t auxv_offset = packet.GetHexMaxU64 (false, std::numeric_limits<uint64_t>::max ());
- if (auxv_offset == std::numeric_limits<uint64_t>::max ())
- return SendIllFormedResponse (packet, "qXfer:auxv:read:: packet missing offset");
-
- // Parse out comma.
- if (packet.GetBytesLeft () < 1 || packet.GetChar () != ',')
- return SendIllFormedResponse (packet, "qXfer:auxv:read:: packet missing comma after offset");
-
- // Parse out the length.
- const uint64_t auxv_length = packet.GetHexMaxU64 (false, std::numeric_limits<uint64_t>::max ());
- if (auxv_length == std::numeric_limits<uint64_t>::max ())
- return SendIllFormedResponse (packet, "qXfer:auxv:read:: packet missing length");
-
- // Grab the auxv data if we need it.
- if (!m_active_auxv_buffer_sp)
- {
- // Make sure we have a valid process.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
- return SendErrorResponse (0x10);
- }
-
- // Grab the auxv data.
- m_active_auxv_buffer_sp = Host::GetAuxvData (m_debugged_process_sp->GetID ());
- if (!m_active_auxv_buffer_sp || m_active_auxv_buffer_sp->GetByteSize () == 0)
- {
- // Hmm, no auxv data, call that an error.
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no auxv data retrieved", __FUNCTION__);
- m_active_auxv_buffer_sp.reset ();
- return SendErrorResponse (0x11);
- }
- }
-
- // FIXME find out if/how I lock the stream here.
-
- StreamGDBRemote response;
- bool done_with_buffer = false;
-
- if (auxv_offset >= m_active_auxv_buffer_sp->GetByteSize ())
- {
- // We have nothing left to send. Mark the buffer as complete.
- response.PutChar ('l');
- done_with_buffer = true;
- }
- else
- {
- // Figure out how many bytes are available starting at the given offset.
- const uint64_t bytes_remaining = m_active_auxv_buffer_sp->GetByteSize () - auxv_offset;
-
- // Figure out how many bytes we're going to read.
- const uint64_t bytes_to_read = (auxv_length > bytes_remaining) ? bytes_remaining : auxv_length;
-
- // Mark the response type according to whether we're reading the remainder of the auxv data.
- if (bytes_to_read >= bytes_remaining)
- {
- // There will be nothing left to read after this
- response.PutChar ('l');
- done_with_buffer = true;
- }
- else
- {
- // There will still be bytes to read after this request.
- response.PutChar ('m');
- }
-
- // Now write the data in encoded binary form.
- response.PutEscapedBytes (m_active_auxv_buffer_sp->GetBytes () + auxv_offset, bytes_to_read);
- }
-
- if (done_with_buffer)
- m_active_auxv_buffer_sp.reset ();
-
- return SendPacketNoLock(response.GetData(), response.GetSize());
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ // Parse out the offset.
+ packet.SetFilePos(strlen("qXfer:auxv:read::"));
+ if (packet.GetBytesLeft() < 1)
+ return SendIllFormedResponse(packet,
+ "qXfer:auxv:read:: packet missing offset");
+
+ const uint64_t auxv_offset =
+ packet.GetHexMaxU64(false, std::numeric_limits<uint64_t>::max());
+ if (auxv_offset == std::numeric_limits<uint64_t>::max())
+ return SendIllFormedResponse(packet,
+ "qXfer:auxv:read:: packet missing offset");
+
+ // Parse out comma.
+ if (packet.GetBytesLeft() < 1 || packet.GetChar() != ',')
+ return SendIllFormedResponse(
+ packet, "qXfer:auxv:read:: packet missing comma after offset");
+
+ // Parse out the length.
+ const uint64_t auxv_length =
+ packet.GetHexMaxU64(false, std::numeric_limits<uint64_t>::max());
+ if (auxv_length == std::numeric_limits<uint64_t>::max())
+ return SendIllFormedResponse(packet,
+ "qXfer:auxv:read:: packet missing length");
+
+ // Grab the auxv data if we need it.
+ if (!m_active_auxv_buffer_sp) {
+ // Make sure we have a valid process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
+ return SendErrorResponse(0x10);
+ }
+
+ // Grab the auxv data.
+ m_active_auxv_buffer_sp = Host::GetAuxvData(m_debugged_process_sp->GetID());
+ if (!m_active_auxv_buffer_sp ||
+ m_active_auxv_buffer_sp->GetByteSize() == 0) {
+ // Hmm, no auxv data, call that an error.
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, no auxv data "
+ "retrieved",
+ __FUNCTION__);
+ m_active_auxv_buffer_sp.reset();
+ return SendErrorResponse(0x11);
+ }
+ }
+
+ // FIXME find out if/how I lock the stream here.
+
+ StreamGDBRemote response;
+ bool done_with_buffer = false;
+
+ if (auxv_offset >= m_active_auxv_buffer_sp->GetByteSize()) {
+ // We have nothing left to send. Mark the buffer as complete.
+ response.PutChar('l');
+ done_with_buffer = true;
+ } else {
+ // Figure out how many bytes are available starting at the given offset.
+ const uint64_t bytes_remaining =
+ m_active_auxv_buffer_sp->GetByteSize() - auxv_offset;
+
+ // Figure out how many bytes we're going to read.
+ const uint64_t bytes_to_read =
+ (auxv_length > bytes_remaining) ? bytes_remaining : auxv_length;
+
+ // Mark the response type according to whether we're reading the remainder
+ // of the auxv data.
+ if (bytes_to_read >= bytes_remaining) {
+ // There will be nothing left to read after this
+ response.PutChar('l');
+ done_with_buffer = true;
+ } else {
+ // There will still be bytes to read after this request.
+ response.PutChar('m');
+ }
+
+ // Now write the data in encoded binary form.
+ response.PutEscapedBytes(m_active_auxv_buffer_sp->GetBytes() + auxv_offset,
+ bytes_to_read);
+ }
+
+ if (done_with_buffer)
+ m_active_auxv_buffer_sp.reset();
+
+ return SendPacketNoLock(response.GetString());
#else
- return SendUnimplementedResponse ("not implemented on this platform");
+ return SendUnimplementedResponse("not implemented on this platform");
#endif
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
-
- // Move past packet name.
- packet.SetFilePos (strlen ("QSaveRegisterState"));
-
- // Get the thread to use.
- NativeThreadProtocolSP thread_sp = GetThreadFromSuffix (packet);
- if (!thread_sp)
- {
- if (m_thread_suffix_supported)
- return SendIllFormedResponse (packet, "No thread specified in QSaveRegisterState packet");
- else
- return SendIllFormedResponse (packet, "No thread was is set with the Hg packet");
- }
-
- // Grab the register context for the thread.
- NativeRegisterContextSP reg_context_sp (thread_sp->GetRegisterContext ());
- if (!reg_context_sp)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 " failed, no register context available for the thread", __FUNCTION__, m_debugged_process_sp->GetID (), thread_sp->GetID ());
- return SendErrorResponse (0x15);
- }
-
- // Save registers to a buffer.
- DataBufferSP register_data_sp;
- Error error = reg_context_sp->ReadAllRegisterValues (register_data_sp);
- if (error.Fail ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " failed to save all register values: %s", __FUNCTION__, m_debugged_process_sp->GetID (), error.AsCString ());
- return SendErrorResponse (0x75);
- }
-
- // Allocate a new save id.
- const uint32_t save_id = GetNextSavedRegistersID ();
- assert ((m_saved_registers_map.find (save_id) == m_saved_registers_map.end ()) && "GetNextRegisterSaveID() returned an existing register save id");
+GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState(
+ StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+
+ // Move past packet name.
+ packet.SetFilePos(strlen("QSaveRegisterState"));
+
+ // Get the thread to use.
+ NativeThreadProtocolSP thread_sp = GetThreadFromSuffix(packet);
+ if (!thread_sp) {
+ if (m_thread_suffix_supported)
+ return SendIllFormedResponse(
+ packet, "No thread specified in QSaveRegisterState packet");
+ else
+ return SendIllFormedResponse(packet,
+ "No thread was is set with the Hg packet");
+ }
- // Save the register data buffer under the save id.
- {
- std::lock_guard<std::mutex> guard(m_saved_registers_mutex);
- m_saved_registers_map[save_id] = register_data_sp;
- }
+ // Grab the register context for the thread.
+ NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext());
+ if (!reg_context_sp) {
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64
+ " failed, no register context available for the thread",
+ __FUNCTION__, m_debugged_process_sp->GetID(), thread_sp->GetID());
+ return SendErrorResponse(0x15);
+ }
+
+ // Save registers to a buffer.
+ DataBufferSP register_data_sp;
+ Error error = reg_context_sp->ReadAllRegisterValues(register_data_sp);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " failed to save all register values: %s",
+ __FUNCTION__, m_debugged_process_sp->GetID(),
+ error.AsCString());
+ return SendErrorResponse(0x75);
+ }
+
+ // Allocate a new save id.
+ const uint32_t save_id = GetNextSavedRegistersID();
+ assert((m_saved_registers_map.find(save_id) == m_saved_registers_map.end()) &&
+ "GetNextRegisterSaveID() returned an existing register save id");
+
+ // Save the register data buffer under the save id.
+ {
+ std::lock_guard<std::mutex> guard(m_saved_registers_mutex);
+ m_saved_registers_map[save_id] = register_data_sp;
+ }
- // Write the response.
- StreamGDBRemote response;
- response.Printf ("%" PRIu32, save_id);
- return SendPacketNoLock(response.GetData(), response.GetSize());
+ // Write the response.
+ StreamGDBRemote response;
+ response.Printf("%" PRIu32, save_id);
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
-
- // Parse out save id.
- packet.SetFilePos (strlen ("QRestoreRegisterState:"));
- if (packet.GetBytesLeft () < 1)
- return SendIllFormedResponse (packet, "QRestoreRegisterState packet missing register save id");
-
- const uint32_t save_id = packet.GetU32 (0);
- if (save_id == 0)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s QRestoreRegisterState packet has malformed save id, expecting decimal uint32_t", __FUNCTION__);
- return SendErrorResponse (0x76);
- }
+GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState(
+ StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+
+ // Parse out save id.
+ packet.SetFilePos(strlen("QRestoreRegisterState:"));
+ if (packet.GetBytesLeft() < 1)
+ return SendIllFormedResponse(
+ packet, "QRestoreRegisterState packet missing register save id");
+
+ const uint32_t save_id = packet.GetU32(0);
+ if (save_id == 0) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s QRestoreRegisterState "
+ "packet has malformed save id, expecting decimal uint32_t",
+ __FUNCTION__);
+ return SendErrorResponse(0x76);
+ }
+
+ // Get the thread to use.
+ NativeThreadProtocolSP thread_sp = GetThreadFromSuffix(packet);
+ if (!thread_sp) {
+ if (m_thread_suffix_supported)
+ return SendIllFormedResponse(
+ packet, "No thread specified in QRestoreRegisterState packet");
+ else
+ return SendIllFormedResponse(packet,
+ "No thread was is set with the Hg packet");
+ }
- // Get the thread to use.
- NativeThreadProtocolSP thread_sp = GetThreadFromSuffix (packet);
- if (!thread_sp)
- {
- if (m_thread_suffix_supported)
- return SendIllFormedResponse (packet, "No thread specified in QRestoreRegisterState packet");
- else
- return SendIllFormedResponse (packet, "No thread was is set with the Hg packet");
- }
+ // Grab the register context for the thread.
+ NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext());
+ if (!reg_context_sp) {
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64
+ " failed, no register context available for the thread",
+ __FUNCTION__, m_debugged_process_sp->GetID(), thread_sp->GetID());
+ return SendErrorResponse(0x15);
+ }
+
+ // Retrieve register state buffer, then remove from the list.
+ DataBufferSP register_data_sp;
+ {
+ std::lock_guard<std::mutex> guard(m_saved_registers_mutex);
- // Grab the register context for the thread.
- NativeRegisterContextSP reg_context_sp (thread_sp->GetRegisterContext ());
- if (!reg_context_sp)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 " failed, no register context available for the thread", __FUNCTION__, m_debugged_process_sp->GetID (), thread_sp->GetID ());
- return SendErrorResponse (0x15);
+ // Find the register set buffer for the given save id.
+ auto it = m_saved_registers_map.find(save_id);
+ if (it == m_saved_registers_map.end()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " does not have a register set save buffer for id %" PRIu32,
+ __FUNCTION__, m_debugged_process_sp->GetID(), save_id);
+ return SendErrorResponse(0x77);
}
+ register_data_sp = it->second;
- // Retrieve register state buffer, then remove from the list.
- DataBufferSP register_data_sp;
- {
- std::lock_guard<std::mutex> guard(m_saved_registers_mutex);
-
- // Find the register set buffer for the given save id.
- auto it = m_saved_registers_map.find (save_id);
- if (it == m_saved_registers_map.end ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " does not have a register set save buffer for id %" PRIu32, __FUNCTION__, m_debugged_process_sp->GetID (), save_id);
- return SendErrorResponse (0x77);
- }
- register_data_sp = it->second;
-
- // Remove it from the map.
- m_saved_registers_map.erase (it);
- }
+ // Remove it from the map.
+ m_saved_registers_map.erase(it);
+ }
- Error error = reg_context_sp->WriteAllRegisterValues (register_data_sp);
- if (error.Fail ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " failed to restore all register values: %s", __FUNCTION__, m_debugged_process_sp->GetID (), error.AsCString ());
- return SendErrorResponse (0x77);
- }
+ Error error = reg_context_sp->WriteAllRegisterValues(register_data_sp);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+ " failed to restore all register values: %s",
+ __FUNCTION__, m_debugged_process_sp->GetID(),
+ error.AsCString());
+ return SendErrorResponse(0x77);
+ }
- return SendOKResponse();
+ return SendOKResponse();
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_vAttach (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- // Consume the ';' after vAttach.
- packet.SetFilePos (strlen ("vAttach"));
- if (!packet.GetBytesLeft () || packet.GetChar () != ';')
- return SendIllFormedResponse (packet, "vAttach missing expected ';'");
-
- // Grab the PID to which we will attach (assume hex encoding).
- lldb::pid_t pid = packet.GetU32 (LLDB_INVALID_PROCESS_ID, 16);
- if (pid == LLDB_INVALID_PROCESS_ID)
- return SendIllFormedResponse (packet, "vAttach failed to parse the process id");
-
- // Attempt to attach.
+GDBRemoteCommunicationServerLLGS::Handle_vAttach(
+ StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ // Consume the ';' after vAttach.
+ packet.SetFilePos(strlen("vAttach"));
+ if (!packet.GetBytesLeft() || packet.GetChar() != ';')
+ return SendIllFormedResponse(packet, "vAttach missing expected ';'");
+
+ // Grab the PID to which we will attach (assume hex encoding).
+ lldb::pid_t pid = packet.GetU32(LLDB_INVALID_PROCESS_ID, 16);
+ if (pid == LLDB_INVALID_PROCESS_ID)
+ return SendIllFormedResponse(packet,
+ "vAttach failed to parse the process id");
+
+ // Attempt to attach.
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s attempting to attach to "
+ "pid %" PRIu64,
+ __FUNCTION__, pid);
+
+ Error error = AttachToProcess(pid);
+
+ if (error.Fail()) {
if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s attempting to attach to pid %" PRIu64, __FUNCTION__, pid);
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to attach to "
+ "pid %" PRIu64 ": %s\n",
+ __FUNCTION__, pid, error.AsCString());
+ return SendErrorResponse(0x01);
+ }
- Error error = AttachToProcess (pid);
-
- if (error.Fail ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to attach to pid %" PRIu64 ": %s\n", __FUNCTION__, pid, error.AsCString());
- return SendErrorResponse (0x01);
- }
-
- // Notify we attached by sending a stop packet.
- return SendStopReasonForState (m_debugged_process_sp->GetState ());
+ // Notify we attached by sending a stop packet.
+ return SendStopReasonForState(m_debugged_process_sp->GetState());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_D (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS));
+GDBRemoteCommunicationServerLLGS::Handle_D(StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- StopSTDIOForwarding();
+ StopSTDIOForwarding();
- // Fail if we don't have a current process.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
- return SendErrorResponse (0x15);
- }
-
- lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
-
- // Consume the ';' after D.
- packet.SetFilePos (1);
- if (packet.GetBytesLeft ())
- {
- if (packet.GetChar () != ';')
- return SendIllFormedResponse (packet, "D missing expected ';'");
-
- // Grab the PID from which we will detach (assume hex encoding).
- pid = packet.GetU32 (LLDB_INVALID_PROCESS_ID, 16);
- if (pid == LLDB_INVALID_PROCESS_ID)
- return SendIllFormedResponse (packet, "D failed to parse the process id");
- }
+ // Fail if we don't have a current process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ if (log)
+ log->Printf(
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
+ return SendErrorResponse(0x15);
+ }
+
+ lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
+
+ // Consume the ';' after D.
+ packet.SetFilePos(1);
+ if (packet.GetBytesLeft()) {
+ if (packet.GetChar() != ';')
+ return SendIllFormedResponse(packet, "D missing expected ';'");
+
+ // Grab the PID from which we will detach (assume hex encoding).
+ pid = packet.GetU32(LLDB_INVALID_PROCESS_ID, 16);
+ if (pid == LLDB_INVALID_PROCESS_ID)
+ return SendIllFormedResponse(packet, "D failed to parse the process id");
+ }
- if (pid != LLDB_INVALID_PROCESS_ID &&
- m_debugged_process_sp->GetID () != pid)
- {
- return SendIllFormedResponse (packet, "Invalid pid");
- }
+ if (pid != LLDB_INVALID_PROCESS_ID && m_debugged_process_sp->GetID() != pid) {
+ return SendIllFormedResponse(packet, "Invalid pid");
+ }
- const Error error = m_debugged_process_sp->Detach ();
- if (error.Fail ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to detach from pid %" PRIu64 ": %s\n",
- __FUNCTION__, m_debugged_process_sp->GetID (), error.AsCString ());
- return SendErrorResponse (0x01);
- }
+ const Error error = m_debugged_process_sp->Detach();
+ if (error.Fail()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to detach from "
+ "pid %" PRIu64 ": %s\n",
+ __FUNCTION__, m_debugged_process_sp->GetID(),
+ error.AsCString());
+ return SendErrorResponse(0x01);
+ }
- return SendOKResponse ();
+ return SendOKResponse();
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo (StringExtractorGDBRemote &packet)
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
-
- packet.SetFilePos (strlen("qThreadStopInfo"));
- const lldb::tid_t tid = packet.GetHexMaxU32 (false, LLDB_INVALID_THREAD_ID);
- if (tid == LLDB_INVALID_THREAD_ID)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, could not parse thread id from request \"%s\"", __FUNCTION__, packet.GetStringRef ().c_str ());
- return SendErrorResponse (0x15);
- }
- return SendStopReplyPacketForThread (tid);
+GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo(
+ StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+
+ packet.SetFilePos(strlen("qThreadStopInfo"));
+ const lldb::tid_t tid = packet.GetHexMaxU32(false, LLDB_INVALID_THREAD_ID);
+ if (tid == LLDB_INVALID_THREAD_ID) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, could not "
+ "parse thread id from request \"%s\"",
+ __FUNCTION__, packet.GetStringRef().c_str());
+ return SendErrorResponse(0x15);
+ }
+ return SendStopReplyPacketForThread(tid);
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_jThreadsInfo (StringExtractorGDBRemote &)
-{
- Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
-
- // Ensure we have a debugged process.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- return SendErrorResponse (50);
-
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s preparing packet for pid %" PRIu64,
+GDBRemoteCommunicationServerLLGS::Handle_jThreadsInfo(
+ StringExtractorGDBRemote &) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+
+ // Ensure we have a debugged process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID))
+ return SendErrorResponse(50);
+
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s preparing packet for pid "
+ "%" PRIu64,
__FUNCTION__, m_debugged_process_sp->GetID());
+ StreamString response;
+ const bool threads_with_valid_stop_info_only = false;
+ JSONArray::SP threads_array_sp = GetJSONThreadsInfo(
+ *m_debugged_process_sp, threads_with_valid_stop_info_only);
+ if (!threads_array_sp) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to prepare a "
+ "packet for pid %" PRIu64,
+ __FUNCTION__, m_debugged_process_sp->GetID());
+ return SendErrorResponse(52);
+ }
- StreamString response;
- const bool threads_with_valid_stop_info_only = false;
- JSONArray::SP threads_array_sp = GetJSONThreadsInfo(*m_debugged_process_sp,
- threads_with_valid_stop_info_only);
- if (! threads_array_sp)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to prepare a packet for pid %" PRIu64,
- __FUNCTION__, m_debugged_process_sp->GetID());
- return SendErrorResponse(52);
- }
-
- threads_array_sp->Write(response);
- StreamGDBRemote escaped_response;
- escaped_response.PutEscapedBytes(response.GetData(), response.GetSize());
- return SendPacketNoLock (escaped_response.GetData(), escaped_response.GetSize());
+ threads_array_sp->Write(response);
+ StreamGDBRemote escaped_response;
+ escaped_response.PutEscapedBytes(response.GetData(), response.GetSize());
+ return SendPacketNoLock(escaped_response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qWatchpointSupportInfo (StringExtractorGDBRemote &packet)
-{
- // Fail if we don't have a current process.
- if (!m_debugged_process_sp ||
- m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID)
- return SendErrorResponse (68);
-
- packet.SetFilePos(strlen("qWatchpointSupportInfo"));
- if (packet.GetBytesLeft() == 0)
- return SendOKResponse();
- if (packet.GetChar() != ':')
- return SendErrorResponse(67);
+GDBRemoteCommunicationServerLLGS::Handle_qWatchpointSupportInfo(
+ StringExtractorGDBRemote &packet) {
+ // Fail if we don't have a current process.
+ if (!m_debugged_process_sp ||
+ m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)
+ return SendErrorResponse(68);
+
+ packet.SetFilePos(strlen("qWatchpointSupportInfo"));
+ if (packet.GetBytesLeft() == 0)
+ return SendOKResponse();
+ if (packet.GetChar() != ':')
+ return SendErrorResponse(67);
- uint32_t num = m_debugged_process_sp->GetMaxWatchpoints();
- StreamGDBRemote response;
- response.Printf ("num:%d;", num);
- return SendPacketNoLock(response.GetData(), response.GetSize());
+ uint32_t num = m_debugged_process_sp->GetMaxWatchpoints();
+ StreamGDBRemote response;
+ response.Printf("num:%d;", num);
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qFileLoadAddress (StringExtractorGDBRemote &packet)
-{
- // Fail if we don't have a current process.
- if (!m_debugged_process_sp ||
- m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID)
- return SendErrorResponse(67);
+GDBRemoteCommunicationServerLLGS::Handle_qFileLoadAddress(
+ StringExtractorGDBRemote &packet) {
+ // Fail if we don't have a current process.
+ if (!m_debugged_process_sp ||
+ m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)
+ return SendErrorResponse(67);
- packet.SetFilePos(strlen("qFileLoadAddress:"));
- if (packet.GetBytesLeft() == 0)
- return SendErrorResponse(68);
+ packet.SetFilePos(strlen("qFileLoadAddress:"));
+ if (packet.GetBytesLeft() == 0)
+ return SendErrorResponse(68);
- std::string file_name;
- packet.GetHexByteString(file_name);
+ std::string file_name;
+ packet.GetHexByteString(file_name);
- lldb::addr_t file_load_address = LLDB_INVALID_ADDRESS;
- Error error = m_debugged_process_sp->GetFileLoadAddress(file_name, file_load_address);
- if (error.Fail())
- return SendErrorResponse(69);
+ lldb::addr_t file_load_address = LLDB_INVALID_ADDRESS;
+ Error error =
+ m_debugged_process_sp->GetFileLoadAddress(file_name, file_load_address);
+ if (error.Fail())
+ return SendErrorResponse(69);
- if (file_load_address == LLDB_INVALID_ADDRESS)
- return SendErrorResponse(1); // File not loaded
+ if (file_load_address == LLDB_INVALID_ADDRESS)
+ return SendErrorResponse(1); // File not loaded
- StreamGDBRemote response;
- response.PutHex64(file_load_address);
- return SendPacketNoLock(response.GetData(), response.GetSize());
-}
-
-void
-GDBRemoteCommunicationServerLLGS::MaybeCloseInferiorTerminalConnection ()
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- // Tell the stdio connection to shut down.
- if (m_stdio_communication.IsConnected())
- {
- auto connection = m_stdio_communication.GetConnection();
- if (connection)
- {
- Error error;
- connection->Disconnect (&error);
-
- if (error.Success ())
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s disconnect process terminal stdio - SUCCESS", __FUNCTION__);
- }
- else
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s disconnect process terminal stdio - FAIL: %s", __FUNCTION__, error.AsCString ());
- }
- }
- }
+ StreamGDBRemote response;
+ response.PutHex64(file_load_address);
+ return SendPacketNoLock(response.GetString());
}
+void GDBRemoteCommunicationServerLLGS::MaybeCloseInferiorTerminalConnection() {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-NativeThreadProtocolSP
-GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix (StringExtractorGDBRemote &packet)
-{
- NativeThreadProtocolSP thread_sp;
+ // Tell the stdio connection to shut down.
+ if (m_stdio_communication.IsConnected()) {
+ auto connection = m_stdio_communication.GetConnection();
+ if (connection) {
+ Error error;
+ connection->Disconnect(&error);
- // We have no thread if we don't have a process.
- if (!m_debugged_process_sp || m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID)
- return thread_sp;
-
- // If the client hasn't asked for thread suffix support, there will not be a thread suffix.
- // Use the current thread in that case.
- if (!m_thread_suffix_supported)
- {
- const lldb::tid_t current_tid = GetCurrentThreadID ();
- if (current_tid == LLDB_INVALID_THREAD_ID)
- return thread_sp;
- else if (current_tid == 0)
- {
- // Pick a thread.
- return m_debugged_process_sp->GetThreadAtIndex (0);
- }
- else
- return m_debugged_process_sp->GetThreadByID (current_tid);
+ if (error.Success()) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s disconnect process "
+ "terminal stdio - SUCCESS",
+ __FUNCTION__);
+ } else {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s disconnect process "
+ "terminal stdio - FAIL: %s",
+ __FUNCTION__, error.AsCString());
+ }
}
+ }
+}
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+NativeThreadProtocolSP GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix(
+ StringExtractorGDBRemote &packet) {
+ NativeThreadProtocolSP thread_sp;
- // Parse out the ';'.
- if (packet.GetBytesLeft () < 1 || packet.GetChar () != ';')
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s gdb-remote parse error: expected ';' prior to start of thread suffix: packet contents = '%s'", __FUNCTION__, packet.GetStringRef ().c_str ());
- return thread_sp;
- }
+ // We have no thread if we don't have a process.
+ if (!m_debugged_process_sp ||
+ m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)
+ return thread_sp;
- if (!packet.GetBytesLeft ())
- return thread_sp;
+ // If the client hasn't asked for thread suffix support, there will not be a
+ // thread suffix.
+ // Use the current thread in that case.
+ if (!m_thread_suffix_supported) {
+ const lldb::tid_t current_tid = GetCurrentThreadID();
+ if (current_tid == LLDB_INVALID_THREAD_ID)
+ return thread_sp;
+ else if (current_tid == 0) {
+ // Pick a thread.
+ return m_debugged_process_sp->GetThreadAtIndex(0);
+ } else
+ return m_debugged_process_sp->GetThreadByID(current_tid);
+ }
+
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+
+ // Parse out the ';'.
+ if (packet.GetBytesLeft() < 1 || packet.GetChar() != ';') {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s gdb-remote parse "
+ "error: expected ';' prior to start of thread suffix: packet "
+ "contents = '%s'",
+ __FUNCTION__, packet.GetStringRef().c_str());
+ return thread_sp;
+ }
- // Parse out thread: portion.
- if (strncmp (packet.Peek (), "thread:", strlen("thread:")) != 0)
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s gdb-remote parse error: expected 'thread:' but not found, packet contents = '%s'", __FUNCTION__, packet.GetStringRef ().c_str ());
- return thread_sp;
- }
- packet.SetFilePos (packet.GetFilePos () + strlen("thread:"));
- const lldb::tid_t tid = packet.GetHexMaxU64(false, 0);
- if (tid != 0)
- return m_debugged_process_sp->GetThreadByID (tid);
+ if (!packet.GetBytesLeft())
+ return thread_sp;
+ // Parse out thread: portion.
+ if (strncmp(packet.Peek(), "thread:", strlen("thread:")) != 0) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s gdb-remote parse "
+ "error: expected 'thread:' but not found, packet contents = "
+ "'%s'",
+ __FUNCTION__, packet.GetStringRef().c_str());
return thread_sp;
+ }
+ packet.SetFilePos(packet.GetFilePos() + strlen("thread:"));
+ const lldb::tid_t tid = packet.GetHexMaxU64(false, 0);
+ if (tid != 0)
+ return m_debugged_process_sp->GetThreadByID(tid);
+
+ return thread_sp;
}
-lldb::tid_t
-GDBRemoteCommunicationServerLLGS::GetCurrentThreadID () const
-{
- if (m_current_tid == 0 || m_current_tid == LLDB_INVALID_THREAD_ID)
- {
- // Use whatever the debug process says is the current thread id
- // since the protocol either didn't specify or specified we want
- // any/all threads marked as the current thread.
- if (!m_debugged_process_sp)
- return LLDB_INVALID_THREAD_ID;
- return m_debugged_process_sp->GetCurrentThreadID ();
- }
- // Use the specific current thread id set by the gdb remote protocol.
- return m_current_tid;
+lldb::tid_t GDBRemoteCommunicationServerLLGS::GetCurrentThreadID() const {
+ if (m_current_tid == 0 || m_current_tid == LLDB_INVALID_THREAD_ID) {
+ // Use whatever the debug process says is the current thread id
+ // since the protocol either didn't specify or specified we want
+ // any/all threads marked as the current thread.
+ if (!m_debugged_process_sp)
+ return LLDB_INVALID_THREAD_ID;
+ return m_debugged_process_sp->GetCurrentThreadID();
+ }
+ // Use the specific current thread id set by the gdb remote protocol.
+ return m_current_tid;
}
-uint32_t
-GDBRemoteCommunicationServerLLGS::GetNextSavedRegistersID ()
-{
- std::lock_guard<std::mutex> guard(m_saved_registers_mutex);
- return m_next_saved_registers_id++;
+uint32_t GDBRemoteCommunicationServerLLGS::GetNextSavedRegistersID() {
+ std::lock_guard<std::mutex> guard(m_saved_registers_mutex);
+ return m_next_saved_registers_id++;
}
-void
-GDBRemoteCommunicationServerLLGS::ClearProcessSpecificData ()
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS|GDBR_LOG_PROCESS));
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s()", __FUNCTION__);
+void GDBRemoteCommunicationServerLLGS::ClearProcessSpecificData() {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | GDBR_LOG_PROCESS));
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s()", __FUNCTION__);
- // Clear any auxv cached data.
- // *BSD impls should be able to do this too.
+// Clear any auxv cached data.
+// *BSD impls should be able to do this too.
#if defined(__linux__)
- if (log)
- log->Printf ("GDBRemoteCommunicationServerLLGS::%s clearing auxv buffer (previously %s)",
- __FUNCTION__,
- m_active_auxv_buffer_sp ? "was set" : "was not set");
- m_active_auxv_buffer_sp.reset ();
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s clearing auxv buffer "
+ "(previously %s)",
+ __FUNCTION__,
+ m_active_auxv_buffer_sp ? "was set" : "was not set");
+ m_active_auxv_buffer_sp.reset();
#endif
}
FileSpec
-GDBRemoteCommunicationServerLLGS::FindModuleFile(const std::string& module_path,
- const ArchSpec& arch)
-{
- if (m_debugged_process_sp)
- {
- FileSpec file_spec;
- if (m_debugged_process_sp->GetLoadedModuleFileSpec(module_path.c_str(), file_spec).Success())
- {
- if (file_spec.Exists())
- return file_spec;
- }
- }
-
- return GDBRemoteCommunicationServerCommon::FindModuleFile(module_path, arch);
+GDBRemoteCommunicationServerLLGS::FindModuleFile(const std::string &module_path,
+ const ArchSpec &arch) {
+ if (m_debugged_process_sp) {
+ FileSpec file_spec;
+ if (m_debugged_process_sp
+ ->GetLoadedModuleFileSpec(module_path.c_str(), file_spec)
+ .Success()) {
+ if (file_spec.Exists())
+ return file_spec;
+ }
+ }
+
+ return GDBRemoteCommunicationServerCommon::FindModuleFile(module_path, arch);
}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
index caf6eb319e63..fa52cdaab493 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -16,10 +16,10 @@
#include <unordered_map>
// Other libraries and framework includes
-#include "lldb/lldb-private-forward.h"
#include "lldb/Core/Communication.h"
-#include "lldb/Host/common/NativeProcessProtocol.h"
#include "lldb/Host/MainLoop.h"
+#include "lldb/Host/common/NativeProcessProtocol.h"
+#include "lldb/lldb-private-forward.h"
// Project includes
#include "GDBRemoteCommunicationServerCommon.h"
@@ -32,282 +32,220 @@ namespace process_gdb_remote {
class ProcessGDBRemote;
-class GDBRemoteCommunicationServerLLGS :
- public GDBRemoteCommunicationServerCommon,
- public NativeProcessProtocol::NativeDelegate
-{
+class GDBRemoteCommunicationServerLLGS
+ : public GDBRemoteCommunicationServerCommon,
+ public NativeProcessProtocol::NativeDelegate {
public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- GDBRemoteCommunicationServerLLGS(MainLoop &mainloop);
-
- //------------------------------------------------------------------
- /// Specify the program to launch and its arguments.
- ///
- /// @param[in] args
- /// The command line to launch.
- ///
- /// @param[in] argc
- /// The number of elements in the args array of cstring pointers.
- ///
- /// @return
- /// An Error object indicating the success or failure of making
- /// the setting.
- //------------------------------------------------------------------
- Error
- SetLaunchArguments (const char *const args[], int argc);
-
- //------------------------------------------------------------------
- /// Specify the launch flags for the process.
- ///
- /// @param[in] launch_flags
- /// The launch flags to use when launching this process.
- ///
- /// @return
- /// An Error object indicating the success or failure of making
- /// the setting.
- //------------------------------------------------------------------
- Error
- SetLaunchFlags (unsigned int launch_flags);
-
- //------------------------------------------------------------------
- /// Launch a process with the current launch settings.
- ///
- /// This method supports running an lldb-gdbserver or similar
- /// server in a situation where the startup code has been provided
- /// with all the information for a child process to be launched.
- ///
- /// @return
- /// An Error object indicating the success or failure of the
- /// launch.
- //------------------------------------------------------------------
- Error
- LaunchProcess () override;
-
- //------------------------------------------------------------------
- /// Attach to a process.
- ///
- /// This method supports attaching llgs to a process accessible via the
- /// configured Platform.
- ///
- /// @return
- /// An Error object indicating the success or failure of the
- /// attach operation.
- //------------------------------------------------------------------
- Error
- AttachToProcess (lldb::pid_t pid);
-
- //------------------------------------------------------------------
- // NativeProcessProtocol::NativeDelegate overrides
- //------------------------------------------------------------------
- void
- InitializeDelegate (NativeProcessProtocol *process) override;
-
- void
- ProcessStateChanged (NativeProcessProtocol *process, lldb::StateType state) override;
-
- void
- DidExec (NativeProcessProtocol *process) override;
-
- Error
- InitializeConnection (std::unique_ptr<Connection> &&connection);
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ GDBRemoteCommunicationServerLLGS(MainLoop &mainloop);
+
+ //------------------------------------------------------------------
+ /// Specify the program to launch and its arguments.
+ ///
+ /// @param[in] args
+ /// The command line to launch.
+ ///
+ /// @param[in] argc
+ /// The number of elements in the args array of cstring pointers.
+ ///
+ /// @return
+ /// An Error object indicating the success or failure of making
+ /// the setting.
+ //------------------------------------------------------------------
+ Error SetLaunchArguments(const char *const args[], int argc);
+
+ //------------------------------------------------------------------
+ /// Specify the launch flags for the process.
+ ///
+ /// @param[in] launch_flags
+ /// The launch flags to use when launching this process.
+ ///
+ /// @return
+ /// An Error object indicating the success or failure of making
+ /// the setting.
+ //------------------------------------------------------------------
+ Error SetLaunchFlags(unsigned int launch_flags);
+
+ //------------------------------------------------------------------
+ /// Launch a process with the current launch settings.
+ ///
+ /// This method supports running an lldb-gdbserver or similar
+ /// server in a situation where the startup code has been provided
+ /// with all the information for a child process to be launched.
+ ///
+ /// @return
+ /// An Error object indicating the success or failure of the
+ /// launch.
+ //------------------------------------------------------------------
+ Error LaunchProcess() override;
+
+ //------------------------------------------------------------------
+ /// Attach to a process.
+ ///
+ /// This method supports attaching llgs to a process accessible via the
+ /// configured Platform.
+ ///
+ /// @return
+ /// An Error object indicating the success or failure of the
+ /// attach operation.
+ //------------------------------------------------------------------
+ Error AttachToProcess(lldb::pid_t pid);
+
+ //------------------------------------------------------------------
+ // NativeProcessProtocol::NativeDelegate overrides
+ //------------------------------------------------------------------
+ void InitializeDelegate(NativeProcessProtocol *process) override;
+
+ void ProcessStateChanged(NativeProcessProtocol *process,
+ lldb::StateType state) override;
+
+ void DidExec(NativeProcessProtocol *process) override;
+
+ Error InitializeConnection(std::unique_ptr<Connection> &&connection);
protected:
- MainLoop &m_mainloop;
- MainLoop::ReadHandleUP m_network_handle_up;
- lldb::tid_t m_current_tid;
- lldb::tid_t m_continue_tid;
- std::recursive_mutex m_debugged_process_mutex;
- NativeProcessProtocolSP m_debugged_process_sp;
+ MainLoop &m_mainloop;
+ MainLoop::ReadHandleUP m_network_handle_up;
+ lldb::tid_t m_current_tid;
+ lldb::tid_t m_continue_tid;
+ std::recursive_mutex m_debugged_process_mutex;
+ NativeProcessProtocolSP m_debugged_process_sp;
- Communication m_stdio_communication;
- MainLoop::ReadHandleUP m_stdio_handle_up;
+ Communication m_stdio_communication;
+ MainLoop::ReadHandleUP m_stdio_handle_up;
- lldb::StateType m_inferior_prev_state;
- lldb::DataBufferSP m_active_auxv_buffer_sp;
- std::mutex m_saved_registers_mutex;
- std::unordered_map<uint32_t, lldb::DataBufferSP> m_saved_registers_map;
- uint32_t m_next_saved_registers_id;
- bool m_handshake_completed : 1;
+ lldb::StateType m_inferior_prev_state;
+ lldb::DataBufferSP m_active_auxv_buffer_sp;
+ std::mutex m_saved_registers_mutex;
+ std::unordered_map<uint32_t, lldb::DataBufferSP> m_saved_registers_map;
+ uint32_t m_next_saved_registers_id;
+ bool m_handshake_completed : 1;
- PacketResult
- SendONotification (const char *buffer, uint32_t len);
+ PacketResult SendONotification(const char *buffer, uint32_t len);
- PacketResult
- SendWResponse (NativeProcessProtocol *process);
+ PacketResult SendWResponse(NativeProcessProtocol *process);
- PacketResult
- SendStopReplyPacketForThread (lldb::tid_t tid);
+ PacketResult SendStopReplyPacketForThread(lldb::tid_t tid);
- PacketResult
- SendStopReasonForState (lldb::StateType process_state);
+ PacketResult SendStopReasonForState(lldb::StateType process_state);
- PacketResult
- Handle_k (StringExtractorGDBRemote &packet);
+ PacketResult Handle_k(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qProcessInfo (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qProcessInfo(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qC (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qC(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_QSetDisableASLR (StringExtractorGDBRemote &packet);
+ PacketResult Handle_QSetDisableASLR(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_QSetWorkingDir (StringExtractorGDBRemote &packet);
+ PacketResult Handle_QSetWorkingDir(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qGetWorkingDir (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qGetWorkingDir(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_C (StringExtractorGDBRemote &packet);
+ PacketResult Handle_C(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_c (StringExtractorGDBRemote &packet);
+ PacketResult Handle_c(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_vCont (StringExtractorGDBRemote &packet);
+ PacketResult Handle_vCont(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_vCont_actions (StringExtractorGDBRemote &packet);
+ PacketResult Handle_vCont_actions(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_stop_reason (StringExtractorGDBRemote &packet);
+ PacketResult Handle_stop_reason(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qRegisterInfo (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qRegisterInfo(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qfThreadInfo (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qfThreadInfo(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qsThreadInfo (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qsThreadInfo(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_p (StringExtractorGDBRemote &packet);
+ PacketResult Handle_p(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_P (StringExtractorGDBRemote &packet);
+ PacketResult Handle_P(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_H (StringExtractorGDBRemote &packet);
+ PacketResult Handle_H(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_I (StringExtractorGDBRemote &packet);
+ PacketResult Handle_I(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_interrupt (StringExtractorGDBRemote &packet);
+ PacketResult Handle_interrupt(StringExtractorGDBRemote &packet);
- // Handles $m and $x packets.
- PacketResult
- Handle_memory_read (StringExtractorGDBRemote &packet);
+ // Handles $m and $x packets.
+ PacketResult Handle_memory_read(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_M (StringExtractorGDBRemote &packet);
+ PacketResult Handle_M(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qMemoryRegionInfoSupported (StringExtractorGDBRemote &packet);
+ PacketResult
+ Handle_qMemoryRegionInfoSupported(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qMemoryRegionInfo (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qMemoryRegionInfo(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_Z (StringExtractorGDBRemote &packet);
+ PacketResult Handle_Z(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_z (StringExtractorGDBRemote &packet);
+ PacketResult Handle_z(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_s (StringExtractorGDBRemote &packet);
+ PacketResult Handle_s(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qXfer_auxv_read (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qXfer_auxv_read(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_QSaveRegisterState (StringExtractorGDBRemote &packet);
+ PacketResult Handle_QSaveRegisterState(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_QRestoreRegisterState (StringExtractorGDBRemote &packet);
+ PacketResult Handle_QRestoreRegisterState(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_vAttach (StringExtractorGDBRemote &packet);
+ PacketResult Handle_vAttach(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_D (StringExtractorGDBRemote &packet);
+ PacketResult Handle_D(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qThreadStopInfo (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qThreadStopInfo(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_jThreadsInfo (StringExtractorGDBRemote &packet);
+ PacketResult Handle_jThreadsInfo(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qWatchpointSupportInfo (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qWatchpointSupportInfo(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qFileLoadAddress (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qFileLoadAddress(StringExtractorGDBRemote &packet);
- void
- SetCurrentThreadID (lldb::tid_t tid);
+ void SetCurrentThreadID(lldb::tid_t tid);
- lldb::tid_t
- GetCurrentThreadID () const;
+ lldb::tid_t GetCurrentThreadID() const;
- void
- SetContinueThreadID (lldb::tid_t tid);
+ void SetContinueThreadID(lldb::tid_t tid);
- lldb::tid_t
- GetContinueThreadID () const { return m_continue_tid; }
+ lldb::tid_t GetContinueThreadID() const { return m_continue_tid; }
- Error
- SetSTDIOFileDescriptor (int fd);
+ Error SetSTDIOFileDescriptor(int fd);
- FileSpec
- FindModuleFile (const std::string& module_path, const ArchSpec& arch) override;
+ FileSpec FindModuleFile(const std::string &module_path,
+ const ArchSpec &arch) override;
private:
- void
- HandleInferiorState_Exited (NativeProcessProtocol *process);
+ void HandleInferiorState_Exited(NativeProcessProtocol *process);
- void
- HandleInferiorState_Stopped (NativeProcessProtocol *process);
+ void HandleInferiorState_Stopped(NativeProcessProtocol *process);
- NativeThreadProtocolSP
- GetThreadFromSuffix (StringExtractorGDBRemote &packet);
+ NativeThreadProtocolSP GetThreadFromSuffix(StringExtractorGDBRemote &packet);
- uint32_t
- GetNextSavedRegistersID ();
+ uint32_t GetNextSavedRegistersID();
- void
- MaybeCloseInferiorTerminalConnection ();
+ void MaybeCloseInferiorTerminalConnection();
- void
- ClearProcessSpecificData ();
+ void ClearProcessSpecificData();
- void
- RegisterPacketHandlers ();
+ void RegisterPacketHandlers();
- void
- DataAvailableCallback ();
+ void DataAvailableCallback();
- void
- SendProcessOutput ();
+ void SendProcessOutput();
- void
- StartSTDIOForwarding();
+ void StartSTDIOForwarding();
- void
- StopSTDIOForwarding();
+ void StopSTDIOForwarding();
- //------------------------------------------------------------------
- // For GDBRemoteCommunicationServerLLGS only
- //------------------------------------------------------------------
- DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunicationServerLLGS);
+ //------------------------------------------------------------------
+ // For GDBRemoteCommunicationServerLLGS only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationServerLLGS);
};
} // namespace process_gdb_remote
} // namespace lldb_private
-#endif // liblldb_GDBRemoteCommunicationServerLLGS_h_
+#endif // liblldb_GDBRemoteCommunicationServerLLGS_h_
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
index d6900c27293c..11069749186a 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
@@ -13,8 +13,8 @@
// C Includes
// C++ Includes
-#include <cstring>
#include <chrono>
+#include <cstring>
#include <mutex>
#include <sstream>
@@ -47,549 +47,525 @@ using namespace lldb_private::process_gdb_remote;
//----------------------------------------------------------------------
// GDBRemoteCommunicationServerPlatform constructor
//----------------------------------------------------------------------
-GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform(const Socket::SocketProtocol socket_protocol,
- const char *socket_scheme)
- : GDBRemoteCommunicationServerCommon("gdb-remote.server", "gdb-remote.server.rx_packet"),
- m_socket_protocol(socket_protocol),
- m_socket_scheme(socket_scheme),
- m_spawned_pids_mutex(),
- m_port_map(),
- m_port_offset(0)
-{
- m_pending_gdb_server.pid = LLDB_INVALID_PROCESS_ID;
- m_pending_gdb_server.port = 0;
-
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qC,
- &GDBRemoteCommunicationServerPlatform::Handle_qC);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir,
- &GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qLaunchGDBServer,
- &GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qQueryGDBServer,
- &GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qKillSpawnedProcess,
- &GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qProcessInfo,
- &GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir,
- &GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir);
- RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_jSignalsInfo,
- &GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo);
-
- RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_interrupt,
- [this](StringExtractorGDBRemote packet, Error &error, bool &interrupt, bool &quit) {
- error.SetErrorString("interrupt received");
- interrupt = true;
- return PacketResult::Success;
- });
+GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform(
+ const Socket::SocketProtocol socket_protocol, const char *socket_scheme)
+ : GDBRemoteCommunicationServerCommon("gdb-remote.server",
+ "gdb-remote.server.rx_packet"),
+ m_socket_protocol(socket_protocol), m_socket_scheme(socket_scheme),
+ m_spawned_pids_mutex(), m_port_map(), m_port_offset(0) {
+ m_pending_gdb_server.pid = LLDB_INVALID_PROCESS_ID;
+ m_pending_gdb_server.port = 0;
+
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qC,
+ &GDBRemoteCommunicationServerPlatform::Handle_qC);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir,
+ &GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qLaunchGDBServer,
+ &GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qQueryGDBServer,
+ &GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qKillSpawnedProcess,
+ &GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qProcessInfo,
+ &GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir,
+ &GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_jSignalsInfo,
+ &GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo);
+
+ RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_interrupt,
+ [this](StringExtractorGDBRemote packet, Error &error,
+ bool &interrupt, bool &quit) {
+ error.SetErrorString("interrupt received");
+ interrupt = true;
+ return PacketResult::Success;
+ });
}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-GDBRemoteCommunicationServerPlatform::~GDBRemoteCommunicationServerPlatform()
-{
-}
-
-Error
-GDBRemoteCommunicationServerPlatform::LaunchGDBServer(const lldb_private::Args& args,
- std::string hostname,
- lldb::pid_t& pid,
- uint16_t& port,
- std::string& socket_name)
-{
- if (port == UINT16_MAX)
- port = GetNextAvailablePort();
-
- // Spawn a new thread to accept the port that gets bound after
- // binding to port 0 (zero).
-
- // ignore the hostname send from the remote end, just use the ip address
- // that we're currently communicating with as the hostname
-
- // Spawn a debugserver and try to get the port it listens to.
- ProcessLaunchInfo debugserver_launch_info;
- if (hostname.empty())
- hostname = "127.0.0.1";
-
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
- if (log)
- log->Printf("Launching debugserver with: %s:%u...", hostname.c_str(), port);
-
- // Do not run in a new session so that it can not linger after the
- // platform closes.
- debugserver_launch_info.SetLaunchInSeparateProcessGroup(false);
- debugserver_launch_info.SetMonitorProcessCallback(
- std::bind(&GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped, this, std::placeholders::_1), false);
-
- std::string platform_scheme;
- std::string platform_ip;
- int platform_port;
- std::string platform_path;
- bool ok = UriParser::Parse(GetConnection()->GetURI().c_str(), platform_scheme, platform_ip, platform_port, platform_path);
- UNUSED_IF_ASSERT_DISABLED(ok);
- assert(ok);
-
- std::ostringstream url;
- // debugserver does not accept the URL scheme prefix.
+GDBRemoteCommunicationServerPlatform::~GDBRemoteCommunicationServerPlatform() {}
+
+Error GDBRemoteCommunicationServerPlatform::LaunchGDBServer(
+ const lldb_private::Args &args, std::string hostname, lldb::pid_t &pid,
+ uint16_t &port, std::string &socket_name) {
+ if (port == UINT16_MAX)
+ port = GetNextAvailablePort();
+
+ // Spawn a new thread to accept the port that gets bound after
+ // binding to port 0 (zero).
+
+ // ignore the hostname send from the remote end, just use the ip address
+ // that we're currently communicating with as the hostname
+
+ // Spawn a debugserver and try to get the port it listens to.
+ ProcessLaunchInfo debugserver_launch_info;
+ if (hostname.empty())
+ hostname = "127.0.0.1";
+
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
+ if (log)
+ log->Printf("Launching debugserver with: %s:%u...", hostname.c_str(), port);
+
+ // Do not run in a new session so that it can not linger after the
+ // platform closes.
+ debugserver_launch_info.SetLaunchInSeparateProcessGroup(false);
+ debugserver_launch_info.SetMonitorProcessCallback(
+ std::bind(&GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped,
+ this, std::placeholders::_1),
+ false);
+
+ llvm::StringRef platform_scheme;
+ llvm::StringRef platform_ip;
+ int platform_port;
+ llvm::StringRef platform_path;
+ bool ok = UriParser::Parse(GetConnection()->GetURI(), platform_scheme,
+ platform_ip, platform_port, platform_path);
+ UNUSED_IF_ASSERT_DISABLED(ok);
+ assert(ok);
+
+ std::ostringstream url;
+// debugserver does not accept the URL scheme prefix.
#if !defined(__APPLE__)
- url << m_socket_scheme << "://";
+ url << m_socket_scheme << "://";
#endif
- uint16_t* port_ptr = &port;
- if (m_socket_protocol == Socket::ProtocolTcp)
- url << platform_ip << ":" << port;
- else
- {
- socket_name = GetDomainSocketPath("gdbserver").GetPath();
- url << socket_name;
- port_ptr = nullptr;
- }
-
- Error error = StartDebugserverProcess (url.str().c_str(),
- nullptr,
- debugserver_launch_info,
- port_ptr,
- args);
-
- pid = debugserver_launch_info.GetProcessID();
- if (pid != LLDB_INVALID_PROCESS_ID)
- {
- std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
- m_spawned_pids.insert(pid);
- if (port > 0)
- AssociatePortWithProcess(port, pid);
- }
- else
- {
- if (port > 0)
- FreePort(port);
- }
- return error;
+ uint16_t *port_ptr = &port;
+ if (m_socket_protocol == Socket::ProtocolTcp)
+ url << platform_ip.str() << ":" << port;
+ else {
+ socket_name = GetDomainSocketPath("gdbserver").GetPath();
+ url << socket_name;
+ port_ptr = nullptr;
+ }
+
+ Error error = StartDebugserverProcess(
+ url.str().c_str(), nullptr, debugserver_launch_info, port_ptr, &args, -1);
+
+ pid = debugserver_launch_info.GetProcessID();
+ if (pid != LLDB_INVALID_PROCESS_ID) {
+ std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
+ m_spawned_pids.insert(pid);
+ if (port > 0)
+ AssociatePortWithProcess(port, pid);
+ } else {
+ if (port > 0)
+ FreePort(port);
+ }
+ return error;
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet)
-{
+GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer(
+ StringExtractorGDBRemote &packet) {
#ifdef _WIN32
- return SendErrorResponse(9);
+ return SendErrorResponse(9);
#else
- // Spawn a local debugserver as a platform so we can then attach or launch
- // a process...
-
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
+ // Spawn a local debugserver as a platform so we can then attach or launch
+ // a process...
+
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerPlatform::%s() called",
+ __FUNCTION__);
+
+ ConnectionFileDescriptor file_conn;
+ std::string hostname;
+ packet.SetFilePos(::strlen("qLaunchGDBServer;"));
+ llvm::StringRef name;
+ llvm::StringRef value;
+ uint16_t port = UINT16_MAX;
+ while (packet.GetNameColonValue(name, value)) {
+ if (name.equals("host"))
+ hostname = value;
+ else if (name.equals("port"))
+ value.getAsInteger(0, port);
+ }
+
+ lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID;
+ std::string socket_name;
+ Error error =
+ LaunchGDBServer(Args(), hostname, debugserver_pid, port, socket_name);
+ if (error.Fail()) {
if (log)
- log->Printf ("GDBRemoteCommunicationServerPlatform::%s() called", __FUNCTION__);
-
- ConnectionFileDescriptor file_conn;
- std::string hostname;
- packet.SetFilePos(::strlen ("qLaunchGDBServer;"));
- std::string name;
- std::string value;
- uint16_t port = UINT16_MAX;
- while (packet.GetNameColonValue(name, value))
- {
- if (name.compare ("host") == 0)
- hostname.swap(value);
- else if (name.compare ("port") == 0)
- port = StringConvert::ToUInt32(value.c_str(), 0, 0);
- }
-
- lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID;
- std::string socket_name;
- Error error = LaunchGDBServer(Args(), hostname, debugserver_pid, port, socket_name);
- if (error.Fail())
- {
- if (log)
- log->Printf("GDBRemoteCommunicationServerPlatform::%s() debugserver launch failed: %s", __FUNCTION__, error.AsCString ());
- return SendErrorResponse(9);
- }
-
- if (log)
- log->Printf ("GDBRemoteCommunicationServerPlatform::%s() debugserver launched successfully as pid %" PRIu64, __FUNCTION__, debugserver_pid);
-
- StreamGDBRemote response;
- response.Printf("pid:%" PRIu64 ";port:%u;", debugserver_pid, port + m_port_offset);
- if (!socket_name.empty())
- {
- response.PutCString("socket_name:");
- response.PutCStringAsRawHex8(socket_name.c_str());
- response.PutChar(';');
- }
-
- PacketResult packet_result = SendPacketNoLock(response.GetData(), response.GetSize());
- if (packet_result != PacketResult::Success)
- {
- if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
- ::kill (debugserver_pid, SIGINT);
- }
- return packet_result;
+ log->Printf("GDBRemoteCommunicationServerPlatform::%s() debugserver "
+ "launch failed: %s",
+ __FUNCTION__, error.AsCString());
+ return SendErrorResponse(9);
+ }
+
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerPlatform::%s() debugserver "
+ "launched successfully as pid %" PRIu64,
+ __FUNCTION__, debugserver_pid);
+
+ StreamGDBRemote response;
+ response.Printf("pid:%" PRIu64 ";port:%u;", debugserver_pid,
+ port + m_port_offset);
+ if (!socket_name.empty()) {
+ response.PutCString("socket_name:");
+ response.PutCStringAsRawHex8(socket_name.c_str());
+ response.PutChar(';');
+ }
+
+ PacketResult packet_result = SendPacketNoLock(response.GetString());
+ if (packet_result != PacketResult::Success) {
+ if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
+ ::kill(debugserver_pid, SIGINT);
+ }
+ return packet_result;
#endif
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer (StringExtractorGDBRemote &packet)
-{
- if (m_pending_gdb_server.pid == LLDB_INVALID_PROCESS_ID)
- return SendErrorResponse(4);
-
- JSONObject::SP server_sp = std::make_shared<JSONObject>();
- server_sp->SetObject("port", std::make_shared<JSONNumber>(m_pending_gdb_server.port));
- if (!m_pending_gdb_server.socket_name.empty())
- server_sp->SetObject("socket_name",
- std::make_shared<JSONString>(m_pending_gdb_server.socket_name.c_str()));
-
- JSONArray server_list;
- server_list.AppendObject(server_sp);
-
- StreamGDBRemote response;
- server_list.Write(response);
-
- StreamGDBRemote escaped_response;
- escaped_response.PutEscapedBytes(response.GetData(), response.GetSize());
- return SendPacketNoLock(escaped_response.GetData(), escaped_response.GetSize());
+GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer(
+ StringExtractorGDBRemote &packet) {
+ if (m_pending_gdb_server.pid == LLDB_INVALID_PROCESS_ID)
+ return SendErrorResponse(4);
+
+ JSONObject::SP server_sp = std::make_shared<JSONObject>();
+ server_sp->SetObject("port",
+ std::make_shared<JSONNumber>(m_pending_gdb_server.port));
+ if (!m_pending_gdb_server.socket_name.empty())
+ server_sp->SetObject(
+ "socket_name",
+ std::make_shared<JSONString>(m_pending_gdb_server.socket_name.c_str()));
+
+ JSONArray server_list;
+ server_list.AppendObject(server_sp);
+
+ StreamGDBRemote response;
+ server_list.Write(response);
+
+ StreamGDBRemote escaped_response;
+ escaped_response.PutEscapedBytes(response.GetString().data(),
+ response.GetSize());
+ return SendPacketNoLock(escaped_response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos(::strlen ("qKillSpawnedProcess:"));
+GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("qKillSpawnedProcess:"));
- lldb::pid_t pid = packet.GetU64(LLDB_INVALID_PROCESS_ID);
+ lldb::pid_t pid = packet.GetU64(LLDB_INVALID_PROCESS_ID);
- // verify that we know anything about this pid.
- // Scope for locker
- {
- std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
- if (m_spawned_pids.find(pid) == m_spawned_pids.end())
- {
- // not a pid we know about
- return SendErrorResponse (10);
- }
+ // verify that we know anything about this pid.
+ // Scope for locker
+ {
+ std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
+ if (m_spawned_pids.find(pid) == m_spawned_pids.end()) {
+ // not a pid we know about
+ return SendErrorResponse(10);
}
+ }
- // go ahead and attempt to kill the spawned process
- if (KillSpawnedProcess (pid))
- return SendOKResponse ();
- else
- return SendErrorResponse (11);
+ // go ahead and attempt to kill the spawned process
+ if (KillSpawnedProcess(pid))
+ return SendOKResponse();
+ else
+ return SendErrorResponse(11);
}
-bool
-GDBRemoteCommunicationServerPlatform::KillSpawnedProcess (lldb::pid_t pid)
-{
- // make sure we know about this process
- {
- std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
- if (m_spawned_pids.find(pid) == m_spawned_pids.end())
- return false;
- }
+bool GDBRemoteCommunicationServerPlatform::KillSpawnedProcess(lldb::pid_t pid) {
+ // make sure we know about this process
+ {
+ std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
+ if (m_spawned_pids.find(pid) == m_spawned_pids.end())
+ return false;
+ }
- // first try a SIGTERM (standard kill)
- Host::Kill (pid, SIGTERM);
+ // first try a SIGTERM (standard kill)
+ Host::Kill(pid, SIGTERM);
- // check if that worked
- for (size_t i=0; i<10; ++i)
+ // check if that worked
+ for (size_t i = 0; i < 10; ++i) {
{
- {
- std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
- if (m_spawned_pids.find(pid) == m_spawned_pids.end())
- {
- // it is now killed
- return true;
- }
- }
- usleep (10000);
+ std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
+ if (m_spawned_pids.find(pid) == m_spawned_pids.end()) {
+ // it is now killed
+ return true;
+ }
}
+ usleep(10000);
+ }
- // check one more time after the final usleep
- {
- std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
- if (m_spawned_pids.find(pid) == m_spawned_pids.end())
- return true;
- }
+ // check one more time after the final usleep
+ {
+ std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
+ if (m_spawned_pids.find(pid) == m_spawned_pids.end())
+ return true;
+ }
- // the launched process still lives. Now try killing it again,
- // this time with an unblockable signal.
- Host::Kill (pid, SIGKILL);
+ // the launched process still lives. Now try killing it again,
+ // this time with an unblockable signal.
+ Host::Kill(pid, SIGKILL);
- for (size_t i=0; i<10; ++i)
+ for (size_t i = 0; i < 10; ++i) {
{
- {
- std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
- if (m_spawned_pids.find(pid) == m_spawned_pids.end())
- {
- // it is now killed
- return true;
- }
- }
- usleep (10000);
+ std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
+ if (m_spawned_pids.find(pid) == m_spawned_pids.end()) {
+ // it is now killed
+ return true;
+ }
}
+ usleep(10000);
+ }
- // check one more time after the final usleep
- // Scope for locker
- {
- std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
- if (m_spawned_pids.find(pid) == m_spawned_pids.end())
- return true;
- }
+ // check one more time after the final usleep
+ // Scope for locker
+ {
+ std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
+ if (m_spawned_pids.find(pid) == m_spawned_pids.end())
+ return true;
+ }
- // no luck - the process still lives
- return false;
+ // no luck - the process still lives
+ return false;
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo (StringExtractorGDBRemote &packet)
-{
- lldb::pid_t pid = m_process_launch_info.GetProcessID ();
- m_process_launch_info.Clear ();
+GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo(
+ StringExtractorGDBRemote &packet) {
+ lldb::pid_t pid = m_process_launch_info.GetProcessID();
+ m_process_launch_info.Clear();
- if (pid == LLDB_INVALID_PROCESS_ID)
- return SendErrorResponse (1);
+ if (pid == LLDB_INVALID_PROCESS_ID)
+ return SendErrorResponse(1);
- ProcessInstanceInfo proc_info;
- if (!Host::GetProcessInfo (pid, proc_info))
- return SendErrorResponse (1);
+ ProcessInstanceInfo proc_info;
+ if (!Host::GetProcessInfo(pid, proc_info))
+ return SendErrorResponse(1);
- StreamString response;
- CreateProcessInfoResponse_DebugServerStyle(proc_info, response);
- return SendPacketNoLock (response.GetData (), response.GetSize ());
+ StreamString response;
+ CreateProcessInfoResponse_DebugServerStyle(proc_info, response);
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir (StringExtractorGDBRemote &packet)
-{
- // If this packet is sent to a platform, then change the current working directory
-
- char cwd[PATH_MAX];
- if (getcwd(cwd, sizeof(cwd)) == NULL)
- return SendErrorResponse(errno);
-
- StreamString response;
- response.PutBytesAsRawHex8(cwd, strlen(cwd));
- return SendPacketNoLock(response.GetData(), response.GetSize());
+GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir(
+ StringExtractorGDBRemote &packet) {
+ // If this packet is sent to a platform, then change the current working
+ // directory
+
+ char cwd[PATH_MAX];
+ if (getcwd(cwd, sizeof(cwd)) == NULL)
+ return SendErrorResponse(errno);
+
+ StreamString response;
+ response.PutBytesAsRawHex8(cwd, strlen(cwd));
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir (StringExtractorGDBRemote &packet)
-{
- packet.SetFilePos (::strlen ("QSetWorkingDir:"));
- std::string path;
- packet.GetHexByteString (path);
-
- // If this packet is sent to a platform, then change the current working directory
- if (::chdir(path.c_str()) != 0)
- return SendErrorResponse (errno);
- return SendOKResponse ();
+GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("QSetWorkingDir:"));
+ std::string path;
+ packet.GetHexByteString(path);
+
+ // If this packet is sent to a platform, then change the current working
+ // directory
+ if (::chdir(path.c_str()) != 0)
+ return SendErrorResponse(errno);
+ return SendOKResponse();
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerPlatform::Handle_qC (StringExtractorGDBRemote &packet)
-{
- // NOTE: lldb should now be using qProcessInfo for process IDs. This path here
- // should not be used. It is reporting process id instead of thread id. The
- // correct answer doesn't seem to make much sense for lldb-platform.
- // CONSIDER: flip to "unsupported".
- lldb::pid_t pid = m_process_launch_info.GetProcessID();
-
- StreamString response;
- response.Printf("QC%" PRIx64, pid);
-
- // If we launch a process and this GDB server is acting as a platform,
- // then we need to clear the process launch state so we can start
- // launching another process. In order to launch a process a bunch or
- // packets need to be sent: environment packets, working directory,
- // disable ASLR, and many more settings. When we launch a process we
- // then need to know when to clear this information. Currently we are
- // selecting the 'qC' packet as that packet which seems to make the most
- // sense.
- if (pid != LLDB_INVALID_PROCESS_ID)
- {
- m_process_launch_info.Clear();
- }
-
- return SendPacketNoLock (response.GetData(), response.GetSize());
+GDBRemoteCommunicationServerPlatform::Handle_qC(
+ StringExtractorGDBRemote &packet) {
+ // NOTE: lldb should now be using qProcessInfo for process IDs. This path
+ // here
+ // should not be used. It is reporting process id instead of thread id. The
+ // correct answer doesn't seem to make much sense for lldb-platform.
+ // CONSIDER: flip to "unsupported".
+ lldb::pid_t pid = m_process_launch_info.GetProcessID();
+
+ StreamString response;
+ response.Printf("QC%" PRIx64, pid);
+
+ // If we launch a process and this GDB server is acting as a platform,
+ // then we need to clear the process launch state so we can start
+ // launching another process. In order to launch a process a bunch or
+ // packets need to be sent: environment packets, working directory,
+ // disable ASLR, and many more settings. When we launch a process we
+ // then need to know when to clear this information. Currently we are
+ // selecting the 'qC' packet as that packet which seems to make the most
+ // sense.
+ if (pid != LLDB_INVALID_PROCESS_ID) {
+ m_process_launch_info.Clear();
+ }
+
+ return SendPacketNoLock(response.GetString());
}
GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo(StringExtractorGDBRemote &packet)
-{
- StructuredData::Array signal_array;
-
- const auto &signals = Host::GetUnixSignals();
- for (auto signo = signals->GetFirstSignalNumber();
- signo != LLDB_INVALID_SIGNAL_NUMBER;
- signo = signals->GetNextSignalNumber(signo))
- {
- auto dictionary = std::make_shared<StructuredData::Dictionary>();
-
- dictionary->AddIntegerItem("signo", signo);
- dictionary->AddStringItem("name", signals->GetSignalAsCString(signo));
-
- bool suppress, stop, notify;
- signals->GetSignalInfo(signo, suppress, stop, notify);
- dictionary->AddBooleanItem("suppress", suppress);
- dictionary->AddBooleanItem("stop", stop);
- dictionary->AddBooleanItem("notify", notify);
-
- signal_array.Push(dictionary);
- }
-
- StreamString response;
- signal_array.Dump(response);
- return SendPacketNoLock(response.GetData(), response.GetSize());
+GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo(
+ StringExtractorGDBRemote &packet) {
+ StructuredData::Array signal_array;
+
+ const auto &signals = Host::GetUnixSignals();
+ for (auto signo = signals->GetFirstSignalNumber();
+ signo != LLDB_INVALID_SIGNAL_NUMBER;
+ signo = signals->GetNextSignalNumber(signo)) {
+ auto dictionary = std::make_shared<StructuredData::Dictionary>();
+
+ dictionary->AddIntegerItem("signo", signo);
+ dictionary->AddStringItem("name", signals->GetSignalAsCString(signo));
+
+ bool suppress, stop, notify;
+ signals->GetSignalInfo(signo, suppress, stop, notify);
+ dictionary->AddBooleanItem("suppress", suppress);
+ dictionary->AddBooleanItem("stop", stop);
+ dictionary->AddBooleanItem("notify", notify);
+
+ signal_array.Push(dictionary);
+ }
+
+ StreamString response;
+ signal_array.Dump(response);
+ return SendPacketNoLock(response.GetString());
}
-bool
-GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped (lldb::pid_t pid)
-{
- std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
- FreePortForProcess(pid);
- m_spawned_pids.erase(pid);
- return true;
+bool GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped(
+ lldb::pid_t pid) {
+ std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
+ FreePortForProcess(pid);
+ m_spawned_pids.erase(pid);
+ return true;
}
-Error
-GDBRemoteCommunicationServerPlatform::LaunchProcess ()
-{
- if (!m_process_launch_info.GetArguments ().GetArgumentCount ())
- return Error ("%s: no process command line specified to launch", __FUNCTION__);
-
- // specify the process monitor if not already set. This should
- // generally be what happens since we need to reap started
- // processes.
- if (!m_process_launch_info.GetMonitorProcessCallback ())
- m_process_launch_info.SetMonitorProcessCallback(
- std::bind(&GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped, this, std::placeholders::_1),
- false);
-
- Error error = Host::LaunchProcess(m_process_launch_info);
- if (!error.Success ())
- {
- fprintf (stderr, "%s: failed to launch executable %s", __FUNCTION__, m_process_launch_info.GetArguments ().GetArgumentAtIndex (0));
- return error;
- }
+Error GDBRemoteCommunicationServerPlatform::LaunchProcess() {
+ if (!m_process_launch_info.GetArguments().GetArgumentCount())
+ return Error("%s: no process command line specified to launch",
+ __FUNCTION__);
+
+ // specify the process monitor if not already set. This should
+ // generally be what happens since we need to reap started
+ // processes.
+ if (!m_process_launch_info.GetMonitorProcessCallback())
+ m_process_launch_info.SetMonitorProcessCallback(
+ std::bind(
+ &GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped,
+ this, std::placeholders::_1),
+ false);
+
+ Error error = Host::LaunchProcess(m_process_launch_info);
+ if (!error.Success()) {
+ fprintf(stderr, "%s: failed to launch executable %s", __FUNCTION__,
+ m_process_launch_info.GetArguments().GetArgumentAtIndex(0));
+ return error;
+ }
- printf ("Launched '%s' as process %" PRIu64 "...\n", m_process_launch_info.GetArguments ().GetArgumentAtIndex (0), m_process_launch_info.GetProcessID());
+ printf("Launched '%s' as process %" PRIu64 "...\n",
+ m_process_launch_info.GetArguments().GetArgumentAtIndex(0),
+ m_process_launch_info.GetProcessID());
- // add to list of spawned processes. On an lldb-gdbserver, we
- // would expect there to be only one.
- const auto pid = m_process_launch_info.GetProcessID();
- if (pid != LLDB_INVALID_PROCESS_ID)
- {
- // add to spawned pids
- std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
- m_spawned_pids.insert(pid);
- }
+ // add to list of spawned processes. On an lldb-gdbserver, we
+ // would expect there to be only one.
+ const auto pid = m_process_launch_info.GetProcessID();
+ if (pid != LLDB_INVALID_PROCESS_ID) {
+ // add to spawned pids
+ std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
+ m_spawned_pids.insert(pid);
+ }
- return error;
+ return error;
}
-void
-GDBRemoteCommunicationServerPlatform::SetPortMap (PortMap &&port_map)
-{
- m_port_map = port_map;
+void GDBRemoteCommunicationServerPlatform::SetPortMap(PortMap &&port_map) {
+ m_port_map = port_map;
}
-uint16_t
-GDBRemoteCommunicationServerPlatform::GetNextAvailablePort ()
-{
- if (m_port_map.empty())
- return 0; // Bind to port zero and get a port, we didn't have any limitations
+uint16_t GDBRemoteCommunicationServerPlatform::GetNextAvailablePort() {
+ if (m_port_map.empty())
+ return 0; // Bind to port zero and get a port, we didn't have any
+ // limitations
- for (auto &pair : m_port_map)
- {
- if (pair.second == LLDB_INVALID_PROCESS_ID)
- {
- pair.second = ~(lldb::pid_t)LLDB_INVALID_PROCESS_ID;
- return pair.first;
- }
+ for (auto &pair : m_port_map) {
+ if (pair.second == LLDB_INVALID_PROCESS_ID) {
+ pair.second = ~(lldb::pid_t)LLDB_INVALID_PROCESS_ID;
+ return pair.first;
}
- return UINT16_MAX;
+ }
+ return UINT16_MAX;
}
-bool
-GDBRemoteCommunicationServerPlatform::AssociatePortWithProcess (uint16_t port, lldb::pid_t pid)
-{
- PortMap::iterator pos = m_port_map.find(port);
- if (pos != m_port_map.end())
- {
- pos->second = pid;
- return true;
- }
- return false;
+bool GDBRemoteCommunicationServerPlatform::AssociatePortWithProcess(
+ uint16_t port, lldb::pid_t pid) {
+ PortMap::iterator pos = m_port_map.find(port);
+ if (pos != m_port_map.end()) {
+ pos->second = pid;
+ return true;
+ }
+ return false;
}
-bool
-GDBRemoteCommunicationServerPlatform::FreePort (uint16_t port)
-{
- PortMap::iterator pos = m_port_map.find(port);
- if (pos != m_port_map.end())
- {
- pos->second = LLDB_INVALID_PROCESS_ID;
- return true;
- }
- return false;
+bool GDBRemoteCommunicationServerPlatform::FreePort(uint16_t port) {
+ PortMap::iterator pos = m_port_map.find(port);
+ if (pos != m_port_map.end()) {
+ pos->second = LLDB_INVALID_PROCESS_ID;
+ return true;
+ }
+ return false;
}
-bool
-GDBRemoteCommunicationServerPlatform::FreePortForProcess (lldb::pid_t pid)
-{
- if (!m_port_map.empty())
- {
- for (auto &pair : m_port_map)
- {
- if (pair.second == pid)
- {
- pair.second = LLDB_INVALID_PROCESS_ID;
- return true;
- }
- }
+bool GDBRemoteCommunicationServerPlatform::FreePortForProcess(lldb::pid_t pid) {
+ if (!m_port_map.empty()) {
+ for (auto &pair : m_port_map) {
+ if (pair.second == pid) {
+ pair.second = LLDB_INVALID_PROCESS_ID;
+ return true;
+ }
}
- return false;
+ }
+ return false;
}
-const FileSpec&
-GDBRemoteCommunicationServerPlatform::GetDomainSocketDir()
-{
- static FileSpec g_domainsocket_dir;
- static std::once_flag g_once_flag;
-
- std::call_once(g_once_flag, []() {
- const char* domainsocket_dir_env = ::getenv("LLDB_DEBUGSERVER_DOMAINSOCKET_DIR");
- if (domainsocket_dir_env != nullptr)
- g_domainsocket_dir = FileSpec(domainsocket_dir_env, false);
- else
- HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, g_domainsocket_dir);
- });
-
- return g_domainsocket_dir;
+const FileSpec &GDBRemoteCommunicationServerPlatform::GetDomainSocketDir() {
+ static FileSpec g_domainsocket_dir;
+ static std::once_flag g_once_flag;
+
+ std::call_once(g_once_flag, []() {
+ const char *domainsocket_dir_env =
+ ::getenv("LLDB_DEBUGSERVER_DOMAINSOCKET_DIR");
+ if (domainsocket_dir_env != nullptr)
+ g_domainsocket_dir = FileSpec(domainsocket_dir_env, false);
+ else
+ HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, g_domainsocket_dir);
+ });
+
+ return g_domainsocket_dir;
}
FileSpec
-GDBRemoteCommunicationServerPlatform::GetDomainSocketPath(const char* prefix)
-{
- llvm::SmallString<PATH_MAX> socket_path;
- llvm::SmallString<PATH_MAX> socket_name((llvm::StringRef(prefix) + ".%%%%%%").str());
+GDBRemoteCommunicationServerPlatform::GetDomainSocketPath(const char *prefix) {
+ llvm::SmallString<PATH_MAX> socket_path;
+ llvm::SmallString<PATH_MAX> socket_name(
+ (llvm::StringRef(prefix) + ".%%%%%%").str());
- FileSpec socket_path_spec(GetDomainSocketDir());
- socket_path_spec.AppendPathComponent(socket_name.c_str());
+ FileSpec socket_path_spec(GetDomainSocketDir());
+ socket_path_spec.AppendPathComponent(socket_name.c_str());
- llvm::sys::fs::createUniqueFile(socket_path_spec.GetCString(), socket_path);
- return FileSpec(socket_path.c_str(), false);
+ llvm::sys::fs::createUniqueFile(socket_path_spec.GetCString(), socket_path);
+ return FileSpec(socket_path.c_str(), false);
}
-void
-GDBRemoteCommunicationServerPlatform::SetPortOffset(uint16_t port_offset)
-{
- m_port_offset = port_offset;
+void GDBRemoteCommunicationServerPlatform::SetPortOffset(uint16_t port_offset) {
+ m_port_offset = port_offset;
}
-void
-GDBRemoteCommunicationServerPlatform::SetPendingGdbServer(lldb::pid_t pid,
- uint16_t port,
- const std::string& socket_name)
-{
- m_pending_gdb_server.pid = pid;
- m_pending_gdb_server.port = port;
- m_pending_gdb_server.socket_name = socket_name;
+void GDBRemoteCommunicationServerPlatform::SetPendingGdbServer(
+ lldb::pid_t pid, uint16_t port, const std::string &socket_name) {
+ m_pending_gdb_server.pid = pid;
+ m_pending_gdb_server.port = port;
+ m_pending_gdb_server.socket_name = socket_name;
}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
index 1f4d08c64e00..472d86e3a15c 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
@@ -24,110 +24,90 @@
namespace lldb_private {
namespace process_gdb_remote {
-class GDBRemoteCommunicationServerPlatform :
- public GDBRemoteCommunicationServerCommon
-{
+class GDBRemoteCommunicationServerPlatform
+ : public GDBRemoteCommunicationServerCommon {
public:
- typedef std::map<uint16_t, lldb::pid_t> PortMap;
+ typedef std::map<uint16_t, lldb::pid_t> PortMap;
- GDBRemoteCommunicationServerPlatform(const Socket::SocketProtocol socket_protocol,
- const char* socket_scheme);
+ GDBRemoteCommunicationServerPlatform(
+ const Socket::SocketProtocol socket_protocol, const char *socket_scheme);
- ~GDBRemoteCommunicationServerPlatform() override;
+ ~GDBRemoteCommunicationServerPlatform() override;
- Error
- LaunchProcess () override;
+ Error LaunchProcess() override;
- // Set both ports to zero to let the platform automatically bind to
- // a port chosen by the OS.
- void
- SetPortMap (PortMap &&port_map);
+ // Set both ports to zero to let the platform automatically bind to
+ // a port chosen by the OS.
+ void SetPortMap(PortMap &&port_map);
- //----------------------------------------------------------------------
- // If we are using a port map where we can only use certain ports,
- // get the next available port.
- //
- // If we are using a port map and we are out of ports, return UINT16_MAX
- //
- // If we aren't using a port map, return 0 to indicate we should bind to
- // port 0 and then figure out which port we used.
- //----------------------------------------------------------------------
- uint16_t
- GetNextAvailablePort ();
+ //----------------------------------------------------------------------
+ // If we are using a port map where we can only use certain ports,
+ // get the next available port.
+ //
+ // If we are using a port map and we are out of ports, return UINT16_MAX
+ //
+ // If we aren't using a port map, return 0 to indicate we should bind to
+ // port 0 and then figure out which port we used.
+ //----------------------------------------------------------------------
+ uint16_t GetNextAvailablePort();
- bool
- AssociatePortWithProcess (uint16_t port, lldb::pid_t pid);
+ bool AssociatePortWithProcess(uint16_t port, lldb::pid_t pid);
- bool
- FreePort (uint16_t port);
+ bool FreePort(uint16_t port);
- bool
- FreePortForProcess (lldb::pid_t pid);
+ bool FreePortForProcess(lldb::pid_t pid);
- void
- SetPortOffset (uint16_t port_offset);
+ void SetPortOffset(uint16_t port_offset);
- void
- SetInferiorArguments (const lldb_private::Args& args);
+ void SetInferiorArguments(const lldb_private::Args &args);
- Error
- LaunchGDBServer(const lldb_private::Args& args,
- std::string hostname,
- lldb::pid_t& pid,
- uint16_t& port,
- std::string& socket_name);
+ Error LaunchGDBServer(const lldb_private::Args &args, std::string hostname,
+ lldb::pid_t &pid, uint16_t &port,
+ std::string &socket_name);
- void
- SetPendingGdbServer(lldb::pid_t pid, uint16_t port, const std::string& socket_name);
+ void SetPendingGdbServer(lldb::pid_t pid, uint16_t port,
+ const std::string &socket_name);
protected:
- const Socket::SocketProtocol m_socket_protocol;
- const std::string m_socket_scheme;
- std::recursive_mutex m_spawned_pids_mutex;
- std::set<lldb::pid_t> m_spawned_pids;
+ const Socket::SocketProtocol m_socket_protocol;
+ const std::string m_socket_scheme;
+ std::recursive_mutex m_spawned_pids_mutex;
+ std::set<lldb::pid_t> m_spawned_pids;
- PortMap m_port_map;
- uint16_t m_port_offset;
- struct { lldb::pid_t pid; uint16_t port; std::string socket_name; } m_pending_gdb_server;
+ PortMap m_port_map;
+ uint16_t m_port_offset;
+ struct {
+ lldb::pid_t pid;
+ uint16_t port;
+ std::string socket_name;
+ } m_pending_gdb_server;
- PacketResult
- Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qLaunchGDBServer(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qQueryGDBServer (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qQueryGDBServer(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qKillSpawnedProcess (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qKillSpawnedProcess(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qProcessInfo (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qProcessInfo(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qGetWorkingDir (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qGetWorkingDir(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_QSetWorkingDir (StringExtractorGDBRemote &packet);
+ PacketResult Handle_QSetWorkingDir(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_qC (StringExtractorGDBRemote &packet);
+ PacketResult Handle_qC(StringExtractorGDBRemote &packet);
- PacketResult
- Handle_jSignalsInfo(StringExtractorGDBRemote &packet);
+ PacketResult Handle_jSignalsInfo(StringExtractorGDBRemote &packet);
private:
- bool
- KillSpawnedProcess (lldb::pid_t pid);
+ bool KillSpawnedProcess(lldb::pid_t pid);
- bool
- DebugserverProcessReaped (lldb::pid_t pid);
+ bool DebugserverProcessReaped(lldb::pid_t pid);
- static const FileSpec&
- GetDomainSocketDir();
+ static const FileSpec &GetDomainSocketDir();
- static FileSpec
- GetDomainSocketPath(const char* prefix);
+ static FileSpec GetDomainSocketPath(const char *prefix);
- DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunicationServerPlatform);
+ DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationServerPlatform);
};
} // namespace process_gdb_remote
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
index 57983c4979a6..27ce67ded783 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
@@ -21,12 +21,12 @@
#include "lldb/Target/Target.h"
#include "lldb/Utility/Utils.h"
// Project includes
-#include "Utility/StringExtractorGDBRemote.h"
#include "ProcessGDBRemote.h"
#include "ProcessGDBRemoteLog.h"
#include "ThreadGDBRemote.h"
#include "Utility/ARM_DWARF_Registers.h"
#include "Utility/ARM_ehframe_Registers.h"
+#include "Utility/StringExtractorGDBRemote.h"
using namespace lldb;
using namespace lldb_private;
@@ -35,1189 +35,953 @@ using namespace lldb_private::process_gdb_remote;
//----------------------------------------------------------------------
// GDBRemoteRegisterContext constructor
//----------------------------------------------------------------------
-GDBRemoteRegisterContext::GDBRemoteRegisterContext
-(
- ThreadGDBRemote &thread,
- uint32_t concrete_frame_idx,
- GDBRemoteDynamicRegisterInfo &reg_info,
- bool read_all_at_once
-) :
- RegisterContext (thread, concrete_frame_idx),
- m_reg_info (reg_info),
- m_reg_valid (),
- m_reg_data (),
- m_read_all_at_once (read_all_at_once)
-{
- // Resize our vector of bools to contain one bool for every register.
- // We will use these boolean values to know when a register value
- // is valid in m_reg_data.
- m_reg_valid.resize (reg_info.GetNumRegisters());
-
- // Make a heap based buffer that is big enough to store all registers
- DataBufferSP reg_data_sp(new DataBufferHeap (reg_info.GetRegisterDataByteSize(), 0));
- m_reg_data.SetData (reg_data_sp);
- m_reg_data.SetByteOrder(thread.GetProcess()->GetByteOrder());
+GDBRemoteRegisterContext::GDBRemoteRegisterContext(
+ ThreadGDBRemote &thread, uint32_t concrete_frame_idx,
+ GDBRemoteDynamicRegisterInfo &reg_info, bool read_all_at_once)
+ : RegisterContext(thread, concrete_frame_idx), m_reg_info(reg_info),
+ m_reg_valid(), m_reg_data(), m_read_all_at_once(read_all_at_once) {
+ // Resize our vector of bools to contain one bool for every register.
+ // We will use these boolean values to know when a register value
+ // is valid in m_reg_data.
+ m_reg_valid.resize(reg_info.GetNumRegisters());
+
+ // Make a heap based buffer that is big enough to store all registers
+ DataBufferSP reg_data_sp(
+ new DataBufferHeap(reg_info.GetRegisterDataByteSize(), 0));
+ m_reg_data.SetData(reg_data_sp);
+ m_reg_data.SetByteOrder(thread.GetProcess()->GetByteOrder());
}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-GDBRemoteRegisterContext::~GDBRemoteRegisterContext()
-{
-}
+GDBRemoteRegisterContext::~GDBRemoteRegisterContext() {}
-void
-GDBRemoteRegisterContext::InvalidateAllRegisters ()
-{
- SetAllRegisterValid (false);
+void GDBRemoteRegisterContext::InvalidateAllRegisters() {
+ SetAllRegisterValid(false);
}
-void
-GDBRemoteRegisterContext::SetAllRegisterValid (bool b)
-{
- std::vector<bool>::iterator pos, end = m_reg_valid.end();
- for (pos = m_reg_valid.begin(); pos != end; ++pos)
- *pos = b;
+void GDBRemoteRegisterContext::SetAllRegisterValid(bool b) {
+ std::vector<bool>::iterator pos, end = m_reg_valid.end();
+ for (pos = m_reg_valid.begin(); pos != end; ++pos)
+ *pos = b;
}
-size_t
-GDBRemoteRegisterContext::GetRegisterCount ()
-{
- return m_reg_info.GetNumRegisters ();
+size_t GDBRemoteRegisterContext::GetRegisterCount() {
+ return m_reg_info.GetNumRegisters();
}
const RegisterInfo *
-GDBRemoteRegisterContext::GetRegisterInfoAtIndex (size_t reg)
-{
- RegisterInfo* reg_info = m_reg_info.GetRegisterInfoAtIndex (reg);
-
- if (reg_info && reg_info->dynamic_size_dwarf_expr_bytes)
- {
- const ArchSpec &arch = m_thread.GetProcess ()->GetTarget ().GetArchitecture ();
- uint8_t reg_size = UpdateDynamicRegisterSize (arch, reg_info);
- reg_info->byte_size = reg_size;
- }
- return reg_info;
+GDBRemoteRegisterContext::GetRegisterInfoAtIndex(size_t reg) {
+ RegisterInfo *reg_info = m_reg_info.GetRegisterInfoAtIndex(reg);
+
+ if (reg_info && reg_info->dynamic_size_dwarf_expr_bytes) {
+ const ArchSpec &arch = m_thread.GetProcess()->GetTarget().GetArchitecture();
+ uint8_t reg_size = UpdateDynamicRegisterSize(arch, reg_info);
+ reg_info->byte_size = reg_size;
+ }
+ return reg_info;
}
-size_t
-GDBRemoteRegisterContext::GetRegisterSetCount ()
-{
- return m_reg_info.GetNumRegisterSets ();
+size_t GDBRemoteRegisterContext::GetRegisterSetCount() {
+ return m_reg_info.GetNumRegisterSets();
}
-
-
-const RegisterSet *
-GDBRemoteRegisterContext::GetRegisterSet (size_t reg_set)
-{
- return m_reg_info.GetRegisterSet (reg_set);
+const RegisterSet *GDBRemoteRegisterContext::GetRegisterSet(size_t reg_set) {
+ return m_reg_info.GetRegisterSet(reg_set);
}
+bool GDBRemoteRegisterContext::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &value) {
+ // Read the register
+ if (ReadRegisterBytes(reg_info, m_reg_data)) {
+ const bool partial_data_ok = false;
+ Error error(value.SetValueFromData(reg_info, m_reg_data,
+ reg_info->byte_offset, partial_data_ok));
+ return error.Success();
+ }
+ return false;
+}
-
-bool
-GDBRemoteRegisterContext::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value)
-{
- // Read the register
- if (ReadRegisterBytes (reg_info, m_reg_data))
- {
- const bool partial_data_ok = false;
- Error error (value.SetValueFromData(reg_info, m_reg_data, reg_info->byte_offset, partial_data_ok));
- return error.Success();
- }
+bool GDBRemoteRegisterContext::PrivateSetRegisterValue(
+ uint32_t reg, llvm::ArrayRef<uint8_t> data) {
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
+ if (reg_info == NULL)
return false;
-}
-bool
-GDBRemoteRegisterContext::PrivateSetRegisterValue (uint32_t reg, StringExtractor &response)
-{
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg);
- if (reg_info == NULL)
- return false;
-
- // Invalidate if needed
- InvalidateIfNeeded(false);
-
- const uint32_t reg_byte_size = reg_info->byte_size;
- const size_t bytes_copied = response.GetHexBytes (const_cast<uint8_t*>(m_reg_data.PeekData(reg_info->byte_offset, reg_byte_size)), reg_byte_size, '\xcc');
- bool success = bytes_copied == reg_byte_size;
- if (success)
- {
- SetRegisterIsValid(reg, true);
- }
- else if (bytes_copied > 0)
- {
- // Only set register is valid to false if we copied some bytes, else
- // leave it as it was.
- SetRegisterIsValid(reg, false);
- }
- return success;
+ // Invalidate if needed
+ InvalidateIfNeeded(false);
+
+ const size_t reg_byte_size = reg_info->byte_size;
+ memcpy(const_cast<uint8_t *>(
+ m_reg_data.PeekData(reg_info->byte_offset, reg_byte_size)),
+ data.data(), std::min(data.size(), reg_byte_size));
+ bool success = data.size() >= reg_byte_size;
+ if (success) {
+ SetRegisterIsValid(reg, true);
+ } else if (data.size() > 0) {
+ // Only set register is valid to false if we copied some bytes, else
+ // leave it as it was.
+ SetRegisterIsValid(reg, false);
+ }
+ return success;
}
-bool
-GDBRemoteRegisterContext::PrivateSetRegisterValue (uint32_t reg, uint64_t new_reg_val)
-{
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg);
- if (reg_info == NULL)
- return false;
-
- // Early in process startup, we can get a thread that has an invalid byte order
- // because the process hasn't been completely set up yet (see the ctor where the
- // byte order is setfrom the process). If that's the case, we can't set the
- // value here.
- if (m_reg_data.GetByteOrder() == eByteOrderInvalid)
- {
- return false;
- }
-
- // Invalidate if needed
- InvalidateIfNeeded (false);
+bool GDBRemoteRegisterContext::PrivateSetRegisterValue(uint32_t reg,
+ uint64_t new_reg_val) {
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
+ if (reg_info == NULL)
+ return false;
- DataBufferSP buffer_sp (new DataBufferHeap (&new_reg_val, sizeof (new_reg_val)));
- DataExtractor data (buffer_sp, endian::InlHostByteOrder(), sizeof (void*));
+ // Early in process startup, we can get a thread that has an invalid byte
+ // order
+ // because the process hasn't been completely set up yet (see the ctor where
+ // the
+ // byte order is setfrom the process). If that's the case, we can't set the
+ // value here.
+ if (m_reg_data.GetByteOrder() == eByteOrderInvalid) {
+ return false;
+ }
- // If our register context and our register info disagree, which should never happen, don't
- // overwrite past the end of the buffer.
- if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size)
- return false;
+ // Invalidate if needed
+ InvalidateIfNeeded(false);
- // Grab a pointer to where we are going to put this register
- uint8_t *dst = const_cast<uint8_t*>(m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size));
+ DataBufferSP buffer_sp(new DataBufferHeap(&new_reg_val, sizeof(new_reg_val)));
+ DataExtractor data(buffer_sp, endian::InlHostByteOrder(), sizeof(void *));
- if (dst == NULL)
- return false;
+ // If our register context and our register info disagree, which should never
+ // happen, don't
+ // overwrite past the end of the buffer.
+ if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size)
+ return false;
+ // Grab a pointer to where we are going to put this register
+ uint8_t *dst = const_cast<uint8_t *>(
+ m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size));
- if (data.CopyByteOrderedData (0, // src offset
- reg_info->byte_size, // src length
- dst, // dst
- reg_info->byte_size, // dst length
- m_reg_data.GetByteOrder())) // dst byte order
- {
- SetRegisterIsValid (reg, true);
- return true;
- }
+ if (dst == NULL)
return false;
+
+ if (data.CopyByteOrderedData(0, // src offset
+ reg_info->byte_size, // src length
+ dst, // dst
+ reg_info->byte_size, // dst length
+ m_reg_data.GetByteOrder())) // dst byte order
+ {
+ SetRegisterIsValid(reg, true);
+ return true;
+ }
+ return false;
}
// Helper function for GDBRemoteRegisterContext::ReadRegisterBytes().
-bool
-GDBRemoteRegisterContext::GetPrimordialRegister(const RegisterInfo *reg_info,
- GDBRemoteCommunicationClient &gdb_comm)
-{
- const uint32_t lldb_reg = reg_info->kinds[eRegisterKindLLDB];
- const uint32_t remote_reg = reg_info->kinds[eRegisterKindProcessPlugin];
- StringExtractorGDBRemote response;
- if (gdb_comm.ReadRegister(m_thread.GetProtocolID(), remote_reg, response))
- return PrivateSetRegisterValue (lldb_reg, response);
- return false;
+bool GDBRemoteRegisterContext::GetPrimordialRegister(
+ const RegisterInfo *reg_info, GDBRemoteCommunicationClient &gdb_comm) {
+ const uint32_t lldb_reg = reg_info->kinds[eRegisterKindLLDB];
+ const uint32_t remote_reg = reg_info->kinds[eRegisterKindProcessPlugin];
+ StringExtractorGDBRemote response;
+ if (DataBufferSP buffer_sp =
+ gdb_comm.ReadRegister(m_thread.GetProtocolID(), remote_reg))
+ return PrivateSetRegisterValue(
+ lldb_reg, llvm::ArrayRef<uint8_t>(buffer_sp->GetBytes(),
+ buffer_sp->GetByteSize()));
+ return false;
}
-bool
-GDBRemoteRegisterContext::ReadRegisterBytes (const RegisterInfo *reg_info, DataExtractor &data)
-{
- ExecutionContext exe_ctx (CalculateThread());
+bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info,
+ DataExtractor &data) {
+ ExecutionContext exe_ctx(CalculateThread());
- Process *process = exe_ctx.GetProcessPtr();
- Thread *thread = exe_ctx.GetThreadPtr();
- if (process == NULL || thread == NULL)
- return false;
-
- GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote());
+ Process *process = exe_ctx.GetProcessPtr();
+ Thread *thread = exe_ctx.GetThreadPtr();
+ if (process == NULL || thread == NULL)
+ return false;
- InvalidateIfNeeded(false);
+ GDBRemoteCommunicationClient &gdb_comm(
+ ((ProcessGDBRemote *)process)->GetGDBRemote());
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+ InvalidateIfNeeded(false);
- if (!GetRegisterIsValid(reg))
- {
- if (m_read_all_at_once)
- {
- StringExtractorGDBRemote response;
- if (!gdb_comm.ReadAllRegisters(m_thread.GetProtocolID(), response))
- return false;
- if (response.IsNormalResponse())
- if (response.GetHexBytes(const_cast<void *>(reinterpret_cast<const void *>(m_reg_data.GetDataStart())),
- m_reg_data.GetByteSize(), '\xcc') == m_reg_data.GetByteSize())
- SetAllRegisterValid (true);
- }
- else if (reg_info->value_regs)
- {
- // Process this composite register request by delegating to the constituent
- // primordial registers.
-
- // Index of the primordial register.
- bool success = true;
- for (uint32_t idx = 0; success; ++idx)
- {
- const uint32_t prim_reg = reg_info->value_regs[idx];
- if (prim_reg == LLDB_INVALID_REGNUM)
- break;
- // We have a valid primordial register as our constituent.
- // Grab the corresponding register info.
- const RegisterInfo *prim_reg_info = GetRegisterInfoAtIndex(prim_reg);
- if (prim_reg_info == NULL)
- success = false;
- else
- {
- // Read the containing register if it hasn't already been read
- if (!GetRegisterIsValid(prim_reg))
- success = GetPrimordialRegister(prim_reg_info, gdb_comm);
- }
- }
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- if (success)
- {
- // If we reach this point, all primordial register requests have succeeded.
- // Validate this composite register.
- SetRegisterIsValid (reg_info, true);
- }
+ if (!GetRegisterIsValid(reg)) {
+ if (m_read_all_at_once) {
+ if (DataBufferSP buffer_sp =
+ gdb_comm.ReadAllRegisters(m_thread.GetProtocolID())) {
+ memcpy(const_cast<uint8_t *>(m_reg_data.GetDataStart()),
+ buffer_sp->GetBytes(),
+ std::min(buffer_sp->GetByteSize(), m_reg_data.GetByteSize()));
+ if (buffer_sp->GetByteSize() >= m_reg_data.GetByteSize()) {
+ SetAllRegisterValid(true);
+ return true;
}
- else
- {
- // Get each register individually
- GetPrimordialRegister(reg_info, gdb_comm);
+ }
+ return false;
+ }
+ if (reg_info->value_regs) {
+ // Process this composite register request by delegating to the
+ // constituent
+ // primordial registers.
+
+ // Index of the primordial register.
+ bool success = true;
+ for (uint32_t idx = 0; success; ++idx) {
+ const uint32_t prim_reg = reg_info->value_regs[idx];
+ if (prim_reg == LLDB_INVALID_REGNUM)
+ break;
+ // We have a valid primordial register as our constituent.
+ // Grab the corresponding register info.
+ const RegisterInfo *prim_reg_info = GetRegisterInfoAtIndex(prim_reg);
+ if (prim_reg_info == NULL)
+ success = false;
+ else {
+ // Read the containing register if it hasn't already been read
+ if (!GetRegisterIsValid(prim_reg))
+ success = GetPrimordialRegister(prim_reg_info, gdb_comm);
}
-
- // Make sure we got a valid register value after reading it
- if (!GetRegisterIsValid(reg))
- return false;
+ }
+
+ if (success) {
+ // If we reach this point, all primordial register requests have
+ // succeeded.
+ // Validate this composite register.
+ SetRegisterIsValid(reg_info, true);
+ }
+ } else {
+ // Get each register individually
+ GetPrimordialRegister(reg_info, gdb_comm);
}
- if (&data != &m_reg_data)
- {
-#if defined (LLDB_CONFIGURATION_DEBUG)
- assert (m_reg_data.GetByteSize() >= reg_info->byte_offset + reg_info->byte_size);
-#endif
- // If our register context and our register info disagree, which should never happen, don't
- // read past the end of the buffer.
- if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size)
- return false;
-
- // If we aren't extracting into our own buffer (which
- // only happens when this function is called from
- // ReadRegisterValue(uint32_t, Scalar&)) then
- // we transfer bytes from our buffer into the data
- // buffer that was passed in
-
- data.SetByteOrder (m_reg_data.GetByteOrder());
- data.SetData (m_reg_data, reg_info->byte_offset, reg_info->byte_size);
- }
- return true;
-}
+ // Make sure we got a valid register value after reading it
+ if (!GetRegisterIsValid(reg))
+ return false;
+ }
-bool
-GDBRemoteRegisterContext::WriteRegister (const RegisterInfo *reg_info,
- const RegisterValue &value)
-{
- DataExtractor data;
- if (value.GetData (data))
- return WriteRegisterBytes (reg_info, data, 0);
- return false;
+ if (&data != &m_reg_data) {
+#if defined(LLDB_CONFIGURATION_DEBUG)
+ assert(m_reg_data.GetByteSize() >=
+ reg_info->byte_offset + reg_info->byte_size);
+#endif
+ // If our register context and our register info disagree, which should
+ // never happen, don't
+ // read past the end of the buffer.
+ if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size)
+ return false;
+
+ // If we aren't extracting into our own buffer (which
+ // only happens when this function is called from
+ // ReadRegisterValue(uint32_t, Scalar&)) then
+ // we transfer bytes from our buffer into the data
+ // buffer that was passed in
+
+ data.SetByteOrder(m_reg_data.GetByteOrder());
+ data.SetData(m_reg_data, reg_info->byte_offset, reg_info->byte_size);
+ }
+ return true;
}
-// Helper function for GDBRemoteRegisterContext::WriteRegisterBytes().
-bool
-GDBRemoteRegisterContext::SetPrimordialRegister(const RegisterInfo *reg_info,
- GDBRemoteCommunicationClient &gdb_comm)
-{
- StreamString packet;
- StringExtractorGDBRemote response;
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- packet.Printf ("P%x=", reg_info->kinds[eRegisterKindProcessPlugin]);
- packet.PutBytesAsRawHex8 (m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size),
- reg_info->byte_size,
- endian::InlHostByteOrder(),
- endian::InlHostByteOrder());
-
- if (gdb_comm.GetThreadSuffixSupported())
- packet.Printf (";thread:%4.4" PRIx64 ";", m_thread.GetProtocolID());
-
- // Invalidate just this register
- SetRegisterIsValid(reg, false);
- if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(),
- packet.GetString().size(),
- response,
- false) == GDBRemoteCommunication::PacketResult::Success)
- {
- if (response.IsOKResponse())
- return true;
- }
- return false;
+bool GDBRemoteRegisterContext::WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &value) {
+ DataExtractor data;
+ if (value.GetData(data))
+ return WriteRegisterBytes(reg_info, data, 0);
+ return false;
}
-void
-GDBRemoteRegisterContext::SyncThreadState(Process *process)
-{
- // NB. We assume our caller has locked the sequence mutex.
-
- GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *) process)->GetGDBRemote());
- if (!gdb_comm.GetSyncThreadStateSupported())
- return;
-
- StreamString packet;
- StringExtractorGDBRemote response;
- packet.Printf ("QSyncThreadState:%4.4" PRIx64 ";", m_thread.GetProtocolID());
- if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(),
- packet.GetString().size(),
- response,
- false) == GDBRemoteCommunication::PacketResult::Success)
- {
- if (response.IsOKResponse())
- InvalidateAllRegisters();
- }
+// Helper function for GDBRemoteRegisterContext::WriteRegisterBytes().
+bool GDBRemoteRegisterContext::SetPrimordialRegister(
+ const RegisterInfo *reg_info, GDBRemoteCommunicationClient &gdb_comm) {
+ StreamString packet;
+ StringExtractorGDBRemote response;
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+ // Invalidate just this register
+ SetRegisterIsValid(reg, false);
+
+ return gdb_comm.WriteRegister(
+ m_thread.GetProtocolID(), reg_info->kinds[eRegisterKindProcessPlugin],
+ {m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size),
+ reg_info->byte_size});
}
-bool
-GDBRemoteRegisterContext::WriteRegisterBytes (const RegisterInfo *reg_info, DataExtractor &data, uint32_t data_offset)
-{
- ExecutionContext exe_ctx (CalculateThread());
+bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info,
+ DataExtractor &data,
+ uint32_t data_offset) {
+ ExecutionContext exe_ctx(CalculateThread());
- Process *process = exe_ctx.GetProcessPtr();
- Thread *thread = exe_ctx.GetThreadPtr();
- if (process == NULL || thread == NULL)
- return false;
-
- GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote());
-// FIXME: This check isn't right because IsRunning checks the Public state, but this
-// is work you need to do - for instance in ShouldStop & friends - before the public
-// state has been changed.
-// if (gdb_comm.IsRunning())
-// return false;
+ Process *process = exe_ctx.GetProcessPtr();
+ Thread *thread = exe_ctx.GetThreadPtr();
+ if (process == NULL || thread == NULL)
+ return false;
+ GDBRemoteCommunicationClient &gdb_comm(
+ ((ProcessGDBRemote *)process)->GetGDBRemote());
-#if defined (LLDB_CONFIGURATION_DEBUG)
- assert (m_reg_data.GetByteSize() >= reg_info->byte_offset + reg_info->byte_size);
+#if defined(LLDB_CONFIGURATION_DEBUG)
+ assert(m_reg_data.GetByteSize() >=
+ reg_info->byte_offset + reg_info->byte_size);
#endif
- // If our register context and our register info disagree, which should never happen, don't
- // overwrite past the end of the buffer.
- if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size)
- return false;
+ // If our register context and our register info disagree, which should never
+ // happen, don't
+ // overwrite past the end of the buffer.
+ if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size)
+ return false;
- // Grab a pointer to where we are going to put this register
- uint8_t *dst = const_cast<uint8_t*>(m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size));
+ // Grab a pointer to where we are going to put this register
+ uint8_t *dst = const_cast<uint8_t *>(
+ m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size));
- if (dst == NULL)
- return false;
+ if (dst == NULL)
+ return false;
+ if (data.CopyByteOrderedData(data_offset, // src offset
+ reg_info->byte_size, // src length
+ dst, // dst
+ reg_info->byte_size, // dst length
+ m_reg_data.GetByteOrder())) // dst byte order
+ {
+ GDBRemoteClientBase::Lock lock(gdb_comm, false);
+ if (lock) {
+ if (m_read_all_at_once) {
+ // Invalidate all register values
+ InvalidateIfNeeded(true);
+
+ // Set all registers in one packet
+ if (gdb_comm.WriteAllRegisters(
+ m_thread.GetProtocolID(),
+ {m_reg_data.GetDataStart(), size_t(m_reg_data.GetByteSize())}))
- if (data.CopyByteOrderedData (data_offset, // src offset
- reg_info->byte_size, // src length
- dst, // dst
- reg_info->byte_size, // dst length
- m_reg_data.GetByteOrder())) // dst byte order
- {
- Mutex::Locker locker;
- if (gdb_comm.GetSequenceMutex (locker, "Didn't get sequence mutex for write register."))
{
- const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported();
- ProcessSP process_sp (m_thread.GetProcess());
- if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetProtocolID()))
- {
- StreamString packet;
- StringExtractorGDBRemote response;
-
- if (m_read_all_at_once)
- {
- // Set all registers in one packet
- packet.PutChar ('G');
- packet.PutBytesAsRawHex8 (m_reg_data.GetDataStart(),
- m_reg_data.GetByteSize(),
- endian::InlHostByteOrder(),
- endian::InlHostByteOrder());
-
- if (thread_suffix_supported)
- packet.Printf (";thread:%4.4" PRIx64 ";", m_thread.GetProtocolID());
-
- // Invalidate all register values
- InvalidateIfNeeded (true);
-
- if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(),
- packet.GetString().size(),
- response,
- false) == GDBRemoteCommunication::PacketResult::Success)
- {
- SetAllRegisterValid (false);
- if (response.IsOKResponse())
- {
- return true;
- }
- }
- }
- else
- {
- bool success = true;
-
- if (reg_info->value_regs)
- {
- // This register is part of another register. In this case we read the actual
- // register data for any "value_regs", and once all that data is read, we will
- // have enough data in our register context bytes for the value of this register
-
- // Invalidate this composite register first.
-
- for (uint32_t idx = 0; success; ++idx)
- {
- const uint32_t reg = reg_info->value_regs[idx];
- if (reg == LLDB_INVALID_REGNUM)
- break;
- // We have a valid primordial register as our constituent.
- // Grab the corresponding register info.
- const RegisterInfo *value_reg_info = GetRegisterInfoAtIndex(reg);
- if (value_reg_info == NULL)
- success = false;
- else
- success = SetPrimordialRegister(value_reg_info, gdb_comm);
- }
- }
- else
- {
- // This is an actual register, write it
- success = SetPrimordialRegister(reg_info, gdb_comm);
- }
-
- // Check if writing this register will invalidate any other register values?
- // If so, invalidate them
- if (reg_info->invalidate_regs)
- {
- for (uint32_t idx = 0, reg = reg_info->invalidate_regs[0];
- reg != LLDB_INVALID_REGNUM;
- reg = reg_info->invalidate_regs[++idx])
- {
- SetRegisterIsValid(reg, false);
- }
- }
-
- return success;
- }
- }
+ SetAllRegisterValid(false);
+ return true;
}
- else
- {
- Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS));
- if (log)
- {
- if (log->GetVerbose())
- {
- StreamString strm;
- gdb_comm.DumpHistory(strm);
- log->Printf("error: failed to get packet sequence mutex, not sending write register for \"%s\":\n%s", reg_info->name, strm.GetData());
- }
- else
- log->Printf("error: failed to get packet sequence mutex, not sending write register for \"%s\"", reg_info->name);
- }
+ } else {
+ bool success = true;
+
+ if (reg_info->value_regs) {
+ // This register is part of another register. In this case we read the
+ // actual
+ // register data for any "value_regs", and once all that data is read,
+ // we will
+ // have enough data in our register context bytes for the value of
+ // this register
+
+ // Invalidate this composite register first.
+
+ for (uint32_t idx = 0; success; ++idx) {
+ const uint32_t reg = reg_info->value_regs[idx];
+ if (reg == LLDB_INVALID_REGNUM)
+ break;
+ // We have a valid primordial register as our constituent.
+ // Grab the corresponding register info.
+ const RegisterInfo *value_reg_info = GetRegisterInfoAtIndex(reg);
+ if (value_reg_info == NULL)
+ success = false;
+ else
+ success = SetPrimordialRegister(value_reg_info, gdb_comm);
+ }
+ } else {
+ // This is an actual register, write it
+ success = SetPrimordialRegister(reg_info, gdb_comm);
+ }
+
+ // Check if writing this register will invalidate any other register
+ // values?
+ // If so, invalidate them
+ if (reg_info->invalidate_regs) {
+ for (uint32_t idx = 0, reg = reg_info->invalidate_regs[0];
+ reg != LLDB_INVALID_REGNUM;
+ reg = reg_info->invalidate_regs[++idx]) {
+ SetRegisterIsValid(reg, false);
+ }
}
+
+ return success;
+ }
+ } else {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_THREAD |
+ GDBR_LOG_PACKETS));
+ if (log) {
+ if (log->GetVerbose()) {
+ StreamString strm;
+ gdb_comm.DumpHistory(strm);
+ log->Printf("error: failed to get packet sequence mutex, not sending "
+ "write register for \"%s\":\n%s",
+ reg_info->name, strm.GetData());
+ } else
+ log->Printf("error: failed to get packet sequence mutex, not sending "
+ "write register for \"%s\"",
+ reg_info->name);
+ }
}
+ }
+ return false;
+}
+
+bool GDBRemoteRegisterContext::ReadAllRegisterValues(
+ RegisterCheckpoint &reg_checkpoint) {
+ ExecutionContext exe_ctx(CalculateThread());
+
+ Process *process = exe_ctx.GetProcessPtr();
+ Thread *thread = exe_ctx.GetThreadPtr();
+ if (process == NULL || thread == NULL)
return false;
+
+ GDBRemoteCommunicationClient &gdb_comm(
+ ((ProcessGDBRemote *)process)->GetGDBRemote());
+
+ uint32_t save_id = 0;
+ if (gdb_comm.SaveRegisterState(thread->GetProtocolID(), save_id)) {
+ reg_checkpoint.SetID(save_id);
+ reg_checkpoint.GetData().reset();
+ return true;
+ } else {
+ reg_checkpoint.SetID(0); // Invalid save ID is zero
+ return ReadAllRegisterValues(reg_checkpoint.GetData());
+ }
}
-bool
-GDBRemoteRegisterContext::ReadAllRegisterValues (RegisterCheckpoint &reg_checkpoint)
-{
- ExecutionContext exe_ctx (CalculateThread());
-
+bool GDBRemoteRegisterContext::WriteAllRegisterValues(
+ const RegisterCheckpoint &reg_checkpoint) {
+ uint32_t save_id = reg_checkpoint.GetID();
+ if (save_id != 0) {
+ ExecutionContext exe_ctx(CalculateThread());
+
Process *process = exe_ctx.GetProcessPtr();
Thread *thread = exe_ctx.GetThreadPtr();
if (process == NULL || thread == NULL)
- return false;
-
- GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote());
-
- uint32_t save_id = 0;
- if (gdb_comm.SaveRegisterState(thread->GetProtocolID(), save_id))
- {
- reg_checkpoint.SetID(save_id);
- reg_checkpoint.GetData().reset();
- return true;
- }
- else
- {
- reg_checkpoint.SetID(0); // Invalid save ID is zero
- return ReadAllRegisterValues(reg_checkpoint.GetData());
- }
-}
+ return false;
-bool
-GDBRemoteRegisterContext::WriteAllRegisterValues (const RegisterCheckpoint &reg_checkpoint)
-{
- uint32_t save_id = reg_checkpoint.GetID();
- if (save_id != 0)
- {
- ExecutionContext exe_ctx (CalculateThread());
-
- Process *process = exe_ctx.GetProcessPtr();
- Thread *thread = exe_ctx.GetThreadPtr();
- if (process == NULL || thread == NULL)
- return false;
-
- GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote());
-
- return gdb_comm.RestoreRegisterState(m_thread.GetProtocolID(), save_id);
- }
- else
- {
- return WriteAllRegisterValues(reg_checkpoint.GetData());
- }
+ GDBRemoteCommunicationClient &gdb_comm(
+ ((ProcessGDBRemote *)process)->GetGDBRemote());
+
+ return gdb_comm.RestoreRegisterState(m_thread.GetProtocolID(), save_id);
+ } else {
+ return WriteAllRegisterValues(reg_checkpoint.GetData());
+ }
}
-bool
-GDBRemoteRegisterContext::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
-{
- ExecutionContext exe_ctx (CalculateThread());
+bool GDBRemoteRegisterContext::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ ExecutionContext exe_ctx(CalculateThread());
- Process *process = exe_ctx.GetProcessPtr();
- Thread *thread = exe_ctx.GetThreadPtr();
- if (process == NULL || thread == NULL)
- return false;
+ Process *process = exe_ctx.GetProcessPtr();
+ Thread *thread = exe_ctx.GetThreadPtr();
+ if (process == NULL || thread == NULL)
+ return false;
- GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote());
+ GDBRemoteCommunicationClient &gdb_comm(
+ ((ProcessGDBRemote *)process)->GetGDBRemote());
- StringExtractorGDBRemote response;
+ const bool use_g_packet =
+ gdb_comm.AvoidGPackets((ProcessGDBRemote *)process) == false;
- const bool use_g_packet = gdb_comm.AvoidGPackets ((ProcessGDBRemote *)process) == false;
+ GDBRemoteClientBase::Lock lock(gdb_comm, false);
+ if (lock) {
+ if (gdb_comm.SyncThreadState(m_thread.GetProtocolID()))
+ InvalidateAllRegisters();
- Mutex::Locker locker;
- if (gdb_comm.GetSequenceMutex (locker, "Didn't get sequence mutex for read all registers."))
- {
- SyncThreadState(process);
-
- char packet[32];
- const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported();
- ProcessSP process_sp (m_thread.GetProcess());
- if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetProtocolID()))
- {
- int packet_len = 0;
- if (thread_suffix_supported)
- packet_len = ::snprintf (packet, sizeof(packet), "g;thread:%4.4" PRIx64, m_thread.GetProtocolID());
- else
- packet_len = ::snprintf (packet, sizeof(packet), "g");
- assert (packet_len < ((int)sizeof(packet) - 1));
-
- if (use_g_packet && gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false) == GDBRemoteCommunication::PacketResult::Success)
- {
- int packet_len = 0;
- if (thread_suffix_supported)
- packet_len = ::snprintf (packet, sizeof(packet), "g;thread:%4.4" PRIx64, m_thread.GetProtocolID());
- else
- packet_len = ::snprintf (packet, sizeof(packet), "g");
- assert (packet_len < ((int)sizeof(packet) - 1));
-
- if (gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false) == GDBRemoteCommunication::PacketResult::Success)
- {
- if (response.IsErrorResponse())
- return false;
-
- std::string &response_str = response.GetStringRef();
- if (isxdigit(response_str[0]))
- {
- response_str.insert(0, 1, 'G');
- if (thread_suffix_supported)
- {
- char thread_id_cstr[64];
- ::snprintf (thread_id_cstr, sizeof(thread_id_cstr), ";thread:%4.4" PRIx64 ";", m_thread.GetProtocolID());
- response_str.append (thread_id_cstr);
- }
- data_sp.reset (new DataBufferHeap (response_str.c_str(), response_str.size()));
- return true;
- }
- }
- }
- else
- {
- // For the use_g_packet == false case, we're going to read each register
- // individually and store them as binary data in a buffer instead of as ascii
- // characters.
- const RegisterInfo *reg_info;
-
- // data_sp will take ownership of this DataBufferHeap pointer soon.
- DataBufferSP reg_ctx(new DataBufferHeap(m_reg_info.GetRegisterDataByteSize(), 0));
-
- for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex (i)) != NULL; i++)
- {
- if (reg_info->value_regs) // skip registers that are slices of real registers
- continue;
- ReadRegisterBytes (reg_info, m_reg_data);
- // ReadRegisterBytes saves the contents of the register in to the m_reg_data buffer
- }
- memcpy (reg_ctx->GetBytes(), m_reg_data.GetDataStart(), m_reg_info.GetRegisterDataByteSize());
-
- data_sp = reg_ctx;
- return true;
- }
- }
- }
- else
- {
+ if (use_g_packet &&
+ (data_sp = gdb_comm.ReadAllRegisters(m_thread.GetProtocolID())))
+ return true;
- Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS));
- if (log)
- {
- if (log->GetVerbose())
- {
- StreamString strm;
- gdb_comm.DumpHistory(strm);
- log->Printf("error: failed to get packet sequence mutex, not sending read all registers:\n%s", strm.GetData());
- }
- else
- log->Printf("error: failed to get packet sequence mutex, not sending read all registers");
- }
+ // We're going to read each register
+ // individually and store them as binary data in a buffer.
+ const RegisterInfo *reg_info;
+
+ for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex(i)) != NULL; i++) {
+ if (reg_info
+ ->value_regs) // skip registers that are slices of real registers
+ continue;
+ ReadRegisterBytes(reg_info, m_reg_data);
+ // ReadRegisterBytes saves the contents of the register in to the
+ // m_reg_data buffer
}
+ data_sp.reset(new DataBufferHeap(m_reg_data.GetDataStart(),
+ m_reg_info.GetRegisterDataByteSize()));
+ return true;
+ } else {
+
+ Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_THREAD |
+ GDBR_LOG_PACKETS));
+ if (log) {
+ if (log->GetVerbose()) {
+ StreamString strm;
+ gdb_comm.DumpHistory(strm);
+ log->Printf("error: failed to get packet sequence mutex, not sending "
+ "read all registers:\n%s",
+ strm.GetData());
+ } else
+ log->Printf("error: failed to get packet sequence mutex, not sending "
+ "read all registers");
+ }
+ }
- data_sp.reset();
- return false;
+ data_sp.reset();
+ return false;
}
-bool
-GDBRemoteRegisterContext::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
-{
- if (!data_sp || data_sp->GetBytes() == NULL || data_sp->GetByteSize() == 0)
- return false;
+bool GDBRemoteRegisterContext::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ if (!data_sp || data_sp->GetBytes() == NULL || data_sp->GetByteSize() == 0)
+ return false;
- ExecutionContext exe_ctx (CalculateThread());
+ ExecutionContext exe_ctx(CalculateThread());
- Process *process = exe_ctx.GetProcessPtr();
- Thread *thread = exe_ctx.GetThreadPtr();
- if (process == NULL || thread == NULL)
- return false;
+ Process *process = exe_ctx.GetProcessPtr();
+ Thread *thread = exe_ctx.GetThreadPtr();
+ if (process == NULL || thread == NULL)
+ return false;
- GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote());
+ GDBRemoteCommunicationClient &gdb_comm(
+ ((ProcessGDBRemote *)process)->GetGDBRemote());
- const bool use_g_packet = gdb_comm.AvoidGPackets ((ProcessGDBRemote *)process) == false;
+ const bool use_g_packet =
+ gdb_comm.AvoidGPackets((ProcessGDBRemote *)process) == false;
- StringExtractorGDBRemote response;
- Mutex::Locker locker;
- if (gdb_comm.GetSequenceMutex (locker, "Didn't get sequence mutex for write all registers."))
- {
- const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported();
- ProcessSP process_sp (m_thread.GetProcess());
- if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetProtocolID()))
- {
- // The data_sp contains the entire G response packet including the
- // G, and if the thread suffix is supported, it has the thread suffix
- // as well.
- const char *G_packet = (const char *)data_sp->GetBytes();
- size_t G_packet_len = data_sp->GetByteSize();
- if (use_g_packet
- && gdb_comm.SendPacketAndWaitForResponse (G_packet,
- G_packet_len,
- response,
- false) == GDBRemoteCommunication::PacketResult::Success)
- {
- // The data_sp contains the entire G response packet including the
- // G, and if the thread suffix is supported, it has the thread suffix
- // as well.
- const char *G_packet = (const char *)data_sp->GetBytes();
- size_t G_packet_len = data_sp->GetByteSize();
- if (gdb_comm.SendPacketAndWaitForResponse (G_packet,
- G_packet_len,
- response,
- false) == GDBRemoteCommunication::PacketResult::Success)
- {
- if (response.IsOKResponse())
- return true;
- else if (response.IsErrorResponse())
- {
- uint32_t num_restored = 0;
- // We need to manually go through all of the registers and
- // restore them manually
-
- response.GetStringRef().assign (G_packet, G_packet_len);
- response.SetFilePos(1); // Skip the leading 'G'
-
- // G_packet_len is hex-ascii characters plus prefix 'G' plus suffix thread specifier.
- // This means buffer will be a little more than 2x larger than necessary but we resize
- // it down once we've extracted all hex ascii chars from the packet.
- DataBufferHeap buffer (G_packet_len, 0);
-
- const uint32_t bytes_extracted = response.GetHexBytes (buffer.GetBytes(),
- buffer.GetByteSize(),
- '\xcc');
-
- DataExtractor restore_data (buffer.GetBytes(),
- buffer.GetByteSize(),
- m_reg_data.GetByteOrder(),
- m_reg_data.GetAddressByteSize());
-
- if (bytes_extracted < restore_data.GetByteSize())
- restore_data.SetData(restore_data.GetDataStart(), bytes_extracted, m_reg_data.GetByteOrder());
-
- const RegisterInfo *reg_info;
-
- // The g packet contents may either include the slice registers (registers defined in
- // terms of other registers, e.g. eax is a subset of rax) or not. The slice registers
- // should NOT be in the g packet, but some implementations may incorrectly include them.
- //
- // If the slice registers are included in the packet, we must step over the slice registers
- // when parsing the packet -- relying on the RegisterInfo byte_offset field would be incorrect.
- // If the slice registers are not included, then using the byte_offset values into the
- // data buffer is the best way to find individual register values.
-
- uint64_t size_including_slice_registers = 0;
- uint64_t size_not_including_slice_registers = 0;
- uint64_t size_by_highest_offset = 0;
-
- for (uint32_t reg_idx=0; (reg_info = GetRegisterInfoAtIndex (reg_idx)) != NULL; ++reg_idx)
- {
- size_including_slice_registers += reg_info->byte_size;
- if (reg_info->value_regs == NULL)
- size_not_including_slice_registers += reg_info->byte_size;
- if (reg_info->byte_offset >= size_by_highest_offset)
- size_by_highest_offset = reg_info->byte_offset + reg_info->byte_size;
- }
-
- bool use_byte_offset_into_buffer;
- if (size_by_highest_offset == restore_data.GetByteSize())
- {
- // The size of the packet agrees with the highest offset: + size in the register file
- use_byte_offset_into_buffer = true;
- }
- else if (size_not_including_slice_registers == restore_data.GetByteSize())
- {
- // The size of the packet is the same as concatenating all of the registers sequentially,
- // skipping the slice registers
- use_byte_offset_into_buffer = true;
- }
- else if (size_including_slice_registers == restore_data.GetByteSize())
- {
- // The slice registers are present in the packet (when they shouldn't be).
- // Don't try to use the RegisterInfo byte_offset into the restore_data, it will
- // point to the wrong place.
- use_byte_offset_into_buffer = false;
- }
- else {
- // None of our expected sizes match the actual g packet data we're looking at.
- // The most conservative approach here is to use the running total byte offset.
- use_byte_offset_into_buffer = false;
- }
-
- // In case our register definitions don't include the correct offsets,
- // keep track of the size of each reg & compute offset based on that.
- uint32_t running_byte_offset = 0;
- for (uint32_t reg_idx=0; (reg_info = GetRegisterInfoAtIndex (reg_idx)) != NULL; ++reg_idx, running_byte_offset += reg_info->byte_size)
- {
- // Skip composite aka slice registers (e.g. eax is a slice of rax).
- if (reg_info->value_regs)
- continue;
-
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
-
- uint32_t register_offset;
- if (use_byte_offset_into_buffer)
- {
- register_offset = reg_info->byte_offset;
- }
- else
- {
- register_offset = running_byte_offset;
- }
-
- // Only write down the registers that need to be written
- // if we are going to be doing registers individually.
- bool write_reg = true;
- const uint32_t reg_byte_size = reg_info->byte_size;
-
- const char *restore_src = (const char *)restore_data.PeekData(register_offset, reg_byte_size);
- if (restore_src)
- {
- StreamString packet;
- packet.Printf ("P%x=", reg_info->kinds[eRegisterKindProcessPlugin]);
- packet.PutBytesAsRawHex8 (restore_src,
- reg_byte_size,
- endian::InlHostByteOrder(),
- endian::InlHostByteOrder());
-
- if (thread_suffix_supported)
- packet.Printf (";thread:%4.4" PRIx64 ";", m_thread.GetProtocolID());
-
- SetRegisterIsValid(reg, false);
- if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(),
- packet.GetString().size(),
- response,
- false) == GDBRemoteCommunication::PacketResult::Success)
- {
- const char *current_src = (const char *)m_reg_data.PeekData(register_offset, reg_byte_size);
- if (current_src)
- write_reg = memcmp (current_src, restore_src, reg_byte_size) != 0;
- }
-
- if (write_reg)
- {
- StreamString packet;
- packet.Printf ("P%x=", reg_info->kinds[eRegisterKindProcessPlugin]);
- packet.PutBytesAsRawHex8 (restore_src,
- reg_byte_size,
- endian::InlHostByteOrder(),
- endian::InlHostByteOrder());
-
- if (thread_suffix_supported)
- packet.Printf (";thread:%4.4" PRIx64 ";", m_thread.GetProtocolID());
-
- SetRegisterIsValid(reg, false);
- if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(),
- packet.GetString().size(),
- response,
- false) == GDBRemoteCommunication::PacketResult::Success)
- {
- if (response.IsOKResponse())
- ++num_restored;
- }
- }
- }
- }
- return num_restored > 0;
- }
- }
- }
- else
- {
- // For the use_g_packet == false case, we're going to write each register
- // individually. The data buffer is binary data in this case, instead of
- // ascii characters.
-
- bool arm64_debugserver = false;
- if (m_thread.GetProcess().get())
- {
- const ArchSpec &arch = m_thread.GetProcess()->GetTarget().GetArchitecture();
- if (arch.IsValid()
- && arch.GetMachine() == llvm::Triple::aarch64
- && arch.GetTriple().getVendor() == llvm::Triple::Apple
- && arch.GetTriple().getOS() == llvm::Triple::IOS)
- {
- arm64_debugserver = true;
- }
- }
- uint32_t num_restored = 0;
- const RegisterInfo *reg_info;
- for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex (i)) != NULL; i++)
- {
- if (reg_info->value_regs) // skip registers that are slices of real registers
- continue;
- // Skip the fpsr and fpcr floating point status/control register writing to
- // work around a bug in an older version of debugserver that would lead to
- // register context corruption when writing fpsr/fpcr.
- if (arm64_debugserver &&
- (strcmp (reg_info->name, "fpsr") == 0 || strcmp (reg_info->name, "fpcr") == 0))
- {
- continue;
- }
- StreamString packet;
- packet.Printf ("P%x=", reg_info->kinds[eRegisterKindProcessPlugin]);
- packet.PutBytesAsRawHex8 (data_sp->GetBytes() + reg_info->byte_offset, reg_info->byte_size, endian::InlHostByteOrder(), endian::InlHostByteOrder());
- if (thread_suffix_supported)
- packet.Printf (";thread:%4.4" PRIx64 ";", m_thread.GetProtocolID());
-
- SetRegisterIsValid(reg_info, false);
- if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(),
- packet.GetString().size(),
- response,
- false) == GDBRemoteCommunication::PacketResult::Success)
- {
- if (response.IsOKResponse())
- ++num_restored;
- }
- }
- return num_restored > 0;
- }
+ GDBRemoteClientBase::Lock lock(gdb_comm, false);
+ if (lock) {
+ // The data_sp contains the G response packet.
+ if (use_g_packet) {
+ if (gdb_comm.WriteAllRegisters(
+ m_thread.GetProtocolID(),
+ {data_sp->GetBytes(), size_t(data_sp->GetByteSize())}))
+ return true;
+
+ uint32_t num_restored = 0;
+ // We need to manually go through all of the registers and
+ // restore them manually
+ DataExtractor restore_data(data_sp, m_reg_data.GetByteOrder(),
+ m_reg_data.GetAddressByteSize());
+
+ const RegisterInfo *reg_info;
+
+ // The g packet contents may either include the slice registers (registers
+ // defined in
+ // terms of other registers, e.g. eax is a subset of rax) or not. The
+ // slice registers
+ // should NOT be in the g packet, but some implementations may incorrectly
+ // include them.
+ //
+ // If the slice registers are included in the packet, we must step over
+ // the slice registers
+ // when parsing the packet -- relying on the RegisterInfo byte_offset
+ // field would be incorrect.
+ // If the slice registers are not included, then using the byte_offset
+ // values into the
+ // data buffer is the best way to find individual register values.
+
+ uint64_t size_including_slice_registers = 0;
+ uint64_t size_not_including_slice_registers = 0;
+ uint64_t size_by_highest_offset = 0;
+
+ for (uint32_t reg_idx = 0;
+ (reg_info = GetRegisterInfoAtIndex(reg_idx)) != NULL; ++reg_idx) {
+ size_including_slice_registers += reg_info->byte_size;
+ if (reg_info->value_regs == NULL)
+ size_not_including_slice_registers += reg_info->byte_size;
+ if (reg_info->byte_offset >= size_by_highest_offset)
+ size_by_highest_offset = reg_info->byte_offset + reg_info->byte_size;
+ }
+
+ bool use_byte_offset_into_buffer;
+ if (size_by_highest_offset == restore_data.GetByteSize()) {
+ // The size of the packet agrees with the highest offset: + size in the
+ // register file
+ use_byte_offset_into_buffer = true;
+ } else if (size_not_including_slice_registers ==
+ restore_data.GetByteSize()) {
+ // The size of the packet is the same as concatenating all of the
+ // registers sequentially,
+ // skipping the slice registers
+ use_byte_offset_into_buffer = true;
+ } else if (size_including_slice_registers == restore_data.GetByteSize()) {
+ // The slice registers are present in the packet (when they shouldn't
+ // be).
+ // Don't try to use the RegisterInfo byte_offset into the restore_data,
+ // it will
+ // point to the wrong place.
+ use_byte_offset_into_buffer = false;
+ } else {
+ // None of our expected sizes match the actual g packet data we're
+ // looking at.
+ // The most conservative approach here is to use the running total byte
+ // offset.
+ use_byte_offset_into_buffer = false;
+ }
+
+ // In case our register definitions don't include the correct offsets,
+ // keep track of the size of each reg & compute offset based on that.
+ uint32_t running_byte_offset = 0;
+ for (uint32_t reg_idx = 0;
+ (reg_info = GetRegisterInfoAtIndex(reg_idx)) != NULL;
+ ++reg_idx, running_byte_offset += reg_info->byte_size) {
+ // Skip composite aka slice registers (e.g. eax is a slice of rax).
+ if (reg_info->value_regs)
+ continue;
+
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+
+ uint32_t register_offset;
+ if (use_byte_offset_into_buffer) {
+ register_offset = reg_info->byte_offset;
+ } else {
+ register_offset = running_byte_offset;
}
- }
- else
- {
- Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS));
- if (log)
- {
- if (log->GetVerbose())
- {
- StreamString strm;
- gdb_comm.DumpHistory(strm);
- log->Printf("error: failed to get packet sequence mutex, not sending write all registers:\n%s", strm.GetData());
- }
- else
- log->Printf("error: failed to get packet sequence mutex, not sending write all registers");
+
+ const uint32_t reg_byte_size = reg_info->byte_size;
+
+ const uint8_t *restore_src =
+ restore_data.PeekData(register_offset, reg_byte_size);
+ if (restore_src) {
+ SetRegisterIsValid(reg, false);
+ if (gdb_comm.WriteRegister(
+ m_thread.GetProtocolID(),
+ reg_info->kinds[eRegisterKindProcessPlugin],
+ {restore_src, reg_byte_size}))
+ ++num_restored;
+ }
+ }
+ return num_restored > 0;
+ } else {
+ // For the use_g_packet == false case, we're going to write each register
+ // individually. The data buffer is binary data in this case, instead of
+ // ascii characters.
+
+ bool arm64_debugserver = false;
+ if (m_thread.GetProcess().get()) {
+ const ArchSpec &arch =
+ m_thread.GetProcess()->GetTarget().GetArchitecture();
+ if (arch.IsValid() && arch.GetMachine() == llvm::Triple::aarch64 &&
+ arch.GetTriple().getVendor() == llvm::Triple::Apple &&
+ arch.GetTriple().getOS() == llvm::Triple::IOS) {
+ arm64_debugserver = true;
}
+ }
+ uint32_t num_restored = 0;
+ const RegisterInfo *reg_info;
+ for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex(i)) != NULL;
+ i++) {
+ if (reg_info->value_regs) // skip registers that are slices of real
+ // registers
+ continue;
+ // Skip the fpsr and fpcr floating point status/control register writing
+ // to
+ // work around a bug in an older version of debugserver that would lead
+ // to
+ // register context corruption when writing fpsr/fpcr.
+ if (arm64_debugserver && (strcmp(reg_info->name, "fpsr") == 0 ||
+ strcmp(reg_info->name, "fpcr") == 0)) {
+ continue;
+ }
+
+ SetRegisterIsValid(reg_info, false);
+ if (gdb_comm.WriteRegister(m_thread.GetProtocolID(),
+ reg_info->kinds[eRegisterKindProcessPlugin],
+ {data_sp->GetBytes() + reg_info->byte_offset,
+ reg_info->byte_size}))
+ ++num_restored;
+ }
+ return num_restored > 0;
}
- return false;
+ } else {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_THREAD |
+ GDBR_LOG_PACKETS));
+ if (log) {
+ if (log->GetVerbose()) {
+ StreamString strm;
+ gdb_comm.DumpHistory(strm);
+ log->Printf("error: failed to get packet sequence mutex, not sending "
+ "write all registers:\n%s",
+ strm.GetData());
+ } else
+ log->Printf("error: failed to get packet sequence mutex, not sending "
+ "write all registers");
+ }
+ }
+ return false;
}
-
-uint32_t
-GDBRemoteRegisterContext::ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t num)
-{
- return m_reg_info.ConvertRegisterKindToRegisterNumber (kind, num);
+uint32_t GDBRemoteRegisterContext::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t num) {
+ return m_reg_info.ConvertRegisterKindToRegisterNumber(kind, num);
}
-
-void
-GDBRemoteDynamicRegisterInfo::HardcodeARMRegisters(bool from_scratch)
-{
- // For Advanced SIMD and VFP register mapping.
- static uint32_t g_d0_regs[] = { 26, 27, LLDB_INVALID_REGNUM }; // (s0, s1)
- static uint32_t g_d1_regs[] = { 28, 29, LLDB_INVALID_REGNUM }; // (s2, s3)
- static uint32_t g_d2_regs[] = { 30, 31, LLDB_INVALID_REGNUM }; // (s4, s5)
- static uint32_t g_d3_regs[] = { 32, 33, LLDB_INVALID_REGNUM }; // (s6, s7)
- static uint32_t g_d4_regs[] = { 34, 35, LLDB_INVALID_REGNUM }; // (s8, s9)
- static uint32_t g_d5_regs[] = { 36, 37, LLDB_INVALID_REGNUM }; // (s10, s11)
- static uint32_t g_d6_regs[] = { 38, 39, LLDB_INVALID_REGNUM }; // (s12, s13)
- static uint32_t g_d7_regs[] = { 40, 41, LLDB_INVALID_REGNUM }; // (s14, s15)
- static uint32_t g_d8_regs[] = { 42, 43, LLDB_INVALID_REGNUM }; // (s16, s17)
- static uint32_t g_d9_regs[] = { 44, 45, LLDB_INVALID_REGNUM }; // (s18, s19)
- static uint32_t g_d10_regs[] = { 46, 47, LLDB_INVALID_REGNUM }; // (s20, s21)
- static uint32_t g_d11_regs[] = { 48, 49, LLDB_INVALID_REGNUM }; // (s22, s23)
- static uint32_t g_d12_regs[] = { 50, 51, LLDB_INVALID_REGNUM }; // (s24, s25)
- static uint32_t g_d13_regs[] = { 52, 53, LLDB_INVALID_REGNUM }; // (s26, s27)
- static uint32_t g_d14_regs[] = { 54, 55, LLDB_INVALID_REGNUM }; // (s28, s29)
- static uint32_t g_d15_regs[] = { 56, 57, LLDB_INVALID_REGNUM }; // (s30, s31)
- static uint32_t g_q0_regs[] = { 26, 27, 28, 29, LLDB_INVALID_REGNUM }; // (d0, d1) -> (s0, s1, s2, s3)
- static uint32_t g_q1_regs[] = { 30, 31, 32, 33, LLDB_INVALID_REGNUM }; // (d2, d3) -> (s4, s5, s6, s7)
- static uint32_t g_q2_regs[] = { 34, 35, 36, 37, LLDB_INVALID_REGNUM }; // (d4, d5) -> (s8, s9, s10, s11)
- static uint32_t g_q3_regs[] = { 38, 39, 40, 41, LLDB_INVALID_REGNUM }; // (d6, d7) -> (s12, s13, s14, s15)
- static uint32_t g_q4_regs[] = { 42, 43, 44, 45, LLDB_INVALID_REGNUM }; // (d8, d9) -> (s16, s17, s18, s19)
- static uint32_t g_q5_regs[] = { 46, 47, 48, 49, LLDB_INVALID_REGNUM }; // (d10, d11) -> (s20, s21, s22, s23)
- static uint32_t g_q6_regs[] = { 50, 51, 52, 53, LLDB_INVALID_REGNUM }; // (d12, d13) -> (s24, s25, s26, s27)
- static uint32_t g_q7_regs[] = { 54, 55, 56, 57, LLDB_INVALID_REGNUM }; // (d14, d15) -> (s28, s29, s30, s31)
- static uint32_t g_q8_regs[] = { 59, 60, LLDB_INVALID_REGNUM }; // (d16, d17)
- static uint32_t g_q9_regs[] = { 61, 62, LLDB_INVALID_REGNUM }; // (d18, d19)
- static uint32_t g_q10_regs[] = { 63, 64, LLDB_INVALID_REGNUM }; // (d20, d21)
- static uint32_t g_q11_regs[] = { 65, 66, LLDB_INVALID_REGNUM }; // (d22, d23)
- static uint32_t g_q12_regs[] = { 67, 68, LLDB_INVALID_REGNUM }; // (d24, d25)
- static uint32_t g_q13_regs[] = { 69, 70, LLDB_INVALID_REGNUM }; // (d26, d27)
- static uint32_t g_q14_regs[] = { 71, 72, LLDB_INVALID_REGNUM }; // (d28, d29)
- static uint32_t g_q15_regs[] = { 73, 74, LLDB_INVALID_REGNUM }; // (d30, d31)
-
- // This is our array of composite registers, with each element coming from the above register mappings.
- static uint32_t *g_composites[] = {
- g_d0_regs, g_d1_regs, g_d2_regs, g_d3_regs, g_d4_regs, g_d5_regs, g_d6_regs, g_d7_regs,
- g_d8_regs, g_d9_regs, g_d10_regs, g_d11_regs, g_d12_regs, g_d13_regs, g_d14_regs, g_d15_regs,
- g_q0_regs, g_q1_regs, g_q2_regs, g_q3_regs, g_q4_regs, g_q5_regs, g_q6_regs, g_q7_regs,
- g_q8_regs, g_q9_regs, g_q10_regs, g_q11_regs, g_q12_regs, g_q13_regs, g_q14_regs, g_q15_regs
- };
-
+void GDBRemoteDynamicRegisterInfo::HardcodeARMRegisters(bool from_scratch) {
+ // For Advanced SIMD and VFP register mapping.
+ static uint32_t g_d0_regs[] = {26, 27, LLDB_INVALID_REGNUM}; // (s0, s1)
+ static uint32_t g_d1_regs[] = {28, 29, LLDB_INVALID_REGNUM}; // (s2, s3)
+ static uint32_t g_d2_regs[] = {30, 31, LLDB_INVALID_REGNUM}; // (s4, s5)
+ static uint32_t g_d3_regs[] = {32, 33, LLDB_INVALID_REGNUM}; // (s6, s7)
+ static uint32_t g_d4_regs[] = {34, 35, LLDB_INVALID_REGNUM}; // (s8, s9)
+ static uint32_t g_d5_regs[] = {36, 37, LLDB_INVALID_REGNUM}; // (s10, s11)
+ static uint32_t g_d6_regs[] = {38, 39, LLDB_INVALID_REGNUM}; // (s12, s13)
+ static uint32_t g_d7_regs[] = {40, 41, LLDB_INVALID_REGNUM}; // (s14, s15)
+ static uint32_t g_d8_regs[] = {42, 43, LLDB_INVALID_REGNUM}; // (s16, s17)
+ static uint32_t g_d9_regs[] = {44, 45, LLDB_INVALID_REGNUM}; // (s18, s19)
+ static uint32_t g_d10_regs[] = {46, 47, LLDB_INVALID_REGNUM}; // (s20, s21)
+ static uint32_t g_d11_regs[] = {48, 49, LLDB_INVALID_REGNUM}; // (s22, s23)
+ static uint32_t g_d12_regs[] = {50, 51, LLDB_INVALID_REGNUM}; // (s24, s25)
+ static uint32_t g_d13_regs[] = {52, 53, LLDB_INVALID_REGNUM}; // (s26, s27)
+ static uint32_t g_d14_regs[] = {54, 55, LLDB_INVALID_REGNUM}; // (s28, s29)
+ static uint32_t g_d15_regs[] = {56, 57, LLDB_INVALID_REGNUM}; // (s30, s31)
+ static uint32_t g_q0_regs[] = {
+ 26, 27, 28, 29, LLDB_INVALID_REGNUM}; // (d0, d1) -> (s0, s1, s2, s3)
+ static uint32_t g_q1_regs[] = {
+ 30, 31, 32, 33, LLDB_INVALID_REGNUM}; // (d2, d3) -> (s4, s5, s6, s7)
+ static uint32_t g_q2_regs[] = {
+ 34, 35, 36, 37, LLDB_INVALID_REGNUM}; // (d4, d5) -> (s8, s9, s10, s11)
+ static uint32_t g_q3_regs[] = {
+ 38, 39, 40, 41, LLDB_INVALID_REGNUM}; // (d6, d7) -> (s12, s13, s14, s15)
+ static uint32_t g_q4_regs[] = {
+ 42, 43, 44, 45, LLDB_INVALID_REGNUM}; // (d8, d9) -> (s16, s17, s18, s19)
+ static uint32_t g_q5_regs[] = {
+ 46, 47, 48, 49,
+ LLDB_INVALID_REGNUM}; // (d10, d11) -> (s20, s21, s22, s23)
+ static uint32_t g_q6_regs[] = {
+ 50, 51, 52, 53,
+ LLDB_INVALID_REGNUM}; // (d12, d13) -> (s24, s25, s26, s27)
+ static uint32_t g_q7_regs[] = {
+ 54, 55, 56, 57,
+ LLDB_INVALID_REGNUM}; // (d14, d15) -> (s28, s29, s30, s31)
+ static uint32_t g_q8_regs[] = {59, 60, LLDB_INVALID_REGNUM}; // (d16, d17)
+ static uint32_t g_q9_regs[] = {61, 62, LLDB_INVALID_REGNUM}; // (d18, d19)
+ static uint32_t g_q10_regs[] = {63, 64, LLDB_INVALID_REGNUM}; // (d20, d21)
+ static uint32_t g_q11_regs[] = {65, 66, LLDB_INVALID_REGNUM}; // (d22, d23)
+ static uint32_t g_q12_regs[] = {67, 68, LLDB_INVALID_REGNUM}; // (d24, d25)
+ static uint32_t g_q13_regs[] = {69, 70, LLDB_INVALID_REGNUM}; // (d26, d27)
+ static uint32_t g_q14_regs[] = {71, 72, LLDB_INVALID_REGNUM}; // (d28, d29)
+ static uint32_t g_q15_regs[] = {73, 74, LLDB_INVALID_REGNUM}; // (d30, d31)
+
+ // This is our array of composite registers, with each element coming from the
+ // above register mappings.
+ static uint32_t *g_composites[] = {
+ g_d0_regs, g_d1_regs, g_d2_regs, g_d3_regs, g_d4_regs, g_d5_regs,
+ g_d6_regs, g_d7_regs, g_d8_regs, g_d9_regs, g_d10_regs, g_d11_regs,
+ g_d12_regs, g_d13_regs, g_d14_regs, g_d15_regs, g_q0_regs, g_q1_regs,
+ g_q2_regs, g_q3_regs, g_q4_regs, g_q5_regs, g_q6_regs, g_q7_regs,
+ g_q8_regs, g_q9_regs, g_q10_regs, g_q11_regs, g_q12_regs, g_q13_regs,
+ g_q14_regs, g_q15_regs};
+
+ // clang-format off
static RegisterInfo g_register_infos[] = {
-// NAME ALT SZ OFF ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB VALUE REGS INVALIDATE REGS
-// ====== ====== === === ============= ============ =================== =================== ====================== ============= ==== ========== ===============
- { "r0", "arg1", 4, 0, eEncodingUint, eFormatHex, { ehframe_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1,0, 0 }, NULL, NULL},
- { "r1", "arg2", 4, 0, eEncodingUint, eFormatHex, { ehframe_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2,1, 1 }, NULL, NULL},
- { "r2", "arg3", 4, 0, eEncodingUint, eFormatHex, { ehframe_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3,2, 2 }, NULL, NULL},
- { "r3", "arg4", 4, 0, eEncodingUint, eFormatHex, { ehframe_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4,3, 3 }, NULL, NULL},
- { "r4", NULL, 4, 0, eEncodingUint, eFormatHex, { ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, 4, 4 }, NULL, NULL},
- { "r5", NULL, 4, 0, eEncodingUint, eFormatHex, { ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, 5, 5 }, NULL, NULL},
- { "r6", NULL, 4, 0, eEncodingUint, eFormatHex, { ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, 6, 6 }, NULL, NULL},
- { "r7", "fp", 4, 0, eEncodingUint, eFormatHex, { ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, 7, 7 }, NULL, NULL},
- { "r8", NULL, 4, 0, eEncodingUint, eFormatHex, { ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, 8, 8 }, NULL, NULL},
- { "r9", NULL, 4, 0, eEncodingUint, eFormatHex, { ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, 9, 9 }, NULL, NULL},
- { "r10", NULL, 4, 0, eEncodingUint, eFormatHex, { ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, 10, 10 }, NULL, NULL},
- { "r11", NULL, 4, 0, eEncodingUint, eFormatHex, { ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, 11, 11 }, NULL, NULL},
- { "r12", NULL, 4, 0, eEncodingUint, eFormatHex, { ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, 12, 12 }, NULL, NULL},
- { "sp", "r13", 4, 0, eEncodingUint, eFormatHex, { ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, 13, 13 }, NULL, NULL},
- { "lr", "r14", 4, 0, eEncodingUint, eFormatHex, { ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, 14, 14 }, NULL, NULL},
- { "pc", "r15", 4, 0, eEncodingUint, eFormatHex, { ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, 15, 15 }, NULL, NULL},
- { "f0", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 16, 16 }, NULL, NULL},
- { "f1", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 17, 17 }, NULL, NULL},
- { "f2", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 18, 18 }, NULL, NULL},
- { "f3", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 19, 19 }, NULL, NULL},
- { "f4", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 20, 20 }, NULL, NULL},
- { "f5", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 21, 21 }, NULL, NULL},
- { "f6", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 22, 22 }, NULL, NULL},
- { "f7", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 23, 23 }, NULL, NULL},
- { "fps", NULL, 4, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 24, 24 }, NULL, NULL},
- { "cpsr","flags", 4, 0, eEncodingUint, eFormatHex, { ehframe_cpsr, dwarf_cpsr, LLDB_INVALID_REGNUM, 25, 25 }, NULL, NULL},
- { "s0", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, 26, 26 }, NULL, NULL},
- { "s1", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, 27, 27 }, NULL, NULL},
- { "s2", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, 28, 28 }, NULL, NULL},
- { "s3", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, 29, 29 }, NULL, NULL},
- { "s4", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, 30, 30 }, NULL, NULL},
- { "s5", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, 31, 31 }, NULL, NULL},
- { "s6", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, 32, 32 }, NULL, NULL},
- { "s7", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, 33, 33 }, NULL, NULL},
- { "s8", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, 34, 34 }, NULL, NULL},
- { "s9", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, 35, 35 }, NULL, NULL},
- { "s10", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, 36, 36 }, NULL, NULL},
- { "s11", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, 37, 37 }, NULL, NULL},
- { "s12", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, 38, 38 }, NULL, NULL},
- { "s13", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, 39, 39 }, NULL, NULL},
- { "s14", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, 40, 40 }, NULL, NULL},
- { "s15", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, 41, 41 }, NULL, NULL},
- { "s16", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, 42, 42 }, NULL, NULL},
- { "s17", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, 43, 43 }, NULL, NULL},
- { "s18", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, 44, 44 }, NULL, NULL},
- { "s19", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, 45, 45 }, NULL, NULL},
- { "s20", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, 46, 46 }, NULL, NULL},
- { "s21", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, 47, 47 }, NULL, NULL},
- { "s22", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, 48, 48 }, NULL, NULL},
- { "s23", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, 49, 49 }, NULL, NULL},
- { "s24", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, 50, 50 }, NULL, NULL},
- { "s25", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, 51, 51 }, NULL, NULL},
- { "s26", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, 52, 52 }, NULL, NULL},
- { "s27", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, 53, 53 }, NULL, NULL},
- { "s28", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, 54, 54 }, NULL, NULL},
- { "s29", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, 55, 55 }, NULL, NULL},
- { "s30", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, 56, 56 }, NULL, NULL},
- { "s31", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, 57, 57 }, NULL, NULL},
- { "fpscr",NULL, 4, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 58, 58 }, NULL, NULL},
- { "d16", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, 59, 59 }, NULL, NULL},
- { "d17", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, 60, 60 }, NULL, NULL},
- { "d18", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, 61, 61 }, NULL, NULL},
- { "d19", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, 62, 62 }, NULL, NULL},
- { "d20", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, 63, 63 }, NULL, NULL},
- { "d21", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, 64, 64 }, NULL, NULL},
- { "d22", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, 65, 65 }, NULL, NULL},
- { "d23", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, 66, 66 }, NULL, NULL},
- { "d24", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, 67, 67 }, NULL, NULL},
- { "d25", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, 68, 68 }, NULL, NULL},
- { "d26", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, 69, 69 }, NULL, NULL},
- { "d27", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, 70, 70 }, NULL, NULL},
- { "d28", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, 71, 71 }, NULL, NULL},
- { "d29", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, 72, 72 }, NULL, NULL},
- { "d30", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, 73, 73 }, NULL, NULL},
- { "d31", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, 74, 74 }, NULL, NULL},
- { "d0", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d0, LLDB_INVALID_REGNUM, 75, 75 }, g_d0_regs, NULL},
- { "d1", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d1, LLDB_INVALID_REGNUM, 76, 76 }, g_d1_regs, NULL},
- { "d2", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d2, LLDB_INVALID_REGNUM, 77, 77 }, g_d2_regs, NULL},
- { "d3", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d3, LLDB_INVALID_REGNUM, 78, 78 }, g_d3_regs, NULL},
- { "d4", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d4, LLDB_INVALID_REGNUM, 79, 79 }, g_d4_regs, NULL},
- { "d5", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d5, LLDB_INVALID_REGNUM, 80, 80 }, g_d5_regs, NULL},
- { "d6", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d6, LLDB_INVALID_REGNUM, 81, 81 }, g_d6_regs, NULL},
- { "d7", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d7, LLDB_INVALID_REGNUM, 82, 82 }, g_d7_regs, NULL},
- { "d8", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d8, LLDB_INVALID_REGNUM, 83, 83 }, g_d8_regs, NULL},
- { "d9", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d9, LLDB_INVALID_REGNUM, 84, 84 }, g_d9_regs, NULL},
- { "d10", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d10, LLDB_INVALID_REGNUM, 85, 85 }, g_d10_regs, NULL},
- { "d11", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d11, LLDB_INVALID_REGNUM, 86, 86 }, g_d11_regs, NULL},
- { "d12", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d12, LLDB_INVALID_REGNUM, 87, 87 }, g_d12_regs, NULL},
- { "d13", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d13, LLDB_INVALID_REGNUM, 88, 88 }, g_d13_regs, NULL},
- { "d14", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d14, LLDB_INVALID_REGNUM, 89, 89 }, g_d14_regs, NULL},
- { "d15", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d15, LLDB_INVALID_REGNUM, 90, 90 }, g_d15_regs, NULL},
- { "q0", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q0, LLDB_INVALID_REGNUM, 91, 91 }, g_q0_regs, NULL},
- { "q1", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q1, LLDB_INVALID_REGNUM, 92, 92 }, g_q1_regs, NULL},
- { "q2", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q2, LLDB_INVALID_REGNUM, 93, 93 }, g_q2_regs, NULL},
- { "q3", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q3, LLDB_INVALID_REGNUM, 94, 94 }, g_q3_regs, NULL},
- { "q4", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q4, LLDB_INVALID_REGNUM, 95, 95 }, g_q4_regs, NULL},
- { "q5", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q5, LLDB_INVALID_REGNUM, 96, 96 }, g_q5_regs, NULL},
- { "q6", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q6, LLDB_INVALID_REGNUM, 97, 97 }, g_q6_regs, NULL},
- { "q7", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q7, LLDB_INVALID_REGNUM, 98, 98 }, g_q7_regs, NULL},
- { "q8", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q8, LLDB_INVALID_REGNUM, 99, 99 }, g_q8_regs, NULL},
- { "q9", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q9, LLDB_INVALID_REGNUM, 100, 100 }, g_q9_regs, NULL},
- { "q10", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q10, LLDB_INVALID_REGNUM, 101, 101 }, g_q10_regs, NULL},
- { "q11", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q11, LLDB_INVALID_REGNUM, 102, 102 }, g_q11_regs, NULL},
- { "q12", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q12, LLDB_INVALID_REGNUM, 103, 103 }, g_q12_regs, NULL},
- { "q13", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q13, LLDB_INVALID_REGNUM, 104, 104 }, g_q13_regs, NULL},
- { "q14", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q14, LLDB_INVALID_REGNUM, 105, 105 }, g_q14_regs, NULL},
- { "q15", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q15, LLDB_INVALID_REGNUM, 106, 106 }, g_q15_regs, NULL}
+// NAME ALT SZ OFF ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB VALUE REGS INVALIDATE REGS SIZE EXPR SIZE LEN
+// ====== ====== === === ============= ========== =================== =================== ====================== ============= ==== ========== =============== ========= ========
+ { "r0", "arg1", 4, 0, eEncodingUint, eFormatHex, { ehframe_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1,0, 0 }, nullptr, nullptr, nullptr, 0 },
+ { "r1", "arg2", 4, 0, eEncodingUint, eFormatHex, { ehframe_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2,1, 1 }, nullptr, nullptr, nullptr, 0 },
+ { "r2", "arg3", 4, 0, eEncodingUint, eFormatHex, { ehframe_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3,2, 2 }, nullptr, nullptr, nullptr, 0 },
+ { "r3", "arg4", 4, 0, eEncodingUint, eFormatHex, { ehframe_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4,3, 3 }, nullptr, nullptr, nullptr, 0 },
+ { "r4", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, 4, 4 }, nullptr, nullptr, nullptr, 0 },
+ { "r5", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, 5, 5 }, nullptr, nullptr, nullptr, 0 },
+ { "r6", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, 6, 6 }, nullptr, nullptr, nullptr, 0 },
+ { "r7", "fp", 4, 0, eEncodingUint, eFormatHex, { ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, 7, 7 }, nullptr, nullptr, nullptr, 0 },
+ { "r8", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, 8, 8 }, nullptr, nullptr, nullptr, 0 },
+ { "r9", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, 9, 9 }, nullptr, nullptr, nullptr, 0 },
+ { "r10", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, 10, 10 }, nullptr, nullptr, nullptr, 0 },
+ { "r11", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, 11, 11 }, nullptr, nullptr, nullptr, 0 },
+ { "r12", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, 12, 12 }, nullptr, nullptr, nullptr, 0 },
+ { "sp", "r13", 4, 0, eEncodingUint, eFormatHex, { ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, 13, 13 }, nullptr, nullptr, nullptr, 0 },
+ { "lr", "r14", 4, 0, eEncodingUint, eFormatHex, { ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, 14, 14 }, nullptr, nullptr, nullptr, 0 },
+ { "pc", "r15", 4, 0, eEncodingUint, eFormatHex, { ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, 15, 15 }, nullptr, nullptr, nullptr, 0 },
+ { "f0", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 16, 16 }, nullptr, nullptr, nullptr, 0 },
+ { "f1", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 17, 17 }, nullptr, nullptr, nullptr, 0 },
+ { "f2", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 18, 18 }, nullptr, nullptr, nullptr, 0 },
+ { "f3", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 19, 19 }, nullptr, nullptr, nullptr, 0 },
+ { "f4", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 20, 20 }, nullptr, nullptr, nullptr, 0 },
+ { "f5", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 21, 21 }, nullptr, nullptr, nullptr, 0 },
+ { "f6", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 22, 22 }, nullptr, nullptr, nullptr, 0 },
+ { "f7", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 23, 23 }, nullptr, nullptr, nullptr, 0 },
+ { "fps", nullptr, 4, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 24, 24 }, nullptr, nullptr, nullptr, 0 },
+ { "cpsr","flags", 4, 0, eEncodingUint, eFormatHex, { ehframe_cpsr, dwarf_cpsr, LLDB_INVALID_REGNUM, 25, 25 }, nullptr, nullptr, nullptr, 0 },
+ { "s0", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, 26, 26 }, nullptr, nullptr, nullptr, 0 },
+ { "s1", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, 27, 27 }, nullptr, nullptr, nullptr, 0 },
+ { "s2", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, 28, 28 }, nullptr, nullptr, nullptr, 0 },
+ { "s3", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, 29, 29 }, nullptr, nullptr, nullptr, 0 },
+ { "s4", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, 30, 30 }, nullptr, nullptr, nullptr, 0 },
+ { "s5", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, 31, 31 }, nullptr, nullptr, nullptr, 0 },
+ { "s6", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, 32, 32 }, nullptr, nullptr, nullptr, 0 },
+ { "s7", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, 33, 33 }, nullptr, nullptr, nullptr, 0 },
+ { "s8", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, 34, 34 }, nullptr, nullptr, nullptr, 0 },
+ { "s9", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, 35, 35 }, nullptr, nullptr, nullptr, 0 },
+ { "s10", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, 36, 36 }, nullptr, nullptr, nullptr, 0 },
+ { "s11", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, 37, 37 }, nullptr, nullptr, nullptr, 0 },
+ { "s12", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, 38, 38 }, nullptr, nullptr, nullptr, 0 },
+ { "s13", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, 39, 39 }, nullptr, nullptr, nullptr, 0 },
+ { "s14", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, 40, 40 }, nullptr, nullptr, nullptr, 0 },
+ { "s15", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, 41, 41 }, nullptr, nullptr, nullptr, 0 },
+ { "s16", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, 42, 42 }, nullptr, nullptr, nullptr, 0 },
+ { "s17", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, 43, 43 }, nullptr, nullptr, nullptr, 0 },
+ { "s18", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, 44, 44 }, nullptr, nullptr, nullptr, 0 },
+ { "s19", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, 45, 45 }, nullptr, nullptr, nullptr, 0 },
+ { "s20", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, 46, 46 }, nullptr, nullptr, nullptr, 0 },
+ { "s21", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, 47, 47 }, nullptr, nullptr, nullptr, 0 },
+ { "s22", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, 48, 48 }, nullptr, nullptr, nullptr, 0 },
+ { "s23", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, 49, 49 }, nullptr, nullptr, nullptr, 0 },
+ { "s24", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, 50, 50 }, nullptr, nullptr, nullptr, 0 },
+ { "s25", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, 51, 51 }, nullptr, nullptr, nullptr, 0 },
+ { "s26", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, 52, 52 }, nullptr, nullptr, nullptr, 0 },
+ { "s27", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, 53, 53 }, nullptr, nullptr, nullptr, 0 },
+ { "s28", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, 54, 54 }, nullptr, nullptr, nullptr, 0 },
+ { "s29", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, 55, 55 }, nullptr, nullptr, nullptr, 0 },
+ { "s30", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, 56, 56 }, nullptr, nullptr, nullptr, 0 },
+ { "s31", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, 57, 57 }, nullptr, nullptr, nullptr, 0 },
+ { "fpscr",nullptr, 4, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 58, 58 }, nullptr, nullptr, nullptr, 0 },
+ { "d16", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, 59, 59 }, nullptr, nullptr, nullptr, 0 },
+ { "d17", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, 60, 60 }, nullptr, nullptr, nullptr, 0 },
+ { "d18", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, 61, 61 }, nullptr, nullptr, nullptr, 0 },
+ { "d19", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, 62, 62 }, nullptr, nullptr, nullptr, 0 },
+ { "d20", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, 63, 63 }, nullptr, nullptr, nullptr, 0 },
+ { "d21", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, 64, 64 }, nullptr, nullptr, nullptr, 0 },
+ { "d22", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, 65, 65 }, nullptr, nullptr, nullptr, 0 },
+ { "d23", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, 66, 66 }, nullptr, nullptr, nullptr, 0 },
+ { "d24", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, 67, 67 }, nullptr, nullptr, nullptr, 0 },
+ { "d25", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, 68, 68 }, nullptr, nullptr, nullptr, 0 },
+ { "d26", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, 69, 69 }, nullptr, nullptr, nullptr, 0 },
+ { "d27", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, 70, 70 }, nullptr, nullptr, nullptr, 0 },
+ { "d28", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, 71, 71 }, nullptr, nullptr, nullptr, 0 },
+ { "d29", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, 72, 72 }, nullptr, nullptr, nullptr, 0 },
+ { "d30", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, 73, 73 }, nullptr, nullptr, nullptr, 0 },
+ { "d31", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, 74, 74 }, nullptr, nullptr, nullptr, 0 },
+ { "d0", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d0, LLDB_INVALID_REGNUM, 75, 75 }, g_d0_regs, nullptr, nullptr, 0 },
+ { "d1", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d1, LLDB_INVALID_REGNUM, 76, 76 }, g_d1_regs, nullptr, nullptr, 0 },
+ { "d2", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d2, LLDB_INVALID_REGNUM, 77, 77 }, g_d2_regs, nullptr, nullptr, 0 },
+ { "d3", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d3, LLDB_INVALID_REGNUM, 78, 78 }, g_d3_regs, nullptr, nullptr, 0 },
+ { "d4", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d4, LLDB_INVALID_REGNUM, 79, 79 }, g_d4_regs, nullptr, nullptr, 0 },
+ { "d5", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d5, LLDB_INVALID_REGNUM, 80, 80 }, g_d5_regs, nullptr, nullptr, 0 },
+ { "d6", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d6, LLDB_INVALID_REGNUM, 81, 81 }, g_d6_regs, nullptr, nullptr, 0 },
+ { "d7", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d7, LLDB_INVALID_REGNUM, 82, 82 }, g_d7_regs, nullptr, nullptr, 0 },
+ { "d8", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d8, LLDB_INVALID_REGNUM, 83, 83 }, g_d8_regs, nullptr, nullptr, 0 },
+ { "d9", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d9, LLDB_INVALID_REGNUM, 84, 84 }, g_d9_regs, nullptr, nullptr, 0 },
+ { "d10", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d10, LLDB_INVALID_REGNUM, 85, 85 }, g_d10_regs, nullptr, nullptr, 0 },
+ { "d11", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d11, LLDB_INVALID_REGNUM, 86, 86 }, g_d11_regs, nullptr, nullptr, 0 },
+ { "d12", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d12, LLDB_INVALID_REGNUM, 87, 87 }, g_d12_regs, nullptr, nullptr, 0 },
+ { "d13", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d13, LLDB_INVALID_REGNUM, 88, 88 }, g_d13_regs, nullptr, nullptr, 0 },
+ { "d14", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d14, LLDB_INVALID_REGNUM, 89, 89 }, g_d14_regs, nullptr, nullptr, 0 },
+ { "d15", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d15, LLDB_INVALID_REGNUM, 90, 90 }, g_d15_regs, nullptr, nullptr, 0 },
+ { "q0", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q0, LLDB_INVALID_REGNUM, 91, 91 }, g_q0_regs, nullptr, nullptr, 0 },
+ { "q1", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q1, LLDB_INVALID_REGNUM, 92, 92 }, g_q1_regs, nullptr, nullptr, 0 },
+ { "q2", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q2, LLDB_INVALID_REGNUM, 93, 93 }, g_q2_regs, nullptr, nullptr, 0 },
+ { "q3", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q3, LLDB_INVALID_REGNUM, 94, 94 }, g_q3_regs, nullptr, nullptr, 0 },
+ { "q4", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q4, LLDB_INVALID_REGNUM, 95, 95 }, g_q4_regs, nullptr, nullptr, 0 },
+ { "q5", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q5, LLDB_INVALID_REGNUM, 96, 96 }, g_q5_regs, nullptr, nullptr, 0 },
+ { "q6", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q6, LLDB_INVALID_REGNUM, 97, 97 }, g_q6_regs, nullptr, nullptr, 0 },
+ { "q7", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q7, LLDB_INVALID_REGNUM, 98, 98 }, g_q7_regs, nullptr, nullptr, 0 },
+ { "q8", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q8, LLDB_INVALID_REGNUM, 99, 99 }, g_q8_regs, nullptr, nullptr, 0 },
+ { "q9", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q9, LLDB_INVALID_REGNUM, 100, 100 }, g_q9_regs, nullptr, nullptr, 0 },
+ { "q10", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q10, LLDB_INVALID_REGNUM, 101, 101 }, g_q10_regs, nullptr, nullptr, 0 },
+ { "q11", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q11, LLDB_INVALID_REGNUM, 102, 102 }, g_q11_regs, nullptr, nullptr, 0 },
+ { "q12", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q12, LLDB_INVALID_REGNUM, 103, 103 }, g_q12_regs, nullptr, nullptr, 0 },
+ { "q13", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q13, LLDB_INVALID_REGNUM, 104, 104 }, g_q13_regs, nullptr, nullptr, 0 },
+ { "q14", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q14, LLDB_INVALID_REGNUM, 105, 105 }, g_q14_regs, nullptr, nullptr, 0 },
+ { "q15", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q15, LLDB_INVALID_REGNUM, 106, 106 }, g_q15_regs, nullptr, nullptr, 0 }
};
-
- static const uint32_t num_registers = llvm::array_lengthof(g_register_infos);
- static ConstString gpr_reg_set ("General Purpose Registers");
- static ConstString sfp_reg_set ("Software Floating Point Registers");
- static ConstString vfp_reg_set ("Floating Point Registers");
- size_t i;
- if (from_scratch)
- {
- // Calculate the offsets of the registers
- // Note that the layout of the "composite" registers (d0-d15 and q0-q15) which comes after the
- // "primordial" registers is important. This enables us to calculate the offset of the composite
- // register by using the offset of its first primordial register. For example, to calculate the
- // offset of q0, use s0's offset.
- if (g_register_infos[2].byte_offset == 0)
- {
- uint32_t byte_offset = 0;
- for (i=0; i<num_registers; ++i)
- {
- // For primordial registers, increment the byte_offset by the byte_size to arrive at the
- // byte_offset for the next register. Otherwise, we have a composite register whose
- // offset can be calculated by consulting the offset of its first primordial register.
- if (!g_register_infos[i].value_regs)
- {
- g_register_infos[i].byte_offset = byte_offset;
- byte_offset += g_register_infos[i].byte_size;
- }
- else
- {
- const uint32_t first_primordial_reg = g_register_infos[i].value_regs[0];
- g_register_infos[i].byte_offset = g_register_infos[first_primordial_reg].byte_offset;
- }
- }
- }
- for (i=0; i<num_registers; ++i)
- {
- ConstString name;
- ConstString alt_name;
- if (g_register_infos[i].name && g_register_infos[i].name[0])
- name.SetCString(g_register_infos[i].name);
- if (g_register_infos[i].alt_name && g_register_infos[i].alt_name[0])
- alt_name.SetCString(g_register_infos[i].alt_name);
-
- if (i <= 15 || i == 25)
- AddRegister (g_register_infos[i], name, alt_name, gpr_reg_set);
- else if (i <= 24)
- AddRegister (g_register_infos[i], name, alt_name, sfp_reg_set);
- else
- AddRegister (g_register_infos[i], name, alt_name, vfp_reg_set);
+ // clang-format on
+
+ static const uint32_t num_registers = llvm::array_lengthof(g_register_infos);
+ static ConstString gpr_reg_set("General Purpose Registers");
+ static ConstString sfp_reg_set("Software Floating Point Registers");
+ static ConstString vfp_reg_set("Floating Point Registers");
+ size_t i;
+ if (from_scratch) {
+ // Calculate the offsets of the registers
+ // Note that the layout of the "composite" registers (d0-d15 and q0-q15)
+ // which comes after the
+ // "primordial" registers is important. This enables us to calculate the
+ // offset of the composite
+ // register by using the offset of its first primordial register. For
+ // example, to calculate the
+ // offset of q0, use s0's offset.
+ if (g_register_infos[2].byte_offset == 0) {
+ uint32_t byte_offset = 0;
+ for (i = 0; i < num_registers; ++i) {
+ // For primordial registers, increment the byte_offset by the byte_size
+ // to arrive at the
+ // byte_offset for the next register. Otherwise, we have a composite
+ // register whose
+ // offset can be calculated by consulting the offset of its first
+ // primordial register.
+ if (!g_register_infos[i].value_regs) {
+ g_register_infos[i].byte_offset = byte_offset;
+ byte_offset += g_register_infos[i].byte_size;
+ } else {
+ const uint32_t first_primordial_reg =
+ g_register_infos[i].value_regs[0];
+ g_register_infos[i].byte_offset =
+ g_register_infos[first_primordial_reg].byte_offset;
}
+ }
}
- else
- {
- // Add composite registers to our primordial registers, then.
- const size_t num_composites = llvm::array_lengthof(g_composites);
- const size_t num_dynamic_regs = GetNumRegisters();
- const size_t num_common_regs = num_registers - num_composites;
- RegisterInfo *g_comp_register_infos = g_register_infos + num_common_regs;
-
- // First we need to validate that all registers that we already have match the non composite regs.
- // If so, then we can add the registers, else we need to bail
- bool match = true;
- if (num_dynamic_regs == num_common_regs)
- {
- for (i=0; match && i<num_dynamic_regs; ++i)
- {
- // Make sure all register names match
- if (m_regs[i].name && g_register_infos[i].name)
- {
- if (strcmp(m_regs[i].name, g_register_infos[i].name))
- {
- match = false;
- break;
- }
- }
-
- // Make sure all register byte sizes match
- if (m_regs[i].byte_size != g_register_infos[i].byte_size)
- {
- match = false;
- break;
- }
- }
- }
- else
- {
- // Wrong number of registers.
+ for (i = 0; i < num_registers; ++i) {
+ ConstString name;
+ ConstString alt_name;
+ if (g_register_infos[i].name && g_register_infos[i].name[0])
+ name.SetCString(g_register_infos[i].name);
+ if (g_register_infos[i].alt_name && g_register_infos[i].alt_name[0])
+ alt_name.SetCString(g_register_infos[i].alt_name);
+
+ if (i <= 15 || i == 25)
+ AddRegister(g_register_infos[i], name, alt_name, gpr_reg_set);
+ else if (i <= 24)
+ AddRegister(g_register_infos[i], name, alt_name, sfp_reg_set);
+ else
+ AddRegister(g_register_infos[i], name, alt_name, vfp_reg_set);
+ }
+ } else {
+ // Add composite registers to our primordial registers, then.
+ const size_t num_composites = llvm::array_lengthof(g_composites);
+ const size_t num_dynamic_regs = GetNumRegisters();
+ const size_t num_common_regs = num_registers - num_composites;
+ RegisterInfo *g_comp_register_infos = g_register_infos + num_common_regs;
+
+ // First we need to validate that all registers that we already have match
+ // the non composite regs.
+ // If so, then we can add the registers, else we need to bail
+ bool match = true;
+ if (num_dynamic_regs == num_common_regs) {
+ for (i = 0; match && i < num_dynamic_regs; ++i) {
+ // Make sure all register names match
+ if (m_regs[i].name && g_register_infos[i].name) {
+ if (strcmp(m_regs[i].name, g_register_infos[i].name)) {
match = false;
+ break;
+ }
}
- // If "match" is true, then we can add extra registers.
- if (match)
- {
- for (i=0; i<num_composites; ++i)
- {
- ConstString name;
- ConstString alt_name;
- const uint32_t first_primordial_reg = g_comp_register_infos[i].value_regs[0];
- const char *reg_name = g_register_infos[first_primordial_reg].name;
- if (reg_name && reg_name[0])
- {
- for (uint32_t j = 0; j < num_dynamic_regs; ++j)
- {
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(j);
- // Find a matching primordial register info entry.
- if (reg_info && reg_info->name && ::strcasecmp(reg_info->name, reg_name) == 0)
- {
- // The name matches the existing primordial entry.
- // Find and assign the offset, and then add this composite register entry.
- g_comp_register_infos[i].byte_offset = reg_info->byte_offset;
- name.SetCString(g_comp_register_infos[i].name);
- AddRegister(g_comp_register_infos[i], name, alt_name, vfp_reg_set);
- }
- }
- }
+
+ // Make sure all register byte sizes match
+ if (m_regs[i].byte_size != g_register_infos[i].byte_size) {
+ match = false;
+ break;
+ }
+ }
+ } else {
+ // Wrong number of registers.
+ match = false;
+ }
+ // If "match" is true, then we can add extra registers.
+ if (match) {
+ for (i = 0; i < num_composites; ++i) {
+ ConstString name;
+ ConstString alt_name;
+ const uint32_t first_primordial_reg =
+ g_comp_register_infos[i].value_regs[0];
+ const char *reg_name = g_register_infos[first_primordial_reg].name;
+ if (reg_name && reg_name[0]) {
+ for (uint32_t j = 0; j < num_dynamic_regs; ++j) {
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(j);
+ // Find a matching primordial register info entry.
+ if (reg_info && reg_info->name &&
+ ::strcasecmp(reg_info->name, reg_name) == 0) {
+ // The name matches the existing primordial entry.
+ // Find and assign the offset, and then add this composite
+ // register entry.
+ g_comp_register_infos[i].byte_offset = reg_info->byte_offset;
+ name.SetCString(g_comp_register_infos[i].name);
+ AddRegister(g_comp_register_infos[i], name, alt_name,
+ vfp_reg_set);
}
+ }
}
+ }
}
+ }
}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
index 0e26c69eb2a9..5b3e04eb588e 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
@@ -16,12 +16,12 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
-#include "lldb/lldb-enumerations.h"
+#include "Plugins/Process/Utility/DynamicRegisterInfo.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Target/RegisterContext.h"
-#include "Plugins/Process/Utility/DynamicRegisterInfo.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-private.h"
#include "GDBRemoteCommunicationClient.h"
@@ -33,133 +33,102 @@ namespace process_gdb_remote {
class ThreadGDBRemote;
class ProcessGDBRemote;
-class GDBRemoteDynamicRegisterInfo :
- public DynamicRegisterInfo
-{
+class GDBRemoteDynamicRegisterInfo : public DynamicRegisterInfo {
public:
- GDBRemoteDynamicRegisterInfo () :
- DynamicRegisterInfo()
- {
- }
+ GDBRemoteDynamicRegisterInfo() : DynamicRegisterInfo() {}
- ~GDBRemoteDynamicRegisterInfo() override = default;
+ ~GDBRemoteDynamicRegisterInfo() override = default;
- void
- HardcodeARMRegisters(bool from_scratch);
+ void HardcodeARMRegisters(bool from_scratch);
};
-class GDBRemoteRegisterContext : public RegisterContext
-{
+class GDBRemoteRegisterContext : public RegisterContext {
public:
- GDBRemoteRegisterContext (ThreadGDBRemote &thread,
- uint32_t concrete_frame_idx,
- GDBRemoteDynamicRegisterInfo &reg_info,
- bool read_all_at_once);
+ GDBRemoteRegisterContext(ThreadGDBRemote &thread, uint32_t concrete_frame_idx,
+ GDBRemoteDynamicRegisterInfo &reg_info,
+ bool read_all_at_once);
+
+ ~GDBRemoteRegisterContext() override;
- ~GDBRemoteRegisterContext() override;
+ void InvalidateAllRegisters() override;
- void
- InvalidateAllRegisters () override;
+ size_t GetRegisterCount() override;
- size_t
- GetRegisterCount () override;
+ const RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
- const RegisterInfo *
- GetRegisterInfoAtIndex (size_t reg) override;
+ size_t GetRegisterSetCount() override;
- size_t
- GetRegisterSetCount () override;
+ const RegisterSet *GetRegisterSet(size_t reg_set) override;
- const RegisterSet *
- GetRegisterSet (size_t reg_set) override;
+ bool ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &value) override;
- bool
- ReadRegister (const RegisterInfo *reg_info, RegisterValue &value) override;
+ bool WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &value) override;
- bool
- WriteRegister (const RegisterInfo *reg_info, const RegisterValue &value) override;
-
- bool
- ReadAllRegisterValues (lldb::DataBufferSP &data_sp) override;
+ bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
- bool
- WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) override;
+ bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- bool
- ReadAllRegisterValues (RegisterCheckpoint &reg_checkpoint) override;
+ bool ReadAllRegisterValues(RegisterCheckpoint &reg_checkpoint) override;
- bool
- WriteAllRegisterValues (const RegisterCheckpoint &reg_checkpoint) override;
+ bool
+ WriteAllRegisterValues(const RegisterCheckpoint &reg_checkpoint) override;
- uint32_t
- ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t num) override;
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
protected:
- friend class ThreadGDBRemote;
-
- bool
- ReadRegisterBytes (const RegisterInfo *reg_info,
- DataExtractor &data);
-
- bool
- WriteRegisterBytes (const RegisterInfo *reg_info,
- DataExtractor &data,
- uint32_t data_offset);
-
- bool
- PrivateSetRegisterValue (uint32_t reg, StringExtractor &response);
-
- bool
- PrivateSetRegisterValue (uint32_t reg, uint64_t val);
-
- void
- SetAllRegisterValid (bool b);
-
- bool
- GetRegisterIsValid (uint32_t reg) const
- {
-#if defined (LLDB_CONFIGURATION_DEBUG)
- assert (reg < m_reg_valid.size());
+ friend class ThreadGDBRemote;
+
+ bool ReadRegisterBytes(const RegisterInfo *reg_info, DataExtractor &data);
+
+ bool WriteRegisterBytes(const RegisterInfo *reg_info, DataExtractor &data,
+ uint32_t data_offset);
+
+ bool PrivateSetRegisterValue(uint32_t reg, llvm::ArrayRef<uint8_t> data);
+
+ bool PrivateSetRegisterValue(uint32_t reg, uint64_t val);
+
+ void SetAllRegisterValid(bool b);
+
+ bool GetRegisterIsValid(uint32_t reg) const {
+#if defined(LLDB_CONFIGURATION_DEBUG)
+ assert(reg < m_reg_valid.size());
#endif
- if (reg < m_reg_valid.size())
- return m_reg_valid[reg];
- return false;
- }
-
- void
- SetRegisterIsValid (const RegisterInfo *reg_info, bool valid)
- {
- if (reg_info)
- return SetRegisterIsValid (reg_info->kinds[lldb::eRegisterKindLLDB], valid);
- }
-
- void
- SetRegisterIsValid (uint32_t reg, bool valid)
- {
-#if defined (LLDB_CONFIGURATION_DEBUG)
- assert (reg < m_reg_valid.size());
+ if (reg < m_reg_valid.size())
+ return m_reg_valid[reg];
+ return false;
+ }
+
+ void SetRegisterIsValid(const RegisterInfo *reg_info, bool valid) {
+ if (reg_info)
+ return SetRegisterIsValid(reg_info->kinds[lldb::eRegisterKindLLDB],
+ valid);
+ }
+
+ void SetRegisterIsValid(uint32_t reg, bool valid) {
+#if defined(LLDB_CONFIGURATION_DEBUG)
+ assert(reg < m_reg_valid.size());
#endif
- if (reg < m_reg_valid.size())
- m_reg_valid[reg] = valid;
- }
-
- void
- SyncThreadState(Process *process); // Assumes the sequence mutex has already been acquired.
-
- GDBRemoteDynamicRegisterInfo &m_reg_info;
- std::vector<bool> m_reg_valid;
- DataExtractor m_reg_data;
- bool m_read_all_at_once;
+ if (reg < m_reg_valid.size())
+ m_reg_valid[reg] = valid;
+ }
+
+ GDBRemoteDynamicRegisterInfo &m_reg_info;
+ std::vector<bool> m_reg_valid;
+ DataExtractor m_reg_data;
+ bool m_read_all_at_once;
private:
- // Helper function for ReadRegisterBytes().
- bool GetPrimordialRegister(const RegisterInfo *reg_info,
- GDBRemoteCommunicationClient &gdb_comm);
- // Helper function for WriteRegisterBytes().
- bool SetPrimordialRegister(const RegisterInfo *reg_info,
- GDBRemoteCommunicationClient &gdb_comm);
-
- DISALLOW_COPY_AND_ASSIGN (GDBRemoteRegisterContext);
+ // Helper function for ReadRegisterBytes().
+ bool GetPrimordialRegister(const RegisterInfo *reg_info,
+ GDBRemoteCommunicationClient &gdb_comm);
+ // Helper function for WriteRegisterBytes().
+ bool SetPrimordialRegister(const RegisterInfo *reg_info,
+ GDBRemoteCommunicationClient &gdb_comm);
+
+ DISALLOW_COPY_AND_ASSIGN(GDBRemoteRegisterContext);
};
} // namespace process_gdb_remote
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index f501e43b00d7..fac52901e763 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -14,7 +14,8 @@
#include <stdlib.h>
#ifndef LLDB_DISABLE_POSIX
#include <netinet/in.h>
-#include <sys/mman.h> // for mmap
+#include <sys/mman.h> // for mmap
+#include <sys/socket.h>
#endif
#include <sys/stat.h>
#include <sys/types.h>
@@ -24,13 +25,11 @@
#include <algorithm>
#include <map>
#include <mutex>
+#include <sstream>
#include "lldb/Breakpoint/Watchpoint.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Debugger.h"
-#include "lldb/Host/ConnectionFileDescriptor.h"
-#include "lldb/Host/FileSpec.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
@@ -40,136 +39,119 @@
#include "lldb/Core/Timer.h"
#include "lldb/Core/Value.h"
#include "lldb/DataFormatters/FormatManager.h"
+#include "lldb/Host/ConnectionFileDescriptor.h"
+#include "lldb/Host/FileSpec.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostThread.h"
#include "lldb/Host/StringConvert.h"
#include "lldb/Host/Symbols.h"
#include "lldb/Host/ThreadLauncher.h"
-#include "lldb/Host/TimeValue.h"
#include "lldb/Host/XML.h"
+#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandObject.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
#include "lldb/Interpreter/CommandReturnObject.h"
-#include "lldb/Interpreter/OptionValueProperties.h"
-#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/OptionGroupBoolean.h"
#include "lldb/Interpreter/OptionGroupUInt64.h"
+#include "lldb/Interpreter/OptionValueProperties.h"
+#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/Property.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/DynamicLoader.h"
+#include "lldb/Target/SystemRuntime.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/TargetList.h"
#include "lldb/Target/ThreadPlanCallFunction.h"
-#include "lldb/Target/SystemRuntime.h"
+#include "lldb/Utility/CleanUp.h"
#include "lldb/Utility/PseudoTerminal.h"
// Project includes
-#include "lldb/Host/Host.h"
+#include "GDBRemoteRegisterContext.h"
+#include "Plugins/Platform/MacOSX/PlatformRemoteiOS.h"
#include "Plugins/Process/Utility/GDBRemoteSignals.h"
#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
#include "Plugins/Process/Utility/StopInfoMachException.h"
-#include "Plugins/Platform/MacOSX/PlatformRemoteiOS.h"
-#include "Utility/StringExtractorGDBRemote.h"
-#include "GDBRemoteRegisterContext.h"
#include "ProcessGDBRemote.h"
#include "ProcessGDBRemoteLog.h"
#include "ThreadGDBRemote.h"
+#include "Utility/StringExtractorGDBRemote.h"
+#include "lldb/Host/Host.h"
-#define DEBUGSERVER_BASENAME "debugserver"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/raw_ostream.h"
+
+#define DEBUGSERVER_BASENAME "debugserver"
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
-namespace lldb
-{
- // Provide a function that can easily dump the packet history if we know a
- // ProcessGDBRemote * value (which we can get from logs or from debugging).
- // We need the function in the lldb namespace so it makes it into the final
- // executable since the LLDB shared library only exports stuff in the lldb
- // namespace. This allows you to attach with a debugger and call this
- // function and get the packet history dumped to a file.
- void
- DumpProcessGDBRemotePacketHistory (void *p, const char *path)
- {
- StreamFile strm;
- Error error (strm.GetFile().Open(path, File::eOpenOptionWrite | File::eOpenOptionCanCreate));
- if (error.Success())
- ((ProcessGDBRemote *)p)->GetGDBRemote().DumpHistory (strm);
- }
+namespace lldb {
+// Provide a function that can easily dump the packet history if we know a
+// ProcessGDBRemote * value (which we can get from logs or from debugging).
+// We need the function in the lldb namespace so it makes it into the final
+// executable since the LLDB shared library only exports stuff in the lldb
+// namespace. This allows you to attach with a debugger and call this
+// function and get the packet history dumped to a file.
+void DumpProcessGDBRemotePacketHistory(void *p, const char *path) {
+ StreamFile strm;
+ Error error(strm.GetFile().Open(path, File::eOpenOptionWrite |
+ File::eOpenOptionCanCreate));
+ if (error.Success())
+ ((ProcessGDBRemote *)p)->GetGDBRemote().DumpHistory(strm);
+}
}
namespace {
- static PropertyDefinition
- g_properties[] =
- {
- { "packet-timeout" , OptionValue::eTypeUInt64 , true , 1, NULL, NULL, "Specify the default packet timeout in seconds." },
- { "target-definition-file" , OptionValue::eTypeFileSpec , true, 0 , NULL, NULL, "The file that provides the description for remote target registers." },
- { NULL , OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL }
- };
-
- enum
- {
- ePropertyPacketTimeout,
- ePropertyTargetDefinitionFile
- };
+static PropertyDefinition g_properties[] = {
+ {"packet-timeout", OptionValue::eTypeUInt64, true, 1, NULL, NULL,
+ "Specify the default packet timeout in seconds."},
+ {"target-definition-file", OptionValue::eTypeFileSpec, true, 0, NULL, NULL,
+ "The file that provides the description for remote target registers."},
+ {NULL, OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL}};
- class PluginProperties : public Properties
- {
- public:
-
- static ConstString
- GetSettingName ()
- {
- return ProcessGDBRemote::GetPluginNameStatic();
- }
-
- PluginProperties() :
- Properties ()
- {
- m_collection_sp.reset (new OptionValueProperties(GetSettingName()));
- m_collection_sp->Initialize(g_properties);
- }
-
- virtual
- ~PluginProperties()
- {
- }
-
- uint64_t
- GetPacketTimeout()
- {
- const uint32_t idx = ePropertyPacketTimeout;
- return m_collection_sp->GetPropertyAtIndexAsUInt64(NULL, idx, g_properties[idx].default_uint_value);
- }
-
- bool
- SetPacketTimeout(uint64_t timeout)
- {
- const uint32_t idx = ePropertyPacketTimeout;
- return m_collection_sp->SetPropertyAtIndexAsUInt64(NULL, idx, timeout);
- }
+enum { ePropertyPacketTimeout, ePropertyTargetDefinitionFile };
- FileSpec
- GetTargetDefinitionFile () const
- {
- const uint32_t idx = ePropertyTargetDefinitionFile;
- return m_collection_sp->GetPropertyAtIndexAsFileSpec (NULL, idx);
- }
- };
+class PluginProperties : public Properties {
+public:
+ static ConstString GetSettingName() {
+ return ProcessGDBRemote::GetPluginNameStatic();
+ }
+
+ PluginProperties() : Properties() {
+ m_collection_sp.reset(new OptionValueProperties(GetSettingName()));
+ m_collection_sp->Initialize(g_properties);
+ }
+
+ virtual ~PluginProperties() {}
+
+ uint64_t GetPacketTimeout() {
+ const uint32_t idx = ePropertyPacketTimeout;
+ return m_collection_sp->GetPropertyAtIndexAsUInt64(
+ NULL, idx, g_properties[idx].default_uint_value);
+ }
+
+ bool SetPacketTimeout(uint64_t timeout) {
+ const uint32_t idx = ePropertyPacketTimeout;
+ return m_collection_sp->SetPropertyAtIndexAsUInt64(NULL, idx, timeout);
+ }
+
+ FileSpec GetTargetDefinitionFile() const {
+ const uint32_t idx = ePropertyTargetDefinitionFile;
+ return m_collection_sp->GetPropertyAtIndexAsFileSpec(NULL, idx);
+ }
+};
- typedef std::shared_ptr<PluginProperties> ProcessKDPPropertiesSP;
+typedef std::shared_ptr<PluginProperties> ProcessKDPPropertiesSP;
- static const ProcessKDPPropertiesSP &
- GetGlobalPluginProperties()
- {
- static ProcessKDPPropertiesSP g_settings_sp;
- if (!g_settings_sp)
- g_settings_sp.reset (new PluginProperties ());
- return g_settings_sp;
- }
+static const ProcessKDPPropertiesSP &GetGlobalPluginProperties() {
+ static ProcessKDPPropertiesSP g_settings_sp;
+ if (!g_settings_sp)
+ g_settings_sp.reset(new PluginProperties());
+ return g_settings_sp;
+}
} // anonymous namespace end
@@ -177,3885 +159,3562 @@ namespace {
// ephemeral port from the kernel and make sure we reserve it before passing
// it to debugserver.
-#if defined (__APPLE__)
-#define LOW_PORT (IPPORT_RESERVED)
-#define HIGH_PORT (IPPORT_HIFIRSTAUTO)
+#if defined(__APPLE__)
+#define LOW_PORT (IPPORT_RESERVED)
+#define HIGH_PORT (IPPORT_HIFIRSTAUTO)
#else
-#define LOW_PORT (1024u)
-#define HIGH_PORT (49151u)
+#define LOW_PORT (1024u)
+#define HIGH_PORT (49151u)
#endif
-#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__) || defined(__aarch64__))
+#if defined(__APPLE__) && \
+ (defined(__arm__) || defined(__arm64__) || defined(__aarch64__))
static bool rand_initialized = false;
-static inline uint16_t
-get_random_port ()
-{
- if (!rand_initialized)
- {
- time_t seed = time(NULL);
+static inline uint16_t get_random_port() {
+ if (!rand_initialized) {
+ time_t seed = time(NULL);
- rand_initialized = true;
- srand(seed);
- }
- return (rand() % (HIGH_PORT - LOW_PORT)) + LOW_PORT;
+ rand_initialized = true;
+ srand(seed);
+ }
+ return (rand() % (HIGH_PORT - LOW_PORT)) + LOW_PORT;
}
#endif
-ConstString
-ProcessGDBRemote::GetPluginNameStatic()
-{
- static ConstString g_name("gdb-remote");
- return g_name;
+ConstString ProcessGDBRemote::GetPluginNameStatic() {
+ static ConstString g_name("gdb-remote");
+ return g_name;
}
-const char *
-ProcessGDBRemote::GetPluginDescriptionStatic()
-{
- return "GDB Remote protocol based debugging plug-in.";
+const char *ProcessGDBRemote::GetPluginDescriptionStatic() {
+ return "GDB Remote protocol based debugging plug-in.";
}
-void
-ProcessGDBRemote::Terminate()
-{
- PluginManager::UnregisterPlugin (ProcessGDBRemote::CreateInstance);
+void ProcessGDBRemote::Terminate() {
+ PluginManager::UnregisterPlugin(ProcessGDBRemote::CreateInstance);
}
-
lldb::ProcessSP
-ProcessGDBRemote::CreateInstance (lldb::TargetSP target_sp, ListenerSP listener_sp, const FileSpec *crash_file_path)
-{
- lldb::ProcessSP process_sp;
- if (crash_file_path == NULL)
- process_sp.reset (new ProcessGDBRemote (target_sp, listener_sp));
- return process_sp;
+ProcessGDBRemote::CreateInstance(lldb::TargetSP target_sp,
+ ListenerSP listener_sp,
+ const FileSpec *crash_file_path) {
+ lldb::ProcessSP process_sp;
+ if (crash_file_path == NULL)
+ process_sp.reset(new ProcessGDBRemote(target_sp, listener_sp));
+ return process_sp;
}
-bool
-ProcessGDBRemote::CanDebug (lldb::TargetSP target_sp, bool plugin_specified_by_name)
-{
- if (plugin_specified_by_name)
- return true;
-
- // For now we are just making sure the file exists for a given module
- Module *exe_module = target_sp->GetExecutableModulePointer();
- if (exe_module)
- {
- ObjectFile *exe_objfile = exe_module->GetObjectFile();
- // We can't debug core files...
- switch (exe_objfile->GetType())
- {
- case ObjectFile::eTypeInvalid:
- case ObjectFile::eTypeCoreFile:
- case ObjectFile::eTypeDebugInfo:
- case ObjectFile::eTypeObjectFile:
- case ObjectFile::eTypeSharedLibrary:
- case ObjectFile::eTypeStubLibrary:
- case ObjectFile::eTypeJIT:
- return false;
- case ObjectFile::eTypeExecutable:
- case ObjectFile::eTypeDynamicLinker:
- case ObjectFile::eTypeUnknown:
- break;
- }
- return exe_module->GetFileSpec().Exists();
- }
- // However, if there is no executable module, we return true since we might be preparing to attach.
+bool ProcessGDBRemote::CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) {
+ if (plugin_specified_by_name)
return true;
+
+ // For now we are just making sure the file exists for a given module
+ Module *exe_module = target_sp->GetExecutableModulePointer();
+ if (exe_module) {
+ ObjectFile *exe_objfile = exe_module->GetObjectFile();
+ // We can't debug core files...
+ switch (exe_objfile->GetType()) {
+ case ObjectFile::eTypeInvalid:
+ case ObjectFile::eTypeCoreFile:
+ case ObjectFile::eTypeDebugInfo:
+ case ObjectFile::eTypeObjectFile:
+ case ObjectFile::eTypeSharedLibrary:
+ case ObjectFile::eTypeStubLibrary:
+ case ObjectFile::eTypeJIT:
+ return false;
+ case ObjectFile::eTypeExecutable:
+ case ObjectFile::eTypeDynamicLinker:
+ case ObjectFile::eTypeUnknown:
+ break;
+ }
+ return exe_module->GetFileSpec().Exists();
+ }
+ // However, if there is no executable module, we return true since we might be
+ // preparing to attach.
+ return true;
}
//----------------------------------------------------------------------
// ProcessGDBRemote constructor
//----------------------------------------------------------------------
-ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp, ListenerSP listener_sp)
- : Process(target_sp, listener_sp),
- m_flags(0),
- m_gdb_comm(),
- m_debugserver_pid(LLDB_INVALID_PROCESS_ID),
- m_last_stop_packet_mutex(),
+ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp,
+ ListenerSP listener_sp)
+ : Process(target_sp, listener_sp), m_flags(0), m_gdb_comm(),
+ m_debugserver_pid(LLDB_INVALID_PROCESS_ID), m_last_stop_packet_mutex(),
m_register_info(),
m_async_broadcaster(NULL, "lldb.process.gdb-remote.async-broadcaster"),
- m_async_listener_sp(Listener::MakeListener("lldb.process.gdb-remote.async-listener")),
- m_async_thread_state_mutex(),
- m_thread_ids(),
- m_thread_pcs(),
- m_jstopinfo_sp(),
- m_jthreadsinfo_sp(),
- m_continue_c_tids(),
- m_continue_C_tids(),
- m_continue_s_tids(),
- m_continue_S_tids(),
- m_max_memory_size(0),
- m_remote_stub_max_memory_size(0),
- m_addr_to_mmap_size(),
- m_thread_create_bp_sp(),
- m_waiting_for_attach(false),
- m_destroy_tried_resuming(false),
- m_command_sp(),
- m_breakpoint_pc_offset(0),
- m_initial_tid(LLDB_INVALID_THREAD_ID)
-{
- m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit, "async thread should exit");
- m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue, "async thread continue");
- m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadDidExit, "async thread did exit");
-
- Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_ASYNC));
-
- const uint32_t async_event_mask = eBroadcastBitAsyncContinue | eBroadcastBitAsyncThreadShouldExit;
-
- if (m_async_listener_sp->StartListeningForEvents(&m_async_broadcaster, async_event_mask) != async_event_mask)
- {
- if (log)
- log->Printf("ProcessGDBRemote::%s failed to listen for m_async_broadcaster events", __FUNCTION__);
- }
-
- const uint32_t gdb_event_mask =
- Communication::eBroadcastBitReadThreadDidExit | GDBRemoteCommunication::eBroadcastBitGdbReadThreadGotNotify;
- if (m_async_listener_sp->StartListeningForEvents(&m_gdb_comm, gdb_event_mask) != gdb_event_mask)
- {
- if (log)
- log->Printf("ProcessGDBRemote::%s failed to listen for m_gdb_comm events", __FUNCTION__);
- }
-
- const uint64_t timeout_seconds = GetGlobalPluginProperties()->GetPacketTimeout();
- if (timeout_seconds > 0)
- m_gdb_comm.SetPacketTimeout(timeout_seconds);
+ m_async_listener_sp(
+ Listener::MakeListener("lldb.process.gdb-remote.async-listener")),
+ m_async_thread_state_mutex(), m_thread_ids(), m_thread_pcs(),
+ m_jstopinfo_sp(), m_jthreadsinfo_sp(), m_continue_c_tids(),
+ m_continue_C_tids(), m_continue_s_tids(), m_continue_S_tids(),
+ m_max_memory_size(0), m_remote_stub_max_memory_size(0),
+ m_addr_to_mmap_size(), m_thread_create_bp_sp(),
+ m_waiting_for_attach(false), m_destroy_tried_resuming(false),
+ m_command_sp(), m_breakpoint_pc_offset(0),
+ m_initial_tid(LLDB_INVALID_THREAD_ID) {
+ m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit,
+ "async thread should exit");
+ m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue,
+ "async thread continue");
+ m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadDidExit,
+ "async thread did exit");
+
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_ASYNC));
+
+ const uint32_t async_event_mask =
+ eBroadcastBitAsyncContinue | eBroadcastBitAsyncThreadShouldExit;
+
+ if (m_async_listener_sp->StartListeningForEvents(
+ &m_async_broadcaster, async_event_mask) != async_event_mask) {
+ if (log)
+ log->Printf("ProcessGDBRemote::%s failed to listen for "
+ "m_async_broadcaster events",
+ __FUNCTION__);
+ }
+
+ const uint32_t gdb_event_mask =
+ Communication::eBroadcastBitReadThreadDidExit |
+ GDBRemoteCommunication::eBroadcastBitGdbReadThreadGotNotify;
+ if (m_async_listener_sp->StartListeningForEvents(
+ &m_gdb_comm, gdb_event_mask) != gdb_event_mask) {
+ if (log)
+ log->Printf("ProcessGDBRemote::%s failed to listen for m_gdb_comm events",
+ __FUNCTION__);
+ }
+
+ const uint64_t timeout_seconds =
+ GetGlobalPluginProperties()->GetPacketTimeout();
+ if (timeout_seconds > 0)
+ m_gdb_comm.SetPacketTimeout(std::chrono::seconds(timeout_seconds));
}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-ProcessGDBRemote::~ProcessGDBRemote()
-{
- // m_mach_process.UnregisterNotificationCallbacks (this);
- Clear();
- // We need to call finalize on the process before destroying ourselves
- // to make sure all of the broadcaster cleanup goes as planned. If we
- // destruct this class, then Process::~Process() might have problems
- // trying to fully destroy the broadcaster.
- Finalize();
-
- // The general Finalize is going to try to destroy the process and that SHOULD
- // shut down the async thread. However, if we don't kill it it will get stranded and
- // its connection will go away so when it wakes up it will crash. So kill it for sure here.
- StopAsyncThread();
- KillDebugserverProcess();
+ProcessGDBRemote::~ProcessGDBRemote() {
+ // m_mach_process.UnregisterNotificationCallbacks (this);
+ Clear();
+ // We need to call finalize on the process before destroying ourselves
+ // to make sure all of the broadcaster cleanup goes as planned. If we
+ // destruct this class, then Process::~Process() might have problems
+ // trying to fully destroy the broadcaster.
+ Finalize();
+
+ // The general Finalize is going to try to destroy the process and that SHOULD
+ // shut down the async thread. However, if we don't kill it it will get
+ // stranded and
+ // its connection will go away so when it wakes up it will crash. So kill it
+ // for sure here.
+ StopAsyncThread();
+ KillDebugserverProcess();
}
//----------------------------------------------------------------------
// PluginInterface
//----------------------------------------------------------------------
-ConstString
-ProcessGDBRemote::GetPluginName()
-{
- return GetPluginNameStatic();
-}
-
-uint32_t
-ProcessGDBRemote::GetPluginVersion()
-{
- return 1;
-}
-
-bool
-ProcessGDBRemote::ParsePythonTargetDefinition(const FileSpec &target_definition_fspec)
-{
- ScriptInterpreter *interpreter = GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
- Error error;
- StructuredData::ObjectSP module_object_sp(interpreter->LoadPluginModule(target_definition_fspec, error));
- if (module_object_sp)
- {
- StructuredData::DictionarySP target_definition_sp(
- interpreter->GetDynamicSettings(module_object_sp, &GetTarget(), "gdb-server-target-definition", error));
-
- if (target_definition_sp)
- {
- StructuredData::ObjectSP target_object(target_definition_sp->GetValueForKey("host-info"));
- if (target_object)
- {
- if (auto host_info_dict = target_object->GetAsDictionary())
- {
- StructuredData::ObjectSP triple_value = host_info_dict->GetValueForKey("triple");
- if (auto triple_string_value = triple_value->GetAsString())
- {
- std::string triple_string = triple_string_value->GetValue();
- ArchSpec host_arch(triple_string.c_str());
- if (!host_arch.IsCompatibleMatch(GetTarget().GetArchitecture()))
- {
- GetTarget().SetArchitecture(host_arch);
- }
- }
- }
- }
- m_breakpoint_pc_offset = 0;
- StructuredData::ObjectSP breakpoint_pc_offset_value = target_definition_sp->GetValueForKey("breakpoint-pc-offset");
- if (breakpoint_pc_offset_value)
- {
- if (auto breakpoint_pc_int_value = breakpoint_pc_offset_value->GetAsInteger())
- m_breakpoint_pc_offset = breakpoint_pc_int_value->GetValue();
- }
-
- if (m_register_info.SetRegisterInfo(*target_definition_sp, GetTarget().GetArchitecture()) > 0)
- {
- return true;
+ConstString ProcessGDBRemote::GetPluginName() { return GetPluginNameStatic(); }
+
+uint32_t ProcessGDBRemote::GetPluginVersion() { return 1; }
+
+bool ProcessGDBRemote::ParsePythonTargetDefinition(
+ const FileSpec &target_definition_fspec) {
+ ScriptInterpreter *interpreter =
+ GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
+ Error error;
+ StructuredData::ObjectSP module_object_sp(
+ interpreter->LoadPluginModule(target_definition_fspec, error));
+ if (module_object_sp) {
+ StructuredData::DictionarySP target_definition_sp(
+ interpreter->GetDynamicSettings(module_object_sp, &GetTarget(),
+ "gdb-server-target-definition", error));
+
+ if (target_definition_sp) {
+ StructuredData::ObjectSP target_object(
+ target_definition_sp->GetValueForKey("host-info"));
+ if (target_object) {
+ if (auto host_info_dict = target_object->GetAsDictionary()) {
+ StructuredData::ObjectSP triple_value =
+ host_info_dict->GetValueForKey("triple");
+ if (auto triple_string_value = triple_value->GetAsString()) {
+ std::string triple_string = triple_string_value->GetValue();
+ ArchSpec host_arch(triple_string.c_str());
+ if (!host_arch.IsCompatibleMatch(GetTarget().GetArchitecture())) {
+ GetTarget().SetArchitecture(host_arch);
}
+ }
}
+ }
+ m_breakpoint_pc_offset = 0;
+ StructuredData::ObjectSP breakpoint_pc_offset_value =
+ target_definition_sp->GetValueForKey("breakpoint-pc-offset");
+ if (breakpoint_pc_offset_value) {
+ if (auto breakpoint_pc_int_value =
+ breakpoint_pc_offset_value->GetAsInteger())
+ m_breakpoint_pc_offset = breakpoint_pc_int_value->GetValue();
+ }
+
+ if (m_register_info.SetRegisterInfo(*target_definition_sp,
+ GetTarget().GetArchitecture()) > 0) {
+ return true;
+ }
}
- return false;
+ }
+ return false;
}
-// If the remote stub didn't give us eh_frame or DWARF register numbers for a register,
+// If the remote stub didn't give us eh_frame or DWARF register numbers for a
+// register,
// see if the ABI can provide them.
// DWARF and eh_frame register numbers are defined as a part of the ABI.
-static void
-AugmentRegisterInfoViaABI (RegisterInfo &reg_info, ConstString reg_name, ABISP abi_sp)
-{
- if (reg_info.kinds[eRegisterKindEHFrame] == LLDB_INVALID_REGNUM
- || reg_info.kinds[eRegisterKindDWARF] == LLDB_INVALID_REGNUM)
- {
- if (abi_sp)
- {
- RegisterInfo abi_reg_info;
- if (abi_sp->GetRegisterInfoByName (reg_name, abi_reg_info))
- {
- if (reg_info.kinds[eRegisterKindEHFrame] == LLDB_INVALID_REGNUM &&
- abi_reg_info.kinds[eRegisterKindEHFrame] != LLDB_INVALID_REGNUM)
- {
- reg_info.kinds[eRegisterKindEHFrame] = abi_reg_info.kinds[eRegisterKindEHFrame];
- }
- if (reg_info.kinds[eRegisterKindDWARF] == LLDB_INVALID_REGNUM &&
- abi_reg_info.kinds[eRegisterKindDWARF] != LLDB_INVALID_REGNUM)
- {
- reg_info.kinds[eRegisterKindDWARF] = abi_reg_info.kinds[eRegisterKindDWARF];
- }
- if (reg_info.kinds[eRegisterKindGeneric] == LLDB_INVALID_REGNUM &&
- abi_reg_info.kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM)
- {
- reg_info.kinds[eRegisterKindGeneric] = abi_reg_info.kinds[eRegisterKindGeneric];
- }
- }
+static void AugmentRegisterInfoViaABI(RegisterInfo &reg_info,
+ ConstString reg_name, ABISP abi_sp) {
+ if (reg_info.kinds[eRegisterKindEHFrame] == LLDB_INVALID_REGNUM ||
+ reg_info.kinds[eRegisterKindDWARF] == LLDB_INVALID_REGNUM) {
+ if (abi_sp) {
+ RegisterInfo abi_reg_info;
+ if (abi_sp->GetRegisterInfoByName(reg_name, abi_reg_info)) {
+ if (reg_info.kinds[eRegisterKindEHFrame] == LLDB_INVALID_REGNUM &&
+ abi_reg_info.kinds[eRegisterKindEHFrame] != LLDB_INVALID_REGNUM) {
+ reg_info.kinds[eRegisterKindEHFrame] =
+ abi_reg_info.kinds[eRegisterKindEHFrame];
}
- }
-}
-
-static size_t
-SplitCommaSeparatedRegisterNumberString(const llvm::StringRef &comma_separated_regiter_numbers, std::vector<uint32_t> &regnums, int base)
-{
- regnums.clear();
- std::pair<llvm::StringRef, llvm::StringRef> value_pair;
- value_pair.second = comma_separated_regiter_numbers;
- do
- {
- value_pair = value_pair.second.split(',');
- if (!value_pair.first.empty())
- {
- uint32_t reg = StringConvert::ToUInt32 (value_pair.first.str().c_str(), LLDB_INVALID_REGNUM, base);
- if (reg != LLDB_INVALID_REGNUM)
- regnums.push_back (reg);
- }
- } while (!value_pair.second.empty());
- return regnums.size();
-}
-
-
-void
-ProcessGDBRemote::BuildDynamicRegisterInfo (bool force)
-{
- if (!force && m_register_info.GetNumRegisters() > 0)
- return;
-
- m_register_info.Clear();
-
- // Check if qHostInfo specified a specific packet timeout for this connection.
- // If so then lets update our setting so the user knows what the timeout is
- // and can see it.
- const uint32_t host_packet_timeout = m_gdb_comm.GetHostDefaultPacketTimeout();
- if (host_packet_timeout)
- {
- GetGlobalPluginProperties()->SetPacketTimeout(host_packet_timeout);
- }
-
- // Register info search order:
- // 1 - Use the target definition python file if one is specified.
- // 2 - If the target definition doesn't have any of the info from the target.xml (registers) then proceed to read the target.xml.
- // 3 - Fall back on the qRegisterInfo packets.
-
- FileSpec target_definition_fspec = GetGlobalPluginProperties()->GetTargetDefinitionFile ();
- if (!target_definition_fspec.Exists())
- {
- // If the filename doesn't exist, it may be a ~ not having been expanded - try to resolve it.
- target_definition_fspec.ResolvePath();
- }
- if (target_definition_fspec)
- {
- // See if we can get register definitions from a python file
- if (ParsePythonTargetDefinition (target_definition_fspec))
- {
- return;
+ if (reg_info.kinds[eRegisterKindDWARF] == LLDB_INVALID_REGNUM &&
+ abi_reg_info.kinds[eRegisterKindDWARF] != LLDB_INVALID_REGNUM) {
+ reg_info.kinds[eRegisterKindDWARF] =
+ abi_reg_info.kinds[eRegisterKindDWARF];
}
- else
- {
- StreamSP stream_sp = GetTarget().GetDebugger().GetAsyncOutputStream();
- stream_sp->Printf ("ERROR: target description file %s failed to parse.\n", target_definition_fspec.GetPath().c_str());
+ if (reg_info.kinds[eRegisterKindGeneric] == LLDB_INVALID_REGNUM &&
+ abi_reg_info.kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM) {
+ reg_info.kinds[eRegisterKindGeneric] =
+ abi_reg_info.kinds[eRegisterKindGeneric];
}
+ }
}
+ }
+}
- const ArchSpec &target_arch = GetTarget().GetArchitecture();
- const ArchSpec &remote_host_arch = m_gdb_comm.GetHostArchitecture();
- const ArchSpec &remote_process_arch = m_gdb_comm.GetProcessArchitecture();
+static size_t SplitCommaSeparatedRegisterNumberString(
+ const llvm::StringRef &comma_separated_regiter_numbers,
+ std::vector<uint32_t> &regnums, int base) {
+ regnums.clear();
+ std::pair<llvm::StringRef, llvm::StringRef> value_pair;
+ value_pair.second = comma_separated_regiter_numbers;
+ do {
+ value_pair = value_pair.second.split(',');
+ if (!value_pair.first.empty()) {
+ uint32_t reg = StringConvert::ToUInt32(value_pair.first.str().c_str(),
+ LLDB_INVALID_REGNUM, base);
+ if (reg != LLDB_INVALID_REGNUM)
+ regnums.push_back(reg);
+ }
+ } while (!value_pair.second.empty());
+ return regnums.size();
+}
- // Use the process' architecture instead of the host arch, if available
- ArchSpec arch_to_use;
- if (remote_process_arch.IsValid ())
- arch_to_use = remote_process_arch;
- else
- arch_to_use = remote_host_arch;
-
- if (!arch_to_use.IsValid())
- arch_to_use = target_arch;
-
- if (GetGDBServerRegisterInfo (arch_to_use))
- return;
-
- char packet[128];
- uint32_t reg_offset = 0;
- uint32_t reg_num = 0;
- for (StringExtractorGDBRemote::ResponseType response_type = StringExtractorGDBRemote::eResponse;
- response_type == StringExtractorGDBRemote::eResponse;
- ++reg_num)
- {
- const int packet_len = ::snprintf (packet, sizeof(packet), "qRegisterInfo%x", reg_num);
- assert (packet_len < (int)sizeof(packet));
- StringExtractorGDBRemote response;
- if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false) == GDBRemoteCommunication::PacketResult::Success)
- {
- response_type = response.GetResponseType();
- if (response_type == StringExtractorGDBRemote::eResponse)
+void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
+ if (!force && m_register_info.GetNumRegisters() > 0)
+ return;
+
+ m_register_info.Clear();
+
+ // Check if qHostInfo specified a specific packet timeout for this connection.
+ // If so then lets update our setting so the user knows what the timeout is
+ // and can see it.
+ const auto host_packet_timeout = m_gdb_comm.GetHostDefaultPacketTimeout();
+ if (host_packet_timeout > std::chrono::seconds(0)) {
+ GetGlobalPluginProperties()->SetPacketTimeout(host_packet_timeout.count());
+ }
+
+ // Register info search order:
+ // 1 - Use the target definition python file if one is specified.
+ // 2 - If the target definition doesn't have any of the info from the
+ // target.xml (registers) then proceed to read the target.xml.
+ // 3 - Fall back on the qRegisterInfo packets.
+
+ FileSpec target_definition_fspec =
+ GetGlobalPluginProperties()->GetTargetDefinitionFile();
+ if (!target_definition_fspec.Exists()) {
+ // If the filename doesn't exist, it may be a ~ not having been expanded -
+ // try to resolve it.
+ target_definition_fspec.ResolvePath();
+ }
+ if (target_definition_fspec) {
+ // See if we can get register definitions from a python file
+ if (ParsePythonTargetDefinition(target_definition_fspec)) {
+ return;
+ } else {
+ StreamSP stream_sp = GetTarget().GetDebugger().GetAsyncOutputStream();
+ stream_sp->Printf("ERROR: target description file %s failed to parse.\n",
+ target_definition_fspec.GetPath().c_str());
+ }
+ }
+
+ const ArchSpec &target_arch = GetTarget().GetArchitecture();
+ const ArchSpec &remote_host_arch = m_gdb_comm.GetHostArchitecture();
+ const ArchSpec &remote_process_arch = m_gdb_comm.GetProcessArchitecture();
+
+ // Use the process' architecture instead of the host arch, if available
+ ArchSpec arch_to_use;
+ if (remote_process_arch.IsValid())
+ arch_to_use = remote_process_arch;
+ else
+ arch_to_use = remote_host_arch;
+
+ if (!arch_to_use.IsValid())
+ arch_to_use = target_arch;
+
+ if (GetGDBServerRegisterInfo(arch_to_use))
+ return;
+
+ char packet[128];
+ uint32_t reg_offset = 0;
+ uint32_t reg_num = 0;
+ for (StringExtractorGDBRemote::ResponseType response_type =
+ StringExtractorGDBRemote::eResponse;
+ response_type == StringExtractorGDBRemote::eResponse; ++reg_num) {
+ const int packet_len =
+ ::snprintf(packet, sizeof(packet), "qRegisterInfo%x", reg_num);
+ assert(packet_len < (int)sizeof(packet));
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
+ StringExtractorGDBRemote response;
+ if (m_gdb_comm.SendPacketAndWaitForResponse(packet, response, false) ==
+ GDBRemoteCommunication::PacketResult::Success) {
+ response_type = response.GetResponseType();
+ if (response_type == StringExtractorGDBRemote::eResponse) {
+ llvm::StringRef name;
+ llvm::StringRef value;
+ ConstString reg_name;
+ ConstString alt_name;
+ ConstString set_name;
+ std::vector<uint32_t> value_regs;
+ std::vector<uint32_t> invalidate_regs;
+ std::vector<uint8_t> dwarf_opcode_bytes;
+ RegisterInfo reg_info = {
+ NULL, // Name
+ NULL, // Alt name
+ 0, // byte size
+ reg_offset, // offset
+ eEncodingUint, // encoding
+ eFormatHex, // format
{
- std::string name;
- std::string value;
- ConstString reg_name;
- ConstString alt_name;
- ConstString set_name;
- std::vector<uint32_t> value_regs;
- std::vector<uint32_t> invalidate_regs;
- std::vector<uint8_t> dwarf_opcode_bytes;
- RegisterInfo reg_info = { NULL, // Name
- NULL, // Alt name
- 0, // byte size
- reg_offset, // offset
- eEncodingUint, // encoding
- eFormatHex, // format
- {
- LLDB_INVALID_REGNUM, // eh_frame reg num
- LLDB_INVALID_REGNUM, // DWARF reg num
- LLDB_INVALID_REGNUM, // generic reg num
- reg_num, // process plugin reg num
- reg_num // native register number
- },
- NULL,
- NULL,
- NULL, // Dwarf expression opcode bytes pointer
- 0 // Dwarf expression opcode bytes length
- };
-
- while (response.GetNameColonValue(name, value))
- {
- if (name.compare("name") == 0)
- {
- reg_name.SetCString(value.c_str());
- }
- else if (name.compare("alt-name") == 0)
- {
- alt_name.SetCString(value.c_str());
- }
- else if (name.compare("bitsize") == 0)
- {
- reg_info.byte_size = StringConvert::ToUInt32(value.c_str(), 0, 0) / CHAR_BIT;
- }
- else if (name.compare("offset") == 0)
- {
- uint32_t offset = StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0);
- if (reg_offset != offset)
- {
- reg_offset = offset;
- }
- }
- else if (name.compare("encoding") == 0)
- {
- const Encoding encoding = Args::StringToEncoding (value.c_str());
- if (encoding != eEncodingInvalid)
- reg_info.encoding = encoding;
- }
- else if (name.compare("format") == 0)
- {
- Format format = eFormatInvalid;
- if (Args::StringToFormat (value.c_str(), format, NULL).Success())
- reg_info.format = format;
- else if (value.compare("binary") == 0)
- reg_info.format = eFormatBinary;
- else if (value.compare("decimal") == 0)
- reg_info.format = eFormatDecimal;
- else if (value.compare("hex") == 0)
- reg_info.format = eFormatHex;
- else if (value.compare("float") == 0)
- reg_info.format = eFormatFloat;
- else if (value.compare("vector-sint8") == 0)
- reg_info.format = eFormatVectorOfSInt8;
- else if (value.compare("vector-uint8") == 0)
- reg_info.format = eFormatVectorOfUInt8;
- else if (value.compare("vector-sint16") == 0)
- reg_info.format = eFormatVectorOfSInt16;
- else if (value.compare("vector-uint16") == 0)
- reg_info.format = eFormatVectorOfUInt16;
- else if (value.compare("vector-sint32") == 0)
- reg_info.format = eFormatVectorOfSInt32;
- else if (value.compare("vector-uint32") == 0)
- reg_info.format = eFormatVectorOfUInt32;
- else if (value.compare("vector-float32") == 0)
- reg_info.format = eFormatVectorOfFloat32;
- else if (value.compare("vector-uint128") == 0)
- reg_info.format = eFormatVectorOfUInt128;
- }
- else if (name.compare("set") == 0)
- {
- set_name.SetCString(value.c_str());
- }
- else if (name.compare("gcc") == 0 || name.compare("ehframe") == 0)
- {
- reg_info.kinds[eRegisterKindEHFrame] = StringConvert::ToUInt32(value.c_str(), LLDB_INVALID_REGNUM, 0);
- }
- else if (name.compare("dwarf") == 0)
- {
- reg_info.kinds[eRegisterKindDWARF] = StringConvert::ToUInt32(value.c_str(), LLDB_INVALID_REGNUM, 0);
- }
- else if (name.compare("generic") == 0)
- {
- reg_info.kinds[eRegisterKindGeneric] = Args::StringToGenericRegister (value.c_str());
- }
- else if (name.compare("container-regs") == 0)
- {
- SplitCommaSeparatedRegisterNumberString(value, value_regs, 16);
- }
- else if (name.compare("invalidate-regs") == 0)
- {
- SplitCommaSeparatedRegisterNumberString(value, invalidate_regs, 16);
- }
- else if (name.compare("dynamic_size_dwarf_expr_bytes") == 0)
- {
- size_t dwarf_opcode_len = value.length () / 2;
- assert (dwarf_opcode_len > 0);
-
- dwarf_opcode_bytes.resize (dwarf_opcode_len);
- StringExtractor opcode_extractor;
- reg_info.dynamic_size_dwarf_len = dwarf_opcode_len;
-
- // Swap "value" over into "opcode_extractor"
- opcode_extractor.GetStringRef ().swap (value);
- uint32_t ret_val = opcode_extractor.GetHexBytesAvail (dwarf_opcode_bytes.data (),
- dwarf_opcode_len);
- assert (dwarf_opcode_len == ret_val);
-
- reg_info.dynamic_size_dwarf_expr_bytes = dwarf_opcode_bytes.data ();
- }
- }
-
- reg_info.byte_offset = reg_offset;
- assert (reg_info.byte_size != 0);
- reg_offset += reg_info.byte_size;
- if (!value_regs.empty())
- {
- value_regs.push_back(LLDB_INVALID_REGNUM);
- reg_info.value_regs = value_regs.data();
- }
- if (!invalidate_regs.empty())
- {
- invalidate_regs.push_back(LLDB_INVALID_REGNUM);
- reg_info.invalidate_regs = invalidate_regs.data();
- }
-
- // We have to make a temporary ABI here, and not use the GetABI because this code
- // gets called in DidAttach, when the target architecture (and consequently the ABI we'll get from
- // the process) may be wrong.
- ABISP abi_to_use = ABI::FindPlugin(arch_to_use);
-
- AugmentRegisterInfoViaABI (reg_info, reg_name, abi_to_use);
+ LLDB_INVALID_REGNUM, // eh_frame reg num
+ LLDB_INVALID_REGNUM, // DWARF reg num
+ LLDB_INVALID_REGNUM, // generic reg num
+ reg_num, // process plugin reg num
+ reg_num // native register number
+ },
+ NULL,
+ NULL,
+ NULL, // Dwarf expression opcode bytes pointer
+ 0 // Dwarf expression opcode bytes length
+ };
- m_register_info.AddRegister(reg_info, reg_name, alt_name, set_name);
+ while (response.GetNameColonValue(name, value)) {
+ if (name.equals("name")) {
+ reg_name.SetString(value);
+ } else if (name.equals("alt-name")) {
+ alt_name.SetString(value);
+ } else if (name.equals("bitsize")) {
+ value.getAsInteger(0, reg_info.byte_size);
+ reg_info.byte_size /= CHAR_BIT;
+ } else if (name.equals("offset")) {
+ if (value.getAsInteger(0, reg_offset))
+ reg_offset = UINT32_MAX;
+ } else if (name.equals("encoding")) {
+ const Encoding encoding = Args::StringToEncoding(value);
+ if (encoding != eEncodingInvalid)
+ reg_info.encoding = encoding;
+ } else if (name.equals("format")) {
+ Format format = eFormatInvalid;
+ if (Args::StringToFormat(value.str().c_str(), format, NULL)
+ .Success())
+ reg_info.format = format;
+ else {
+ reg_info.format =
+ llvm::StringSwitch<Format>(value)
+ .Case("binary", eFormatBinary)
+ .Case("decimal", eFormatDecimal)
+ .Case("hex", eFormatHex)
+ .Case("float", eFormatFloat)
+ .Case("vector-sint8", eFormatVectorOfSInt8)
+ .Case("vector-uint8", eFormatVectorOfUInt8)
+ .Case("vector-sint16", eFormatVectorOfSInt16)
+ .Case("vector-uint16", eFormatVectorOfUInt16)
+ .Case("vector-sint32", eFormatVectorOfSInt32)
+ .Case("vector-uint32", eFormatVectorOfUInt32)
+ .Case("vector-float32", eFormatVectorOfFloat32)
+ .Case("vector-uint64", eFormatVectorOfUInt64)
+ .Case("vector-uint128", eFormatVectorOfUInt128)
+ .Default(eFormatInvalid);
}
- else
- {
- break; // ensure exit before reg_num is incremented
- }
- }
- else
- {
- break;
+ } else if (name.equals("set")) {
+ set_name.SetString(value);
+ } else if (name.equals("gcc") || name.equals("ehframe")) {
+ if (value.getAsInteger(0, reg_info.kinds[eRegisterKindEHFrame]))
+ reg_info.kinds[eRegisterKindEHFrame] = LLDB_INVALID_REGNUM;
+ } else if (name.equals("dwarf")) {
+ if (value.getAsInteger(0, reg_info.kinds[eRegisterKindDWARF]))
+ reg_info.kinds[eRegisterKindDWARF] = LLDB_INVALID_REGNUM;
+ } else if (name.equals("generic")) {
+ reg_info.kinds[eRegisterKindGeneric] =
+ Args::StringToGenericRegister(value);
+ } else if (name.equals("container-regs")) {
+ SplitCommaSeparatedRegisterNumberString(value, value_regs, 16);
+ } else if (name.equals("invalidate-regs")) {
+ SplitCommaSeparatedRegisterNumberString(value, invalidate_regs, 16);
+ } else if (name.equals("dynamic_size_dwarf_expr_bytes")) {
+ size_t dwarf_opcode_len = value.size() / 2;
+ assert(dwarf_opcode_len > 0);
+
+ dwarf_opcode_bytes.resize(dwarf_opcode_len);
+ reg_info.dynamic_size_dwarf_len = dwarf_opcode_len;
+
+ StringExtractor opcode_extractor(value);
+ uint32_t ret_val =
+ opcode_extractor.GetHexBytesAvail(dwarf_opcode_bytes);
+ assert(dwarf_opcode_len == ret_val);
+
+ reg_info.dynamic_size_dwarf_expr_bytes = dwarf_opcode_bytes.data();
+ }
}
- }
- if (m_register_info.GetNumRegisters() > 0)
- {
- m_register_info.Finalize(GetTarget().GetArchitecture());
- return;
- }
+ reg_info.byte_offset = reg_offset;
+ assert(reg_info.byte_size != 0);
+ reg_offset += reg_info.byte_size;
+ if (!value_regs.empty()) {
+ value_regs.push_back(LLDB_INVALID_REGNUM);
+ reg_info.value_regs = value_regs.data();
+ }
+ if (!invalidate_regs.empty()) {
+ invalidate_regs.push_back(LLDB_INVALID_REGNUM);
+ reg_info.invalidate_regs = invalidate_regs.data();
+ }
- // We didn't get anything if the accumulated reg_num is zero. See if we are
- // debugging ARM and fill with a hard coded register set until we can get an
- // updated debugserver down on the devices.
- // On the other hand, if the accumulated reg_num is positive, see if we can
- // add composite registers to the existing primordial ones.
- bool from_scratch = (m_register_info.GetNumRegisters() == 0);
+ // We have to make a temporary ABI here, and not use the GetABI because
+ // this code
+ // gets called in DidAttach, when the target architecture (and
+ // consequently the ABI we'll get from
+ // the process) may be wrong.
+ ABISP abi_to_use = ABI::FindPlugin(arch_to_use);
- if (!target_arch.IsValid())
- {
- if (arch_to_use.IsValid()
- && (arch_to_use.GetMachine() == llvm::Triple::arm || arch_to_use.GetMachine() == llvm::Triple::thumb)
- && arch_to_use.GetTriple().getVendor() == llvm::Triple::Apple)
- m_register_info.HardcodeARMRegisters(from_scratch);
- }
- else if (target_arch.GetMachine() == llvm::Triple::arm
- || target_arch.GetMachine() == llvm::Triple::thumb)
- {
- m_register_info.HardcodeARMRegisters(from_scratch);
- }
+ AugmentRegisterInfoViaABI(reg_info, reg_name, abi_to_use);
- // At this point, we can finalize our register info.
- m_register_info.Finalize (GetTarget().GetArchitecture());
+ m_register_info.AddRegister(reg_info, reg_name, alt_name, set_name);
+ } else {
+ break; // ensure exit before reg_num is incremented
+ }
+ } else {
+ break;
+ }
+ }
+
+ if (m_register_info.GetNumRegisters() > 0) {
+ m_register_info.Finalize(GetTarget().GetArchitecture());
+ return;
+ }
+
+ // We didn't get anything if the accumulated reg_num is zero. See if we are
+ // debugging ARM and fill with a hard coded register set until we can get an
+ // updated debugserver down on the devices.
+ // On the other hand, if the accumulated reg_num is positive, see if we can
+ // add composite registers to the existing primordial ones.
+ bool from_scratch = (m_register_info.GetNumRegisters() == 0);
+
+ if (!target_arch.IsValid()) {
+ if (arch_to_use.IsValid() &&
+ (arch_to_use.GetMachine() == llvm::Triple::arm ||
+ arch_to_use.GetMachine() == llvm::Triple::thumb) &&
+ arch_to_use.GetTriple().getVendor() == llvm::Triple::Apple)
+ m_register_info.HardcodeARMRegisters(from_scratch);
+ } else if (target_arch.GetMachine() == llvm::Triple::arm ||
+ target_arch.GetMachine() == llvm::Triple::thumb) {
+ m_register_info.HardcodeARMRegisters(from_scratch);
+ }
+
+ // At this point, we can finalize our register info.
+ m_register_info.Finalize(GetTarget().GetArchitecture());
}
-Error
-ProcessGDBRemote::WillLaunch (Module* module)
-{
- return WillLaunchOrAttach ();
+Error ProcessGDBRemote::WillLaunch(Module *module) {
+ return WillLaunchOrAttach();
}
-Error
-ProcessGDBRemote::WillAttachToProcessWithID (lldb::pid_t pid)
-{
- return WillLaunchOrAttach ();
+Error ProcessGDBRemote::WillAttachToProcessWithID(lldb::pid_t pid) {
+ return WillLaunchOrAttach();
}
-Error
-ProcessGDBRemote::WillAttachToProcessWithName (const char *process_name, bool wait_for_launch)
-{
- return WillLaunchOrAttach ();
+Error ProcessGDBRemote::WillAttachToProcessWithName(const char *process_name,
+ bool wait_for_launch) {
+ return WillLaunchOrAttach();
}
-Error
-ProcessGDBRemote::DoConnectRemote (Stream *strm, const char *remote_url)
-{
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
- Error error (WillLaunchOrAttach ());
-
- if (error.Fail())
- return error;
-
- error = ConnectToDebugserver (remote_url);
+Error ProcessGDBRemote::DoConnectRemote(Stream *strm,
+ llvm::StringRef remote_url) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ Error error(WillLaunchOrAttach());
- if (error.Fail())
- return error;
- StartAsyncThread ();
-
- lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID ();
- if (pid == LLDB_INVALID_PROCESS_ID)
- {
- // We don't have a valid process ID, so note that we are connected
- // and could now request to launch or attach, or get remote process
- // listings...
- SetPrivateState (eStateConnected);
- }
- else
- {
- // We have a valid process
- SetID (pid);
- GetThreadList();
- StringExtractorGDBRemote response;
- if (m_gdb_comm.GetStopReply(response))
- {
- SetLastStopPacket(response);
+ if (error.Fail())
+ return error;
- // '?' Packets must be handled differently in non-stop mode
- if (GetTarget().GetNonStopModeEnabled())
- HandleStopReplySequence();
+ error = ConnectToDebugserver(remote_url);
- Target &target = GetTarget();
- if (!target.GetArchitecture().IsValid())
- {
- if (m_gdb_comm.GetProcessArchitecture().IsValid())
- {
- target.SetArchitecture(m_gdb_comm.GetProcessArchitecture());
- }
- else
- {
- target.SetArchitecture(m_gdb_comm.GetHostArchitecture());
- }
- }
-
- const StateType state = SetThreadStopInfo (response);
- if (state != eStateInvalid)
- {
- SetPrivateState (state);
- }
- else
- error.SetErrorStringWithFormat ("Process %" PRIu64 " was reported after connecting to '%s', but state was not stopped: %s", pid, remote_url, StateAsCString (state));
+ if (error.Fail())
+ return error;
+ StartAsyncThread();
+
+ lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID();
+ if (pid == LLDB_INVALID_PROCESS_ID) {
+ // We don't have a valid process ID, so note that we are connected
+ // and could now request to launch or attach, or get remote process
+ // listings...
+ SetPrivateState(eStateConnected);
+ } else {
+ // We have a valid process
+ SetID(pid);
+ GetThreadList();
+ StringExtractorGDBRemote response;
+ if (m_gdb_comm.GetStopReply(response)) {
+ SetLastStopPacket(response);
+
+ // '?' Packets must be handled differently in non-stop mode
+ if (GetTarget().GetNonStopModeEnabled())
+ HandleStopReplySequence();
+
+ Target &target = GetTarget();
+ if (!target.GetArchitecture().IsValid()) {
+ if (m_gdb_comm.GetProcessArchitecture().IsValid()) {
+ target.SetArchitecture(m_gdb_comm.GetProcessArchitecture());
+ } else {
+ target.SetArchitecture(m_gdb_comm.GetHostArchitecture());
}
- else
- error.SetErrorStringWithFormat ("Process %" PRIu64 " was reported after connecting to '%s', but no stop reply packet was received", pid, remote_url);
- }
-
- if (log)
- log->Printf ("ProcessGDBRemote::%s pid %" PRIu64 ": normalizing target architecture initial triple: %s (GetTarget().GetArchitecture().IsValid() %s, m_gdb_comm.GetHostArchitecture().IsValid(): %s)", __FUNCTION__, GetID (), GetTarget ().GetArchitecture ().GetTriple ().getTriple ().c_str (), GetTarget ().GetArchitecture ().IsValid () ? "true" : "false", m_gdb_comm.GetHostArchitecture ().IsValid () ? "true" : "false");
-
-
- if (error.Success()
- && !GetTarget().GetArchitecture().IsValid()
- && m_gdb_comm.GetHostArchitecture().IsValid())
- {
- // Prefer the *process'* architecture over that of the *host*, if available.
- if (m_gdb_comm.GetProcessArchitecture().IsValid())
- GetTarget().SetArchitecture(m_gdb_comm.GetProcessArchitecture());
- else
- GetTarget().SetArchitecture(m_gdb_comm.GetHostArchitecture());
- }
-
- if (log)
- log->Printf ("ProcessGDBRemote::%s pid %" PRIu64 ": normalized target architecture triple: %s", __FUNCTION__, GetID (), GetTarget ().GetArchitecture ().GetTriple ().getTriple ().c_str ());
-
- if (error.Success())
- {
- PlatformSP platform_sp = GetTarget().GetPlatform();
- if (platform_sp && platform_sp->IsConnected())
- SetUnixSignals(platform_sp->GetUnixSignals());
- else
- SetUnixSignals(UnixSignals::Create(GetTarget().GetArchitecture()));
- }
+ }
+
+ const StateType state = SetThreadStopInfo(response);
+ if (state != eStateInvalid) {
+ SetPrivateState(state);
+ } else
+ error.SetErrorStringWithFormat(
+ "Process %" PRIu64 " was reported after connecting to "
+ "'%s', but state was not stopped: %s",
+ pid, remote_url.str().c_str(), StateAsCString(state));
+ } else
+ error.SetErrorStringWithFormat("Process %" PRIu64
+ " was reported after connecting to '%s', "
+ "but no stop reply packet was received",
+ pid, remote_url.str().c_str());
+ }
+
+ if (log)
+ log->Printf("ProcessGDBRemote::%s pid %" PRIu64
+ ": normalizing target architecture initial triple: %s "
+ "(GetTarget().GetArchitecture().IsValid() %s, "
+ "m_gdb_comm.GetHostArchitecture().IsValid(): %s)",
+ __FUNCTION__, GetID(),
+ GetTarget().GetArchitecture().GetTriple().getTriple().c_str(),
+ GetTarget().GetArchitecture().IsValid() ? "true" : "false",
+ m_gdb_comm.GetHostArchitecture().IsValid() ? "true" : "false");
+
+ if (error.Success() && !GetTarget().GetArchitecture().IsValid() &&
+ m_gdb_comm.GetHostArchitecture().IsValid()) {
+ // Prefer the *process'* architecture over that of the *host*, if available.
+ if (m_gdb_comm.GetProcessArchitecture().IsValid())
+ GetTarget().SetArchitecture(m_gdb_comm.GetProcessArchitecture());
+ else
+ GetTarget().SetArchitecture(m_gdb_comm.GetHostArchitecture());
+ }
+
+ if (log)
+ log->Printf("ProcessGDBRemote::%s pid %" PRIu64
+ ": normalized target architecture triple: %s",
+ __FUNCTION__, GetID(),
+ GetTarget().GetArchitecture().GetTriple().getTriple().c_str());
+
+ if (error.Success()) {
+ PlatformSP platform_sp = GetTarget().GetPlatform();
+ if (platform_sp && platform_sp->IsConnected())
+ SetUnixSignals(platform_sp->GetUnixSignals());
+ else
+ SetUnixSignals(UnixSignals::Create(GetTarget().GetArchitecture()));
+ }
- return error;
+ return error;
}
-Error
-ProcessGDBRemote::WillLaunchOrAttach ()
-{
- Error error;
- m_stdio_communication.Clear ();
- return error;
+Error ProcessGDBRemote::WillLaunchOrAttach() {
+ Error error;
+ m_stdio_communication.Clear();
+ return error;
}
//----------------------------------------------------------------------
// Process Control
//----------------------------------------------------------------------
-Error
-ProcessGDBRemote::DoLaunch (Module *exe_module, ProcessLaunchInfo &launch_info)
-{
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
- Error error;
-
- if (log)
- log->Printf ("ProcessGDBRemote::%s() entered", __FUNCTION__);
-
- uint32_t launch_flags = launch_info.GetFlags().Get();
- FileSpec stdin_file_spec{};
- FileSpec stdout_file_spec{};
- FileSpec stderr_file_spec{};
- FileSpec working_dir = launch_info.GetWorkingDirectory();
-
- const FileAction *file_action;
- file_action = launch_info.GetFileActionForFD (STDIN_FILENO);
- if (file_action)
- {
- if (file_action->GetAction() == FileAction::eFileActionOpen)
- stdin_file_spec = file_action->GetFileSpec();
- }
- file_action = launch_info.GetFileActionForFD (STDOUT_FILENO);
- if (file_action)
- {
- if (file_action->GetAction() == FileAction::eFileActionOpen)
- stdout_file_spec = file_action->GetFileSpec();
- }
- file_action = launch_info.GetFileActionForFD (STDERR_FILENO);
- if (file_action)
- {
- if (file_action->GetAction() == FileAction::eFileActionOpen)
- stderr_file_spec = file_action->GetFileSpec();
- }
-
- if (log)
- {
- if (stdin_file_spec || stdout_file_spec || stderr_file_spec)
- log->Printf ("ProcessGDBRemote::%s provided with STDIO paths via launch_info: stdin=%s, stdout=%s, stderr=%s",
- __FUNCTION__,
- stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
- stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
- stderr_file_spec ? stderr_file_spec.GetCString() : "<null>");
- else
- log->Printf ("ProcessGDBRemote::%s no STDIO paths given via launch_info", __FUNCTION__);
- }
-
- const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
- if (stdin_file_spec || disable_stdio)
- {
- // the inferior will be reading stdin from the specified file
- // or stdio is completely disabled
- m_stdin_forward = false;
- }
+Error ProcessGDBRemote::DoLaunch(Module *exe_module,
+ ProcessLaunchInfo &launch_info) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ Error error;
+
+ if (log)
+ log->Printf("ProcessGDBRemote::%s() entered", __FUNCTION__);
+
+ uint32_t launch_flags = launch_info.GetFlags().Get();
+ FileSpec stdin_file_spec{};
+ FileSpec stdout_file_spec{};
+ FileSpec stderr_file_spec{};
+ FileSpec working_dir = launch_info.GetWorkingDirectory();
+
+ const FileAction *file_action;
+ file_action = launch_info.GetFileActionForFD(STDIN_FILENO);
+ if (file_action) {
+ if (file_action->GetAction() == FileAction::eFileActionOpen)
+ stdin_file_spec = file_action->GetFileSpec();
+ }
+ file_action = launch_info.GetFileActionForFD(STDOUT_FILENO);
+ if (file_action) {
+ if (file_action->GetAction() == FileAction::eFileActionOpen)
+ stdout_file_spec = file_action->GetFileSpec();
+ }
+ file_action = launch_info.GetFileActionForFD(STDERR_FILENO);
+ if (file_action) {
+ if (file_action->GetAction() == FileAction::eFileActionOpen)
+ stderr_file_spec = file_action->GetFileSpec();
+ }
+
+ if (log) {
+ if (stdin_file_spec || stdout_file_spec || stderr_file_spec)
+ log->Printf("ProcessGDBRemote::%s provided with STDIO paths via "
+ "launch_info: stdin=%s, stdout=%s, stderr=%s",
+ __FUNCTION__,
+ stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
+ stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
+ stderr_file_spec ? stderr_file_spec.GetCString() : "<null>");
else
- {
- m_stdin_forward = true;
- }
-
- // ::LogSetBitMask (GDBR_LOG_DEFAULT);
- // ::LogSetOptions (LLDB_LOG_OPTION_THREADSAFE | LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD);
- // ::LogSetLogFile ("/dev/stdout");
-
- ObjectFile * object_file = exe_module->GetObjectFile();
- if (object_file)
- {
- error = EstablishConnectionIfNeeded (launch_info);
- if (error.Success())
- {
- lldb_utility::PseudoTerminal pty;
- const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
-
- PlatformSP platform_sp (GetTarget().GetPlatform());
- if (disable_stdio)
- {
- // set to /dev/null unless redirected to a file above
- if (!stdin_file_spec)
- stdin_file_spec.SetFile(FileSystem::DEV_NULL, false);
- if (!stdout_file_spec)
- stdout_file_spec.SetFile(FileSystem::DEV_NULL, false);
- if (!stderr_file_spec)
- stderr_file_spec.SetFile(FileSystem::DEV_NULL, false);
- }
- else if (platform_sp && platform_sp->IsHost())
- {
- // If the debugserver is local and we aren't disabling STDIO, lets use
- // a pseudo terminal to instead of relying on the 'O' packets for stdio
- // since 'O' packets can really slow down debugging if the inferior
- // does a lot of output.
- if ((!stdin_file_spec || !stdout_file_spec || !stderr_file_spec) &&
- pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY, NULL, 0))
- {
- FileSpec slave_name{pty.GetSlaveName(NULL, 0), false};
-
- if (!stdin_file_spec)
- stdin_file_spec = slave_name;
-
- if (!stdout_file_spec)
- stdout_file_spec = slave_name;
-
- if (!stderr_file_spec)
- stderr_file_spec = slave_name;
- }
- if (log)
- log->Printf ("ProcessGDBRemote::%s adjusted STDIO paths for local platform (IsHost() is true) using slave: stdin=%s, stdout=%s, stderr=%s",
- __FUNCTION__,
- stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
- stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
- stderr_file_spec ? stderr_file_spec.GetCString() : "<null>");
- }
-
- if (log)
- log->Printf ("ProcessGDBRemote::%s final STDIO paths after all adjustments: stdin=%s, stdout=%s, stderr=%s",
- __FUNCTION__,
- stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
- stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
- stderr_file_spec ? stderr_file_spec.GetCString() : "<null>");
-
- if (stdin_file_spec)
- m_gdb_comm.SetSTDIN(stdin_file_spec);
- if (stdout_file_spec)
- m_gdb_comm.SetSTDOUT(stdout_file_spec);
- if (stderr_file_spec)
- m_gdb_comm.SetSTDERR(stderr_file_spec);
-
- m_gdb_comm.SetDisableASLR (launch_flags & eLaunchFlagDisableASLR);
- m_gdb_comm.SetDetachOnError (launch_flags & eLaunchFlagDetachOnError);
-
- m_gdb_comm.SendLaunchArchPacket (GetTarget().GetArchitecture().GetArchitectureName());
-
- const char * launch_event_data = launch_info.GetLaunchEventData();
- if (launch_event_data != NULL && *launch_event_data != '\0')
- m_gdb_comm.SendLaunchEventDataPacket (launch_event_data);
-
- if (working_dir)
- {
- m_gdb_comm.SetWorkingDir (working_dir);
- }
-
- // Send the environment and the program + arguments after we connect
- const Args &environment = launch_info.GetEnvironmentEntries();
- if (environment.GetArgumentCount())
- {
- size_t num_environment_entries = environment.GetArgumentCount();
- for (size_t i=0; i<num_environment_entries; ++i)
- {
- const char *env_entry = environment.GetArgumentAtIndex(i);
- if (env_entry == NULL || m_gdb_comm.SendEnvironmentPacket(env_entry) != 0)
- break;
- }
- }
-
- {
- // Scope for the scoped timeout object
- GDBRemoteCommunication::ScopedTimeout timeout (m_gdb_comm, 10);
-
- int arg_packet_err = m_gdb_comm.SendArgumentsPacket (launch_info);
- if (arg_packet_err == 0)
- {
- std::string error_str;
- if (m_gdb_comm.GetLaunchSuccess (error_str))
- {
- SetID (m_gdb_comm.GetCurrentProcessID ());
- }
- else
- {
- error.SetErrorString (error_str.c_str());
- }
- }
- else
- {
- error.SetErrorStringWithFormat("'A' packet returned an error: %i", arg_packet_err);
- }
- }
-
- if (GetID() == LLDB_INVALID_PROCESS_ID)
- {
- if (log)
- log->Printf("failed to connect to debugserver: %s", error.AsCString());
- KillDebugserverProcess ();
- return error;
- }
-
- StringExtractorGDBRemote response;
- if (m_gdb_comm.GetStopReply(response))
- {
- SetLastStopPacket(response);
- // '?' Packets must be handled differently in non-stop mode
- if (GetTarget().GetNonStopModeEnabled())
- HandleStopReplySequence();
-
- const ArchSpec &process_arch = m_gdb_comm.GetProcessArchitecture();
-
- if (process_arch.IsValid())
- {
- GetTarget().MergeArchitecture(process_arch);
- }
- else
- {
- const ArchSpec &host_arch = m_gdb_comm.GetHostArchitecture();
- if (host_arch.IsValid())
- GetTarget().MergeArchitecture(host_arch);
- }
-
- SetPrivateState (SetThreadStopInfo (response));
-
- if (!disable_stdio)
- {
- if (pty.GetMasterFileDescriptor() != lldb_utility::PseudoTerminal::invalid_fd)
- SetSTDIOFileDescriptor (pty.ReleaseMasterFileDescriptor());
- }
- }
+ log->Printf("ProcessGDBRemote::%s no STDIO paths given via launch_info",
+ __FUNCTION__);
+ }
+
+ const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
+ if (stdin_file_spec || disable_stdio) {
+ // the inferior will be reading stdin from the specified file
+ // or stdio is completely disabled
+ m_stdin_forward = false;
+ } else {
+ m_stdin_forward = true;
+ }
+
+ // ::LogSetBitMask (GDBR_LOG_DEFAULT);
+ // ::LogSetOptions (LLDB_LOG_OPTION_THREADSAFE |
+ // LLDB_LOG_OPTION_PREPEND_TIMESTAMP |
+ // LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD);
+ // ::LogSetLogFile ("/dev/stdout");
+
+ ObjectFile *object_file = exe_module->GetObjectFile();
+ if (object_file) {
+ error = EstablishConnectionIfNeeded(launch_info);
+ if (error.Success()) {
+ lldb_utility::PseudoTerminal pty;
+ const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
+
+ PlatformSP platform_sp(GetTarget().GetPlatform());
+ if (disable_stdio) {
+ // set to /dev/null unless redirected to a file above
+ if (!stdin_file_spec)
+ stdin_file_spec.SetFile(FileSystem::DEV_NULL, false);
+ if (!stdout_file_spec)
+ stdout_file_spec.SetFile(FileSystem::DEV_NULL, false);
+ if (!stderr_file_spec)
+ stderr_file_spec.SetFile(FileSystem::DEV_NULL, false);
+ } else if (platform_sp && platform_sp->IsHost()) {
+ // If the debugserver is local and we aren't disabling STDIO, lets use
+ // a pseudo terminal to instead of relying on the 'O' packets for stdio
+ // since 'O' packets can really slow down debugging if the inferior
+ // does a lot of output.
+ if ((!stdin_file_spec || !stdout_file_spec || !stderr_file_spec) &&
+ pty.OpenFirstAvailableMaster(O_RDWR | O_NOCTTY, NULL, 0)) {
+ FileSpec slave_name{pty.GetSlaveName(NULL, 0), false};
+
+ if (!stdin_file_spec)
+ stdin_file_spec = slave_name;
+
+ if (!stdout_file_spec)
+ stdout_file_spec = slave_name;
+
+ if (!stderr_file_spec)
+ stderr_file_spec = slave_name;
}
- else
- {
- if (log)
- log->Printf("failed to connect to debugserver: %s", error.AsCString());
+ if (log)
+ log->Printf(
+ "ProcessGDBRemote::%s adjusted STDIO paths for local platform "
+ "(IsHost() is true) using slave: stdin=%s, stdout=%s, stderr=%s",
+ __FUNCTION__,
+ stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
+ stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
+ stderr_file_spec ? stderr_file_spec.GetCString() : "<null>");
+ }
+
+ if (log)
+ log->Printf("ProcessGDBRemote::%s final STDIO paths after all "
+ "adjustments: stdin=%s, stdout=%s, stderr=%s",
+ __FUNCTION__,
+ stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
+ stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
+ stderr_file_spec ? stderr_file_spec.GetCString()
+ : "<null>");
+
+ if (stdin_file_spec)
+ m_gdb_comm.SetSTDIN(stdin_file_spec);
+ if (stdout_file_spec)
+ m_gdb_comm.SetSTDOUT(stdout_file_spec);
+ if (stderr_file_spec)
+ m_gdb_comm.SetSTDERR(stderr_file_spec);
+
+ m_gdb_comm.SetDisableASLR(launch_flags & eLaunchFlagDisableASLR);
+ m_gdb_comm.SetDetachOnError(launch_flags & eLaunchFlagDetachOnError);
+
+ m_gdb_comm.SendLaunchArchPacket(
+ GetTarget().GetArchitecture().GetArchitectureName());
+
+ const char *launch_event_data = launch_info.GetLaunchEventData();
+ if (launch_event_data != NULL && *launch_event_data != '\0')
+ m_gdb_comm.SendLaunchEventDataPacket(launch_event_data);
+
+ if (working_dir) {
+ m_gdb_comm.SetWorkingDir(working_dir);
+ }
+
+ // Send the environment and the program + arguments after we connect
+ const Args &environment = launch_info.GetEnvironmentEntries();
+ if (environment.GetArgumentCount()) {
+ size_t num_environment_entries = environment.GetArgumentCount();
+ for (size_t i = 0; i < num_environment_entries; ++i) {
+ const char *env_entry = environment.GetArgumentAtIndex(i);
+ if (env_entry == NULL ||
+ m_gdb_comm.SendEnvironmentPacket(env_entry) != 0)
+ break;
}
- }
- else
- {
- // Set our user ID to an invalid process ID.
- SetID(LLDB_INVALID_PROCESS_ID);
- error.SetErrorStringWithFormat ("failed to get object file from '%s' for arch %s",
- exe_module->GetFileSpec().GetFilename().AsCString(),
- exe_module->GetArchitecture().GetArchitectureName());
- }
- return error;
-
-}
-
+ }
-Error
-ProcessGDBRemote::ConnectToDebugserver (const char *connect_url)
-{
- Error error;
- // Only connect if we have a valid connect URL
- Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ {
+ // Scope for the scoped timeout object
+ GDBRemoteCommunication::ScopedTimeout timeout(m_gdb_comm,
+ std::chrono::seconds(10));
+
+ int arg_packet_err = m_gdb_comm.SendArgumentsPacket(launch_info);
+ if (arg_packet_err == 0) {
+ std::string error_str;
+ if (m_gdb_comm.GetLaunchSuccess(error_str)) {
+ SetID(m_gdb_comm.GetCurrentProcessID());
+ } else {
+ error.SetErrorString(error_str.c_str());
+ }
+ } else {
+ error.SetErrorStringWithFormat("'A' packet returned an error: %i",
+ arg_packet_err);
+ }
+ }
- if (connect_url && connect_url[0])
- {
+ if (GetID() == LLDB_INVALID_PROCESS_ID) {
if (log)
- log->Printf("ProcessGDBRemote::%s Connecting to %s", __FUNCTION__, connect_url);
- std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
- if (conn_ap.get())
- {
- const uint32_t max_retry_count = 50;
- uint32_t retry_count = 0;
- while (!m_gdb_comm.IsConnected())
- {
- if (conn_ap->Connect(connect_url, &error) == eConnectionStatusSuccess)
- {
- m_gdb_comm.SetConnection (conn_ap.release());
- break;
- }
- else if (error.WasInterrupted())
- {
- // If we were interrupted, don't keep retrying.
- break;
- }
+ log->Printf("failed to connect to debugserver: %s",
+ error.AsCString());
+ KillDebugserverProcess();
+ return error;
+ }
- retry_count++;
+ StringExtractorGDBRemote response;
+ if (m_gdb_comm.GetStopReply(response)) {
+ SetLastStopPacket(response);
+ // '?' Packets must be handled differently in non-stop mode
+ if (GetTarget().GetNonStopModeEnabled())
+ HandleStopReplySequence();
+
+ const ArchSpec &process_arch = m_gdb_comm.GetProcessArchitecture();
+
+ if (process_arch.IsValid()) {
+ GetTarget().MergeArchitecture(process_arch);
+ } else {
+ const ArchSpec &host_arch = m_gdb_comm.GetHostArchitecture();
+ if (host_arch.IsValid())
+ GetTarget().MergeArchitecture(host_arch);
+ }
- if (retry_count >= max_retry_count)
- break;
+ SetPrivateState(SetThreadStopInfo(response));
- usleep (100000);
- }
+ if (!disable_stdio) {
+ if (pty.GetMasterFileDescriptor() !=
+ lldb_utility::PseudoTerminal::invalid_fd)
+ SetSTDIOFileDescriptor(pty.ReleaseMasterFileDescriptor());
}
- }
+ }
+ } else {
+ if (log)
+ log->Printf("failed to connect to debugserver: %s", error.AsCString());
+ }
+ } else {
+ // Set our user ID to an invalid process ID.
+ SetID(LLDB_INVALID_PROCESS_ID);
+ error.SetErrorStringWithFormat(
+ "failed to get object file from '%s' for arch %s",
+ exe_module->GetFileSpec().GetFilename().AsCString(),
+ exe_module->GetArchitecture().GetArchitectureName());
+ }
+ return error;
+}
- if (!m_gdb_comm.IsConnected())
- {
- if (error.Success())
- error.SetErrorString("not connected to remote gdb server");
- return error;
- }
+Error ProcessGDBRemote::ConnectToDebugserver(llvm::StringRef connect_url) {
+ Error error;
+ // Only connect if we have a valid connect URL
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ if (!connect_url.empty()) {
+ if (log)
+ log->Printf("ProcessGDBRemote::%s Connecting to %s", __FUNCTION__,
+ connect_url.str().c_str());
+ std::unique_ptr<ConnectionFileDescriptor> conn_ap(
+ new ConnectionFileDescriptor());
+ if (conn_ap.get()) {
+ const uint32_t max_retry_count = 50;
+ uint32_t retry_count = 0;
+ while (!m_gdb_comm.IsConnected()) {
+ if (conn_ap->Connect(connect_url, &error) == eConnectionStatusSuccess) {
+ m_gdb_comm.SetConnection(conn_ap.release());
+ break;
+ } else if (error.WasInterrupted()) {
+ // If we were interrupted, don't keep retrying.
+ break;
+ }
- // Start the communications read thread so all incoming data can be
- // parsed into packets and queued as they arrive.
- if (GetTarget().GetNonStopModeEnabled())
- m_gdb_comm.StartReadThread();
+ retry_count++;
- // We always seem to be able to open a connection to a local port
- // so we need to make sure we can then send data to it. If we can't
- // then we aren't actually connected to anything, so try and do the
- // handshake with the remote GDB server and make sure that goes
- // alright.
- if (!m_gdb_comm.HandshakeWithServer (&error))
- {
- m_gdb_comm.Disconnect();
- if (error.Success())
- error.SetErrorString("not connected to remote gdb server");
- return error;
+ if (retry_count >= max_retry_count)
+ break;
+
+ usleep(100000);
+ }
}
+ }
- // Send $QNonStop:1 packet on startup if required
- if (GetTarget().GetNonStopModeEnabled())
- GetTarget().SetNonStopModeEnabled (m_gdb_comm.SetNonStopMode(true));
+ if (!m_gdb_comm.IsConnected()) {
+ if (error.Success())
+ error.SetErrorString("not connected to remote gdb server");
+ return error;
+ }
+
+ // Start the communications read thread so all incoming data can be
+ // parsed into packets and queued as they arrive.
+ if (GetTarget().GetNonStopModeEnabled())
+ m_gdb_comm.StartReadThread();
+
+ // We always seem to be able to open a connection to a local port
+ // so we need to make sure we can then send data to it. If we can't
+ // then we aren't actually connected to anything, so try and do the
+ // handshake with the remote GDB server and make sure that goes
+ // alright.
+ if (!m_gdb_comm.HandshakeWithServer(&error)) {
+ m_gdb_comm.Disconnect();
+ if (error.Success())
+ error.SetErrorString("not connected to remote gdb server");
+ return error;
+ }
- m_gdb_comm.GetEchoSupported ();
- m_gdb_comm.GetThreadSuffixSupported ();
- m_gdb_comm.GetListThreadsInStopReplySupported ();
- m_gdb_comm.GetHostInfo ();
- m_gdb_comm.GetVContSupported ('c');
- m_gdb_comm.GetVAttachOrWaitSupported();
+ // Send $QNonStop:1 packet on startup if required
+ if (GetTarget().GetNonStopModeEnabled())
+ GetTarget().SetNonStopModeEnabled(m_gdb_comm.SetNonStopMode(true));
- // Ask the remote server for the default thread id
- if (GetTarget().GetNonStopModeEnabled())
- m_gdb_comm.GetDefaultThreadId(m_initial_tid);
+ m_gdb_comm.GetEchoSupported();
+ m_gdb_comm.GetThreadSuffixSupported();
+ m_gdb_comm.GetListThreadsInStopReplySupported();
+ m_gdb_comm.GetHostInfo();
+ m_gdb_comm.GetVContSupported('c');
+ m_gdb_comm.GetVAttachOrWaitSupported();
+ // Ask the remote server for the default thread id
+ if (GetTarget().GetNonStopModeEnabled())
+ m_gdb_comm.GetDefaultThreadId(m_initial_tid);
- size_t num_cmds = GetExtraStartupCommands().GetArgumentCount();
- for (size_t idx = 0; idx < num_cmds; idx++)
- {
- StringExtractorGDBRemote response;
- m_gdb_comm.SendPacketAndWaitForResponse (GetExtraStartupCommands().GetArgumentAtIndex(idx), response, false);
- }
- return error;
+ size_t num_cmds = GetExtraStartupCommands().GetArgumentCount();
+ for (size_t idx = 0; idx < num_cmds; idx++) {
+ StringExtractorGDBRemote response;
+ m_gdb_comm.SendPacketAndWaitForResponse(
+ GetExtraStartupCommands().GetArgumentAtIndex(idx), response, false);
+ }
+ return error;
}
-void
-ProcessGDBRemote::DidLaunchOrAttach (ArchSpec& process_arch)
-{
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
- if (log)
- log->Printf ("ProcessGDBRemote::DidLaunch()");
- if (GetID() != LLDB_INVALID_PROCESS_ID)
- {
- BuildDynamicRegisterInfo (false);
+void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ if (log)
+ log->Printf("ProcessGDBRemote::%s()", __FUNCTION__);
+ if (GetID() != LLDB_INVALID_PROCESS_ID) {
+ BuildDynamicRegisterInfo(false);
- // See if the GDB server supports the qHostInfo information
+ // See if the GDB server supports the qHostInfo information
+ // See if the GDB server supports the qProcessInfo packet, if so
+ // prefer that over the Host information as it will be more specific
+ // to our process.
- // See if the GDB server supports the qProcessInfo packet, if so
- // prefer that over the Host information as it will be more specific
- // to our process.
+ const ArchSpec &remote_process_arch = m_gdb_comm.GetProcessArchitecture();
+ if (remote_process_arch.IsValid()) {
+ process_arch = remote_process_arch;
+ if (log)
+ log->Printf("ProcessGDBRemote::%s gdb-remote had process architecture, "
+ "using %s %s",
+ __FUNCTION__, process_arch.GetArchitectureName()
+ ? process_arch.GetArchitectureName()
+ : "<null>",
+ process_arch.GetTriple().getTriple().c_str()
+ ? process_arch.GetTriple().getTriple().c_str()
+ : "<null>");
+ } else {
+ process_arch = m_gdb_comm.GetHostArchitecture();
+ if (log)
+ log->Printf("ProcessGDBRemote::%s gdb-remote did not have process "
+ "architecture, using gdb-remote host architecture %s %s",
+ __FUNCTION__, process_arch.GetArchitectureName()
+ ? process_arch.GetArchitectureName()
+ : "<null>",
+ process_arch.GetTriple().getTriple().c_str()
+ ? process_arch.GetTriple().getTriple().c_str()
+ : "<null>");
+ }
+
+ if (process_arch.IsValid()) {
+ const ArchSpec &target_arch = GetTarget().GetArchitecture();
+ if (target_arch.IsValid()) {
+ if (log)
+ log->Printf(
+ "ProcessGDBRemote::%s analyzing target arch, currently %s %s",
+ __FUNCTION__, target_arch.GetArchitectureName()
+ ? target_arch.GetArchitectureName()
+ : "<null>",
+ target_arch.GetTriple().getTriple().c_str()
+ ? target_arch.GetTriple().getTriple().c_str()
+ : "<null>");
+
+ // If the remote host is ARM and we have apple as the vendor, then
+ // ARM executables and shared libraries can have mixed ARM
+ // architectures.
+ // You can have an armv6 executable, and if the host is armv7, then the
+ // system will load the best possible architecture for all shared
+ // libraries
+ // it has, so we really need to take the remote host architecture as our
+ // defacto architecture in this case.
+
+ if ((process_arch.GetMachine() == llvm::Triple::arm ||
+ process_arch.GetMachine() == llvm::Triple::thumb) &&
+ process_arch.GetTriple().getVendor() == llvm::Triple::Apple) {
+ GetTarget().SetArchitecture(process_arch);
+ if (log)
+ log->Printf("ProcessGDBRemote::%s remote process is ARM/Apple, "
+ "setting target arch to %s %s",
+ __FUNCTION__, process_arch.GetArchitectureName()
+ ? process_arch.GetArchitectureName()
+ : "<null>",
+ process_arch.GetTriple().getTriple().c_str()
+ ? process_arch.GetTriple().getTriple().c_str()
+ : "<null>");
+ } else {
+ // Fill in what is missing in the triple
+ const llvm::Triple &remote_triple = process_arch.GetTriple();
+ llvm::Triple new_target_triple = target_arch.GetTriple();
+ if (new_target_triple.getVendorName().size() == 0) {
+ new_target_triple.setVendor(remote_triple.getVendor());
+
+ if (new_target_triple.getOSName().size() == 0) {
+ new_target_triple.setOS(remote_triple.getOS());
+
+ if (new_target_triple.getEnvironmentName().size() == 0)
+ new_target_triple.setEnvironment(
+ remote_triple.getEnvironment());
+ }
- const ArchSpec &remote_process_arch = m_gdb_comm.GetProcessArchitecture();
- if (remote_process_arch.IsValid())
- {
- process_arch = remote_process_arch;
- if (log)
- log->Printf ("ProcessGDBRemote::%s gdb-remote had process architecture, using %s %s",
- __FUNCTION__,
- process_arch.GetArchitectureName () ? process_arch.GetArchitectureName () : "<null>",
- process_arch.GetTriple().getTriple ().c_str() ? process_arch.GetTriple().getTriple ().c_str() : "<null>");
+ ArchSpec new_target_arch = target_arch;
+ new_target_arch.SetTriple(new_target_triple);
+ GetTarget().SetArchitecture(new_target_arch);
+ }
}
- else
- {
- process_arch = m_gdb_comm.GetHostArchitecture();
- if (log)
- log->Printf ("ProcessGDBRemote::%s gdb-remote did not have process architecture, using gdb-remote host architecture %s %s",
- __FUNCTION__,
- process_arch.GetArchitectureName () ? process_arch.GetArchitectureName () : "<null>",
- process_arch.GetTriple().getTriple ().c_str() ? process_arch.GetTriple().getTriple ().c_str() : "<null>");
- }
-
- if (process_arch.IsValid())
- {
- const ArchSpec &target_arch = GetTarget().GetArchitecture();
- if (target_arch.IsValid())
- {
- if (log)
- log->Printf ("ProcessGDBRemote::%s analyzing target arch, currently %s %s",
- __FUNCTION__,
- target_arch.GetArchitectureName () ? target_arch.GetArchitectureName () : "<null>",
- target_arch.GetTriple().getTriple ().c_str() ? target_arch.GetTriple().getTriple ().c_str() : "<null>");
-
- // If the remote host is ARM and we have apple as the vendor, then
- // ARM executables and shared libraries can have mixed ARM architectures.
- // You can have an armv6 executable, and if the host is armv7, then the
- // system will load the best possible architecture for all shared libraries
- // it has, so we really need to take the remote host architecture as our
- // defacto architecture in this case.
-
- if ((process_arch.GetMachine() == llvm::Triple::arm || process_arch.GetMachine() == llvm::Triple::thumb)
- && process_arch.GetTriple().getVendor() == llvm::Triple::Apple)
- {
- GetTarget().SetArchitecture (process_arch);
- if (log)
- log->Printf ("ProcessGDBRemote::%s remote process is ARM/Apple, setting target arch to %s %s",
- __FUNCTION__,
- process_arch.GetArchitectureName () ? process_arch.GetArchitectureName () : "<null>",
- process_arch.GetTriple().getTriple ().c_str() ? process_arch.GetTriple().getTriple ().c_str() : "<null>");
- }
- else
- {
- // Fill in what is missing in the triple
- const llvm::Triple &remote_triple = process_arch.GetTriple();
- llvm::Triple new_target_triple = target_arch.GetTriple();
- if (new_target_triple.getVendorName().size() == 0)
- {
- new_target_triple.setVendor (remote_triple.getVendor());
-
- if (new_target_triple.getOSName().size() == 0)
- {
- new_target_triple.setOS (remote_triple.getOS());
-
- if (new_target_triple.getEnvironmentName().size() == 0)
- new_target_triple.setEnvironment (remote_triple.getEnvironment());
- }
-
- ArchSpec new_target_arch = target_arch;
- new_target_arch.SetTriple(new_target_triple);
- GetTarget().SetArchitecture(new_target_arch);
- }
- }
- if (log)
- log->Printf ("ProcessGDBRemote::%s final target arch after adjustments for remote architecture: %s %s",
- __FUNCTION__,
- target_arch.GetArchitectureName () ? target_arch.GetArchitectureName () : "<null>",
- target_arch.GetTriple().getTriple ().c_str() ? target_arch.GetTriple().getTriple ().c_str() : "<null>");
- }
- else
- {
- // The target doesn't have a valid architecture yet, set it from
- // the architecture we got from the remote GDB server
- GetTarget().SetArchitecture (process_arch);
- }
- }
- }
+ if (log)
+ log->Printf("ProcessGDBRemote::%s final target arch after "
+ "adjustments for remote architecture: %s %s",
+ __FUNCTION__, target_arch.GetArchitectureName()
+ ? target_arch.GetArchitectureName()
+ : "<null>",
+ target_arch.GetTriple().getTriple().c_str()
+ ? target_arch.GetTriple().getTriple().c_str()
+ : "<null>");
+ } else {
+ // The target doesn't have a valid architecture yet, set it from
+ // the architecture we got from the remote GDB server
+ GetTarget().SetArchitecture(process_arch);
+ }
+ }
+
+ // Find out which StructuredDataPlugins are supported by the
+ // debug monitor. These plugins transmit data over async $J packets.
+ auto supported_packets_array =
+ m_gdb_comm.GetSupportedStructuredDataPlugins();
+ if (supported_packets_array)
+ MapSupportedStructuredDataPlugins(*supported_packets_array);
+ }
}
-void
-ProcessGDBRemote::DidLaunch ()
-{
- ArchSpec process_arch;
- DidLaunchOrAttach (process_arch);
+void ProcessGDBRemote::DidLaunch() {
+ ArchSpec process_arch;
+ DidLaunchOrAttach(process_arch);
}
-Error
-ProcessGDBRemote::DoAttachToProcessWithID (lldb::pid_t attach_pid, const ProcessAttachInfo &attach_info)
-{
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
- Error error;
-
- if (log)
- log->Printf ("ProcessGDBRemote::%s()", __FUNCTION__);
-
- // Clear out and clean up from any current state
- Clear();
- if (attach_pid != LLDB_INVALID_PROCESS_ID)
- {
- error = EstablishConnectionIfNeeded (attach_info);
- if (error.Success())
- {
- m_gdb_comm.SetDetachOnError(attach_info.GetDetachOnError());
-
- char packet[64];
- const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%" PRIx64, attach_pid);
- SetID (attach_pid);
- m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (packet, packet_len));
- }
- else
- SetExitStatus (-1, error.AsCString());
- }
-
- return error;
+Error ProcessGDBRemote::DoAttachToProcessWithID(
+ lldb::pid_t attach_pid, const ProcessAttachInfo &attach_info) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ Error error;
+
+ if (log)
+ log->Printf("ProcessGDBRemote::%s()", __FUNCTION__);
+
+ // Clear out and clean up from any current state
+ Clear();
+ if (attach_pid != LLDB_INVALID_PROCESS_ID) {
+ error = EstablishConnectionIfNeeded(attach_info);
+ if (error.Success()) {
+ m_gdb_comm.SetDetachOnError(attach_info.GetDetachOnError());
+
+ char packet[64];
+ const int packet_len =
+ ::snprintf(packet, sizeof(packet), "vAttach;%" PRIx64, attach_pid);
+ SetID(attach_pid);
+ m_async_broadcaster.BroadcastEvent(
+ eBroadcastBitAsyncContinue, new EventDataBytes(packet, packet_len));
+ } else
+ SetExitStatus(-1, error.AsCString());
+ }
+
+ return error;
}
-Error
-ProcessGDBRemote::DoAttachToProcessWithName (const char *process_name, const ProcessAttachInfo &attach_info)
-{
- Error error;
- // Clear out and clean up from any current state
- Clear();
-
- if (process_name && process_name[0])
- {
- error = EstablishConnectionIfNeeded (attach_info);
- if (error.Success())
- {
- StreamString packet;
-
- m_gdb_comm.SetDetachOnError(attach_info.GetDetachOnError());
-
- if (attach_info.GetWaitForLaunch())
- {
- if (!m_gdb_comm.GetVAttachOrWaitSupported())
- {
- packet.PutCString ("vAttachWait");
- }
- else
- {
- if (attach_info.GetIgnoreExisting())
- packet.PutCString("vAttachWait");
- else
- packet.PutCString ("vAttachOrWait");
- }
- }
- else
- packet.PutCString("vAttachName");
- packet.PutChar(';');
- packet.PutBytesAsRawHex8(process_name, strlen(process_name), endian::InlHostByteOrder(), endian::InlHostByteOrder());
-
- m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (packet.GetData(), packet.GetSize()));
-
+Error ProcessGDBRemote::DoAttachToProcessWithName(
+ const char *process_name, const ProcessAttachInfo &attach_info) {
+ Error error;
+ // Clear out and clean up from any current state
+ Clear();
+
+ if (process_name && process_name[0]) {
+ error = EstablishConnectionIfNeeded(attach_info);
+ if (error.Success()) {
+ StreamString packet;
+
+ m_gdb_comm.SetDetachOnError(attach_info.GetDetachOnError());
+
+ if (attach_info.GetWaitForLaunch()) {
+ if (!m_gdb_comm.GetVAttachOrWaitSupported()) {
+ packet.PutCString("vAttachWait");
+ } else {
+ if (attach_info.GetIgnoreExisting())
+ packet.PutCString("vAttachWait");
+ else
+ packet.PutCString("vAttachOrWait");
}
- else
- SetExitStatus (-1, error.AsCString());
- }
- return error;
+ } else
+ packet.PutCString("vAttachName");
+ packet.PutChar(';');
+ packet.PutBytesAsRawHex8(process_name, strlen(process_name),
+ endian::InlHostByteOrder(),
+ endian::InlHostByteOrder());
+
+ m_async_broadcaster.BroadcastEvent(
+ eBroadcastBitAsyncContinue,
+ new EventDataBytes(packet.GetString().data(), packet.GetSize()));
+
+ } else
+ SetExitStatus(-1, error.AsCString());
+ }
+ return error;
}
-void
-ProcessGDBRemote::DidExit ()
-{
- // When we exit, disconnect from the GDB server communications
- m_gdb_comm.Disconnect();
+void ProcessGDBRemote::DidExit() {
+ // When we exit, disconnect from the GDB server communications
+ m_gdb_comm.Disconnect();
}
-void
-ProcessGDBRemote::DidAttach (ArchSpec &process_arch)
-{
- // If you can figure out what the architecture is, fill it in here.
- process_arch.Clear();
- DidLaunchOrAttach (process_arch);
+void ProcessGDBRemote::DidAttach(ArchSpec &process_arch) {
+ // If you can figure out what the architecture is, fill it in here.
+ process_arch.Clear();
+ DidLaunchOrAttach(process_arch);
}
-
-Error
-ProcessGDBRemote::WillResume ()
-{
- m_continue_c_tids.clear();
- m_continue_C_tids.clear();
- m_continue_s_tids.clear();
- m_continue_S_tids.clear();
- m_jstopinfo_sp.reset();
- m_jthreadsinfo_sp.reset();
- return Error();
+Error ProcessGDBRemote::WillResume() {
+ m_continue_c_tids.clear();
+ m_continue_C_tids.clear();
+ m_continue_s_tids.clear();
+ m_continue_S_tids.clear();
+ m_jstopinfo_sp.reset();
+ m_jthreadsinfo_sp.reset();
+ return Error();
}
-Error
-ProcessGDBRemote::DoResume ()
-{
- Error error;
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
- if (log)
- log->Printf ("ProcessGDBRemote::Resume()");
-
- ListenerSP listener_sp (Listener::MakeListener("gdb-remote.resume-packet-sent"));
- if (listener_sp->StartListeningForEvents (&m_gdb_comm, GDBRemoteCommunication::eBroadcastBitRunPacketSent))
- {
- listener_sp->StartListeningForEvents (&m_async_broadcaster, ProcessGDBRemote::eBroadcastBitAsyncThreadDidExit);
-
- const size_t num_threads = GetThreadList().GetSize();
-
- StreamString continue_packet;
- bool continue_packet_error = false;
- if (m_gdb_comm.HasAnyVContSupport ())
- {
- if (!GetTarget().GetNonStopModeEnabled() &&
- (m_continue_c_tids.size() == num_threads ||
- (m_continue_c_tids.empty() &&
- m_continue_C_tids.empty() &&
- m_continue_s_tids.empty() &&
- m_continue_S_tids.empty())))
- {
- // All threads are continuing, just send a "c" packet
- continue_packet.PutCString ("c");
- }
- else
- {
- continue_packet.PutCString ("vCont");
-
- if (!m_continue_c_tids.empty())
- {
- if (m_gdb_comm.GetVContSupported ('c'))
- {
- for (tid_collection::const_iterator t_pos = m_continue_c_tids.begin(), t_end = m_continue_c_tids.end(); t_pos != t_end; ++t_pos)
- continue_packet.Printf(";c:%4.4" PRIx64, *t_pos);
- }
- else
- continue_packet_error = true;
- }
-
- if (!continue_packet_error && !m_continue_C_tids.empty())
- {
- if (m_gdb_comm.GetVContSupported ('C'))
- {
- for (tid_sig_collection::const_iterator s_pos = m_continue_C_tids.begin(), s_end = m_continue_C_tids.end(); s_pos != s_end; ++s_pos)
- continue_packet.Printf(";C%2.2x:%4.4" PRIx64, s_pos->second, s_pos->first);
- }
- else
- continue_packet_error = true;
- }
-
- if (!continue_packet_error && !m_continue_s_tids.empty())
- {
- if (m_gdb_comm.GetVContSupported ('s'))
- {
- for (tid_collection::const_iterator t_pos = m_continue_s_tids.begin(), t_end = m_continue_s_tids.end(); t_pos != t_end; ++t_pos)
- continue_packet.Printf(";s:%4.4" PRIx64, *t_pos);
- }
- else
- continue_packet_error = true;
- }
+Error ProcessGDBRemote::DoResume() {
+ Error error;
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ if (log)
+ log->Printf("ProcessGDBRemote::Resume()");
+
+ ListenerSP listener_sp(
+ Listener::MakeListener("gdb-remote.resume-packet-sent"));
+ if (listener_sp->StartListeningForEvents(
+ &m_gdb_comm, GDBRemoteCommunication::eBroadcastBitRunPacketSent)) {
+ listener_sp->StartListeningForEvents(
+ &m_async_broadcaster,
+ ProcessGDBRemote::eBroadcastBitAsyncThreadDidExit);
+
+ const size_t num_threads = GetThreadList().GetSize();
+
+ StreamString continue_packet;
+ bool continue_packet_error = false;
+ if (m_gdb_comm.HasAnyVContSupport()) {
+ if (!GetTarget().GetNonStopModeEnabled() &&
+ (m_continue_c_tids.size() == num_threads ||
+ (m_continue_c_tids.empty() && m_continue_C_tids.empty() &&
+ m_continue_s_tids.empty() && m_continue_S_tids.empty()))) {
+ // All threads are continuing, just send a "c" packet
+ continue_packet.PutCString("c");
+ } else {
+ continue_packet.PutCString("vCont");
+
+ if (!m_continue_c_tids.empty()) {
+ if (m_gdb_comm.GetVContSupported('c')) {
+ for (tid_collection::const_iterator
+ t_pos = m_continue_c_tids.begin(),
+ t_end = m_continue_c_tids.end();
+ t_pos != t_end; ++t_pos)
+ continue_packet.Printf(";c:%4.4" PRIx64, *t_pos);
+ } else
+ continue_packet_error = true;
+ }
- if (!continue_packet_error && !m_continue_S_tids.empty())
- {
- if (m_gdb_comm.GetVContSupported ('S'))
- {
- for (tid_sig_collection::const_iterator s_pos = m_continue_S_tids.begin(), s_end = m_continue_S_tids.end(); s_pos != s_end; ++s_pos)
- continue_packet.Printf(";S%2.2x:%4.4" PRIx64, s_pos->second, s_pos->first);
- }
- else
- continue_packet_error = true;
- }
+ if (!continue_packet_error && !m_continue_C_tids.empty()) {
+ if (m_gdb_comm.GetVContSupported('C')) {
+ for (tid_sig_collection::const_iterator
+ s_pos = m_continue_C_tids.begin(),
+ s_end = m_continue_C_tids.end();
+ s_pos != s_end; ++s_pos)
+ continue_packet.Printf(";C%2.2x:%4.4" PRIx64, s_pos->second,
+ s_pos->first);
+ } else
+ continue_packet_error = true;
+ }
- if (continue_packet_error)
- continue_packet.GetString().clear();
- }
+ if (!continue_packet_error && !m_continue_s_tids.empty()) {
+ if (m_gdb_comm.GetVContSupported('s')) {
+ for (tid_collection::const_iterator
+ t_pos = m_continue_s_tids.begin(),
+ t_end = m_continue_s_tids.end();
+ t_pos != t_end; ++t_pos)
+ continue_packet.Printf(";s:%4.4" PRIx64, *t_pos);
+ } else
+ continue_packet_error = true;
}
- else
+
+ if (!continue_packet_error && !m_continue_S_tids.empty()) {
+ if (m_gdb_comm.GetVContSupported('S')) {
+ for (tid_sig_collection::const_iterator
+ s_pos = m_continue_S_tids.begin(),
+ s_end = m_continue_S_tids.end();
+ s_pos != s_end; ++s_pos)
+ continue_packet.Printf(";S%2.2x:%4.4" PRIx64, s_pos->second,
+ s_pos->first);
+ } else
continue_packet_error = true;
+ }
if (continue_packet_error)
- {
- // Either no vCont support, or we tried to use part of the vCont
- // packet that wasn't supported by the remote GDB server.
- // We need to try and make a simple packet that can do our continue
- const size_t num_continue_c_tids = m_continue_c_tids.size();
- const size_t num_continue_C_tids = m_continue_C_tids.size();
- const size_t num_continue_s_tids = m_continue_s_tids.size();
- const size_t num_continue_S_tids = m_continue_S_tids.size();
- if (num_continue_c_tids > 0)
- {
- if (num_continue_c_tids == num_threads)
- {
- // All threads are resuming...
- m_gdb_comm.SetCurrentThreadForRun (-1);
- continue_packet.PutChar ('c');
- continue_packet_error = false;
- }
- else if (num_continue_c_tids == 1 &&
- num_continue_C_tids == 0 &&
- num_continue_s_tids == 0 &&
- num_continue_S_tids == 0 )
- {
- // Only one thread is continuing
- m_gdb_comm.SetCurrentThreadForRun (m_continue_c_tids.front());
- continue_packet.PutChar ('c');
- continue_packet_error = false;
- }
+ continue_packet.Clear();
+ }
+ } else
+ continue_packet_error = true;
+
+ if (continue_packet_error) {
+ // Either no vCont support, or we tried to use part of the vCont
+ // packet that wasn't supported by the remote GDB server.
+ // We need to try and make a simple packet that can do our continue
+ const size_t num_continue_c_tids = m_continue_c_tids.size();
+ const size_t num_continue_C_tids = m_continue_C_tids.size();
+ const size_t num_continue_s_tids = m_continue_s_tids.size();
+ const size_t num_continue_S_tids = m_continue_S_tids.size();
+ if (num_continue_c_tids > 0) {
+ if (num_continue_c_tids == num_threads) {
+ // All threads are resuming...
+ m_gdb_comm.SetCurrentThreadForRun(-1);
+ continue_packet.PutChar('c');
+ continue_packet_error = false;
+ } else if (num_continue_c_tids == 1 && num_continue_C_tids == 0 &&
+ num_continue_s_tids == 0 && num_continue_S_tids == 0) {
+ // Only one thread is continuing
+ m_gdb_comm.SetCurrentThreadForRun(m_continue_c_tids.front());
+ continue_packet.PutChar('c');
+ continue_packet_error = false;
+ }
+ }
+
+ if (continue_packet_error && num_continue_C_tids > 0) {
+ if ((num_continue_C_tids + num_continue_c_tids) == num_threads &&
+ num_continue_C_tids > 0 && num_continue_s_tids == 0 &&
+ num_continue_S_tids == 0) {
+ const int continue_signo = m_continue_C_tids.front().second;
+ // Only one thread is continuing
+ if (num_continue_C_tids > 1) {
+ // More that one thread with a signal, yet we don't have
+ // vCont support and we are being asked to resume each
+ // thread with a signal, we need to make sure they are
+ // all the same signal, or we can't issue the continue
+ // accurately with the current support...
+ if (num_continue_C_tids > 1) {
+ continue_packet_error = false;
+ for (size_t i = 1; i < m_continue_C_tids.size(); ++i) {
+ if (m_continue_C_tids[i].second != continue_signo)
+ continue_packet_error = true;
+ }
}
+ if (!continue_packet_error)
+ m_gdb_comm.SetCurrentThreadForRun(-1);
+ } else {
+ // Set the continue thread ID
+ continue_packet_error = false;
+ m_gdb_comm.SetCurrentThreadForRun(m_continue_C_tids.front().first);
+ }
+ if (!continue_packet_error) {
+ // Add threads continuing with the same signo...
+ continue_packet.Printf("C%2.2x", continue_signo);
+ }
+ }
+ }
- if (continue_packet_error && num_continue_C_tids > 0)
- {
- if ((num_continue_C_tids + num_continue_c_tids) == num_threads &&
- num_continue_C_tids > 0 &&
- num_continue_s_tids == 0 &&
- num_continue_S_tids == 0 )
- {
- const int continue_signo = m_continue_C_tids.front().second;
- // Only one thread is continuing
- if (num_continue_C_tids > 1)
- {
- // More that one thread with a signal, yet we don't have
- // vCont support and we are being asked to resume each
- // thread with a signal, we need to make sure they are
- // all the same signal, or we can't issue the continue
- // accurately with the current support...
- if (num_continue_C_tids > 1)
- {
- continue_packet_error = false;
- for (size_t i=1; i<m_continue_C_tids.size(); ++i)
- {
- if (m_continue_C_tids[i].second != continue_signo)
- continue_packet_error = true;
- }
- }
- if (!continue_packet_error)
- m_gdb_comm.SetCurrentThreadForRun (-1);
- }
- else
- {
- // Set the continue thread ID
- continue_packet_error = false;
- m_gdb_comm.SetCurrentThreadForRun (m_continue_C_tids.front().first);
- }
- if (!continue_packet_error)
- {
- // Add threads continuing with the same signo...
- continue_packet.Printf("C%2.2x", continue_signo);
- }
- }
- }
+ if (continue_packet_error && num_continue_s_tids > 0) {
+ if (num_continue_s_tids == num_threads) {
+ // All threads are resuming...
+ m_gdb_comm.SetCurrentThreadForRun(-1);
- if (continue_packet_error && num_continue_s_tids > 0)
- {
- if (num_continue_s_tids == num_threads)
- {
- // All threads are resuming...
- m_gdb_comm.SetCurrentThreadForRun (-1);
-
- // If in Non-Stop-Mode use vCont when stepping
- if (GetTarget().GetNonStopModeEnabled())
- {
- if (m_gdb_comm.GetVContSupported('s'))
- continue_packet.PutCString("vCont;s");
- else
- continue_packet.PutChar('s');
- }
- else
- continue_packet.PutChar('s');
-
- continue_packet_error = false;
- }
- else if (num_continue_c_tids == 0 &&
- num_continue_C_tids == 0 &&
- num_continue_s_tids == 1 &&
- num_continue_S_tids == 0 )
- {
- // Only one thread is stepping
- m_gdb_comm.SetCurrentThreadForRun (m_continue_s_tids.front());
- continue_packet.PutChar ('s');
- continue_packet_error = false;
- }
- }
-
- if (!continue_packet_error && num_continue_S_tids > 0)
- {
- if (num_continue_S_tids == num_threads)
- {
- const int step_signo = m_continue_S_tids.front().second;
- // Are all threads trying to step with the same signal?
- continue_packet_error = false;
- if (num_continue_S_tids > 1)
- {
- for (size_t i=1; i<num_threads; ++i)
- {
- if (m_continue_S_tids[i].second != step_signo)
- continue_packet_error = true;
- }
- }
- if (!continue_packet_error)
- {
- // Add threads stepping with the same signo...
- m_gdb_comm.SetCurrentThreadForRun (-1);
- continue_packet.Printf("S%2.2x", step_signo);
- }
- }
- else if (num_continue_c_tids == 0 &&
- num_continue_C_tids == 0 &&
- num_continue_s_tids == 0 &&
- num_continue_S_tids == 1 )
- {
- // Only one thread is stepping with signal
- m_gdb_comm.SetCurrentThreadForRun (m_continue_S_tids.front().first);
- continue_packet.Printf("S%2.2x", m_continue_S_tids.front().second);
- continue_packet_error = false;
- }
+ // If in Non-Stop-Mode use vCont when stepping
+ if (GetTarget().GetNonStopModeEnabled()) {
+ if (m_gdb_comm.GetVContSupported('s'))
+ continue_packet.PutCString("vCont;s");
+ else
+ continue_packet.PutChar('s');
+ } else
+ continue_packet.PutChar('s');
+
+ continue_packet_error = false;
+ } else if (num_continue_c_tids == 0 && num_continue_C_tids == 0 &&
+ num_continue_s_tids == 1 && num_continue_S_tids == 0) {
+ // Only one thread is stepping
+ m_gdb_comm.SetCurrentThreadForRun(m_continue_s_tids.front());
+ continue_packet.PutChar('s');
+ continue_packet_error = false;
+ }
+ }
+
+ if (!continue_packet_error && num_continue_S_tids > 0) {
+ if (num_continue_S_tids == num_threads) {
+ const int step_signo = m_continue_S_tids.front().second;
+ // Are all threads trying to step with the same signal?
+ continue_packet_error = false;
+ if (num_continue_S_tids > 1) {
+ for (size_t i = 1; i < num_threads; ++i) {
+ if (m_continue_S_tids[i].second != step_signo)
+ continue_packet_error = true;
}
+ }
+ if (!continue_packet_error) {
+ // Add threads stepping with the same signo...
+ m_gdb_comm.SetCurrentThreadForRun(-1);
+ continue_packet.Printf("S%2.2x", step_signo);
+ }
+ } else if (num_continue_c_tids == 0 && num_continue_C_tids == 0 &&
+ num_continue_s_tids == 0 && num_continue_S_tids == 1) {
+ // Only one thread is stepping with signal
+ m_gdb_comm.SetCurrentThreadForRun(m_continue_S_tids.front().first);
+ continue_packet.Printf("S%2.2x", m_continue_S_tids.front().second);
+ continue_packet_error = false;
}
+ }
+ }
- if (continue_packet_error)
- {
- error.SetErrorString ("can't make continue packet for this resume");
- }
- else
- {
- EventSP event_sp;
- TimeValue timeout;
- timeout = TimeValue::Now();
- timeout.OffsetWithSeconds (5);
- if (!m_async_thread.IsJoinable())
- {
- error.SetErrorString ("Trying to resume but the async thread is dead.");
- if (log)
- log->Printf ("ProcessGDBRemote::DoResume: Trying to resume but the async thread is dead.");
- return error;
- }
+ if (continue_packet_error) {
+ error.SetErrorString("can't make continue packet for this resume");
+ } else {
+ EventSP event_sp;
+ if (!m_async_thread.IsJoinable()) {
+ error.SetErrorString("Trying to resume but the async thread is dead.");
+ if (log)
+ log->Printf("ProcessGDBRemote::DoResume: Trying to resume but the "
+ "async thread is dead.");
+ return error;
+ }
- m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (continue_packet.GetData(), continue_packet.GetSize()));
+ m_async_broadcaster.BroadcastEvent(
+ eBroadcastBitAsyncContinue,
+ new EventDataBytes(continue_packet.GetString().data(),
+ continue_packet.GetSize()));
- if (listener_sp->WaitForEvent (&timeout, event_sp) == false)
- {
- error.SetErrorString("Resume timed out.");
- if (log)
- log->Printf ("ProcessGDBRemote::DoResume: Resume timed out.");
- }
- else if (event_sp->BroadcasterIs (&m_async_broadcaster))
- {
- error.SetErrorString ("Broadcast continue, but the async thread was killed before we got an ack back.");
- if (log)
- log->Printf ("ProcessGDBRemote::DoResume: Broadcast continue, but the async thread was killed before we got an ack back.");
- return error;
- }
- }
+ if (listener_sp->GetEvent(event_sp, std::chrono::seconds(5)) == false) {
+ error.SetErrorString("Resume timed out.");
+ if (log)
+ log->Printf("ProcessGDBRemote::DoResume: Resume timed out.");
+ } else if (event_sp->BroadcasterIs(&m_async_broadcaster)) {
+ error.SetErrorString("Broadcast continue, but the async thread was "
+ "killed before we got an ack back.");
+ if (log)
+ log->Printf("ProcessGDBRemote::DoResume: Broadcast continue, but the "
+ "async thread was killed before we got an ack back.");
+ return error;
+ }
}
+ }
- return error;
+ return error;
}
-void
-ProcessGDBRemote::HandleStopReplySequence ()
-{
- while(true)
- {
- // Send vStopped
- StringExtractorGDBRemote response;
- m_gdb_comm.SendPacketAndWaitForResponse("vStopped", response, false);
+void ProcessGDBRemote::HandleStopReplySequence() {
+ while (true) {
+ // Send vStopped
+ StringExtractorGDBRemote response;
+ m_gdb_comm.SendPacketAndWaitForResponse("vStopped", response, false);
- // OK represents end of signal list
- if (response.IsOKResponse())
- break;
+ // OK represents end of signal list
+ if (response.IsOKResponse())
+ break;
- // If not OK or a normal packet we have a problem
- if (!response.IsNormalResponse())
- break;
+ // If not OK or a normal packet we have a problem
+ if (!response.IsNormalResponse())
+ break;
- SetLastStopPacket(response);
- }
+ SetLastStopPacket(response);
+ }
}
-void
-ProcessGDBRemote::ClearThreadIDList ()
-{
- std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());
- m_thread_ids.clear();
- m_thread_pcs.clear();
+void ProcessGDBRemote::ClearThreadIDList() {
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());
+ m_thread_ids.clear();
+ m_thread_pcs.clear();
}
size_t
-ProcessGDBRemote::UpdateThreadIDsFromStopReplyThreadsValue (std::string &value)
-{
- m_thread_ids.clear();
- m_thread_pcs.clear();
- size_t comma_pos;
- lldb::tid_t tid;
- while ((comma_pos = value.find(',')) != std::string::npos)
- {
- value[comma_pos] = '\0';
- // thread in big endian hex
- tid = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16);
- if (tid != LLDB_INVALID_THREAD_ID)
- m_thread_ids.push_back (tid);
- value.erase(0, comma_pos + 1);
- }
- tid = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16);
+ProcessGDBRemote::UpdateThreadIDsFromStopReplyThreadsValue(std::string &value) {
+ m_thread_ids.clear();
+ m_thread_pcs.clear();
+ size_t comma_pos;
+ lldb::tid_t tid;
+ while ((comma_pos = value.find(',')) != std::string::npos) {
+ value[comma_pos] = '\0';
+ // thread in big endian hex
+ tid = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_THREAD_ID, 16);
if (tid != LLDB_INVALID_THREAD_ID)
- m_thread_ids.push_back (tid);
- return m_thread_ids.size();
+ m_thread_ids.push_back(tid);
+ value.erase(0, comma_pos + 1);
+ }
+ tid = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_THREAD_ID, 16);
+ if (tid != LLDB_INVALID_THREAD_ID)
+ m_thread_ids.push_back(tid);
+ return m_thread_ids.size();
}
size_t
-ProcessGDBRemote::UpdateThreadPCsFromStopReplyThreadsValue (std::string &value)
-{
- m_thread_pcs.clear();
- size_t comma_pos;
- lldb::addr_t pc;
- while ((comma_pos = value.find(',')) != std::string::npos)
- {
- value[comma_pos] = '\0';
- pc = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_ADDRESS, 16);
- if (pc != LLDB_INVALID_ADDRESS)
- m_thread_pcs.push_back (pc);
- value.erase(0, comma_pos + 1);
- }
- pc = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_ADDRESS, 16);
- if (pc != LLDB_INVALID_THREAD_ID)
- m_thread_pcs.push_back (pc);
- return m_thread_pcs.size();
+ProcessGDBRemote::UpdateThreadPCsFromStopReplyThreadsValue(std::string &value) {
+ m_thread_pcs.clear();
+ size_t comma_pos;
+ lldb::addr_t pc;
+ while ((comma_pos = value.find(',')) != std::string::npos) {
+ value[comma_pos] = '\0';
+ pc = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_ADDRESS, 16);
+ if (pc != LLDB_INVALID_ADDRESS)
+ m_thread_pcs.push_back(pc);
+ value.erase(0, comma_pos + 1);
+ }
+ pc = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_ADDRESS, 16);
+ if (pc != LLDB_INVALID_THREAD_ID)
+ m_thread_pcs.push_back(pc);
+ return m_thread_pcs.size();
}
-bool
-ProcessGDBRemote::UpdateThreadIDList ()
-{
- std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());
-
- if (m_jthreadsinfo_sp)
- {
- // If we have the JSON threads info, we can get the thread list from that
- StructuredData::Array *thread_infos = m_jthreadsinfo_sp->GetAsArray();
- if (thread_infos && thread_infos->GetSize() > 0)
- {
- m_thread_ids.clear();
- m_thread_pcs.clear();
- thread_infos->ForEach([this](StructuredData::Object* object) -> bool {
- StructuredData::Dictionary *thread_dict = object->GetAsDictionary();
- if (thread_dict)
- {
- // Set the thread stop info from the JSON dictionary
- SetThreadStopInfo (thread_dict);
- lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
- if (thread_dict->GetValueForKeyAsInteger<lldb::tid_t>("tid", tid))
- m_thread_ids.push_back(tid);
- }
- return true; // Keep iterating through all thread_info objects
- });
+bool ProcessGDBRemote::UpdateThreadIDList() {
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());
+
+ if (m_jthreadsinfo_sp) {
+ // If we have the JSON threads info, we can get the thread list from that
+ StructuredData::Array *thread_infos = m_jthreadsinfo_sp->GetAsArray();
+ if (thread_infos && thread_infos->GetSize() > 0) {
+ m_thread_ids.clear();
+ m_thread_pcs.clear();
+ thread_infos->ForEach([this](StructuredData::Object *object) -> bool {
+ StructuredData::Dictionary *thread_dict = object->GetAsDictionary();
+ if (thread_dict) {
+ // Set the thread stop info from the JSON dictionary
+ SetThreadStopInfo(thread_dict);
+ lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
+ if (thread_dict->GetValueForKeyAsInteger<lldb::tid_t>("tid", tid))
+ m_thread_ids.push_back(tid);
+ }
+ return true; // Keep iterating through all thread_info objects
+ });
+ }
+ if (!m_thread_ids.empty())
+ return true;
+ } else {
+ // See if we can get the thread IDs from the current stop reply packets
+ // that might contain a "threads" key/value pair
+
+ // Lock the thread stack while we access it
+ // Mutex::Locker stop_stack_lock(m_last_stop_packet_mutex);
+ std::unique_lock<std::recursive_mutex> stop_stack_lock(
+ m_last_stop_packet_mutex, std::defer_lock);
+ if (stop_stack_lock.try_lock()) {
+ // Get the number of stop packets on the stack
+ int nItems = m_stop_packet_stack.size();
+ // Iterate over them
+ for (int i = 0; i < nItems; i++) {
+ // Get the thread stop info
+ StringExtractorGDBRemote &stop_info = m_stop_packet_stack[i];
+ const std::string &stop_info_str = stop_info.GetStringRef();
+
+ m_thread_pcs.clear();
+ const size_t thread_pcs_pos = stop_info_str.find(";thread-pcs:");
+ if (thread_pcs_pos != std::string::npos) {
+ const size_t start = thread_pcs_pos + strlen(";thread-pcs:");
+ const size_t end = stop_info_str.find(';', start);
+ if (end != std::string::npos) {
+ std::string value = stop_info_str.substr(start, end - start);
+ UpdateThreadPCsFromStopReplyThreadsValue(value);
+ }
}
- if (!m_thread_ids.empty())
- return true;
- }
- else
- {
- // See if we can get the thread IDs from the current stop reply packets
- // that might contain a "threads" key/value pair
-
- // Lock the thread stack while we access it
- //Mutex::Locker stop_stack_lock(m_last_stop_packet_mutex);
- std::unique_lock<std::recursive_mutex> stop_stack_lock(m_last_stop_packet_mutex, std::defer_lock);
- if (stop_stack_lock.try_lock())
- {
- // Get the number of stop packets on the stack
- int nItems = m_stop_packet_stack.size();
- // Iterate over them
- for (int i = 0; i < nItems; i++)
- {
- // Get the thread stop info
- StringExtractorGDBRemote &stop_info = m_stop_packet_stack[i];
- const std::string &stop_info_str = stop_info.GetStringRef();
-
- m_thread_pcs.clear();
- const size_t thread_pcs_pos = stop_info_str.find(";thread-pcs:");
- if (thread_pcs_pos != std::string::npos)
- {
- const size_t start = thread_pcs_pos + strlen(";thread-pcs:");
- const size_t end = stop_info_str.find(';', start);
- if (end != std::string::npos)
- {
- std::string value = stop_info_str.substr(start, end - start);
- UpdateThreadPCsFromStopReplyThreadsValue(value);
- }
- }
- const size_t threads_pos = stop_info_str.find(";threads:");
- if (threads_pos != std::string::npos)
- {
- const size_t start = threads_pos + strlen(";threads:");
- const size_t end = stop_info_str.find(';', start);
- if (end != std::string::npos)
- {
- std::string value = stop_info_str.substr(start, end - start);
- if (UpdateThreadIDsFromStopReplyThreadsValue(value))
- return true;
- }
- }
- }
+ const size_t threads_pos = stop_info_str.find(";threads:");
+ if (threads_pos != std::string::npos) {
+ const size_t start = threads_pos + strlen(";threads:");
+ const size_t end = stop_info_str.find(';', start);
+ if (end != std::string::npos) {
+ std::string value = stop_info_str.substr(start, end - start);
+ if (UpdateThreadIDsFromStopReplyThreadsValue(value))
+ return true;
+ }
}
+ }
}
+ }
- bool sequence_mutex_unavailable = false;
- m_gdb_comm.GetCurrentThreadIDs (m_thread_ids, sequence_mutex_unavailable);
- if (sequence_mutex_unavailable)
- {
- return false; // We just didn't get the list
- }
- return true;
+ bool sequence_mutex_unavailable = false;
+ m_gdb_comm.GetCurrentThreadIDs(m_thread_ids, sequence_mutex_unavailable);
+ if (sequence_mutex_unavailable) {
+ return false; // We just didn't get the list
+ }
+ return true;
}
-bool
-ProcessGDBRemote::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
-{
- // locker will keep a mutex locked until it goes out of scope
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_THREAD));
- if (log && log->GetMask().Test(GDBR_LOG_VERBOSE))
- log->Printf ("ProcessGDBRemote::%s (pid = %" PRIu64 ")", __FUNCTION__, GetID());
-
- size_t num_thread_ids = m_thread_ids.size();
- // The "m_thread_ids" thread ID list should always be updated after each stop
- // reply packet, but in case it isn't, update it here.
- if (num_thread_ids == 0)
- {
- if (!UpdateThreadIDList ())
- return false;
- num_thread_ids = m_thread_ids.size();
- }
-
- ThreadList old_thread_list_copy(old_thread_list);
- if (num_thread_ids > 0)
- {
- for (size_t i=0; i<num_thread_ids; ++i)
- {
- tid_t tid = m_thread_ids[i];
- ThreadSP thread_sp (old_thread_list_copy.RemoveThreadByProtocolID(tid, false));
- if (!thread_sp)
- {
- thread_sp.reset (new ThreadGDBRemote (*this, tid));
- if (log && log->GetMask().Test(GDBR_LOG_VERBOSE))
- log->Printf(
- "ProcessGDBRemote::%s Making new thread: %p for thread ID: 0x%" PRIx64 ".\n",
- __FUNCTION__, static_cast<void*>(thread_sp.get()),
- thread_sp->GetID());
- }
- else
- {
- if (log && log->GetMask().Test(GDBR_LOG_VERBOSE))
- log->Printf(
- "ProcessGDBRemote::%s Found old thread: %p for thread ID: 0x%" PRIx64 ".\n",
- __FUNCTION__, static_cast<void*>(thread_sp.get()),
- thread_sp->GetID());
- }
- // The m_thread_pcs vector has pc values in big-endian order, not target-endian, unlike most
- // of the register read/write packets in gdb-remote protocol.
- // Early in the process startup, we may not yet have set the process ByteOrder so we ignore these;
- // they are a performance improvement over fetching thread register values individually, the
- // method we will fall back to if needed.
- if (m_thread_ids.size() == m_thread_pcs.size() && thread_sp.get() && GetByteOrder() != eByteOrderInvalid)
- {
- ThreadGDBRemote *gdb_thread = static_cast<ThreadGDBRemote *> (thread_sp.get());
- RegisterContextSP reg_ctx_sp (thread_sp->GetRegisterContext());
- if (reg_ctx_sp)
- {
- uint32_t pc_regnum = reg_ctx_sp->ConvertRegisterKindToRegisterNumber
- (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
- if (pc_regnum != LLDB_INVALID_REGNUM)
- {
- gdb_thread->PrivateSetRegisterValue (pc_regnum, m_thread_pcs[i]);
- }
- }
- }
- new_thread_list.AddThreadSortedByIndexID (thread_sp);
+bool ProcessGDBRemote::UpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) {
+ // locker will keep a mutex locked until it goes out of scope
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_THREAD));
+ if (log && log->GetMask().Test(GDBR_LOG_VERBOSE))
+ log->Printf("ProcessGDBRemote::%s (pid = %" PRIu64 ")", __FUNCTION__,
+ GetID());
+
+ size_t num_thread_ids = m_thread_ids.size();
+ // The "m_thread_ids" thread ID list should always be updated after each stop
+ // reply packet, but in case it isn't, update it here.
+ if (num_thread_ids == 0) {
+ if (!UpdateThreadIDList())
+ return false;
+ num_thread_ids = m_thread_ids.size();
+ }
+
+ ThreadList old_thread_list_copy(old_thread_list);
+ if (num_thread_ids > 0) {
+ for (size_t i = 0; i < num_thread_ids; ++i) {
+ tid_t tid = m_thread_ids[i];
+ ThreadSP thread_sp(
+ old_thread_list_copy.RemoveThreadByProtocolID(tid, false));
+ if (!thread_sp) {
+ thread_sp.reset(new ThreadGDBRemote(*this, tid));
+ if (log && log->GetMask().Test(GDBR_LOG_VERBOSE))
+ log->Printf("ProcessGDBRemote::%s Making new thread: %p for thread "
+ "ID: 0x%" PRIx64 ".\n",
+ __FUNCTION__, static_cast<void *>(thread_sp.get()),
+ thread_sp->GetID());
+ } else {
+ if (log && log->GetMask().Test(GDBR_LOG_VERBOSE))
+ log->Printf("ProcessGDBRemote::%s Found old thread: %p for thread "
+ "ID: 0x%" PRIx64 ".\n",
+ __FUNCTION__, static_cast<void *>(thread_sp.get()),
+ thread_sp->GetID());
+ }
+ // The m_thread_pcs vector has pc values in big-endian order, not
+ // target-endian, unlike most
+ // of the register read/write packets in gdb-remote protocol.
+ // Early in the process startup, we may not yet have set the process
+ // ByteOrder so we ignore these;
+ // they are a performance improvement over fetching thread register values
+ // individually, the
+ // method we will fall back to if needed.
+ if (m_thread_ids.size() == m_thread_pcs.size() && thread_sp.get() &&
+ GetByteOrder() != eByteOrderInvalid) {
+ ThreadGDBRemote *gdb_thread =
+ static_cast<ThreadGDBRemote *>(thread_sp.get());
+ RegisterContextSP reg_ctx_sp(thread_sp->GetRegisterContext());
+ if (reg_ctx_sp) {
+ uint32_t pc_regnum = reg_ctx_sp->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+ if (pc_regnum != LLDB_INVALID_REGNUM) {
+ gdb_thread->PrivateSetRegisterValue(pc_regnum, m_thread_pcs[i]);
+ }
}
+ }
+ new_thread_list.AddThreadSortedByIndexID(thread_sp);
}
+ }
- // Whatever that is left in old_thread_list_copy are not
- // present in new_thread_list. Remove non-existent threads from internal id table.
- size_t old_num_thread_ids = old_thread_list_copy.GetSize(false);
- for (size_t i=0; i<old_num_thread_ids; i++)
- {
- ThreadSP old_thread_sp(old_thread_list_copy.GetThreadAtIndex (i, false));
- if (old_thread_sp)
- {
- lldb::tid_t old_thread_id = old_thread_sp->GetProtocolID();
- m_thread_id_to_index_id_map.erase(old_thread_id);
- }
+ // Whatever that is left in old_thread_list_copy are not
+ // present in new_thread_list. Remove non-existent threads from internal id
+ // table.
+ size_t old_num_thread_ids = old_thread_list_copy.GetSize(false);
+ for (size_t i = 0; i < old_num_thread_ids; i++) {
+ ThreadSP old_thread_sp(old_thread_list_copy.GetThreadAtIndex(i, false));
+ if (old_thread_sp) {
+ lldb::tid_t old_thread_id = old_thread_sp->GetProtocolID();
+ m_thread_id_to_index_id_map.erase(old_thread_id);
}
+ }
- return true;
+ return true;
}
-
-bool
-ProcessGDBRemote::GetThreadStopInfoFromJSON (ThreadGDBRemote *thread, const StructuredData::ObjectSP &thread_infos_sp)
-{
- // See if we got thread stop infos for all threads via the "jThreadsInfo" packet
- if (thread_infos_sp)
- {
- StructuredData::Array *thread_infos = thread_infos_sp->GetAsArray();
- if (thread_infos)
- {
- lldb::tid_t tid;
- const size_t n = thread_infos->GetSize();
- for (size_t i=0; i<n; ++i)
- {
- StructuredData::Dictionary *thread_dict = thread_infos->GetItemAtIndex(i)->GetAsDictionary();
- if (thread_dict)
- {
- if (thread_dict->GetValueForKeyAsInteger<lldb::tid_t>("tid", tid, LLDB_INVALID_THREAD_ID))
- {
- if (tid == thread->GetID())
- return (bool)SetThreadStopInfo(thread_dict);
- }
- }
- }
+bool ProcessGDBRemote::GetThreadStopInfoFromJSON(
+ ThreadGDBRemote *thread, const StructuredData::ObjectSP &thread_infos_sp) {
+ // See if we got thread stop infos for all threads via the "jThreadsInfo"
+ // packet
+ if (thread_infos_sp) {
+ StructuredData::Array *thread_infos = thread_infos_sp->GetAsArray();
+ if (thread_infos) {
+ lldb::tid_t tid;
+ const size_t n = thread_infos->GetSize();
+ for (size_t i = 0; i < n; ++i) {
+ StructuredData::Dictionary *thread_dict =
+ thread_infos->GetItemAtIndex(i)->GetAsDictionary();
+ if (thread_dict) {
+ if (thread_dict->GetValueForKeyAsInteger<lldb::tid_t>(
+ "tid", tid, LLDB_INVALID_THREAD_ID)) {
+ if (tid == thread->GetID())
+ return (bool)SetThreadStopInfo(thread_dict);
+ }
}
+ }
}
- return false;
+ }
+ return false;
}
-bool
-ProcessGDBRemote::CalculateThreadStopInfo (ThreadGDBRemote *thread)
-{
- // See if we got thread stop infos for all threads via the "jThreadsInfo" packet
- if (GetThreadStopInfoFromJSON (thread, m_jthreadsinfo_sp))
- return true;
+bool ProcessGDBRemote::CalculateThreadStopInfo(ThreadGDBRemote *thread) {
+ // See if we got thread stop infos for all threads via the "jThreadsInfo"
+ // packet
+ if (GetThreadStopInfoFromJSON(thread, m_jthreadsinfo_sp))
+ return true;
- // See if we got thread stop info for any threads valid stop info reasons threads
- // via the "jstopinfo" packet stop reply packet key/value pair?
- if (m_jstopinfo_sp)
- {
- // If we have "jstopinfo" then we have stop descriptions for all threads
- // that have stop reasons, and if there is no entry for a thread, then
- // it has no stop reason.
- thread->GetRegisterContext()->InvalidateIfNeeded(true);
- if (!GetThreadStopInfoFromJSON (thread, m_jstopinfo_sp))
- {
- thread->SetStopInfo (StopInfoSP());
- }
- return true;
+ // See if we got thread stop info for any threads valid stop info reasons
+ // threads
+ // via the "jstopinfo" packet stop reply packet key/value pair?
+ if (m_jstopinfo_sp) {
+ // If we have "jstopinfo" then we have stop descriptions for all threads
+ // that have stop reasons, and if there is no entry for a thread, then
+ // it has no stop reason.
+ thread->GetRegisterContext()->InvalidateIfNeeded(true);
+ if (!GetThreadStopInfoFromJSON(thread, m_jstopinfo_sp)) {
+ thread->SetStopInfo(StopInfoSP());
}
+ return true;
+ }
- // Fall back to using the qThreadStopInfo packet
- StringExtractorGDBRemote stop_packet;
- if (GetGDBRemote().GetThreadStopInfo(thread->GetProtocolID(), stop_packet))
- return SetThreadStopInfo (stop_packet) == eStateStopped;
- return false;
+ // Fall back to using the qThreadStopInfo packet
+ StringExtractorGDBRemote stop_packet;
+ if (GetGDBRemote().GetThreadStopInfo(thread->GetProtocolID(), stop_packet))
+ return SetThreadStopInfo(stop_packet) == eStateStopped;
+ return false;
}
-
-ThreadSP
-ProcessGDBRemote::SetThreadStopInfo (lldb::tid_t tid,
- ExpeditedRegisterMap &expedited_register_map,
- uint8_t signo,
- const std::string &thread_name,
- const std::string &reason,
- const std::string &description,
- uint32_t exc_type,
- const std::vector<addr_t> &exc_data,
- addr_t thread_dispatch_qaddr,
- bool queue_vars_valid, // Set to true if queue_name, queue_kind and queue_serial are valid
- LazyBool associated_with_dispatch_queue,
- addr_t dispatch_queue_t,
- std::string &queue_name,
- QueueKind queue_kind,
- uint64_t queue_serial)
-{
- ThreadSP thread_sp;
- if (tid != LLDB_INVALID_THREAD_ID)
- {
- // Scope for "locker" below
- {
- // m_thread_list_real does have its own mutex, but we need to
- // hold onto the mutex between the call to m_thread_list_real.FindThreadByID(...)
- // and the m_thread_list_real.AddThread(...) so it doesn't change on us
- std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());
- thread_sp = m_thread_list_real.FindThreadByProtocolID(tid, false);
-
- if (!thread_sp)
- {
- // Create the thread if we need to
- thread_sp.reset (new ThreadGDBRemote (*this, tid));
- m_thread_list_real.AddThread(thread_sp);
+ThreadSP ProcessGDBRemote::SetThreadStopInfo(
+ lldb::tid_t tid, ExpeditedRegisterMap &expedited_register_map,
+ uint8_t signo, const std::string &thread_name, const std::string &reason,
+ const std::string &description, uint32_t exc_type,
+ const std::vector<addr_t> &exc_data, addr_t thread_dispatch_qaddr,
+ bool queue_vars_valid, // Set to true if queue_name, queue_kind and
+ // queue_serial are valid
+ LazyBool associated_with_dispatch_queue, addr_t dispatch_queue_t,
+ std::string &queue_name, QueueKind queue_kind, uint64_t queue_serial) {
+ ThreadSP thread_sp;
+ if (tid != LLDB_INVALID_THREAD_ID) {
+ // Scope for "locker" below
+ {
+ // m_thread_list_real does have its own mutex, but we need to
+ // hold onto the mutex between the call to
+ // m_thread_list_real.FindThreadByID(...)
+ // and the m_thread_list_real.AddThread(...) so it doesn't change on us
+ std::lock_guard<std::recursive_mutex> guard(
+ m_thread_list_real.GetMutex());
+ thread_sp = m_thread_list_real.FindThreadByProtocolID(tid, false);
+
+ if (!thread_sp) {
+ // Create the thread if we need to
+ thread_sp.reset(new ThreadGDBRemote(*this, tid));
+ m_thread_list_real.AddThread(thread_sp);
+ }
+ }
+
+ if (thread_sp) {
+ ThreadGDBRemote *gdb_thread =
+ static_cast<ThreadGDBRemote *>(thread_sp.get());
+ gdb_thread->GetRegisterContext()->InvalidateIfNeeded(true);
+
+ for (const auto &pair : expedited_register_map) {
+ StringExtractor reg_value_extractor;
+ reg_value_extractor.GetStringRef() = pair.second;
+ DataBufferSP buffer_sp(new DataBufferHeap(
+ reg_value_extractor.GetStringRef().size() / 2, 0));
+ reg_value_extractor.GetHexBytes(buffer_sp->GetData(), '\xcc');
+ gdb_thread->PrivateSetRegisterValue(pair.first, buffer_sp->GetData());
+ }
+
+ thread_sp->SetName(thread_name.empty() ? NULL : thread_name.c_str());
+
+ gdb_thread->SetThreadDispatchQAddr(thread_dispatch_qaddr);
+ // Check if the GDB server was able to provide the queue name, kind and
+ // serial number
+ if (queue_vars_valid)
+ gdb_thread->SetQueueInfo(std::move(queue_name), queue_kind,
+ queue_serial, dispatch_queue_t,
+ associated_with_dispatch_queue);
+ else
+ gdb_thread->ClearQueueInfo();
+
+ gdb_thread->SetAssociatedWithLibdispatchQueue(
+ associated_with_dispatch_queue);
+
+ if (dispatch_queue_t != LLDB_INVALID_ADDRESS)
+ gdb_thread->SetQueueLibdispatchQueueAddress(dispatch_queue_t);
+
+ // Make sure we update our thread stop reason just once
+ if (!thread_sp->StopInfoIsUpToDate()) {
+ thread_sp->SetStopInfo(StopInfoSP());
+ // If there's a memory thread backed by this thread, we need to use it
+ // to calcualte StopInfo.
+ ThreadSP memory_thread_sp =
+ m_thread_list.FindThreadByProtocolID(thread_sp->GetProtocolID());
+ if (memory_thread_sp)
+ thread_sp = memory_thread_sp;
+
+ if (exc_type != 0) {
+ const size_t exc_data_size = exc_data.size();
+
+ thread_sp->SetStopInfo(
+ StopInfoMachException::CreateStopReasonWithMachException(
+ *thread_sp, exc_type, exc_data_size,
+ exc_data_size >= 1 ? exc_data[0] : 0,
+ exc_data_size >= 2 ? exc_data[1] : 0,
+ exc_data_size >= 3 ? exc_data[2] : 0));
+ } else {
+ bool handled = false;
+ bool did_exec = false;
+ if (!reason.empty()) {
+ if (reason.compare("trace") == 0) {
+ addr_t pc = thread_sp->GetRegisterContext()->GetPC();
+ lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess()
+ ->GetBreakpointSiteList()
+ .FindByAddress(pc);
+
+ // If the current pc is a breakpoint site then the StopInfo should
+ // be set to Breakpoint
+ // Otherwise, it will be set to Trace.
+ if (bp_site_sp &&
+ bp_site_sp->ValidForThisThread(thread_sp.get())) {
+ thread_sp->SetStopInfo(
+ StopInfo::CreateStopReasonWithBreakpointSiteID(
+ *thread_sp, bp_site_sp->GetID()));
+ } else
+ thread_sp->SetStopInfo(
+ StopInfo::CreateStopReasonToTrace(*thread_sp));
+ handled = true;
+ } else if (reason.compare("breakpoint") == 0) {
+ addr_t pc = thread_sp->GetRegisterContext()->GetPC();
+ lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess()
+ ->GetBreakpointSiteList()
+ .FindByAddress(pc);
+ if (bp_site_sp) {
+ // If the breakpoint is for this thread, then we'll report the
+ // hit, but if it is for another thread,
+ // we can just report no 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.
+ handled = true;
+ if (bp_site_sp->ValidForThisThread(thread_sp.get())) {
+ thread_sp->SetStopInfo(
+ StopInfo::CreateStopReasonWithBreakpointSiteID(
+ *thread_sp, bp_site_sp->GetID()));
+ } else {
+ StopInfoSP invalid_stop_info_sp;
+ thread_sp->SetStopInfo(invalid_stop_info_sp);
+ }
+ }
+ } else if (reason.compare("trap") == 0) {
+ // Let the trap just use the standard signal stop reason below...
+ } else if (reason.compare("watchpoint") == 0) {
+ StringExtractor desc_extractor(description.c_str());
+ addr_t wp_addr = desc_extractor.GetU64(LLDB_INVALID_ADDRESS);
+ uint32_t wp_index = desc_extractor.GetU32(LLDB_INVALID_INDEX32);
+ addr_t wp_hit_addr = desc_extractor.GetU64(LLDB_INVALID_ADDRESS);
+ watch_id_t watch_id = LLDB_INVALID_WATCH_ID;
+ if (wp_addr != LLDB_INVALID_ADDRESS) {
+ WatchpointSP wp_sp;
+ ArchSpec::Core core = GetTarget().GetArchitecture().GetCore();
+ if ((core >= ArchSpec::kCore_mips_first &&
+ core <= ArchSpec::kCore_mips_last) ||
+ (core >= ArchSpec::eCore_arm_generic &&
+ core <= ArchSpec::eCore_arm_aarch64))
+ wp_sp = GetTarget().GetWatchpointList().FindByAddress(
+ wp_hit_addr);
+ if (!wp_sp)
+ wp_sp =
+ GetTarget().GetWatchpointList().FindByAddress(wp_addr);
+ if (wp_sp) {
+ wp_sp->SetHardwareIndex(wp_index);
+ watch_id = wp_sp->GetID();
+ }
+ }
+ if (watch_id == LLDB_INVALID_WATCH_ID) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(
+ GDBR_LOG_WATCHPOINTS));
+ if (log)
+ log->Printf("failed to find watchpoint");
+ }
+ thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithWatchpointID(
+ *thread_sp, watch_id, wp_hit_addr));
+ handled = true;
+ } else if (reason.compare("exception") == 0) {
+ thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithException(
+ *thread_sp, description.c_str()));
+ handled = true;
+ } else if (reason.compare("exec") == 0) {
+ did_exec = true;
+ thread_sp->SetStopInfo(
+ StopInfo::CreateStopReasonWithExec(*thread_sp));
+ handled = true;
}
- }
-
- if (thread_sp)
- {
- ThreadGDBRemote *gdb_thread = static_cast<ThreadGDBRemote *> (thread_sp.get());
- gdb_thread->GetRegisterContext()->InvalidateIfNeeded(true);
-
- for (const auto &pair : expedited_register_map)
- {
- StringExtractor reg_value_extractor;
- reg_value_extractor.GetStringRef() = pair.second;
- gdb_thread->PrivateSetRegisterValue (pair.first, reg_value_extractor);
+ } else if (!signo) {
+ addr_t pc = thread_sp->GetRegisterContext()->GetPC();
+ lldb::BreakpointSiteSP bp_site_sp =
+ thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(
+ pc);
+
+ // If the current pc is a breakpoint site then the StopInfo should
+ // be set to Breakpoint
+ // even though the remote stub did not set it as such. This can
+ // happen when
+ // the thread is involuntarily interrupted (e.g. due to stops on
+ // other
+ // threads) just as it is about to execute the breakpoint
+ // instruction.
+ if (bp_site_sp && bp_site_sp->ValidForThisThread(thread_sp.get())) {
+ thread_sp->SetStopInfo(
+ StopInfo::CreateStopReasonWithBreakpointSiteID(
+ *thread_sp, bp_site_sp->GetID()));
+ handled = true;
}
-
- thread_sp->SetName (thread_name.empty() ? NULL : thread_name.c_str());
-
- gdb_thread->SetThreadDispatchQAddr (thread_dispatch_qaddr);
- // Check if the GDB server was able to provide the queue name, kind and serial number
- if (queue_vars_valid)
- gdb_thread->SetQueueInfo(std::move(queue_name), queue_kind, queue_serial, dispatch_queue_t, associated_with_dispatch_queue);
- else
- gdb_thread->ClearQueueInfo();
-
- gdb_thread->SetAssociatedWithLibdispatchQueue (associated_with_dispatch_queue);
-
- if (dispatch_queue_t != LLDB_INVALID_ADDRESS)
- gdb_thread->SetQueueLibdispatchQueueAddress (dispatch_queue_t);
-
- // Make sure we update our thread stop reason just once
- if (!thread_sp->StopInfoIsUpToDate())
- {
- thread_sp->SetStopInfo (StopInfoSP());
- // If there's a memory thread backed by this thread, we need to use it to calcualte StopInfo.
- ThreadSP memory_thread_sp = m_thread_list.FindThreadByProtocolID(thread_sp->GetProtocolID());
- if (memory_thread_sp)
- thread_sp = memory_thread_sp;
-
- if (exc_type != 0)
- {
- const size_t exc_data_size = exc_data.size();
-
- thread_sp->SetStopInfo (StopInfoMachException::CreateStopReasonWithMachException (*thread_sp,
- exc_type,
- exc_data_size,
- exc_data_size >= 1 ? exc_data[0] : 0,
- exc_data_size >= 2 ? exc_data[1] : 0,
- exc_data_size >= 3 ? exc_data[2] : 0));
+ }
+
+ if (!handled && signo && did_exec == false) {
+ if (signo == SIGTRAP) {
+ // Currently we are going to assume SIGTRAP means we are either
+ // hitting a breakpoint or hardware single stepping.
+ handled = true;
+ addr_t pc = thread_sp->GetRegisterContext()->GetPC() +
+ m_breakpoint_pc_offset;
+ lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess()
+ ->GetBreakpointSiteList()
+ .FindByAddress(pc);
+
+ if (bp_site_sp) {
+ // If the breakpoint is for this thread, then we'll report the
+ // hit, but if it is for another thread,
+ // we can just report no 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_sp->ValidForThisThread(thread_sp.get())) {
+ if (m_breakpoint_pc_offset != 0)
+ thread_sp->GetRegisterContext()->SetPC(pc);
+ thread_sp->SetStopInfo(
+ StopInfo::CreateStopReasonWithBreakpointSiteID(
+ *thread_sp, bp_site_sp->GetID()));
+ } else {
+ StopInfoSP invalid_stop_info_sp;
+ thread_sp->SetStopInfo(invalid_stop_info_sp);
}
+ } else {
+ // If we were stepping then assume the stop was the result of
+ // the trace. If we were
+ // not stepping then report the SIGTRAP.
+ // FIXME: We are still missing the case where we single step
+ // over a trap instruction.
+ if (thread_sp->GetTemporaryResumeState() == eStateStepping)
+ thread_sp->SetStopInfo(
+ StopInfo::CreateStopReasonToTrace(*thread_sp));
else
- {
- bool handled = false;
- bool did_exec = false;
- if (!reason.empty())
- {
- if (reason.compare("trace") == 0)
- {
- addr_t pc = thread_sp->GetRegisterContext()->GetPC();
- lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
-
- // If the current pc is a breakpoint site then the StopInfo should be set to Breakpoint
- // Otherwise, it will be set to Trace.
- if (bp_site_sp && bp_site_sp->ValidForThisThread(thread_sp.get()))
- {
- thread_sp->SetStopInfo(
- StopInfo::CreateStopReasonWithBreakpointSiteID(*thread_sp, bp_site_sp->GetID()));
- }
- else
- thread_sp->SetStopInfo (StopInfo::CreateStopReasonToTrace (*thread_sp));
- handled = true;
- }
- else if (reason.compare("breakpoint") == 0)
- {
- addr_t pc = thread_sp->GetRegisterContext()->GetPC();
- lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
- if (bp_site_sp)
- {
- // If the breakpoint is for this thread, then we'll report the hit, but if it is for another thread,
- // we can just report no 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.
- handled = true;
- if (bp_site_sp->ValidForThisThread (thread_sp.get()))
- {
- thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID (*thread_sp, bp_site_sp->GetID()));
- }
- else
- {
- StopInfoSP invalid_stop_info_sp;
- thread_sp->SetStopInfo (invalid_stop_info_sp);
- }
- }
- }
- else if (reason.compare("trap") == 0)
- {
- // Let the trap just use the standard signal stop reason below...
- }
- else if (reason.compare("watchpoint") == 0)
- {
- StringExtractor desc_extractor(description.c_str());
- addr_t wp_addr = desc_extractor.GetU64(LLDB_INVALID_ADDRESS);
- uint32_t wp_index = desc_extractor.GetU32(LLDB_INVALID_INDEX32);
- addr_t wp_hit_addr = desc_extractor.GetU64(LLDB_INVALID_ADDRESS);
- watch_id_t watch_id = LLDB_INVALID_WATCH_ID;
- if (wp_addr != LLDB_INVALID_ADDRESS)
- {
- WatchpointSP wp_sp;
- ArchSpec::Core core = GetTarget().GetArchitecture().GetCore();
- if ((core >= ArchSpec::kCore_mips_first && core <= ArchSpec::kCore_mips_last) ||
- (core >= ArchSpec::eCore_arm_generic && core <= ArchSpec::eCore_arm_aarch64))
- wp_sp = GetTarget().GetWatchpointList().FindByAddress(wp_hit_addr);
- if (!wp_sp)
- wp_sp = GetTarget().GetWatchpointList().FindByAddress(wp_addr);
- if (wp_sp)
- {
- wp_sp->SetHardwareIndex(wp_index);
- watch_id = wp_sp->GetID();
- }
- }
- if (watch_id == LLDB_INVALID_WATCH_ID)
- {
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_WATCHPOINTS));
- if (log) log->Printf ("failed to find watchpoint");
- }
- thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithWatchpointID (*thread_sp, watch_id, wp_hit_addr));
- handled = true;
- }
- else if (reason.compare("exception") == 0)
- {
- thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithException(*thread_sp, description.c_str()));
- handled = true;
- }
- else if (reason.compare("exec") == 0)
- {
- did_exec = true;
- thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithExec(*thread_sp));
- handled = true;
- }
- }
- else if (!signo)
- {
- addr_t pc = thread_sp->GetRegisterContext()->GetPC();
- lldb::BreakpointSiteSP bp_site_sp =
- thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
-
- // If the current pc is a breakpoint site then the StopInfo should be set to Breakpoint
- // even though the remote stub did not set it as such. This can happen when
- // the thread is involuntarily interrupted (e.g. due to stops on other
- // threads) just as it is about to execute the breakpoint instruction.
- if (bp_site_sp && bp_site_sp->ValidForThisThread(thread_sp.get()))
- {
- thread_sp->SetStopInfo(
- StopInfo::CreateStopReasonWithBreakpointSiteID(*thread_sp, bp_site_sp->GetID()));
- handled = true;
- }
- }
-
- if (!handled && signo && did_exec == false)
- {
- if (signo == SIGTRAP)
- {
- // Currently we are going to assume SIGTRAP means we are either
- // hitting a breakpoint or hardware single stepping.
- handled = true;
- addr_t pc = thread_sp->GetRegisterContext()->GetPC() + m_breakpoint_pc_offset;
- lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
-
- if (bp_site_sp)
- {
- // If the breakpoint is for this thread, then we'll report the hit, but if it is for another thread,
- // we can just report no 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_sp->ValidForThisThread (thread_sp.get()))
- {
- if(m_breakpoint_pc_offset != 0)
- thread_sp->GetRegisterContext()->SetPC(pc);
- thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID (*thread_sp, bp_site_sp->GetID()));
- }
- else
- {
- StopInfoSP invalid_stop_info_sp;
- thread_sp->SetStopInfo (invalid_stop_info_sp);
- }
- }
- else
- {
- // If we were stepping then assume the stop was the result of the trace. If we were
- // not stepping then report the SIGTRAP.
- // FIXME: We are still missing the case where we single step over a trap instruction.
- if (thread_sp->GetTemporaryResumeState() == eStateStepping)
- thread_sp->SetStopInfo (StopInfo::CreateStopReasonToTrace (*thread_sp));
- else
- thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithSignal(*thread_sp, signo, description.c_str()));
- }
- }
- if (!handled)
- thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithSignal (*thread_sp, signo, description.c_str()));
- }
-
- if (!description.empty())
- {
- lldb::StopInfoSP stop_info_sp (thread_sp->GetStopInfo ());
- if (stop_info_sp)
- {
- const char *stop_info_desc = stop_info_sp->GetDescription();
- if (!stop_info_desc || !stop_info_desc[0])
- stop_info_sp->SetDescription (description.c_str());
- }
- else
- {
- thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithException (*thread_sp, description.c_str()));
- }
- }
- }
+ thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithSignal(
+ *thread_sp, signo, description.c_str()));
+ }
}
+ if (!handled)
+ thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithSignal(
+ *thread_sp, signo, description.c_str()));
+ }
+
+ if (!description.empty()) {
+ lldb::StopInfoSP stop_info_sp(thread_sp->GetStopInfo());
+ if (stop_info_sp) {
+ const char *stop_info_desc = stop_info_sp->GetDescription();
+ if (!stop_info_desc || !stop_info_desc[0])
+ stop_info_sp->SetDescription(description.c_str());
+ } else {
+ thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithException(
+ *thread_sp, description.c_str()));
+ }
+ }
}
+ }
}
- return thread_sp;
+ }
+ return thread_sp;
}
lldb::ThreadSP
-ProcessGDBRemote::SetThreadStopInfo (StructuredData::Dictionary *thread_dict)
-{
- static ConstString g_key_tid("tid");
- static ConstString g_key_name("name");
- static ConstString g_key_reason("reason");
- static ConstString g_key_metype("metype");
- static ConstString g_key_medata("medata");
- static ConstString g_key_qaddr("qaddr");
- static ConstString g_key_dispatch_queue_t("dispatch_queue_t");
- static ConstString g_key_associated_with_dispatch_queue("associated_with_dispatch_queue");
- static ConstString g_key_queue_name("qname");
- static ConstString g_key_queue_kind("qkind");
- static ConstString g_key_queue_serial_number("qserialnum");
- static ConstString g_key_registers("registers");
- static ConstString g_key_memory("memory");
- static ConstString g_key_address("address");
- static ConstString g_key_bytes("bytes");
- static ConstString g_key_description("description");
- static ConstString g_key_signal("signal");
+ProcessGDBRemote::SetThreadStopInfo(StructuredData::Dictionary *thread_dict) {
+ static ConstString g_key_tid("tid");
+ static ConstString g_key_name("name");
+ static ConstString g_key_reason("reason");
+ static ConstString g_key_metype("metype");
+ static ConstString g_key_medata("medata");
+ static ConstString g_key_qaddr("qaddr");
+ static ConstString g_key_dispatch_queue_t("dispatch_queue_t");
+ static ConstString g_key_associated_with_dispatch_queue(
+ "associated_with_dispatch_queue");
+ static ConstString g_key_queue_name("qname");
+ static ConstString g_key_queue_kind("qkind");
+ static ConstString g_key_queue_serial_number("qserialnum");
+ static ConstString g_key_registers("registers");
+ static ConstString g_key_memory("memory");
+ static ConstString g_key_address("address");
+ static ConstString g_key_bytes("bytes");
+ static ConstString g_key_description("description");
+ static ConstString g_key_signal("signal");
+
+ // Stop with signal and thread info
+ lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
+ uint8_t signo = 0;
+ std::string value;
+ std::string thread_name;
+ std::string reason;
+ std::string description;
+ uint32_t exc_type = 0;
+ std::vector<addr_t> exc_data;
+ addr_t thread_dispatch_qaddr = LLDB_INVALID_ADDRESS;
+ ExpeditedRegisterMap expedited_register_map;
+ bool queue_vars_valid = false;
+ addr_t dispatch_queue_t = LLDB_INVALID_ADDRESS;
+ LazyBool associated_with_dispatch_queue = eLazyBoolCalculate;
+ std::string queue_name;
+ QueueKind queue_kind = eQueueKindUnknown;
+ uint64_t queue_serial_number = 0;
+ // Iterate through all of the thread dictionary key/value pairs from the
+ // structured data dictionary
+
+ thread_dict->ForEach([this, &tid, &expedited_register_map, &thread_name,
+ &signo, &reason, &description, &exc_type, &exc_data,
+ &thread_dispatch_qaddr, &queue_vars_valid,
+ &associated_with_dispatch_queue, &dispatch_queue_t,
+ &queue_name, &queue_kind, &queue_serial_number](
+ ConstString key,
+ StructuredData::Object *object) -> bool {
+ if (key == g_key_tid) {
+ // thread in big endian hex
+ tid = object->GetIntegerValue(LLDB_INVALID_THREAD_ID);
+ } else if (key == g_key_metype) {
+ // exception type in big endian hex
+ exc_type = object->GetIntegerValue(0);
+ } else if (key == g_key_medata) {
+ // exception data in big endian hex
+ StructuredData::Array *array = object->GetAsArray();
+ if (array) {
+ array->ForEach([&exc_data](StructuredData::Object *object) -> bool {
+ exc_data.push_back(object->GetIntegerValue());
+ return true; // Keep iterating through all array items
+ });
+ }
+ } else if (key == g_key_name) {
+ thread_name = object->GetStringValue();
+ } else if (key == g_key_qaddr) {
+ thread_dispatch_qaddr = object->GetIntegerValue(LLDB_INVALID_ADDRESS);
+ } else if (key == g_key_queue_name) {
+ queue_vars_valid = true;
+ queue_name = object->GetStringValue();
+ } else if (key == g_key_queue_kind) {
+ std::string queue_kind_str = object->GetStringValue();
+ if (queue_kind_str == "serial") {
+ queue_vars_valid = true;
+ queue_kind = eQueueKindSerial;
+ } else if (queue_kind_str == "concurrent") {
+ queue_vars_valid = true;
+ queue_kind = eQueueKindConcurrent;
+ }
+ } else if (key == g_key_queue_serial_number) {
+ queue_serial_number = object->GetIntegerValue(0);
+ if (queue_serial_number != 0)
+ queue_vars_valid = true;
+ } else if (key == g_key_dispatch_queue_t) {
+ dispatch_queue_t = object->GetIntegerValue(0);
+ if (dispatch_queue_t != 0 && dispatch_queue_t != LLDB_INVALID_ADDRESS)
+ queue_vars_valid = true;
+ } else if (key == g_key_associated_with_dispatch_queue) {
+ queue_vars_valid = true;
+ bool associated = object->GetBooleanValue();
+ if (associated)
+ associated_with_dispatch_queue = eLazyBoolYes;
+ else
+ associated_with_dispatch_queue = eLazyBoolNo;
+ } else if (key == g_key_reason) {
+ reason = object->GetStringValue();
+ } else if (key == g_key_description) {
+ description = object->GetStringValue();
+ } else if (key == g_key_registers) {
+ StructuredData::Dictionary *registers_dict = object->GetAsDictionary();
+
+ if (registers_dict) {
+ registers_dict->ForEach(
+ [&expedited_register_map](ConstString key,
+ StructuredData::Object *object) -> bool {
+ const uint32_t reg =
+ StringConvert::ToUInt32(key.GetCString(), UINT32_MAX, 10);
+ if (reg != UINT32_MAX)
+ expedited_register_map[reg] = object->GetStringValue();
+ return true; // Keep iterating through all array items
+ });
+ }
+ } else if (key == g_key_memory) {
+ StructuredData::Array *array = object->GetAsArray();
+ if (array) {
+ array->ForEach([this](StructuredData::Object *object) -> bool {
+ StructuredData::Dictionary *mem_cache_dict =
+ object->GetAsDictionary();
+ if (mem_cache_dict) {
+ lldb::addr_t mem_cache_addr = LLDB_INVALID_ADDRESS;
+ if (mem_cache_dict->GetValueForKeyAsInteger<lldb::addr_t>(
+ "address", mem_cache_addr)) {
+ if (mem_cache_addr != LLDB_INVALID_ADDRESS) {
+ StringExtractor bytes;
+ if (mem_cache_dict->GetValueForKeyAsString(
+ "bytes", bytes.GetStringRef())) {
+ bytes.SetFilePos(0);
+
+ const size_t byte_size = bytes.GetStringRef().size() / 2;
+ DataBufferSP data_buffer_sp(new DataBufferHeap(byte_size, 0));
+ const size_t bytes_copied =
+ bytes.GetHexBytes(data_buffer_sp->GetData(), 0);
+ if (bytes_copied == byte_size)
+ m_memory_cache.AddL1CacheData(mem_cache_addr,
+ data_buffer_sp);
+ }
+ }
+ }
+ }
+ return true; // Keep iterating through all array items
+ });
+ }
+
+ } else if (key == g_key_signal)
+ signo = object->GetIntegerValue(LLDB_INVALID_SIGNAL_NUMBER);
+ return true; // Keep iterating through all dictionary key/value pairs
+ });
+
+ return SetThreadStopInfo(tid, expedited_register_map, signo, thread_name,
+ reason, description, exc_type, exc_data,
+ thread_dispatch_qaddr, queue_vars_valid,
+ associated_with_dispatch_queue, dispatch_queue_t,
+ queue_name, queue_kind, queue_serial_number);
+}
+StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {
+ stop_packet.SetFilePos(0);
+ const char stop_type = stop_packet.GetChar();
+ switch (stop_type) {
+ case 'T':
+ case 'S': {
+ // This is a bit of a hack, but is is required. If we did exec, we
+ // need to clear our thread lists and also know to rebuild our dynamic
+ // register info before we lookup and threads and populate the expedited
+ // register values so we need to know this right away so we can cleanup
+ // and update our registers.
+ const uint32_t stop_id = GetStopID();
+ if (stop_id == 0) {
+ // Our first stop, make sure we have a process ID, and also make
+ // sure we know about our registers
+ if (GetID() == LLDB_INVALID_PROCESS_ID) {
+ lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID();
+ if (pid != LLDB_INVALID_PROCESS_ID)
+ SetID(pid);
+ }
+ BuildDynamicRegisterInfo(true);
+ }
// Stop with signal and thread info
lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
- uint8_t signo = 0;
- std::string value;
+ const uint8_t signo = stop_packet.GetHexU8();
+ llvm::StringRef key;
+ llvm::StringRef value;
std::string thread_name;
std::string reason;
std::string description;
uint32_t exc_type = 0;
std::vector<addr_t> exc_data;
addr_t thread_dispatch_qaddr = LLDB_INVALID_ADDRESS;
- ExpeditedRegisterMap expedited_register_map;
- bool queue_vars_valid = false;
+ bool queue_vars_valid =
+ false; // says if locals below that start with "queue_" are valid
addr_t dispatch_queue_t = LLDB_INVALID_ADDRESS;
LazyBool associated_with_dispatch_queue = eLazyBoolCalculate;
std::string queue_name;
QueueKind queue_kind = eQueueKindUnknown;
uint64_t queue_serial_number = 0;
- // Iterate through all of the thread dictionary key/value pairs from the structured data dictionary
-
- thread_dict->ForEach([this,
- &tid,
- &expedited_register_map,
- &thread_name,
- &signo,
- &reason,
- &description,
- &exc_type,
- &exc_data,
- &thread_dispatch_qaddr,
- &queue_vars_valid,
- &associated_with_dispatch_queue,
- &dispatch_queue_t,
- &queue_name,
- &queue_kind,
- &queue_serial_number]
- (ConstString key, StructuredData::Object* object) -> bool
- {
- if (key == g_key_tid)
- {
- // thread in big endian hex
- tid = object->GetIntegerValue(LLDB_INVALID_THREAD_ID);
- }
- else if (key == g_key_metype)
- {
- // exception type in big endian hex
- exc_type = object->GetIntegerValue(0);
- }
- else if (key == g_key_medata)
- {
- // exception data in big endian hex
- StructuredData::Array *array = object->GetAsArray();
- if (array)
- {
- array->ForEach([&exc_data](StructuredData::Object* object) -> bool {
- exc_data.push_back(object->GetIntegerValue());
- return true; // Keep iterating through all array items
- });
- }
- }
- else if (key == g_key_name)
- {
- thread_name = object->GetStringValue();
- }
- else if (key == g_key_qaddr)
- {
- thread_dispatch_qaddr = object->GetIntegerValue(LLDB_INVALID_ADDRESS);
- }
- else if (key == g_key_queue_name)
- {
- queue_vars_valid = true;
- queue_name = object->GetStringValue();
- }
- else if (key == g_key_queue_kind)
- {
- std::string queue_kind_str = object->GetStringValue();
- if (queue_kind_str == "serial")
- {
- queue_vars_valid = true;
- queue_kind = eQueueKindSerial;
- }
- else if (queue_kind_str == "concurrent")
- {
- queue_vars_valid = true;
- queue_kind = eQueueKindConcurrent;
- }
- }
- else if (key == g_key_queue_serial_number)
- {
- queue_serial_number = object->GetIntegerValue(0);
- if (queue_serial_number != 0)
- queue_vars_valid = true;
- }
- else if (key == g_key_dispatch_queue_t)
- {
- dispatch_queue_t = object->GetIntegerValue(0);
- if (dispatch_queue_t != 0 && dispatch_queue_t != LLDB_INVALID_ADDRESS)
- queue_vars_valid = true;
- }
- else if (key == g_key_associated_with_dispatch_queue)
- {
- queue_vars_valid = true;
- bool associated = object->GetBooleanValue ();
- if (associated)
- associated_with_dispatch_queue = eLazyBoolYes;
- else
- associated_with_dispatch_queue = eLazyBoolNo;
- }
- else if (key == g_key_reason)
- {
- reason = object->GetStringValue();
- }
- else if (key == g_key_description)
- {
- description = object->GetStringValue();
+ ExpeditedRegisterMap expedited_register_map;
+ while (stop_packet.GetNameColonValue(key, value)) {
+ if (key.compare("metype") == 0) {
+ // exception type in big endian hex
+ value.getAsInteger(16, exc_type);
+ } else if (key.compare("medata") == 0) {
+ // exception data in big endian hex
+ uint64_t x;
+ value.getAsInteger(16, x);
+ exc_data.push_back(x);
+ } else if (key.compare("thread") == 0) {
+ // thread in big endian hex
+ if (value.getAsInteger(16, tid))
+ tid = LLDB_INVALID_THREAD_ID;
+ } else if (key.compare("threads") == 0) {
+ std::lock_guard<std::recursive_mutex> guard(
+ m_thread_list_real.GetMutex());
+
+ m_thread_ids.clear();
+ // A comma separated list of all threads in the current
+ // process that includes the thread for this stop reply
+ // packet
+ lldb::tid_t tid;
+ while (!value.empty()) {
+ llvm::StringRef tid_str;
+ std::tie(tid_str, value) = value.split(',');
+ if (tid_str.getAsInteger(16, tid))
+ tid = LLDB_INVALID_THREAD_ID;
+ m_thread_ids.push_back(tid);
}
- else if (key == g_key_registers)
- {
- StructuredData::Dictionary *registers_dict = object->GetAsDictionary();
-
- if (registers_dict)
- {
- registers_dict->ForEach([&expedited_register_map](ConstString key, StructuredData::Object* object) -> bool {
- const uint32_t reg = StringConvert::ToUInt32 (key.GetCString(), UINT32_MAX, 10);
- if (reg != UINT32_MAX)
- expedited_register_map[reg] = object->GetStringValue();
- return true; // Keep iterating through all array items
- });
- }
+ } else if (key.compare("thread-pcs") == 0) {
+ m_thread_pcs.clear();
+ // A comma separated list of all threads in the current
+ // process that includes the thread for this stop reply
+ // packet
+ lldb::addr_t pc;
+ while (!value.empty()) {
+ llvm::StringRef pc_str;
+ std::tie(pc_str, value) = value.split(',');
+ if (pc_str.getAsInteger(16, pc))
+ pc = LLDB_INVALID_ADDRESS;
+ m_thread_pcs.push_back(pc);
}
- else if (key == g_key_memory)
- {
- StructuredData::Array *array = object->GetAsArray();
- if (array)
- {
- array->ForEach([this](StructuredData::Object* object) -> bool {
- StructuredData::Dictionary *mem_cache_dict = object->GetAsDictionary();
- if (mem_cache_dict)
- {
- lldb::addr_t mem_cache_addr = LLDB_INVALID_ADDRESS;
- if (mem_cache_dict->GetValueForKeyAsInteger<lldb::addr_t>("address", mem_cache_addr))
- {
- if (mem_cache_addr != LLDB_INVALID_ADDRESS)
- {
- StringExtractor bytes;
- if (mem_cache_dict->GetValueForKeyAsString("bytes", bytes.GetStringRef()))
- {
- bytes.SetFilePos(0);
-
- const size_t byte_size = bytes.GetStringRef().size()/2;
- DataBufferSP data_buffer_sp(new DataBufferHeap(byte_size, 0));
- const size_t bytes_copied = bytes.GetHexBytes (data_buffer_sp->GetBytes(), byte_size, 0);
- if (bytes_copied == byte_size)
- m_memory_cache.AddL1CacheData(mem_cache_addr, data_buffer_sp);
- }
- }
- }
- }
- return true; // Keep iterating through all array items
- });
- }
-
+ } else if (key.compare("jstopinfo") == 0) {
+ StringExtractor json_extractor(value);
+ std::string json;
+ // Now convert the HEX bytes into a string value
+ json_extractor.GetHexByteString(json);
+
+ // This JSON contains thread IDs and thread stop info for all threads.
+ // It doesn't contain expedited registers, memory or queue info.
+ m_jstopinfo_sp = StructuredData::ParseJSON(json);
+ } else if (key.compare("hexname") == 0) {
+ StringExtractor name_extractor(value);
+ std::string name;
+ // Now convert the HEX bytes into a string value
+ name_extractor.GetHexByteString(thread_name);
+ } else if (key.compare("name") == 0) {
+ thread_name = value;
+ } else if (key.compare("qaddr") == 0) {
+ value.getAsInteger(16, thread_dispatch_qaddr);
+ } else if (key.compare("dispatch_queue_t") == 0) {
+ queue_vars_valid = true;
+ value.getAsInteger(16, dispatch_queue_t);
+ } else if (key.compare("qname") == 0) {
+ queue_vars_valid = true;
+ StringExtractor name_extractor(value);
+ // Now convert the HEX bytes into a string value
+ name_extractor.GetHexByteString(queue_name);
+ } else if (key.compare("qkind") == 0) {
+ queue_kind = llvm::StringSwitch<QueueKind>(value)
+ .Case("serial", eQueueKindSerial)
+ .Case("concurrent", eQueueKindConcurrent)
+ .Default(eQueueKindUnknown);
+ queue_vars_valid = queue_kind != eQueueKindUnknown;
+ } else if (key.compare("qserialnum") == 0) {
+ if (!value.getAsInteger(0, queue_serial_number))
+ queue_vars_valid = true;
+ } else if (key.compare("reason") == 0) {
+ reason = value;
+ } else if (key.compare("description") == 0) {
+ StringExtractor desc_extractor(value);
+ // Now convert the HEX bytes into a string value
+ desc_extractor.GetHexByteString(description);
+ } else if (key.compare("memory") == 0) {
+ // Expedited memory. GDB servers can choose to send back expedited
+ // memory
+ // that can populate the L1 memory cache in the process so that things
+ // like
+ // the frame pointer backchain can be expedited. This will help stack
+ // backtracing be more efficient by not having to send as many memory
+ // read
+ // requests down the remote GDB server.
+
+ // Key/value pair format: memory:<addr>=<bytes>;
+ // <addr> is a number whose base will be interpreted by the prefix:
+ // "0x[0-9a-fA-F]+" for hex
+ // "0[0-7]+" for octal
+ // "[1-9]+" for decimal
+ // <bytes> is native endian ASCII hex bytes just like the register
+ // values
+ llvm::StringRef addr_str, bytes_str;
+ std::tie(addr_str, bytes_str) = value.split('=');
+ if (!addr_str.empty() && !bytes_str.empty()) {
+ lldb::addr_t mem_cache_addr = LLDB_INVALID_ADDRESS;
+ if (!addr_str.getAsInteger(0, mem_cache_addr)) {
+ StringExtractor bytes(bytes_str);
+ const size_t byte_size = bytes.GetBytesLeft() / 2;
+ DataBufferSP data_buffer_sp(new DataBufferHeap(byte_size, 0));
+ const size_t bytes_copied =
+ bytes.GetHexBytes(data_buffer_sp->GetData(), 0);
+ if (bytes_copied == byte_size)
+ m_memory_cache.AddL1CacheData(mem_cache_addr, data_buffer_sp);
+ }
}
- else if (key == g_key_signal)
- signo = object->GetIntegerValue(LLDB_INVALID_SIGNAL_NUMBER);
- return true; // Keep iterating through all dictionary key/value pairs
- });
-
- return SetThreadStopInfo (tid,
- expedited_register_map,
- signo,
- thread_name,
- reason,
- description,
- exc_type,
- exc_data,
- thread_dispatch_qaddr,
- queue_vars_valid,
- associated_with_dispatch_queue,
- dispatch_queue_t,
- queue_name,
- queue_kind,
- queue_serial_number);
+ } else if (key.compare("watch") == 0 || key.compare("rwatch") == 0 ||
+ key.compare("awatch") == 0) {
+ // Support standard GDB remote stop reply packet 'TAAwatch:addr'
+ lldb::addr_t wp_addr = LLDB_INVALID_ADDRESS;
+ value.getAsInteger(16, wp_addr);
+
+ WatchpointSP wp_sp =
+ GetTarget().GetWatchpointList().FindByAddress(wp_addr);
+ uint32_t wp_index = LLDB_INVALID_INDEX32;
+
+ if (wp_sp)
+ wp_index = wp_sp->GetHardwareIndex();
+
+ reason = "watchpoint";
+ StreamString ostr;
+ ostr.Printf("%" PRIu64 " %" PRIu32, wp_addr, wp_index);
+ description = ostr.GetString();
+ } else if (key.compare("library") == 0) {
+ LoadModules();
+ } else if (key.size() == 2 && ::isxdigit(key[0]) && ::isxdigit(key[1])) {
+ uint32_t reg = UINT32_MAX;
+ if (!key.getAsInteger(16, reg))
+ expedited_register_map[reg] = std::move(value);
+ }
+ }
+
+ if (tid == LLDB_INVALID_THREAD_ID) {
+ // A thread id may be invalid if the response is old style 'S' packet
+ // which does not provide the
+ // thread information. So update the thread list and choose the first one.
+ UpdateThreadIDList();
+
+ if (!m_thread_ids.empty()) {
+ tid = m_thread_ids.front();
+ }
+ }
+
+ ThreadSP thread_sp = SetThreadStopInfo(
+ tid, expedited_register_map, signo, thread_name, reason, description,
+ exc_type, exc_data, thread_dispatch_qaddr, queue_vars_valid,
+ associated_with_dispatch_queue, dispatch_queue_t, queue_name,
+ queue_kind, queue_serial_number);
+
+ return eStateStopped;
+ } break;
+
+ case 'W':
+ case 'X':
+ // process exited
+ return eStateExited;
+
+ default:
+ break;
+ }
+ return eStateInvalid;
}
-StateType
-ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
-{
- stop_packet.SetFilePos (0);
- const char stop_type = stop_packet.GetChar();
- switch (stop_type)
- {
- case 'T':
- case 'S':
- {
- // This is a bit of a hack, but is is required. If we did exec, we
- // need to clear our thread lists and also know to rebuild our dynamic
- // register info before we lookup and threads and populate the expedited
- // register values so we need to know this right away so we can cleanup
- // and update our registers.
- const uint32_t stop_id = GetStopID();
- if (stop_id == 0)
- {
- // Our first stop, make sure we have a process ID, and also make
- // sure we know about our registers
- if (GetID() == LLDB_INVALID_PROCESS_ID)
- {
- lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID ();
- if (pid != LLDB_INVALID_PROCESS_ID)
- SetID (pid);
- }
- BuildDynamicRegisterInfo (true);
- }
- // Stop with signal and thread info
- lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
- const uint8_t signo = stop_packet.GetHexU8();
- std::string key;
- std::string value;
- std::string thread_name;
- std::string reason;
- std::string description;
- uint32_t exc_type = 0;
- std::vector<addr_t> exc_data;
- addr_t thread_dispatch_qaddr = LLDB_INVALID_ADDRESS;
- bool queue_vars_valid = false; // says if locals below that start with "queue_" are valid
- addr_t dispatch_queue_t = LLDB_INVALID_ADDRESS;
- LazyBool associated_with_dispatch_queue = eLazyBoolCalculate;
- std::string queue_name;
- QueueKind queue_kind = eQueueKindUnknown;
- uint64_t queue_serial_number = 0;
- ExpeditedRegisterMap expedited_register_map;
- while (stop_packet.GetNameColonValue(key, value))
- {
- if (key.compare("metype") == 0)
- {
- // exception type in big endian hex
- exc_type = StringConvert::ToUInt32 (value.c_str(), 0, 16);
- }
- else if (key.compare("medata") == 0)
- {
- // exception data in big endian hex
- exc_data.push_back(StringConvert::ToUInt64 (value.c_str(), 0, 16));
- }
- else if (key.compare("thread") == 0)
- {
- // thread in big endian hex
- tid = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16);
- }
- else if (key.compare("threads") == 0)
- {
- std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());
-
- m_thread_ids.clear();
- // A comma separated list of all threads in the current
- // process that includes the thread for this stop reply
- // packet
- size_t comma_pos;
- lldb::tid_t tid;
- while ((comma_pos = value.find(',')) != std::string::npos)
- {
- value[comma_pos] = '\0';
- // thread in big endian hex
- tid = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16);
- if (tid != LLDB_INVALID_THREAD_ID)
- m_thread_ids.push_back (tid);
- value.erase(0, comma_pos + 1);
- }
- tid = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16);
- if (tid != LLDB_INVALID_THREAD_ID)
- m_thread_ids.push_back (tid);
- }
- else if (key.compare("thread-pcs") == 0)
- {
- m_thread_pcs.clear();
- // A comma separated list of all threads in the current
- // process that includes the thread for this stop reply
- // packet
- size_t comma_pos;
- lldb::addr_t pc;
- while ((comma_pos = value.find(',')) != std::string::npos)
- {
- value[comma_pos] = '\0';
- // thread in big endian hex
- pc = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_ADDRESS, 16);
- if (pc != LLDB_INVALID_ADDRESS)
- m_thread_pcs.push_back (pc);
- value.erase(0, comma_pos + 1);
- }
- pc = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_ADDRESS, 16);
- if (pc != LLDB_INVALID_ADDRESS)
- m_thread_pcs.push_back (pc);
- }
- else if (key.compare("jstopinfo") == 0)
- {
- StringExtractor json_extractor;
- // Swap "value" over into "name_extractor"
- json_extractor.GetStringRef().swap(value);
- // Now convert the HEX bytes into a string value
- json_extractor.GetHexByteString (value);
-
- // This JSON contains thread IDs and thread stop info for all threads.
- // It doesn't contain expedited registers, memory or queue info.
- m_jstopinfo_sp = StructuredData::ParseJSON (value);
- }
- else if (key.compare("hexname") == 0)
- {
- StringExtractor name_extractor;
- // Swap "value" over into "name_extractor"
- name_extractor.GetStringRef().swap(value);
- // Now convert the HEX bytes into a string value
- name_extractor.GetHexByteString (value);
- thread_name.swap (value);
- }
- else if (key.compare("name") == 0)
- {
- thread_name.swap (value);
- }
- else if (key.compare("qaddr") == 0)
- {
- thread_dispatch_qaddr = StringConvert::ToUInt64 (value.c_str(), 0, 16);
- }
- else if (key.compare("dispatch_queue_t") == 0)
- {
- queue_vars_valid = true;
- dispatch_queue_t = StringConvert::ToUInt64 (value.c_str(), 0, 16);
- }
- else if (key.compare("qname") == 0)
- {
- queue_vars_valid = true;
- StringExtractor name_extractor;
- // Swap "value" over into "name_extractor"
- name_extractor.GetStringRef().swap(value);
- // Now convert the HEX bytes into a string value
- name_extractor.GetHexByteString (value);
- queue_name.swap (value);
- }
- else if (key.compare("qkind") == 0)
- {
- if (value == "serial")
- {
- queue_vars_valid = true;
- queue_kind = eQueueKindSerial;
- }
- else if (value == "concurrent")
- {
- queue_vars_valid = true;
- queue_kind = eQueueKindConcurrent;
- }
- }
- else if (key.compare("qserialnum") == 0)
- {
- queue_serial_number = StringConvert::ToUInt64 (value.c_str(), 0, 0);
- if (queue_serial_number != 0)
- queue_vars_valid = true;
- }
- else if (key.compare("reason") == 0)
- {
- reason.swap(value);
- }
- else if (key.compare("description") == 0)
- {
- StringExtractor desc_extractor;
- // Swap "value" over into "name_extractor"
- desc_extractor.GetStringRef().swap(value);
- // Now convert the HEX bytes into a string value
- desc_extractor.GetHexByteString (value);
- description.swap(value);
- }
- else if (key.compare("memory") == 0)
- {
- // Expedited memory. GDB servers can choose to send back expedited memory
- // that can populate the L1 memory cache in the process so that things like
- // the frame pointer backchain can be expedited. This will help stack
- // backtracing be more efficient by not having to send as many memory read
- // requests down the remote GDB server.
-
- // Key/value pair format: memory:<addr>=<bytes>;
- // <addr> is a number whose base will be interpreted by the prefix:
- // "0x[0-9a-fA-F]+" for hex
- // "0[0-7]+" for octal
- // "[1-9]+" for decimal
- // <bytes> is native endian ASCII hex bytes just like the register values
- llvm::StringRef value_ref(value);
- std::pair<llvm::StringRef, llvm::StringRef> pair;
- pair = value_ref.split('=');
- if (!pair.first.empty() && !pair.second.empty())
- {
- std::string addr_str(pair.first.str());
- const lldb::addr_t mem_cache_addr = StringConvert::ToUInt64(addr_str.c_str(), LLDB_INVALID_ADDRESS, 0);
- if (mem_cache_addr != LLDB_INVALID_ADDRESS)
- {
- StringExtractor bytes;
- bytes.GetStringRef() = pair.second.str();
- const size_t byte_size = bytes.GetStringRef().size()/2;
- DataBufferSP data_buffer_sp(new DataBufferHeap(byte_size, 0));
- const size_t bytes_copied = bytes.GetHexBytes (data_buffer_sp->GetBytes(), byte_size, 0);
- if (bytes_copied == byte_size)
- m_memory_cache.AddL1CacheData(mem_cache_addr, data_buffer_sp);
- }
- }
- }
- else if (key.compare("watch") == 0 || key.compare("rwatch") == 0 || key.compare("awatch") == 0)
- {
- // Support standard GDB remote stop reply packet 'TAAwatch:addr'
- lldb::addr_t wp_addr = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_ADDRESS, 16);
- WatchpointSP wp_sp = GetTarget().GetWatchpointList().FindByAddress(wp_addr);
- uint32_t wp_index = LLDB_INVALID_INDEX32;
-
- if (wp_sp)
- wp_index = wp_sp->GetHardwareIndex();
-
- reason = "watchpoint";
- StreamString ostr;
- ostr.Printf("%" PRIu64 " %" PRIu32, wp_addr, wp_index);
- description = ostr.GetString().c_str();
- }
- else if (key.compare("library") == 0)
- {
- LoadModules();
- }
- else if (key.size() == 2 && ::isxdigit(key[0]) && ::isxdigit(key[1]))
- {
- uint32_t reg = StringConvert::ToUInt32 (key.c_str(), UINT32_MAX, 16);
- if (reg != UINT32_MAX)
- expedited_register_map[reg] = std::move(value);
- }
- }
-
- if (tid == LLDB_INVALID_THREAD_ID)
- {
- // A thread id may be invalid if the response is old style 'S' packet which does not provide the
- // thread information. So update the thread list and choose the first one.
- UpdateThreadIDList ();
-
- if (!m_thread_ids.empty ())
- {
- tid = m_thread_ids.front ();
- }
- }
-
- ThreadSP thread_sp = SetThreadStopInfo (tid,
- expedited_register_map,
- signo,
- thread_name,
- reason,
- description,
- exc_type,
- exc_data,
- thread_dispatch_qaddr,
- queue_vars_valid,
- associated_with_dispatch_queue,
- dispatch_queue_t,
- queue_name,
- queue_kind,
- queue_serial_number);
-
- return eStateStopped;
- }
- break;
-
- case 'W':
- case 'X':
- // process exited
- return eStateExited;
-
- default:
- break;
- }
- return eStateInvalid;
+void ProcessGDBRemote::RefreshStateAfterStop() {
+ std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());
+
+ m_thread_ids.clear();
+ m_thread_pcs.clear();
+ // Set the thread stop info. It might have a "threads" key whose value is
+ // a list of all thread IDs in the current process, so m_thread_ids might
+ // get set.
+
+ // Scope for the lock
+ {
+ // Lock the thread stack while we access it
+ std::lock_guard<std::recursive_mutex> guard(m_last_stop_packet_mutex);
+ // Get the number of stop packets on the stack
+ int nItems = m_stop_packet_stack.size();
+ // Iterate over them
+ for (int i = 0; i < nItems; i++) {
+ // Get the thread stop info
+ StringExtractorGDBRemote stop_info = m_stop_packet_stack[i];
+ // Process thread stop info
+ SetThreadStopInfo(stop_info);
+ }
+ // Clear the thread stop stack
+ m_stop_packet_stack.clear();
+ }
+
+ // Check to see if SetThreadStopInfo() filled in m_thread_ids?
+ if (m_thread_ids.empty()) {
+ // No, we need to fetch the thread list manually
+ UpdateThreadIDList();
+ }
+
+ // If we have queried for a default thread id
+ if (m_initial_tid != LLDB_INVALID_THREAD_ID) {
+ m_thread_list.SetSelectedThreadByID(m_initial_tid);
+ m_initial_tid = LLDB_INVALID_THREAD_ID;
+ }
+
+ // Let all threads recover from stopping and do any clean up based
+ // on the previous thread state (if any).
+ m_thread_list_real.RefreshStateAfterStop();
}
-void
-ProcessGDBRemote::RefreshStateAfterStop ()
-{
- std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());
-
- m_thread_ids.clear();
- m_thread_pcs.clear();
- // Set the thread stop info. It might have a "threads" key whose value is
- // a list of all thread IDs in the current process, so m_thread_ids might
- // get set.
-
- // Scope for the lock
- {
- // Lock the thread stack while we access it
- std::lock_guard<std::recursive_mutex> guard(m_last_stop_packet_mutex);
- // Get the number of stop packets on the stack
- int nItems = m_stop_packet_stack.size();
- // Iterate over them
- for (int i = 0; i < nItems; i++)
- {
- // Get the thread stop info
- StringExtractorGDBRemote stop_info = m_stop_packet_stack[i];
- // Process thread stop info
- SetThreadStopInfo(stop_info);
- }
- // Clear the thread stop stack
- m_stop_packet_stack.clear();
- }
-
- // Check to see if SetThreadStopInfo() filled in m_thread_ids?
- if (m_thread_ids.empty())
- {
- // No, we need to fetch the thread list manually
- UpdateThreadIDList();
- }
-
- // If we have queried for a default thread id
- if (m_initial_tid != LLDB_INVALID_THREAD_ID)
- {
- m_thread_list.SetSelectedThreadByID(m_initial_tid);
- m_initial_tid = LLDB_INVALID_THREAD_ID;
- }
-
- // Let all threads recover from stopping and do any clean up based
- // on the previous thread state (if any).
- m_thread_list_real.RefreshStateAfterStop();
+Error ProcessGDBRemote::DoHalt(bool &caused_stop) {
+ Error error;
+ if (m_public_state.GetValue() == eStateAttaching) {
+ // We are being asked to halt during an attach. We need to just close
+ // our file handle and debugserver will go away, and we can be done...
+ m_gdb_comm.Disconnect();
+ } else
+ caused_stop = m_gdb_comm.Interrupt();
+ return error;
}
-Error
-ProcessGDBRemote::DoHalt (bool &caused_stop)
-{
- Error error;
-
- bool timed_out = false;
- Mutex::Locker locker;
+Error ProcessGDBRemote::DoDetach(bool keep_stopped) {
+ Error error;
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ if (log)
+ log->Printf("ProcessGDBRemote::DoDetach(keep_stopped: %i)", keep_stopped);
- if (m_public_state.GetValue() == eStateAttaching)
- {
- // We are being asked to halt during an attach. We need to just close
- // our file handle and debugserver will go away, and we can be done...
- m_gdb_comm.Disconnect();
- }
+ error = m_gdb_comm.Detach(keep_stopped);
+ if (log) {
+ if (error.Success())
+ log->PutCString(
+ "ProcessGDBRemote::DoDetach() detach packet sent successfully");
else
- {
- if (!m_gdb_comm.SendInterrupt (locker, 2, timed_out))
- {
- if (timed_out)
- error.SetErrorString("timed out sending interrupt packet");
- else
- error.SetErrorString("unknown error sending interrupt packet");
- }
+ log->Printf("ProcessGDBRemote::DoDetach() detach packet send failed: %s",
+ error.AsCString() ? error.AsCString() : "<unknown error>");
+ }
- caused_stop = m_gdb_comm.GetInterruptWasSent ();
- }
+ if (!error.Success())
return error;
-}
-Error
-ProcessGDBRemote::DoDetach(bool keep_stopped)
-{
- Error error;
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf ("ProcessGDBRemote::DoDetach(keep_stopped: %i)", keep_stopped);
+ // Sleep for one second to let the process get all detached...
+ StopAsyncThread();
- error = m_gdb_comm.Detach (keep_stopped);
- if (log)
- {
- if (error.Success())
- log->PutCString ("ProcessGDBRemote::DoDetach() detach packet sent successfully");
- else
- log->Printf ("ProcessGDBRemote::DoDetach() detach packet send failed: %s", error.AsCString() ? error.AsCString() : "<unknown error>");
- }
-
- if (!error.Success())
- return error;
+ SetPrivateState(eStateDetached);
+ ResumePrivateStateThread();
- // Sleep for one second to let the process get all detached...
- StopAsyncThread ();
-
- SetPrivateState (eStateDetached);
- ResumePrivateStateThread();
-
- //KillDebugserverProcess ();
- return error;
+ // KillDebugserverProcess ();
+ return error;
}
+Error ProcessGDBRemote::DoDestroy() {
+ Error error;
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ if (log)
+ log->Printf("ProcessGDBRemote::DoDestroy()");
+
+ // There is a bug in older iOS debugservers where they don't shut down the
+ // process
+ // they are debugging properly. If the process is sitting at a breakpoint or
+ // an exception,
+ // this can cause problems with restarting. So we check to see if any of our
+ // threads are stopped
+ // at a breakpoint, and if so we remove all the breakpoints, resume the
+ // process, and THEN
+ // destroy it again.
+ //
+ // Note, we don't have a good way to test the version of debugserver, but I
+ // happen to know that
+ // the set of all the iOS debugservers which don't support
+ // GetThreadSuffixSupported() and that of
+ // the debugservers with this bug are equal. There really should be a better
+ // way to test this!
+ //
+ // We also use m_destroy_tried_resuming to make sure we only do this once, if
+ // we resume and then halt and
+ // get called here to destroy again and we're still at a breakpoint or
+ // exception, then we should
+ // just do the straight-forward kill.
+ //
+ // And of course, if we weren't able to stop the process by the time we get
+ // here, it isn't
+ // necessary (or helpful) to do any of this.
+
+ if (!m_gdb_comm.GetThreadSuffixSupported() &&
+ m_public_state.GetValue() != eStateRunning) {
+ PlatformSP platform_sp = GetTarget().GetPlatform();
+
+ // FIXME: These should be ConstStrings so we aren't doing strcmp'ing.
+ if (platform_sp && platform_sp->GetName() &&
+ platform_sp->GetName() == PlatformRemoteiOS::GetPluginNameStatic()) {
+ if (m_destroy_tried_resuming) {
+ if (log)
+ log->PutCString("ProcessGDBRemote::DoDestroy() - Tried resuming to "
+ "destroy once already, not doing it again.");
+ } else {
+ // At present, the plans are discarded and the breakpoints disabled
+ // Process::Destroy,
+ // but we really need it to happen here and it doesn't matter if we do
+ // it twice.
+ m_thread_list.DiscardThreadPlans();
+ DisableAllBreakpointSites();
+
+ bool stop_looks_like_crash = false;
+ ThreadList &threads = GetThreadList();
-Error
-ProcessGDBRemote::DoDestroy ()
-{
- Error error;
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf ("ProcessGDBRemote::DoDestroy()");
-
- // There is a bug in older iOS debugservers where they don't shut down the process
- // they are debugging properly. If the process is sitting at a breakpoint or an exception,
- // this can cause problems with restarting. So we check to see if any of our threads are stopped
- // at a breakpoint, and if so we remove all the breakpoints, resume the process, and THEN
- // destroy it again.
- //
- // Note, we don't have a good way to test the version of debugserver, but I happen to know that
- // the set of all the iOS debugservers which don't support GetThreadSuffixSupported() and that of
- // the debugservers with this bug are equal. There really should be a better way to test this!
- //
- // We also use m_destroy_tried_resuming to make sure we only do this once, if we resume and then halt and
- // get called here to destroy again and we're still at a breakpoint or exception, then we should
- // just do the straight-forward kill.
- //
- // And of course, if we weren't able to stop the process by the time we get here, it isn't
- // necessary (or helpful) to do any of this.
-
- if (!m_gdb_comm.GetThreadSuffixSupported() && m_public_state.GetValue() != eStateRunning)
- {
- PlatformSP platform_sp = GetTarget().GetPlatform();
-
- // FIXME: These should be ConstStrings so we aren't doing strcmp'ing.
- if (platform_sp
- && platform_sp->GetName()
- && platform_sp->GetName() == PlatformRemoteiOS::GetPluginNameStatic())
{
- if (m_destroy_tried_resuming)
- {
- if (log)
- log->PutCString ("ProcessGDBRemote::DoDestroy() - Tried resuming to destroy once already, not doing it again.");
+ std::lock_guard<std::recursive_mutex> guard(threads.GetMutex());
+
+ size_t num_threads = threads.GetSize();
+ for (size_t i = 0; i < num_threads; i++) {
+ ThreadSP thread_sp = threads.GetThreadAtIndex(i);
+ StopInfoSP stop_info_sp = thread_sp->GetPrivateStopInfo();
+ StopReason reason = eStopReasonInvalid;
+ if (stop_info_sp)
+ reason = stop_info_sp->GetStopReason();
+ if (reason == eStopReasonBreakpoint ||
+ reason == eStopReasonException) {
+ if (log)
+ log->Printf(
+ "ProcessGDBRemote::DoDestroy() - thread: 0x%4.4" PRIx64
+ " stopped with reason: %s.",
+ thread_sp->GetProtocolID(), stop_info_sp->GetDescription());
+ stop_looks_like_crash = true;
+ break;
}
- else
- {
- // At present, the plans are discarded and the breakpoints disabled Process::Destroy,
- // but we really need it to happen here and it doesn't matter if we do it twice.
- m_thread_list.DiscardThreadPlans();
- DisableAllBreakpointSites();
-
- bool stop_looks_like_crash = false;
- ThreadList &threads = GetThreadList();
-
- {
- std::lock_guard<std::recursive_mutex> guard(threads.GetMutex());
-
- size_t num_threads = threads.GetSize();
- for (size_t i = 0; i < num_threads; i++)
- {
- ThreadSP thread_sp = threads.GetThreadAtIndex(i);
- StopInfoSP stop_info_sp = thread_sp->GetPrivateStopInfo();
- StopReason reason = eStopReasonInvalid;
- if (stop_info_sp)
- reason = stop_info_sp->GetStopReason();
- if (reason == eStopReasonBreakpoint
- || reason == eStopReasonException)
- {
- if (log)
- log->Printf ("ProcessGDBRemote::DoDestroy() - thread: 0x%4.4" PRIx64 " stopped with reason: %s.",
- thread_sp->GetProtocolID(),
- stop_info_sp->GetDescription());
- stop_looks_like_crash = true;
- break;
- }
- }
- }
+ }
+ }
- if (stop_looks_like_crash)
- {
- if (log)
- log->PutCString ("ProcessGDBRemote::DoDestroy() - Stopped at a breakpoint, continue and then kill.");
- m_destroy_tried_resuming = true;
-
- // If we are going to run again before killing, it would be good to suspend all the threads
- // before resuming so they won't get into more trouble. Sadly, for the threads stopped with
- // the breakpoint or exception, the exception doesn't get cleared if it is suspended, so we do
- // have to run the risk of letting those threads proceed a bit.
-
- {
- std::lock_guard<std::recursive_mutex> guard(threads.GetMutex());
-
- size_t num_threads = threads.GetSize();
- for (size_t i = 0; i < num_threads; i++)
- {
- ThreadSP thread_sp = threads.GetThreadAtIndex(i);
- StopInfoSP stop_info_sp = thread_sp->GetPrivateStopInfo();
- StopReason reason = eStopReasonInvalid;
- if (stop_info_sp)
- reason = stop_info_sp->GetStopReason();
- if (reason != eStopReasonBreakpoint
- && reason != eStopReasonException)
- {
- if (log)
- log->Printf ("ProcessGDBRemote::DoDestroy() - Suspending thread: 0x%4.4" PRIx64 " before running.",
- thread_sp->GetProtocolID());
- thread_sp->SetResumeState(eStateSuspended);
- }
- }
- }
- Resume ();
- return Destroy(false);
- }
+ if (stop_looks_like_crash) {
+ if (log)
+ log->PutCString("ProcessGDBRemote::DoDestroy() - Stopped at a "
+ "breakpoint, continue and then kill.");
+ m_destroy_tried_resuming = true;
+
+ // If we are going to run again before killing, it would be good to
+ // suspend all the threads
+ // before resuming so they won't get into more trouble. Sadly, for
+ // the threads stopped with
+ // the breakpoint or exception, the exception doesn't get cleared if
+ // it is suspended, so we do
+ // have to run the risk of letting those threads proceed a bit.
+
+ {
+ std::lock_guard<std::recursive_mutex> guard(threads.GetMutex());
+
+ size_t num_threads = threads.GetSize();
+ for (size_t i = 0; i < num_threads; i++) {
+ ThreadSP thread_sp = threads.GetThreadAtIndex(i);
+ StopInfoSP stop_info_sp = thread_sp->GetPrivateStopInfo();
+ StopReason reason = eStopReasonInvalid;
+ if (stop_info_sp)
+ reason = stop_info_sp->GetStopReason();
+ if (reason != eStopReasonBreakpoint &&
+ reason != eStopReasonException) {
+ if (log)
+ log->Printf("ProcessGDBRemote::DoDestroy() - Suspending "
+ "thread: 0x%4.4" PRIx64 " before running.",
+ thread_sp->GetProtocolID());
+ thread_sp->SetResumeState(eStateSuspended);
+ }
}
+ }
+ Resume();
+ return Destroy(false);
}
+ }
}
+ }
- // Interrupt if our inferior is running...
- int exit_status = SIGABRT;
- std::string exit_string;
+ // Interrupt if our inferior is running...
+ int exit_status = SIGABRT;
+ std::string exit_string;
- if (m_gdb_comm.IsConnected())
- {
- if (m_public_state.GetValue() != eStateAttaching)
- {
- StringExtractorGDBRemote response;
- bool send_async = true;
- GDBRemoteCommunication::ScopedTimeout (m_gdb_comm, 3);
+ if (m_gdb_comm.IsConnected()) {
+ if (m_public_state.GetValue() != eStateAttaching) {
+ StringExtractorGDBRemote response;
+ bool send_async = true;
+ GDBRemoteCommunication::ScopedTimeout(m_gdb_comm,
+ std::chrono::seconds(3));
- if (m_gdb_comm.SendPacketAndWaitForResponse("k", 1, response, send_async) == GDBRemoteCommunication::PacketResult::Success)
- {
- char packet_cmd = response.GetChar(0);
+ if (m_gdb_comm.SendPacketAndWaitForResponse("k", response, send_async) ==
+ GDBRemoteCommunication::PacketResult::Success) {
+ char packet_cmd = response.GetChar(0);
- if (packet_cmd == 'W' || packet_cmd == 'X')
- {
+ if (packet_cmd == 'W' || packet_cmd == 'X') {
#if defined(__APPLE__)
- // For Native processes on Mac OS X, we launch through the Host Platform, then hand the process off
- // to debugserver, which becomes the parent process through "PT_ATTACH". Then when we go to kill
- // the process on Mac OS X we call ptrace(PT_KILL) to kill it, then we call waitpid which returns
- // with no error and the correct status. But amusingly enough that doesn't seem to actually reap
- // the process, but instead it is left around as a Zombie. Probably the kernel is in the process of
- // switching ownership back to lldb which was the original parent, and gets confused in the handoff.
- // Anyway, so call waitpid here to finally reap it.
- PlatformSP platform_sp(GetTarget().GetPlatform());
- if (platform_sp && platform_sp->IsHost())
- {
- int status;
- ::pid_t reap_pid;
- reap_pid = waitpid (GetID(), &status, WNOHANG);
- if (log)
- log->Printf ("Reaped pid: %d, status: %d.\n", reap_pid, status);
- }
-#endif
- SetLastStopPacket (response);
- ClearThreadIDList ();
- exit_status = response.GetHexU8();
- }
- else
- {
- if (log)
- log->Printf ("ProcessGDBRemote::DoDestroy - got unexpected response to k packet: %s", response.GetStringRef().c_str());
- exit_string.assign("got unexpected response to k packet: ");
- exit_string.append(response.GetStringRef());
- }
- }
- else
- {
- if (log)
- log->Printf ("ProcessGDBRemote::DoDestroy - failed to send k packet");
- exit_string.assign("failed to send the k packet");
- }
- }
- else
- {
+ // For Native processes on Mac OS X, we launch through the Host
+ // Platform, then hand the process off
+ // to debugserver, which becomes the parent process through
+ // "PT_ATTACH". Then when we go to kill
+ // the process on Mac OS X we call ptrace(PT_KILL) to kill it, then we
+ // call waitpid which returns
+ // with no error and the correct status. But amusingly enough that
+ // doesn't seem to actually reap
+ // the process, but instead it is left around as a Zombie. Probably
+ // the kernel is in the process of
+ // switching ownership back to lldb which was the original parent, and
+ // gets confused in the handoff.
+ // Anyway, so call waitpid here to finally reap it.
+ PlatformSP platform_sp(GetTarget().GetPlatform());
+ if (platform_sp && platform_sp->IsHost()) {
+ int status;
+ ::pid_t reap_pid;
+ reap_pid = waitpid(GetID(), &status, WNOHANG);
if (log)
- log->Printf ("ProcessGDBRemote::DoDestroy - killed or interrupted while attaching");
- exit_string.assign ("killed or interrupted while attaching.");
+ log->Printf("Reaped pid: %d, status: %d.\n", reap_pid, status);
+ }
+#endif
+ SetLastStopPacket(response);
+ ClearThreadIDList();
+ exit_status = response.GetHexU8();
+ } else {
+ if (log)
+ log->Printf("ProcessGDBRemote::DoDestroy - got unexpected response "
+ "to k packet: %s",
+ response.GetStringRef().c_str());
+ exit_string.assign("got unexpected response to k packet: ");
+ exit_string.append(response.GetStringRef());
}
- }
- else
- {
- // If we missed setting the exit status on the way out, do it here.
- // NB set exit status can be called multiple times, the first one sets the status.
- exit_string.assign("destroying when not connected to debugserver");
- }
-
- SetExitStatus(exit_status, exit_string.c_str());
-
- StopAsyncThread ();
- KillDebugserverProcess ();
- return error;
-}
-
-void
-ProcessGDBRemote::SetLastStopPacket (const StringExtractorGDBRemote &response)
-{
- const bool did_exec = response.GetStringRef().find(";reason:exec;") != std::string::npos;
- if (did_exec)
- {
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ } else {
if (log)
- log->Printf ("ProcessGDBRemote::SetLastStopPacket () - detected exec");
+ log->Printf("ProcessGDBRemote::DoDestroy - failed to send k packet");
+ exit_string.assign("failed to send the k packet");
+ }
+ } else {
+ if (log)
+ log->Printf("ProcessGDBRemote::DoDestroy - killed or interrupted while "
+ "attaching");
+ exit_string.assign("killed or interrupted while attaching.");
+ }
+ } else {
+ // If we missed setting the exit status on the way out, do it here.
+ // NB set exit status can be called multiple times, the first one sets the
+ // status.
+ exit_string.assign("destroying when not connected to debugserver");
+ }
+
+ SetExitStatus(exit_status, exit_string.c_str());
+
+ StopAsyncThread();
+ KillDebugserverProcess();
+ return error;
+}
- m_thread_list_real.Clear();
- m_thread_list.Clear();
- BuildDynamicRegisterInfo (true);
- m_gdb_comm.ResetDiscoverableSettings (did_exec);
- }
+void ProcessGDBRemote::SetLastStopPacket(
+ const StringExtractorGDBRemote &response) {
+ const bool did_exec =
+ response.GetStringRef().find(";reason:exec;") != std::string::npos;
+ if (did_exec) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ if (log)
+ log->Printf("ProcessGDBRemote::SetLastStopPacket () - detected exec");
- // Scope the lock
- {
- // Lock the thread stack while we access it
- std::lock_guard<std::recursive_mutex> guard(m_last_stop_packet_mutex);
-
- // We are are not using non-stop mode, there can only be one last stop
- // reply packet, so clear the list.
- if (GetTarget().GetNonStopModeEnabled() == false)
- m_stop_packet_stack.clear();
-
- // Add this stop packet to the stop packet stack
- // This stack will get popped and examined when we switch to the
- // Stopped state
- m_stop_packet_stack.push_back(response);
- }
+ m_thread_list_real.Clear();
+ m_thread_list.Clear();
+ BuildDynamicRegisterInfo(true);
+ m_gdb_comm.ResetDiscoverableSettings(did_exec);
+ }
+
+ // Scope the lock
+ {
+ // Lock the thread stack while we access it
+ std::lock_guard<std::recursive_mutex> guard(m_last_stop_packet_mutex);
+
+ // We are are not using non-stop mode, there can only be one last stop
+ // reply packet, so clear the list.
+ if (GetTarget().GetNonStopModeEnabled() == false)
+ m_stop_packet_stack.clear();
+
+ // Add this stop packet to the stop packet stack
+ // This stack will get popped and examined when we switch to the
+ // Stopped state
+ m_stop_packet_stack.push_back(response);
+ }
}
-void
-ProcessGDBRemote::SetUnixSignals(const UnixSignalsSP &signals_sp)
-{
- Process::SetUnixSignals(std::make_shared<GDBRemoteSignals>(signals_sp));
+void ProcessGDBRemote::SetUnixSignals(const UnixSignalsSP &signals_sp) {
+ Process::SetUnixSignals(std::make_shared<GDBRemoteSignals>(signals_sp));
}
//------------------------------------------------------------------
// Process Queries
//------------------------------------------------------------------
-bool
-ProcessGDBRemote::IsAlive ()
-{
- return m_gdb_comm.IsConnected() && Process::IsAlive();
+bool ProcessGDBRemote::IsAlive() {
+ return m_gdb_comm.IsConnected() && Process::IsAlive();
}
-addr_t
-ProcessGDBRemote::GetImageInfoAddress()
-{
- // request the link map address via the $qShlibInfoAddr packet
- lldb::addr_t addr = m_gdb_comm.GetShlibInfoAddr();
+addr_t ProcessGDBRemote::GetImageInfoAddress() {
+ // request the link map address via the $qShlibInfoAddr packet
+ lldb::addr_t addr = m_gdb_comm.GetShlibInfoAddr();
- // the loaded module list can also provides a link map address
- if (addr == LLDB_INVALID_ADDRESS)
- {
- LoadedModuleInfoList list;
- if (GetLoadedModuleList (list).Success())
- addr = list.m_link_map;
- }
+ // the loaded module list can also provides a link map address
+ if (addr == LLDB_INVALID_ADDRESS) {
+ LoadedModuleInfoList list;
+ if (GetLoadedModuleList(list).Success())
+ addr = list.m_link_map;
+ }
- return addr;
+ return addr;
}
-void
-ProcessGDBRemote::WillPublicStop ()
-{
- // See if the GDB remote client supports the JSON threads info.
- // If so, we gather stop info for all threads, expedited registers,
- // expedited memory, runtime queue information (iOS and MacOSX only),
- // and more. Expediting memory will help stack backtracing be much
- // faster. Expediting registers will make sure we don't have to read
- // the thread registers for GPRs.
- m_jthreadsinfo_sp = m_gdb_comm.GetThreadsInfo();
-
- if (m_jthreadsinfo_sp)
- {
- // Now set the stop info for each thread and also expedite any registers
- // and memory that was in the jThreadsInfo response.
- StructuredData::Array *thread_infos = m_jthreadsinfo_sp->GetAsArray();
- if (thread_infos)
- {
- const size_t n = thread_infos->GetSize();
- for (size_t i=0; i<n; ++i)
- {
- StructuredData::Dictionary *thread_dict = thread_infos->GetItemAtIndex(i)->GetAsDictionary();
- if (thread_dict)
- SetThreadStopInfo(thread_dict);
- }
- }
- }
+void ProcessGDBRemote::WillPublicStop() {
+ // See if the GDB remote client supports the JSON threads info.
+ // If so, we gather stop info for all threads, expedited registers,
+ // expedited memory, runtime queue information (iOS and MacOSX only),
+ // and more. Expediting memory will help stack backtracing be much
+ // faster. Expediting registers will make sure we don't have to read
+ // the thread registers for GPRs.
+ m_jthreadsinfo_sp = m_gdb_comm.GetThreadsInfo();
+
+ if (m_jthreadsinfo_sp) {
+ // Now set the stop info for each thread and also expedite any registers
+ // and memory that was in the jThreadsInfo response.
+ StructuredData::Array *thread_infos = m_jthreadsinfo_sp->GetAsArray();
+ if (thread_infos) {
+ const size_t n = thread_infos->GetSize();
+ for (size_t i = 0; i < n; ++i) {
+ StructuredData::Dictionary *thread_dict =
+ thread_infos->GetItemAtIndex(i)->GetAsDictionary();
+ if (thread_dict)
+ SetThreadStopInfo(thread_dict);
+ }
+ }
+ }
}
//------------------------------------------------------------------
// Process Memory
//------------------------------------------------------------------
-size_t
-ProcessGDBRemote::DoReadMemory (addr_t addr, void *buf, size_t size, Error &error)
-{
- GetMaxMemorySize ();
- if (size > m_max_memory_size)
- {
- // Keep memory read sizes down to a sane limit. This function will be
- // called multiple times in order to complete the task by
- // lldb_private::Process so it is ok to do this.
- size = m_max_memory_size;
- }
-
- char packet[64];
- int packet_len;
- bool binary_memory_read = m_gdb_comm.GetxPacketSupported();
- packet_len = ::snprintf(packet, sizeof(packet), "%c%" PRIx64 ",%" PRIx64,
- binary_memory_read ? 'x' : 'm', (uint64_t)addr, (uint64_t)size);
- assert (packet_len + 1 < (int)sizeof(packet));
- StringExtractorGDBRemote response;
- if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, true) == GDBRemoteCommunication::PacketResult::Success)
- {
- if (response.IsNormalResponse())
- {
- error.Clear();
- if (binary_memory_read)
- {
- // The lower level GDBRemoteCommunication packet receive layer has already de-quoted any
- // 0x7d character escaping that was present in the packet
-
- size_t data_received_size = response.GetBytesLeft();
- if (data_received_size > size)
- {
- // Don't write past the end of BUF if the remote debug server gave us too
- // much data for some reason.
- data_received_size = size;
- }
- memcpy (buf, response.GetStringRef().data(), data_received_size);
- return data_received_size;
- }
- else
- {
- return response.GetHexBytes(buf, size, '\xdd');
- }
+size_t ProcessGDBRemote::DoReadMemory(addr_t addr, void *buf, size_t size,
+ Error &error) {
+ GetMaxMemorySize();
+ if (size > m_max_memory_size) {
+ // Keep memory read sizes down to a sane limit. This function will be
+ // called multiple times in order to complete the task by
+ // lldb_private::Process so it is ok to do this.
+ size = m_max_memory_size;
+ }
+
+ char packet[64];
+ int packet_len;
+ bool binary_memory_read = m_gdb_comm.GetxPacketSupported();
+ packet_len = ::snprintf(packet, sizeof(packet), "%c%" PRIx64 ",%" PRIx64,
+ binary_memory_read ? 'x' : 'm', (uint64_t)addr,
+ (uint64_t)size);
+ assert(packet_len + 1 < (int)sizeof(packet));
+ UNUSED_IF_ASSERT_DISABLED(packet_len);
+ StringExtractorGDBRemote response;
+ if (m_gdb_comm.SendPacketAndWaitForResponse(packet, response, true) ==
+ GDBRemoteCommunication::PacketResult::Success) {
+ if (response.IsNormalResponse()) {
+ error.Clear();
+ if (binary_memory_read) {
+ // The lower level GDBRemoteCommunication packet receive layer has
+ // already de-quoted any
+ // 0x7d character escaping that was present in the packet
+
+ size_t data_received_size = response.GetBytesLeft();
+ if (data_received_size > size) {
+ // Don't write past the end of BUF if the remote debug server gave us
+ // too
+ // much data for some reason.
+ data_received_size = size;
}
- else if (response.IsErrorResponse())
- error.SetErrorStringWithFormat("memory read failed for 0x%" PRIx64, addr);
- else if (response.IsUnsupportedResponse())
- error.SetErrorStringWithFormat("GDB server does not support reading memory");
- else
- error.SetErrorStringWithFormat("unexpected response to GDB server memory read packet '%s': '%s'", packet, response.GetStringRef().c_str());
- }
+ memcpy(buf, response.GetStringRef().data(), data_received_size);
+ return data_received_size;
+ } else {
+ return response.GetHexBytes(
+ llvm::MutableArrayRef<uint8_t>((uint8_t *)buf, size), '\xdd');
+ }
+ } else if (response.IsErrorResponse())
+ error.SetErrorStringWithFormat("memory read failed for 0x%" PRIx64, addr);
+ else if (response.IsUnsupportedResponse())
+ error.SetErrorStringWithFormat(
+ "GDB server does not support reading memory");
else
- {
- error.SetErrorStringWithFormat("failed to send packet: '%s'", packet);
- }
- return 0;
+ error.SetErrorStringWithFormat(
+ "unexpected response to GDB server memory read packet '%s': '%s'",
+ packet, response.GetStringRef().c_str());
+ } else {
+ error.SetErrorStringWithFormat("failed to send packet: '%s'", packet);
+ }
+ return 0;
}
-size_t
-ProcessGDBRemote::DoWriteMemory (addr_t addr, const void *buf, size_t size, Error &error)
-{
- GetMaxMemorySize ();
- if (size > m_max_memory_size)
- {
- // Keep memory read sizes down to a sane limit. This function will be
- // called multiple times in order to complete the task by
- // lldb_private::Process so it is ok to do this.
- size = m_max_memory_size;
- }
-
- StreamString packet;
- packet.Printf("M%" PRIx64 ",%" PRIx64 ":", addr, (uint64_t)size);
- packet.PutBytesAsRawHex8(buf, size, endian::InlHostByteOrder(), endian::InlHostByteOrder());
- StringExtractorGDBRemote response;
- if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(), response, true) == GDBRemoteCommunication::PacketResult::Success)
- {
- if (response.IsOKResponse())
- {
- error.Clear();
- return size;
- }
- else if (response.IsErrorResponse())
- error.SetErrorStringWithFormat("memory write failed for 0x%" PRIx64, addr);
- else if (response.IsUnsupportedResponse())
- error.SetErrorStringWithFormat("GDB server does not support writing memory");
- else
- error.SetErrorStringWithFormat("unexpected response to GDB server memory write packet '%s': '%s'", packet.GetString().c_str(), response.GetStringRef().c_str());
- }
+size_t ProcessGDBRemote::DoWriteMemory(addr_t addr, const void *buf,
+ size_t size, Error &error) {
+ GetMaxMemorySize();
+ if (size > m_max_memory_size) {
+ // Keep memory read sizes down to a sane limit. This function will be
+ // called multiple times in order to complete the task by
+ // lldb_private::Process so it is ok to do this.
+ size = m_max_memory_size;
+ }
+
+ StreamString packet;
+ packet.Printf("M%" PRIx64 ",%" PRIx64 ":", addr, (uint64_t)size);
+ packet.PutBytesAsRawHex8(buf, size, endian::InlHostByteOrder(),
+ endian::InlHostByteOrder());
+ StringExtractorGDBRemote response;
+ if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response,
+ true) ==
+ GDBRemoteCommunication::PacketResult::Success) {
+ if (response.IsOKResponse()) {
+ error.Clear();
+ return size;
+ } else if (response.IsErrorResponse())
+ error.SetErrorStringWithFormat("memory write failed for 0x%" PRIx64,
+ addr);
+ else if (response.IsUnsupportedResponse())
+ error.SetErrorStringWithFormat(
+ "GDB server does not support writing memory");
else
- {
- error.SetErrorStringWithFormat("failed to send packet: '%s'", packet.GetString().c_str());
- }
- return 0;
+ error.SetErrorStringWithFormat(
+ "unexpected response to GDB server memory write packet '%s': '%s'",
+ packet.GetData(), response.GetStringRef().c_str());
+ } else {
+ error.SetErrorStringWithFormat("failed to send packet: '%s'",
+ packet.GetData());
+ }
+ return 0;
}
-lldb::addr_t
-ProcessGDBRemote::DoAllocateMemory (size_t size, uint32_t permissions, Error &error)
-{
- Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS|LIBLLDB_LOG_EXPRESSIONS));
- addr_t allocated_addr = LLDB_INVALID_ADDRESS;
-
- if (m_gdb_comm.SupportsAllocDeallocMemory() != eLazyBoolNo)
- {
- allocated_addr = m_gdb_comm.AllocateMemory (size, permissions);
- if (allocated_addr != LLDB_INVALID_ADDRESS || m_gdb_comm.SupportsAllocDeallocMemory() == eLazyBoolYes)
- return allocated_addr;
- }
-
- if (m_gdb_comm.SupportsAllocDeallocMemory() == eLazyBoolNo)
- {
- // Call mmap() to create memory in the inferior..
- 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;
- else
- {
- allocated_addr = LLDB_INVALID_ADDRESS;
- if (log)
- log->Printf ("ProcessGDBRemote::%s no direct stub support for memory allocation, and InferiorCallMmap also failed - is stub missing register context save/restore capability?", __FUNCTION__);
- }
- }
-
- if (allocated_addr == LLDB_INVALID_ADDRESS)
- error.SetErrorStringWithFormat("unable to allocate %" PRIu64 " bytes of memory with permissions %s", (uint64_t)size, GetPermissionsAsCString (permissions));
- else
- error.Clear();
- return allocated_addr;
+lldb::addr_t ProcessGDBRemote::DoAllocateMemory(size_t size,
+ uint32_t permissions,
+ Error &error) {
+ Log *log(
+ GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_EXPRESSIONS));
+ addr_t allocated_addr = LLDB_INVALID_ADDRESS;
+
+ if (m_gdb_comm.SupportsAllocDeallocMemory() != eLazyBoolNo) {
+ allocated_addr = m_gdb_comm.AllocateMemory(size, permissions);
+ if (allocated_addr != LLDB_INVALID_ADDRESS ||
+ m_gdb_comm.SupportsAllocDeallocMemory() == eLazyBoolYes)
+ return allocated_addr;
+ }
+
+ if (m_gdb_comm.SupportsAllocDeallocMemory() == eLazyBoolNo) {
+ // Call mmap() to create memory in the inferior..
+ 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;
+ else {
+ allocated_addr = LLDB_INVALID_ADDRESS;
+ if (log)
+ log->Printf("ProcessGDBRemote::%s no direct stub support for memory "
+ "allocation, and InferiorCallMmap also failed - is stub "
+ "missing register context save/restore capability?",
+ __FUNCTION__);
+ }
+ }
+
+ if (allocated_addr == LLDB_INVALID_ADDRESS)
+ error.SetErrorStringWithFormat(
+ "unable to allocate %" PRIu64 " bytes of memory with permissions %s",
+ (uint64_t)size, GetPermissionsAsCString(permissions));
+ else
+ error.Clear();
+ return allocated_addr;
}
-Error
-ProcessGDBRemote::GetMemoryRegionInfo (addr_t load_addr,
- MemoryRegionInfo &region_info)
-{
+Error ProcessGDBRemote::GetMemoryRegionInfo(addr_t load_addr,
+ MemoryRegionInfo &region_info) {
- Error error (m_gdb_comm.GetMemoryRegionInfo (load_addr, region_info));
- return error;
+ Error error(m_gdb_comm.GetMemoryRegionInfo(load_addr, region_info));
+ return error;
}
-Error
-ProcessGDBRemote::GetWatchpointSupportInfo (uint32_t &num)
-{
+Error ProcessGDBRemote::GetWatchpointSupportInfo(uint32_t &num) {
- Error error (m_gdb_comm.GetWatchpointSupportInfo (num));
- return error;
+ Error error(m_gdb_comm.GetWatchpointSupportInfo(num));
+ return error;
}
-Error
-ProcessGDBRemote::GetWatchpointSupportInfo (uint32_t &num, bool& after)
-{
- Error error (m_gdb_comm.GetWatchpointSupportInfo (num, after, GetTarget().GetArchitecture()));
- return error;
+Error ProcessGDBRemote::GetWatchpointSupportInfo(uint32_t &num, bool &after) {
+ Error error(m_gdb_comm.GetWatchpointSupportInfo(
+ num, after, GetTarget().GetArchitecture()));
+ return error;
}
-Error
-ProcessGDBRemote::DoDeallocateMemory (lldb::addr_t addr)
-{
- Error error;
- LazyBool supported = m_gdb_comm.SupportsAllocDeallocMemory();
-
- switch (supported)
- {
- case eLazyBoolCalculate:
- // We should never be deallocating memory without allocating memory
- // first so we should never get eLazyBoolCalculate
- error.SetErrorString ("tried to deallocate memory without ever allocating memory");
- break;
-
- case eLazyBoolYes:
- if (!m_gdb_comm.DeallocateMemory (addr))
- error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64, addr);
- break;
-
- case eLazyBoolNo:
- // Call munmap() to deallocate memory in the inferior..
- {
- 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);
- }
- break;
- }
-
- return error;
+Error ProcessGDBRemote::DoDeallocateMemory(lldb::addr_t addr) {
+ Error error;
+ LazyBool supported = m_gdb_comm.SupportsAllocDeallocMemory();
+
+ switch (supported) {
+ case eLazyBoolCalculate:
+ // We should never be deallocating memory without allocating memory
+ // first so we should never get eLazyBoolCalculate
+ error.SetErrorString(
+ "tried to deallocate memory without ever allocating memory");
+ break;
+
+ case eLazyBoolYes:
+ if (!m_gdb_comm.DeallocateMemory(addr))
+ error.SetErrorStringWithFormat(
+ "unable to deallocate memory at 0x%" PRIx64, addr);
+ break;
+
+ case eLazyBoolNo:
+ // Call munmap() to deallocate memory in the inferior..
+ {
+ 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);
+ }
+ break;
+ }
+
+ return error;
}
-
//------------------------------------------------------------------
// Process STDIO
//------------------------------------------------------------------
-size_t
-ProcessGDBRemote::PutSTDIN (const char *src, size_t src_len, Error &error)
-{
- if (m_stdio_communication.IsConnected())
- {
- ConnectionStatus status;
- m_stdio_communication.Write(src, src_len, status, NULL);
- }
- else if (m_stdin_forward)
- {
- m_gdb_comm.SendStdinNotification(src, src_len);
- }
- return 0;
+size_t ProcessGDBRemote::PutSTDIN(const char *src, size_t src_len,
+ Error &error) {
+ if (m_stdio_communication.IsConnected()) {
+ ConnectionStatus status;
+ m_stdio_communication.Write(src, src_len, status, NULL);
+ } else if (m_stdin_forward) {
+ m_gdb_comm.SendStdinNotification(src, src_len);
+ }
+ return 0;
}
-Error
-ProcessGDBRemote::EnableBreakpointSite (BreakpointSite *bp_site)
-{
- Error error;
- assert(bp_site != NULL);
-
- // Get logging info
- Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS));
- user_id_t site_id = bp_site->GetID();
-
- // Get the breakpoint address
- const addr_t addr = bp_site->GetLoadAddress();
-
- // Log that a breakpoint was requested
- if (log)
- log->Printf("ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64 ") address = 0x%" PRIx64, site_id, (uint64_t)addr);
-
- // Breakpoint already exists and is enabled
- if (bp_site->IsEnabled())
- {
- if (log)
- log->Printf("ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64 ") address = 0x%" PRIx64 " -- SUCCESS (already enabled)", site_id, (uint64_t)addr);
- return error;
- }
+Error ProcessGDBRemote::EnableBreakpointSite(BreakpointSite *bp_site) {
+ Error error;
+ assert(bp_site != NULL);
- // Get the software breakpoint trap opcode size
- const size_t bp_op_size = GetSoftwareBreakpointTrapOpcode(bp_site);
+ // Get logging info
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS));
+ user_id_t site_id = bp_site->GetID();
- // SupportsGDBStoppointPacket() simply checks a boolean, indicating if this breakpoint type
- // is supported by the remote stub. These are set to true by default, and later set to false
- // only after we receive an unimplemented response when sending a breakpoint packet. This means
- // initially that unless we were specifically instructed to use a hardware breakpoint, LLDB will
- // attempt to set a software breakpoint. HardwareRequired() also queries a boolean variable which
- // indicates if the user specifically asked for hardware breakpoints. If true then we will
- // skip over software breakpoints.
- if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware) && (!bp_site->HardwareRequired()))
- {
- // Try to send off a software breakpoint packet ($Z0)
- uint8_t error_no = m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointSoftware, true, addr, bp_op_size);
- if (error_no == 0)
- {
- // The breakpoint was placed successfully
- bp_site->SetEnabled(true);
- bp_site->SetType(BreakpointSite::eExternal);
- return error;
- }
+ // Get the breakpoint address
+ const addr_t addr = bp_site->GetLoadAddress();
- // SendGDBStoppointTypePacket() will return an error if it was unable to set this
- // breakpoint. We need to differentiate between a error specific to placing this breakpoint
- // or if we have learned that this breakpoint type is unsupported. To do this, we
- // must test the support boolean for this breakpoint type to see if it now indicates that
- // this breakpoint type is unsupported. If they are still supported then we should return
- // with the error code. If they are now unsupported, then we would like to fall through
- // and try another form of breakpoint.
- if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware))
- {
- if (error_no != UINT8_MAX)
- error.SetErrorStringWithFormat("error: %d sending the breakpoint request", errno);
- else
- error.SetErrorString("error sending the breakpoint request");
- return error;
- }
-
- // We reach here when software breakpoints have been found to be unsupported. For future
- // calls to set a breakpoint, we will not attempt to set a breakpoint with a type that is
- // known not to be supported.
- if (log)
- log->Printf("Software breakpoints are unsupported");
-
- // So we will fall through and try a hardware breakpoint
- }
-
- // The process of setting a hardware breakpoint is much the same as above. We check the
- // supported boolean for this breakpoint type, and if it is thought to be supported then we
- // will try to set this breakpoint with a hardware breakpoint.
- if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointHardware))
- {
- // Try to send off a hardware breakpoint packet ($Z1)
- uint8_t error_no = m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointHardware, true, addr, bp_op_size);
- if (error_no == 0)
- {
- // The breakpoint was placed successfully
- bp_site->SetEnabled(true);
- bp_site->SetType(BreakpointSite::eHardware);
- return error;
- }
-
- // Check if the error was something other then an unsupported breakpoint type
- if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointHardware))
- {
- // Unable to set this hardware breakpoint
- if (error_no != UINT8_MAX)
- error.SetErrorStringWithFormat("error: %d sending the hardware breakpoint request "
- "(hardware breakpoint resources might be exhausted or unavailable)",
- error_no);
- else
- error.SetErrorString("error sending the hardware breakpoint request (hardware breakpoint resources "
- "might be exhausted or unavailable)");
- return error;
- }
+ // Log that a breakpoint was requested
+ if (log)
+ log->Printf("ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64
+ ") address = 0x%" PRIx64,
+ site_id, (uint64_t)addr);
- // We will reach here when the stub gives an unsupported response to a hardware breakpoint
- if (log)
- log->Printf("Hardware breakpoints are unsupported");
+ // Breakpoint already exists and is enabled
+ if (bp_site->IsEnabled()) {
+ if (log)
+ log->Printf("ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64
+ ") address = 0x%" PRIx64 " -- SUCCESS (already enabled)",
+ site_id, (uint64_t)addr);
+ return error;
+ }
+
+ // Get the software breakpoint trap opcode size
+ const size_t bp_op_size = GetSoftwareBreakpointTrapOpcode(bp_site);
+
+ // SupportsGDBStoppointPacket() simply checks a boolean, indicating if this
+ // breakpoint type
+ // is supported by the remote stub. These are set to true by default, and
+ // later set to false
+ // only after we receive an unimplemented response when sending a breakpoint
+ // packet. This means
+ // initially that unless we were specifically instructed to use a hardware
+ // breakpoint, LLDB will
+ // attempt to set a software breakpoint. HardwareRequired() also queries a
+ // boolean variable which
+ // indicates if the user specifically asked for hardware breakpoints. If true
+ // then we will
+ // skip over software breakpoints.
+ if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware) &&
+ (!bp_site->HardwareRequired())) {
+ // Try to send off a software breakpoint packet ($Z0)
+ uint8_t error_no = m_gdb_comm.SendGDBStoppointTypePacket(
+ eBreakpointSoftware, true, addr, bp_op_size);
+ if (error_no == 0) {
+ // The breakpoint was placed successfully
+ bp_site->SetEnabled(true);
+ bp_site->SetType(BreakpointSite::eExternal);
+ return error;
+ }
+
+ // SendGDBStoppointTypePacket() will return an error if it was unable to set
+ // this
+ // breakpoint. We need to differentiate between a error specific to placing
+ // this breakpoint
+ // or if we have learned that this breakpoint type is unsupported. To do
+ // this, we
+ // must test the support boolean for this breakpoint type to see if it now
+ // indicates that
+ // this breakpoint type is unsupported. If they are still supported then we
+ // should return
+ // with the error code. If they are now unsupported, then we would like to
+ // fall through
+ // and try another form of breakpoint.
+ if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware)) {
+ if (error_no != UINT8_MAX)
+ error.SetErrorStringWithFormat(
+ "error: %d sending the breakpoint request", errno);
+ else
+ error.SetErrorString("error sending the breakpoint request");
+ return error;
+ }
+
+ // We reach here when software breakpoints have been found to be
+ // unsupported. For future
+ // calls to set a breakpoint, we will not attempt to set a breakpoint with a
+ // type that is
+ // known not to be supported.
+ if (log)
+ log->Printf("Software breakpoints are unsupported");
+
+ // So we will fall through and try a hardware breakpoint
+ }
+
+ // The process of setting a hardware breakpoint is much the same as above. We
+ // check the
+ // supported boolean for this breakpoint type, and if it is thought to be
+ // supported then we
+ // will try to set this breakpoint with a hardware breakpoint.
+ if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointHardware)) {
+ // Try to send off a hardware breakpoint packet ($Z1)
+ uint8_t error_no = m_gdb_comm.SendGDBStoppointTypePacket(
+ eBreakpointHardware, true, addr, bp_op_size);
+ if (error_no == 0) {
+ // The breakpoint was placed successfully
+ bp_site->SetEnabled(true);
+ bp_site->SetType(BreakpointSite::eHardware);
+ return error;
+ }
+
+ // Check if the error was something other then an unsupported breakpoint
+ // type
+ if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointHardware)) {
+ // Unable to set this hardware breakpoint
+ if (error_no != UINT8_MAX)
+ error.SetErrorStringWithFormat(
+ "error: %d sending the hardware breakpoint request "
+ "(hardware breakpoint resources might be exhausted or unavailable)",
+ error_no);
+ else
+ error.SetErrorString("error sending the hardware breakpoint request "
+ "(hardware breakpoint resources "
+ "might be exhausted or unavailable)");
+ return error;
+ }
+
+ // We will reach here when the stub gives an unsupported response to a
+ // hardware breakpoint
+ if (log)
+ log->Printf("Hardware breakpoints are unsupported");
- // Finally we will falling through to a #trap style breakpoint
- }
+ // Finally we will falling through to a #trap style breakpoint
+ }
- // Don't fall through when hardware breakpoints were specifically requested
- if (bp_site->HardwareRequired())
- {
- error.SetErrorString("hardware breakpoints are not supported");
- return error;
- }
+ // Don't fall through when hardware breakpoints were specifically requested
+ if (bp_site->HardwareRequired()) {
+ error.SetErrorString("hardware breakpoints are not supported");
+ return error;
+ }
- // As a last resort we want to place a manual breakpoint. An instruction
- // is placed into the process memory using memory write packets.
- return EnableSoftwareBreakpoint(bp_site);
+ // As a last resort we want to place a manual breakpoint. An instruction
+ // is placed into the process memory using memory write packets.
+ return EnableSoftwareBreakpoint(bp_site);
}
-Error
-ProcessGDBRemote::DisableBreakpointSite (BreakpointSite *bp_site)
-{
- Error error;
- assert (bp_site != NULL);
- addr_t addr = bp_site->GetLoadAddress();
- user_id_t site_id = bp_site->GetID();
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS));
- if (log)
- log->Printf ("ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64 ") addr = 0x%8.8" PRIx64, site_id, (uint64_t)addr);
-
- if (bp_site->IsEnabled())
- {
- const size_t bp_op_size = GetSoftwareBreakpointTrapOpcode (bp_site);
+Error ProcessGDBRemote::DisableBreakpointSite(BreakpointSite *bp_site) {
+ Error error;
+ assert(bp_site != NULL);
+ addr_t addr = bp_site->GetLoadAddress();
+ user_id_t site_id = bp_site->GetID();
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS));
+ if (log)
+ log->Printf("ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64
+ ") addr = 0x%8.8" PRIx64,
+ site_id, (uint64_t)addr);
+
+ if (bp_site->IsEnabled()) {
+ const size_t bp_op_size = GetSoftwareBreakpointTrapOpcode(bp_site);
- BreakpointSite::Type bp_type = bp_site->GetType();
- switch (bp_type)
- {
- case BreakpointSite::eSoftware:
- error = DisableSoftwareBreakpoint (bp_site);
- break;
+ BreakpointSite::Type bp_type = bp_site->GetType();
+ switch (bp_type) {
+ case BreakpointSite::eSoftware:
+ error = DisableSoftwareBreakpoint(bp_site);
+ break;
- case BreakpointSite::eHardware:
- if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointHardware, false, addr, bp_op_size))
- error.SetErrorToGenericError();
- break;
+ case BreakpointSite::eHardware:
+ if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointHardware, false,
+ addr, bp_op_size))
+ error.SetErrorToGenericError();
+ break;
- case BreakpointSite::eExternal:
- {
- GDBStoppointType stoppoint_type;
- if (bp_site->IsHardware())
- stoppoint_type = eBreakpointHardware;
- else
- stoppoint_type = eBreakpointSoftware;
+ case BreakpointSite::eExternal: {
+ GDBStoppointType stoppoint_type;
+ if (bp_site->IsHardware())
+ stoppoint_type = eBreakpointHardware;
+ else
+ stoppoint_type = eBreakpointSoftware;
- if (m_gdb_comm.SendGDBStoppointTypePacket(stoppoint_type, false, addr, bp_op_size))
- error.SetErrorToGenericError();
- }
- break;
- }
- if (error.Success())
- bp_site->SetEnabled(false);
- }
- else
- {
- if (log)
- log->Printf ("ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64 ") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)", site_id, (uint64_t)addr);
- return error;
+ if (m_gdb_comm.SendGDBStoppointTypePacket(stoppoint_type, false, addr,
+ bp_op_size))
+ error.SetErrorToGenericError();
+ } break;
}
-
if (error.Success())
- error.SetErrorToGenericError();
+ bp_site->SetEnabled(false);
+ } else {
+ if (log)
+ log->Printf("ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64
+ ") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)",
+ site_id, (uint64_t)addr);
return error;
+ }
+
+ if (error.Success())
+ error.SetErrorToGenericError();
+ return error;
}
// Pre-requisite: wp != NULL.
-static GDBStoppointType
-GetGDBStoppointType (Watchpoint *wp)
-{
- assert(wp);
- bool watch_read = wp->WatchpointRead();
- bool watch_write = wp->WatchpointWrite();
-
- // watch_read and watch_write cannot both be false.
- assert(watch_read || watch_write);
- if (watch_read && watch_write)
- return eWatchpointReadWrite;
- else if (watch_read)
- return eWatchpointRead;
- else // Must be watch_write, then.
- return eWatchpointWrite;
+static GDBStoppointType GetGDBStoppointType(Watchpoint *wp) {
+ assert(wp);
+ bool watch_read = wp->WatchpointRead();
+ bool watch_write = wp->WatchpointWrite();
+
+ // watch_read and watch_write cannot both be false.
+ assert(watch_read || watch_write);
+ if (watch_read && watch_write)
+ return eWatchpointReadWrite;
+ else if (watch_read)
+ return eWatchpointRead;
+ else // Must be watch_write, then.
+ return eWatchpointWrite;
}
-Error
-ProcessGDBRemote::EnableWatchpoint (Watchpoint *wp, bool notify)
-{
- Error error;
- if (wp)
- {
- user_id_t watchID = wp->GetID();
- addr_t addr = wp->GetLoadAddress();
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64 ")", watchID);
- if (wp->IsEnabled())
- {
- if (log)
- log->Printf("ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64 ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.", watchID, (uint64_t)addr);
- return error;
- }
-
- GDBStoppointType type = GetGDBStoppointType(wp);
- // Pass down an appropriate z/Z packet...
- if (m_gdb_comm.SupportsGDBStoppointPacket (type))
- {
- if (m_gdb_comm.SendGDBStoppointTypePacket(type, true, addr, wp->GetByteSize()) == 0)
- {
- wp->SetEnabled(true, notify);
- return error;
- }
- else
- error.SetErrorString("sending gdb watchpoint packet failed");
- }
- else
- error.SetErrorString("watchpoints not supported");
- }
- else
- {
- error.SetErrorString("Watchpoint argument was NULL.");
- }
- if (error.Success())
- error.SetErrorToGenericError();
- return error;
+Error ProcessGDBRemote::EnableWatchpoint(Watchpoint *wp, bool notify) {
+ Error error;
+ if (wp) {
+ user_id_t watchID = wp->GetID();
+ addr_t addr = wp->GetLoadAddress();
+ Log *log(
+ ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS));
+ if (log)
+ log->Printf("ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64 ")",
+ watchID);
+ if (wp->IsEnabled()) {
+ if (log)
+ log->Printf("ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64
+ ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
+ watchID, (uint64_t)addr);
+ return error;
+ }
+
+ GDBStoppointType type = GetGDBStoppointType(wp);
+ // Pass down an appropriate z/Z packet...
+ if (m_gdb_comm.SupportsGDBStoppointPacket(type)) {
+ if (m_gdb_comm.SendGDBStoppointTypePacket(type, true, addr,
+ wp->GetByteSize()) == 0) {
+ wp->SetEnabled(true, notify);
+ return error;
+ } else
+ error.SetErrorString("sending gdb watchpoint packet failed");
+ } else
+ error.SetErrorString("watchpoints not supported");
+ } else {
+ error.SetErrorString("Watchpoint argument was NULL.");
+ }
+ if (error.Success())
+ error.SetErrorToGenericError();
+ return error;
}
-Error
-ProcessGDBRemote::DisableWatchpoint (Watchpoint *wp, bool notify)
-{
- Error error;
- if (wp)
- {
- user_id_t watchID = wp->GetID();
-
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS));
+Error ProcessGDBRemote::DisableWatchpoint(Watchpoint *wp, bool notify) {
+ Error error;
+ if (wp) {
+ user_id_t watchID = wp->GetID();
- addr_t addr = wp->GetLoadAddress();
+ Log *log(
+ ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS));
- if (log)
- log->Printf ("ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64 ") addr = 0x%8.8" PRIx64, watchID, (uint64_t)addr);
-
- if (!wp->IsEnabled())
- {
- if (log)
- log->Printf ("ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64 ") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)", watchID, (uint64_t)addr);
- // See also 'class WatchpointSentry' within StopInfo.cpp.
- // This disabling attempt might come from the user-supplied actions, we'll route it in order for
- // the watchpoint object to intelligently process this action.
- wp->SetEnabled(false, notify);
- return error;
- }
+ addr_t addr = wp->GetLoadAddress();
- if (wp->IsHardware())
- {
- GDBStoppointType type = GetGDBStoppointType(wp);
- // Pass down an appropriate z/Z packet...
- if (m_gdb_comm.SendGDBStoppointTypePacket(type, false, addr, wp->GetByteSize()) == 0)
- {
- wp->SetEnabled(false, notify);
- return error;
- }
- else
- error.SetErrorString("sending gdb watchpoint packet failed");
- }
- // TODO: clear software watchpoints if we implement them
- }
- else
- {
- error.SetErrorString("Watchpoint argument was NULL.");
- }
- if (error.Success())
- error.SetErrorToGenericError();
- return error;
+ if (log)
+ log->Printf("ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
+ ") addr = 0x%8.8" PRIx64,
+ watchID, (uint64_t)addr);
+
+ if (!wp->IsEnabled()) {
+ if (log)
+ log->Printf("ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
+ ") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)",
+ watchID, (uint64_t)addr);
+ // See also 'class WatchpointSentry' within StopInfo.cpp.
+ // This disabling attempt might come from the user-supplied actions, we'll
+ // route it in order for
+ // the watchpoint object to intelligently process this action.
+ wp->SetEnabled(false, notify);
+ return error;
+ }
+
+ if (wp->IsHardware()) {
+ GDBStoppointType type = GetGDBStoppointType(wp);
+ // Pass down an appropriate z/Z packet...
+ if (m_gdb_comm.SendGDBStoppointTypePacket(type, false, addr,
+ wp->GetByteSize()) == 0) {
+ wp->SetEnabled(false, notify);
+ return error;
+ } else
+ error.SetErrorString("sending gdb watchpoint packet failed");
+ }
+ // TODO: clear software watchpoints if we implement them
+ } else {
+ error.SetErrorString("Watchpoint argument was NULL.");
+ }
+ if (error.Success())
+ error.SetErrorToGenericError();
+ return error;
}
-void
-ProcessGDBRemote::Clear()
-{
- m_flags = 0;
- m_thread_list_real.Clear();
- m_thread_list.Clear();
+void ProcessGDBRemote::Clear() {
+ m_flags = 0;
+ m_thread_list_real.Clear();
+ m_thread_list.Clear();
}
-Error
-ProcessGDBRemote::DoSignal (int signo)
-{
- Error error;
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf ("ProcessGDBRemote::DoSignal (signal = %d)", signo);
+Error ProcessGDBRemote::DoSignal(int signo) {
+ Error error;
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ if (log)
+ log->Printf("ProcessGDBRemote::DoSignal (signal = %d)", signo);
- if (!m_gdb_comm.SendAsyncSignal (signo))
- error.SetErrorStringWithFormat("failed to send signal %i", signo);
- return error;
+ if (!m_gdb_comm.SendAsyncSignal(signo))
+ error.SetErrorStringWithFormat("failed to send signal %i", signo);
+ return error;
}
-Error
-ProcessGDBRemote::EstablishConnectionIfNeeded (const ProcessInfo &process_info)
-{
- // Make sure we aren't already connected?
- if (m_gdb_comm.IsConnected())
- return Error();
-
- PlatformSP platform_sp (GetTarget ().GetPlatform ());
- if (platform_sp && !platform_sp->IsHost ())
- return Error("Lost debug server connection");
+Error ProcessGDBRemote::EstablishConnectionIfNeeded(
+ const ProcessInfo &process_info) {
+ // Make sure we aren't already connected?
+ if (m_gdb_comm.IsConnected())
+ return Error();
- auto error = LaunchAndConnectToDebugserver (process_info);
- if (error.Fail())
- {
- const char *error_string = error.AsCString();
- if (error_string == nullptr)
- error_string = "unable to launch " DEBUGSERVER_BASENAME;
- }
- return error;
+ PlatformSP platform_sp(GetTarget().GetPlatform());
+ if (platform_sp && !platform_sp->IsHost())
+ return Error("Lost debug server connection");
+
+ auto error = LaunchAndConnectToDebugserver(process_info);
+ if (error.Fail()) {
+ const char *error_string = error.AsCString();
+ if (error_string == nullptr)
+ error_string = "unable to launch " DEBUGSERVER_BASENAME;
+ }
+ return error;
}
+#if defined(__APPLE__)
+#define USE_SOCKETPAIR_FOR_LOCAL_CONNECTION 1
+#endif
-Error
-ProcessGDBRemote::LaunchAndConnectToDebugserver (const ProcessInfo &process_info)
-{
- using namespace std::placeholders; // For _1, _2, etc.
-
- Error error;
- if (m_debugserver_pid == LLDB_INVALID_PROCESS_ID)
- {
- // If we locate debugserver, keep that located version around
- static FileSpec g_debugserver_file_spec;
-
- ProcessLaunchInfo debugserver_launch_info;
- // Make debugserver run in its own session so signals generated by
- // special terminal key sequences (^C) don't affect debugserver.
- debugserver_launch_info.SetLaunchInSeparateProcessGroup(true);
-
- const std::weak_ptr<ProcessGDBRemote> this_wp = std::static_pointer_cast<ProcessGDBRemote>(shared_from_this());
- debugserver_launch_info.SetMonitorProcessCallback(std::bind(MonitorDebugserverProcess, this_wp, _1, _2, _3, _4),
- false);
- debugserver_launch_info.SetUserID(process_info.GetUserID());
-
-#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))
- // On iOS, still do a local connection using a random port
- const char *hostname = "127.0.0.1";
- uint16_t port = get_random_port ();
+#ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION
+static bool SetCloexecFlag(int fd) {
+#if defined(FD_CLOEXEC)
+ int flags = ::fcntl(fd, F_GETFD);
+ if (flags == -1)
+ return false;
+ return (::fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == 0);
#else
- // Set hostname being NULL to do the reverse connect where debugserver
- // will bind to port zero and it will communicate back to us the port
- // that we will connect to
- const char *hostname = nullptr;
- uint16_t port = 0;
+ return false;
+#endif
+}
#endif
- StreamString url_str;
- const char* url = nullptr;
- if (hostname != nullptr)
- {
- url_str.Printf("%s:%u", hostname, port);
- url = url_str.GetData();
- }
+Error ProcessGDBRemote::LaunchAndConnectToDebugserver(
+ const ProcessInfo &process_info) {
+ using namespace std::placeholders; // For _1, _2, etc.
+
+ Error error;
+ if (m_debugserver_pid == LLDB_INVALID_PROCESS_ID) {
+ // If we locate debugserver, keep that located version around
+ static FileSpec g_debugserver_file_spec;
+
+ ProcessLaunchInfo debugserver_launch_info;
+ // Make debugserver run in its own session so signals generated by
+ // special terminal key sequences (^C) don't affect debugserver.
+ debugserver_launch_info.SetLaunchInSeparateProcessGroup(true);
+
+ const std::weak_ptr<ProcessGDBRemote> this_wp =
+ std::static_pointer_cast<ProcessGDBRemote>(shared_from_this());
+ debugserver_launch_info.SetMonitorProcessCallback(
+ std::bind(MonitorDebugserverProcess, this_wp, _1, _2, _3, _4), false);
+ debugserver_launch_info.SetUserID(process_info.GetUserID());
+
+ int communication_fd = -1;
+#ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION
+ // Auto close the sockets we might open up unless everything goes OK. This
+ // helps us not leak file descriptors when things go wrong.
+ lldb_utility::CleanUp<int, int> our_socket(-1, -1, close);
+ lldb_utility::CleanUp<int, int> gdb_socket(-1, -1, close);
+
+ // Use a socketpair on Apple for now until other platforms can verify it
+ // works and is fast enough
+ {
+ int sockets[2]; /* the pair of socket descriptors */
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) == -1) {
+ error.SetErrorToErrno();
+ return error;
+ }
- error = m_gdb_comm.StartDebugserverProcess (url,
- GetTarget().GetPlatform().get(),
- debugserver_launch_info,
- &port);
+ our_socket.set(sockets[0]);
+ gdb_socket.set(sockets[1]);
+ }
- if (error.Success ())
- m_debugserver_pid = debugserver_launch_info.GetProcessID();
- else
- m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
+ // Don't let any child processes inherit our communication socket
+ SetCloexecFlag(our_socket.get());
+ communication_fd = gdb_socket.get();
+#endif
- if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
- StartAsyncThread ();
+ error = m_gdb_comm.StartDebugserverProcess(
+ nullptr, GetTarget().GetPlatform().get(), debugserver_launch_info,
+ nullptr, nullptr, communication_fd);
- if (error.Fail())
- {
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
+ if (error.Success())
+ m_debugserver_pid = debugserver_launch_info.GetProcessID();
+ else
+ m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
+
+ if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID) {
+#ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION
+ // Our process spawned correctly, we can now set our connection to use our
+ // end of the socket pair
+ m_gdb_comm.SetConnection(
+ new ConnectionFileDescriptor(our_socket.release(), true));
+#endif
+ StartAsyncThread();
+ }
- if (log)
- log->Printf("failed to start debugserver process: %s", error.AsCString());
- return error;
- }
+ if (error.Fail()) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (m_gdb_comm.IsConnected())
- {
- // Finish the connection process by doing the handshake without connecting (send NULL URL)
- ConnectToDebugserver (NULL);
- }
- else
- {
- StreamString connect_url;
- connect_url.Printf("connect://%s:%u", hostname, port);
- error = ConnectToDebugserver (connect_url.GetString().c_str());
- }
+ if (log)
+ log->Printf("failed to start debugserver process: %s",
+ error.AsCString());
+ return error;
+ }
+ if (m_gdb_comm.IsConnected()) {
+ // Finish the connection process by doing the handshake without connecting
+ // (send NULL URL)
+ ConnectToDebugserver("");
+ } else {
+ error.SetErrorString("connection failed");
}
- return error;
+ }
+ return error;
}
-bool
-ProcessGDBRemote::MonitorDebugserverProcess(std::weak_ptr<ProcessGDBRemote> process_wp, lldb::pid_t debugserver_pid,
- bool exited, // True if the process did exit
- int signo, // Zero for no signal
- int exit_status // Exit value of process if signal is zero
- )
-{
- // "debugserver_pid" argument passed in is the process ID for
- // debugserver that we are tracking...
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- const bool handled = true;
-
- if (log)
- log->Printf("ProcessGDBRemote::%s(process_wp, pid=%" PRIu64 ", signo=%i (0x%x), exit_status=%i)", __FUNCTION__,
- debugserver_pid, signo, signo, exit_status);
-
- std::shared_ptr<ProcessGDBRemote> process_sp = process_wp.lock();
- if (log)
- log->Printf("ProcessGDBRemote::%s(process = %p)", __FUNCTION__, static_cast<void *>(process_sp.get()));
- if (!process_sp || process_sp->m_debugserver_pid != debugserver_pid)
- return handled;
-
- // Sleep for a half a second to make sure our inferior process has
- // time to set its exit status before we set it incorrectly when
- // both the debugserver and the inferior process shut down.
- usleep(500000);
- // If our process hasn't yet exited, debugserver might have died.
- // If the process did exit, then we are reaping it.
- const StateType state = process_sp->GetState();
-
- if (state != eStateInvalid && state != eStateUnloaded && state != eStateExited && state != eStateDetached)
- {
- char error_str[1024];
- if (signo)
- {
- const char *signal_cstr = process_sp->GetUnixSignals()->GetSignalAsCString(signo);
- if (signal_cstr)
- ::snprintf(error_str, sizeof(error_str), DEBUGSERVER_BASENAME " died with signal %s", signal_cstr);
- else
- ::snprintf(error_str, sizeof(error_str), DEBUGSERVER_BASENAME " died with signal %i", signo);
- }
- else
- {
- ::snprintf(error_str, sizeof(error_str), DEBUGSERVER_BASENAME " died with an exit status of 0x%8.8x",
- exit_status);
- }
+bool ProcessGDBRemote::MonitorDebugserverProcess(
+ std::weak_ptr<ProcessGDBRemote> process_wp, lldb::pid_t debugserver_pid,
+ bool exited, // True if the process did exit
+ int signo, // Zero for no signal
+ int exit_status // Exit value of process if signal is zero
+ ) {
+ // "debugserver_pid" argument passed in is the process ID for
+ // debugserver that we are tracking...
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ const bool handled = true;
+
+ if (log)
+ log->Printf("ProcessGDBRemote::%s(process_wp, pid=%" PRIu64
+ ", signo=%i (0x%x), exit_status=%i)",
+ __FUNCTION__, debugserver_pid, signo, signo, exit_status);
+
+ std::shared_ptr<ProcessGDBRemote> process_sp = process_wp.lock();
+ if (log)
+ log->Printf("ProcessGDBRemote::%s(process = %p)", __FUNCTION__,
+ static_cast<void *>(process_sp.get()));
+ if (!process_sp || process_sp->m_debugserver_pid != debugserver_pid)
+ return handled;
- process_sp->SetExitStatus(-1, error_str);
+ // Sleep for a half a second to make sure our inferior process has
+ // time to set its exit status before we set it incorrectly when
+ // both the debugserver and the inferior process shut down.
+ usleep(500000);
+ // If our process hasn't yet exited, debugserver might have died.
+ // If the process did exit, then we are reaping it.
+ const StateType state = process_sp->GetState();
+
+ if (state != eStateInvalid && state != eStateUnloaded &&
+ state != eStateExited && state != eStateDetached) {
+ char error_str[1024];
+ if (signo) {
+ const char *signal_cstr =
+ process_sp->GetUnixSignals()->GetSignalAsCString(signo);
+ if (signal_cstr)
+ ::snprintf(error_str, sizeof(error_str),
+ DEBUGSERVER_BASENAME " died with signal %s", signal_cstr);
+ else
+ ::snprintf(error_str, sizeof(error_str),
+ DEBUGSERVER_BASENAME " died with signal %i", signo);
+ } else {
+ ::snprintf(error_str, sizeof(error_str),
+ DEBUGSERVER_BASENAME " died with an exit status of 0x%8.8x",
+ exit_status);
}
- // Debugserver has exited we need to let our ProcessGDBRemote
- // know that it no longer has a debugserver instance
- process_sp->m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
- return handled;
+
+ process_sp->SetExitStatus(-1, error_str);
+ }
+ // Debugserver has exited we need to let our ProcessGDBRemote
+ // know that it no longer has a debugserver instance
+ process_sp->m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
+ return handled;
}
-void
-ProcessGDBRemote::KillDebugserverProcess ()
-{
- m_gdb_comm.Disconnect();
- if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
- {
- Host::Kill (m_debugserver_pid, SIGINT);
- m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
- }
+void ProcessGDBRemote::KillDebugserverProcess() {
+ m_gdb_comm.Disconnect();
+ if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID) {
+ Host::Kill(m_debugserver_pid, SIGINT);
+ m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
+ }
}
-void
-ProcessGDBRemote::Initialize()
-{
- static std::once_flag g_once_flag;
+void ProcessGDBRemote::Initialize() {
+ static std::once_flag g_once_flag;
- std::call_once(g_once_flag, []()
- {
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance,
- DebuggerInitialize);
- });
+ std::call_once(g_once_flag, []() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance,
+ DebuggerInitialize);
+ });
}
-void
-ProcessGDBRemote::DebuggerInitialize (Debugger &debugger)
-{
- if (!PluginManager::GetSettingForProcessPlugin(debugger, PluginProperties::GetSettingName()))
- {
- const bool is_global_setting = true;
- PluginManager::CreateSettingForProcessPlugin (debugger,
- GetGlobalPluginProperties()->GetValueProperties(),
- ConstString ("Properties for the gdb-remote process plug-in."),
- is_global_setting);
- }
+void ProcessGDBRemote::DebuggerInitialize(Debugger &debugger) {
+ if (!PluginManager::GetSettingForProcessPlugin(
+ debugger, PluginProperties::GetSettingName())) {
+ const bool is_global_setting = true;
+ PluginManager::CreateSettingForProcessPlugin(
+ debugger, GetGlobalPluginProperties()->GetValueProperties(),
+ ConstString("Properties for the gdb-remote process plug-in."),
+ is_global_setting);
+ }
}
-bool
-ProcessGDBRemote::StartAsyncThread ()
-{
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+bool ProcessGDBRemote::StartAsyncThread() {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf ("ProcessGDBRemote::%s ()", __FUNCTION__);
+ if (log)
+ log->Printf("ProcessGDBRemote::%s ()", __FUNCTION__);
- std::lock_guard<std::recursive_mutex> guard(m_async_thread_state_mutex);
- if (!m_async_thread.IsJoinable())
- {
- // Create a thread that watches our internal state and controls which
- // events make it to clients (into the DCProcess event queue).
+ std::lock_guard<std::recursive_mutex> guard(m_async_thread_state_mutex);
+ if (!m_async_thread.IsJoinable()) {
+ // Create a thread that watches our internal state and controls which
+ // events make it to clients (into the DCProcess event queue).
- m_async_thread = ThreadLauncher::LaunchThread("<lldb.process.gdb-remote.async>", ProcessGDBRemote::AsyncThread, this, NULL);
- }
- else if (log)
- log->Printf("ProcessGDBRemote::%s () - Called when Async thread was already running.", __FUNCTION__);
+ m_async_thread =
+ ThreadLauncher::LaunchThread("<lldb.process.gdb-remote.async>",
+ ProcessGDBRemote::AsyncThread, this, NULL);
+ } else if (log)
+ log->Printf("ProcessGDBRemote::%s () - Called when Async thread was "
+ "already running.",
+ __FUNCTION__);
- return m_async_thread.IsJoinable();
+ return m_async_thread.IsJoinable();
}
-void
-ProcessGDBRemote::StopAsyncThread ()
-{
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+void ProcessGDBRemote::StopAsyncThread() {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf ("ProcessGDBRemote::%s ()", __FUNCTION__);
+ if (log)
+ log->Printf("ProcessGDBRemote::%s ()", __FUNCTION__);
- std::lock_guard<std::recursive_mutex> guard(m_async_thread_state_mutex);
- if (m_async_thread.IsJoinable())
- {
- m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncThreadShouldExit);
+ std::lock_guard<std::recursive_mutex> guard(m_async_thread_state_mutex);
+ if (m_async_thread.IsJoinable()) {
+ m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncThreadShouldExit);
- // This will shut down the async thread.
- m_gdb_comm.Disconnect(); // Disconnect from the debug server.
+ // This will shut down the async thread.
+ m_gdb_comm.Disconnect(); // Disconnect from the debug server.
- // Stop the stdio thread
- m_async_thread.Join(nullptr);
- m_async_thread.Reset();
- }
- else if (log)
- log->Printf("ProcessGDBRemote::%s () - Called when Async thread was not running.", __FUNCTION__);
+ // Stop the stdio thread
+ m_async_thread.Join(nullptr);
+ m_async_thread.Reset();
+ } else if (log)
+ log->Printf(
+ "ProcessGDBRemote::%s () - Called when Async thread was not running.",
+ __FUNCTION__);
}
-bool
-ProcessGDBRemote::HandleNotifyPacket (StringExtractorGDBRemote &packet)
-{
- // get the packet at a string
- const std::string &pkt = packet.GetStringRef();
- // skip %stop:
- StringExtractorGDBRemote stop_info(pkt.c_str() + 5);
-
- // pass as a thread stop info packet
- SetLastStopPacket(stop_info);
-
- // check for more stop reasons
- HandleStopReplySequence();
-
- // if the process is stopped then we need to fake a resume
- // so that we can stop properly with the new break. This
- // is possible due to SetPrivateState() broadcasting the
- // state change as a side effect.
- if (GetPrivateState() == lldb::StateType::eStateStopped)
- {
- SetPrivateState(lldb::StateType::eStateRunning);
- }
+bool ProcessGDBRemote::HandleNotifyPacket(StringExtractorGDBRemote &packet) {
+ // get the packet at a string
+ const std::string &pkt = packet.GetStringRef();
+ // skip %stop:
+ StringExtractorGDBRemote stop_info(pkt.c_str() + 5);
- // since we have some stopped packets we can halt the process
- SetPrivateState(lldb::StateType::eStateStopped);
+ // pass as a thread stop info packet
+ SetLastStopPacket(stop_info);
- return true;
+ // check for more stop reasons
+ HandleStopReplySequence();
+
+ // if the process is stopped then we need to fake a resume
+ // so that we can stop properly with the new break. This
+ // is possible due to SetPrivateState() broadcasting the
+ // state change as a side effect.
+ if (GetPrivateState() == lldb::StateType::eStateStopped) {
+ SetPrivateState(lldb::StateType::eStateRunning);
+ }
+
+ // since we have some stopped packets we can halt the process
+ SetPrivateState(lldb::StateType::eStateStopped);
+
+ return true;
}
-thread_result_t
-ProcessGDBRemote::AsyncThread (void *arg)
-{
- ProcessGDBRemote *process = (ProcessGDBRemote*) arg;
+thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
+ ProcessGDBRemote *process = (ProcessGDBRemote *)arg;
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
- if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") thread starting...", __FUNCTION__, arg, process->GetID());
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ if (log)
+ log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") thread starting...",
+ __FUNCTION__, arg, process->GetID());
- EventSP event_sp;
- bool done = false;
- while (!done)
- {
+ EventSP event_sp;
+ bool done = false;
+ while (!done) {
+ if (log)
+ log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") listener.WaitForEvent (NULL, event_sp)...",
+ __FUNCTION__, arg, process->GetID());
+ if (process->m_async_listener_sp->GetEvent(event_sp, llvm::None)) {
+ const uint32_t event_type = event_sp->GetType();
+ if (event_sp->BroadcasterIs(&process->m_async_broadcaster)) {
if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") listener.WaitForEvent (NULL, event_sp)...", __FUNCTION__, arg, process->GetID());
- if (process->m_async_listener_sp->WaitForEvent (NULL, event_sp))
- {
- const uint32_t event_type = event_sp->GetType();
- if (event_sp->BroadcasterIs (&process->m_async_broadcaster))
- {
- if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") Got an event of type: %d...", __FUNCTION__, arg, process->GetID(), event_type);
-
- switch (event_type)
- {
- case eBroadcastBitAsyncContinue:
- {
- const EventDataBytes *continue_packet = EventDataBytes::GetEventDataFromEvent(event_sp.get());
-
- if (continue_packet)
- {
- const char *continue_cstr = (const char *)continue_packet->GetBytes ();
- const size_t continue_cstr_len = continue_packet->GetByteSize ();
- if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") got eBroadcastBitAsyncContinue: %s", __FUNCTION__, arg, process->GetID(), continue_cstr);
-
- if (::strstr (continue_cstr, "vAttach") == NULL)
- process->SetPrivateState(eStateRunning);
- StringExtractorGDBRemote response;
-
- // If in Non-Stop-Mode
- if (process->GetTarget().GetNonStopModeEnabled())
- {
- // send the vCont packet
- if (!process->GetGDBRemote().SendvContPacket(process, continue_cstr, continue_cstr_len, response))
- {
- // Something went wrong
- done = true;
- break;
- }
- }
- // If in All-Stop-Mode
- else
- {
- StateType stop_state = process->GetGDBRemote().SendContinuePacketAndWaitForResponse (process, continue_cstr, continue_cstr_len, response);
-
- // We need to immediately clear the thread ID list so we are sure to get a valid list of threads.
- // The thread ID list might be contained within the "response", or the stop reply packet that
- // caused the stop. So clear it now before we give the stop reply packet to the process
- // using the process->SetLastStopPacket()...
- process->ClearThreadIDList ();
-
- switch (stop_state)
- {
- case eStateStopped:
- case eStateCrashed:
- case eStateSuspended:
- process->SetLastStopPacket (response);
- process->SetPrivateState (stop_state);
- break;
-
- case eStateExited:
- {
- process->SetLastStopPacket (response);
- process->ClearThreadIDList();
- response.SetFilePos(1);
-
- int exit_status = response.GetHexU8();
- const char *desc_cstr = NULL;
- StringExtractor extractor;
- std::string desc_string;
- if (response.GetBytesLeft() > 0 && response.GetChar('-') == ';')
- {
- std::string desc_token;
- while (response.GetNameColonValue (desc_token, desc_string))
- {
- if (desc_token == "description")
- {
- extractor.GetStringRef().swap(desc_string);
- extractor.SetFilePos(0);
- extractor.GetHexByteString (desc_string);
- desc_cstr = desc_string.c_str();
- }
- }
- }
- process->SetExitStatus(exit_status, desc_cstr);
- done = true;
- break;
- }
- case eStateInvalid:
- {
- // Check to see if we were trying to attach and if we got back
- // the "E87" error code from debugserver -- this indicates that
- // the process is not debuggable. Return a slightly more helpful
- // error message about why the attach failed.
- if (::strstr (continue_cstr, "vAttach") != NULL
- && response.GetError() == 0x87)
- {
- process->SetExitStatus(-1, "cannot attach to process due to System Integrity Protection");
- }
- // E01 code from vAttach means that the attach failed
- if (::strstr (continue_cstr, "vAttach") != NULL
- && response.GetError() == 0x1)
- {
- process->SetExitStatus(-1, "unable to attach");
- }
- else
- {
- process->SetExitStatus(-1, "lost connection");
- }
- break;
- }
-
- default:
- process->SetPrivateState (stop_state);
- break;
- } // switch(stop_state)
- } // else // if in All-stop-mode
- } // if (continue_packet)
- } // case eBroadcastBitAysncContinue
- break;
-
- case eBroadcastBitAsyncThreadShouldExit:
- if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") got eBroadcastBitAsyncThreadShouldExit...", __FUNCTION__, arg, process->GetID());
- done = true;
- break;
-
- default:
- if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") got unknown event 0x%8.8x", __FUNCTION__, arg, process->GetID(), event_type);
- done = true;
- break;
- }
+ log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") Got an event of type: %d...",
+ __FUNCTION__, arg, process->GetID(), event_type);
+
+ switch (event_type) {
+ case eBroadcastBitAsyncContinue: {
+ const EventDataBytes *continue_packet =
+ EventDataBytes::GetEventDataFromEvent(event_sp.get());
+
+ if (continue_packet) {
+ const char *continue_cstr =
+ (const char *)continue_packet->GetBytes();
+ const size_t continue_cstr_len = continue_packet->GetByteSize();
+ if (log)
+ log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") got eBroadcastBitAsyncContinue: %s",
+ __FUNCTION__, arg, process->GetID(), continue_cstr);
+
+ if (::strstr(continue_cstr, "vAttach") == NULL)
+ process->SetPrivateState(eStateRunning);
+ StringExtractorGDBRemote response;
+
+ // If in Non-Stop-Mode
+ if (process->GetTarget().GetNonStopModeEnabled()) {
+ // send the vCont packet
+ if (!process->GetGDBRemote().SendvContPacket(
+ llvm::StringRef(continue_cstr, continue_cstr_len),
+ response)) {
+ // Something went wrong
+ done = true;
+ break;
+ }
}
- else if (event_sp->BroadcasterIs (&process->m_gdb_comm))
- {
- switch (event_type)
- {
- case Communication::eBroadcastBitReadThreadDidExit:
- process->SetExitStatus (-1, "lost connection");
- done = true;
- break;
-
- case GDBRemoteCommunication::eBroadcastBitGdbReadThreadGotNotify:
- {
- lldb_private::Event *event = event_sp.get();
- const EventDataBytes *continue_packet = EventDataBytes::GetEventDataFromEvent(event);
- StringExtractorGDBRemote notify((const char*)continue_packet->GetBytes());
- // Hand this over to the process to handle
- process->HandleNotifyPacket(notify);
- break;
- }
-
- default:
- if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") got unknown event 0x%8.8x", __FUNCTION__, arg, process->GetID(), event_type);
- done = true;
- break;
+ // If in All-Stop-Mode
+ else {
+ StateType stop_state =
+ process->GetGDBRemote().SendContinuePacketAndWaitForResponse(
+ *process, *process->GetUnixSignals(),
+ llvm::StringRef(continue_cstr, continue_cstr_len),
+ response);
+
+ // We need to immediately clear the thread ID list so we are sure
+ // to get a valid list of threads.
+ // The thread ID list might be contained within the "response", or
+ // the stop reply packet that
+ // caused the stop. So clear it now before we give the stop reply
+ // packet to the process
+ // using the process->SetLastStopPacket()...
+ process->ClearThreadIDList();
+
+ switch (stop_state) {
+ case eStateStopped:
+ case eStateCrashed:
+ case eStateSuspended:
+ process->SetLastStopPacket(response);
+ process->SetPrivateState(stop_state);
+ break;
+
+ case eStateExited: {
+ process->SetLastStopPacket(response);
+ process->ClearThreadIDList();
+ response.SetFilePos(1);
+
+ int exit_status = response.GetHexU8();
+ std::string desc_string;
+ if (response.GetBytesLeft() > 0 &&
+ response.GetChar('-') == ';') {
+ llvm::StringRef desc_str;
+ llvm::StringRef desc_token;
+ while (response.GetNameColonValue(desc_token, desc_str)) {
+ if (desc_token != "description")
+ continue;
+ StringExtractor extractor(desc_str);
+ extractor.GetHexByteString(desc_string);
+ }
}
- }
+ process->SetExitStatus(exit_status, desc_string.c_str());
+ done = true;
+ break;
+ }
+ case eStateInvalid: {
+ // Check to see if we were trying to attach and if we got back
+ // the "E87" error code from debugserver -- this indicates that
+ // the process is not debuggable. Return a slightly more
+ // helpful
+ // error message about why the attach failed.
+ if (::strstr(continue_cstr, "vAttach") != NULL &&
+ response.GetError() == 0x87) {
+ process->SetExitStatus(-1, "cannot attach to process due to "
+ "System Integrity Protection");
+ }
+ // E01 code from vAttach means that the attach failed
+ if (::strstr(continue_cstr, "vAttach") != NULL &&
+ response.GetError() == 0x1) {
+ process->SetExitStatus(-1, "unable to attach");
+ } else {
+ process->SetExitStatus(-1, "lost connection");
+ }
+ break;
+ }
+
+ default:
+ process->SetPrivateState(stop_state);
+ break;
+ } // switch(stop_state)
+ } // else // if in All-stop-mode
+ } // if (continue_packet)
+ } // case eBroadcastBitAysncContinue
+ break;
+
+ case eBroadcastBitAsyncThreadShouldExit:
+ if (log)
+ log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") got eBroadcastBitAsyncThreadShouldExit...",
+ __FUNCTION__, arg, process->GetID());
+ done = true;
+ break;
+
+ default:
+ if (log)
+ log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") got unknown event 0x%8.8x",
+ __FUNCTION__, arg, process->GetID(), event_type);
+ done = true;
+ break;
}
- else
- {
- if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") listener.WaitForEvent (NULL, event_sp) => false", __FUNCTION__, arg, process->GetID());
- done = true;
+ } else if (event_sp->BroadcasterIs(&process->m_gdb_comm)) {
+ switch (event_type) {
+ case Communication::eBroadcastBitReadThreadDidExit:
+ process->SetExitStatus(-1, "lost connection");
+ done = true;
+ break;
+
+ case GDBRemoteCommunication::eBroadcastBitGdbReadThreadGotNotify: {
+ lldb_private::Event *event = event_sp.get();
+ const EventDataBytes *continue_packet =
+ EventDataBytes::GetEventDataFromEvent(event);
+ StringExtractorGDBRemote notify(
+ (const char *)continue_packet->GetBytes());
+ // Hand this over to the process to handle
+ process->HandleNotifyPacket(notify);
+ break;
+ }
+
+ default:
+ if (log)
+ log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") got unknown event 0x%8.8x",
+ __FUNCTION__, arg, process->GetID(), event_type);
+ done = true;
+ break;
}
+ }
+ } else {
+ if (log)
+ log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") listener.WaitForEvent (NULL, event_sp) => false",
+ __FUNCTION__, arg, process->GetID());
+ done = true;
}
+ }
- if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") thread exiting...", __FUNCTION__, arg, process->GetID());
+ if (log)
+ log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+ ") thread exiting...",
+ __FUNCTION__, arg, process->GetID());
- return NULL;
+ return NULL;
}
-//uint32_t
-//ProcessGDBRemote::ListProcessesMatchingName (const char *name, StringList &matches, std::vector<lldb::pid_t> &pids)
+// uint32_t
+// ProcessGDBRemote::ListProcessesMatchingName (const char *name, StringList
+// &matches, std::vector<lldb::pid_t> &pids)
//{
-// // If we are planning to launch the debugserver remotely, then we need to fire up a debugserver
-// // process and ask it for the list of processes. But if we are local, we can let the Host do it.
+// // If we are planning to launch the debugserver remotely, then we need to
+// fire up a debugserver
+// // process and ask it for the list of processes. But if we are local, we
+// can let the Host do it.
// if (m_local_debugserver)
// {
// return Host::ListProcessesMatchingName (name, matches, pids);
@@ -4068,189 +3727,240 @@ ProcessGDBRemote::AsyncThread (void *arg)
//
//}
//
-bool
-ProcessGDBRemote::NewThreadNotifyBreakpointHit (void *baton,
- StoppointCallbackContext *context,
- lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id)
-{
- // I don't think I have to do anything here, just make sure I notice the new thread when it starts to
- // run so I can stop it if that's what I want to do.
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
- if (log)
- log->Printf("Hit New Thread Notification breakpoint.");
- return false;
+bool ProcessGDBRemote::NewThreadNotifyBreakpointHit(
+ void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id) {
+ // I don't think I have to do anything here, just make sure I notice the new
+ // thread when it starts to
+ // run so I can stop it if that's what I want to do.
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+ if (log)
+ log->Printf("Hit New Thread Notification breakpoint.");
+ return false;
}
-
-bool
-ProcessGDBRemote::StartNoticingNewThreads()
-{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
- if (m_thread_create_bp_sp)
- {
+bool ProcessGDBRemote::StartNoticingNewThreads() {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+ if (m_thread_create_bp_sp) {
+ if (log && log->GetVerbose())
+ log->Printf("Enabled noticing new thread breakpoint.");
+ m_thread_create_bp_sp->SetEnabled(true);
+ } else {
+ PlatformSP platform_sp(GetTarget().GetPlatform());
+ if (platform_sp) {
+ m_thread_create_bp_sp =
+ platform_sp->SetThreadCreationBreakpoint(GetTarget());
+ if (m_thread_create_bp_sp) {
if (log && log->GetVerbose())
- log->Printf("Enabled noticing new thread breakpoint.");
- m_thread_create_bp_sp->SetEnabled(true);
- }
- else
- {
- PlatformSP platform_sp (GetTarget().GetPlatform());
- if (platform_sp)
- {
- m_thread_create_bp_sp = platform_sp->SetThreadCreationBreakpoint(GetTarget());
- if (m_thread_create_bp_sp)
- {
- if (log && log->GetVerbose())
- log->Printf("Successfully created new thread notification breakpoint %i", m_thread_create_bp_sp->GetID());
- m_thread_create_bp_sp->SetCallback (ProcessGDBRemote::NewThreadNotifyBreakpointHit, this, true);
- }
- else
- {
- if (log)
- log->Printf("Failed to create new thread notification breakpoint.");
- }
- }
+ log->Printf(
+ "Successfully created new thread notification breakpoint %i",
+ m_thread_create_bp_sp->GetID());
+ m_thread_create_bp_sp->SetCallback(
+ ProcessGDBRemote::NewThreadNotifyBreakpointHit, this, true);
+ } else {
+ if (log)
+ log->Printf("Failed to create new thread notification breakpoint.");
+ }
}
- return m_thread_create_bp_sp.get() != NULL;
+ }
+ return m_thread_create_bp_sp.get() != NULL;
}
-bool
-ProcessGDBRemote::StopNoticingNewThreads()
-{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
- if (log && log->GetVerbose())
- log->Printf ("Disabling new thread notification breakpoint.");
+bool ProcessGDBRemote::StopNoticingNewThreads() {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+ if (log && log->GetVerbose())
+ log->Printf("Disabling new thread notification breakpoint.");
- if (m_thread_create_bp_sp)
- m_thread_create_bp_sp->SetEnabled(false);
+ if (m_thread_create_bp_sp)
+ m_thread_create_bp_sp->SetEnabled(false);
- return true;
+ return true;
}
-DynamicLoader *
-ProcessGDBRemote::GetDynamicLoader ()
-{
- if (m_dyld_ap.get() == NULL)
- m_dyld_ap.reset (DynamicLoader::FindPlugin(this, NULL));
- return m_dyld_ap.get();
+DynamicLoader *ProcessGDBRemote::GetDynamicLoader() {
+ if (m_dyld_ap.get() == NULL)
+ m_dyld_ap.reset(DynamicLoader::FindPlugin(this, NULL));
+ return m_dyld_ap.get();
}
-Error
-ProcessGDBRemote::SendEventData(const char *data)
-{
- int return_value;
- bool was_supported;
+Error ProcessGDBRemote::SendEventData(const char *data) {
+ int return_value;
+ bool was_supported;
- Error error;
+ Error error;
- return_value = m_gdb_comm.SendLaunchEventDataPacket (data, &was_supported);
- if (return_value != 0)
- {
- if (!was_supported)
- error.SetErrorString("Sending events is not supported for this process.");
- else
- error.SetErrorStringWithFormat("Error sending event data: %d.", return_value);
- }
- return error;
+ return_value = m_gdb_comm.SendLaunchEventDataPacket(data, &was_supported);
+ if (return_value != 0) {
+ if (!was_supported)
+ error.SetErrorString("Sending events is not supported for this process.");
+ else
+ error.SetErrorStringWithFormat("Error sending event data: %d.",
+ return_value);
+ }
+ return error;
}
-const DataBufferSP
-ProcessGDBRemote::GetAuxvData()
-{
- DataBufferSP buf;
- if (m_gdb_comm.GetQXferAuxvReadSupported())
- {
- std::string response_string;
- if (m_gdb_comm.SendPacketsAndConcatenateResponses("qXfer:auxv:read::", response_string) == GDBRemoteCommunication::PacketResult::Success)
- buf.reset(new DataBufferHeap(response_string.c_str(), response_string.length()));
- }
- return buf;
+const DataBufferSP ProcessGDBRemote::GetAuxvData() {
+ DataBufferSP buf;
+ if (m_gdb_comm.GetQXferAuxvReadSupported()) {
+ std::string response_string;
+ if (m_gdb_comm.SendPacketsAndConcatenateResponses("qXfer:auxv:read::",
+ response_string) ==
+ GDBRemoteCommunication::PacketResult::Success)
+ buf.reset(new DataBufferHeap(response_string.c_str(),
+ response_string.length()));
+ }
+ return buf;
}
StructuredData::ObjectSP
-ProcessGDBRemote::GetExtendedInfoForThread (lldb::tid_t tid)
-{
- StructuredData::ObjectSP object_sp;
+ProcessGDBRemote::GetExtendedInfoForThread(lldb::tid_t tid) {
+ StructuredData::ObjectSP object_sp;
- if (m_gdb_comm.GetThreadExtendedInfoSupported())
- {
- StructuredData::ObjectSP args_dict(new StructuredData::Dictionary());
- SystemRuntime *runtime = GetSystemRuntime();
- if (runtime)
- {
- runtime->AddThreadExtendedInfoPacketHints (args_dict);
- }
- args_dict->GetAsDictionary()->AddIntegerItem ("thread", tid);
+ if (m_gdb_comm.GetThreadExtendedInfoSupported()) {
+ StructuredData::ObjectSP args_dict(new StructuredData::Dictionary());
+ SystemRuntime *runtime = GetSystemRuntime();
+ if (runtime) {
+ runtime->AddThreadExtendedInfoPacketHints(args_dict);
+ }
+ args_dict->GetAsDictionary()->AddIntegerItem("thread", tid);
- StreamString packet;
- packet << "jThreadExtendedInfo:";
- args_dict->Dump (packet);
+ StreamString packet;
+ packet << "jThreadExtendedInfo:";
+ args_dict->Dump(packet, false);
- // FIXME the final character of a JSON dictionary, '}', is the escape
- // character in gdb-remote binary mode. lldb currently doesn't escape
- // these characters in its packet output -- so we add the quoted version
- // of the } character here manually in case we talk to a debugserver which
- // un-escapes the characters at packet read time.
- packet << (char) (0x7d ^ 0x20);
+ // FIXME the final character of a JSON dictionary, '}', is the escape
+ // character in gdb-remote binary mode. lldb currently doesn't escape
+ // these characters in its packet output -- so we add the quoted version
+ // of the } character here manually in case we talk to a debugserver which
+ // un-escapes the characters at packet read time.
+ packet << (char)(0x7d ^ 0x20);
- StringExtractorGDBRemote response;
- response.SetResponseValidatorToJSON();
- if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(), response, false) == GDBRemoteCommunication::PacketResult::Success)
- {
- StringExtractorGDBRemote::ResponseType response_type = response.GetResponseType();
- if (response_type == StringExtractorGDBRemote::eResponse)
- {
- if (!response.Empty())
- {
- object_sp = StructuredData::ParseJSON (response.GetStringRef());
- }
- }
+ StringExtractorGDBRemote response;
+ response.SetResponseValidatorToJSON();
+ if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response,
+ false) ==
+ GDBRemoteCommunication::PacketResult::Success) {
+ StringExtractorGDBRemote::ResponseType response_type =
+ response.GetResponseType();
+ if (response_type == StringExtractorGDBRemote::eResponse) {
+ if (!response.Empty()) {
+ object_sp = StructuredData::ParseJSON(response.GetStringRef());
}
+ }
}
- return object_sp;
+ }
+ return object_sp;
+}
+
+StructuredData::ObjectSP ProcessGDBRemote::GetLoadedDynamicLibrariesInfos(
+ lldb::addr_t image_list_address, lldb::addr_t image_count) {
+
+ StructuredData::ObjectSP args_dict(new StructuredData::Dictionary());
+ args_dict->GetAsDictionary()->AddIntegerItem("image_list_address",
+ image_list_address);
+ args_dict->GetAsDictionary()->AddIntegerItem("image_count", image_count);
+
+ return GetLoadedDynamicLibrariesInfos_sender(args_dict);
+}
+
+StructuredData::ObjectSP ProcessGDBRemote::GetLoadedDynamicLibrariesInfos() {
+ StructuredData::ObjectSP args_dict(new StructuredData::Dictionary());
+
+ args_dict->GetAsDictionary()->AddBooleanItem("fetch_all_solibs", true);
+
+ return GetLoadedDynamicLibrariesInfos_sender(args_dict);
+}
+
+StructuredData::ObjectSP ProcessGDBRemote::GetLoadedDynamicLibrariesInfos(
+ const std::vector<lldb::addr_t> &load_addresses) {
+ StructuredData::ObjectSP args_dict(new StructuredData::Dictionary());
+ StructuredData::ArraySP addresses(new StructuredData::Array);
+
+ for (auto addr : load_addresses) {
+ StructuredData::ObjectSP addr_sp(new StructuredData::Integer(addr));
+ addresses->AddItem(addr_sp);
+ }
+
+ args_dict->GetAsDictionary()->AddItem("solib_addresses", addresses);
+
+ return GetLoadedDynamicLibrariesInfos_sender(args_dict);
}
StructuredData::ObjectSP
-ProcessGDBRemote::GetLoadedDynamicLibrariesInfos (lldb::addr_t image_list_address, lldb::addr_t image_count)
-{
- StructuredData::ObjectSP object_sp;
+ProcessGDBRemote::GetLoadedDynamicLibrariesInfos_sender(
+ StructuredData::ObjectSP args_dict) {
+ StructuredData::ObjectSP object_sp;
- if (m_gdb_comm.GetLoadedDynamicLibrariesInfosSupported())
- {
- // Scope for the scoped timeout object
- GDBRemoteCommunication::ScopedTimeout timeout (m_gdb_comm, 10);
+ if (m_gdb_comm.GetLoadedDynamicLibrariesInfosSupported()) {
+ // Scope for the scoped timeout object
+ GDBRemoteCommunication::ScopedTimeout timeout(m_gdb_comm,
+ std::chrono::seconds(10));
- StructuredData::ObjectSP args_dict(new StructuredData::Dictionary());
- args_dict->GetAsDictionary()->AddIntegerItem ("image_list_address", image_list_address);
- args_dict->GetAsDictionary()->AddIntegerItem ("image_count", image_count);
+ StreamString packet;
+ packet << "jGetLoadedDynamicLibrariesInfos:";
+ args_dict->Dump(packet, false);
- StreamString packet;
- packet << "jGetLoadedDynamicLibrariesInfos:";
- args_dict->Dump (packet);
+ // FIXME the final character of a JSON dictionary, '}', is the escape
+ // character in gdb-remote binary mode. lldb currently doesn't escape
+ // these characters in its packet output -- so we add the quoted version
+ // of the } character here manually in case we talk to a debugserver which
+ // un-escapes the characters at packet read time.
+ packet << (char)(0x7d ^ 0x20);
- // FIXME the final character of a JSON dictionary, '}', is the escape
- // character in gdb-remote binary mode. lldb currently doesn't escape
- // these characters in its packet output -- so we add the quoted version
- // of the } character here manually in case we talk to a debugserver which
- // un-escapes the characters at packet read time.
- packet << (char) (0x7d ^ 0x20);
+ StringExtractorGDBRemote response;
+ response.SetResponseValidatorToJSON();
+ if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response,
+ false) ==
+ GDBRemoteCommunication::PacketResult::Success) {
+ StringExtractorGDBRemote::ResponseType response_type =
+ response.GetResponseType();
+ if (response_type == StringExtractorGDBRemote::eResponse) {
+ if (!response.Empty()) {
+ object_sp = StructuredData::ParseJSON(response.GetStringRef());
+ }
+ }
+ }
+ }
+ return object_sp;
+}
- StringExtractorGDBRemote response;
- response.SetResponseValidatorToJSON();
- if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(), response, false) == GDBRemoteCommunication::PacketResult::Success)
- {
- StringExtractorGDBRemote::ResponseType response_type = response.GetResponseType();
- if (response_type == StringExtractorGDBRemote::eResponse)
- {
- if (!response.Empty())
- {
- object_sp = StructuredData::ParseJSON (response.GetStringRef());
- }
- }
+StructuredData::ObjectSP ProcessGDBRemote::GetSharedCacheInfo() {
+ StructuredData::ObjectSP object_sp;
+ StructuredData::ObjectSP args_dict(new StructuredData::Dictionary());
+
+ if (m_gdb_comm.GetSharedCacheInfoSupported()) {
+ StreamString packet;
+ packet << "jGetSharedCacheInfo:";
+ args_dict->Dump(packet, false);
+
+ // FIXME the final character of a JSON dictionary, '}', is the escape
+ // character in gdb-remote binary mode. lldb currently doesn't escape
+ // these characters in its packet output -- so we add the quoted version
+ // of the } character here manually in case we talk to a debugserver which
+ // un-escapes the characters at packet read time.
+ packet << (char)(0x7d ^ 0x20);
+
+ StringExtractorGDBRemote response;
+ response.SetResponseValidatorToJSON();
+ if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response,
+ false) ==
+ GDBRemoteCommunication::PacketResult::Success) {
+ StringExtractorGDBRemote::ResponseType response_type =
+ response.GetResponseType();
+ if (response_type == StringExtractorGDBRemote::eResponse) {
+ if (!response.Empty()) {
+ object_sp = StructuredData::ParseJSON(response.GetStringRef());
}
+ }
}
- return object_sp;
+ }
+ return object_sp;
+}
+
+Error ProcessGDBRemote::ConfigureStructuredData(
+ const ConstString &type_name, const StructuredData::ObjectSP &config_sp) {
+ return m_gdb_comm.ConfigureRemoteStructuredData(type_name, config_sp);
}
// Establish the largest memory read/write payloads we should use.
@@ -4262,100 +3972,103 @@ ProcessGDBRemote::GetLoadedDynamicLibrariesInfos (lldb::addr_t image_list_addres
// If the remote stub doesn't advertise a max packet size, use a
// conservative default.
-void
-ProcessGDBRemote::GetMaxMemorySize()
-{
- const uint64_t reasonable_largeish_default = 128 * 1024;
- const uint64_t conservative_default = 512;
+void ProcessGDBRemote::GetMaxMemorySize() {
+ const uint64_t reasonable_largeish_default = 128 * 1024;
+ const uint64_t conservative_default = 512;
- if (m_max_memory_size == 0)
- {
- uint64_t stub_max_size = m_gdb_comm.GetRemoteMaxPacketSize();
- if (stub_max_size != UINT64_MAX && stub_max_size != 0)
- {
- // Save the stub's claimed maximum packet size
- m_remote_stub_max_memory_size = stub_max_size;
+ if (m_max_memory_size == 0) {
+ uint64_t stub_max_size = m_gdb_comm.GetRemoteMaxPacketSize();
+ if (stub_max_size != UINT64_MAX && stub_max_size != 0) {
+ // Save the stub's claimed maximum packet size
+ m_remote_stub_max_memory_size = stub_max_size;
- // Even if the stub says it can support ginormous packets,
- // don't exceed our reasonable largeish default packet size.
- if (stub_max_size > reasonable_largeish_default)
- {
- stub_max_size = reasonable_largeish_default;
- }
+ // Even if the stub says it can support ginormous packets,
+ // don't exceed our reasonable largeish default packet size.
+ if (stub_max_size > reasonable_largeish_default) {
+ stub_max_size = reasonable_largeish_default;
+ }
- m_max_memory_size = stub_max_size;
- }
- else
- {
- m_max_memory_size = conservative_default;
- }
+ m_max_memory_size = stub_max_size;
+ } else {
+ m_max_memory_size = conservative_default;
}
+ }
}
-void
-ProcessGDBRemote::SetUserSpecifiedMaxMemoryTransferSize (uint64_t user_specified_max)
-{
- if (user_specified_max != 0)
- {
- GetMaxMemorySize ();
-
- if (m_remote_stub_max_memory_size != 0)
- {
- if (m_remote_stub_max_memory_size < user_specified_max)
- {
- m_max_memory_size = m_remote_stub_max_memory_size; // user specified a packet size too big, go as big
- // as the remote stub says we can go.
- }
- else
- {
- m_max_memory_size = user_specified_max; // user's packet size is good
- }
- }
- else
- {
- m_max_memory_size = user_specified_max; // user's packet size is probably fine
- }
+void ProcessGDBRemote::SetUserSpecifiedMaxMemoryTransferSize(
+ uint64_t user_specified_max) {
+ if (user_specified_max != 0) {
+ GetMaxMemorySize();
+
+ if (m_remote_stub_max_memory_size != 0) {
+ if (m_remote_stub_max_memory_size < user_specified_max) {
+ m_max_memory_size = m_remote_stub_max_memory_size; // user specified a
+ // packet size too
+ // big, go as big
+ // as the remote stub says we can go.
+ } else {
+ m_max_memory_size = user_specified_max; // user's packet size is good
+ }
+ } else {
+ m_max_memory_size =
+ user_specified_max; // user's packet size is probably fine
}
+ }
}
-bool
-ProcessGDBRemote::GetModuleSpec(const FileSpec& module_file_spec,
- const ArchSpec& arch,
- ModuleSpec &module_spec)
-{
- Log *log = GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PLATFORM);
+bool ProcessGDBRemote::GetModuleSpec(const FileSpec &module_file_spec,
+ const ArchSpec &arch,
+ ModuleSpec &module_spec) {
+ Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
- if (!m_gdb_comm.GetModuleInfo (module_file_spec, arch, module_spec))
- {
- if (log)
- log->Printf ("ProcessGDBRemote::%s - failed to get module info for %s:%s",
- __FUNCTION__, module_file_spec.GetPath ().c_str (),
- arch.GetTriple ().getTriple ().c_str ());
- return false;
- }
+ const ModuleCacheKey key(module_file_spec.GetPath(),
+ arch.GetTriple().getTriple());
+ auto cached = m_cached_module_specs.find(key);
+ if (cached != m_cached_module_specs.end()) {
+ module_spec = cached->second;
+ return bool(module_spec);
+ }
+ if (!m_gdb_comm.GetModuleInfo(module_file_spec, arch, module_spec)) {
if (log)
- {
- StreamString stream;
- module_spec.Dump (stream);
- log->Printf ("ProcessGDBRemote::%s - got module info for (%s:%s) : %s",
- __FUNCTION__, module_file_spec.GetPath ().c_str (),
- arch.GetTriple ().getTriple ().c_str (), stream.GetString ().c_str ());
- }
+ log->Printf("ProcessGDBRemote::%s - failed to get module info for %s:%s",
+ __FUNCTION__, module_file_spec.GetPath().c_str(),
+ arch.GetTriple().getTriple().c_str());
+ return false;
+ }
+
+ if (log) {
+ StreamString stream;
+ module_spec.Dump(stream);
+ log->Printf("ProcessGDBRemote::%s - got module info for (%s:%s) : %s",
+ __FUNCTION__, module_file_spec.GetPath().c_str(),
+ arch.GetTriple().getTriple().c_str(), stream.GetData());
+ }
+
+ m_cached_module_specs[key] = module_spec;
+ return true;
+}
- return true;
+void ProcessGDBRemote::PrefetchModuleSpecs(
+ llvm::ArrayRef<FileSpec> module_file_specs, const llvm::Triple &triple) {
+ auto module_specs = m_gdb_comm.GetModulesInfo(module_file_specs, triple);
+ if (module_specs) {
+ for (const FileSpec &spec : module_file_specs)
+ m_cached_module_specs[ModuleCacheKey(spec.GetPath(),
+ triple.getTriple())] = ModuleSpec();
+ for (const ModuleSpec &spec : *module_specs)
+ m_cached_module_specs[ModuleCacheKey(spec.GetFileSpec().GetPath(),
+ triple.getTriple())] = spec;
+ }
}
-bool
-ProcessGDBRemote::GetHostOSVersion(uint32_t &major,
- uint32_t &minor,
- uint32_t &update)
-{
- if (m_gdb_comm.GetOSVersion(major, minor, update))
- return true;
- // We failed to get the host OS version, defer to the base
- // implementation to correctly invalidate the arguments.
- return Process::GetHostOSVersion(major, minor, update);
+bool ProcessGDBRemote::GetHostOSVersion(uint32_t &major, uint32_t &minor,
+ uint32_t &update) {
+ if (m_gdb_comm.GetOSVersion(major, minor, update))
+ return true;
+ // We failed to get the host OS version, defer to the base
+ // implementation to correctly invalidate the arguments.
+ return Process::GetHostOSVersion(major, minor, update);
}
namespace {
@@ -4363,29 +4076,29 @@ namespace {
typedef std::vector<std::string> stringVec;
typedef std::vector<struct GdbServerRegisterInfo> GDBServerRegisterVec;
-struct RegisterSetInfo
-{
- ConstString name;
+struct RegisterSetInfo {
+ ConstString name;
};
typedef std::map<uint32_t, RegisterSetInfo> RegisterSetMap;
-struct GdbServerTargetInfo
-{
- std::string arch;
- std::string osabi;
- stringVec includes;
- RegisterSetMap reg_set_map;
- XMLNode feature_node;
+struct GdbServerTargetInfo {
+ std::string arch;
+ std::string osabi;
+ stringVec includes;
+ RegisterSetMap reg_set_map;
+ XMLNode feature_node;
};
-bool
-ParseRegisters (XMLNode feature_node, GdbServerTargetInfo &target_info, GDBRemoteDynamicRegisterInfo &dyn_reg_info, ABISP abi_sp, uint32_t &cur_reg_num, uint32_t &reg_offset)
-{
- if (!feature_node)
- return false;
+bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info,
+ GDBRemoteDynamicRegisterInfo &dyn_reg_info, ABISP abi_sp,
+ uint32_t &cur_reg_num, uint32_t &reg_offset) {
+ if (!feature_node)
+ return false;
- feature_node.ForEachChildElementWithName("reg", [&target_info, &dyn_reg_info, &cur_reg_num, &reg_offset, &abi_sp](const XMLNode &reg_node) -> bool {
+ feature_node.ForEachChildElementWithName(
+ "reg", [&target_info, &dyn_reg_info, &cur_reg_num, &reg_offset,
+ &abi_sp](const XMLNode &reg_node) -> bool {
std::string gdb_group;
std::string gdb_type;
ConstString reg_name;
@@ -4396,931 +4109,1038 @@ ParseRegisters (XMLNode feature_node, GdbServerTargetInfo &target_info, GDBRemot
std::vector<uint8_t> dwarf_opcode_bytes;
bool encoding_set = false;
bool format_set = false;
- RegisterInfo reg_info = { NULL, // Name
- NULL, // Alt name
- 0, // byte size
- reg_offset, // offset
- eEncodingUint, // encoding
- eFormatHex, // format
+ RegisterInfo reg_info = {
+ NULL, // Name
+ NULL, // Alt name
+ 0, // byte size
+ reg_offset, // offset
+ eEncodingUint, // encoding
+ eFormatHex, // format
{
LLDB_INVALID_REGNUM, // eh_frame reg num
LLDB_INVALID_REGNUM, // DWARF reg num
LLDB_INVALID_REGNUM, // generic reg num
- cur_reg_num, // process plugin reg num
- cur_reg_num // native register number
+ cur_reg_num, // process plugin reg num
+ cur_reg_num // native register number
},
NULL,
NULL,
- NULL, // Dwarf Expression opcode bytes pointer
- 0 // Dwarf Expression opcode bytes length
+ NULL, // Dwarf Expression opcode bytes pointer
+ 0 // Dwarf Expression opcode bytes length
};
- reg_node.ForEachAttribute([&target_info, &gdb_group, &gdb_type, &reg_name, &alt_name, &set_name, &value_regs, &invalidate_regs, &encoding_set, &format_set, &reg_info, &cur_reg_num, &reg_offset, &dwarf_opcode_bytes](const llvm::StringRef &name, const llvm::StringRef &value) -> bool {
- if (name == "name")
- {
- reg_name.SetString(value);
- }
- else if (name == "bitsize")
- {
- reg_info.byte_size = StringConvert::ToUInt32(value.data(), 0, 0) / CHAR_BIT;
- }
- else if (name == "type")
- {
- gdb_type = value.str();
- }
- else if (name == "group")
- {
- gdb_group = value.str();
- }
- else if (name == "regnum")
- {
- const uint32_t regnum = StringConvert::ToUInt32(value.data(), LLDB_INVALID_REGNUM, 0);
- if (regnum != LLDB_INVALID_REGNUM)
- {
- reg_info.kinds[eRegisterKindProcessPlugin] = regnum;
- }
- }
- else if (name == "offset")
- {
- reg_offset = StringConvert::ToUInt32(value.data(), UINT32_MAX, 0);
- }
- else if (name == "altname")
- {
- alt_name.SetString(value);
- }
- else if (name == "encoding")
- {
- encoding_set = true;
- reg_info.encoding = Args::StringToEncoding (value.data(), eEncodingUint);
- }
- else if (name == "format")
- {
- format_set = true;
- Format format = eFormatInvalid;
- if (Args::StringToFormat (value.data(), format, NULL).Success())
- reg_info.format = format;
- else if (value == "vector-sint8")
- reg_info.format = eFormatVectorOfSInt8;
- else if (value == "vector-uint8")
- reg_info.format = eFormatVectorOfUInt8;
- else if (value == "vector-sint16")
- reg_info.format = eFormatVectorOfSInt16;
- else if (value == "vector-uint16")
- reg_info.format = eFormatVectorOfUInt16;
- else if (value == "vector-sint32")
- reg_info.format = eFormatVectorOfSInt32;
- else if (value == "vector-uint32")
- reg_info.format = eFormatVectorOfUInt32;
- else if (value == "vector-float32")
- reg_info.format = eFormatVectorOfFloat32;
- else if (value == "vector-uint128")
- reg_info.format = eFormatVectorOfUInt128;
- }
- else if (name == "group_id")
- {
- const uint32_t set_id = StringConvert::ToUInt32(value.data(), UINT32_MAX, 0);
- RegisterSetMap::const_iterator pos = target_info.reg_set_map.find(set_id);
- if (pos != target_info.reg_set_map.end())
- set_name = pos->second.name;
- }
- else if (name == "gcc_regnum" || name == "ehframe_regnum")
- {
- reg_info.kinds[eRegisterKindEHFrame] = StringConvert::ToUInt32(value.data(), LLDB_INVALID_REGNUM, 0);
- }
- else if (name == "dwarf_regnum")
- {
- reg_info.kinds[eRegisterKindDWARF] = StringConvert::ToUInt32(value.data(), LLDB_INVALID_REGNUM, 0);
- }
- else if (name == "generic")
- {
- reg_info.kinds[eRegisterKindGeneric] = Args::StringToGenericRegister(value.data());
- }
- else if (name == "value_regnums")
- {
- SplitCommaSeparatedRegisterNumberString(value, value_regs, 0);
- }
- else if (name == "invalidate_regnums")
- {
- SplitCommaSeparatedRegisterNumberString(value, invalidate_regs, 0);
- }
- else if (name == "dynamic_size_dwarf_expr_bytes")
- {
- StringExtractor opcode_extractor;
- std::string opcode_string = value.str ();
- size_t dwarf_opcode_len = opcode_string.length () / 2;
- assert (dwarf_opcode_len > 0);
-
- dwarf_opcode_bytes.resize (dwarf_opcode_len);
- reg_info.dynamic_size_dwarf_len = dwarf_opcode_len;
- opcode_extractor.GetStringRef ().swap (opcode_string);
- uint32_t ret_val = opcode_extractor.GetHexBytesAvail (dwarf_opcode_bytes.data (),
- dwarf_opcode_len);
- assert (dwarf_opcode_len == ret_val);
-
- reg_info.dynamic_size_dwarf_expr_bytes = dwarf_opcode_bytes.data ();
- }
- else
- {
- printf("unhandled attribute %s = %s\n", name.data(), value.data());
+ reg_node.ForEachAttribute([&target_info, &gdb_group, &gdb_type,
+ &reg_name, &alt_name, &set_name, &value_regs,
+ &invalidate_regs, &encoding_set, &format_set,
+ &reg_info, &cur_reg_num, &reg_offset,
+ &dwarf_opcode_bytes](
+ const llvm::StringRef &name,
+ const llvm::StringRef &value) -> bool {
+ if (name == "name") {
+ reg_name.SetString(value);
+ } else if (name == "bitsize") {
+ reg_info.byte_size =
+ StringConvert::ToUInt32(value.data(), 0, 0) / CHAR_BIT;
+ } else if (name == "type") {
+ gdb_type = value.str();
+ } else if (name == "group") {
+ gdb_group = value.str();
+ } else if (name == "regnum") {
+ const uint32_t regnum =
+ StringConvert::ToUInt32(value.data(), LLDB_INVALID_REGNUM, 0);
+ if (regnum != LLDB_INVALID_REGNUM) {
+ reg_info.kinds[eRegisterKindProcessPlugin] = regnum;
}
- return true; // Keep iterating through all attributes
+ } else if (name == "offset") {
+ reg_offset = StringConvert::ToUInt32(value.data(), UINT32_MAX, 0);
+ } else if (name == "altname") {
+ alt_name.SetString(value);
+ } else if (name == "encoding") {
+ encoding_set = true;
+ reg_info.encoding = Args::StringToEncoding(value, eEncodingUint);
+ } else if (name == "format") {
+ format_set = true;
+ Format format = eFormatInvalid;
+ if (Args::StringToFormat(value.data(), format, NULL).Success())
+ reg_info.format = format;
+ else if (value == "vector-sint8")
+ reg_info.format = eFormatVectorOfSInt8;
+ else if (value == "vector-uint8")
+ reg_info.format = eFormatVectorOfUInt8;
+ else if (value == "vector-sint16")
+ reg_info.format = eFormatVectorOfSInt16;
+ else if (value == "vector-uint16")
+ reg_info.format = eFormatVectorOfUInt16;
+ else if (value == "vector-sint32")
+ reg_info.format = eFormatVectorOfSInt32;
+ else if (value == "vector-uint32")
+ reg_info.format = eFormatVectorOfUInt32;
+ else if (value == "vector-float32")
+ reg_info.format = eFormatVectorOfFloat32;
+ else if (value == "vector-uint64")
+ reg_info.format = eFormatVectorOfUInt64;
+ else if (value == "vector-uint128")
+ reg_info.format = eFormatVectorOfUInt128;
+ } else if (name == "group_id") {
+ const uint32_t set_id =
+ StringConvert::ToUInt32(value.data(), UINT32_MAX, 0);
+ RegisterSetMap::const_iterator pos =
+ target_info.reg_set_map.find(set_id);
+ if (pos != target_info.reg_set_map.end())
+ set_name = pos->second.name;
+ } else if (name == "gcc_regnum" || name == "ehframe_regnum") {
+ reg_info.kinds[eRegisterKindEHFrame] =
+ StringConvert::ToUInt32(value.data(), LLDB_INVALID_REGNUM, 0);
+ } else if (name == "dwarf_regnum") {
+ reg_info.kinds[eRegisterKindDWARF] =
+ StringConvert::ToUInt32(value.data(), LLDB_INVALID_REGNUM, 0);
+ } else if (name == "generic") {
+ reg_info.kinds[eRegisterKindGeneric] =
+ Args::StringToGenericRegister(value);
+ } else if (name == "value_regnums") {
+ SplitCommaSeparatedRegisterNumberString(value, value_regs, 0);
+ } else if (name == "invalidate_regnums") {
+ SplitCommaSeparatedRegisterNumberString(value, invalidate_regs, 0);
+ } else if (name == "dynamic_size_dwarf_expr_bytes") {
+ StringExtractor opcode_extractor;
+ std::string opcode_string = value.str();
+ size_t dwarf_opcode_len = opcode_string.length() / 2;
+ assert(dwarf_opcode_len > 0);
+
+ dwarf_opcode_bytes.resize(dwarf_opcode_len);
+ reg_info.dynamic_size_dwarf_len = dwarf_opcode_len;
+ opcode_extractor.GetStringRef().swap(opcode_string);
+ uint32_t ret_val =
+ opcode_extractor.GetHexBytesAvail(dwarf_opcode_bytes);
+ assert(dwarf_opcode_len == ret_val);
+
+ reg_info.dynamic_size_dwarf_expr_bytes = dwarf_opcode_bytes.data();
+ } else {
+ printf("unhandled attribute %s = %s\n", name.data(), value.data());
+ }
+ return true; // Keep iterating through all attributes
});
- if (!gdb_type.empty() && !(encoding_set || format_set))
- {
- if (gdb_type.find("int") == 0)
- {
- reg_info.format = eFormatHex;
- reg_info.encoding = eEncodingUint;
- }
- else if (gdb_type == "data_ptr" || gdb_type == "code_ptr")
- {
- reg_info.format = eFormatAddressInfo;
- reg_info.encoding = eEncodingUint;
- }
- else if (gdb_type == "i387_ext" || gdb_type == "float")
- {
- reg_info.format = eFormatFloat;
- reg_info.encoding = eEncodingIEEE754;
- }
+ if (!gdb_type.empty() && !(encoding_set || format_set)) {
+ if (gdb_type.find("int") == 0) {
+ reg_info.format = eFormatHex;
+ reg_info.encoding = eEncodingUint;
+ } else if (gdb_type == "data_ptr" || gdb_type == "code_ptr") {
+ reg_info.format = eFormatAddressInfo;
+ reg_info.encoding = eEncodingUint;
+ } else if (gdb_type == "i387_ext" || gdb_type == "float") {
+ reg_info.format = eFormatFloat;
+ reg_info.encoding = eEncodingIEEE754;
+ }
}
- // Only update the register set name if we didn't get a "reg_set" attribute.
+ // Only update the register set name if we didn't get a "reg_set"
+ // attribute.
// "set_name" will be empty if we didn't have a "reg_set" attribute.
if (!set_name && !gdb_group.empty())
- set_name.SetCString(gdb_group.c_str());
+ set_name.SetCString(gdb_group.c_str());
reg_info.byte_offset = reg_offset;
- assert (reg_info.byte_size != 0);
+ assert(reg_info.byte_size != 0);
reg_offset += reg_info.byte_size;
- if (!value_regs.empty())
- {
- value_regs.push_back(LLDB_INVALID_REGNUM);
- reg_info.value_regs = value_regs.data();
+ if (!value_regs.empty()) {
+ value_regs.push_back(LLDB_INVALID_REGNUM);
+ reg_info.value_regs = value_regs.data();
}
- if (!invalidate_regs.empty())
- {
- invalidate_regs.push_back(LLDB_INVALID_REGNUM);
- reg_info.invalidate_regs = invalidate_regs.data();
+ if (!invalidate_regs.empty()) {
+ invalidate_regs.push_back(LLDB_INVALID_REGNUM);
+ reg_info.invalidate_regs = invalidate_regs.data();
}
++cur_reg_num;
- AugmentRegisterInfoViaABI (reg_info, reg_name, abi_sp);
+ AugmentRegisterInfoViaABI(reg_info, reg_name, abi_sp);
dyn_reg_info.AddRegister(reg_info, reg_name, alt_name, set_name);
return true; // Keep iterating through all "reg" elements
- });
- return true;
+ });
+ return true;
}
} // namespace {}
-
// query the target of gdb-remote for extended target information
// return: 'true' on success
// 'false' on failure
-bool
-ProcessGDBRemote::GetGDBServerRegisterInfo (ArchSpec &arch_to_use)
-{
- // Make sure LLDB has an XML parser it can use first
- if (!XMLDocument::XMLEnabled())
- return false;
-
- // redirect libxml2's error handler since the default prints to stdout
-
- GDBRemoteCommunicationClient & comm = m_gdb_comm;
-
- // check that we have extended feature read support
- if ( !comm.GetQXferFeaturesReadSupported( ) )
- return false;
-
- // request the target xml file
- std::string raw;
- lldb_private::Error lldberr;
- if (!comm.ReadExtFeature(ConstString("features"),
- ConstString("target.xml"),
- raw,
- lldberr))
- {
- return false;
- }
+bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) {
+ // Make sure LLDB has an XML parser it can use first
+ if (!XMLDocument::XMLEnabled())
+ return false;
+ // redirect libxml2's error handler since the default prints to stdout
- XMLDocument xml_document;
+ GDBRemoteCommunicationClient &comm = m_gdb_comm;
- if (xml_document.ParseMemory(raw.c_str(), raw.size(), "target.xml"))
- {
- GdbServerTargetInfo target_info;
+ // check that we have extended feature read support
+ if (!comm.GetQXferFeaturesReadSupported())
+ return false;
- XMLNode target_node = xml_document.GetRootElement("target");
- if (target_node)
- {
- XMLNode feature_node;
- target_node.ForEachChildElement([&target_info, this, &feature_node](const XMLNode &node) -> bool
- {
- llvm::StringRef name = node.GetName();
- if (name == "architecture")
- {
- node.GetElementText(target_info.arch);
- }
- else if (name == "osabi")
- {
- node.GetElementText(target_info.osabi);
- }
- else if (name == "xi:include" || name == "include")
- {
- llvm::StringRef href = node.GetAttributeValue("href");
- if (!href.empty())
- target_info.includes.push_back(href.str());
- }
- else if (name == "feature")
- {
- feature_node = node;
- }
- else if (name == "groups")
- {
- node.ForEachChildElementWithName("group", [&target_info](const XMLNode &node) -> bool {
- uint32_t set_id = UINT32_MAX;
- RegisterSetInfo set_info;
-
- node.ForEachAttribute([&set_id, &set_info](const llvm::StringRef &name, const llvm::StringRef &value) -> bool {
- if (name == "id")
- set_id = StringConvert::ToUInt32(value.data(), UINT32_MAX, 0);
- if (name == "name")
- set_info.name = ConstString(value);
- return true; // Keep iterating through all attributes
- });
-
- if (set_id != UINT32_MAX)
- target_info.reg_set_map[set_id] = set_info;
- return true; // Keep iterating through all "group" elements
+ // request the target xml file
+ std::string raw;
+ lldb_private::Error lldberr;
+ if (!comm.ReadExtFeature(ConstString("features"), ConstString("target.xml"),
+ raw, lldberr)) {
+ return false;
+ }
+
+ XMLDocument xml_document;
+
+ if (xml_document.ParseMemory(raw.c_str(), raw.size(), "target.xml")) {
+ GdbServerTargetInfo target_info;
+
+ XMLNode target_node = xml_document.GetRootElement("target");
+ if (target_node) {
+ XMLNode feature_node;
+ target_node.ForEachChildElement([&target_info, this, &feature_node](
+ const XMLNode &node) -> bool {
+ llvm::StringRef name = node.GetName();
+ if (name == "architecture") {
+ node.GetElementText(target_info.arch);
+ } else if (name == "osabi") {
+ node.GetElementText(target_info.osabi);
+ } else if (name == "xi:include" || name == "include") {
+ llvm::StringRef href = node.GetAttributeValue("href");
+ if (!href.empty())
+ target_info.includes.push_back(href.str());
+ } else if (name == "feature") {
+ feature_node = node;
+ } else if (name == "groups") {
+ node.ForEachChildElementWithName(
+ "group", [&target_info](const XMLNode &node) -> bool {
+ uint32_t set_id = UINT32_MAX;
+ RegisterSetInfo set_info;
+
+ node.ForEachAttribute(
+ [&set_id, &set_info](const llvm::StringRef &name,
+ const llvm::StringRef &value) -> bool {
+ if (name == "id")
+ set_id = StringConvert::ToUInt32(value.data(),
+ UINT32_MAX, 0);
+ if (name == "name")
+ set_info.name = ConstString(value);
+ return true; // Keep iterating through all attributes
});
- }
- return true; // Keep iterating through all children of the target_node
- });
-
- // Initialize these outside of ParseRegisters, since they should not be reset inside each include feature
- uint32_t cur_reg_num = 0;
- uint32_t reg_offset = 0;
-
- // Don't use Process::GetABI, this code gets called from DidAttach, and in that context we haven't
- // set the Target's architecture yet, so the ABI is also potentially incorrect.
- ABISP abi_to_use_sp = ABI::FindPlugin(arch_to_use);
- if (feature_node)
- {
- ParseRegisters(feature_node, target_info, this->m_register_info, abi_to_use_sp, cur_reg_num, reg_offset);
- }
- for (const auto &include : target_info.includes)
- {
- // request register file
- std::string xml_data;
- if (!comm.ReadExtFeature(ConstString("features"),
- ConstString(include),
- xml_data,
- lldberr))
- continue;
-
- XMLDocument include_xml_document;
- include_xml_document.ParseMemory(xml_data.data(), xml_data.size(), include.c_str());
- XMLNode include_feature_node = include_xml_document.GetRootElement("feature");
- if (include_feature_node)
- {
- ParseRegisters(include_feature_node, target_info, this->m_register_info, abi_to_use_sp, cur_reg_num, reg_offset);
- }
- }
- this->m_register_info.Finalize(arch_to_use);
+ if (set_id != UINT32_MAX)
+ target_info.reg_set_map[set_id] = set_info;
+ return true; // Keep iterating through all "group" elements
+ });
+ }
+ return true; // Keep iterating through all children of the target_node
+ });
+
+ // Initialize these outside of ParseRegisters, since they should not be
+ // reset inside each include feature
+ uint32_t cur_reg_num = 0;
+ uint32_t reg_offset = 0;
+
+ // Don't use Process::GetABI, this code gets called from DidAttach, and in
+ // that context we haven't
+ // set the Target's architecture yet, so the ABI is also potentially
+ // incorrect.
+ ABISP abi_to_use_sp = ABI::FindPlugin(arch_to_use);
+ if (feature_node) {
+ ParseRegisters(feature_node, target_info, this->m_register_info,
+ abi_to_use_sp, cur_reg_num, reg_offset);
+ }
+
+ for (const auto &include : target_info.includes) {
+ // request register file
+ std::string xml_data;
+ if (!comm.ReadExtFeature(ConstString("features"), ConstString(include),
+ xml_data, lldberr))
+ continue;
+
+ XMLDocument include_xml_document;
+ include_xml_document.ParseMemory(xml_data.data(), xml_data.size(),
+ include.c_str());
+ XMLNode include_feature_node =
+ include_xml_document.GetRootElement("feature");
+ if (include_feature_node) {
+ ParseRegisters(include_feature_node, target_info,
+ this->m_register_info, abi_to_use_sp, cur_reg_num,
+ reg_offset);
}
+ }
+ this->m_register_info.Finalize(arch_to_use);
}
+ }
- return m_register_info.GetNumRegisters() > 0;
+ return m_register_info.GetNumRegisters() > 0;
}
-Error
-ProcessGDBRemote::GetLoadedModuleList (LoadedModuleInfoList & list)
-{
- // Make sure LLDB has an XML parser it can use first
- if (!XMLDocument::XMLEnabled())
- return Error (0, ErrorType::eErrorTypeGeneric);
+Error ProcessGDBRemote::GetLoadedModuleList(LoadedModuleInfoList &list) {
+ // Make sure LLDB has an XML parser it can use first
+ if (!XMLDocument::XMLEnabled())
+ return Error(0, ErrorType::eErrorTypeGeneric);
- Log *log = GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS);
- if (log)
- log->Printf ("ProcessGDBRemote::%s", __FUNCTION__);
+ Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS);
+ if (log)
+ log->Printf("ProcessGDBRemote::%s", __FUNCTION__);
- GDBRemoteCommunicationClient & comm = m_gdb_comm;
+ GDBRemoteCommunicationClient &comm = m_gdb_comm;
- // check that we have extended feature read support
- if (comm.GetQXferLibrariesSVR4ReadSupported ()) {
- list.clear ();
+ // check that we have extended feature read support
+ if (comm.GetQXferLibrariesSVR4ReadSupported()) {
+ list.clear();
- // request the loaded library list
- std::string raw;
- lldb_private::Error lldberr;
+ // request the loaded library list
+ std::string raw;
+ lldb_private::Error lldberr;
- if (!comm.ReadExtFeature (ConstString ("libraries-svr4"), ConstString (""), raw, lldberr))
- return Error (0, ErrorType::eErrorTypeGeneric);
+ if (!comm.ReadExtFeature(ConstString("libraries-svr4"), ConstString(""),
+ raw, lldberr))
+ return Error(0, ErrorType::eErrorTypeGeneric);
- // parse the xml file in memory
- if (log)
- log->Printf ("parsing: %s", raw.c_str());
- XMLDocument doc;
+ // parse the xml file in memory
+ if (log)
+ log->Printf("parsing: %s", raw.c_str());
+ XMLDocument doc;
- if (!doc.ParseMemory(raw.c_str(), raw.size(), "noname.xml"))
- return Error (0, ErrorType::eErrorTypeGeneric);
+ if (!doc.ParseMemory(raw.c_str(), raw.size(), "noname.xml"))
+ return Error(0, ErrorType::eErrorTypeGeneric);
- XMLNode root_element = doc.GetRootElement("library-list-svr4");
- if (!root_element)
- return Error();
+ XMLNode root_element = doc.GetRootElement("library-list-svr4");
+ if (!root_element)
+ return Error();
- // main link map structure
- llvm::StringRef main_lm = root_element.GetAttributeValue("main-lm");
- if (!main_lm.empty())
- {
- list.m_link_map = StringConvert::ToUInt64(main_lm.data(), LLDB_INVALID_ADDRESS, 0);
- }
+ // main link map structure
+ llvm::StringRef main_lm = root_element.GetAttributeValue("main-lm");
+ if (!main_lm.empty()) {
+ list.m_link_map =
+ StringConvert::ToUInt64(main_lm.data(), LLDB_INVALID_ADDRESS, 0);
+ }
- root_element.ForEachChildElementWithName("library", [log, &list](const XMLNode &library) -> bool {
+ root_element.ForEachChildElementWithName(
+ "library", [log, &list](const XMLNode &library) -> bool {
- LoadedModuleInfoList::LoadedModuleInfo module;
+ LoadedModuleInfoList::LoadedModuleInfo module;
- library.ForEachAttribute([log, &module](const llvm::StringRef &name, const llvm::StringRef &value) -> bool {
+ library.ForEachAttribute(
+ [log, &module](const llvm::StringRef &name,
+ const llvm::StringRef &value) -> bool {
if (name == "name")
- module.set_name (value.str());
- else if (name == "lm")
- {
- // the address of the link_map struct.
- module.set_link_map(StringConvert::ToUInt64(value.data(), LLDB_INVALID_ADDRESS, 0));
- }
- else if (name == "l_addr")
- {
- // the displacement as read from the field 'l_addr' of the link_map struct.
- module.set_base(StringConvert::ToUInt64(value.data(), LLDB_INVALID_ADDRESS, 0));
- // base address is always a displacement, not an absolute value.
- module.set_base_is_offset(true);
- }
- else if (name == "l_ld")
- {
- // the memory address of the libraries PT_DYAMIC section.
- module.set_dynamic(StringConvert::ToUInt64(value.data(), LLDB_INVALID_ADDRESS, 0));
+ module.set_name(value.str());
+ else if (name == "lm") {
+ // the address of the link_map struct.
+ module.set_link_map(StringConvert::ToUInt64(
+ value.data(), LLDB_INVALID_ADDRESS, 0));
+ } else if (name == "l_addr") {
+ // the displacement as read from the field 'l_addr' of the
+ // link_map struct.
+ module.set_base(StringConvert::ToUInt64(
+ value.data(), LLDB_INVALID_ADDRESS, 0));
+ // base address is always a displacement, not an absolute
+ // value.
+ module.set_base_is_offset(true);
+ } else if (name == "l_ld") {
+ // the memory address of the libraries PT_DYAMIC section.
+ module.set_dynamic(StringConvert::ToUInt64(
+ value.data(), LLDB_INVALID_ADDRESS, 0));
}
return true; // Keep iterating over all properties of "library"
- });
-
- if (log)
- {
- std::string name;
- lldb::addr_t lm=0, base=0, ld=0;
- bool base_is_offset;
-
- module.get_name (name);
- module.get_link_map (lm);
- module.get_base (base);
- module.get_base_is_offset (base_is_offset);
- module.get_dynamic (ld);
-
- log->Printf ("found (link_map:0x%08" PRIx64 ", base:0x%08" PRIx64 "[%s], ld:0x%08" PRIx64 ", name:'%s')", lm, base, (base_is_offset ? "offset" : "absolute"), ld, name.c_str());
- }
-
- list.add (module);
- return true; // Keep iterating over all "library" elements in the root node
+ });
+
+ if (log) {
+ std::string name;
+ lldb::addr_t lm = 0, base = 0, ld = 0;
+ bool base_is_offset;
+
+ module.get_name(name);
+ module.get_link_map(lm);
+ module.get_base(base);
+ module.get_base_is_offset(base_is_offset);
+ module.get_dynamic(ld);
+
+ log->Printf("found (link_map:0x%08" PRIx64 ", base:0x%08" PRIx64
+ "[%s], ld:0x%08" PRIx64 ", name:'%s')",
+ lm, base, (base_is_offset ? "offset" : "absolute"), ld,
+ name.c_str());
+ }
+
+ list.add(module);
+ return true; // Keep iterating over all "library" elements in the root
+ // node
});
- if (log)
- log->Printf ("found %" PRId32 " modules in total", (int) list.m_list.size());
- } else if (comm.GetQXferLibrariesReadSupported ()) {
- list.clear ();
-
- // request the loaded library list
- std::string raw;
- lldb_private::Error lldberr;
-
- if (!comm.ReadExtFeature (ConstString ("libraries"), ConstString (""), raw, lldberr))
- return Error (0, ErrorType::eErrorTypeGeneric);
-
- if (log)
- log->Printf ("parsing: %s", raw.c_str());
- XMLDocument doc;
-
- if (!doc.ParseMemory(raw.c_str(), raw.size(), "noname.xml"))
- return Error (0, ErrorType::eErrorTypeGeneric);
-
- XMLNode root_element = doc.GetRootElement("library-list");
- if (!root_element)
- return Error();
-
- root_element.ForEachChildElementWithName("library", [log, &list](const XMLNode &library) -> bool {
- LoadedModuleInfoList::LoadedModuleInfo module;
-
- llvm::StringRef name = library.GetAttributeValue("name");
- module.set_name(name.str());
+ if (log)
+ log->Printf("found %" PRId32 " modules in total",
+ (int)list.m_list.size());
+ } else if (comm.GetQXferLibrariesReadSupported()) {
+ list.clear();
- // The base address of a given library will be the address of its
- // first section. Most remotes send only one section for Windows
- // targets for example.
- const XMLNode &section = library.FindFirstChildElementWithName("section");
- llvm::StringRef address = section.GetAttributeValue("address");
- module.set_base(StringConvert::ToUInt64(address.data(), LLDB_INVALID_ADDRESS, 0));
- // These addresses are absolute values.
- module.set_base_is_offset(false);
+ // request the loaded library list
+ std::string raw;
+ lldb_private::Error lldberr;
- if (log)
- {
- std::string name;
- lldb::addr_t base = 0;
- bool base_is_offset;
- module.get_name (name);
- module.get_base (base);
- module.get_base_is_offset (base_is_offset);
-
- log->Printf ("found (base:0x%08" PRIx64 "[%s], name:'%s')", base, (base_is_offset ? "offset" : "absolute"), name.c_str());
- }
+ if (!comm.ReadExtFeature(ConstString("libraries"), ConstString(""), raw,
+ lldberr))
+ return Error(0, ErrorType::eErrorTypeGeneric);
- list.add (module);
- return true; // Keep iterating over all "library" elements in the root node
+ if (log)
+ log->Printf("parsing: %s", raw.c_str());
+ XMLDocument doc;
+
+ if (!doc.ParseMemory(raw.c_str(), raw.size(), "noname.xml"))
+ return Error(0, ErrorType::eErrorTypeGeneric);
+
+ XMLNode root_element = doc.GetRootElement("library-list");
+ if (!root_element)
+ return Error();
+
+ root_element.ForEachChildElementWithName(
+ "library", [log, &list](const XMLNode &library) -> bool {
+ LoadedModuleInfoList::LoadedModuleInfo module;
+
+ llvm::StringRef name = library.GetAttributeValue("name");
+ module.set_name(name.str());
+
+ // The base address of a given library will be the address of its
+ // first section. Most remotes send only one section for Windows
+ // targets for example.
+ const XMLNode &section =
+ library.FindFirstChildElementWithName("section");
+ llvm::StringRef address = section.GetAttributeValue("address");
+ module.set_base(
+ StringConvert::ToUInt64(address.data(), LLDB_INVALID_ADDRESS, 0));
+ // These addresses are absolute values.
+ module.set_base_is_offset(false);
+
+ if (log) {
+ std::string name;
+ lldb::addr_t base = 0;
+ bool base_is_offset;
+ module.get_name(name);
+ module.get_base(base);
+ module.get_base_is_offset(base_is_offset);
+
+ log->Printf("found (base:0x%08" PRIx64 "[%s], name:'%s')", base,
+ (base_is_offset ? "offset" : "absolute"), name.c_str());
+ }
+
+ list.add(module);
+ return true; // Keep iterating over all "library" elements in the root
+ // node
});
- if (log)
- log->Printf ("found %" PRId32 " modules in total", (int) list.m_list.size());
- } else {
- return Error (0, ErrorType::eErrorTypeGeneric);
- }
+ if (log)
+ log->Printf("found %" PRId32 " modules in total",
+ (int)list.m_list.size());
+ } else {
+ return Error(0, ErrorType::eErrorTypeGeneric);
+ }
- return Error();
+ return Error();
}
-lldb::ModuleSP
-ProcessGDBRemote::LoadModuleAtAddress (const FileSpec &file, lldb::addr_t link_map,
- lldb::addr_t base_addr, bool value_is_offset)
-{
- DynamicLoader *loader = GetDynamicLoader();
- if (!loader)
- return nullptr;
+lldb::ModuleSP ProcessGDBRemote::LoadModuleAtAddress(const FileSpec &file,
+ lldb::addr_t link_map,
+ lldb::addr_t base_addr,
+ bool value_is_offset) {
+ DynamicLoader *loader = GetDynamicLoader();
+ if (!loader)
+ return nullptr;
- return loader->LoadModuleAtAddress(file, link_map, base_addr, value_is_offset);
+ return loader->LoadModuleAtAddress(file, link_map, base_addr,
+ value_is_offset);
}
-size_t
-ProcessGDBRemote::LoadModules (LoadedModuleInfoList &module_list)
-{
- using lldb_private::process_gdb_remote::ProcessGDBRemote;
-
- // request a list of loaded libraries from GDBServer
- if (GetLoadedModuleList (module_list).Fail())
- return 0;
+size_t ProcessGDBRemote::LoadModules(LoadedModuleInfoList &module_list) {
+ using lldb_private::process_gdb_remote::ProcessGDBRemote;
- // get a list of all the modules
- ModuleList new_modules;
+ // request a list of loaded libraries from GDBServer
+ if (GetLoadedModuleList(module_list).Fail())
+ return 0;
- for (LoadedModuleInfoList::LoadedModuleInfo & modInfo : module_list.m_list)
- {
- std::string mod_name;
- lldb::addr_t mod_base;
- lldb::addr_t link_map;
- bool mod_base_is_offset;
-
- bool valid = true;
- valid &= modInfo.get_name (mod_name);
- valid &= modInfo.get_base (mod_base);
- valid &= modInfo.get_base_is_offset (mod_base_is_offset);
- if (!valid)
- continue;
-
- if (!modInfo.get_link_map (link_map))
- link_map = LLDB_INVALID_ADDRESS;
-
- FileSpec file (mod_name.c_str(), true);
- lldb::ModuleSP module_sp = LoadModuleAtAddress (file, link_map, mod_base,
- mod_base_is_offset);
-
- if (module_sp.get())
- new_modules.Append (module_sp);
- }
+ // get a list of all the modules
+ ModuleList new_modules;
+
+ for (LoadedModuleInfoList::LoadedModuleInfo &modInfo : module_list.m_list) {
+ std::string mod_name;
+ lldb::addr_t mod_base;
+ lldb::addr_t link_map;
+ bool mod_base_is_offset;
+
+ bool valid = true;
+ valid &= modInfo.get_name(mod_name);
+ valid &= modInfo.get_base(mod_base);
+ valid &= modInfo.get_base_is_offset(mod_base_is_offset);
+ if (!valid)
+ continue;
+
+ if (!modInfo.get_link_map(link_map))
+ link_map = LLDB_INVALID_ADDRESS;
+
+ FileSpec file(mod_name, true);
+ lldb::ModuleSP module_sp =
+ LoadModuleAtAddress(file, link_map, mod_base, mod_base_is_offset);
+
+ if (module_sp.get())
+ new_modules.Append(module_sp);
+ }
+
+ if (new_modules.GetSize() > 0) {
+ ModuleList removed_modules;
+ Target &target = GetTarget();
+ ModuleList &loaded_modules = m_process->GetTarget().GetImages();
+
+ for (size_t i = 0; i < loaded_modules.GetSize(); ++i) {
+ const lldb::ModuleSP loaded_module = loaded_modules.GetModuleAtIndex(i);
+
+ bool found = false;
+ for (size_t j = 0; j < new_modules.GetSize(); ++j) {
+ if (new_modules.GetModuleAtIndex(j).get() == loaded_module.get())
+ found = true;
+ }
+
+ // The main executable will never be included in libraries-svr4, don't
+ // remove it
+ if (!found &&
+ loaded_module.get() != target.GetExecutableModulePointer()) {
+ removed_modules.Append(loaded_module);
+ }
+ }
+
+ loaded_modules.Remove(removed_modules);
+ m_process->GetTarget().ModulesDidUnload(removed_modules, false);
+
+ new_modules.ForEach([&target](const lldb::ModuleSP module_sp) -> bool {
+ lldb_private::ObjectFile *obj = module_sp->GetObjectFile();
+ if (!obj)
+ return true;
- if (new_modules.GetSize() > 0)
- {
- ModuleList removed_modules;
- Target &target = GetTarget();
- ModuleList &loaded_modules = m_process->GetTarget().GetImages();
+ if (obj->GetType() != ObjectFile::Type::eTypeExecutable)
+ return true;
- for (size_t i = 0; i < loaded_modules.GetSize(); ++i)
- {
- const lldb::ModuleSP loaded_module = loaded_modules.GetModuleAtIndex(i);
+ lldb::ModuleSP module_copy_sp = module_sp;
+ target.SetExecutableModule(module_copy_sp, false);
+ return false;
+ });
- bool found = false;
- for (size_t j = 0; j < new_modules.GetSize(); ++j)
- {
- if (new_modules.GetModuleAtIndex(j).get() == loaded_module.get())
- found = true;
- }
+ loaded_modules.AppendIfNeeded(new_modules);
+ m_process->GetTarget().ModulesDidLoad(new_modules);
+ }
- // The main executable will never be included in libraries-svr4, don't remove it
- if (!found && loaded_module.get() != target.GetExecutableModulePointer())
- {
- removed_modules.Append (loaded_module);
- }
- }
-
- loaded_modules.Remove (removed_modules);
- m_process->GetTarget().ModulesDidUnload (removed_modules, false);
+ return new_modules.GetSize();
+}
- new_modules.ForEach ([&target](const lldb::ModuleSP module_sp) -> bool
- {
- lldb_private::ObjectFile * obj = module_sp->GetObjectFile ();
- if (!obj)
- return true;
+size_t ProcessGDBRemote::LoadModules() {
+ LoadedModuleInfoList module_list;
+ return LoadModules(module_list);
+}
- if (obj->GetType () != ObjectFile::Type::eTypeExecutable)
- return true;
+Error ProcessGDBRemote::GetFileLoadAddress(const FileSpec &file,
+ bool &is_loaded,
+ lldb::addr_t &load_addr) {
+ is_loaded = false;
+ load_addr = LLDB_INVALID_ADDRESS;
+
+ std::string file_path = file.GetPath(false);
+ if (file_path.empty())
+ return Error("Empty file name specified");
+
+ StreamString packet;
+ packet.PutCString("qFileLoadAddress:");
+ packet.PutCStringAsRawHex8(file_path.c_str());
+
+ StringExtractorGDBRemote response;
+ if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response,
+ false) !=
+ GDBRemoteCommunication::PacketResult::Success)
+ return Error("Sending qFileLoadAddress packet failed");
+
+ if (response.IsErrorResponse()) {
+ if (response.GetError() == 1) {
+ // The file is not loaded into the inferior
+ is_loaded = false;
+ load_addr = LLDB_INVALID_ADDRESS;
+ return Error();
+ }
+
+ return Error(
+ "Fetching file load address from remote server returned an error");
+ }
+
+ if (response.IsNormalResponse()) {
+ is_loaded = true;
+ load_addr = response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
+ return Error();
+ }
- lldb::ModuleSP module_copy_sp = module_sp;
- target.SetExecutableModule (module_copy_sp, false);
- return false;
- });
+ return Error("Unknown error happened during sending the load address packet");
+}
- loaded_modules.AppendIfNeeded (new_modules);
- m_process->GetTarget().ModulesDidLoad (new_modules);
- }
+void ProcessGDBRemote::ModulesDidLoad(ModuleList &module_list) {
+ // We must call the lldb_private::Process::ModulesDidLoad () first before we
+ // do anything
+ Process::ModulesDidLoad(module_list);
- return new_modules.GetSize();
+ // After loading shared libraries, we can ask our remote GDB server if
+ // it needs any symbols.
+ m_gdb_comm.ServeSymbolLookups(this);
}
-size_t
-ProcessGDBRemote::LoadModules ()
-{
- LoadedModuleInfoList module_list;
- return LoadModules (module_list);
+void ProcessGDBRemote::HandleAsyncStdout(llvm::StringRef out) {
+ AppendSTDOUT(out.data(), out.size());
}
-Error
-ProcessGDBRemote::GetFileLoadAddress(const FileSpec& file, bool& is_loaded, lldb::addr_t& load_addr)
-{
- is_loaded = false;
- load_addr = LLDB_INVALID_ADDRESS;
-
- std::string file_path = file.GetPath(false);
- if (file_path.empty ())
- return Error("Empty file name specified");
-
- StreamString packet;
- packet.PutCString("qFileLoadAddress:");
- packet.PutCStringAsRawHex8(file_path.c_str());
-
- StringExtractorGDBRemote response;
- if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(), response, false) != GDBRemoteCommunication::PacketResult::Success)
- return Error("Sending qFileLoadAddress packet failed");
+static const char *end_delimiter = "--end--;";
+static const int end_delimiter_len = 8;
+
+void ProcessGDBRemote::HandleAsyncMisc(llvm::StringRef data) {
+ std::string input = data.str(); // '1' to move beyond 'A'
+ if (m_partial_profile_data.length() > 0) {
+ m_partial_profile_data.append(input);
+ input = m_partial_profile_data;
+ m_partial_profile_data.clear();
+ }
+
+ size_t found, pos = 0, len = input.length();
+ while ((found = input.find(end_delimiter, pos)) != std::string::npos) {
+ StringExtractorGDBRemote profileDataExtractor(
+ input.substr(pos, found).c_str());
+ std::string profile_data =
+ HarmonizeThreadIdsForProfileData(profileDataExtractor);
+ BroadcastAsyncProfileData(profile_data);
+
+ pos = found + end_delimiter_len;
+ }
+
+ if (pos < len) {
+ // Last incomplete chunk.
+ m_partial_profile_data = input.substr(pos);
+ }
+}
- if (response.IsErrorResponse())
- {
- if (response.GetError() == 1)
- {
- // The file is not loaded into the inferior
- is_loaded = false;
- load_addr = LLDB_INVALID_ADDRESS;
- return Error();
+std::string ProcessGDBRemote::HarmonizeThreadIdsForProfileData(
+ StringExtractorGDBRemote &profileDataExtractor) {
+ std::map<uint64_t, uint32_t> new_thread_id_to_used_usec_map;
+ std::string output;
+ llvm::raw_string_ostream output_stream(output);
+ llvm::StringRef name, value;
+
+ // Going to assuming thread_used_usec comes first, else bail out.
+ while (profileDataExtractor.GetNameColonValue(name, value)) {
+ if (name.compare("thread_used_id") == 0) {
+ StringExtractor threadIDHexExtractor(value);
+ uint64_t thread_id = threadIDHexExtractor.GetHexMaxU64(false, 0);
+
+ bool has_used_usec = false;
+ uint32_t curr_used_usec = 0;
+ llvm::StringRef usec_name, usec_value;
+ uint32_t input_file_pos = profileDataExtractor.GetFilePos();
+ if (profileDataExtractor.GetNameColonValue(usec_name, usec_value)) {
+ if (usec_name.equals("thread_used_usec")) {
+ has_used_usec = true;
+ usec_value.getAsInteger(0, curr_used_usec);
+ } else {
+ // We didn't find what we want, it is probably
+ // an older version. Bail out.
+ profileDataExtractor.SetFilePos(input_file_pos);
+ }
+ }
+
+ if (has_used_usec) {
+ uint32_t prev_used_usec = 0;
+ std::map<uint64_t, uint32_t>::iterator iterator =
+ m_thread_id_to_used_usec_map.find(thread_id);
+ if (iterator != m_thread_id_to_used_usec_map.end()) {
+ prev_used_usec = m_thread_id_to_used_usec_map[thread_id];
}
- return Error("Fetching file load address from remote server returned an error");
- }
+ uint32_t real_used_usec = curr_used_usec - prev_used_usec;
+ // A good first time record is one that runs for at least 0.25 sec
+ bool good_first_time =
+ (prev_used_usec == 0) && (real_used_usec > 250000);
+ bool good_subsequent_time =
+ (prev_used_usec > 0) &&
+ ((real_used_usec > 0) || (HasAssignedIndexIDToThread(thread_id)));
+
+ if (good_first_time || good_subsequent_time) {
+ // We try to avoid doing too many index id reservation,
+ // resulting in fast increase of index ids.
+
+ output_stream << name << ":";
+ int32_t index_id = AssignIndexIDToThread(thread_id);
+ output_stream << index_id << ";";
+
+ output_stream << usec_name << ":" << usec_value << ";";
+ } else {
+ // Skip past 'thread_used_name'.
+ llvm::StringRef local_name, local_value;
+ profileDataExtractor.GetNameColonValue(local_name, local_value);
+ }
- if (response.IsNormalResponse())
- {
- is_loaded = true;
- load_addr = response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
- return Error();
+ // Store current time as previous time so that they can be compared
+ // later.
+ new_thread_id_to_used_usec_map[thread_id] = curr_used_usec;
+ } else {
+ // Bail out and use old string.
+ output_stream << name << ":" << value << ";";
+ }
+ } else {
+ output_stream << name << ":" << value << ";";
}
+ }
+ output_stream << end_delimiter;
+ m_thread_id_to_used_usec_map = new_thread_id_to_used_usec_map;
- return Error("Unknown error happened during sending the load address packet");
+ return output_stream.str();
}
+void ProcessGDBRemote::HandleStopReply() {
+ if (GetStopID() != 0)
+ return;
-void
-ProcessGDBRemote::ModulesDidLoad (ModuleList &module_list)
-{
- // We must call the lldb_private::Process::ModulesDidLoad () first before we do anything
- Process::ModulesDidLoad (module_list);
-
- // After loading shared libraries, we can ask our remote GDB server if
- // it needs any symbols.
- m_gdb_comm.ServeSymbolLookups(this);
+ if (GetID() == LLDB_INVALID_PROCESS_ID) {
+ lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID();
+ if (pid != LLDB_INVALID_PROCESS_ID)
+ SetID(pid);
+ }
+ BuildDynamicRegisterInfo(true);
}
-
-class CommandObjectProcessGDBRemoteSpeedTest: public CommandObjectParsed
-{
-public:
- CommandObjectProcessGDBRemoteSpeedTest(CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "process plugin packet speed-test",
- "Tests packet speeds of various sizes to determine the performance characteristics of the GDB remote connection. ",
- NULL),
- m_option_group (interpreter),
- m_num_packets (LLDB_OPT_SET_1, false, "count", 'c', 0, eArgTypeCount, "The number of packets to send of each varying size (default is 1000).", 1000),
- m_max_send (LLDB_OPT_SET_1, false, "max-send", 's', 0, eArgTypeCount, "The maximum number of bytes to send in a packet. Sizes increase in powers of 2 while the size is less than or equal to this option value. (default 1024).", 1024),
- m_max_recv (LLDB_OPT_SET_1, false, "max-receive", 'r', 0, eArgTypeCount, "The maximum number of bytes to receive in a packet. Sizes increase in powers of 2 while the size is less than or equal to this option value. (default 1024).", 1024),
- m_json (LLDB_OPT_SET_1, false, "json", 'j', "Print the output as JSON data for easy parsing.", false, true)
- {
- m_option_group.Append (&m_num_packets, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Append (&m_max_send, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Append (&m_max_recv, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Append (&m_json, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Finalize();
- }
-
- ~CommandObjectProcessGDBRemoteSpeedTest ()
- {
+static const char *const s_async_json_packet_prefix = "JSON-async:";
+
+static StructuredData::ObjectSP
+ParseStructuredDataPacket(llvm::StringRef packet) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+
+ if (!packet.consume_front(s_async_json_packet_prefix)) {
+ if (log) {
+ log->Printf(
+ "GDBRemoteCommmunicationClientBase::%s() received $J packet "
+ "but was not a StructuredData packet: packet starts with "
+ "%s",
+ __FUNCTION__,
+ packet.slice(0, strlen(s_async_json_packet_prefix)).str().c_str());
+ }
+ return StructuredData::ObjectSP();
+ }
+
+ // This is an asynchronous JSON packet, destined for a
+ // StructuredDataPlugin.
+ StructuredData::ObjectSP json_sp = StructuredData::ParseJSON(packet);
+ if (log) {
+ if (json_sp) {
+ StreamString json_str;
+ json_sp->Dump(json_str);
+ json_str.Flush();
+ log->Printf("ProcessGDBRemote::%s() "
+ "received Async StructuredData packet: %s",
+ __FUNCTION__, json_str.GetData());
+ } else {
+ log->Printf("ProcessGDBRemote::%s"
+ "() received StructuredData packet:"
+ " parse failure",
+ __FUNCTION__);
}
+ }
+ return json_sp;
+}
+void ProcessGDBRemote::HandleAsyncStructuredDataPacket(llvm::StringRef data) {
+ auto structured_data_sp = ParseStructuredDataPacket(data);
+ if (structured_data_sp)
+ RouteAsyncStructuredData(structured_data_sp);
+}
- Options *
- GetOptions () override
- {
- return &m_option_group;
+class CommandObjectProcessGDBRemoteSpeedTest : public CommandObjectParsed {
+public:
+ CommandObjectProcessGDBRemoteSpeedTest(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "process plugin packet speed-test",
+ "Tests packet speeds of various sizes to determine "
+ "the performance characteristics of the GDB remote "
+ "connection. ",
+ NULL),
+ m_option_group(),
+ m_num_packets(LLDB_OPT_SET_1, false, "count", 'c', 0, eArgTypeCount,
+ "The number of packets to send of each varying size "
+ "(default is 1000).",
+ 1000),
+ m_max_send(LLDB_OPT_SET_1, false, "max-send", 's', 0, eArgTypeCount,
+ "The maximum number of bytes to send in a packet. Sizes "
+ "increase in powers of 2 while the size is less than or "
+ "equal to this option value. (default 1024).",
+ 1024),
+ m_max_recv(LLDB_OPT_SET_1, false, "max-receive", 'r', 0, eArgTypeCount,
+ "The maximum number of bytes to receive in a packet. Sizes "
+ "increase in powers of 2 while the size is less than or "
+ "equal to this option value. (default 1024).",
+ 1024),
+ m_json(LLDB_OPT_SET_1, false, "json", 'j',
+ "Print the output as JSON data for easy parsing.", false, true) {
+ m_option_group.Append(&m_num_packets, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Append(&m_max_send, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Append(&m_max_recv, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Append(&m_json, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Finalize();
+ }
+
+ ~CommandObjectProcessGDBRemoteSpeedTest() {}
+
+ Options *GetOptions() override { return &m_option_group; }
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ const size_t argc = command.GetArgumentCount();
+ if (argc == 0) {
+ ProcessGDBRemote *process =
+ (ProcessGDBRemote *)m_interpreter.GetExecutionContext()
+ .GetProcessPtr();
+ if (process) {
+ StreamSP output_stream_sp(
+ m_interpreter.GetDebugger().GetAsyncOutputStream());
+ result.SetImmediateOutputStream(output_stream_sp);
+
+ const uint32_t num_packets =
+ (uint32_t)m_num_packets.GetOptionValue().GetCurrentValue();
+ const uint64_t max_send = m_max_send.GetOptionValue().GetCurrentValue();
+ const uint64_t max_recv = m_max_recv.GetOptionValue().GetCurrentValue();
+ const bool json = m_json.GetOptionValue().GetCurrentValue();
+ const uint64_t k_recv_amount =
+ 4 * 1024 * 1024; // Receive amount in bytes
+ process->GetGDBRemote().TestPacketSpeed(
+ num_packets, max_send, max_recv, k_recv_amount, json,
+ output_stream_sp ? *output_stream_sp : result.GetOutputStream());
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
+ } else {
+ result.AppendErrorWithFormat("'%s' takes no arguments",
+ m_cmd_name.c_str());
}
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- const size_t argc = command.GetArgumentCount();
- if (argc == 0)
- {
- ProcessGDBRemote *process = (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();
- if (process)
- {
- StreamSP output_stream_sp (m_interpreter.GetDebugger().GetAsyncOutputStream());
- result.SetImmediateOutputStream (output_stream_sp);
-
- const uint32_t num_packets = (uint32_t)m_num_packets.GetOptionValue().GetCurrentValue();
- const uint64_t max_send = m_max_send.GetOptionValue().GetCurrentValue();
- const uint64_t max_recv = m_max_recv.GetOptionValue().GetCurrentValue();
- const bool json = m_json.GetOptionValue().GetCurrentValue();
- if (output_stream_sp)
- process->GetGDBRemote().TestPacketSpeed (num_packets, max_send, max_recv, json, *output_stream_sp);
- else
- {
- process->GetGDBRemote().TestPacketSpeed (num_packets, max_send, max_recv, json, result.GetOutputStream());
- }
- result.SetStatus (eReturnStatusSuccessFinishResult);
- return true;
- }
- }
- else
- {
- result.AppendErrorWithFormat ("'%s' takes no arguments", m_cmd_name.c_str());
- }
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
protected:
- OptionGroupOptions m_option_group;
- OptionGroupUInt64 m_num_packets;
- OptionGroupUInt64 m_max_send;
- OptionGroupUInt64 m_max_recv;
- OptionGroupBoolean m_json;
-
+ OptionGroupOptions m_option_group;
+ OptionGroupUInt64 m_num_packets;
+ OptionGroupUInt64 m_max_send;
+ OptionGroupUInt64 m_max_recv;
+ OptionGroupBoolean m_json;
};
-class CommandObjectProcessGDBRemotePacketHistory : public CommandObjectParsed
-{
+class CommandObjectProcessGDBRemotePacketHistory : public CommandObjectParsed {
private:
-
public:
- CommandObjectProcessGDBRemotePacketHistory(CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "process plugin packet history",
- "Dumps the packet history buffer. ",
- NULL)
- {
- }
-
- ~CommandObjectProcessGDBRemotePacketHistory ()
- {
- }
-
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- const size_t argc = command.GetArgumentCount();
- if (argc == 0)
- {
- ProcessGDBRemote *process = (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();
- if (process)
- {
- process->GetGDBRemote().DumpHistory(result.GetOutputStream());
- result.SetStatus (eReturnStatusSuccessFinishResult);
- return true;
- }
- }
- else
- {
- result.AppendErrorWithFormat ("'%s' takes no arguments", m_cmd_name.c_str());
- }
- result.SetStatus (eReturnStatusFailed);
- return false;
+ CommandObjectProcessGDBRemotePacketHistory(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "process plugin packet history",
+ "Dumps the packet history buffer. ", NULL) {}
+
+ ~CommandObjectProcessGDBRemotePacketHistory() {}
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ const size_t argc = command.GetArgumentCount();
+ if (argc == 0) {
+ ProcessGDBRemote *process =
+ (ProcessGDBRemote *)m_interpreter.GetExecutionContext()
+ .GetProcessPtr();
+ if (process) {
+ process->GetGDBRemote().DumpHistory(result.GetOutputStream());
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
+ } else {
+ result.AppendErrorWithFormat("'%s' takes no arguments",
+ m_cmd_name.c_str());
}
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
};
-class CommandObjectProcessGDBRemotePacketXferSize : public CommandObjectParsed
-{
+class CommandObjectProcessGDBRemotePacketXferSize : public CommandObjectParsed {
private:
-
public:
- CommandObjectProcessGDBRemotePacketXferSize(CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "process plugin packet xfer-size",
- "Maximum size that lldb will try to read/write one one chunk.",
- NULL)
- {
- }
-
- ~CommandObjectProcessGDBRemotePacketXferSize ()
- {
- }
-
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- const size_t argc = command.GetArgumentCount();
- if (argc == 0)
- {
- result.AppendErrorWithFormat ("'%s' takes an argument to specify the max amount to be transferred when reading/writing", m_cmd_name.c_str());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- ProcessGDBRemote *process = (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();
- if (process)
- {
- const char *packet_size = command.GetArgumentAtIndex(0);
- errno = 0;
- uint64_t user_specified_max = strtoul (packet_size, NULL, 10);
- if (errno == 0 && user_specified_max != 0)
- {
- process->SetUserSpecifiedMaxMemoryTransferSize (user_specified_max);
- result.SetStatus (eReturnStatusSuccessFinishResult);
- return true;
- }
- }
- result.SetStatus (eReturnStatusFailed);
- return false;
+ CommandObjectProcessGDBRemotePacketXferSize(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "process plugin packet xfer-size",
+ "Maximum size that lldb will try to read/write one one chunk.",
+ NULL) {}
+
+ ~CommandObjectProcessGDBRemotePacketXferSize() {}
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ const size_t argc = command.GetArgumentCount();
+ if (argc == 0) {
+ result.AppendErrorWithFormat("'%s' takes an argument to specify the max "
+ "amount to be transferred when "
+ "reading/writing",
+ m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ ProcessGDBRemote *process =
+ (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();
+ if (process) {
+ const char *packet_size = command.GetArgumentAtIndex(0);
+ errno = 0;
+ uint64_t user_specified_max = strtoul(packet_size, NULL, 10);
+ if (errno == 0 && user_specified_max != 0) {
+ process->SetUserSpecifiedMaxMemoryTransferSize(user_specified_max);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
}
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
};
-
-class CommandObjectProcessGDBRemotePacketSend : public CommandObjectParsed
-{
+class CommandObjectProcessGDBRemotePacketSend : public CommandObjectParsed {
private:
-
public:
- CommandObjectProcessGDBRemotePacketSend(CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "process plugin packet send",
- "Send a custom packet through the GDB remote protocol and print the answer. "
- "The packet header and footer will automatically be added to the packet prior to sending and stripped from the result.",
- NULL)
- {
- }
-
- ~CommandObjectProcessGDBRemotePacketSend ()
- {
- }
-
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- const size_t argc = command.GetArgumentCount();
- if (argc == 0)
- {
- result.AppendErrorWithFormat ("'%s' takes a one or more packet content arguments", m_cmd_name.c_str());
- result.SetStatus (eReturnStatusFailed);
- return false;
+ CommandObjectProcessGDBRemotePacketSend(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "process plugin packet send",
+ "Send a custom packet through the GDB remote "
+ "protocol and print the answer. "
+ "The packet header and footer will automatically "
+ "be added to the packet prior to sending and "
+ "stripped from the result.",
+ NULL) {}
+
+ ~CommandObjectProcessGDBRemotePacketSend() {}
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ const size_t argc = command.GetArgumentCount();
+ if (argc == 0) {
+ result.AppendErrorWithFormat(
+ "'%s' takes a one or more packet content arguments",
+ m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ ProcessGDBRemote *process =
+ (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();
+ if (process) {
+ for (size_t i = 0; i < argc; ++i) {
+ const char *packet_cstr = command.GetArgumentAtIndex(0);
+ bool send_async = true;
+ StringExtractorGDBRemote response;
+ process->GetGDBRemote().SendPacketAndWaitForResponse(
+ packet_cstr, response, send_async);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ Stream &output_strm = result.GetOutputStream();
+ output_strm.Printf(" packet: %s\n", packet_cstr);
+ std::string &response_str = response.GetStringRef();
+
+ if (strstr(packet_cstr, "qGetProfileData") != NULL) {
+ response_str = process->HarmonizeThreadIdsForProfileData(response);
}
- ProcessGDBRemote *process = (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();
- if (process)
- {
- for (size_t i=0; i<argc; ++ i)
- {
- const char *packet_cstr = command.GetArgumentAtIndex(0);
- bool send_async = true;
- StringExtractorGDBRemote response;
- process->GetGDBRemote().SendPacketAndWaitForResponse(packet_cstr, response, send_async);
- result.SetStatus (eReturnStatusSuccessFinishResult);
- Stream &output_strm = result.GetOutputStream();
- output_strm.Printf (" packet: %s\n", packet_cstr);
- std::string &response_str = response.GetStringRef();
-
- if (strstr(packet_cstr, "qGetProfileData") != NULL)
- {
- response_str = process->GetGDBRemote().HarmonizeThreadIdsForProfileData(process, response);
- }
-
- if (response_str.empty())
- output_strm.PutCString ("response: \nerror: UNIMPLEMENTED\n");
- else
- output_strm.Printf ("response: %s\n", response.GetStringRef().c_str());
- }
- }
- return true;
+ if (response_str.empty())
+ output_strm.PutCString("response: \nerror: UNIMPLEMENTED\n");
+ else
+ output_strm.Printf("response: %s\n", response.GetStringRef().c_str());
+ }
}
+ return true;
+ }
};
-class CommandObjectProcessGDBRemotePacketMonitor : public CommandObjectRaw
-{
+class CommandObjectProcessGDBRemotePacketMonitor : public CommandObjectRaw {
private:
-
public:
- CommandObjectProcessGDBRemotePacketMonitor(CommandInterpreter &interpreter) :
- CommandObjectRaw (interpreter,
- "process plugin packet monitor",
- "Send a qRcmd packet through the GDB remote protocol and print the response."
- "The argument passed to this command will be hex encoded into a valid 'qRcmd' packet, sent and the response will be printed.",
- NULL)
- {
- }
-
- ~CommandObjectProcessGDBRemotePacketMonitor ()
- {
- }
-
- bool
- DoExecute (const char *command, CommandReturnObject &result) override
- {
- if (command == NULL || command[0] == '\0')
- {
- result.AppendErrorWithFormat ("'%s' takes a command string argument", m_cmd_name.c_str());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- ProcessGDBRemote *process = (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();
- if (process)
- {
- StreamString packet;
- packet.PutCString("qRcmd,");
- packet.PutBytesAsRawHex8(command, strlen(command));
- const char *packet_cstr = packet.GetString().c_str();
-
- bool send_async = true;
- StringExtractorGDBRemote response;
- process->GetGDBRemote().SendPacketAndWaitForResponse(packet_cstr, response, send_async);
- result.SetStatus (eReturnStatusSuccessFinishResult);
- Stream &output_strm = result.GetOutputStream();
- output_strm.Printf (" packet: %s\n", packet_cstr);
- const std::string &response_str = response.GetStringRef();
-
- if (response_str.empty())
- output_strm.PutCString ("response: \nerror: UNIMPLEMENTED\n");
- else
- output_strm.Printf ("response: %s\n", response.GetStringRef().c_str());
- }
- return true;
+ CommandObjectProcessGDBRemotePacketMonitor(CommandInterpreter &interpreter)
+ : CommandObjectRaw(interpreter, "process plugin packet monitor",
+ "Send a qRcmd packet through the GDB remote protocol "
+ "and print the response."
+ "The argument passed to this command will be hex "
+ "encoded into a valid 'qRcmd' packet, sent and the "
+ "response will be printed.") {}
+
+ ~CommandObjectProcessGDBRemotePacketMonitor() {}
+
+ bool DoExecute(const char *command, CommandReturnObject &result) override {
+ if (command == NULL || command[0] == '\0') {
+ result.AppendErrorWithFormat("'%s' takes a command string argument",
+ m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ ProcessGDBRemote *process =
+ (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();
+ if (process) {
+ StreamString packet;
+ packet.PutCString("qRcmd,");
+ packet.PutBytesAsRawHex8(command, strlen(command));
+
+ bool send_async = true;
+ StringExtractorGDBRemote response;
+ process->GetGDBRemote().SendPacketAndWaitForResponse(
+ packet.GetString(), response, send_async);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ Stream &output_strm = result.GetOutputStream();
+ output_strm.Printf(" packet: %s\n", packet.GetData());
+ const std::string &response_str = response.GetStringRef();
+
+ if (response_str.empty())
+ output_strm.PutCString("response: \nerror: UNIMPLEMENTED\n");
+ else
+ output_strm.Printf("response: %s\n", response.GetStringRef().c_str());
}
+ return true;
+ }
};
-class CommandObjectProcessGDBRemotePacket : public CommandObjectMultiword
-{
+class CommandObjectProcessGDBRemotePacket : public CommandObjectMultiword {
private:
-
public:
- CommandObjectProcessGDBRemotePacket(CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "process plugin packet",
- "Commands that deal with GDB remote packets.",
- NULL)
- {
- LoadSubCommand ("history", CommandObjectSP (new CommandObjectProcessGDBRemotePacketHistory (interpreter)));
- LoadSubCommand ("send", CommandObjectSP (new CommandObjectProcessGDBRemotePacketSend (interpreter)));
- LoadSubCommand ("monitor", CommandObjectSP (new CommandObjectProcessGDBRemotePacketMonitor (interpreter)));
- LoadSubCommand ("xfer-size", CommandObjectSP (new CommandObjectProcessGDBRemotePacketXferSize (interpreter)));
- LoadSubCommand ("speed-test", CommandObjectSP (new CommandObjectProcessGDBRemoteSpeedTest (interpreter)));
- }
-
- ~CommandObjectProcessGDBRemotePacket ()
- {
- }
+ CommandObjectProcessGDBRemotePacket(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "process plugin packet",
+ "Commands that deal with GDB remote packets.",
+ NULL) {
+ LoadSubCommand(
+ "history",
+ CommandObjectSP(
+ new CommandObjectProcessGDBRemotePacketHistory(interpreter)));
+ LoadSubCommand(
+ "send", CommandObjectSP(
+ new CommandObjectProcessGDBRemotePacketSend(interpreter)));
+ LoadSubCommand(
+ "monitor",
+ CommandObjectSP(
+ new CommandObjectProcessGDBRemotePacketMonitor(interpreter)));
+ LoadSubCommand(
+ "xfer-size",
+ CommandObjectSP(
+ new CommandObjectProcessGDBRemotePacketXferSize(interpreter)));
+ LoadSubCommand("speed-test",
+ CommandObjectSP(new CommandObjectProcessGDBRemoteSpeedTest(
+ interpreter)));
+ }
+
+ ~CommandObjectProcessGDBRemotePacket() {}
};
-class CommandObjectMultiwordProcessGDBRemote : public CommandObjectMultiword
-{
+class CommandObjectMultiwordProcessGDBRemote : public CommandObjectMultiword {
public:
- CommandObjectMultiwordProcessGDBRemote(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "process plugin", "Commands for operating on a ProcessGDBRemote process.",
- "process plugin <subcommand> [<subcommand-options>]")
- {
- LoadSubCommand ("packet", CommandObjectSP (new CommandObjectProcessGDBRemotePacket (interpreter)));
- }
-
- ~CommandObjectMultiwordProcessGDBRemote ()
- {
- }
+ CommandObjectMultiwordProcessGDBRemote(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "process plugin",
+ "Commands for operating on a ProcessGDBRemote process.",
+ "process plugin <subcommand> [<subcommand-options>]") {
+ LoadSubCommand(
+ "packet",
+ CommandObjectSP(new CommandObjectProcessGDBRemotePacket(interpreter)));
+ }
+
+ ~CommandObjectMultiwordProcessGDBRemote() {}
};
-CommandObject *
-ProcessGDBRemote::GetPluginCommandObject()
-{
- if (!m_command_sp)
- m_command_sp.reset (new CommandObjectMultiwordProcessGDBRemote (GetTarget().GetDebugger().GetCommandInterpreter()));
- return m_command_sp.get();
+CommandObject *ProcessGDBRemote::GetPluginCommandObject() {
+ if (!m_command_sp)
+ m_command_sp.reset(new CommandObjectMultiwordProcessGDBRemote(
+ GetTarget().GetDebugger().GetCommandInterpreter()));
+ return m_command_sp.get();
}
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 6d373965fc42..6423abc55836 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -24,462 +24,425 @@
#include "lldb/Core/Broadcaster.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Error.h"
+#include "lldb/Core/LoadedModuleInfoList.h"
+#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/StringList.h"
#include "lldb/Core/StructuredData.h"
#include "lldb/Core/ThreadSafeValue.h"
-#include "lldb/Core/LoadedModuleInfoList.h"
#include "lldb/Host/HostThread.h"
-#include "lldb/lldb-private-forward.h"
-#include "lldb/Utility/StringExtractor.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"
+#include "lldb/Utility/StringExtractor.h"
+#include "lldb/lldb-private-forward.h"
#include "GDBRemoteCommunicationClient.h"
#include "GDBRemoteRegisterContext.h"
+#include "llvm/ADT/DenseMap.h"
+
namespace lldb_private {
namespace process_gdb_remote {
class ThreadGDBRemote;
-class ProcessGDBRemote : public Process
-{
+class ProcessGDBRemote : public Process,
+ private GDBRemoteClientBase::ContinueDelegate {
public:
- ProcessGDBRemote(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp);
+ ProcessGDBRemote(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp);
- ~ProcessGDBRemote() override;
+ ~ProcessGDBRemote() override;
- static lldb::ProcessSP
- CreateInstance (lldb::TargetSP target_sp,
- lldb::ListenerSP listener_sp,
- const FileSpec *crash_file_path);
+ static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp,
+ lldb::ListenerSP listener_sp,
+ const FileSpec *crash_file_path);
- static void
- Initialize();
+ static void Initialize();
- static void
- DebuggerInitialize (Debugger &debugger);
+ static void DebuggerInitialize(Debugger &debugger);
- static void
- Terminate();
+ static void Terminate();
- static ConstString
- GetPluginNameStatic();
+ static ConstString GetPluginNameStatic();
- static const char *
- GetPluginDescriptionStatic();
+ static const char *GetPluginDescriptionStatic();
- //------------------------------------------------------------------
- // Check if a given Process
- //------------------------------------------------------------------
- bool
- CanDebug (lldb::TargetSP target_sp, bool plugin_specified_by_name) override;
+ //------------------------------------------------------------------
+ // Check if a given Process
+ //------------------------------------------------------------------
+ bool CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) override;
- CommandObject *
- GetPluginCommandObject() override;
+ CommandObject *GetPluginCommandObject() override;
- //------------------------------------------------------------------
- // Creating a new process, or attaching to an existing one
- //------------------------------------------------------------------
- Error
- WillLaunch (Module* module) override;
+ //------------------------------------------------------------------
+ // Creating a new process, or attaching to an existing one
+ //------------------------------------------------------------------
+ Error WillLaunch(Module *module) override;
- Error
- DoLaunch (Module *exe_module, ProcessLaunchInfo &launch_info) override;
+ Error DoLaunch(Module *exe_module, ProcessLaunchInfo &launch_info) override;
- void
- DidLaunch () override;
-
- Error
- WillAttachToProcessWithID (lldb::pid_t pid) override;
-
- Error
- WillAttachToProcessWithName (const char *process_name, bool wait_for_launch) override;
+ void DidLaunch() override;
- Error
- DoConnectRemote (Stream *strm, const char *remote_url) override;
-
- Error
- WillLaunchOrAttach ();
-
- Error
- DoAttachToProcessWithID (lldb::pid_t pid, const ProcessAttachInfo &attach_info) override;
-
- Error
- DoAttachToProcessWithName (const char *process_name,
- const ProcessAttachInfo &attach_info) override;
-
- void
- DidAttach (ArchSpec &process_arch) override;
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override;
-
- //------------------------------------------------------------------
- // Process Control
- //------------------------------------------------------------------
- Error
- WillResume () override;
-
- Error
- DoResume () override;
-
- Error
- DoHalt (bool &caused_stop) override;
-
- Error
- DoDetach (bool keep_stopped) override;
-
- bool
- DetachRequiresHalt() override { return true; }
-
- Error
- DoSignal (int signal) override;
-
- Error
- DoDestroy () override;
-
- void
- RefreshStateAfterStop() override;
-
- void
- SetUnixSignals(const lldb::UnixSignalsSP &signals_sp);
-
- //------------------------------------------------------------------
- // Process Queries
- //------------------------------------------------------------------
- bool
- IsAlive () override;
-
- lldb::addr_t
- GetImageInfoAddress() override;
-
- void
- WillPublicStop () override;
-
- //------------------------------------------------------------------
- // Process Memory
- //------------------------------------------------------------------
- size_t
- DoReadMemory (lldb::addr_t addr, void *buf, size_t size, Error &error) override;
-
- size_t
- DoWriteMemory (lldb::addr_t addr, const void *buf, size_t size, Error &error) override;
-
- lldb::addr_t
- DoAllocateMemory (size_t size, uint32_t permissions, Error &error) override;
-
- Error
- GetMemoryRegionInfo (lldb::addr_t load_addr, MemoryRegionInfo &region_info) override;
-
- Error
- DoDeallocateMemory (lldb::addr_t ptr) override;
-
- //------------------------------------------------------------------
- // Process STDIO
- //------------------------------------------------------------------
- size_t
- PutSTDIN (const char *buf, size_t buf_size, Error &error) override;
-
- //----------------------------------------------------------------------
- // Process Breakpoints
- //----------------------------------------------------------------------
- Error
- EnableBreakpointSite (BreakpointSite *bp_site) override;
-
- Error
- DisableBreakpointSite (BreakpointSite *bp_site) override;
-
- //----------------------------------------------------------------------
- // Process Watchpoints
- //----------------------------------------------------------------------
- Error
- EnableWatchpoint (Watchpoint *wp, bool notify = true) override;
-
- Error
- DisableWatchpoint (Watchpoint *wp, bool notify = true) override;
-
- Error
- GetWatchpointSupportInfo (uint32_t &num) override;
-
- Error
- GetWatchpointSupportInfo (uint32_t &num, bool& after) override;
-
- bool
- StartNoticingNewThreads() override;
-
- bool
- StopNoticingNewThreads() override;
-
- GDBRemoteCommunicationClient &
- GetGDBRemote()
- {
- return m_gdb_comm;
- }
-
- Error
- SendEventData(const char *data) override;
+ Error WillAttachToProcessWithID(lldb::pid_t pid) override;
+
+ Error WillAttachToProcessWithName(const char *process_name,
+ bool wait_for_launch) override;
+
+ Error DoConnectRemote(Stream *strm, llvm::StringRef remote_url) override;
+
+ Error WillLaunchOrAttach();
+
+ Error DoAttachToProcessWithID(lldb::pid_t pid,
+ const ProcessAttachInfo &attach_info) override;
+
+ Error
+ DoAttachToProcessWithName(const char *process_name,
+ const ProcessAttachInfo &attach_info) override;
+
+ void DidAttach(ArchSpec &process_arch) override;
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
+
+ //------------------------------------------------------------------
+ // Process Control
+ //------------------------------------------------------------------
+ Error WillResume() override;
+
+ Error DoResume() override;
+
+ Error DoHalt(bool &caused_stop) override;
+
+ Error DoDetach(bool keep_stopped) override;
+
+ bool DetachRequiresHalt() override { return true; }
+
+ Error DoSignal(int signal) override;
+
+ Error DoDestroy() override;
+
+ void RefreshStateAfterStop() override;
+
+ void SetUnixSignals(const lldb::UnixSignalsSP &signals_sp);
+
+ //------------------------------------------------------------------
+ // Process Queries
+ //------------------------------------------------------------------
+ bool IsAlive() override;
+
+ lldb::addr_t GetImageInfoAddress() override;
+
+ void WillPublicStop() override;
+
+ //------------------------------------------------------------------
+ // Process Memory
+ //------------------------------------------------------------------
+ size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ Error &error) override;
+
+ size_t DoWriteMemory(lldb::addr_t addr, const void *buf, size_t size,
+ Error &error) override;
+
+ lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions,
+ Error &error) override;
+
+ Error GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &region_info) override;
- //----------------------------------------------------------------------
- // Override DidExit so we can disconnect from the remote GDB server
- //----------------------------------------------------------------------
- void
- DidExit () override;
+ Error DoDeallocateMemory(lldb::addr_t ptr) override;
- void
- SetUserSpecifiedMaxMemoryTransferSize (uint64_t user_specified_max);
+ //------------------------------------------------------------------
+ // Process STDIO
+ //------------------------------------------------------------------
+ size_t PutSTDIN(const char *buf, size_t buf_size, Error &error) override;
- bool
- GetModuleSpec(const FileSpec& module_file_spec,
- const ArchSpec& arch,
- ModuleSpec &module_spec) override;
+ //----------------------------------------------------------------------
+ // Process Breakpoints
+ //----------------------------------------------------------------------
+ Error EnableBreakpointSite(BreakpointSite *bp_site) override;
- bool
- GetHostOSVersion(uint32_t &major,
- uint32_t &minor,
- uint32_t &update) override;
+ Error DisableBreakpointSite(BreakpointSite *bp_site) override;
- size_t
- LoadModules(LoadedModuleInfoList &module_list) override;
+ //----------------------------------------------------------------------
+ // Process Watchpoints
+ //----------------------------------------------------------------------
+ Error EnableWatchpoint(Watchpoint *wp, bool notify = true) override;
- size_t
- LoadModules() override;
+ Error DisableWatchpoint(Watchpoint *wp, bool notify = true) override;
- Error
- GetFileLoadAddress(const FileSpec& file, bool& is_loaded, lldb::addr_t& load_addr) override;
+ Error GetWatchpointSupportInfo(uint32_t &num) override;
- void
- ModulesDidLoad (ModuleList &module_list) override;
+ Error GetWatchpointSupportInfo(uint32_t &num, bool &after) override;
- StructuredData::ObjectSP
- GetLoadedDynamicLibrariesInfos (lldb::addr_t image_list_address, lldb::addr_t image_count) override;
+ bool StartNoticingNewThreads() override;
+
+ bool StopNoticingNewThreads() override;
+
+ GDBRemoteCommunicationClient &GetGDBRemote() { return m_gdb_comm; }
+
+ Error SendEventData(const char *data) override;
+
+ //----------------------------------------------------------------------
+ // Override DidExit so we can disconnect from the remote GDB server
+ //----------------------------------------------------------------------
+ void DidExit() override;
+
+ void SetUserSpecifiedMaxMemoryTransferSize(uint64_t user_specified_max);
+
+ bool GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch,
+ ModuleSpec &module_spec) override;
+
+ void PrefetchModuleSpecs(llvm::ArrayRef<FileSpec> module_file_specs,
+ const llvm::Triple &triple) override;
+
+ bool GetHostOSVersion(uint32_t &major, uint32_t &minor,
+ uint32_t &update) override;
+
+ size_t LoadModules(LoadedModuleInfoList &module_list) override;
+
+ size_t LoadModules() override;
+
+ Error GetFileLoadAddress(const FileSpec &file, bool &is_loaded,
+ lldb::addr_t &load_addr) override;
+
+ void ModulesDidLoad(ModuleList &module_list) override;
+
+ StructuredData::ObjectSP
+ GetLoadedDynamicLibrariesInfos(lldb::addr_t image_list_address,
+ lldb::addr_t image_count) override;
+
+ Error
+ ConfigureStructuredData(const ConstString &type_name,
+ const StructuredData::ObjectSP &config_sp) override;
+
+ StructuredData::ObjectSP GetLoadedDynamicLibrariesInfos() override;
+
+ StructuredData::ObjectSP GetLoadedDynamicLibrariesInfos(
+ const std::vector<lldb::addr_t> &load_addresses) override;
+
+ StructuredData::ObjectSP
+ GetLoadedDynamicLibrariesInfos_sender(StructuredData::ObjectSP args);
+
+ StructuredData::ObjectSP GetSharedCacheInfo() override;
+
+ std::string HarmonizeThreadIdsForProfileData(
+ StringExtractorGDBRemote &inputStringExtractor);
protected:
- friend class ThreadGDBRemote;
- friend class GDBRemoteCommunicationClient;
- friend class GDBRemoteRegisterContext;
-
- //------------------------------------------------------------------
- /// Broadcaster event bits definitions.
- //------------------------------------------------------------------
- enum
- {
- eBroadcastBitAsyncContinue = (1 << 0),
- eBroadcastBitAsyncThreadShouldExit = (1 << 1),
- eBroadcastBitAsyncThreadDidExit = (1 << 2)
- };
-
- Flags m_flags; // Process specific flags (see eFlags enums)
- GDBRemoteCommunicationClient m_gdb_comm;
- std::atomic<lldb::pid_t> m_debugserver_pid;
- std::vector<StringExtractorGDBRemote> m_stop_packet_stack; // The stop packet stack replaces the last stop packet variable
- std::recursive_mutex m_last_stop_packet_mutex;
- GDBRemoteDynamicRegisterInfo m_register_info;
- Broadcaster m_async_broadcaster;
- lldb::ListenerSP m_async_listener_sp;
- HostThread m_async_thread;
- std::recursive_mutex m_async_thread_state_mutex;
- typedef std::vector<lldb::tid_t> tid_collection;
- typedef std::vector< std::pair<lldb::tid_t,int> > tid_sig_collection;
- typedef std::map<lldb::addr_t, lldb::addr_t> MMapMap;
- typedef std::map<uint32_t, std::string> ExpeditedRegisterMap;
- tid_collection m_thread_ids; // Thread IDs for all threads. This list gets updated after stopping
- std::vector<lldb::addr_t> m_thread_pcs; // PC values for all the threads.
- StructuredData::ObjectSP m_jstopinfo_sp; // Stop info only for any threads that have valid stop infos
- StructuredData::ObjectSP m_jthreadsinfo_sp; // Full stop info, expedited registers and memory for all threads if "jThreadsInfo" packet is supported
- tid_collection m_continue_c_tids; // 'c' for continue
- tid_sig_collection m_continue_C_tids; // 'C' for continue with signal
- tid_collection m_continue_s_tids; // 's' for step
- tid_sig_collection m_continue_S_tids; // 'S' for step with signal
- uint64_t m_max_memory_size; // The maximum number of bytes to read/write when reading and writing memory
- uint64_t m_remote_stub_max_memory_size; // The maximum memory size the remote gdb stub can handle
- MMapMap m_addr_to_mmap_size;
- lldb::BreakpointSP m_thread_create_bp_sp;
- bool m_waiting_for_attach;
- bool m_destroy_tried_resuming;
- lldb::CommandObjectSP m_command_sp;
- int64_t m_breakpoint_pc_offset;
- lldb::tid_t m_initial_tid; // The initial thread ID, given by stub on attach
-
- //----------------------------------------------------------------------
- // Accessors
- //----------------------------------------------------------------------
- bool
- IsRunning ( lldb::StateType state )
- {
- return state == lldb::eStateRunning || IsStepping(state);
- }
+ friend class ThreadGDBRemote;
+ friend class GDBRemoteCommunicationClient;
+ friend class GDBRemoteRegisterContext;
+
+ //------------------------------------------------------------------
+ /// Broadcaster event bits definitions.
+ //------------------------------------------------------------------
+ enum {
+ eBroadcastBitAsyncContinue = (1 << 0),
+ eBroadcastBitAsyncThreadShouldExit = (1 << 1),
+ eBroadcastBitAsyncThreadDidExit = (1 << 2)
+ };
- bool
- IsStepping ( lldb::StateType state)
- {
- return state == lldb::eStateStepping;
- }
+ Flags m_flags; // Process specific flags (see eFlags enums)
+ GDBRemoteCommunicationClient m_gdb_comm;
+ std::atomic<lldb::pid_t> m_debugserver_pid;
+ std::vector<StringExtractorGDBRemote> m_stop_packet_stack; // The stop packet
+ // stack replaces
+ // the last stop
+ // packet variable
+ std::recursive_mutex m_last_stop_packet_mutex;
+ GDBRemoteDynamicRegisterInfo m_register_info;
+ Broadcaster m_async_broadcaster;
+ lldb::ListenerSP m_async_listener_sp;
+ HostThread m_async_thread;
+ std::recursive_mutex m_async_thread_state_mutex;
+ typedef std::vector<lldb::tid_t> tid_collection;
+ typedef std::vector<std::pair<lldb::tid_t, int>> tid_sig_collection;
+ typedef std::map<lldb::addr_t, lldb::addr_t> MMapMap;
+ typedef std::map<uint32_t, std::string> ExpeditedRegisterMap;
+ tid_collection m_thread_ids; // Thread IDs for all threads. This list gets
+ // updated after stopping
+ std::vector<lldb::addr_t> m_thread_pcs; // PC values for all the threads.
+ StructuredData::ObjectSP m_jstopinfo_sp; // Stop info only for any threads
+ // that have valid stop infos
+ StructuredData::ObjectSP m_jthreadsinfo_sp; // Full stop info, expedited
+ // registers and memory for all
+ // threads if "jThreadsInfo"
+ // packet is supported
+ tid_collection m_continue_c_tids; // 'c' for continue
+ tid_sig_collection m_continue_C_tids; // 'C' for continue with signal
+ tid_collection m_continue_s_tids; // 's' for step
+ tid_sig_collection m_continue_S_tids; // 'S' for step with signal
+ uint64_t m_max_memory_size; // The maximum number of bytes to read/write when
+ // reading and writing memory
+ uint64_t m_remote_stub_max_memory_size; // The maximum memory size the remote
+ // gdb stub can handle
+ MMapMap m_addr_to_mmap_size;
+ lldb::BreakpointSP m_thread_create_bp_sp;
+ bool m_waiting_for_attach;
+ bool m_destroy_tried_resuming;
+ lldb::CommandObjectSP m_command_sp;
+ int64_t m_breakpoint_pc_offset;
+ lldb::tid_t m_initial_tid; // The initial thread ID, given by stub on attach
- bool
- CanResume ( lldb::StateType state)
- {
- return state == lldb::eStateStopped;
- }
+ //----------------------------------------------------------------------
+ // Accessors
+ //----------------------------------------------------------------------
+ bool IsRunning(lldb::StateType state) {
+ return state == lldb::eStateRunning || IsStepping(state);
+ }
- bool
- HasExited (lldb::StateType state)
- {
- return state == lldb::eStateExited;
- }
+ bool IsStepping(lldb::StateType state) {
+ return state == lldb::eStateStepping;
+ }
- bool
- ProcessIDIsValid ( ) const;
+ bool CanResume(lldb::StateType state) { return state == lldb::eStateStopped; }
- void
- Clear ( );
+ bool HasExited(lldb::StateType state) { return state == lldb::eStateExited; }
- Flags &
- GetFlags ()
- {
- return m_flags;
- }
+ bool ProcessIDIsValid() const;
- const Flags &
- GetFlags () const
- {
- return m_flags;
- }
+ void Clear();
+
+ Flags &GetFlags() { return m_flags; }
- bool
- UpdateThreadList (ThreadList &old_thread_list,
- ThreadList &new_thread_list) override;
+ const Flags &GetFlags() const { return m_flags; }
- Error
- EstablishConnectionIfNeeded (const ProcessInfo &process_info);
+ bool UpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) override;
- Error
- LaunchAndConnectToDebugserver (const ProcessInfo &process_info);
+ Error EstablishConnectionIfNeeded(const ProcessInfo &process_info);
- void
- KillDebugserverProcess ();
+ Error LaunchAndConnectToDebugserver(const ProcessInfo &process_info);
- void
- BuildDynamicRegisterInfo (bool force);
+ void KillDebugserverProcess();
- void
- SetLastStopPacket (const StringExtractorGDBRemote &response);
+ void BuildDynamicRegisterInfo(bool force);
- bool
- ParsePythonTargetDefinition(const FileSpec &target_definition_fspec);
+ void SetLastStopPacket(const StringExtractorGDBRemote &response);
- const lldb::DataBufferSP
- GetAuxvData() override;
+ bool ParsePythonTargetDefinition(const FileSpec &target_definition_fspec);
- StructuredData::ObjectSP
- GetExtendedInfoForThread (lldb::tid_t tid);
+ const lldb::DataBufferSP GetAuxvData() override;
- void
- GetMaxMemorySize();
+ StructuredData::ObjectSP GetExtendedInfoForThread(lldb::tid_t tid);
- bool
- CalculateThreadStopInfo (ThreadGDBRemote *thread);
+ void GetMaxMemorySize();
- size_t
- UpdateThreadPCsFromStopReplyThreadsValue (std::string &value);
+ bool CalculateThreadStopInfo(ThreadGDBRemote *thread);
- size_t
- UpdateThreadIDsFromStopReplyThreadsValue (std::string &value);
+ size_t UpdateThreadPCsFromStopReplyThreadsValue(std::string &value);
- bool
- HandleNotifyPacket(StringExtractorGDBRemote &packet);
+ size_t UpdateThreadIDsFromStopReplyThreadsValue(std::string &value);
- bool
- StartAsyncThread ();
+ bool HandleNotifyPacket(StringExtractorGDBRemote &packet);
- void
- StopAsyncThread ();
+ bool StartAsyncThread();
- static lldb::thread_result_t
- AsyncThread (void *arg);
+ void StopAsyncThread();
- static bool
- MonitorDebugserverProcess(std::weak_ptr<ProcessGDBRemote> process_wp, lldb::pid_t pid, bool exited, int signo,
- int exit_status);
+ static lldb::thread_result_t AsyncThread(void *arg);
- lldb::StateType
- SetThreadStopInfo (StringExtractor& stop_packet);
+ static bool
+ MonitorDebugserverProcess(std::weak_ptr<ProcessGDBRemote> process_wp,
+ lldb::pid_t pid, bool exited, int signo,
+ int exit_status);
- bool
- GetThreadStopInfoFromJSON (ThreadGDBRemote *thread, const StructuredData::ObjectSP &thread_infos_sp);
+ lldb::StateType SetThreadStopInfo(StringExtractor &stop_packet);
- lldb::ThreadSP
- SetThreadStopInfo (StructuredData::Dictionary *thread_dict);
+ bool
+ GetThreadStopInfoFromJSON(ThreadGDBRemote *thread,
+ const StructuredData::ObjectSP &thread_infos_sp);
- lldb::ThreadSP
- SetThreadStopInfo (lldb::tid_t tid,
- ExpeditedRegisterMap &expedited_register_map,
- uint8_t signo,
- const std::string &thread_name,
- const std::string &reason,
- const std::string &description,
- uint32_t exc_type,
- const std::vector<lldb::addr_t> &exc_data,
- lldb::addr_t thread_dispatch_qaddr,
- bool queue_vars_valid,
- lldb_private::LazyBool associated_with_libdispatch_queue,
- lldb::addr_t dispatch_queue_t,
- std::string &queue_name,
- lldb::QueueKind queue_kind,
- uint64_t queue_serial);
+ lldb::ThreadSP SetThreadStopInfo(StructuredData::Dictionary *thread_dict);
- void
- HandleStopReplySequence ();
+ lldb::ThreadSP
+ SetThreadStopInfo(lldb::tid_t tid,
+ ExpeditedRegisterMap &expedited_register_map, uint8_t signo,
+ const std::string &thread_name, const std::string &reason,
+ const std::string &description, uint32_t exc_type,
+ const std::vector<lldb::addr_t> &exc_data,
+ lldb::addr_t thread_dispatch_qaddr, bool queue_vars_valid,
+ lldb_private::LazyBool associated_with_libdispatch_queue,
+ lldb::addr_t dispatch_queue_t, std::string &queue_name,
+ lldb::QueueKind queue_kind, uint64_t queue_serial);
- void
- ClearThreadIDList ();
+ void HandleStopReplySequence();
- bool
- UpdateThreadIDList ();
+ void ClearThreadIDList();
- void
- DidLaunchOrAttach (ArchSpec& process_arch);
+ bool UpdateThreadIDList();
- Error
- ConnectToDebugserver (const char *host_port);
+ void DidLaunchOrAttach(ArchSpec &process_arch);
- const char *
- GetDispatchQueueNameForThread (lldb::addr_t thread_dispatch_qaddr,
- std::string &dispatch_queue_name);
+ Error ConnectToDebugserver(llvm::StringRef host_port);
- DynamicLoader *
- GetDynamicLoader () override;
+ const char *GetDispatchQueueNameForThread(lldb::addr_t thread_dispatch_qaddr,
+ std::string &dispatch_queue_name);
- // Query remote GDBServer for register information
- bool
- GetGDBServerRegisterInfo (ArchSpec &arch);
+ DynamicLoader *GetDynamicLoader() override;
- // Query remote GDBServer for a detailed loaded library list
- Error
- GetLoadedModuleList (LoadedModuleInfoList &);
+ // Query remote GDBServer for register information
+ bool GetGDBServerRegisterInfo(ArchSpec &arch);
- lldb::ModuleSP
- LoadModuleAtAddress (const FileSpec &file, lldb::addr_t link_map, lldb::addr_t base_addr,
- bool value_is_offset);
+ // Query remote GDBServer for a detailed loaded library list
+ Error GetLoadedModuleList(LoadedModuleInfoList &);
+
+ lldb::ModuleSP LoadModuleAtAddress(const FileSpec &file,
+ lldb::addr_t link_map,
+ lldb::addr_t base_addr,
+ bool value_is_offset);
private:
- //------------------------------------------------------------------
- // For ProcessGDBRemote only
- //------------------------------------------------------------------
- static bool
- NewThreadNotifyBreakpointHit (void *baton,
- StoppointCallbackContext *context,
- lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id);
-
- DISALLOW_COPY_AND_ASSIGN (ProcessGDBRemote);
+ //------------------------------------------------------------------
+ // For ProcessGDBRemote only
+ //------------------------------------------------------------------
+ std::string m_partial_profile_data;
+ std::map<uint64_t, uint32_t> m_thread_id_to_used_usec_map;
+
+ static bool NewThreadNotifyBreakpointHit(void *baton,
+ StoppointCallbackContext *context,
+ lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id);
+
+ //------------------------------------------------------------------
+ // ContinueDelegate interface
+ //------------------------------------------------------------------
+ void HandleAsyncStdout(llvm::StringRef out) override;
+ void HandleAsyncMisc(llvm::StringRef data) override;
+ void HandleStopReply() override;
+ void HandleAsyncStructuredDataPacket(llvm::StringRef data) override;
+
+ using ModuleCacheKey = std::pair<std::string, std::string>;
+ // KeyInfo for the cached module spec DenseMap.
+ // The invariant is that all real keys will have the file and architecture
+ // set.
+ // The empty key has an empty file and an empty arch.
+ // The tombstone key has an invalid arch and an empty file.
+ // The comparison and hash functions take the file name and architecture
+ // triple into account.
+ struct ModuleCacheInfo {
+ static ModuleCacheKey getEmptyKey() { return ModuleCacheKey(); }
+
+ static ModuleCacheKey getTombstoneKey() { return ModuleCacheKey("", "T"); }
+
+ static unsigned getHashValue(const ModuleCacheKey &key) {
+ return llvm::hash_combine(key.first, key.second);
+ }
+
+ static bool isEqual(const ModuleCacheKey &LHS, const ModuleCacheKey &RHS) {
+ return LHS == RHS;
+ }
+ };
+
+ llvm::DenseMap<ModuleCacheKey, ModuleSpec, ModuleCacheInfo>
+ m_cached_module_specs;
+
+ DISALLOW_COPY_AND_ASSIGN(ProcessGDBRemote);
};
} // namespace process_gdb_remote
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp
index d4726adc890e..899037ae98aa 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp
@@ -11,8 +11,8 @@
#include <mutex>
-#include "lldb/Interpreter/Args.h"
#include "lldb/Core/StreamFile.h"
+#include "lldb/Interpreter/Args.h"
#include "ProcessGDBRemote.h"
@@ -20,196 +20,198 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
-
// We want to avoid global constructors where code needs to be run so here we
// control access to our static g_log_sp by hiding it in a singleton function
-// that will construct the static g_lob_sp the first time this function is
+// that will construct the static g_lob_sp the first time this function is
// called.
static bool g_log_enabled = false;
-static Log * g_log = NULL;
-static Log *
-GetLog ()
-{
- if (!g_log_enabled)
- return NULL;
- return g_log;
+static Log *g_log = NULL;
+static Log *GetLog() {
+ if (!g_log_enabled)
+ return NULL;
+ return g_log;
}
-void
-ProcessGDBRemoteLog::Initialize()
-{
- static ConstString g_name("gdb-remote");
- static std::once_flag g_once_flag;
-
- std::call_once(g_once_flag, [](){
- Log::Callbacks log_callbacks = {
- DisableLog,
- EnableLog,
- ListLogCategories
- };
-
- Log::RegisterLogChannel (g_name, log_callbacks);
- });
-}
+void ProcessGDBRemoteLog::Initialize() {
+ static ConstString g_name("gdb-remote");
+ static std::once_flag g_once_flag;
-Log *
-ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (uint32_t mask)
-{
- Log *log(GetLog ());
- if (log && mask)
- {
- uint32_t log_mask = log->GetMask().Get();
- if ((log_mask & mask) != mask)
- return NULL;
- }
- return log;
+ std::call_once(g_once_flag, []() {
+ Log::Callbacks log_callbacks = {DisableLog, EnableLog, ListLogCategories};
+
+ Log::RegisterLogChannel(g_name, log_callbacks);
+ });
}
-Log *
-ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (uint32_t mask)
-{
- Log *log(GetLog ());
- if (log && log->GetMask().Get() & mask)
- return log;
- return NULL;
+Log *ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(uint32_t mask) {
+ Log *log(GetLog());
+ if (log && mask) {
+ uint32_t log_mask = log->GetMask().Get();
+ if ((log_mask & mask) != mask)
+ return NULL;
+ }
+ return log;
}
-void
-ProcessGDBRemoteLog::DisableLog (const char **categories, Stream *feedback_strm)
-{
- Log *log (GetLog ());
- if (log)
- {
- uint32_t flag_bits = 0;
-
- if (categories[0] != NULL)
- {
- flag_bits = log->GetMask().Get();
- for (size_t i = 0; categories[i] != NULL; ++i)
- {
- const char *arg = categories[i];
-
-
- if (::strcasecmp (arg, "all") == 0 ) flag_bits &= ~GDBR_LOG_ALL;
- else if (::strcasecmp (arg, "async") == 0 ) flag_bits &= ~GDBR_LOG_ASYNC;
- else if (::strncasecmp (arg, "break", 5) == 0 ) flag_bits &= ~GDBR_LOG_BREAKPOINTS;
- else if (::strncasecmp (arg, "comm", 4) == 0 ) flag_bits &= ~GDBR_LOG_COMM;
- else if (::strcasecmp (arg, "default") == 0 ) flag_bits &= ~GDBR_LOG_DEFAULT;
- else if (::strcasecmp (arg, "packets") == 0 ) flag_bits &= ~GDBR_LOG_PACKETS;
- else if (::strcasecmp (arg, "memory") == 0 ) flag_bits &= ~GDBR_LOG_MEMORY;
- else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits &= ~GDBR_LOG_MEMORY_DATA_SHORT;
- else if (::strcasecmp (arg, "data-long") == 0 ) flag_bits &= ~GDBR_LOG_MEMORY_DATA_LONG;
- else if (::strcasecmp (arg, "process") == 0 ) flag_bits &= ~GDBR_LOG_PROCESS;
- else if (::strcasecmp (arg, "step") == 0 ) flag_bits &= ~GDBR_LOG_STEP;
- else if (::strcasecmp (arg, "thread") == 0 ) flag_bits &= ~GDBR_LOG_THREAD;
- else if (::strcasecmp (arg, "verbose") == 0 ) flag_bits &= ~GDBR_LOG_VERBOSE;
- else if (::strncasecmp (arg, "watch", 5) == 0 ) flag_bits &= ~GDBR_LOG_WATCHPOINTS;
- else
- {
- feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
- ListLogCategories (feedback_strm);
- }
-
- }
- }
-
- if (flag_bits == 0)
- g_log_enabled = false;
- else
- log->GetMask().Reset (flag_bits);
- }
-
- return;
+Log *ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(uint32_t mask) {
+ Log *log(GetLog());
+ if (log && log->GetMask().Get() & mask)
+ return log;
+ return NULL;
}
-Log *
-ProcessGDBRemoteLog::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, const char **categories, Stream *feedback_strm)
-{
- // Try see if there already is a log - that way we can reuse its settings.
- // We could reuse the log in toto, but we don't know that the stream is the same.
+void ProcessGDBRemoteLog::DisableLog(const char **categories,
+ Stream *feedback_strm) {
+ Log *log(GetLog());
+ if (log) {
uint32_t flag_bits = 0;
- if (g_log)
- flag_bits = g_log->GetMask().Get();
-
- // Now make a new log with this stream if one was provided
- if (log_stream_sp)
- {
- if (g_log)
- g_log->SetStream(log_stream_sp);
- else
- g_log = new Log(log_stream_sp);
+
+ if (categories && categories[0]) {
+ flag_bits = log->GetMask().Get();
+ for (size_t i = 0; categories[i] != NULL; ++i) {
+ const char *arg = categories[i];
+
+ if (::strcasecmp(arg, "all") == 0)
+ flag_bits &= ~GDBR_LOG_ALL;
+ else if (::strcasecmp(arg, "async") == 0)
+ flag_bits &= ~GDBR_LOG_ASYNC;
+ else if (::strncasecmp(arg, "break", 5) == 0)
+ flag_bits &= ~GDBR_LOG_BREAKPOINTS;
+ else if (::strncasecmp(arg, "comm", 4) == 0)
+ flag_bits &= ~GDBR_LOG_COMM;
+ else if (::strcasecmp(arg, "default") == 0)
+ flag_bits &= ~GDBR_LOG_DEFAULT;
+ else if (::strcasecmp(arg, "packets") == 0)
+ flag_bits &= ~GDBR_LOG_PACKETS;
+ else if (::strcasecmp(arg, "memory") == 0)
+ flag_bits &= ~GDBR_LOG_MEMORY;
+ else if (::strcasecmp(arg, "data-short") == 0)
+ flag_bits &= ~GDBR_LOG_MEMORY_DATA_SHORT;
+ else if (::strcasecmp(arg, "data-long") == 0)
+ flag_bits &= ~GDBR_LOG_MEMORY_DATA_LONG;
+ else if (::strcasecmp(arg, "process") == 0)
+ flag_bits &= ~GDBR_LOG_PROCESS;
+ else if (::strcasecmp(arg, "step") == 0)
+ flag_bits &= ~GDBR_LOG_STEP;
+ else if (::strcasecmp(arg, "thread") == 0)
+ flag_bits &= ~GDBR_LOG_THREAD;
+ else if (::strcasecmp(arg, "verbose") == 0)
+ flag_bits &= ~GDBR_LOG_VERBOSE;
+ else if (::strncasecmp(arg, "watch", 5) == 0)
+ flag_bits &= ~GDBR_LOG_WATCHPOINTS;
+ else {
+ feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
+ ListLogCategories(feedback_strm);
+ }
+ }
}
+ if (flag_bits == 0)
+ g_log_enabled = false;
+ else
+ log->GetMask().Reset(flag_bits);
+ }
+
+ return;
+}
+
+Log *ProcessGDBRemoteLog::EnableLog(StreamSP &log_stream_sp,
+ uint32_t log_options,
+ const char **categories,
+ Stream *feedback_strm) {
+ // Try see if there already is a log - that way we can reuse its settings.
+ // We could reuse the log in toto, but we don't know that the stream is the
+ // same.
+ uint32_t flag_bits = 0;
+ if (g_log)
+ flag_bits = g_log->GetMask().Get();
+
+ // Now make a new log with this stream if one was provided
+ if (log_stream_sp) {
if (g_log)
- {
- bool got_unknown_category = false;
- for (size_t i=0; categories[i] != NULL; ++i)
- {
- const char *arg = categories[i];
-
- if (::strcasecmp (arg, "all") == 0 ) flag_bits |= GDBR_LOG_ALL;
- else if (::strcasecmp (arg, "async") == 0 ) flag_bits |= GDBR_LOG_ASYNC;
- else if (::strncasecmp (arg, "break", 5) == 0 ) flag_bits |= GDBR_LOG_BREAKPOINTS;
- else if (::strncasecmp (arg, "comm", 4) == 0 ) flag_bits |= GDBR_LOG_COMM;
- else if (::strcasecmp (arg, "default") == 0 ) flag_bits |= GDBR_LOG_DEFAULT;
- else if (::strcasecmp (arg, "packets") == 0 ) flag_bits |= GDBR_LOG_PACKETS;
- else if (::strcasecmp (arg, "memory") == 0 ) flag_bits |= GDBR_LOG_MEMORY;
- else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits |= GDBR_LOG_MEMORY_DATA_SHORT;
- else if (::strcasecmp (arg, "data-long") == 0 ) flag_bits |= GDBR_LOG_MEMORY_DATA_LONG;
- else if (::strcasecmp (arg, "process") == 0 ) flag_bits |= GDBR_LOG_PROCESS;
- else if (::strcasecmp (arg, "step") == 0 ) flag_bits |= GDBR_LOG_STEP;
- else if (::strcasecmp (arg, "thread") == 0 ) flag_bits |= GDBR_LOG_THREAD;
- else if (::strcasecmp (arg, "verbose") == 0 ) flag_bits |= GDBR_LOG_VERBOSE;
- else if (::strncasecmp (arg, "watch", 5) == 0 ) flag_bits |= GDBR_LOG_WATCHPOINTS;
- else
- {
- feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
- if (got_unknown_category == false)
- {
- got_unknown_category = true;
- ListLogCategories (feedback_strm);
- }
- }
+ g_log->SetStream(log_stream_sp);
+ else
+ g_log = new Log(log_stream_sp);
+ }
+
+ if (g_log) {
+ bool got_unknown_category = false;
+ for (size_t i = 0; categories[i] != NULL; ++i) {
+ const char *arg = categories[i];
+
+ if (::strcasecmp(arg, "all") == 0)
+ flag_bits |= GDBR_LOG_ALL;
+ else if (::strcasecmp(arg, "async") == 0)
+ flag_bits |= GDBR_LOG_ASYNC;
+ else if (::strncasecmp(arg, "break", 5) == 0)
+ flag_bits |= GDBR_LOG_BREAKPOINTS;
+ else if (::strncasecmp(arg, "comm", 4) == 0)
+ flag_bits |= GDBR_LOG_COMM;
+ else if (::strcasecmp(arg, "default") == 0)
+ flag_bits |= GDBR_LOG_DEFAULT;
+ else if (::strcasecmp(arg, "packets") == 0)
+ flag_bits |= GDBR_LOG_PACKETS;
+ else if (::strcasecmp(arg, "memory") == 0)
+ flag_bits |= GDBR_LOG_MEMORY;
+ else if (::strcasecmp(arg, "data-short") == 0)
+ flag_bits |= GDBR_LOG_MEMORY_DATA_SHORT;
+ else if (::strcasecmp(arg, "data-long") == 0)
+ flag_bits |= GDBR_LOG_MEMORY_DATA_LONG;
+ else if (::strcasecmp(arg, "process") == 0)
+ flag_bits |= GDBR_LOG_PROCESS;
+ else if (::strcasecmp(arg, "step") == 0)
+ flag_bits |= GDBR_LOG_STEP;
+ else if (::strcasecmp(arg, "thread") == 0)
+ flag_bits |= GDBR_LOG_THREAD;
+ else if (::strcasecmp(arg, "verbose") == 0)
+ flag_bits |= GDBR_LOG_VERBOSE;
+ else if (::strncasecmp(arg, "watch", 5) == 0)
+ flag_bits |= GDBR_LOG_WATCHPOINTS;
+ else {
+ feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
+ if (got_unknown_category == false) {
+ got_unknown_category = true;
+ ListLogCategories(feedback_strm);
}
- if (flag_bits == 0)
- flag_bits = GDBR_LOG_DEFAULT;
- g_log->GetMask().Reset(flag_bits);
- g_log->GetOptions().Reset(log_options);
+ }
}
- g_log_enabled = true;
- return g_log;
+ if (flag_bits == 0)
+ flag_bits = GDBR_LOG_DEFAULT;
+ g_log->GetMask().Reset(flag_bits);
+ g_log->GetOptions().Reset(log_options);
+ }
+ g_log_enabled = true;
+ return g_log;
}
-void
-ProcessGDBRemoteLog::ListLogCategories (Stream *strm)
-{
- strm->Printf ("Logging categories for '%s':\n"
- " all - turn on all available logging categories\n"
- " async - log asynchronous activity\n"
- " break - log breakpoints\n"
- " communication - log communication activity\n"
- " default - enable the default set of logging categories for liblldb\n"
- " packets - log gdb remote packets\n"
- " memory - log memory reads and writes\n"
- " data-short - log memory bytes for memory reads and writes for short transactions only\n"
- " data-long - log memory bytes for memory reads and writes for all transactions\n"
- " process - log process events and activities\n"
- " thread - log thread events and activities\n"
- " step - log step related activities\n"
- " verbose - enable verbose logging\n"
- " watch - log watchpoint related activities\n", ProcessGDBRemote::GetPluginNameStatic().GetCString());
+void ProcessGDBRemoteLog::ListLogCategories(Stream *strm) {
+ strm->Printf(
+ "Logging categories for '%s':\n"
+ " all - turn on all available logging categories\n"
+ " async - log asynchronous activity\n"
+ " break - log breakpoints\n"
+ " communication - log communication activity\n"
+ " default - enable the default set of logging categories for liblldb\n"
+ " packets - log gdb remote packets\n"
+ " memory - log memory reads and writes\n"
+ " data-short - log memory bytes for memory reads and writes for short "
+ "transactions only\n"
+ " data-long - log memory bytes for memory reads and writes for all "
+ "transactions\n"
+ " process - log process events and activities\n"
+ " thread - log thread events and activities\n"
+ " step - log step related activities\n"
+ " verbose - enable verbose logging\n"
+ " watch - log watchpoint related activities\n",
+ ProcessGDBRemote::GetPluginNameStatic().GetCString());
}
-
-void
-ProcessGDBRemoteLog::LogIf (uint32_t mask, const char *format, ...)
-{
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (mask));
- if (log)
- {
- va_list args;
- va_start (args, format);
- log->VAPrintf (format, args);
- va_end (args);
- }
+void ProcessGDBRemoteLog::LogIf(uint32_t mask, const char *format, ...) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(mask));
+ if (log) {
+ va_list args;
+ va_start(args, format);
+ log->VAPrintf(format, args);
+ va_end(args);
+ }
}
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h b/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
index 3cd974d7d821..f5e92b450614 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
@@ -17,50 +17,44 @@
// Project includes
#include "lldb/Core/Log.h"
-#define GDBR_LOG_VERBOSE (1u << 0)
-#define GDBR_LOG_PROCESS (1u << 1)
-#define GDBR_LOG_THREAD (1u << 2)
-#define GDBR_LOG_PACKETS (1u << 3)
-#define GDBR_LOG_MEMORY (1u << 4) // Log memory reads/writes calls
-#define GDBR_LOG_MEMORY_DATA_SHORT (1u << 5) // Log short memory reads/writes bytes
-#define GDBR_LOG_MEMORY_DATA_LONG (1u << 6) // Log all memory reads/writes bytes
-#define GDBR_LOG_BREAKPOINTS (1u << 7)
-#define GDBR_LOG_WATCHPOINTS (1u << 8)
-#define GDBR_LOG_STEP (1u << 9)
-#define GDBR_LOG_COMM (1u << 10)
-#define GDBR_LOG_ASYNC (1u << 11)
-#define GDBR_LOG_ALL (UINT32_MAX)
-#define GDBR_LOG_DEFAULT GDBR_LOG_PACKETS
+#define GDBR_LOG_VERBOSE (1u << 0)
+#define GDBR_LOG_PROCESS (1u << 1)
+#define GDBR_LOG_THREAD (1u << 2)
+#define GDBR_LOG_PACKETS (1u << 3)
+#define GDBR_LOG_MEMORY (1u << 4) // Log memory reads/writes calls
+#define GDBR_LOG_MEMORY_DATA_SHORT \
+ (1u << 5) // Log short memory reads/writes bytes
+#define GDBR_LOG_MEMORY_DATA_LONG (1u << 6) // Log all memory reads/writes bytes
+#define GDBR_LOG_BREAKPOINTS (1u << 7)
+#define GDBR_LOG_WATCHPOINTS (1u << 8)
+#define GDBR_LOG_STEP (1u << 9)
+#define GDBR_LOG_COMM (1u << 10)
+#define GDBR_LOG_ASYNC (1u << 11)
+#define GDBR_LOG_ALL (UINT32_MAX)
+#define GDBR_LOG_DEFAULT GDBR_LOG_PACKETS
namespace lldb_private {
namespace process_gdb_remote {
-class ProcessGDBRemoteLog
-{
+class ProcessGDBRemoteLog {
public:
- static void
- Initialize();
+ static void Initialize();
- static Log *
- GetLogIfAllCategoriesSet(uint32_t mask = 0);
-
- static Log *
- GetLogIfAnyCategoryIsSet (uint32_t mask);
+ static Log *GetLogIfAllCategoriesSet(uint32_t mask = 0);
- static void
- DisableLog (const char **categories, Stream *feedback_strm);
+ static Log *GetLogIfAnyCategoryIsSet(uint32_t mask);
- static Log *
- EnableLog (lldb::StreamSP &log_stream_sp, uint32_t log_options, const char **categories, Stream *feedback_strm);
+ static void DisableLog(const char **categories, Stream *feedback_strm);
- static void
- ListLogCategories (Stream *strm);
+ static Log *EnableLog(lldb::StreamSP &log_stream_sp, uint32_t log_options,
+ const char **categories, Stream *feedback_strm);
- static void
- LogIf (uint32_t mask, const char *format, ...);
+ static void ListLogCategories(Stream *strm);
+
+ static void LogIf(uint32_t mask, const char *format, ...);
};
} // namespace process_gdb_remote
} // namespace lldb_private
-#endif // liblldb_ProcessGDBRemoteLog_h_
+#endif // liblldb_ProcessGDBRemoteLog_h_
diff --git a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
index a4af12c492c1..ab552145a18b 100644
--- a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-
#include "ThreadGDBRemote.h"
#include "lldb/Breakpoint/Watchpoint.h"
@@ -36,372 +35,318 @@ using namespace lldb_private::process_gdb_remote;
// Thread Registers
//----------------------------------------------------------------------
-ThreadGDBRemote::ThreadGDBRemote (Process &process, lldb::tid_t tid) :
- Thread(process, tid),
- m_thread_name (),
- m_dispatch_queue_name (),
- m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS),
- m_dispatch_queue_t (LLDB_INVALID_ADDRESS),
- m_queue_kind (eQueueKindUnknown),
- m_queue_serial_number (LLDB_INVALID_QUEUE_ID),
- m_associated_with_libdispatch_queue (eLazyBoolCalculate)
-{
- ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD, "%p: ThreadGDBRemote::ThreadGDBRemote (pid = %i, tid = 0x%4.4x)",
- this,
- process.GetID(),
- GetID());
+ThreadGDBRemote::ThreadGDBRemote(Process &process, lldb::tid_t tid)
+ : Thread(process, tid), m_thread_name(), m_dispatch_queue_name(),
+ m_thread_dispatch_qaddr(LLDB_INVALID_ADDRESS),
+ m_dispatch_queue_t(LLDB_INVALID_ADDRESS), m_queue_kind(eQueueKindUnknown),
+ m_queue_serial_number(LLDB_INVALID_QUEUE_ID),
+ m_associated_with_libdispatch_queue(eLazyBoolCalculate) {
+ ProcessGDBRemoteLog::LogIf(
+ GDBR_LOG_THREAD,
+ "%p: ThreadGDBRemote::ThreadGDBRemote (pid = %i, tid = 0x%4.4x)", this,
+ process.GetID(), GetID());
}
-ThreadGDBRemote::~ThreadGDBRemote ()
-{
- ProcessSP process_sp(GetProcess());
- ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD, "%p: ThreadGDBRemote::~ThreadGDBRemote (pid = %i, tid = 0x%4.4x)",
- this,
- process_sp ? process_sp->GetID() : LLDB_INVALID_PROCESS_ID,
- GetID());
- DestroyThread();
+ThreadGDBRemote::~ThreadGDBRemote() {
+ ProcessSP process_sp(GetProcess());
+ ProcessGDBRemoteLog::LogIf(
+ GDBR_LOG_THREAD,
+ "%p: ThreadGDBRemote::~ThreadGDBRemote (pid = %i, tid = 0x%4.4x)", this,
+ process_sp ? process_sp->GetID() : LLDB_INVALID_PROCESS_ID, GetID());
+ DestroyThread();
}
-const char *
-ThreadGDBRemote::GetName ()
-{
- if (m_thread_name.empty())
- return NULL;
- return m_thread_name.c_str();
+const char *ThreadGDBRemote::GetName() {
+ if (m_thread_name.empty())
+ return NULL;
+ return m_thread_name.c_str();
}
-void
-ThreadGDBRemote::ClearQueueInfo ()
-{
- m_dispatch_queue_name.clear();
- m_queue_kind = eQueueKindUnknown;
- m_queue_serial_number = 0;
- m_dispatch_queue_t = LLDB_INVALID_ADDRESS;
- m_associated_with_libdispatch_queue = eLazyBoolCalculate;
+void ThreadGDBRemote::ClearQueueInfo() {
+ m_dispatch_queue_name.clear();
+ m_queue_kind = eQueueKindUnknown;
+ m_queue_serial_number = 0;
+ m_dispatch_queue_t = LLDB_INVALID_ADDRESS;
+ m_associated_with_libdispatch_queue = eLazyBoolCalculate;
}
-void
-ThreadGDBRemote::SetQueueInfo (std::string &&queue_name, QueueKind queue_kind, uint64_t queue_serial, addr_t dispatch_queue_t, LazyBool associated_with_libdispatch_queue)
-{
- m_dispatch_queue_name = queue_name;
- m_queue_kind = queue_kind;
- m_queue_serial_number = queue_serial;
- m_dispatch_queue_t = dispatch_queue_t;
- m_associated_with_libdispatch_queue = associated_with_libdispatch_queue;
+void ThreadGDBRemote::SetQueueInfo(std::string &&queue_name,
+ QueueKind queue_kind, uint64_t queue_serial,
+ addr_t dispatch_queue_t,
+ LazyBool associated_with_libdispatch_queue) {
+ m_dispatch_queue_name = queue_name;
+ m_queue_kind = queue_kind;
+ m_queue_serial_number = queue_serial;
+ m_dispatch_queue_t = dispatch_queue_t;
+ m_associated_with_libdispatch_queue = associated_with_libdispatch_queue;
}
+const char *ThreadGDBRemote::GetQueueName() {
+ // If our cached queue info is valid, then someone called
+ // ThreadGDBRemote::SetQueueInfo(...)
+ // with valid information that was gleaned from the stop reply packet. In this
+ // case we trust
+ // that the info is valid in m_dispatch_queue_name without refetching it
+ if (CachedQueueInfoIsValid()) {
+ if (m_dispatch_queue_name.empty())
+ return nullptr;
+ else
+ return m_dispatch_queue_name.c_str();
+ }
+ // Always re-fetch the dispatch queue name since it can change
-const char *
-ThreadGDBRemote::GetQueueName ()
-{
- // If our cached queue info is valid, then someone called ThreadGDBRemote::SetQueueInfo(...)
- // with valid information that was gleaned from the stop reply packet. In this case we trust
- // that the info is valid in m_dispatch_queue_name without refetching it
- if (CachedQueueInfoIsValid())
- {
- if (m_dispatch_queue_name.empty())
- return nullptr;
- else
- return m_dispatch_queue_name.c_str();
- }
- // Always re-fetch the dispatch queue name since it can change
-
- if (m_associated_with_libdispatch_queue == eLazyBoolNo)
- return nullptr;
-
- if (m_thread_dispatch_qaddr != 0 && m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS)
- {
- ProcessSP process_sp (GetProcess());
- if (process_sp)
- {
- SystemRuntime *runtime = process_sp->GetSystemRuntime ();
- if (runtime)
- m_dispatch_queue_name = runtime->GetQueueNameFromThreadQAddress (m_thread_dispatch_qaddr);
- else
- m_dispatch_queue_name.clear();
-
- if (!m_dispatch_queue_name.empty())
- return m_dispatch_queue_name.c_str();
- }
+ if (m_associated_with_libdispatch_queue == eLazyBoolNo)
+ return nullptr;
+
+ if (m_thread_dispatch_qaddr != 0 &&
+ m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) {
+ ProcessSP process_sp(GetProcess());
+ if (process_sp) {
+ SystemRuntime *runtime = process_sp->GetSystemRuntime();
+ if (runtime)
+ m_dispatch_queue_name =
+ runtime->GetQueueNameFromThreadQAddress(m_thread_dispatch_qaddr);
+ else
+ m_dispatch_queue_name.clear();
+
+ if (!m_dispatch_queue_name.empty())
+ return m_dispatch_queue_name.c_str();
}
- return NULL;
+ }
+ return NULL;
}
-QueueKind
-ThreadGDBRemote::GetQueueKind ()
-{
- // If our cached queue info is valid, then someone called ThreadGDBRemote::SetQueueInfo(...)
- // with valid information that was gleaned from the stop reply packet. In this case we trust
- // that the info is valid in m_dispatch_queue_name without refetching it
- if (CachedQueueInfoIsValid())
- {
- return m_queue_kind;
- }
+QueueKind ThreadGDBRemote::GetQueueKind() {
+ // If our cached queue info is valid, then someone called
+ // ThreadGDBRemote::SetQueueInfo(...)
+ // with valid information that was gleaned from the stop reply packet. In this
+ // case we trust
+ // that the info is valid in m_dispatch_queue_name without refetching it
+ if (CachedQueueInfoIsValid()) {
+ return m_queue_kind;
+ }
+
+ if (m_associated_with_libdispatch_queue == eLazyBoolNo)
+ return eQueueKindUnknown;
- if (m_associated_with_libdispatch_queue == eLazyBoolNo)
- return eQueueKindUnknown;
-
- if (m_thread_dispatch_qaddr != 0 && m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS)
- {
- ProcessSP process_sp (GetProcess());
- if (process_sp)
- {
- SystemRuntime *runtime = process_sp->GetSystemRuntime ();
- if (runtime)
- m_queue_kind = runtime->GetQueueKind (m_thread_dispatch_qaddr);
- return m_queue_kind;
- }
+ if (m_thread_dispatch_qaddr != 0 &&
+ m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) {
+ ProcessSP process_sp(GetProcess());
+ if (process_sp) {
+ SystemRuntime *runtime = process_sp->GetSystemRuntime();
+ if (runtime)
+ m_queue_kind = runtime->GetQueueKind(m_thread_dispatch_qaddr);
+ return m_queue_kind;
}
- return eQueueKindUnknown;
+ }
+ return eQueueKindUnknown;
}
+queue_id_t ThreadGDBRemote::GetQueueID() {
+ // If our cached queue info is valid, then someone called
+ // ThreadGDBRemote::SetQueueInfo(...)
+ // with valid information that was gleaned from the stop reply packet. In this
+ // case we trust
+ // that the info is valid in m_dispatch_queue_name without refetching it
+ if (CachedQueueInfoIsValid())
+ return m_queue_serial_number;
-queue_id_t
-ThreadGDBRemote::GetQueueID ()
-{
- // If our cached queue info is valid, then someone called ThreadGDBRemote::SetQueueInfo(...)
- // with valid information that was gleaned from the stop reply packet. In this case we trust
- // that the info is valid in m_dispatch_queue_name without refetching it
- if (CachedQueueInfoIsValid())
- return m_queue_serial_number;
-
- if (m_associated_with_libdispatch_queue == eLazyBoolNo)
- return LLDB_INVALID_QUEUE_ID;
-
- if (m_thread_dispatch_qaddr != 0 && m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS)
- {
- ProcessSP process_sp (GetProcess());
- if (process_sp)
- {
- SystemRuntime *runtime = process_sp->GetSystemRuntime ();
- if (runtime)
- {
- return runtime->GetQueueIDFromThreadQAddress (m_thread_dispatch_qaddr);
- }
- }
- }
+ if (m_associated_with_libdispatch_queue == eLazyBoolNo)
return LLDB_INVALID_QUEUE_ID;
+
+ if (m_thread_dispatch_qaddr != 0 &&
+ m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) {
+ ProcessSP process_sp(GetProcess());
+ if (process_sp) {
+ SystemRuntime *runtime = process_sp->GetSystemRuntime();
+ if (runtime) {
+ return runtime->GetQueueIDFromThreadQAddress(m_thread_dispatch_qaddr);
+ }
+ }
+ }
+ return LLDB_INVALID_QUEUE_ID;
}
-QueueSP
-ThreadGDBRemote::GetQueue ()
-{
- queue_id_t queue_id = GetQueueID();
- QueueSP queue;
- if (queue_id != LLDB_INVALID_QUEUE_ID)
- {
- ProcessSP process_sp (GetProcess());
- if (process_sp)
- {
- queue = process_sp->GetQueueList().FindQueueByID (queue_id);
- }
+QueueSP ThreadGDBRemote::GetQueue() {
+ queue_id_t queue_id = GetQueueID();
+ QueueSP queue;
+ if (queue_id != LLDB_INVALID_QUEUE_ID) {
+ ProcessSP process_sp(GetProcess());
+ if (process_sp) {
+ queue = process_sp->GetQueueList().FindQueueByID(queue_id);
}
- return queue;
+ }
+ return queue;
}
-addr_t
-ThreadGDBRemote::GetQueueLibdispatchQueueAddress ()
-{
- if (m_dispatch_queue_t == LLDB_INVALID_ADDRESS)
- {
- if (m_thread_dispatch_qaddr != 0 && m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS)
- {
- ProcessSP process_sp (GetProcess());
- if (process_sp)
- {
- SystemRuntime *runtime = process_sp->GetSystemRuntime ();
- if (runtime)
- {
- m_dispatch_queue_t = runtime->GetLibdispatchQueueAddressFromThreadQAddress (m_thread_dispatch_qaddr);
- }
- }
+addr_t ThreadGDBRemote::GetQueueLibdispatchQueueAddress() {
+ if (m_dispatch_queue_t == LLDB_INVALID_ADDRESS) {
+ if (m_thread_dispatch_qaddr != 0 &&
+ m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) {
+ ProcessSP process_sp(GetProcess());
+ if (process_sp) {
+ SystemRuntime *runtime = process_sp->GetSystemRuntime();
+ if (runtime) {
+ m_dispatch_queue_t =
+ runtime->GetLibdispatchQueueAddressFromThreadQAddress(
+ m_thread_dispatch_qaddr);
}
+ }
}
- return m_dispatch_queue_t;
+ }
+ return m_dispatch_queue_t;
}
-void
-ThreadGDBRemote::SetQueueLibdispatchQueueAddress (lldb::addr_t dispatch_queue_t)
-{
- m_dispatch_queue_t = dispatch_queue_t;
+void ThreadGDBRemote::SetQueueLibdispatchQueueAddress(
+ lldb::addr_t dispatch_queue_t) {
+ m_dispatch_queue_t = dispatch_queue_t;
}
-bool
-ThreadGDBRemote::ThreadHasQueueInformation () const
-{
- if (m_thread_dispatch_qaddr != 0
- && m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS
- && m_dispatch_queue_t != LLDB_INVALID_ADDRESS
- && m_queue_kind != eQueueKindUnknown
- && m_queue_serial_number != 0)
- {
- return true;
- }
- return false;
+bool ThreadGDBRemote::ThreadHasQueueInformation() const {
+ if (m_thread_dispatch_qaddr != 0 &&
+ m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS &&
+ m_dispatch_queue_t != LLDB_INVALID_ADDRESS &&
+ m_queue_kind != eQueueKindUnknown && m_queue_serial_number != 0) {
+ return true;
+ }
+ return false;
}
-LazyBool
-ThreadGDBRemote::GetAssociatedWithLibdispatchQueue ()
-{
- return m_associated_with_libdispatch_queue;
+LazyBool ThreadGDBRemote::GetAssociatedWithLibdispatchQueue() {
+ return m_associated_with_libdispatch_queue;
}
-void
-ThreadGDBRemote::SetAssociatedWithLibdispatchQueue (LazyBool associated_with_libdispatch_queue)
-{
- m_associated_with_libdispatch_queue = associated_with_libdispatch_queue;
+void ThreadGDBRemote::SetAssociatedWithLibdispatchQueue(
+ LazyBool associated_with_libdispatch_queue) {
+ m_associated_with_libdispatch_queue = associated_with_libdispatch_queue;
}
-StructuredData::ObjectSP
-ThreadGDBRemote::FetchThreadExtendedInfo ()
-{
- StructuredData::ObjectSP object_sp;
- const lldb::user_id_t tid = GetProtocolID();
- Log *log(GetLogIfAnyCategoriesSet (GDBR_LOG_THREAD));
- if (log)
- log->Printf ("Fetching extended information for thread %4.4" PRIx64, tid);
- ProcessSP process_sp (GetProcess());
- if (process_sp)
- {
- ProcessGDBRemote *gdb_process = static_cast<ProcessGDBRemote *>(process_sp.get());
- object_sp = gdb_process->GetExtendedInfoForThread (tid);
- }
- return object_sp;
+StructuredData::ObjectSP ThreadGDBRemote::FetchThreadExtendedInfo() {
+ StructuredData::ObjectSP object_sp;
+ const lldb::user_id_t tid = GetProtocolID();
+ Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD));
+ if (log)
+ log->Printf("Fetching extended information for thread %4.4" PRIx64, tid);
+ ProcessSP process_sp(GetProcess());
+ if (process_sp) {
+ ProcessGDBRemote *gdb_process =
+ static_cast<ProcessGDBRemote *>(process_sp.get());
+ object_sp = gdb_process->GetExtendedInfoForThread(tid);
+ }
+ return object_sp;
}
-void
-ThreadGDBRemote::WillResume (StateType resume_state)
-{
- int signo = GetResumeSignal();
- const lldb::user_id_t tid = GetProtocolID();
- Log *log(GetLogIfAnyCategoriesSet (GDBR_LOG_THREAD));
- if (log)
- log->Printf ("Resuming thread: %4.4" PRIx64 " with state: %s.", tid, StateAsCString(resume_state));
-
- ProcessSP process_sp (GetProcess());
- if (process_sp)
- {
- ProcessGDBRemote *gdb_process = static_cast<ProcessGDBRemote *>(process_sp.get());
- switch (resume_state)
- {
- case eStateSuspended:
- case eStateStopped:
- // Don't append anything for threads that should stay stopped.
- break;
-
- case eStateRunning:
- if (gdb_process->GetUnixSignals()->SignalIsValid(signo))
- gdb_process->m_continue_C_tids.push_back(std::make_pair(tid, signo));
- else
- gdb_process->m_continue_c_tids.push_back(tid);
- break;
-
- case eStateStepping:
- if (gdb_process->GetUnixSignals()->SignalIsValid(signo))
- gdb_process->m_continue_S_tids.push_back(std::make_pair(tid, signo));
- else
- gdb_process->m_continue_s_tids.push_back(tid);
- break;
-
- default:
- break;
- }
+void ThreadGDBRemote::WillResume(StateType resume_state) {
+ int signo = GetResumeSignal();
+ const lldb::user_id_t tid = GetProtocolID();
+ Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD));
+ if (log)
+ log->Printf("Resuming thread: %4.4" PRIx64 " with state: %s.", tid,
+ StateAsCString(resume_state));
+
+ ProcessSP process_sp(GetProcess());
+ if (process_sp) {
+ ProcessGDBRemote *gdb_process =
+ static_cast<ProcessGDBRemote *>(process_sp.get());
+ switch (resume_state) {
+ case eStateSuspended:
+ case eStateStopped:
+ // Don't append anything for threads that should stay stopped.
+ break;
+
+ case eStateRunning:
+ if (gdb_process->GetUnixSignals()->SignalIsValid(signo))
+ gdb_process->m_continue_C_tids.push_back(std::make_pair(tid, signo));
+ else
+ gdb_process->m_continue_c_tids.push_back(tid);
+ break;
+
+ case eStateStepping:
+ if (gdb_process->GetUnixSignals()->SignalIsValid(signo))
+ gdb_process->m_continue_S_tids.push_back(std::make_pair(tid, signo));
+ else
+ gdb_process->m_continue_s_tids.push_back(tid);
+ break;
+
+ default:
+ break;
}
+ }
}
-void
-ThreadGDBRemote::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 GDBRemoteRegisterContext
- // 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.
- const bool force = false;
- GetRegisterContext()->InvalidateIfNeeded (force);
-}
-
-bool
-ThreadGDBRemote::ThreadIDIsValid (lldb::tid_t thread)
-{
- return thread != 0;
+void ThreadGDBRemote::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 GDBRemoteRegisterContext
+ // 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.
+ const bool force = false;
+ GetRegisterContext()->InvalidateIfNeeded(force);
}
-void
-ThreadGDBRemote::Dump(Log *log, uint32_t index)
-{
+bool ThreadGDBRemote::ThreadIDIsValid(lldb::tid_t thread) {
+ return thread != 0;
}
+void ThreadGDBRemote::Dump(Log *log, uint32_t index) {}
-bool
-ThreadGDBRemote::ShouldStop (bool &step_more)
-{
- return true;
-}
-lldb::RegisterContextSP
-ThreadGDBRemote::GetRegisterContext ()
-{
- if (m_reg_context_sp.get() == NULL)
- m_reg_context_sp = CreateRegisterContextForFrame (NULL);
- return m_reg_context_sp;
+bool ThreadGDBRemote::ShouldStop(bool &step_more) { return true; }
+lldb::RegisterContextSP ThreadGDBRemote::GetRegisterContext() {
+ if (m_reg_context_sp.get() == NULL)
+ m_reg_context_sp = CreateRegisterContextForFrame(NULL);
+ return m_reg_context_sp;
}
lldb::RegisterContextSP
-ThreadGDBRemote::CreateRegisterContextForFrame (StackFrame *frame)
-{
- lldb::RegisterContextSP reg_ctx_sp;
- uint32_t concrete_frame_idx = 0;
-
- if (frame)
- concrete_frame_idx = frame->GetConcreteFrameIndex ();
-
-
- if (concrete_frame_idx == 0)
- {
- ProcessSP process_sp (GetProcess());
- if (process_sp)
- {
- ProcessGDBRemote *gdb_process = static_cast<ProcessGDBRemote *>(process_sp.get());
- // read_all_registers_at_once will be true if 'p' packet is not supported.
- bool read_all_registers_at_once = !gdb_process->GetGDBRemote().GetpPacketSupported (GetID());
- reg_ctx_sp.reset (new GDBRemoteRegisterContext (*this, concrete_frame_idx, gdb_process->m_register_info, read_all_registers_at_once));
- }
- }
- else
- {
- Unwind *unwinder = GetUnwinder ();
- if (unwinder)
- reg_ctx_sp = unwinder->CreateRegisterContextForFrame (frame);
+ThreadGDBRemote::CreateRegisterContextForFrame(StackFrame *frame) {
+ lldb::RegisterContextSP reg_ctx_sp;
+ uint32_t concrete_frame_idx = 0;
+
+ if (frame)
+ concrete_frame_idx = frame->GetConcreteFrameIndex();
+
+ if (concrete_frame_idx == 0) {
+ ProcessSP process_sp(GetProcess());
+ if (process_sp) {
+ ProcessGDBRemote *gdb_process =
+ static_cast<ProcessGDBRemote *>(process_sp.get());
+ // read_all_registers_at_once will be true if 'p' packet is not supported.
+ bool read_all_registers_at_once =
+ !gdb_process->GetGDBRemote().GetpPacketSupported(GetID());
+ reg_ctx_sp.reset(new GDBRemoteRegisterContext(
+ *this, concrete_frame_idx, gdb_process->m_register_info,
+ read_all_registers_at_once));
}
- return reg_ctx_sp;
+ } else {
+ Unwind *unwinder = GetUnwinder();
+ if (unwinder)
+ reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame);
+ }
+ return reg_ctx_sp;
}
-bool
-ThreadGDBRemote::PrivateSetRegisterValue (uint32_t reg, StringExtractor &response)
-{
- GDBRemoteRegisterContext *gdb_reg_ctx = static_cast<GDBRemoteRegisterContext *>(GetRegisterContext ().get());
- assert (gdb_reg_ctx);
- return gdb_reg_ctx->PrivateSetRegisterValue (reg, response);
+bool ThreadGDBRemote::PrivateSetRegisterValue(uint32_t reg,
+ llvm::ArrayRef<uint8_t> data) {
+ GDBRemoteRegisterContext *gdb_reg_ctx =
+ static_cast<GDBRemoteRegisterContext *>(GetRegisterContext().get());
+ assert(gdb_reg_ctx);
+ return gdb_reg_ctx->PrivateSetRegisterValue(reg, data);
}
-bool
-ThreadGDBRemote::PrivateSetRegisterValue (uint32_t reg, uint64_t regval)
-{
- GDBRemoteRegisterContext *gdb_reg_ctx = static_cast<GDBRemoteRegisterContext *>(GetRegisterContext ().get());
- assert (gdb_reg_ctx);
- return gdb_reg_ctx->PrivateSetRegisterValue (reg, regval);
+bool ThreadGDBRemote::PrivateSetRegisterValue(uint32_t reg, uint64_t regval) {
+ GDBRemoteRegisterContext *gdb_reg_ctx =
+ static_cast<GDBRemoteRegisterContext *>(GetRegisterContext().get());
+ assert(gdb_reg_ctx);
+ return gdb_reg_ctx->PrivateSetRegisterValue(reg, regval);
}
-bool
-ThreadGDBRemote::CalculateStopInfo ()
-{
- ProcessSP process_sp (GetProcess());
- if (process_sp)
- return static_cast<ProcessGDBRemote *>(process_sp.get())->CalculateThreadStopInfo(this);
- return false;
+bool ThreadGDBRemote::CalculateStopInfo() {
+ ProcessSP process_sp(GetProcess());
+ if (process_sp)
+ return static_cast<ProcessGDBRemote *>(process_sp.get())
+ ->CalculateThreadStopInfo(this);
+ return false;
}
-
-
diff --git a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
index d7619f491e66..27caf42fc4a5 100644
--- a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
+++ b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
@@ -27,126 +27,94 @@ namespace process_gdb_remote {
class ProcessGDBRemote;
-class ThreadGDBRemote : public Thread
-{
+class ThreadGDBRemote : public Thread {
public:
- ThreadGDBRemote (Process &process, lldb::tid_t tid);
+ ThreadGDBRemote(Process &process, lldb::tid_t tid);
- ~ThreadGDBRemote() override;
+ ~ThreadGDBRemote() override;
- void
- WillResume (lldb::StateType resume_state) override;
+ void WillResume(lldb::StateType resume_state) override;
- void
- RefreshStateAfterStop() override;
+ void RefreshStateAfterStop() override;
- const char *
- GetName () override;
+ const char *GetName() override;
- const char *
- GetQueueName () override;
+ const char *GetQueueName() override;
- lldb::QueueKind
- GetQueueKind () override;
+ lldb::QueueKind GetQueueKind() override;
- lldb::queue_id_t
- GetQueueID () override;
+ lldb::queue_id_t GetQueueID() override;
- lldb::QueueSP
- GetQueue () override;
+ lldb::QueueSP GetQueue() override;
- lldb::addr_t
- GetQueueLibdispatchQueueAddress () override;
+ lldb::addr_t GetQueueLibdispatchQueueAddress() override;
- void
- SetQueueLibdispatchQueueAddress (lldb::addr_t dispatch_queue_t) override;
+ void SetQueueLibdispatchQueueAddress(lldb::addr_t dispatch_queue_t) override;
- bool
- ThreadHasQueueInformation () const override;
+ bool ThreadHasQueueInformation() const override;
- lldb::RegisterContextSP
- GetRegisterContext () override;
+ lldb::RegisterContextSP GetRegisterContext() override;
- lldb::RegisterContextSP
- CreateRegisterContextForFrame (StackFrame *frame) override;
+ lldb::RegisterContextSP
+ CreateRegisterContextForFrame(StackFrame *frame) override;
- void
- Dump (Log *log, uint32_t index);
+ void Dump(Log *log, uint32_t index);
- static bool
- ThreadIDIsValid (lldb::tid_t thread);
+ static bool ThreadIDIsValid(lldb::tid_t thread);
- bool
- ShouldStop (bool &step_more);
+ bool ShouldStop(bool &step_more);
- const char *
- GetBasicInfoAsString ();
+ const char *GetBasicInfoAsString();
- void
- SetName (const char *name) override
- {
- if (name && name[0])
- m_thread_name.assign (name);
- else
- m_thread_name.clear();
- }
+ void SetName(const char *name) override {
+ if (name && name[0])
+ m_thread_name.assign(name);
+ else
+ m_thread_name.clear();
+ }
- lldb::addr_t
- GetThreadDispatchQAddr ()
- {
- return m_thread_dispatch_qaddr;
- }
+ lldb::addr_t GetThreadDispatchQAddr() { return m_thread_dispatch_qaddr; }
- void
- SetThreadDispatchQAddr (lldb::addr_t thread_dispatch_qaddr)
- {
- m_thread_dispatch_qaddr = thread_dispatch_qaddr;
- }
+ void SetThreadDispatchQAddr(lldb::addr_t thread_dispatch_qaddr) {
+ m_thread_dispatch_qaddr = thread_dispatch_qaddr;
+ }
- void
- ClearQueueInfo ();
-
- void
- SetQueueInfo (std::string &&queue_name, lldb::QueueKind queue_kind, uint64_t queue_serial, lldb::addr_t dispatch_queue_t, lldb_private::LazyBool associated_with_libdispatch_queue);
+ void ClearQueueInfo();
- lldb_private::LazyBool
- GetAssociatedWithLibdispatchQueue () override;
+ void SetQueueInfo(std::string &&queue_name, lldb::QueueKind queue_kind,
+ uint64_t queue_serial, lldb::addr_t dispatch_queue_t,
+ lldb_private::LazyBool associated_with_libdispatch_queue);
- void
- SetAssociatedWithLibdispatchQueue (lldb_private::LazyBool associated_with_libdispatch_queue) override;
+ lldb_private::LazyBool GetAssociatedWithLibdispatchQueue() override;
- StructuredData::ObjectSP
- FetchThreadExtendedInfo () override;
+ void SetAssociatedWithLibdispatchQueue(
+ lldb_private::LazyBool associated_with_libdispatch_queue) override;
+
+ StructuredData::ObjectSP FetchThreadExtendedInfo() override;
protected:
- friend class ProcessGDBRemote;
-
- std::string m_thread_name;
- std::string m_dispatch_queue_name;
- lldb::addr_t m_thread_dispatch_qaddr;
- lldb::addr_t m_dispatch_queue_t;
- lldb::QueueKind m_queue_kind; // Queue info from stop reply/stop info for thread
- uint64_t m_queue_serial_number; // Queue info from stop reply/stop info for thread
- lldb_private::LazyBool m_associated_with_libdispatch_queue;
-
- bool
- PrivateSetRegisterValue (uint32_t reg,
- StringExtractor &response);
-
- bool
- PrivateSetRegisterValue (uint32_t reg,
- uint64_t regval);
-
- bool
- CachedQueueInfoIsValid() const
- {
- return m_queue_kind != lldb::eQueueKindUnknown;
- }
- void
- SetStopInfoFromPacket (StringExtractor &stop_packet, uint32_t stop_id);
-
- bool
- CalculateStopInfo () override;
+ friend class ProcessGDBRemote;
+
+ std::string m_thread_name;
+ std::string m_dispatch_queue_name;
+ lldb::addr_t m_thread_dispatch_qaddr;
+ lldb::addr_t m_dispatch_queue_t;
+ lldb::QueueKind
+ m_queue_kind; // Queue info from stop reply/stop info for thread
+ uint64_t
+ m_queue_serial_number; // Queue info from stop reply/stop info for thread
+ lldb_private::LazyBool m_associated_with_libdispatch_queue;
+
+ bool PrivateSetRegisterValue(uint32_t reg, llvm::ArrayRef<uint8_t> data);
+
+ bool PrivateSetRegisterValue(uint32_t reg, uint64_t regval);
+
+ bool CachedQueueInfoIsValid() const {
+ return m_queue_kind != lldb::eQueueKindUnknown;
+ }
+ void SetStopInfoFromPacket(StringExtractor &stop_packet, uint32_t stop_id);
+
+ bool CalculateStopInfo() override;
};
} // namespace process_gdb_remote
diff --git a/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/source/Plugins/Process/mach-core/ProcessMachCore.cpp
index 6bf198ca2f37..f83499cdb233 100644
--- a/source/Plugins/Process/mach-core/ProcessMachCore.cpp
+++ b/source/Plugins/Process/mach-core/ProcessMachCore.cpp
@@ -1,4 +1,5 @@
-//===-- ProcessMachCore.cpp ------------------------------------------*- C++ -*-===//
+//===-- ProcessMachCore.cpp ------------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -32,622 +33,576 @@
// Project includes
#include "ProcessMachCore.h"
-#include "ThreadMachCore.h"
#include "StopInfoMachException.h"
+#include "ThreadMachCore.h"
// Needed for the plug-in names for the dynamic loaders.
#include "lldb/Utility/SafeMachO.h"
-#include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h"
#include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h"
+#include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h"
#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
using namespace lldb;
using namespace lldb_private;
-ConstString
-ProcessMachCore::GetPluginNameStatic()
-{
- static ConstString g_name("mach-o-core");
- return g_name;
+ConstString ProcessMachCore::GetPluginNameStatic() {
+ static ConstString g_name("mach-o-core");
+ return g_name;
}
-const char *
-ProcessMachCore::GetPluginDescriptionStatic()
-{
- return "Mach-O core file debugging plug-in.";
+const char *ProcessMachCore::GetPluginDescriptionStatic() {
+ return "Mach-O core file debugging plug-in.";
}
-void
-ProcessMachCore::Terminate()
-{
- PluginManager::UnregisterPlugin (ProcessMachCore::CreateInstance);
+void ProcessMachCore::Terminate() {
+ PluginManager::UnregisterPlugin(ProcessMachCore::CreateInstance);
}
-
-lldb::ProcessSP
-ProcessMachCore::CreateInstance (lldb::TargetSP target_sp, ListenerSP listener_sp, const FileSpec *crash_file)
-{
- lldb::ProcessSP process_sp;
- if (crash_file)
- {
- const size_t header_size = sizeof(llvm::MachO::mach_header);
- lldb::DataBufferSP data_sp (crash_file->ReadFileContents(0, header_size));
- if (data_sp && data_sp->GetByteSize() == header_size)
- {
- DataExtractor data(data_sp, lldb::eByteOrderLittle, 4);
-
- lldb::offset_t data_offset = 0;
- llvm::MachO::mach_header mach_header;
- if (ObjectFileMachO::ParseHeader(data, &data_offset, mach_header))
- {
- if (mach_header.filetype == llvm::MachO::MH_CORE)
- process_sp.reset(new ProcessMachCore (target_sp, listener_sp, *crash_file));
- }
- }
-
+lldb::ProcessSP ProcessMachCore::CreateInstance(lldb::TargetSP target_sp,
+ ListenerSP listener_sp,
+ const FileSpec *crash_file) {
+ lldb::ProcessSP process_sp;
+ if (crash_file) {
+ const size_t header_size = sizeof(llvm::MachO::mach_header);
+ lldb::DataBufferSP data_sp(crash_file->ReadFileContents(0, header_size));
+ if (data_sp && data_sp->GetByteSize() == header_size) {
+ DataExtractor data(data_sp, lldb::eByteOrderLittle, 4);
+
+ lldb::offset_t data_offset = 0;
+ llvm::MachO::mach_header mach_header;
+ if (ObjectFileMachO::ParseHeader(data, &data_offset, mach_header)) {
+ if (mach_header.filetype == llvm::MachO::MH_CORE)
+ process_sp.reset(
+ new ProcessMachCore(target_sp, listener_sp, *crash_file));
+ }
}
- return process_sp;
+ }
+ return process_sp;
}
-bool
-ProcessMachCore::CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name)
-{
- if (plugin_specified_by_name)
- return true;
+bool ProcessMachCore::CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) {
+ if (plugin_specified_by_name)
+ return true;
- // For now we are just making sure the file exists for a given module
- if (!m_core_module_sp && m_core_file.Exists())
- {
- // Don't add the Target's architecture to the ModuleSpec - we may be working
- // with a core file that doesn't have the correct cpusubtype in the header
- // but we should still try to use it - ModuleSpecList::FindMatchingModuleSpec
- // enforces a strict arch mach.
- ModuleSpec core_module_spec(m_core_file);
- Error error (ModuleList::GetSharedModule (core_module_spec,
- m_core_module_sp,
- NULL,
- NULL,
- NULL));
-
- if (m_core_module_sp)
- {
- ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
- if (core_objfile && core_objfile->GetType() == ObjectFile::eTypeCoreFile)
- return true;
- }
+ // For now we are just making sure the file exists for a given module
+ if (!m_core_module_sp && m_core_file.Exists()) {
+ // Don't add the Target's architecture to the ModuleSpec - we may be working
+ // with a core file that doesn't have the correct cpusubtype in the header
+ // but we should still try to use it -
+ // ModuleSpecList::FindMatchingModuleSpec
+ // enforces a strict arch mach.
+ ModuleSpec core_module_spec(m_core_file);
+ Error error(ModuleList::GetSharedModule(core_module_spec, m_core_module_sp,
+ NULL, NULL, NULL));
+
+ if (m_core_module_sp) {
+ ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
+ if (core_objfile && core_objfile->GetType() == ObjectFile::eTypeCoreFile)
+ return true;
}
- return false;
+ }
+ return false;
}
//----------------------------------------------------------------------
// ProcessMachCore constructor
//----------------------------------------------------------------------
-ProcessMachCore::ProcessMachCore(lldb::TargetSP target_sp, ListenerSP listener_sp, const FileSpec &core_file)
- : Process(target_sp, listener_sp),
- m_core_aranges(),
- m_core_range_infos(),
- m_core_module_sp(),
- m_core_file(core_file),
+ProcessMachCore::ProcessMachCore(lldb::TargetSP target_sp,
+ ListenerSP listener_sp,
+ const FileSpec &core_file)
+ : Process(target_sp, listener_sp), m_core_aranges(), m_core_range_infos(),
+ m_core_module_sp(), m_core_file(core_file),
m_dyld_addr(LLDB_INVALID_ADDRESS),
- m_mach_kernel_addr(LLDB_INVALID_ADDRESS),
- m_dyld_plugin_name()
-{
-}
+ m_mach_kernel_addr(LLDB_INVALID_ADDRESS), m_dyld_plugin_name() {}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-ProcessMachCore::~ProcessMachCore()
-{
- Clear();
- // We need to call finalize on the process before destroying ourselves
- // to make sure all of the broadcaster cleanup goes as planned. If we
- // destruct this class, then Process::~Process() might have problems
- // trying to fully destroy the broadcaster.
- Finalize();
+ProcessMachCore::~ProcessMachCore() {
+ Clear();
+ // We need to call finalize on the process before destroying ourselves
+ // to make sure all of the broadcaster cleanup goes as planned. If we
+ // destruct this class, then Process::~Process() might have problems
+ // trying to fully destroy the broadcaster.
+ Finalize();
}
//----------------------------------------------------------------------
// PluginInterface
//----------------------------------------------------------------------
-ConstString
-ProcessMachCore::GetPluginName()
-{
- return GetPluginNameStatic();
-}
+ConstString ProcessMachCore::GetPluginName() { return GetPluginNameStatic(); }
-uint32_t
-ProcessMachCore::GetPluginVersion()
-{
- return 1;
-}
+uint32_t ProcessMachCore::GetPluginVersion() { return 1; }
-bool
-ProcessMachCore::GetDynamicLoaderAddress (lldb::addr_t addr)
-{
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER | LIBLLDB_LOG_PROCESS));
- llvm::MachO::mach_header header;
- Error error;
- if (DoReadMemory (addr, &header, sizeof(header), error) != sizeof(header))
- return false;
- if (header.magic == llvm::MachO::MH_CIGAM ||
- header.magic == llvm::MachO::MH_CIGAM_64)
- {
- header.magic = llvm::ByteSwap_32(header.magic);
- header.cputype = llvm::ByteSwap_32(header.cputype);
- header.cpusubtype = llvm::ByteSwap_32(header.cpusubtype);
- header.filetype = llvm::ByteSwap_32(header.filetype);
- header.ncmds = llvm::ByteSwap_32(header.ncmds);
- header.sizeofcmds = llvm::ByteSwap_32(header.sizeofcmds);
- header.flags = llvm::ByteSwap_32(header.flags);
- }
-
- // TODO: swap header if needed...
- //printf("0x%16.16" PRIx64 ": magic = 0x%8.8x, file_type= %u\n", vaddr, header.magic, header.filetype);
- if (header.magic == llvm::MachO::MH_MAGIC ||
- header.magic == llvm::MachO::MH_MAGIC_64)
- {
- // Check MH_EXECUTABLE to see if we can find the mach image
- // that contains the shared library list. The dynamic loader
- // (dyld) is what contains the list for user applications,
- // and the mach kernel contains a global that has the list
- // of kexts to load
- switch (header.filetype)
- {
- case llvm::MachO::MH_DYLINKER:
- //printf("0x%16.16" PRIx64 ": file_type = MH_DYLINKER\n", vaddr);
- // Address of dyld "struct mach_header" in the core file
- if (log)
- log->Printf ("ProcessMachCore::GetDynamicLoaderAddress found a user process dyld binary image at 0x%" PRIx64, addr);
- m_dyld_addr = addr;
- return true;
-
- case llvm::MachO::MH_EXECUTE:
- //printf("0x%16.16" PRIx64 ": file_type = MH_EXECUTE\n", vaddr);
- // Check MH_EXECUTABLE file types to see if the dynamic link object flag
- // is NOT set. If it isn't, then we have a mach_kernel.
- if ((header.flags & llvm::MachO::MH_DYLDLINK) == 0)
- {
- if (log)
- log->Printf ("ProcessMachCore::GetDynamicLoaderAddress found a mach kernel binary image at 0x%" PRIx64, addr);
- // Address of the mach kernel "struct mach_header" in the core file.
- m_mach_kernel_addr = addr;
- return true;
- }
- break;
- }
- }
+bool ProcessMachCore::GetDynamicLoaderAddress(lldb::addr_t addr) {
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER |
+ LIBLLDB_LOG_PROCESS));
+ llvm::MachO::mach_header header;
+ Error error;
+ if (DoReadMemory(addr, &header, sizeof(header), error) != sizeof(header))
return false;
+ if (header.magic == llvm::MachO::MH_CIGAM ||
+ header.magic == llvm::MachO::MH_CIGAM_64) {
+ header.magic = llvm::ByteSwap_32(header.magic);
+ header.cputype = llvm::ByteSwap_32(header.cputype);
+ header.cpusubtype = llvm::ByteSwap_32(header.cpusubtype);
+ header.filetype = llvm::ByteSwap_32(header.filetype);
+ header.ncmds = llvm::ByteSwap_32(header.ncmds);
+ header.sizeofcmds = llvm::ByteSwap_32(header.sizeofcmds);
+ header.flags = llvm::ByteSwap_32(header.flags);
+ }
+
+ // TODO: swap header if needed...
+ // printf("0x%16.16" PRIx64 ": magic = 0x%8.8x, file_type= %u\n", vaddr,
+ // header.magic, header.filetype);
+ if (header.magic == llvm::MachO::MH_MAGIC ||
+ header.magic == llvm::MachO::MH_MAGIC_64) {
+ // Check MH_EXECUTABLE to see if we can find the mach image
+ // that contains the shared library list. The dynamic loader
+ // (dyld) is what contains the list for user applications,
+ // and the mach kernel contains a global that has the list
+ // of kexts to load
+ switch (header.filetype) {
+ case llvm::MachO::MH_DYLINKER:
+ // printf("0x%16.16" PRIx64 ": file_type = MH_DYLINKER\n", vaddr);
+ // Address of dyld "struct mach_header" in the core file
+ if (log)
+ log->Printf("ProcessMachCore::GetDynamicLoaderAddress found a user "
+ "process dyld binary image at 0x%" PRIx64,
+ addr);
+ m_dyld_addr = addr;
+ return true;
+
+ case llvm::MachO::MH_EXECUTE:
+ // printf("0x%16.16" PRIx64 ": file_type = MH_EXECUTE\n", vaddr);
+ // Check MH_EXECUTABLE file types to see if the dynamic link object flag
+ // is NOT set. If it isn't, then we have a mach_kernel.
+ if ((header.flags & llvm::MachO::MH_DYLDLINK) == 0) {
+ if (log)
+ log->Printf("ProcessMachCore::GetDynamicLoaderAddress found a mach "
+ "kernel binary image at 0x%" PRIx64,
+ addr);
+ // Address of the mach kernel "struct mach_header" in the core file.
+ m_mach_kernel_addr = addr;
+ return true;
+ }
+ break;
+ }
+ }
+ return false;
}
//----------------------------------------------------------------------
// Process Control
//----------------------------------------------------------------------
-Error
-ProcessMachCore::DoLoadCore ()
-{
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER | LIBLLDB_LOG_PROCESS));
- Error error;
- if (!m_core_module_sp)
- {
- error.SetErrorString ("invalid core module");
- return error;
- }
+Error ProcessMachCore::DoLoadCore() {
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER |
+ LIBLLDB_LOG_PROCESS));
+ Error error;
+ if (!m_core_module_sp) {
+ error.SetErrorString("invalid core module");
+ return error;
+ }
- ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
- if (core_objfile == NULL)
- {
- error.SetErrorString ("invalid core object file");
- return error;
- }
-
- if (core_objfile->GetNumThreadContexts() == 0)
- {
- error.SetErrorString ("core file doesn't contain any LC_THREAD load commands, or the LC_THREAD architecture is not supported in this lldb");
- return error;
- }
+ ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
+ if (core_objfile == NULL) {
+ error.SetErrorString("invalid core object file");
+ return error;
+ }
- SectionList *section_list = core_objfile->GetSectionList();
- if (section_list == NULL)
- {
- error.SetErrorString ("core file has no sections");
- return error;
- }
-
- const uint32_t num_sections = section_list->GetNumSections(0);
- if (num_sections == 0)
- {
- error.SetErrorString ("core file has no sections");
- return error;
- }
-
- SetCanJIT(false);
-
- llvm::MachO::mach_header header;
- DataExtractor data (&header,
- sizeof(header),
- m_core_module_sp->GetArchitecture().GetByteOrder(),
- m_core_module_sp->GetArchitecture().GetAddressByteSize());
-
- bool ranges_are_sorted = true;
- addr_t vm_addr = 0;
- for (uint32_t i=0; i<num_sections; ++i)
- {
- Section *section = section_list->GetSectionAtIndex (i).get();
- if (section)
- {
- lldb::addr_t section_vm_addr = section->GetFileAddress();
- FileRange file_range (section->GetFileOffset(), section->GetFileSize());
- VMRangeToFileOffset::Entry range_entry (section_vm_addr,
- section->GetByteSize(),
- file_range);
-
- if (vm_addr > section_vm_addr)
- ranges_are_sorted = false;
- vm_addr = section->GetFileAddress();
- VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back();
-// printf ("LC_SEGMENT[%u] arange=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), frange=[0x%8.8x - 0x%8.8x)\n",
-// i,
-// range_entry.GetRangeBase(),
-// range_entry.GetRangeEnd(),
-// range_entry.data.GetRangeBase(),
-// range_entry.data.GetRangeEnd());
-
- if (last_entry &&
- last_entry->GetRangeEnd() == range_entry.GetRangeBase() &&
- last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase())
- {
- last_entry->SetRangeEnd (range_entry.GetRangeEnd());
- last_entry->data.SetRangeEnd (range_entry.data.GetRangeEnd());
- //puts("combine");
- }
- else
- {
- m_core_aranges.Append(range_entry);
- }
- // Some core files don't fill in the permissions correctly. If that is the case
- // assume read + execute so clients don't think the memory is not readable,
- // or executable. The memory isn't writable since this plug-in doesn't implement
- // DoWriteMemory.
- uint32_t permissions = section->GetPermissions();
- if (permissions == 0)
- permissions = lldb::ePermissionsReadable | lldb::ePermissionsExecutable;
- m_core_range_infos.Append(
- VMRangeToPermissions::Entry(section_vm_addr, section->GetByteSize(), permissions));
- }
+ if (core_objfile->GetNumThreadContexts() == 0) {
+ error.SetErrorString("core file doesn't contain any LC_THREAD load "
+ "commands, or the LC_THREAD architecture is not "
+ "supported in this lldb");
+ return error;
+ }
+
+ SectionList *section_list = core_objfile->GetSectionList();
+ if (section_list == NULL) {
+ error.SetErrorString("core file has no sections");
+ return error;
+ }
+
+ const uint32_t num_sections = section_list->GetNumSections(0);
+ if (num_sections == 0) {
+ error.SetErrorString("core file has no sections");
+ return error;
+ }
+
+ SetCanJIT(false);
+
+ llvm::MachO::mach_header header;
+ DataExtractor data(&header, sizeof(header),
+ m_core_module_sp->GetArchitecture().GetByteOrder(),
+ m_core_module_sp->GetArchitecture().GetAddressByteSize());
+
+ bool ranges_are_sorted = true;
+ addr_t vm_addr = 0;
+ for (uint32_t i = 0; i < num_sections; ++i) {
+ Section *section = section_list->GetSectionAtIndex(i).get();
+ if (section) {
+ lldb::addr_t section_vm_addr = section->GetFileAddress();
+ FileRange file_range(section->GetFileOffset(), section->GetFileSize());
+ VMRangeToFileOffset::Entry range_entry(
+ section_vm_addr, section->GetByteSize(), file_range);
+
+ if (vm_addr > section_vm_addr)
+ ranges_are_sorted = false;
+ vm_addr = section->GetFileAddress();
+ VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back();
+ // printf ("LC_SEGMENT[%u] arange=[0x%16.16" PRIx64 " -
+ // 0x%16.16" PRIx64 "), frange=[0x%8.8x - 0x%8.8x)\n",
+ // i,
+ // range_entry.GetRangeBase(),
+ // range_entry.GetRangeEnd(),
+ // range_entry.data.GetRangeBase(),
+ // range_entry.data.GetRangeEnd());
+
+ if (last_entry &&
+ last_entry->GetRangeEnd() == range_entry.GetRangeBase() &&
+ last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase()) {
+ last_entry->SetRangeEnd(range_entry.GetRangeEnd());
+ last_entry->data.SetRangeEnd(range_entry.data.GetRangeEnd());
+ // puts("combine");
+ } else {
+ m_core_aranges.Append(range_entry);
+ }
+ // Some core files don't fill in the permissions correctly. If that is the
+ // case
+ // assume read + execute so clients don't think the memory is not
+ // readable,
+ // or executable. The memory isn't writable since this plug-in doesn't
+ // implement
+ // DoWriteMemory.
+ uint32_t permissions = section->GetPermissions();
+ if (permissions == 0)
+ permissions = lldb::ePermissionsReadable | lldb::ePermissionsExecutable;
+ m_core_range_infos.Append(VMRangeToPermissions::Entry(
+ section_vm_addr, section->GetByteSize(), permissions));
}
- if (!ranges_are_sorted)
- {
- m_core_aranges.Sort();
- m_core_range_infos.Sort();
+ }
+ if (!ranges_are_sorted) {
+ m_core_aranges.Sort();
+ m_core_range_infos.Sort();
+ }
+
+ if (m_dyld_addr == LLDB_INVALID_ADDRESS ||
+ m_mach_kernel_addr == LLDB_INVALID_ADDRESS) {
+ // We need to locate the main executable in the memory ranges
+ // we have in the core file. We need to search for both a user-process dyld
+ // binary
+ // and a kernel binary in memory; we must look at all the pages in the
+ // binary so
+ // we don't miss one or the other. Step through all memory segments
+ // searching for
+ // a kernel binary and for a user process dyld -- we'll decide which to
+ // prefer
+ // later if both are present.
+
+ const size_t num_core_aranges = m_core_aranges.GetSize();
+ for (size_t i = 0; i < num_core_aranges; ++i) {
+ const VMRangeToFileOffset::Entry *entry =
+ m_core_aranges.GetEntryAtIndex(i);
+ lldb::addr_t section_vm_addr_start = entry->GetRangeBase();
+ lldb::addr_t section_vm_addr_end = entry->GetRangeEnd();
+ for (lldb::addr_t section_vm_addr = section_vm_addr_start;
+ section_vm_addr < section_vm_addr_end; section_vm_addr += 0x1000) {
+ GetDynamicLoaderAddress(section_vm_addr);
+ }
}
-
- if (m_dyld_addr == LLDB_INVALID_ADDRESS || m_mach_kernel_addr == LLDB_INVALID_ADDRESS)
- {
- // We need to locate the main executable in the memory ranges
- // we have in the core file. We need to search for both a user-process dyld binary
- // and a kernel binary in memory; we must look at all the pages in the binary so
- // we don't miss one or the other. Step through all memory segments searching for
- // a kernel binary and for a user process dyld -- we'll decide which to prefer
- // later if both are present.
-
- const size_t num_core_aranges = m_core_aranges.GetSize();
- for (size_t i = 0; i < num_core_aranges; ++i)
- {
- const VMRangeToFileOffset::Entry *entry = m_core_aranges.GetEntryAtIndex(i);
- lldb::addr_t section_vm_addr_start = entry->GetRangeBase();
- lldb::addr_t section_vm_addr_end = entry->GetRangeEnd();
- for (lldb::addr_t section_vm_addr = section_vm_addr_start;
- section_vm_addr < section_vm_addr_end;
- section_vm_addr += 0x1000)
- {
- GetDynamicLoaderAddress (section_vm_addr);
- }
- }
+ }
+
+ if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) {
+ // In the case of multiple kernel images found in the core file via
+ // exhaustive
+ // search, we may not pick the correct one. See if the
+ // DynamicLoaderDarwinKernel's
+ // search heuristics might identify the correct one.
+ // Most of the time, I expect the address from SearchForDarwinKernel() will
+ // be the
+ // same as the address we found via exhaustive search.
+
+ if (GetTarget().GetArchitecture().IsValid() == false &&
+ m_core_module_sp.get()) {
+ GetTarget().SetArchitecture(m_core_module_sp->GetArchitecture());
}
-
- if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS)
- {
- // In the case of multiple kernel images found in the core file via exhaustive
- // search, we may not pick the correct one. See if the DynamicLoaderDarwinKernel's
- // search heuristics might identify the correct one.
- // Most of the time, I expect the address from SearchForDarwinKernel() will be the
- // same as the address we found via exhaustive search.
-
- if (GetTarget().GetArchitecture().IsValid() == false && m_core_module_sp.get())
- {
- GetTarget().SetArchitecture (m_core_module_sp->GetArchitecture());
- }
-
- // SearchForDarwinKernel will end up calling back into this this class in the GetImageInfoAddress
- // method which will give it the m_mach_kernel_addr/m_dyld_addr it already has. Save that aside
- // and set m_mach_kernel_addr/m_dyld_addr to an invalid address temporarily so
- // DynamicLoaderDarwinKernel does a real search for the kernel using its own heuristics.
-
- addr_t saved_mach_kernel_addr = m_mach_kernel_addr;
- addr_t saved_user_dyld_addr = m_dyld_addr;
- m_mach_kernel_addr = LLDB_INVALID_ADDRESS;
- m_dyld_addr = LLDB_INVALID_ADDRESS;
-
- addr_t better_kernel_address = DynamicLoaderDarwinKernel::SearchForDarwinKernel (this);
-
- m_mach_kernel_addr = saved_mach_kernel_addr;
- m_dyld_addr = saved_user_dyld_addr;
-
- if (better_kernel_address != LLDB_INVALID_ADDRESS)
- {
- if (log)
- log->Printf ("ProcessMachCore::DoLoadCore: Using the kernel address from DynamicLoaderDarwinKernel");
- m_mach_kernel_addr = better_kernel_address;
- }
+ // SearchForDarwinKernel will end up calling back into this this class in
+ // the GetImageInfoAddress
+ // method which will give it the m_mach_kernel_addr/m_dyld_addr it already
+ // has. Save that aside
+ // and set m_mach_kernel_addr/m_dyld_addr to an invalid address temporarily
+ // so
+ // DynamicLoaderDarwinKernel does a real search for the kernel using its own
+ // heuristics.
+
+ addr_t saved_mach_kernel_addr = m_mach_kernel_addr;
+ addr_t saved_user_dyld_addr = m_dyld_addr;
+ m_mach_kernel_addr = LLDB_INVALID_ADDRESS;
+ m_dyld_addr = LLDB_INVALID_ADDRESS;
+
+ addr_t better_kernel_address =
+ DynamicLoaderDarwinKernel::SearchForDarwinKernel(this);
+
+ m_mach_kernel_addr = saved_mach_kernel_addr;
+ m_dyld_addr = saved_user_dyld_addr;
+
+ if (better_kernel_address != LLDB_INVALID_ADDRESS) {
+ if (log)
+ log->Printf("ProcessMachCore::DoLoadCore: Using the kernel address "
+ "from DynamicLoaderDarwinKernel");
+ m_mach_kernel_addr = better_kernel_address;
}
-
-
- // If we found both a user-process dyld and a kernel binary, we need to decide
- // which to prefer.
- if (GetCorefilePreference() == eKernelCorefile)
- {
- if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS)
- {
- if (log)
- log->Printf ("ProcessMachCore::DoLoadCore: Using kernel corefile image at 0x%" PRIx64, m_mach_kernel_addr);
- m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
- }
- else if (m_dyld_addr != LLDB_INVALID_ADDRESS)
- {
- if (log)
- log->Printf ("ProcessMachCore::DoLoadCore: Using user process dyld image at 0x%" PRIx64, m_dyld_addr);
- m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
- }
+ }
+
+ // If we found both a user-process dyld and a kernel binary, we need to decide
+ // which to prefer.
+ if (GetCorefilePreference() == eKernelCorefile) {
+ if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) {
+ if (log)
+ log->Printf("ProcessMachCore::DoLoadCore: Using kernel corefile image "
+ "at 0x%" PRIx64,
+ m_mach_kernel_addr);
+ m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
+ } else if (m_dyld_addr != LLDB_INVALID_ADDRESS) {
+ if (log)
+ log->Printf("ProcessMachCore::DoLoadCore: Using user process dyld "
+ "image at 0x%" PRIx64,
+ m_dyld_addr);
+ m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
}
- else
- {
- if (m_dyld_addr != LLDB_INVALID_ADDRESS)
- {
- if (log)
- log->Printf ("ProcessMachCore::DoLoadCore: Using user process dyld image at 0x%" PRIx64, m_dyld_addr);
- m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
- }
- else if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS)
- {
- if (log)
- log->Printf ("ProcessMachCore::DoLoadCore: Using kernel corefile image at 0x%" PRIx64, m_mach_kernel_addr);
- m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
- }
+ } else {
+ if (m_dyld_addr != LLDB_INVALID_ADDRESS) {
+ if (log)
+ log->Printf("ProcessMachCore::DoLoadCore: Using user process dyld "
+ "image at 0x%" PRIx64,
+ m_dyld_addr);
+ m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
+ } else if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) {
+ if (log)
+ log->Printf("ProcessMachCore::DoLoadCore: Using kernel corefile image "
+ "at 0x%" PRIx64,
+ m_mach_kernel_addr);
+ m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
}
-
- // Even if the architecture is set in the target, we need to override
- // it to match the core file which is always single arch.
- ArchSpec arch (m_core_module_sp->GetArchitecture());
- if (arch.GetCore() == ArchSpec::eCore_x86_32_i486)
- {
- arch.SetTriple ("i386", GetTarget().GetPlatform().get());
+ }
+
+ if (m_dyld_plugin_name != DynamicLoaderMacOSXDYLD::GetPluginNameStatic()) {
+ // For non-user process core files, the permissions on the core file
+ // segments are usually
+ // meaningless, they may be just "read", because we're dealing with kernel
+ // coredumps or
+ // early startup coredumps and the dumper is grabbing pages of memory
+ // without knowing
+ // what they are. If they aren't marked as "exeuctable", that can break the
+ // unwinder
+ // which will check a pc value to see if it is in an executable segment and
+ // stop the
+ // backtrace early if it is not ("executable" and "unknown" would both be
+ // fine, but
+ // "not executable" will break the unwinder).
+ size_t core_range_infos_size = m_core_range_infos.GetSize();
+ for (size_t i = 0; i < core_range_infos_size; i++) {
+ VMRangeToPermissions::Entry *ent =
+ m_core_range_infos.GetMutableEntryAtIndex(i);
+ ent->data = lldb::ePermissionsReadable | lldb::ePermissionsExecutable;
}
- if (arch.IsValid())
- GetTarget().SetArchitecture(arch);
-
- return error;
+ }
+
+ // Even if the architecture is set in the target, we need to override
+ // it to match the core file which is always single arch.
+ ArchSpec arch(m_core_module_sp->GetArchitecture());
+ if (arch.GetCore() == ArchSpec::eCore_x86_32_i486) {
+ arch.SetTriple("i386", GetTarget().GetPlatform().get());
+ }
+ if (arch.IsValid())
+ GetTarget().SetArchitecture(arch);
+
+ return error;
}
-lldb_private::DynamicLoader *
-ProcessMachCore::GetDynamicLoader ()
-{
- if (m_dyld_ap.get() == NULL)
- m_dyld_ap.reset (DynamicLoader::FindPlugin(this, m_dyld_plugin_name.IsEmpty() ? NULL : m_dyld_plugin_name.GetCString()));
- return m_dyld_ap.get();
+lldb_private::DynamicLoader *ProcessMachCore::GetDynamicLoader() {
+ if (m_dyld_ap.get() == NULL)
+ m_dyld_ap.reset(DynamicLoader::FindPlugin(
+ this,
+ m_dyld_plugin_name.IsEmpty() ? NULL : m_dyld_plugin_name.GetCString()));
+ return m_dyld_ap.get();
}
-bool
-ProcessMachCore::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
-{
- if (old_thread_list.GetSize(false) == 0)
- {
- // Make up the thread the first time this is called so we can setup our one and only
- // core thread state.
- ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
-
- if (core_objfile)
- {
- const uint32_t num_threads = core_objfile->GetNumThreadContexts ();
- for (lldb::tid_t tid = 0; tid < num_threads; ++tid)
- {
- ThreadSP thread_sp(new ThreadMachCore (*this, tid));
- new_thread_list.AddThread (thread_sp);
- }
- }
- }
- else
- {
- const uint32_t num_threads = old_thread_list.GetSize(false);
- for (uint32_t i=0; i<num_threads; ++i)
- new_thread_list.AddThread (old_thread_list.GetThreadAtIndex (i, false));
+bool ProcessMachCore::UpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) {
+ if (old_thread_list.GetSize(false) == 0) {
+ // Make up the thread the first time this is called so we can setup our one
+ // and only
+ // core thread state.
+ ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
+
+ if (core_objfile) {
+ const uint32_t num_threads = core_objfile->GetNumThreadContexts();
+ for (lldb::tid_t tid = 0; tid < num_threads; ++tid) {
+ ThreadSP thread_sp(new ThreadMachCore(*this, tid));
+ new_thread_list.AddThread(thread_sp);
+ }
}
- return new_thread_list.GetSize(false) > 0;
+ } else {
+ const uint32_t num_threads = old_thread_list.GetSize(false);
+ for (uint32_t i = 0; i < num_threads; ++i)
+ new_thread_list.AddThread(old_thread_list.GetThreadAtIndex(i, false));
+ }
+ return new_thread_list.GetSize(false) > 0;
}
-void
-ProcessMachCore::RefreshStateAfterStop ()
-{
- // Let all threads recover from stopping and do any clean up based
- // on the previous thread state (if any).
- m_thread_list.RefreshStateAfterStop();
- //SetThreadStopInfo (m_last_stop_packet);
+void ProcessMachCore::RefreshStateAfterStop() {
+ // Let all threads recover from stopping and do any clean up based
+ // on the previous thread state (if any).
+ m_thread_list.RefreshStateAfterStop();
+ // SetThreadStopInfo (m_last_stop_packet);
}
-Error
-ProcessMachCore::DoDestroy ()
-{
- return Error();
-}
+Error ProcessMachCore::DoDestroy() { return Error(); }
//------------------------------------------------------------------
// Process Queries
//------------------------------------------------------------------
-bool
-ProcessMachCore::IsAlive ()
-{
- return true;
-}
+bool ProcessMachCore::IsAlive() { return true; }
-bool
-ProcessMachCore::WarnBeforeDetach () const
-{
- return false;
-}
+bool ProcessMachCore::WarnBeforeDetach() const { return false; }
//------------------------------------------------------------------
// Process Memory
//------------------------------------------------------------------
-size_t
-ProcessMachCore::ReadMemory (addr_t addr, void *buf, size_t size, Error &error)
-{
- // Don't allow the caching that lldb_private::Process::ReadMemory does
- // since in core files we have it all cached our our core file anyway.
- return DoReadMemory (addr, buf, size, error);
+size_t ProcessMachCore::ReadMemory(addr_t addr, void *buf, size_t size,
+ Error &error) {
+ // Don't allow the caching that lldb_private::Process::ReadMemory does
+ // since in core files we have it all cached our our core file anyway.
+ return DoReadMemory(addr, buf, size, error);
}
-size_t
-ProcessMachCore::DoReadMemory (addr_t addr, void *buf, size_t size, Error &error)
-{
- ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
- size_t bytes_read = 0;
-
- if (core_objfile)
- {
- //----------------------------------------------------------------------
- // Segments are not always contiguous in mach-o core files. We have core
- // files that have segments like:
- // Address Size File off File size
- // ---------- ---------- ---------- ----------
- // LC_SEGMENT 0x000f6000 0x00001000 0x1d509ee8 0x00001000 --- --- 0 0x00000000 __TEXT
- // LC_SEGMENT 0x0f600000 0x00100000 0x1d50aee8 0x00100000 --- --- 0 0x00000000 __TEXT
- // LC_SEGMENT 0x000f7000 0x00001000 0x1d60aee8 0x00001000 --- --- 0 0x00000000 __TEXT
- //
- // Any if the user executes the following command:
- //
- // (lldb) mem read 0xf6ff0
- //
- // We would attempt to read 32 bytes from 0xf6ff0 but would only
- // get 16 unless we loop through consecutive memory ranges that are
- // contiguous in the address space, but not in the file data.
- //----------------------------------------------------------------------
- while (bytes_read < size)
- {
- const addr_t curr_addr = addr + bytes_read;
- const VMRangeToFileOffset::Entry *core_memory_entry = m_core_aranges.FindEntryThatContains(curr_addr);
-
- if (core_memory_entry)
- {
- const addr_t offset = curr_addr - core_memory_entry->GetRangeBase();
- const addr_t bytes_left = core_memory_entry->GetRangeEnd() - curr_addr;
- const size_t bytes_to_read = std::min(size - bytes_read, (size_t)bytes_left);
- const size_t curr_bytes_read = core_objfile->CopyData(core_memory_entry->data.GetRangeBase() + offset,
- bytes_to_read, (char *)buf + bytes_read);
- if (curr_bytes_read == 0)
- break;
- bytes_read += curr_bytes_read;
- }
- else
- {
- // Only set the error if we didn't read any bytes
- if (bytes_read == 0)
- error.SetErrorStringWithFormat("core file does not contain 0x%" PRIx64, curr_addr);
- break;
- }
- }
+size_t ProcessMachCore::DoReadMemory(addr_t addr, void *buf, size_t size,
+ Error &error) {
+ ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
+ size_t bytes_read = 0;
+
+ if (core_objfile) {
+ //----------------------------------------------------------------------
+ // Segments are not always contiguous in mach-o core files. We have core
+ // files that have segments like:
+ // Address Size File off File size
+ // ---------- ---------- ---------- ----------
+ // LC_SEGMENT 0x000f6000 0x00001000 0x1d509ee8 0x00001000 --- --- 0
+ // 0x00000000 __TEXT
+ // LC_SEGMENT 0x0f600000 0x00100000 0x1d50aee8 0x00100000 --- --- 0
+ // 0x00000000 __TEXT
+ // LC_SEGMENT 0x000f7000 0x00001000 0x1d60aee8 0x00001000 --- --- 0
+ // 0x00000000 __TEXT
+ //
+ // Any if the user executes the following command:
+ //
+ // (lldb) mem read 0xf6ff0
+ //
+ // We would attempt to read 32 bytes from 0xf6ff0 but would only
+ // get 16 unless we loop through consecutive memory ranges that are
+ // contiguous in the address space, but not in the file data.
+ //----------------------------------------------------------------------
+ while (bytes_read < size) {
+ const addr_t curr_addr = addr + bytes_read;
+ const VMRangeToFileOffset::Entry *core_memory_entry =
+ m_core_aranges.FindEntryThatContains(curr_addr);
+
+ if (core_memory_entry) {
+ const addr_t offset = curr_addr - core_memory_entry->GetRangeBase();
+ const addr_t bytes_left = core_memory_entry->GetRangeEnd() - curr_addr;
+ const size_t bytes_to_read =
+ std::min(size - bytes_read, (size_t)bytes_left);
+ const size_t curr_bytes_read = core_objfile->CopyData(
+ core_memory_entry->data.GetRangeBase() + offset, bytes_to_read,
+ (char *)buf + bytes_read);
+ if (curr_bytes_read == 0)
+ break;
+ bytes_read += curr_bytes_read;
+ } else {
+ // Only set the error if we didn't read any bytes
+ if (bytes_read == 0)
+ error.SetErrorStringWithFormat(
+ "core file does not contain 0x%" PRIx64, curr_addr);
+ break;
+ }
}
+ }
- return bytes_read;
+ return bytes_read;
}
-Error
-ProcessMachCore::GetMemoryRegionInfo(addr_t load_addr, MemoryRegionInfo &region_info)
-{
- region_info.Clear();
- const VMRangeToPermissions::Entry *permission_entry = m_core_range_infos.FindEntryThatContainsOrFollows(load_addr);
- if (permission_entry)
- {
- if (permission_entry->Contains(load_addr))
- {
- region_info.GetRange().SetRangeBase(permission_entry->GetRangeBase());
- region_info.GetRange().SetRangeEnd(permission_entry->GetRangeEnd());
- const Flags permissions(permission_entry->data);
- region_info.SetReadable(permissions.Test(ePermissionsReadable) ? MemoryRegionInfo::eYes
- : MemoryRegionInfo::eNo);
- region_info.SetWritable(permissions.Test(ePermissionsWritable) ? MemoryRegionInfo::eYes
- : MemoryRegionInfo::eNo);
- region_info.SetExecutable(permissions.Test(ePermissionsExecutable) ? MemoryRegionInfo::eYes
- : MemoryRegionInfo::eNo);
- region_info.SetMapped(MemoryRegionInfo::eYes);
- }
- else if (load_addr < permission_entry->GetRangeBase())
- {
- region_info.GetRange().SetRangeBase(load_addr);
- region_info.GetRange().SetRangeEnd(permission_entry->GetRangeBase());
- region_info.SetReadable(MemoryRegionInfo::eNo);
- region_info.SetWritable(MemoryRegionInfo::eNo);
- region_info.SetExecutable(MemoryRegionInfo::eNo);
- region_info.SetMapped(MemoryRegionInfo::eNo);
- }
- return Error();
+Error ProcessMachCore::GetMemoryRegionInfo(addr_t load_addr,
+ MemoryRegionInfo &region_info) {
+ region_info.Clear();
+ const VMRangeToPermissions::Entry *permission_entry =
+ m_core_range_infos.FindEntryThatContainsOrFollows(load_addr);
+ if (permission_entry) {
+ if (permission_entry->Contains(load_addr)) {
+ region_info.GetRange().SetRangeBase(permission_entry->GetRangeBase());
+ region_info.GetRange().SetRangeEnd(permission_entry->GetRangeEnd());
+ const Flags permissions(permission_entry->data);
+ region_info.SetReadable(permissions.Test(ePermissionsReadable)
+ ? MemoryRegionInfo::eYes
+ : MemoryRegionInfo::eNo);
+ region_info.SetWritable(permissions.Test(ePermissionsWritable)
+ ? MemoryRegionInfo::eYes
+ : MemoryRegionInfo::eNo);
+ region_info.SetExecutable(permissions.Test(ePermissionsExecutable)
+ ? MemoryRegionInfo::eYes
+ : MemoryRegionInfo::eNo);
+ region_info.SetMapped(MemoryRegionInfo::eYes);
+ } else if (load_addr < permission_entry->GetRangeBase()) {
+ region_info.GetRange().SetRangeBase(load_addr);
+ region_info.GetRange().SetRangeEnd(permission_entry->GetRangeBase());
+ region_info.SetReadable(MemoryRegionInfo::eNo);
+ region_info.SetWritable(MemoryRegionInfo::eNo);
+ region_info.SetExecutable(MemoryRegionInfo::eNo);
+ region_info.SetMapped(MemoryRegionInfo::eNo);
}
-
- region_info.GetRange().SetRangeBase(load_addr);
- region_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
- region_info.SetReadable(MemoryRegionInfo::eNo);
- region_info.SetWritable(MemoryRegionInfo::eNo);
- region_info.SetExecutable(MemoryRegionInfo::eNo);
- region_info.SetMapped(MemoryRegionInfo::eNo);
return Error();
+ }
+
+ region_info.GetRange().SetRangeBase(load_addr);
+ region_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
+ region_info.SetReadable(MemoryRegionInfo::eNo);
+ region_info.SetWritable(MemoryRegionInfo::eNo);
+ region_info.SetExecutable(MemoryRegionInfo::eNo);
+ region_info.SetMapped(MemoryRegionInfo::eNo);
+ return Error();
}
-void
-ProcessMachCore::Clear()
-{
- m_thread_list.Clear();
-}
+void ProcessMachCore::Clear() { m_thread_list.Clear(); }
-void
-ProcessMachCore::Initialize()
-{
- static std::once_flag g_once_flag;
+void ProcessMachCore::Initialize() {
+ static std::once_flag g_once_flag;
- std::call_once(g_once_flag, []() {
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
- });
+ std::call_once(g_once_flag, []() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
+ });
}
-addr_t
-ProcessMachCore::GetImageInfoAddress()
-{
- // If we found both a user-process dyld and a kernel binary, we need to decide
- // which to prefer.
- if (GetCorefilePreference() == eKernelCorefile)
- {
- if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS)
- {
- return m_mach_kernel_addr;
- }
- return m_dyld_addr;
+addr_t ProcessMachCore::GetImageInfoAddress() {
+ // If we found both a user-process dyld and a kernel binary, we need to decide
+ // which to prefer.
+ if (GetCorefilePreference() == eKernelCorefile) {
+ if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) {
+ return m_mach_kernel_addr;
}
- else
- {
- if (m_dyld_addr != LLDB_INVALID_ADDRESS)
- {
- return m_dyld_addr;
- }
- return m_mach_kernel_addr;
+ return m_dyld_addr;
+ } else {
+ if (m_dyld_addr != LLDB_INVALID_ADDRESS) {
+ return m_dyld_addr;
}
+ return m_mach_kernel_addr;
+ }
}
-
-lldb_private::ObjectFile *
-ProcessMachCore::GetCoreObjectFile ()
-{
- return m_core_module_sp->GetObjectFile();
+lldb_private::ObjectFile *ProcessMachCore::GetCoreObjectFile() {
+ return m_core_module_sp->GetObjectFile();
}
diff --git a/source/Plugins/Process/mach-core/ProcessMachCore.h b/source/Plugins/Process/mach-core/ProcessMachCore.h
index 21a0083b2d12..7094eb33110b 100644
--- a/source/Plugins/Process/mach-core/ProcessMachCore.h
+++ b/source/Plugins/Process/mach-core/ProcessMachCore.h
@@ -23,147 +23,131 @@
class ThreadKDP;
-class ProcessMachCore : public lldb_private::Process
-{
+class ProcessMachCore : public lldb_private::Process {
public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- ProcessMachCore(lldb::TargetSP target_sp,
- lldb::ListenerSP listener,
- const lldb_private::FileSpec &core_file);
-
- ~ProcessMachCore() override;
-
- static lldb::ProcessSP
- CreateInstance (lldb::TargetSP target_sp,
- lldb::ListenerSP listener,
- const lldb_private::FileSpec *crash_file_path);
-
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- static const char *
- GetPluginDescriptionStatic();
-
- //------------------------------------------------------------------
- // Check if a given Process
- //------------------------------------------------------------------
- bool
- CanDebug (lldb::TargetSP target_sp,
- bool plugin_specified_by_name) override;
-
- //------------------------------------------------------------------
- // Creating a new process, or attaching to an existing one
- //------------------------------------------------------------------
- lldb_private::Error
- DoLoadCore () override;
-
- lldb_private::DynamicLoader *
- GetDynamicLoader () override;
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
-
- uint32_t
- GetPluginVersion() override;
-
- //------------------------------------------------------------------
- // Process Control
- //------------------------------------------------------------------
- lldb_private::Error
- DoDestroy () override;
-
- void
- RefreshStateAfterStop() override;
-
- //------------------------------------------------------------------
- // Process Queries
- //------------------------------------------------------------------
- bool
- IsAlive () override;
-
- bool
- WarnBeforeDetach () const override;
-
- //------------------------------------------------------------------
- // Process Memory
- //------------------------------------------------------------------
- size_t
- ReadMemory (lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error) override;
-
- size_t
- DoReadMemory (lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error) override;
-
- lldb_private::Error
- GetMemoryRegionInfo(lldb::addr_t load_addr, lldb_private::MemoryRegionInfo &region_info) override;
-
- lldb::addr_t
- GetImageInfoAddress () override;
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ ProcessMachCore(lldb::TargetSP target_sp, lldb::ListenerSP listener,
+ const lldb_private::FileSpec &core_file);
+
+ ~ProcessMachCore() override;
+
+ static lldb::ProcessSP
+ CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener,
+ const lldb_private::FileSpec *crash_file_path);
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static const char *GetPluginDescriptionStatic();
+
+ //------------------------------------------------------------------
+ // Check if a given Process
+ //------------------------------------------------------------------
+ bool CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) override;
+
+ //------------------------------------------------------------------
+ // Creating a new process, or attaching to an existing one
+ //------------------------------------------------------------------
+ lldb_private::Error DoLoadCore() override;
+
+ lldb_private::DynamicLoader *GetDynamicLoader() override;
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
+
+ //------------------------------------------------------------------
+ // Process Control
+ //------------------------------------------------------------------
+ lldb_private::Error DoDestroy() override;
+
+ void RefreshStateAfterStop() override;
+
+ //------------------------------------------------------------------
+ // Process Queries
+ //------------------------------------------------------------------
+ bool IsAlive() override;
+
+ bool WarnBeforeDetach() const override;
+
+ //------------------------------------------------------------------
+ // Process Memory
+ //------------------------------------------------------------------
+ size_t ReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ lldb_private::Error &error) override;
+
+ size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ lldb_private::Error &error) override;
+
+ lldb_private::Error
+ GetMemoryRegionInfo(lldb::addr_t load_addr,
+ lldb_private::MemoryRegionInfo &region_info) override;
+
+ lldb::addr_t GetImageInfoAddress() override;
protected:
- friend class ThreadMachCore;
-
- void
- Clear ( );
-
- bool
- UpdateThreadList (lldb_private::ThreadList &old_thread_list,
- lldb_private::ThreadList &new_thread_list) override;
-
- lldb_private::ObjectFile *
- GetCoreObjectFile ();
+ friend class ThreadMachCore;
+
+ void Clear();
+
+ bool UpdateThreadList(lldb_private::ThreadList &old_thread_list,
+ lldb_private::ThreadList &new_thread_list) override;
+
+ lldb_private::ObjectFile *GetCoreObjectFile();
+
private:
- bool
- GetDynamicLoaderAddress (lldb::addr_t addr);
-
- typedef enum CorefilePreference { eUserProcessCorefile, eKernelCorefile } CorefilePreferences;
-
- //------------------------------------------------------------------
- /// If a core file can be interpreted multiple ways, this establishes
- /// which style wins.
- ///
- /// If a core file contains both a kernel binary and a user-process
- /// dynamic loader, lldb needs to pick one over the other. This could
- /// be a kernel corefile that happens to have a copy of dyld in its
- /// memory. Or it could be a user process coredump of lldb while doing
- /// kernel debugging - so a copy of the kernel is in its heap. This
- /// should become a setting so it can be over-ridden when necessary.
- //------------------------------------------------------------------
- CorefilePreference
- GetCorefilePreference ()
- {
- // For now, if both user process and kernel binaries a present,
- // assume this is a kernel coredump which has a copy of a user
- // process dyld in one of its pages.
- return eKernelCorefile;
- }
-
- //------------------------------------------------------------------
- // For ProcessMachCore only
- //------------------------------------------------------------------
- typedef lldb_private::Range<lldb::addr_t, lldb::addr_t> FileRange;
- typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, FileRange> VMRangeToFileOffset;
- typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, uint32_t> VMRangeToPermissions;
-
- VMRangeToFileOffset m_core_aranges;
- VMRangeToPermissions m_core_range_infos;
- lldb::ModuleSP m_core_module_sp;
- lldb_private::FileSpec m_core_file;
- lldb::addr_t m_dyld_addr;
- lldb::addr_t m_mach_kernel_addr;
- lldb_private::ConstString m_dyld_plugin_name;
-
- DISALLOW_COPY_AND_ASSIGN (ProcessMachCore);
+ bool GetDynamicLoaderAddress(lldb::addr_t addr);
+
+ typedef enum CorefilePreference {
+ eUserProcessCorefile,
+ eKernelCorefile
+ } CorefilePreferences;
+
+ //------------------------------------------------------------------
+ /// If a core file can be interpreted multiple ways, this establishes
+ /// which style wins.
+ ///
+ /// If a core file contains both a kernel binary and a user-process
+ /// dynamic loader, lldb needs to pick one over the other. This could
+ /// be a kernel corefile that happens to have a copy of dyld in its
+ /// memory. Or it could be a user process coredump of lldb while doing
+ /// kernel debugging - so a copy of the kernel is in its heap. This
+ /// should become a setting so it can be over-ridden when necessary.
+ //------------------------------------------------------------------
+ CorefilePreference GetCorefilePreference() {
+ // For now, if both user process and kernel binaries a present,
+ // assume this is a kernel coredump which has a copy of a user
+ // process dyld in one of its pages.
+ return eKernelCorefile;
+ }
+
+ //------------------------------------------------------------------
+ // For ProcessMachCore only
+ //------------------------------------------------------------------
+ typedef lldb_private::Range<lldb::addr_t, lldb::addr_t> FileRange;
+ typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, FileRange>
+ VMRangeToFileOffset;
+ typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, uint32_t>
+ VMRangeToPermissions;
+
+ VMRangeToFileOffset m_core_aranges;
+ VMRangeToPermissions m_core_range_infos;
+ lldb::ModuleSP m_core_module_sp;
+ lldb_private::FileSpec m_core_file;
+ lldb::addr_t m_dyld_addr;
+ lldb::addr_t m_mach_kernel_addr;
+ lldb_private::ConstString m_dyld_plugin_name;
+
+ DISALLOW_COPY_AND_ASSIGN(ProcessMachCore);
};
#endif // liblldb_ProcessMachCore_h_
diff --git a/source/Plugins/Process/mach-core/ThreadMachCore.cpp b/source/Plugins/Process/mach-core/ThreadMachCore.cpp
index 2720c910e4d1..828b705edf57 100644
--- a/source/Plugins/Process/mach-core/ThreadMachCore.cpp
+++ b/source/Plugins/Process/mach-core/ThreadMachCore.cpp
@@ -7,22 +7,21 @@
//
//===----------------------------------------------------------------------===//
-
#include "ThreadMachCore.h"
#include "lldb/Utility/SafeMachO.h"
+#include "lldb/Breakpoint/Watchpoint.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/DataExtractor.h"
-#include "lldb/Core/StreamString.h"
#include "lldb/Core/State.h"
+#include "lldb/Core/StreamString.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Unwind.h"
-#include "lldb/Breakpoint/Watchpoint.h"
#include "ProcessMachCore.h"
//#include "RegisterContextKDP_arm.h"
@@ -36,97 +35,71 @@ using namespace lldb_private;
// Thread Registers
//----------------------------------------------------------------------
-ThreadMachCore::ThreadMachCore (Process &process, lldb::tid_t tid) :
- Thread(process, tid),
- m_thread_name (),
- m_dispatch_queue_name (),
- m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS),
- m_thread_reg_ctx_sp ()
-{
-}
+ThreadMachCore::ThreadMachCore(Process &process, lldb::tid_t tid)
+ : Thread(process, tid), m_thread_name(), m_dispatch_queue_name(),
+ m_thread_dispatch_qaddr(LLDB_INVALID_ADDRESS), m_thread_reg_ctx_sp() {}
-ThreadMachCore::~ThreadMachCore ()
-{
- DestroyThread();
-}
+ThreadMachCore::~ThreadMachCore() { DestroyThread(); }
-const char *
-ThreadMachCore::GetName ()
-{
- if (m_thread_name.empty())
- return NULL;
- return m_thread_name.c_str();
+const char *ThreadMachCore::GetName() {
+ if (m_thread_name.empty())
+ return NULL;
+ return m_thread_name.c_str();
}
-void
-ThreadMachCore::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.
- const bool force = false;
- GetRegisterContext()->InvalidateIfNeeded (force);
+void ThreadMachCore::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.
+ const bool force = false;
+ GetRegisterContext()->InvalidateIfNeeded(force);
}
-bool
-ThreadMachCore::ThreadIDIsValid (lldb::tid_t thread)
-{
- return thread != 0;
-}
+bool ThreadMachCore::ThreadIDIsValid(lldb::tid_t thread) { return thread != 0; }
-lldb::RegisterContextSP
-ThreadMachCore::GetRegisterContext ()
-{
- if (m_reg_context_sp.get() == NULL)
- m_reg_context_sp = CreateRegisterContextForFrame (NULL);
- return m_reg_context_sp;
+lldb::RegisterContextSP ThreadMachCore::GetRegisterContext() {
+ if (m_reg_context_sp.get() == NULL)
+ m_reg_context_sp = CreateRegisterContextForFrame(NULL);
+ return m_reg_context_sp;
}
lldb::RegisterContextSP
-ThreadMachCore::CreateRegisterContextForFrame (StackFrame *frame)
-{
- lldb::RegisterContextSP reg_ctx_sp;
- uint32_t concrete_frame_idx = 0;
-
- if (frame)
- concrete_frame_idx = frame->GetConcreteFrameIndex ();
-
- if (concrete_frame_idx == 0)
- {
- if (!m_thread_reg_ctx_sp)
- {
- ProcessSP process_sp (GetProcess());
-
- ObjectFile *core_objfile = static_cast<ProcessMachCore *>(process_sp.get())->GetCoreObjectFile ();
- if (core_objfile)
- m_thread_reg_ctx_sp = core_objfile->GetThreadContextAtIndex (GetID(), *this);
- }
- reg_ctx_sp = m_thread_reg_ctx_sp;
- }
- else
- {
- Unwind *unwinder = GetUnwinder ();
- if (unwinder)
- reg_ctx_sp = unwinder->CreateRegisterContextForFrame (frame);
+ThreadMachCore::CreateRegisterContextForFrame(StackFrame *frame) {
+ lldb::RegisterContextSP reg_ctx_sp;
+ uint32_t concrete_frame_idx = 0;
+
+ if (frame)
+ concrete_frame_idx = frame->GetConcreteFrameIndex();
+
+ if (concrete_frame_idx == 0) {
+ if (!m_thread_reg_ctx_sp) {
+ ProcessSP process_sp(GetProcess());
+
+ ObjectFile *core_objfile =
+ static_cast<ProcessMachCore *>(process_sp.get())->GetCoreObjectFile();
+ if (core_objfile)
+ m_thread_reg_ctx_sp =
+ core_objfile->GetThreadContextAtIndex(GetID(), *this);
}
- return reg_ctx_sp;
+ reg_ctx_sp = m_thread_reg_ctx_sp;
+ } else {
+ Unwind *unwinder = GetUnwinder();
+ if (unwinder)
+ reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame);
+ }
+ return reg_ctx_sp;
}
-bool
-ThreadMachCore::CalculateStopInfo ()
-{
- ProcessSP process_sp (GetProcess());
- if (process_sp)
- {
- SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, SIGSTOP));
- return true;
- }
- return false;
+bool ThreadMachCore::CalculateStopInfo() {
+ ProcessSP process_sp(GetProcess());
+ if (process_sp) {
+ SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, SIGSTOP));
+ return true;
+ }
+ return false;
}
-
-
diff --git a/source/Plugins/Process/mach-core/ThreadMachCore.h b/source/Plugins/Process/mach-core/ThreadMachCore.h
index 25973540db16..a4db484e850f 100644
--- a/source/Plugins/Process/mach-core/ThreadMachCore.h
+++ b/source/Plugins/Process/mach-core/ThreadMachCore.h
@@ -20,72 +20,55 @@
class ProcessMachCore;
-class ThreadMachCore : public lldb_private::Thread
-{
+class ThreadMachCore : public lldb_private::Thread {
public:
- ThreadMachCore (lldb_private::Process &process,
- lldb::tid_t tid);
+ ThreadMachCore(lldb_private::Process &process, lldb::tid_t tid);
- ~ThreadMachCore() override;
+ ~ThreadMachCore() override;
- void
- RefreshStateAfterStop() override;
+ void RefreshStateAfterStop() 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;
- static bool
- ThreadIDIsValid (lldb::tid_t thread);
+ static bool ThreadIDIsValid(lldb::tid_t thread);
- bool
- ShouldStop (bool &step_more);
+ bool ShouldStop(bool &step_more);
- const char *
- GetBasicInfoAsString ();
+ const char *GetBasicInfoAsString();
- void
- SetName(const char *name) override
- {
- if (name && name[0])
- m_thread_name.assign (name);
- else
- m_thread_name.clear();
- }
+ void SetName(const char *name) override {
+ if (name && name[0])
+ m_thread_name.assign(name);
+ else
+ m_thread_name.clear();
+ }
- lldb::addr_t
- GetThreadDispatchQAddr ()
- {
- return m_thread_dispatch_qaddr;
- }
+ lldb::addr_t GetThreadDispatchQAddr() { return m_thread_dispatch_qaddr; }
- void
- SetThreadDispatchQAddr (lldb::addr_t thread_dispatch_qaddr)
- {
- m_thread_dispatch_qaddr = thread_dispatch_qaddr;
- }
+ void SetThreadDispatchQAddr(lldb::addr_t thread_dispatch_qaddr) {
+ m_thread_dispatch_qaddr = thread_dispatch_qaddr;
+ }
protected:
- friend class ProcessMachCore;
-
- //------------------------------------------------------------------
- // Member variables.
- //------------------------------------------------------------------
- std::string m_thread_name;
- std::string m_dispatch_queue_name;
- lldb::addr_t m_thread_dispatch_qaddr;
- lldb::RegisterContextSP m_thread_reg_ctx_sp;
-
- //------------------------------------------------------------------
- // Protected member functions.
- //------------------------------------------------------------------
- bool
- CalculateStopInfo() override;
+ friend class ProcessMachCore;
+
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ std::string m_thread_name;
+ std::string m_dispatch_queue_name;
+ lldb::addr_t m_thread_dispatch_qaddr;
+ lldb::RegisterContextSP m_thread_reg_ctx_sp;
+
+ //------------------------------------------------------------------
+ // Protected member functions.
+ //------------------------------------------------------------------
+ bool CalculateStopInfo() override;
};
#endif // liblldb_ThreadMachCore_h_
diff --git a/source/Plugins/Process/minidump/CMakeLists.txt b/source/Plugins/Process/minidump/CMakeLists.txt
new file mode 100644
index 000000000000..ddc89cbd92c1
--- /dev/null
+++ b/source/Plugins/Process/minidump/CMakeLists.txt
@@ -0,0 +1,10 @@
+include_directories(../Utility)
+
+add_lldb_library(lldbPluginProcessMinidump
+ MinidumpTypes.cpp
+ MinidumpParser.cpp
+ RegisterContextMinidump_x86_32.cpp
+ RegisterContextMinidump_x86_64.cpp
+ ProcessMinidump.cpp
+ ThreadMinidump.cpp
+ )
diff --git a/source/Plugins/Process/minidump/MinidumpParser.cpp b/source/Plugins/Process/minidump/MinidumpParser.cpp
new file mode 100644
index 000000000000..37b3709c09c1
--- /dev/null
+++ b/source/Plugins/Process/minidump/MinidumpParser.cpp
@@ -0,0 +1,458 @@
+//===-- MinidumpParser.cpp ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Project includes
+#include "MinidumpParser.h"
+#include "NtStructures.h"
+#include "RegisterContextMinidump_x86_32.h"
+
+// Other libraries and framework includes
+#include "lldb/Target/MemoryRegionInfo.h"
+
+// C includes
+// C++ includes
+#include <map>
+
+using namespace lldb_private;
+using namespace minidump;
+
+llvm::Optional<MinidumpParser>
+MinidumpParser::Create(const lldb::DataBufferSP &data_buf_sp) {
+ if (data_buf_sp->GetByteSize() < sizeof(MinidumpHeader)) {
+ return llvm::None;
+ }
+
+ llvm::ArrayRef<uint8_t> header_data(data_buf_sp->GetBytes(),
+ sizeof(MinidumpHeader));
+ const MinidumpHeader *header = MinidumpHeader::Parse(header_data);
+
+ if (header == nullptr) {
+ return llvm::None;
+ }
+
+ lldb::offset_t directory_list_offset = header->stream_directory_rva;
+ // check if there is enough data for the parsing of the directory list
+ if ((directory_list_offset +
+ sizeof(MinidumpDirectory) * header->streams_count) >
+ data_buf_sp->GetByteSize()) {
+ return llvm::None;
+ }
+
+ const MinidumpDirectory *directory = nullptr;
+ Error error;
+ llvm::ArrayRef<uint8_t> directory_data(
+ data_buf_sp->GetBytes() + directory_list_offset,
+ sizeof(MinidumpDirectory) * header->streams_count);
+ llvm::DenseMap<uint32_t, MinidumpLocationDescriptor> directory_map;
+
+ for (uint32_t i = 0; i < header->streams_count; ++i) {
+ error = consumeObject(directory_data, directory);
+ if (error.Fail()) {
+ return llvm::None;
+ }
+ directory_map[static_cast<const uint32_t>(directory->stream_type)] =
+ directory->location;
+ }
+
+ return MinidumpParser(data_buf_sp, header, std::move(directory_map));
+}
+
+MinidumpParser::MinidumpParser(
+ const lldb::DataBufferSP &data_buf_sp, const MinidumpHeader *header,
+ llvm::DenseMap<uint32_t, MinidumpLocationDescriptor> &&directory_map)
+ : m_data_sp(data_buf_sp), m_header(header), m_directory_map(directory_map) {
+}
+
+llvm::ArrayRef<uint8_t> MinidumpParser::GetData() {
+ return llvm::ArrayRef<uint8_t>(m_data_sp->GetBytes(),
+ m_data_sp->GetByteSize());
+}
+
+llvm::ArrayRef<uint8_t>
+MinidumpParser::GetStream(MinidumpStreamType stream_type) {
+ auto iter = m_directory_map.find(static_cast<uint32_t>(stream_type));
+ if (iter == m_directory_map.end())
+ return {};
+
+ // check if there is enough data
+ if (iter->second.rva + iter->second.data_size > m_data_sp->GetByteSize())
+ return {};
+
+ return llvm::ArrayRef<uint8_t>(m_data_sp->GetBytes() + iter->second.rva,
+ iter->second.data_size);
+}
+
+llvm::Optional<std::string> MinidumpParser::GetMinidumpString(uint32_t rva) {
+ auto arr_ref = m_data_sp->GetData();
+ if (rva > arr_ref.size())
+ return llvm::None;
+ arr_ref = arr_ref.drop_front(rva);
+ return parseMinidumpString(arr_ref);
+}
+
+llvm::ArrayRef<MinidumpThread> MinidumpParser::GetThreads() {
+ llvm::ArrayRef<uint8_t> data = GetStream(MinidumpStreamType::ThreadList);
+
+ if (data.size() == 0)
+ return llvm::None;
+
+ return MinidumpThread::ParseThreadList(data);
+}
+
+llvm::ArrayRef<uint8_t>
+MinidumpParser::GetThreadContext(const MinidumpThread &td) {
+ if (td.thread_context.rva + td.thread_context.data_size > GetData().size())
+ return {};
+
+ return GetData().slice(td.thread_context.rva, td.thread_context.data_size);
+}
+
+llvm::ArrayRef<uint8_t>
+MinidumpParser::GetThreadContextWow64(const MinidumpThread &td) {
+ // On Windows, a 32-bit process can run on a 64-bit machine under
+ // WOW64. If the minidump was captured with a 64-bit debugger, then
+ // the CONTEXT we just grabbed from the mini_dump_thread is the one
+ // for the 64-bit "native" process rather than the 32-bit "guest"
+ // process we care about. In this case, we can get the 32-bit CONTEXT
+ // from the TEB (Thread Environment Block) of the 64-bit process.
+ auto teb_mem = GetMemory(td.teb, sizeof(TEB64));
+ if (teb_mem.empty())
+ return {};
+
+ const TEB64 *wow64teb;
+ Error error = consumeObject(teb_mem, wow64teb);
+ if (error.Fail())
+ return {};
+
+ // Slot 1 of the thread-local storage in the 64-bit TEB points to a
+ // structure that includes the 32-bit CONTEXT (after a ULONG).
+ // See: https://msdn.microsoft.com/en-us/library/ms681670.aspx
+ auto context =
+ GetMemory(wow64teb->tls_slots[1] + 4, sizeof(MinidumpContext_x86_32));
+ if (context.size() < sizeof(MinidumpContext_x86_32))
+ return {};
+
+ return context;
+ // NOTE: We don't currently use the TEB for anything else. If we
+ // need it in the future, the 32-bit TEB is located according to the address
+ // stored in the first slot of the 64-bit TEB (wow64teb.Reserved1[0]).
+}
+
+const MinidumpSystemInfo *MinidumpParser::GetSystemInfo() {
+ llvm::ArrayRef<uint8_t> data = GetStream(MinidumpStreamType::SystemInfo);
+
+ if (data.size() == 0)
+ return nullptr;
+
+ return MinidumpSystemInfo::Parse(data);
+}
+
+ArchSpec MinidumpParser::GetArchitecture() {
+ ArchSpec arch_spec;
+ const MinidumpSystemInfo *system_info = GetSystemInfo();
+
+ if (!system_info)
+ return arch_spec;
+
+ // TODO what to do about big endiand flavors of arm ?
+ // TODO set the arm subarch stuff if the minidump has info about it
+
+ llvm::Triple triple;
+ triple.setVendor(llvm::Triple::VendorType::UnknownVendor);
+
+ const MinidumpCPUArchitecture arch =
+ static_cast<const MinidumpCPUArchitecture>(
+ static_cast<const uint32_t>(system_info->processor_arch));
+
+ switch (arch) {
+ case MinidumpCPUArchitecture::X86:
+ triple.setArch(llvm::Triple::ArchType::x86);
+ break;
+ case MinidumpCPUArchitecture::AMD64:
+ triple.setArch(llvm::Triple::ArchType::x86_64);
+ break;
+ case MinidumpCPUArchitecture::ARM:
+ triple.setArch(llvm::Triple::ArchType::arm);
+ break;
+ case MinidumpCPUArchitecture::ARM64:
+ triple.setArch(llvm::Triple::ArchType::aarch64);
+ break;
+ default:
+ triple.setArch(llvm::Triple::ArchType::UnknownArch);
+ break;
+ }
+
+ const MinidumpOSPlatform os = static_cast<const MinidumpOSPlatform>(
+ static_cast<const uint32_t>(system_info->platform_id));
+
+ // TODO add all of the OSes that Minidump/breakpad distinguishes?
+ switch (os) {
+ case MinidumpOSPlatform::Win32S:
+ case MinidumpOSPlatform::Win32Windows:
+ case MinidumpOSPlatform::Win32NT:
+ case MinidumpOSPlatform::Win32CE:
+ triple.setOS(llvm::Triple::OSType::Win32);
+ break;
+ case MinidumpOSPlatform::Linux:
+ triple.setOS(llvm::Triple::OSType::Linux);
+ break;
+ case MinidumpOSPlatform::MacOSX:
+ triple.setOS(llvm::Triple::OSType::MacOSX);
+ break;
+ case MinidumpOSPlatform::Android:
+ triple.setOS(llvm::Triple::OSType::Linux);
+ triple.setEnvironment(llvm::Triple::EnvironmentType::Android);
+ break;
+ default:
+ triple.setOS(llvm::Triple::OSType::UnknownOS);
+ break;
+ }
+
+ arch_spec.SetTriple(triple);
+
+ return arch_spec;
+}
+
+const MinidumpMiscInfo *MinidumpParser::GetMiscInfo() {
+ llvm::ArrayRef<uint8_t> data = GetStream(MinidumpStreamType::MiscInfo);
+
+ if (data.size() == 0)
+ return nullptr;
+
+ return MinidumpMiscInfo::Parse(data);
+}
+
+llvm::Optional<LinuxProcStatus> MinidumpParser::GetLinuxProcStatus() {
+ llvm::ArrayRef<uint8_t> data = GetStream(MinidumpStreamType::LinuxProcStatus);
+
+ if (data.size() == 0)
+ return llvm::None;
+
+ return LinuxProcStatus::Parse(data);
+}
+
+llvm::Optional<lldb::pid_t> MinidumpParser::GetPid() {
+ const MinidumpMiscInfo *misc_info = GetMiscInfo();
+ if (misc_info != nullptr) {
+ return misc_info->GetPid();
+ }
+
+ llvm::Optional<LinuxProcStatus> proc_status = GetLinuxProcStatus();
+ if (proc_status.hasValue()) {
+ return proc_status->GetPid();
+ }
+
+ return llvm::None;
+}
+
+llvm::ArrayRef<MinidumpModule> MinidumpParser::GetModuleList() {
+ llvm::ArrayRef<uint8_t> data = GetStream(MinidumpStreamType::ModuleList);
+
+ if (data.size() == 0)
+ return {};
+
+ return MinidumpModule::ParseModuleList(data);
+}
+
+std::vector<const MinidumpModule *> MinidumpParser::GetFilteredModuleList() {
+ llvm::ArrayRef<MinidumpModule> modules = GetModuleList();
+ // map module_name -> pair(load_address, pointer to module struct in memory)
+ llvm::StringMap<std::pair<uint64_t, const MinidumpModule *>> lowest_addr;
+
+ std::vector<const MinidumpModule *> filtered_modules;
+
+ llvm::Optional<std::string> name;
+ std::string module_name;
+
+ for (const auto &module : modules) {
+ name = GetMinidumpString(module.module_name_rva);
+
+ if (!name)
+ continue;
+
+ module_name = name.getValue();
+
+ auto iter = lowest_addr.end();
+ bool exists;
+ std::tie(iter, exists) = lowest_addr.try_emplace(
+ module_name, std::make_pair(module.base_of_image, &module));
+
+ if (exists && module.base_of_image < iter->second.first)
+ iter->second = std::make_pair(module.base_of_image, &module);
+ }
+
+ filtered_modules.reserve(lowest_addr.size());
+ for (const auto &module : lowest_addr) {
+ filtered_modules.push_back(module.second.second);
+ }
+
+ return filtered_modules;
+}
+
+const MinidumpExceptionStream *MinidumpParser::GetExceptionStream() {
+ llvm::ArrayRef<uint8_t> data = GetStream(MinidumpStreamType::Exception);
+
+ if (data.size() == 0)
+ return nullptr;
+
+ return MinidumpExceptionStream::Parse(data);
+}
+
+llvm::Optional<minidump::Range>
+MinidumpParser::FindMemoryRange(lldb::addr_t addr) {
+ llvm::ArrayRef<uint8_t> data = GetStream(MinidumpStreamType::MemoryList);
+ llvm::ArrayRef<uint8_t> data64 = GetStream(MinidumpStreamType::Memory64List);
+
+ if (data.empty() && data64.empty())
+ return llvm::None;
+
+ if (!data.empty()) {
+ llvm::ArrayRef<MinidumpMemoryDescriptor> memory_list =
+ MinidumpMemoryDescriptor::ParseMemoryList(data);
+
+ if (memory_list.empty())
+ return llvm::None;
+
+ for (const auto &memory_desc : memory_list) {
+ const MinidumpLocationDescriptor &loc_desc = memory_desc.memory;
+ const lldb::addr_t range_start = memory_desc.start_of_memory_range;
+ const size_t range_size = loc_desc.data_size;
+
+ if (loc_desc.rva + loc_desc.data_size > GetData().size())
+ return llvm::None;
+
+ if (range_start <= addr && addr < range_start + range_size) {
+ return minidump::Range(range_start,
+ GetData().slice(loc_desc.rva, range_size));
+ }
+ }
+ }
+
+ // Some Minidumps have a Memory64ListStream that captures all the heap
+ // memory (full-memory Minidumps). We can't exactly use the same loop as
+ // above, because the Minidump uses slightly different data structures to
+ // describe those
+
+ if (!data64.empty()) {
+ llvm::ArrayRef<MinidumpMemoryDescriptor64> memory64_list;
+ uint64_t base_rva;
+ std::tie(memory64_list, base_rva) =
+ MinidumpMemoryDescriptor64::ParseMemory64List(data64);
+
+ if (memory64_list.empty())
+ return llvm::None;
+
+ for (const auto &memory_desc64 : memory64_list) {
+ const lldb::addr_t range_start = memory_desc64.start_of_memory_range;
+ const size_t range_size = memory_desc64.data_size;
+
+ if (base_rva + range_size > GetData().size())
+ return llvm::None;
+
+ if (range_start <= addr && addr < range_start + range_size) {
+ return minidump::Range(range_start,
+ GetData().slice(base_rva, range_size));
+ }
+ base_rva += range_size;
+ }
+ }
+
+ return llvm::None;
+}
+
+llvm::ArrayRef<uint8_t> MinidumpParser::GetMemory(lldb::addr_t addr,
+ size_t size) {
+ // I don't have a sense of how frequently this is called or how many memory
+ // ranges a Minidump typically has, so I'm not sure if searching for the
+ // appropriate range linearly each time is stupid. Perhaps we should build
+ // an index for faster lookups.
+ llvm::Optional<minidump::Range> range = FindMemoryRange(addr);
+ if (!range)
+ return {};
+
+ // There's at least some overlap between the beginning of the desired range
+ // (addr) and the current range. Figure out where the overlap begins and
+ // how much overlap there is.
+
+ const size_t offset = addr - range->start;
+
+ if (addr < range->start || offset >= range->range_ref.size())
+ return {};
+
+ const size_t overlap = std::min(size, range->range_ref.size() - offset);
+ return range->range_ref.slice(offset, overlap);
+}
+
+llvm::Optional<MemoryRegionInfo>
+MinidumpParser::GetMemoryRegionInfo(lldb::addr_t load_addr) {
+ MemoryRegionInfo info;
+ llvm::ArrayRef<uint8_t> data = GetStream(MinidumpStreamType::MemoryInfoList);
+ if (data.empty())
+ return llvm::None;
+
+ std::vector<const MinidumpMemoryInfo *> mem_info_list =
+ MinidumpMemoryInfo::ParseMemoryInfoList(data);
+ if (mem_info_list.empty())
+ return llvm::None;
+
+ const auto yes = MemoryRegionInfo::eYes;
+ const auto no = MemoryRegionInfo::eNo;
+
+ const MinidumpMemoryInfo *next_entry = nullptr;
+ for (const auto &entry : mem_info_list) {
+ const auto head = entry->base_address;
+ const auto tail = head + entry->region_size;
+
+ if (head <= load_addr && load_addr < tail) {
+ info.GetRange().SetRangeBase(
+ (entry->state != uint32_t(MinidumpMemoryInfoState::MemFree))
+ ? head
+ : load_addr);
+ info.GetRange().SetRangeEnd(tail);
+
+ const uint32_t PageNoAccess =
+ static_cast<uint32_t>(MinidumpMemoryProtectionContants::PageNoAccess);
+ info.SetReadable((entry->protect & PageNoAccess) == 0 ? yes : no);
+
+ const uint32_t PageWritable =
+ static_cast<uint32_t>(MinidumpMemoryProtectionContants::PageWritable);
+ info.SetWritable((entry->protect & PageWritable) != 0 ? yes : no);
+
+ const uint32_t PageExecutable = static_cast<uint32_t>(
+ MinidumpMemoryProtectionContants::PageExecutable);
+ info.SetExecutable((entry->protect & PageExecutable) != 0 ? yes : no);
+
+ const uint32_t MemFree =
+ static_cast<uint32_t>(MinidumpMemoryInfoState::MemFree);
+ info.SetMapped((entry->state != MemFree) ? yes : no);
+
+ return info;
+ } else if (head > load_addr &&
+ (next_entry == nullptr || head < next_entry->base_address)) {
+ // In case there is no region containing load_addr keep track of the
+ // nearest region after load_addr so we can return the distance to it.
+ next_entry = entry;
+ }
+ }
+
+ // No containing region found. Create an unmapped region that extends to the
+ // next region or LLDB_INVALID_ADDRESS
+ info.GetRange().SetRangeBase(load_addr);
+ info.GetRange().SetRangeEnd((next_entry != nullptr) ? next_entry->base_address
+ : LLDB_INVALID_ADDRESS);
+ info.SetReadable(no);
+ info.SetWritable(no);
+ info.SetExecutable(no);
+ info.SetMapped(no);
+
+ // Note that the memory info list doesn't seem to contain ranges in kernel
+ // space, so if you're walking a stack that has kernel frames, the stack may
+ // appear truncated.
+ return info;
+}
diff --git a/source/Plugins/Process/minidump/MinidumpParser.h b/source/Plugins/Process/minidump/MinidumpParser.h
new file mode 100644
index 000000000000..67523a72ad11
--- /dev/null
+++ b/source/Plugins/Process/minidump/MinidumpParser.h
@@ -0,0 +1,102 @@
+//===-- MinidumpParser.h -----------------------------------------*- C++
+//-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_MinidumpParser_h_
+#define liblldb_MinidumpParser_h_
+
+// Project includes
+#include "MinidumpTypes.h"
+
+// Other libraries and framework includes
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/DataBuffer.h"
+#include "lldb/Core/Error.h"
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+
+// C includes
+
+// C++ includes
+#include <cstring>
+#include <unordered_map>
+
+namespace lldb_private {
+
+namespace minidump {
+
+// Describes a range of memory captured in the Minidump
+struct Range {
+ lldb::addr_t start; // virtual address of the beginning of the range
+ // range_ref - absolute pointer to the first byte of the range and size
+ llvm::ArrayRef<uint8_t> range_ref;
+
+ Range(lldb::addr_t start, llvm::ArrayRef<uint8_t> range_ref)
+ : start(start), range_ref(range_ref) {}
+};
+
+class MinidumpParser {
+public:
+ static llvm::Optional<MinidumpParser>
+ Create(const lldb::DataBufferSP &data_buf_sp);
+
+ llvm::ArrayRef<uint8_t> GetData();
+
+ llvm::ArrayRef<uint8_t> GetStream(MinidumpStreamType stream_type);
+
+ llvm::Optional<std::string> GetMinidumpString(uint32_t rva);
+
+ llvm::ArrayRef<MinidumpThread> GetThreads();
+
+ llvm::ArrayRef<uint8_t> GetThreadContext(const MinidumpThread &td);
+
+ llvm::ArrayRef<uint8_t> GetThreadContextWow64(const MinidumpThread &td);
+
+ const MinidumpSystemInfo *GetSystemInfo();
+
+ ArchSpec GetArchitecture();
+
+ const MinidumpMiscInfo *GetMiscInfo();
+
+ llvm::Optional<LinuxProcStatus> GetLinuxProcStatus();
+
+ llvm::Optional<lldb::pid_t> GetPid();
+
+ llvm::ArrayRef<MinidumpModule> GetModuleList();
+
+ // There are cases in which there is more than one record in the ModuleList
+ // for the same module name.(e.g. when the binary has non contiguous segments)
+ // So this function returns a filtered module list - if it finds records that
+ // have the same name, it keeps the copy with the lowest load address.
+ std::vector<const MinidumpModule *> GetFilteredModuleList();
+
+ const MinidumpExceptionStream *GetExceptionStream();
+
+ llvm::Optional<Range> FindMemoryRange(lldb::addr_t addr);
+
+ llvm::ArrayRef<uint8_t> GetMemory(lldb::addr_t addr, size_t size);
+
+ llvm::Optional<MemoryRegionInfo> GetMemoryRegionInfo(lldb::addr_t);
+
+private:
+ lldb::DataBufferSP m_data_sp;
+ const MinidumpHeader *m_header;
+ llvm::DenseMap<uint32_t, MinidumpLocationDescriptor> m_directory_map;
+
+ MinidumpParser(
+ const lldb::DataBufferSP &data_buf_sp, const MinidumpHeader *header,
+ llvm::DenseMap<uint32_t, MinidumpLocationDescriptor> &&directory_map);
+};
+
+} // end namespace minidump
+} // end namespace lldb_private
+#endif // liblldb_MinidumpParser_h_
diff --git a/source/Plugins/Process/minidump/MinidumpTypes.cpp b/source/Plugins/Process/minidump/MinidumpTypes.cpp
new file mode 100644
index 000000000000..863d124a7ccc
--- /dev/null
+++ b/source/Plugins/Process/minidump/MinidumpTypes.cpp
@@ -0,0 +1,235 @@
+//===-- MinidumpTypes.cpp ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Project includes
+#include "MinidumpTypes.h"
+
+// Other libraries and framework includes
+// C includes
+// C++ includes
+
+using namespace lldb_private;
+using namespace minidump;
+
+const MinidumpHeader *MinidumpHeader::Parse(llvm::ArrayRef<uint8_t> &data) {
+ const MinidumpHeader *header = nullptr;
+ Error error = consumeObject(data, header);
+
+ const MinidumpHeaderConstants signature =
+ static_cast<const MinidumpHeaderConstants>(
+ static_cast<const uint32_t>(header->signature));
+ const MinidumpHeaderConstants version =
+ static_cast<const MinidumpHeaderConstants>(
+ static_cast<const uint32_t>(header->version) & 0x0000ffff);
+ // the high 16 bits of the version field are implementation specific
+
+ if (error.Fail() || signature != MinidumpHeaderConstants::Signature ||
+ version != MinidumpHeaderConstants::Version)
+ return nullptr;
+
+ // TODO check for max number of streams ?
+ // TODO more sanity checks ?
+
+ return header;
+}
+
+// Minidump string
+llvm::Optional<std::string>
+lldb_private::minidump::parseMinidumpString(llvm::ArrayRef<uint8_t> &data) {
+ std::string result;
+
+ const uint32_t *source_length;
+ Error error = consumeObject(data, source_length);
+ if (error.Fail() || *source_length > data.size() || *source_length % 2 != 0)
+ return llvm::None;
+
+ auto source_start = reinterpret_cast<const llvm::UTF16 *>(data.data());
+ // source_length is the length of the string in bytes
+ // we need the length of the string in UTF-16 characters/code points (16 bits
+ // per char)
+ // that's why it's divided by 2
+ const auto source_end = source_start + (*source_length) / 2;
+ // resize to worst case length
+ result.resize(UNI_MAX_UTF8_BYTES_PER_CODE_POINT * (*source_length) / 2);
+ auto result_start = reinterpret_cast<llvm::UTF8 *>(&result[0]);
+ const auto result_end = result_start + result.size();
+ llvm::ConvertUTF16toUTF8(&source_start, source_end, &result_start, result_end,
+ llvm::strictConversion);
+ const auto result_size =
+ std::distance(reinterpret_cast<llvm::UTF8 *>(&result[0]), result_start);
+ result.resize(result_size); // shrink to actual length
+
+ return result;
+}
+
+// MinidumpThread
+const MinidumpThread *MinidumpThread::Parse(llvm::ArrayRef<uint8_t> &data) {
+ const MinidumpThread *thread = nullptr;
+ Error error = consumeObject(data, thread);
+ if (error.Fail())
+ return nullptr;
+
+ return thread;
+}
+
+llvm::ArrayRef<MinidumpThread>
+MinidumpThread::ParseThreadList(llvm::ArrayRef<uint8_t> &data) {
+ const llvm::support::ulittle32_t *thread_count;
+ Error error = consumeObject(data, thread_count);
+ if (error.Fail() || *thread_count * sizeof(MinidumpThread) > data.size())
+ return {};
+
+ return llvm::ArrayRef<MinidumpThread>(
+ reinterpret_cast<const MinidumpThread *>(data.data()), *thread_count);
+}
+
+// MinidumpSystemInfo
+const MinidumpSystemInfo *
+MinidumpSystemInfo::Parse(llvm::ArrayRef<uint8_t> &data) {
+ const MinidumpSystemInfo *system_info;
+ Error error = consumeObject(data, system_info);
+ if (error.Fail())
+ return nullptr;
+
+ return system_info;
+}
+
+// MinidumpMiscInfo
+const MinidumpMiscInfo *MinidumpMiscInfo::Parse(llvm::ArrayRef<uint8_t> &data) {
+ const MinidumpMiscInfo *misc_info;
+ Error error = consumeObject(data, misc_info);
+ if (error.Fail())
+ return nullptr;
+
+ return misc_info;
+}
+
+llvm::Optional<lldb::pid_t> MinidumpMiscInfo::GetPid() const {
+ uint32_t pid_flag =
+ static_cast<const uint32_t>(MinidumpMiscInfoFlags::ProcessID);
+ if (flags1 & pid_flag)
+ return llvm::Optional<lldb::pid_t>(process_id);
+
+ return llvm::None;
+}
+
+// Linux Proc Status
+// it's stored as an ascii string in the file
+llvm::Optional<LinuxProcStatus>
+LinuxProcStatus::Parse(llvm::ArrayRef<uint8_t> &data) {
+ LinuxProcStatus result;
+ result.proc_status =
+ llvm::StringRef(reinterpret_cast<const char *>(data.data()), data.size());
+ data = data.drop_front(data.size());
+
+ llvm::SmallVector<llvm::StringRef, 0> lines;
+ result.proc_status.split(lines, '\n', 42);
+ // /proc/$pid/status has 41 lines, but why not use 42?
+ for (auto line : lines) {
+ if (line.consume_front("Pid:")) {
+ line = line.trim();
+ if (!line.getAsInteger(10, result.pid))
+ return result;
+ }
+ }
+
+ return llvm::None;
+}
+
+lldb::pid_t LinuxProcStatus::GetPid() const { return pid; }
+
+// Module stuff
+const MinidumpModule *MinidumpModule::Parse(llvm::ArrayRef<uint8_t> &data) {
+ const MinidumpModule *module = nullptr;
+ Error error = consumeObject(data, module);
+ if (error.Fail())
+ return nullptr;
+
+ return module;
+}
+
+llvm::ArrayRef<MinidumpModule>
+MinidumpModule::ParseModuleList(llvm::ArrayRef<uint8_t> &data) {
+
+ const llvm::support::ulittle32_t *modules_count;
+ Error error = consumeObject(data, modules_count);
+ if (error.Fail() || *modules_count * sizeof(MinidumpModule) > data.size())
+ return {};
+
+ return llvm::ArrayRef<MinidumpModule>(
+ reinterpret_cast<const MinidumpModule *>(data.data()), *modules_count);
+}
+
+// Exception stuff
+const MinidumpExceptionStream *
+MinidumpExceptionStream::Parse(llvm::ArrayRef<uint8_t> &data) {
+ const MinidumpExceptionStream *exception_stream = nullptr;
+ Error error = consumeObject(data, exception_stream);
+ if (error.Fail())
+ return nullptr;
+
+ return exception_stream;
+}
+
+llvm::ArrayRef<MinidumpMemoryDescriptor>
+MinidumpMemoryDescriptor::ParseMemoryList(llvm::ArrayRef<uint8_t> &data) {
+ const llvm::support::ulittle32_t *mem_ranges_count;
+ Error error = consumeObject(data, mem_ranges_count);
+ if (error.Fail() ||
+ *mem_ranges_count * sizeof(MinidumpMemoryDescriptor) > data.size())
+ return {};
+
+ return llvm::makeArrayRef(
+ reinterpret_cast<const MinidumpMemoryDescriptor *>(data.data()),
+ *mem_ranges_count);
+}
+
+std::pair<llvm::ArrayRef<MinidumpMemoryDescriptor64>, uint64_t>
+MinidumpMemoryDescriptor64::ParseMemory64List(llvm::ArrayRef<uint8_t> &data) {
+ const llvm::support::ulittle64_t *mem_ranges_count;
+ Error error = consumeObject(data, mem_ranges_count);
+ if (error.Fail() ||
+ *mem_ranges_count * sizeof(MinidumpMemoryDescriptor64) > data.size())
+ return {};
+
+ const llvm::support::ulittle64_t *base_rva;
+ error = consumeObject(data, base_rva);
+ if (error.Fail())
+ return {};
+
+ return std::make_pair(
+ llvm::makeArrayRef(
+ reinterpret_cast<const MinidumpMemoryDescriptor64 *>(data.data()),
+ *mem_ranges_count),
+ *base_rva);
+}
+
+std::vector<const MinidumpMemoryInfo *>
+MinidumpMemoryInfo::ParseMemoryInfoList(llvm::ArrayRef<uint8_t> &data) {
+ const MinidumpMemoryInfoListHeader *header;
+ Error error = consumeObject(data, header);
+ if (error.Fail() ||
+ header->size_of_header < sizeof(MinidumpMemoryInfoListHeader) ||
+ header->size_of_entry < sizeof(MinidumpMemoryInfo))
+ return {};
+
+ data = data.drop_front(header->size_of_header -
+ sizeof(MinidumpMemoryInfoListHeader));
+
+ if (header->size_of_entry * header->num_of_entries > data.size())
+ return {};
+
+ std::vector<const MinidumpMemoryInfo *> result;
+ for (uint64_t i = 0; i < header->num_of_entries; ++i) {
+ result.push_back(reinterpret_cast<const MinidumpMemoryInfo *>(
+ data.data() + i * header->size_of_entry));
+ }
+
+ return result;
+}
diff --git a/source/Plugins/Process/minidump/MinidumpTypes.h b/source/Plugins/Process/minidump/MinidumpTypes.h
new file mode 100644
index 000000000000..46871a1b84d8
--- /dev/null
+++ b/source/Plugins/Process/minidump/MinidumpTypes.h
@@ -0,0 +1,470 @@
+//===-- MinidumpTypes.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_MinidumpTypes_h_
+#define liblldb_MinidumpTypes_h_
+
+// Project includes
+
+// Other libraries and framework includes
+#include "lldb/Core/Error.h"
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/BitmaskEnum.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/Endian.h"
+
+// C includes
+// C++ includes
+
+// Reference:
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms679293(v=vs.85).aspx
+// https://chromium.googlesource.com/breakpad/breakpad/
+
+namespace lldb_private {
+
+namespace minidump {
+
+LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
+
+enum class MinidumpHeaderConstants : uint32_t {
+ Signature = 0x504d444d, // 'PMDM'
+ Version = 0x0000a793, // 42899
+ LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ Signature)
+
+};
+
+// Reference:
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680394.aspx
+enum class MinidumpStreamType : uint32_t {
+ Unused = 0,
+ Reserved0 = 1,
+ Reserved1 = 2,
+ ThreadList = 3,
+ ModuleList = 4,
+ MemoryList = 5,
+ Exception = 6,
+ SystemInfo = 7,
+ ThreadExList = 8,
+ Memory64List = 9,
+ CommentA = 10,
+ CommentW = 11,
+ HandleData = 12,
+ FunctionTable = 13,
+ UnloadedModuleList = 14,
+ MiscInfo = 15,
+ MemoryInfoList = 16,
+ ThreadInfoList = 17,
+ HandleOperationList = 18,
+ Token = 19,
+ JavascriptData = 20,
+ SystemMemoryInfo = 21,
+ ProcessVMCounters = 22,
+ LastReserved = 0x0000ffff,
+
+ /* Breakpad extension types. 0x4767 = "Gg" */
+ BreakpadInfo = 0x47670001,
+ AssertionInfo = 0x47670002,
+ /* These are additional minidump stream values which are specific to
+ * the linux breakpad implementation. */
+ LinuxCPUInfo = 0x47670003, /* /proc/cpuinfo */
+ LinuxProcStatus = 0x47670004, /* /proc/$x/status */
+ LinuxLSBRelease = 0x47670005, /* /etc/lsb-release */
+ LinuxCMDLine = 0x47670006, /* /proc/$x/cmdline */
+ LinuxEnviron = 0x47670007, /* /proc/$x/environ */
+ LinuxAuxv = 0x47670008, /* /proc/$x/auxv */
+ LinuxMaps = 0x47670009, /* /proc/$x/maps */
+ LinuxDSODebug = 0x4767000A
+};
+
+// for MinidumpSystemInfo.processor_arch
+enum class MinidumpCPUArchitecture : uint16_t {
+ X86 = 0, /* PROCESSOR_ARCHITECTURE_INTEL */
+ MIPS = 1, /* PROCESSOR_ARCHITECTURE_MIPS */
+ Alpha = 2, /* PROCESSOR_ARCHITECTURE_ALPHA */
+ PPC = 3, /* PROCESSOR_ARCHITECTURE_PPC */
+ SHX = 4, /* PROCESSOR_ARCHITECTURE_SHX (Super-H) */
+ ARM = 5, /* PROCESSOR_ARCHITECTURE_ARM */
+ IA64 = 6, /* PROCESSOR_ARCHITECTURE_IA64 */
+ Alpha64 = 7, /* PROCESSOR_ARCHITECTURE_ALPHA64 */
+ MSIL = 8, /* PROCESSOR_ARCHITECTURE_MSIL
+ * (Microsoft Intermediate Language) */
+ AMD64 = 9, /* PROCESSOR_ARCHITECTURE_AMD64 */
+ X86Win64 = 10, /* PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 (WoW64) */
+ SPARC = 0x8001, /* Breakpad-defined value for SPARC */
+ PPC64 = 0x8002, /* Breakpad-defined value for PPC64 */
+ ARM64 = 0x8003, /* Breakpad-defined value for ARM64 */
+ MIPS64 = 0x8004, /* Breakpad-defined value for MIPS64 */
+ Unknown = 0xffff /* PROCESSOR_ARCHITECTURE_UNKNOWN */
+};
+
+// for MinidumpSystemInfo.platform_id
+enum class MinidumpOSPlatform : uint32_t {
+ Win32S = 0, /* VER_PLATFORM_WIN32s (Windows 3.1) */
+ Win32Windows = 1, /* VER_PLATFORM_WIN32_WINDOWS (Windows 95-98-Me) */
+ Win32NT = 2, /* VER_PLATFORM_WIN32_NT (Windows NT, 2000+) */
+ Win32CE = 3, /* VER_PLATFORM_WIN32_CE, VER_PLATFORM_WIN32_HH
+ * (Windows CE, Windows Mobile, "Handheld") */
+
+ /* The following values are Breakpad-defined. */
+ Unix = 0x8000, /* Generic Unix-ish */
+ MacOSX = 0x8101, /* Mac OS X/Darwin */
+ IOS = 0x8102, /* iOS */
+ Linux = 0x8201, /* Linux */
+ Solaris = 0x8202, /* Solaris */
+ Android = 0x8203, /* Android */
+ PS3 = 0x8204, /* PS3 */
+ NaCl = 0x8205 /* Native Client (NaCl) */
+};
+
+// For MinidumpCPUInfo.arm_cpu_info.elf_hwcaps.
+// This matches the Linux kernel definitions from <asm/hwcaps.h>
+enum class MinidumpPCPUInformationARMElfHwCaps : uint32_t {
+ SWP = (1 << 0),
+ Half = (1 << 1),
+ Thumb = (1 << 2),
+ _26BIT = (1 << 3),
+ FastMult = (1 << 4),
+ FPA = (1 << 5),
+ VFP = (1 << 6),
+ EDSP = (1 << 7),
+ Java = (1 << 8),
+ IWMMXT = (1 << 9),
+ Crunch = (1 << 10),
+ ThumbEE = (1 << 11),
+ Neon = (1 << 12),
+ VFPv3 = (1 << 13),
+ VFPv3D16 = (1 << 14),
+ TLS = (1 << 15),
+ VFPv4 = (1 << 16),
+ IDIVA = (1 << 17),
+ IDIVT = (1 << 18),
+ LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ IDIVT)
+};
+
+enum class MinidumpMiscInfoFlags : uint32_t {
+ ProcessID = (1 << 0),
+ ProcessTimes = (1 << 1),
+ LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ ProcessTimes)
+};
+
+template <typename T>
+Error consumeObject(llvm::ArrayRef<uint8_t> &Buffer, const T *&Object) {
+ Error error;
+ if (Buffer.size() < sizeof(T)) {
+ error.SetErrorString("Insufficient buffer!");
+ return error;
+ }
+
+ Object = reinterpret_cast<const T *>(Buffer.data());
+ Buffer = Buffer.drop_front(sizeof(T));
+ return error;
+}
+
+// parse a MinidumpString which is with UTF-16
+// Reference:
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680395(v=vs.85).aspx
+llvm::Optional<std::string> parseMinidumpString(llvm::ArrayRef<uint8_t> &data);
+
+// Reference:
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680378(v=vs.85).aspx
+struct MinidumpHeader {
+ llvm::support::ulittle32_t signature;
+ llvm::support::ulittle32_t
+ version; // The high 16 bits of version field are implementation specific
+ llvm::support::ulittle32_t streams_count;
+ llvm::support::ulittle32_t
+ stream_directory_rva; // offset of the stream directory
+ llvm::support::ulittle32_t checksum;
+ llvm::support::ulittle32_t time_date_stamp; // time_t format
+ llvm::support::ulittle64_t flags;
+
+ static const MinidumpHeader *Parse(llvm::ArrayRef<uint8_t> &data);
+};
+static_assert(sizeof(MinidumpHeader) == 32,
+ "sizeof MinidumpHeader is not correct!");
+
+// Reference:
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680383.aspx
+struct MinidumpLocationDescriptor {
+ llvm::support::ulittle32_t data_size;
+ llvm::support::ulittle32_t rva;
+};
+static_assert(sizeof(MinidumpLocationDescriptor) == 8,
+ "sizeof MinidumpLocationDescriptor is not correct!");
+
+// Reference:
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680384(v=vs.85).aspx
+struct MinidumpMemoryDescriptor {
+ llvm::support::ulittle64_t start_of_memory_range;
+ MinidumpLocationDescriptor memory;
+
+ static llvm::ArrayRef<MinidumpMemoryDescriptor>
+ ParseMemoryList(llvm::ArrayRef<uint8_t> &data);
+};
+static_assert(sizeof(MinidumpMemoryDescriptor) == 16,
+ "sizeof MinidumpMemoryDescriptor is not correct!");
+
+struct MinidumpMemoryDescriptor64 {
+ llvm::support::ulittle64_t start_of_memory_range;
+ llvm::support::ulittle64_t data_size;
+
+ static std::pair<llvm::ArrayRef<MinidumpMemoryDescriptor64>, uint64_t>
+ ParseMemory64List(llvm::ArrayRef<uint8_t> &data);
+};
+static_assert(sizeof(MinidumpMemoryDescriptor64) == 16,
+ "sizeof MinidumpMemoryDescriptor64 is not correct!");
+
+// Reference:
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680365.aspx
+struct MinidumpDirectory {
+ llvm::support::ulittle32_t stream_type;
+ MinidumpLocationDescriptor location;
+};
+static_assert(sizeof(MinidumpDirectory) == 12,
+ "sizeof MinidumpDirectory is not correct!");
+
+// Reference:
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680385(v=vs.85).aspx
+struct MinidumpMemoryInfoListHeader {
+ llvm::support::ulittle32_t size_of_header;
+ llvm::support::ulittle32_t size_of_entry;
+ llvm::support::ulittle64_t num_of_entries;
+};
+static_assert(sizeof(MinidumpMemoryInfoListHeader) == 16,
+ "sizeof MinidumpMemoryInfoListHeader is not correct!");
+
+// Reference:
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680386(v=vs.85).aspx
+struct MinidumpMemoryInfo {
+ llvm::support::ulittle64_t base_address;
+ llvm::support::ulittle64_t allocation_base;
+ llvm::support::ulittle32_t allocation_protect;
+ llvm::support::ulittle32_t alignment1;
+ llvm::support::ulittle64_t region_size;
+ llvm::support::ulittle32_t state;
+ llvm::support::ulittle32_t protect;
+ llvm::support::ulittle32_t type;
+ llvm::support::ulittle32_t alignment2;
+
+ static std::vector<const MinidumpMemoryInfo *>
+ ParseMemoryInfoList(llvm::ArrayRef<uint8_t> &data);
+};
+static_assert(sizeof(MinidumpMemoryInfo) == 48,
+ "sizeof MinidumpMemoryInfo is not correct!");
+
+enum class MinidumpMemoryInfoState : uint32_t {
+ MemCommit = 0x1000,
+ MemFree = 0x10000,
+ MemReserve = 0x2000,
+ LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ MemFree)
+};
+
+enum class MinidumpMemoryInfoType : uint32_t {
+ MemImage = 0x1000000,
+ MemMapped = 0x40000,
+ MemPrivate = 0x20000,
+ LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ MemImage)
+};
+
+// Reference:
+// https://msdn.microsoft.com/en-us/library/windows/desktop/aa366786(v=vs.85).aspx
+enum class MinidumpMemoryProtectionContants : uint32_t {
+ PageExecute = 0x10,
+ PageExecuteRead = 0x20,
+ PageExecuteReadWrite = 0x40,
+ PageExecuteWriteCopy = 0x80,
+ PageNoAccess = 0x01,
+ PageReadOnly = 0x02,
+ PageReadWrite = 0x04,
+ PageWriteCopy = 0x08,
+ PageTargetsInvalid = 0x40000000,
+ PageTargetsNoUpdate = 0x40000000,
+
+ PageWritable = PageExecuteReadWrite | PageExecuteWriteCopy | PageReadWrite |
+ PageWriteCopy,
+ PageExecutable = PageExecute | PageExecuteRead | PageExecuteReadWrite |
+ PageExecuteWriteCopy,
+ LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ PageTargetsInvalid)
+};
+
+// Reference:
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680517(v=vs.85).aspx
+struct MinidumpThread {
+ llvm::support::ulittle32_t thread_id;
+ llvm::support::ulittle32_t suspend_count;
+ llvm::support::ulittle32_t priority_class;
+ llvm::support::ulittle32_t priority;
+ llvm::support::ulittle64_t teb;
+ MinidumpMemoryDescriptor stack;
+ MinidumpLocationDescriptor thread_context;
+
+ static const MinidumpThread *Parse(llvm::ArrayRef<uint8_t> &data);
+
+ static llvm::ArrayRef<MinidumpThread>
+ ParseThreadList(llvm::ArrayRef<uint8_t> &data);
+};
+static_assert(sizeof(MinidumpThread) == 48,
+ "sizeof MinidumpThread is not correct!");
+
+// Reference:
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680396(v=vs.85).aspx
+union MinidumpCPUInfo {
+ struct {
+ llvm::support::ulittle32_t vendor_id[3]; /* cpuid 0: ebx, edx, ecx */
+ llvm::support::ulittle32_t version_information; /* cpuid 1: eax */
+ llvm::support::ulittle32_t feature_information; /* cpuid 1: edx */
+ llvm::support::ulittle32_t
+ amd_extended_cpu_features; /* cpuid 0x80000001, ebx */
+ } x86_cpu_info;
+ struct {
+ llvm::support::ulittle32_t cpuid;
+ llvm::support::ulittle32_t elf_hwcaps; /* linux specific, 0 otherwise */
+ } arm_cpu_info;
+ struct {
+ llvm::support::ulittle64_t processor_features[2];
+ } other_cpu_info;
+};
+static_assert(sizeof(MinidumpCPUInfo) == 24,
+ "sizeof MinidumpCPUInfo is not correct!");
+
+// Reference:
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680396(v=vs.85).aspx
+struct MinidumpSystemInfo {
+ llvm::support::ulittle16_t processor_arch;
+ llvm::support::ulittle16_t processor_level;
+ llvm::support::ulittle16_t processor_revision;
+
+ uint8_t number_of_processors;
+ uint8_t product_type;
+
+ llvm::support::ulittle32_t major_version;
+ llvm::support::ulittle32_t minor_version;
+ llvm::support::ulittle32_t build_number;
+ llvm::support::ulittle32_t platform_id;
+ llvm::support::ulittle32_t csd_version_rva;
+
+ llvm::support::ulittle16_t suit_mask;
+ llvm::support::ulittle16_t reserved2;
+
+ MinidumpCPUInfo cpu;
+
+ static const MinidumpSystemInfo *Parse(llvm::ArrayRef<uint8_t> &data);
+};
+static_assert(sizeof(MinidumpSystemInfo) == 56,
+ "sizeof MinidumpSystemInfo is not correct!");
+
+// TODO misc2, misc3 ?
+// Reference:
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680389(v=vs.85).aspx
+struct MinidumpMiscInfo {
+ llvm::support::ulittle32_t size;
+ // flags1 represents what info in the struct is valid
+ llvm::support::ulittle32_t flags1;
+ llvm::support::ulittle32_t process_id;
+ llvm::support::ulittle32_t process_create_time;
+ llvm::support::ulittle32_t process_user_time;
+ llvm::support::ulittle32_t process_kernel_time;
+
+ static const MinidumpMiscInfo *Parse(llvm::ArrayRef<uint8_t> &data);
+
+ llvm::Optional<lldb::pid_t> GetPid() const;
+};
+static_assert(sizeof(MinidumpMiscInfo) == 24,
+ "sizeof MinidumpMiscInfo is not correct!");
+
+// The /proc/pid/status is saved as an ascii string in the file
+class LinuxProcStatus {
+public:
+ llvm::StringRef proc_status;
+ lldb::pid_t pid;
+
+ static llvm::Optional<LinuxProcStatus> Parse(llvm::ArrayRef<uint8_t> &data);
+
+ lldb::pid_t GetPid() const;
+
+private:
+ LinuxProcStatus() = default;
+};
+
+// MinidumpModule stuff
+struct MinidumpVSFixedFileInfo {
+ llvm::support::ulittle32_t signature;
+ llvm::support::ulittle32_t struct_version;
+ llvm::support::ulittle32_t file_version_hi;
+ llvm::support::ulittle32_t file_version_lo;
+ llvm::support::ulittle32_t product_version_hi;
+ llvm::support::ulittle32_t product_version_lo;
+ // file_flags_mask - identifies valid bits in fileFlags
+ llvm::support::ulittle32_t file_flags_mask;
+ llvm::support::ulittle32_t file_flags;
+ llvm::support::ulittle32_t file_os;
+ llvm::support::ulittle32_t file_type;
+ llvm::support::ulittle32_t file_subtype;
+ llvm::support::ulittle32_t file_date_hi;
+ llvm::support::ulittle32_t file_date_lo;
+};
+static_assert(sizeof(MinidumpVSFixedFileInfo) == 52,
+ "sizeof MinidumpVSFixedFileInfo is not correct!");
+
+struct MinidumpModule {
+ llvm::support::ulittle64_t base_of_image;
+ llvm::support::ulittle32_t size_of_image;
+ llvm::support::ulittle32_t checksum;
+ llvm::support::ulittle32_t time_date_stamp;
+ llvm::support::ulittle32_t module_name_rva;
+ MinidumpVSFixedFileInfo version_info;
+ MinidumpLocationDescriptor CV_record;
+ MinidumpLocationDescriptor misc_record;
+ llvm::support::ulittle32_t reserved0[2];
+ llvm::support::ulittle32_t reserved1[2];
+
+ static const MinidumpModule *Parse(llvm::ArrayRef<uint8_t> &data);
+
+ static llvm::ArrayRef<MinidumpModule>
+ ParseModuleList(llvm::ArrayRef<uint8_t> &data);
+};
+static_assert(sizeof(MinidumpModule) == 108,
+ "sizeof MinidumpVSFixedFileInfo is not correct!");
+
+// Exception stuff
+struct MinidumpException {
+ enum : unsigned {
+ ExceptonInfoMaxParams = 15,
+ DumpRequested = 0xFFFFFFFF,
+ };
+
+ llvm::support::ulittle32_t exception_code;
+ llvm::support::ulittle32_t exception_flags;
+ llvm::support::ulittle64_t exception_record;
+ llvm::support::ulittle64_t exception_address;
+ llvm::support::ulittle32_t number_parameters;
+ llvm::support::ulittle32_t unused_alignment;
+ llvm::support::ulittle64_t exception_information[ExceptonInfoMaxParams];
+};
+static_assert(sizeof(MinidumpException) == 152,
+ "sizeof MinidumpException is not correct!");
+
+struct MinidumpExceptionStream {
+ llvm::support::ulittle32_t thread_id;
+ llvm::support::ulittle32_t alignment;
+ MinidumpException exception_record;
+ MinidumpLocationDescriptor thread_context;
+
+ static const MinidumpExceptionStream *Parse(llvm::ArrayRef<uint8_t> &data);
+};
+static_assert(sizeof(MinidumpExceptionStream) == 168,
+ "sizeof MinidumpExceptionStream is not correct!");
+
+} // namespace minidump
+} // namespace lldb_private
+#endif // liblldb_MinidumpTypes_h_
diff --git a/source/Plugins/Process/minidump/NtStructures.h b/source/Plugins/Process/minidump/NtStructures.h
new file mode 100644
index 000000000000..c0afd77358cd
--- /dev/null
+++ b/source/Plugins/Process/minidump/NtStructures.h
@@ -0,0 +1,37 @@
+//===-- NtStructures.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Plugins_Process_Minidump_NtStructures_h_
+#define liblldb_Plugins_Process_Minidump_NtStructures_h_
+
+#include "llvm/Support/Endian.h"
+
+namespace lldb_private {
+
+namespace minidump {
+
+// This describes the layout of a TEB (Thread Environment Block) for a 64-bit
+// process. It's adapted from the 32-bit TEB in winternl.h. Currently, we care
+// only about the position of the tls_slots.
+struct TEB64 {
+ llvm::support::ulittle64_t reserved1[12];
+ llvm::support::ulittle64_t process_environment_block;
+ llvm::support::ulittle64_t reserved2[399];
+ uint8_t reserved3[1952];
+ llvm::support::ulittle64_t tls_slots[64];
+ uint8_t reserved4[8];
+ llvm::support::ulittle64_t reserved5[26];
+ llvm::support::ulittle64_t reserved_for_ole; // Windows 2000 only
+ llvm::support::ulittle64_t reserved6[4];
+ llvm::support::ulittle64_t tls_expansion_slots;
+};
+
+#endif // liblldb_Plugins_Process_Minidump_NtStructures_h_
+} // namespace minidump
+} // namespace lldb_private
diff --git a/source/Plugins/Process/minidump/ProcessMinidump.cpp b/source/Plugins/Process/minidump/ProcessMinidump.cpp
new file mode 100644
index 000000000000..46d8df8b16f1
--- /dev/null
+++ b/source/Plugins/Process/minidump/ProcessMinidump.cpp
@@ -0,0 +1,301 @@
+//===-- ProcessMinidump.cpp -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Project includes
+#include "ProcessMinidump.h"
+#include "ThreadMinidump.h"
+
+// Other libraries and framework includes
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Core/State.h"
+#include "lldb/Target/DynamicLoader.h"
+#include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/UnixSignals.h"
+#include "lldb/Utility/LLDBAssert.h"
+
+// C includes
+// C++ includes
+
+using namespace lldb_private;
+using namespace minidump;
+
+ConstString ProcessMinidump::GetPluginNameStatic() {
+ static ConstString g_name("minidump");
+ return g_name;
+}
+
+const char *ProcessMinidump::GetPluginDescriptionStatic() {
+ return "Minidump plug-in.";
+}
+
+lldb::ProcessSP ProcessMinidump::CreateInstance(lldb::TargetSP target_sp,
+ lldb::ListenerSP listener_sp,
+ const FileSpec *crash_file) {
+ if (!crash_file)
+ return nullptr;
+
+ lldb::ProcessSP process_sp;
+ // Read enough data for the Minidump header
+ const size_t header_size = sizeof(MinidumpHeader);
+ lldb::DataBufferSP data_sp(crash_file->MemoryMapFileContents(0, header_size));
+ if (!data_sp)
+ return nullptr;
+
+ // first, only try to parse the header, beacuse we need to be fast
+ llvm::ArrayRef<uint8_t> header_data(data_sp->GetBytes(), header_size);
+ const MinidumpHeader *header = MinidumpHeader::Parse(header_data);
+
+ if (data_sp->GetByteSize() != header_size || header == nullptr)
+ return nullptr;
+
+ lldb::DataBufferSP all_data_sp(crash_file->MemoryMapFileContents());
+ auto minidump_parser = MinidumpParser::Create(all_data_sp);
+ // check if the parser object is valid
+ if (!minidump_parser)
+ return nullptr;
+
+ return std::make_shared<ProcessMinidump>(target_sp, listener_sp, *crash_file,
+ minidump_parser.getValue());
+}
+
+bool ProcessMinidump::CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) {
+ return true;
+}
+
+ProcessMinidump::ProcessMinidump(lldb::TargetSP target_sp,
+ lldb::ListenerSP listener_sp,
+ const FileSpec &core_file,
+ MinidumpParser minidump_parser)
+ : Process(target_sp, listener_sp), m_minidump_parser(minidump_parser),
+ m_core_file(core_file), m_is_wow64(false) {}
+
+ProcessMinidump::~ProcessMinidump() {
+ Clear();
+ // We need to call finalize on the process before destroying ourselves
+ // to make sure all of the broadcaster cleanup goes as planned. If we
+ // destruct this class, then Process::~Process() might have problems
+ // trying to fully destroy the broadcaster.
+ Finalize();
+}
+
+void ProcessMinidump::Initialize() {
+ static std::once_flag g_once_flag;
+
+ std::call_once(g_once_flag, []() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(),
+ ProcessMinidump::CreateInstance);
+ });
+}
+
+void ProcessMinidump::Terminate() {
+ PluginManager::UnregisterPlugin(ProcessMinidump::CreateInstance);
+}
+
+Error ProcessMinidump::DoLoadCore() {
+ Error error;
+
+ m_thread_list = m_minidump_parser.GetThreads();
+ m_active_exception = m_minidump_parser.GetExceptionStream();
+ ReadModuleList();
+ GetTarget().SetArchitecture(GetArchitecture());
+
+ llvm::Optional<lldb::pid_t> pid = m_minidump_parser.GetPid();
+ if (!pid) {
+ error.SetErrorString("failed to parse PID");
+ return error;
+ }
+ SetID(pid.getValue());
+
+ return error;
+}
+
+DynamicLoader *ProcessMinidump::GetDynamicLoader() {
+ if (m_dyld_ap.get() == nullptr)
+ m_dyld_ap.reset(DynamicLoader::FindPlugin(this, nullptr));
+ return m_dyld_ap.get();
+}
+
+ConstString ProcessMinidump::GetPluginName() { return GetPluginNameStatic(); }
+
+uint32_t ProcessMinidump::GetPluginVersion() { return 1; }
+
+Error ProcessMinidump::DoDestroy() { return Error(); }
+
+void ProcessMinidump::RefreshStateAfterStop() {
+ if (!m_active_exception)
+ return;
+
+ if (m_active_exception->exception_record.exception_code ==
+ MinidumpException::DumpRequested) {
+ return;
+ }
+
+ lldb::StopInfoSP stop_info;
+ lldb::ThreadSP stop_thread;
+
+ Process::m_thread_list.SetSelectedThreadByID(m_active_exception->thread_id);
+ stop_thread = Process::m_thread_list.GetSelectedThread();
+ ArchSpec arch = GetArchitecture();
+
+ if (arch.GetTriple().getOS() == llvm::Triple::Linux) {
+ stop_info = StopInfo::CreateStopReasonWithSignal(
+ *stop_thread, m_active_exception->exception_record.exception_code);
+ } else {
+ std::string desc;
+ llvm::raw_string_ostream desc_stream(desc);
+ desc_stream << "Exception "
+ << llvm::format_hex(
+ m_active_exception->exception_record.exception_code, 8)
+ << " encountered at address "
+ << llvm::format_hex(
+ m_active_exception->exception_record.exception_address,
+ 8);
+ stop_info = StopInfo::CreateStopReasonWithException(
+ *stop_thread, desc_stream.str().c_str());
+ }
+
+ stop_thread->SetStopInfo(stop_info);
+}
+
+bool ProcessMinidump::IsAlive() { return true; }
+
+bool ProcessMinidump::WarnBeforeDetach() const { return false; }
+
+size_t ProcessMinidump::ReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ Error &error) {
+ // Don't allow the caching that lldb_private::Process::ReadMemory does
+ // since we have it all cached in our dump file anyway.
+ return DoReadMemory(addr, buf, size, error);
+}
+
+size_t ProcessMinidump::DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ Error &error) {
+
+ llvm::ArrayRef<uint8_t> mem = m_minidump_parser.GetMemory(addr, size);
+ if (mem.empty()) {
+ error.SetErrorString("could not parse memory info");
+ return 0;
+ }
+
+ std::memcpy(buf, mem.data(), mem.size());
+ return mem.size();
+}
+
+ArchSpec ProcessMinidump::GetArchitecture() {
+ if (!m_is_wow64) {
+ return m_minidump_parser.GetArchitecture();
+ }
+
+ llvm::Triple triple;
+ triple.setVendor(llvm::Triple::VendorType::UnknownVendor);
+ triple.setArch(llvm::Triple::ArchType::x86);
+ triple.setOS(llvm::Triple::OSType::Win32);
+ return ArchSpec(triple);
+}
+
+Error ProcessMinidump::GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &range_info) {
+ Error error;
+ auto info = m_minidump_parser.GetMemoryRegionInfo(load_addr);
+ if (!info) {
+ error.SetErrorString("No valid MemoryRegionInfo found!");
+ return error;
+ }
+ range_info = info.getValue();
+ return error;
+}
+
+void ProcessMinidump::Clear() { Process::m_thread_list.Clear(); }
+
+bool ProcessMinidump::UpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) {
+ uint32_t num_threads = 0;
+ if (m_thread_list.size() > 0)
+ num_threads = m_thread_list.size();
+
+ for (lldb::tid_t tid = 0; tid < num_threads; ++tid) {
+ llvm::ArrayRef<uint8_t> context;
+ if (!m_is_wow64)
+ context = m_minidump_parser.GetThreadContext(m_thread_list[tid]);
+ else
+ context = m_minidump_parser.GetThreadContextWow64(m_thread_list[tid]);
+
+ lldb::ThreadSP thread_sp(
+ new ThreadMinidump(*this, m_thread_list[tid], context));
+ new_thread_list.AddThread(thread_sp);
+ }
+ return new_thread_list.GetSize(false) > 0;
+}
+
+void ProcessMinidump::ReadModuleList() {
+ std::vector<const MinidumpModule *> filtered_modules =
+ m_minidump_parser.GetFilteredModuleList();
+
+ for (auto module : filtered_modules) {
+ llvm::Optional<std::string> name =
+ m_minidump_parser.GetMinidumpString(module->module_name_rva);
+
+ if (!name)
+ continue;
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES));
+ if (log) {
+ log->Printf("ProcessMinidump::%s found module: name: %s %#010" PRIx64
+ "-%#010" PRIx64 " size: %" PRIu32,
+ __FUNCTION__, name.getValue().c_str(),
+ uint64_t(module->base_of_image),
+ module->base_of_image + module->size_of_image,
+ uint32_t(module->size_of_image));
+ }
+
+ // check if the process is wow64 - a 32 bit windows process running on a
+ // 64 bit windows
+ if (llvm::StringRef(name.getValue()).endswith_lower("wow64.dll")) {
+ m_is_wow64 = true;
+ }
+
+ const auto file_spec = FileSpec(name.getValue(), true);
+ ModuleSpec module_spec = file_spec;
+ Error error;
+ lldb::ModuleSP module_sp = GetTarget().GetSharedModule(module_spec, &error);
+ if (!module_sp || error.Fail()) {
+ continue;
+ }
+
+ if (log) {
+ log->Printf("ProcessMinidump::%s load module: name: %s", __FUNCTION__,
+ name.getValue().c_str());
+ }
+
+ bool load_addr_changed = false;
+ module_sp->SetLoadAddress(GetTarget(), module->base_of_image, false,
+ load_addr_changed);
+ }
+}
+
+bool ProcessMinidump::GetProcessInfo(ProcessInstanceInfo &info) {
+ info.Clear();
+ info.SetProcessID(GetID());
+ info.SetArchitecture(GetArchitecture());
+ lldb::ModuleSP module_sp = GetTarget().GetExecutableModule();
+ if (module_sp) {
+ const bool add_exe_file_as_first_arg = false;
+ info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(),
+ add_exe_file_as_first_arg);
+ }
+ return true;
+}
diff --git a/source/Plugins/Process/minidump/ProcessMinidump.h b/source/Plugins/Process/minidump/ProcessMinidump.h
new file mode 100644
index 000000000000..78eadc809a4d
--- /dev/null
+++ b/source/Plugins/Process/minidump/ProcessMinidump.h
@@ -0,0 +1,105 @@
+//===-- ProcessMinidump.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ProcessMinidump_h_
+#define liblldb_ProcessMinidump_h_
+
+// Project includes
+#include "MinidumpParser.h"
+#include "MinidumpTypes.h"
+
+// Other libraries and framework includes
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/StopInfo.h"
+#include "lldb/Target/Target.h"
+
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+
+// C Includes
+// C++ Includes
+
+namespace lldb_private {
+
+namespace minidump {
+
+class ProcessMinidump : public Process {
+public:
+ static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp,
+ lldb::ListenerSP listener_sp,
+ const FileSpec *crash_file_path);
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static ConstString GetPluginNameStatic();
+
+ static const char *GetPluginDescriptionStatic();
+
+ ProcessMinidump(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
+ const FileSpec &core_file, MinidumpParser minidump_parser);
+
+ ~ProcessMinidump() override;
+
+ bool CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) override;
+
+ Error DoLoadCore() override;
+
+ DynamicLoader *GetDynamicLoader() override;
+
+ ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
+
+ Error DoDestroy() override;
+
+ void RefreshStateAfterStop() override;
+
+ bool IsAlive() override;
+
+ bool WarnBeforeDetach() const override;
+
+ size_t ReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ Error &error) override;
+
+ size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ Error &error) override;
+
+ ArchSpec GetArchitecture();
+
+ Error GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &range_info) override;
+
+ bool GetProcessInfo(ProcessInstanceInfo &info) override;
+
+ MinidumpParser m_minidump_parser;
+
+protected:
+ void Clear();
+
+ bool UpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) override;
+
+ void ReadModuleList();
+
+private:
+ FileSpec m_core_file;
+ llvm::ArrayRef<MinidumpThread> m_thread_list;
+ const MinidumpExceptionStream *m_active_exception;
+ bool m_is_wow64;
+};
+
+} // namespace minidump
+} // namespace lldb_private
+
+#endif // liblldb_ProcessMinidump_h_
diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp b/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp
new file mode 100644
index 000000000000..7f3768216f3a
--- /dev/null
+++ b/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp
@@ -0,0 +1,99 @@
+//===-- RegisterContextMinidump_x86_32.cpp ----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Project includes
+#include "RegisterContextMinidump_x86_32.h"
+
+// Other libraries and framework includes
+#include "lldb/Core/DataBufferHeap.h"
+
+// C includes
+// C++ includes
+
+using namespace lldb_private;
+using namespace minidump;
+
+static void writeRegister(const void *reg_src,
+ llvm::MutableArrayRef<uint8_t> reg_dest) {
+ memcpy(reg_dest.data(), reg_src, reg_dest.size());
+}
+
+lldb::DataBufferSP lldb_private::minidump::ConvertMinidumpContext_x86_32(
+ llvm::ArrayRef<uint8_t> source_data,
+ RegisterInfoInterface *target_reg_interface) {
+
+ const RegisterInfo *reg_info = target_reg_interface->GetRegisterInfo();
+
+ lldb::DataBufferSP result_context_buf(
+ new DataBufferHeap(target_reg_interface->GetGPRSize(), 0));
+ uint8_t *result_base = result_context_buf->GetBytes();
+
+ if (source_data.size() < sizeof(MinidumpContext_x86_32))
+ return nullptr;
+
+ const MinidumpContext_x86_32 *context;
+ consumeObject(source_data, context);
+
+ const MinidumpContext_x86_32_Flags context_flags =
+ static_cast<MinidumpContext_x86_32_Flags>(
+ static_cast<uint32_t>(context->context_flags));
+ auto x86_32_Flag = MinidumpContext_x86_32_Flags::x86_32_Flag;
+ auto ControlFlag = MinidumpContext_x86_32_Flags::Control;
+ auto IntegerFlag = MinidumpContext_x86_32_Flags::Integer;
+ auto SegmentsFlag = MinidumpContext_x86_32_Flags::Segments;
+
+ if ((context_flags & x86_32_Flag) != x86_32_Flag) {
+ return nullptr;
+ }
+
+ if ((context_flags & ControlFlag) == ControlFlag) {
+ writeRegister(&context->ebp,
+ reg_info[lldb_ebp_i386].mutable_data(result_base));
+ writeRegister(&context->eip,
+ reg_info[lldb_eip_i386].mutable_data(result_base));
+ writeRegister(&context->cs,
+ reg_info[lldb_cs_i386].mutable_data(result_base));
+ writeRegister(&context->eflags,
+ reg_info[lldb_eflags_i386].mutable_data(result_base));
+ writeRegister(&context->esp,
+ reg_info[lldb_esp_i386].mutable_data(result_base));
+ writeRegister(&context->ss,
+ reg_info[lldb_ss_i386].mutable_data(result_base));
+ }
+
+ if ((context_flags & SegmentsFlag) == SegmentsFlag) {
+ writeRegister(&context->ds,
+ reg_info[lldb_ds_i386].mutable_data(result_base));
+ writeRegister(&context->es,
+ reg_info[lldb_es_i386].mutable_data(result_base));
+ writeRegister(&context->fs,
+ reg_info[lldb_fs_i386].mutable_data(result_base));
+ writeRegister(&context->gs,
+ reg_info[lldb_gs_i386].mutable_data(result_base));
+ }
+
+ if ((context_flags & IntegerFlag) == IntegerFlag) {
+ writeRegister(&context->eax,
+ reg_info[lldb_eax_i386].mutable_data(result_base));
+ writeRegister(&context->ecx,
+ reg_info[lldb_ecx_i386].mutable_data(result_base));
+ writeRegister(&context->edx,
+ reg_info[lldb_edx_i386].mutable_data(result_base));
+ writeRegister(&context->ebx,
+ reg_info[lldb_ebx_i386].mutable_data(result_base));
+ writeRegister(&context->esi,
+ reg_info[lldb_esi_i386].mutable_data(result_base));
+ writeRegister(&context->edi,
+ reg_info[lldb_edi_i386].mutable_data(result_base));
+ }
+
+ // TODO parse the floating point registers
+
+ return result_context_buf;
+}
diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h b/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h
new file mode 100644
index 000000000000..e18bb3b4f5d9
--- /dev/null
+++ b/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h
@@ -0,0 +1,138 @@
+//===-- RegisterContextMinidump_x86_32.h ------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_RegisterContextMinidump_x86_32_h_
+#define liblldb_RegisterContextMinidump_x86_32_h_
+
+// Project includes
+#include "MinidumpTypes.h"
+
+// Other libraries and framework includes
+#include "Plugins/Process/Utility/RegisterInfoInterface.h"
+#include "Plugins/Process/Utility/lldb-x86-register-enums.h"
+
+#include "lldb/Target/RegisterContext.h"
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/BitmaskEnum.h"
+#include "llvm/Support/Endian.h"
+
+// C includes
+// C++ includes
+
+namespace lldb_private {
+
+namespace minidump {
+
+// This function receives an ArrayRef pointing to the bytes of the Minidump
+// register context and returns a DataBuffer that's ordered by the offsets
+// specified in the RegisterInfoInterface argument
+// This way we can reuse the already existing register contexts
+lldb::DataBufferSP
+ConvertMinidumpContext_x86_32(llvm::ArrayRef<uint8_t> source_data,
+ RegisterInfoInterface *target_reg_interface);
+
+// Reference: see breakpad/crashpad source or WinNT.h
+struct MinidumpFloatingSaveAreaX86 {
+ llvm::support::ulittle32_t control_word;
+ llvm::support::ulittle32_t status_word;
+ llvm::support::ulittle32_t tag_word;
+ llvm::support::ulittle32_t error_offset;
+ llvm::support::ulittle32_t error_selector;
+ llvm::support::ulittle32_t data_offset;
+ llvm::support::ulittle32_t data_selector;
+
+ enum {
+ RegisterAreaSize = 80,
+ };
+ // register_area contains eight 80-bit (x87 "long double") quantities for
+ // floating-point registers %st0 (%mm0) through %st7 (%mm7).
+ uint8_t register_area[RegisterAreaSize];
+ llvm::support::ulittle32_t cr0_npx_state;
+};
+
+struct MinidumpContext_x86_32 {
+ // The context_flags field determines which parts
+ // of the structure are populated (have valid values)
+ llvm::support::ulittle32_t context_flags;
+
+ // The next 6 registers are included with
+ // MinidumpContext_x86_32_Flags::DebugRegisters
+ llvm::support::ulittle32_t dr0;
+ llvm::support::ulittle32_t dr1;
+ llvm::support::ulittle32_t dr2;
+ llvm::support::ulittle32_t dr3;
+ llvm::support::ulittle32_t dr6;
+ llvm::support::ulittle32_t dr7;
+
+ // The next field is included with
+ // MinidumpContext_x86_32_Flags::FloatingPoint
+ MinidumpFloatingSaveAreaX86 float_save;
+
+ // The next 4 registers are included with
+ // MinidumpContext_x86_32_Flags::Segments
+ llvm::support::ulittle32_t gs;
+ llvm::support::ulittle32_t fs;
+ llvm::support::ulittle32_t es;
+ llvm::support::ulittle32_t ds;
+
+ // The next 6 registers are included with
+ // MinidumpContext_x86_32_Flags::Integer
+ llvm::support::ulittle32_t edi;
+ llvm::support::ulittle32_t esi;
+ llvm::support::ulittle32_t ebx;
+ llvm::support::ulittle32_t edx;
+ llvm::support::ulittle32_t ecx;
+ llvm::support::ulittle32_t eax;
+
+ // The next 6 registers are included with
+ // MinidumpContext_x86_32_Flags::Control
+ llvm::support::ulittle32_t ebp;
+ llvm::support::ulittle32_t eip;
+ llvm::support::ulittle32_t cs; // WinNT.h says "must be sanitized"
+ llvm::support::ulittle32_t eflags; // WinNT.h says "must be sanitized"
+ llvm::support::ulittle32_t esp;
+ llvm::support::ulittle32_t ss;
+
+ // The next field is included with
+ // MinidumpContext_x86_32_Flags::ExtendedRegisters
+ // It contains vector (MMX/SSE) registers. It it laid out in the
+ // format used by the fxsave and fsrstor instructions, so it includes
+ // a copy of the x87 floating-point registers as well. See FXSAVE in
+ // "Intel Architecture Software Developer's Manual, Volume 2."
+ enum {
+ ExtendedRegistersSize = 512,
+ };
+ uint8_t extended_registers[ExtendedRegistersSize];
+};
+
+LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
+
+// For context_flags. These values indicate the type of
+// context stored in the structure. The high 24 bits identify the CPU, the
+// low 8 bits identify the type of context saved.
+enum class MinidumpContext_x86_32_Flags : uint32_t {
+ x86_32_Flag = 0x00010000, // CONTEXT_i386, CONTEXT_i486
+ Control = x86_32_Flag | 0x00000001,
+ Integer = x86_32_Flag | 0x00000002,
+ Segments = x86_32_Flag | 0x00000004,
+ FloatingPoint = x86_32_Flag | 0x00000008,
+ DebugRegisters = x86_32_Flag | 0x00000010,
+ ExtendedRegisters = x86_32_Flag | 0x00000020,
+ XState = x86_32_Flag | 0x00000040,
+
+ Full = Control | Integer | Segments,
+ All = Full | FloatingPoint | DebugRegisters | ExtendedRegisters,
+
+ LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ All)
+};
+
+} // end namespace minidump
+} // end namespace lldb_private
+#endif // liblldb_RegisterContextMinidump_x86_32_h_
diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp b/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp
new file mode 100644
index 000000000000..881c26a5774a
--- /dev/null
+++ b/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp
@@ -0,0 +1,113 @@
+//===-- RegisterContextMinidump_x86_64.cpp ----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Project includes
+#include "RegisterContextMinidump_x86_64.h"
+
+// Other libraries and framework includes
+#include "lldb/Core/DataBufferHeap.h"
+
+// C includes
+// C++ includes
+
+using namespace lldb_private;
+using namespace minidump;
+
+static llvm::MutableArrayRef<uint8_t> getDestRegister(uint8_t *context,
+ const RegisterInfo &reg) {
+ auto bytes = reg.mutable_data(context);
+
+ switch (reg.kinds[lldb::eRegisterKindLLDB]) {
+ case lldb_cs_x86_64:
+ case lldb_ds_x86_64:
+ case lldb_es_x86_64:
+ case lldb_fs_x86_64:
+ case lldb_gs_x86_64:
+ case lldb_ss_x86_64:
+ return bytes.take_front(2);
+ break;
+ case lldb_rflags_x86_64:
+ return bytes.take_front(4);
+ break;
+ default:
+ return bytes.take_front(8);
+ break;
+ }
+}
+
+static void writeRegister(const void *reg_src, uint8_t *context,
+ const RegisterInfo &reg) {
+ llvm::MutableArrayRef<uint8_t> reg_dest = getDestRegister(context, reg);
+ memcpy(reg_dest.data(), reg_src, reg_dest.size());
+}
+
+lldb::DataBufferSP lldb_private::minidump::ConvertMinidumpContext_x86_64(
+ llvm::ArrayRef<uint8_t> source_data,
+ RegisterInfoInterface *target_reg_interface) {
+
+ const RegisterInfo *reg_info = target_reg_interface->GetRegisterInfo();
+
+ lldb::DataBufferSP result_context_buf(
+ new DataBufferHeap(target_reg_interface->GetGPRSize(), 0));
+ uint8_t *result_base = result_context_buf->GetBytes();
+
+ if (source_data.size() < sizeof(MinidumpContext_x86_64))
+ return nullptr;
+
+ const MinidumpContext_x86_64 *context;
+ consumeObject(source_data, context);
+
+ const MinidumpContext_x86_64_Flags context_flags =
+ static_cast<MinidumpContext_x86_64_Flags>(
+ static_cast<uint32_t>(context->context_flags));
+ auto x86_64_Flag = MinidumpContext_x86_64_Flags::x86_64_Flag;
+ auto ControlFlag = MinidumpContext_x86_64_Flags::Control;
+ auto IntegerFlag = MinidumpContext_x86_64_Flags::Integer;
+ auto SegmentsFlag = MinidumpContext_x86_64_Flags::Segments;
+
+ if ((context_flags & x86_64_Flag) != x86_64_Flag)
+ return nullptr;
+
+ if ((context_flags & ControlFlag) == ControlFlag) {
+ writeRegister(&context->cs, result_base, reg_info[lldb_cs_x86_64]);
+ writeRegister(&context->ss, result_base, reg_info[lldb_ss_x86_64]);
+ writeRegister(&context->eflags, result_base, reg_info[lldb_rflags_x86_64]);
+ writeRegister(&context->rsp, result_base, reg_info[lldb_rsp_x86_64]);
+ writeRegister(&context->rip, result_base, reg_info[lldb_rip_x86_64]);
+ }
+
+ if ((context_flags & SegmentsFlag) == SegmentsFlag) {
+ writeRegister(&context->ds, result_base, reg_info[lldb_ds_x86_64]);
+ writeRegister(&context->es, result_base, reg_info[lldb_es_x86_64]);
+ writeRegister(&context->fs, result_base, reg_info[lldb_fs_x86_64]);
+ writeRegister(&context->gs, result_base, reg_info[lldb_gs_x86_64]);
+ }
+
+ if ((context_flags & IntegerFlag) == IntegerFlag) {
+ writeRegister(&context->rax, result_base, reg_info[lldb_rax_x86_64]);
+ writeRegister(&context->rcx, result_base, reg_info[lldb_rcx_x86_64]);
+ writeRegister(&context->rdx, result_base, reg_info[lldb_rdx_x86_64]);
+ writeRegister(&context->rbx, result_base, reg_info[lldb_rbx_x86_64]);
+ writeRegister(&context->rbp, result_base, reg_info[lldb_rbp_x86_64]);
+ writeRegister(&context->rsi, result_base, reg_info[lldb_rsi_x86_64]);
+ writeRegister(&context->rdi, result_base, reg_info[lldb_rdi_x86_64]);
+ writeRegister(&context->r8, result_base, reg_info[lldb_r8_x86_64]);
+ writeRegister(&context->r9, result_base, reg_info[lldb_r9_x86_64]);
+ writeRegister(&context->r10, result_base, reg_info[lldb_r10_x86_64]);
+ writeRegister(&context->r11, result_base, reg_info[lldb_r11_x86_64]);
+ writeRegister(&context->r12, result_base, reg_info[lldb_r12_x86_64]);
+ writeRegister(&context->r13, result_base, reg_info[lldb_r13_x86_64]);
+ writeRegister(&context->r14, result_base, reg_info[lldb_r14_x86_64]);
+ writeRegister(&context->r15, result_base, reg_info[lldb_r15_x86_64]);
+ }
+
+ // TODO parse the floating point registers
+
+ return result_context_buf;
+}
diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.h b/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.h
new file mode 100644
index 000000000000..9ba2ee9f29ad
--- /dev/null
+++ b/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.h
@@ -0,0 +1,183 @@
+//===-- RegisterContextMinidump_x86_64.h ------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_RegisterContextMinidump_h_
+#define liblldb_RegisterContextMinidump_h_
+
+// Project includes
+#include "MinidumpTypes.h"
+
+// Other libraries and framework includes
+#include "Plugins/Process/Utility/RegisterInfoInterface.h"
+#include "Plugins/Process/Utility/lldb-x86-register-enums.h"
+
+#include "lldb/Target/RegisterContext.h"
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/BitmaskEnum.h"
+#include "llvm/Support/Endian.h"
+
+// C includes
+// C++ includes
+
+namespace lldb_private {
+
+namespace minidump {
+
+// This function receives an ArrayRef pointing to the bytes of the Minidump
+// register context and returns a DataBuffer that's ordered by the offsets
+// specified in the RegisterInfoInterface argument
+// This way we can reuse the already existing register contexts
+lldb::DataBufferSP
+ConvertMinidumpContext_x86_64(llvm::ArrayRef<uint8_t> source_data,
+ RegisterInfoInterface *target_reg_interface);
+
+struct Uint128 {
+ llvm::support::ulittle64_t high;
+ llvm::support::ulittle64_t low;
+};
+
+// Reference: see breakpad/crashpad source or WinNT.h
+struct MinidumpXMMSaveArea32AMD64 {
+ llvm::support::ulittle16_t control_word;
+ llvm::support::ulittle16_t status_word;
+ uint8_t tag_word;
+ uint8_t reserved1;
+ llvm::support::ulittle16_t error_opcode;
+ llvm::support::ulittle32_t error_offset;
+ llvm::support::ulittle16_t error_selector;
+ llvm::support::ulittle16_t reserved2;
+ llvm::support::ulittle32_t data_offset;
+ llvm::support::ulittle16_t data_selector;
+ llvm::support::ulittle16_t reserved3;
+ llvm::support::ulittle32_t mx_csr;
+ llvm::support::ulittle32_t mx_csr_mask;
+ Uint128 float_registers[8];
+ Uint128 xmm_registers[16];
+ uint8_t reserved4[96];
+};
+
+struct MinidumpContext_x86_64 {
+ // Register parameter home addresses.
+ llvm::support::ulittle64_t p1_home;
+ llvm::support::ulittle64_t p2_home;
+ llvm::support::ulittle64_t p3_home;
+ llvm::support::ulittle64_t p4_home;
+ llvm::support::ulittle64_t p5_home;
+ llvm::support::ulittle64_t p6_home;
+
+ // The context_flags field determines which parts
+ // of the structure are populated (have valid values)
+ llvm::support::ulittle32_t context_flags;
+ llvm::support::ulittle32_t mx_csr;
+
+ // The next register is included with
+ // MinidumpContext_x86_64_Flags::Control
+ llvm::support::ulittle16_t cs;
+
+ // The next 4 registers are included with
+ // MinidumpContext_x86_64_Flags::Segments
+ llvm::support::ulittle16_t ds;
+ llvm::support::ulittle16_t es;
+ llvm::support::ulittle16_t fs;
+ llvm::support::ulittle16_t gs;
+
+ // The next 2 registers are included with
+ // MinidumpContext_x86_64_Flags::Control
+ llvm::support::ulittle16_t ss;
+ llvm::support::ulittle32_t eflags;
+
+ // The next 6 registers are included with
+ // MinidumpContext_x86_64_Flags::DebugRegisters
+ llvm::support::ulittle64_t dr0;
+ llvm::support::ulittle64_t dr1;
+ llvm::support::ulittle64_t dr2;
+ llvm::support::ulittle64_t dr3;
+ llvm::support::ulittle64_t dr6;
+ llvm::support::ulittle64_t dr7;
+
+ // The next 4 registers are included with
+ // MinidumpContext_x86_64_Flags::Integer
+ llvm::support::ulittle64_t rax;
+ llvm::support::ulittle64_t rcx;
+ llvm::support::ulittle64_t rdx;
+ llvm::support::ulittle64_t rbx;
+
+ // The next register is included with
+ // MinidumpContext_x86_64_Flags::Control
+ llvm::support::ulittle64_t rsp;
+
+ // The next 11 registers are included with
+ // MinidumpContext_x86_64_Flags::Integer
+ llvm::support::ulittle64_t rbp;
+ llvm::support::ulittle64_t rsi;
+ llvm::support::ulittle64_t rdi;
+ llvm::support::ulittle64_t r8;
+ llvm::support::ulittle64_t r9;
+ llvm::support::ulittle64_t r10;
+ llvm::support::ulittle64_t r11;
+ llvm::support::ulittle64_t r12;
+ llvm::support::ulittle64_t r13;
+ llvm::support::ulittle64_t r14;
+ llvm::support::ulittle64_t r15;
+
+ // The next register is included with
+ // MinidumpContext_x86_64_Flags::Control
+ llvm::support::ulittle64_t rip;
+
+ // The next set of registers are included with
+ // MinidumpContext_x86_64_Flags:FloatingPoint
+ union FPR {
+ MinidumpXMMSaveArea32AMD64 flt_save;
+ struct {
+ Uint128 header[2];
+ Uint128 legacy[8];
+ Uint128 xmm[16];
+ } sse_registers;
+ };
+
+ enum {
+ VRCount = 26,
+ };
+
+ Uint128 vector_register[VRCount];
+ llvm::support::ulittle64_t vector_control;
+
+ // The next 5 registers are included with
+ // MinidumpContext_x86_64_Flags::DebugRegisters
+ llvm::support::ulittle64_t debug_control;
+ llvm::support::ulittle64_t last_branch_to_rip;
+ llvm::support::ulittle64_t last_branch_from_rip;
+ llvm::support::ulittle64_t last_exception_to_rip;
+ llvm::support::ulittle64_t last_exception_from_rip;
+};
+
+// For context_flags. These values indicate the type of
+// context stored in the structure. The high 24 bits identify the CPU, the
+// low 8 bits identify the type of context saved.
+LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
+
+enum class MinidumpContext_x86_64_Flags : uint32_t {
+ x86_64_Flag = 0x00100000,
+ Control = x86_64_Flag | 0x00000001,
+ Integer = x86_64_Flag | 0x00000002,
+ Segments = x86_64_Flag | 0x00000004,
+ FloatingPoint = x86_64_Flag | 0x00000008,
+ DebugRegisters = x86_64_Flag | 0x00000010,
+ XState = x86_64_Flag | 0x00000040,
+
+ Full = Control | Integer | FloatingPoint,
+ All = Full | Segments | DebugRegisters,
+
+ LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ All)
+};
+
+} // end namespace minidump
+} // end namespace lldb_private
+#endif // liblldb_RegisterContextMinidump_h_
diff --git a/source/Plugins/Process/minidump/ThreadMinidump.cpp b/source/Plugins/Process/minidump/ThreadMinidump.cpp
new file mode 100644
index 000000000000..e42108b9261a
--- /dev/null
+++ b/source/Plugins/Process/minidump/ThreadMinidump.cpp
@@ -0,0 +1,114 @@
+//===-- ThreadMinidump.cpp --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Project includes
+#include "ThreadMinidump.h"
+#include "ProcessMinidump.h"
+
+#include "RegisterContextMinidump_x86_32.h"
+#include "RegisterContextMinidump_x86_64.h"
+
+// Other libraries and framework includes
+#include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
+#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
+
+#include "Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h"
+
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/StopInfo.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Unwind.h"
+
+// C Includes
+// C++ Includes
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace minidump;
+
+ThreadMinidump::ThreadMinidump(Process &process, const MinidumpThread &td,
+ llvm::ArrayRef<uint8_t> gpregset_data)
+ : Thread(process, td.thread_id), m_thread_reg_ctx_sp(),
+ m_gpregset_data(gpregset_data) {}
+
+ThreadMinidump::~ThreadMinidump() {}
+
+void ThreadMinidump::RefreshStateAfterStop() {}
+
+void ThreadMinidump::ClearStackFrames() {}
+
+RegisterContextSP ThreadMinidump::GetRegisterContext() {
+ if (!m_reg_context_sp) {
+ m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
+ }
+ return m_reg_context_sp;
+}
+
+RegisterContextSP
+ThreadMinidump::CreateRegisterContextForFrame(StackFrame *frame) {
+ RegisterContextSP reg_ctx_sp;
+ uint32_t concrete_frame_idx = 0;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
+
+ if (frame)
+ concrete_frame_idx = frame->GetConcreteFrameIndex();
+
+ if (concrete_frame_idx == 0) {
+ if (m_thread_reg_ctx_sp)
+ return m_thread_reg_ctx_sp;
+
+ ProcessMinidump *process =
+ static_cast<ProcessMinidump *>(GetProcess().get());
+ ArchSpec arch = process->GetArchitecture();
+ RegisterInfoInterface *reg_interface = nullptr;
+
+ // TODO write other register contexts and add them here
+ switch (arch.GetMachine()) {
+ case llvm::Triple::x86: {
+ reg_interface = new RegisterContextLinux_i386(arch);
+ lldb::DataBufferSP buf =
+ ConvertMinidumpContext_x86_32(m_gpregset_data, reg_interface);
+ DataExtractor gpregs(buf, lldb::eByteOrderLittle, 4);
+ DataExtractor fpregs;
+ m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64(
+ *this, reg_interface, gpregs, fpregs));
+ break;
+ }
+ case llvm::Triple::x86_64: {
+ reg_interface = new RegisterContextLinux_x86_64(arch);
+ lldb::DataBufferSP buf =
+ ConvertMinidumpContext_x86_64(m_gpregset_data, reg_interface);
+ DataExtractor gpregs(buf, lldb::eByteOrderLittle, 8);
+ DataExtractor fpregs;
+ m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64(
+ *this, reg_interface, gpregs, fpregs));
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (!reg_interface) {
+ if (log)
+ log->Printf("elf-core::%s:: Architecture(%d) not supported",
+ __FUNCTION__, arch.GetMachine());
+ assert(false && "Architecture not supported");
+ }
+
+ reg_ctx_sp = m_thread_reg_ctx_sp;
+ } else if (m_unwinder_ap) {
+ reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame(frame);
+ }
+
+ return reg_ctx_sp;
+}
+
+bool ThreadMinidump::CalculateStopInfo() { return false; }
diff --git a/source/Plugins/Process/minidump/ThreadMinidump.h b/source/Plugins/Process/minidump/ThreadMinidump.h
new file mode 100644
index 000000000000..97db452edfff
--- /dev/null
+++ b/source/Plugins/Process/minidump/ThreadMinidump.h
@@ -0,0 +1,52 @@
+//===-- ThreadMinidump.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadMinidump_h_
+#define liblldb_ThreadMinidump_h_
+
+// Project includes
+#include "MinidumpTypes.h"
+
+// Other libraries and framework includes
+#include "lldb/Target/Thread.h"
+
+// C Includes
+// C++ Includes
+
+namespace lldb_private {
+
+namespace minidump {
+
+class ThreadMinidump : public Thread {
+public:
+ ThreadMinidump(Process &process, const MinidumpThread &td,
+ llvm::ArrayRef<uint8_t> gpregset_data);
+
+ ~ThreadMinidump() override;
+
+ void RefreshStateAfterStop() override;
+
+ lldb::RegisterContextSP GetRegisterContext() override;
+
+ lldb::RegisterContextSP
+ CreateRegisterContextForFrame(StackFrame *frame) override;
+
+ void ClearStackFrames() override;
+
+protected:
+ lldb::RegisterContextSP m_thread_reg_ctx_sp;
+ llvm::ArrayRef<uint8_t> m_gpregset_data;
+
+ bool CalculateStopInfo() override;
+};
+
+} // namespace minidump
+} // namespace lldb_private
+
+#endif // liblldb_ThreadMinidump_h_